diff --git a/HISTORY.md b/HISTORY.md new file mode 100644 index 0000000..1b03492 --- /dev/null +++ b/HISTORY.md @@ -0,0 +1,13 @@ +## 2021 +[SimplyTranslate](https://codeberg.org/SimpleWeb/SimplyTranslate-Web) was founded by metalune and fattalion. +It was written in Python and used the Quart framework. + +## 2022 +fattalion created a Go implementation. + +## 2023 +* Both metalune and fattalion retired, and they handed SimplyTranslate over to [ManeraKai](https://manerakai.com). +* Arya K. from [~vern](https://vern.cc) made a hard-fork named [Mozhi](https://codeberg.org/aryak/mozhi) and has vastly refactored it. + +## 2024 +Izuru Yakumo took interest in SimplyTranslate and decided to fork it in October 2023, and in January he turned it into a hard-fork, eventually renaming it to "Mai", after a character from the fifth [Touhou Project](https://en.touhouwiki.net/wiki/Touhou_Project) game, [Mai](https://en.touhouwiki.net/wiki/Mai). diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..f3ca296 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,11 @@ +# Installation + +```shell +$ git clone https://git.chaotic.ninja/yakumo.izuru/mai +$ cd mai +$ make +# make PREFIX=/usr/local install +``` +* Read the [mai.ini(5)](mai.ini.5) manual page +* Use any web server than is able to reverse proxy, like Apache, h2o, or NGINX. + diff --git a/INSTANCES.md b/INSTANCES.md new file mode 100644 index 0000000..0e9f011 --- /dev/null +++ b/INSTANCES.md @@ -0,0 +1,6 @@ +# List of known instances + +* [tr.chaotic.ninja](https://tr.chaotic.ninja) + * Location: Germany + * Cloudflare: No + diff --git a/LEGAL.md b/LEGAL.md new file mode 100644 index 0000000..4c35c76 --- /dev/null +++ b/LEGAL.md @@ -0,0 +1,9 @@ +Mai does not host any content. All content shown on any Mai instances is from [Google Translate](https://translate.google.com), [Reverso](https://www.reverso.net/), and [LibreTranslate](https://libretranslate.com) + +Mai is not affiliated with none of the above, which this program relays. + +Trademarks belong to their respective owners. +Google Translate is a trademark of [Google LLC](https://www.google.com). Reverso is a trademark of Reverso, et cetera. + +The creators and maintainers of this repository assume no liability for the accuracy and timeliness of any information provided above. Trademark owner information was researched to the best of the author's knowledge at the time of curation and may be outdated or incorrect. + diff --git a/README.md b/README.md index 29b1f5a..f2bf040 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,9 @@ ## Mai A privacy friendly frontend to multiple translation engines. -### History -1. SimplyTranslate was founded by [metalune and fattalion](https://codeberg.org/SimpleWeb/SimplyTranslate-Web). It was written in Python. -2. Fattalion created a Go implementation. -3. Both metalune and fattalion retired, and they handed SimplyTranslate over to ManeraKai. -4. [Izuru Yakumo The Violet Hermit](https://geidontei.chaotic.ninja/usr/yakumo_izuru) stole it, and renamed it after [Mai](https://en.touhouwiki.net/wiki/Mai) from [Mystic Square](https://en.touhouwiki.net/wiki/Mystic_Square) - -### Instances -| URL | Location | Cloudflare? | -|-----|----------|-------------| -| [tr.chaotic.ninja](https://tr.chaotic.ninja) | DE | No | - -### Installation - -```shell -% git clone https://git.chaotic.ninja/yakumo.izuru/mai -% cd mai -% make -# make install -``` - -### Setup -For [nginx](https://www.nginx.com) you can use this snippet, this also serves the static resources. - -```nginx -location / { - proxy_set_header Host $host; - proxy_pass http://localhost:5000; -} -``` - -### Legal notice -Mai does not host any content. All content shown on any Mai instances is from [Google Translate](https://translate.google.com), [Reverso](https://www.reverso.net/), [iCIBA](https://www.iciba.net) and [LibreTranslate](https://libretranslate.com) - -Mai is not affiliated with none of the above, which this program relays. - -Trademarks belong to their respective owners. -Google Translate is a trademark of [Google LLC](https://www.google.com). Reverso is a trademark of Reverso, et cetera. - -The creators and maintainers of this repository assume no liability for the accuracy and timeliness of any information provided above. Trademark owner information was researched to the best of the author's knowledge at the time of curation and may be outdated or incorrect. +* [How to install](INSTALL.md) +* [List of instances](INSTANCES.md) +* [Legal notice](LEGAL.md) ### Other projects * [Mozhi](https://codeberg.org/aryak/mozhi), also a fork of SimplyTranslate diff --git a/cmd/mai/main.go b/cmd/mai/main.go index bd17042..65922bf 100644 --- a/cmd/mai/main.go +++ b/cmd/mai/main.go @@ -21,13 +21,13 @@ import ( ) var ( configfile string + groupname string + username string ) var conf struct { - group string listen string staticpath string tmplpath string - user string } func main() { parseFlags() @@ -41,8 +41,8 @@ func main() { conf.staticpath = "./static" conf.tmplpath = "./views" - if conf.user != "" { - uid, gid, err := usergroupids(conf.user, conf.group) + if username != "" { + uid, gid, err := usergroupids(username, groupname) if err != nil { fmt.Println(err) os.Exit(1) @@ -258,6 +258,9 @@ func main() { } } }) + app.Get("/robots.txt", func(c *fiber.Ctx) error { + return c.SendString("User-Agent: *\nDisallow: /\n") + }) app.Get("/version", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{ "fiberversion": fiber.Version, diff --git a/cmd/mai/parseflags.go b/cmd/mai/parseflags.go index dda2529..4969f9e 100644 --- a/cmd/mai/parseflags.go +++ b/cmd/mai/parseflags.go @@ -7,5 +7,7 @@ import ( func parseFlags() { flag.StringVar(&configfile, "f", "", "Configuration file") + flag.StringVar(&username, "u", "", "Sets the user to which privilege dropping is done") + flag.StringVar(&groupname, "g", "", "Sets the group to which privilege dropping is done") flag.Parse() } diff --git a/cmd/mai/readconf.go b/cmd/mai/readconf.go index 9e86bb3..c184797 100644 --- a/cmd/mai/readconf.go +++ b/cmd/mai/readconf.go @@ -10,11 +10,9 @@ func readConf(file string) error { if err != nil { return err } - conf.group = cfg.Section("mai").Key("group").String() conf.listen = cfg.Section("mai").Key("listen").String() conf.staticpath = cfg.Section("mai").Key("static").String() conf.tmplpath = cfg.Section("mai").Key("templates").String() - conf.user = cfg.Section("mai").Key("user").String() return nil } diff --git a/cmd/mai/usergroupids.go b/cmd/mai/usergroupids.go index dd4b609..e3d7ced 100644 --- a/cmd/mai/usergroupids.go +++ b/cmd/mai/usergroupids.go @@ -14,7 +14,7 @@ func usergroupids(username string, groupname string) (int, int, error) { uid, _ := strconv.Atoi(u.Uid) gid, _ := strconv.Atoi(u.Gid) - if conf.group != "" { + if groupname != "" { g, err := user.LookupGroup(groupname) if err != nil { return uid, -1, err diff --git a/docs/api/index.html b/docs/api/index.html index ef9b03e..4a96142 100644 --- a/docs/api/index.html +++ b/docs/api/index.html @@ -7,49 +7,68 @@ API Documentation | Mai -

API Documentation

-

-

[GET] /api/translate

-

[POST] /api/translate

-

Description

-

Translation endpoint, input must be URL-encoded (e.g. multi-byte characters, words separated by space)

-

Arguments

- -

Examples

-

GET /api/translate?engine=google&from=auto&to=en&text="sonrisa"

-
-

[GET] /api/source_languages

-

[GET] /api/target_languages

-

Description

-

Get a JSON array of supported source and target languages for a particular engine

-

Arguments

- -

Examples

-

GET /api/source_languages?engine=google

-

GET /api/target_languages?engine=google

-
-

[GET] /api/tts

-

Description

-

Obtain text-to-speech audio files from an engine, provided said engine supports them

-

Arguments

- -

Examples

-

GET /api/tts?engine=google&lang=en&text="hi"

-
-

[POST] /switchlanguages

-

Description

-

Switch between source and target languages, as long as the source language isn't "auto"

-
+

API documentation

+ + + + + + + + + + + + + + + + + + + +
+

[GET] /api/translate

+

[POST] /api/translate

+

Description

+

Translation endpoint, input must be URL-encoded (e.g. multi-byte characters, words separated by space)

+

Arguments

+
    +
  • engine
  • +
  • from
  • +
  • text
  • +
  • to
  • +
+
+

[GET] /api/source_languages

+

[GET] /api/target_languages

+

Description

+

Get a JSON array of supported source and target languages for a particular engine

+

Arguments

+
    +
  • engine
  • +
+
+

[GET] /api/tts

+

Description

+

Obtain text-to-speech audio files from an engine, provided said engine supports them

+

Arguments

+
    +
  • engine
  • +
  • lang
  • +
  • text
  • +
+
+

[GET] /robots.txt

+
+

[POST] /switchlanguages

+

Description

+

Switch between source and target languages, as long as the source language isn't "auto"

+

Must only be called inside the form interface

+
+

[GET] /version

+

Description

+

Return the software version as a JSON array

+
diff --git a/docs/index.html b/docs/index.html index 5b32e69..3dcb9b7 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,12 +6,27 @@ Mai | Documentation - - -

Documentation

- + + + + +
+ + + + +
API
+
+ + + + +
+

Welcome to Mai's documentation!

+

See the menu for the available entries

+

Anything else is covered by the man pages

+
+
diff --git a/docs/style.css b/docs/style.css index da3e48a..1b24e42 100644 --- a/docs/style.css +++ b/docs/style.css @@ -1,114 +1,22 @@ -/* - * Taken from vnpower - */ - -* { - box-sizing: border-box; } - body { - top: 0; - margin: 0; - background-color: #1d1f21; - color: white; - font-family: "Open Sans", "Roboto", "Noto Sans", "Noto Sans CJK JP", sans-serif; - line-height: 1.618; + background-color: #f8cfd2; + color: rgb(206, 147, 191); } -h2.get { - color: orange; +a, a:visited { + color: rgb(206, 147, 191); } -h2.post { - color: green; +@media screen and (prefers-color-scheme: dark) { + body { + background-color: #700000; + color: #ffffff; + } + a, a:visited { + color: #18c018; + } } -@media (max-width: 684px) { - body { - font-size: 1rem; } } - -@media (max-width: 382px) { - body { - font-size: 1rem; } } - -a { - color: #81a2be; - text-decoration-color: #81a2be; } - -#header { - width: 100%; - min-width: 320px; - background-color: #282a2e; } - -#header img { - width: 280px; } - -#header-content { - margin: 0 auto; - width: min-content; } - -#nav { - display: flex; - justify-content: center; - background-color: #373b41; } - -#footer { - margin-top: 0.5rem; - text-align: center; } - -#body { - min-height: 75vh; - max-width: 800px; - margin: 1rem auto; - padding: 0 0.6rem; } - #body h1, - #body h2, - #body h3, - #body h4, - #body h5, - #body h6 { - line-height: 1.1; - font-family: sans-serif; - font-weight: 700; - margin-top: 1rem; - margin-bottom: 1rem; - overflow-wrap: break-word; - word-wrap: break-word; - -ms-word-break: break-all; - word-break: break-word; } - #body h1 { - border-bottom: 1px solid #b5bd68; - display: block; } - #body p { - margin-top: 0px; - margin-bottom: 0.5rem; } - #body li > p { - padding: 0; - margin: 0; } - #body small, - #body sub, - #body sup { - font-size: 75%; } - #body img, - #body video { - height: auto; - max-width: 100%; - margin-top: 0.5rem; - margin-bottom: 0.5rem; - box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.12), 0px 2px 2px 0px rgba(0, 0, 0, 0.12), 0px 4px 4px 0px rgba(0, 0, 0, 0.12), 0px 8px 8px 0px rgba(0, 0, 0, 0.12), 0px 16px 16px 0px rgba(0, 0, 0, 0.12); } - #body pre { - background-color: #373b41; - display: block; - padding: 1em; - overflow-x: auto; - margin-top: 0px; - margin-bottom: 0.5rem; } - #body code, #body kbd, #body samp { - padding: 0 0.5em; - background-color: #373b41; - white-space: pre-wrap; } - #body pre > code { - padding: 0; - background-color: transparent; - white-space: pre; - font-size: 1em; } - +table { + border-color: white; +} diff --git a/engines/engine.go b/engines/engine.go index 239f700..499cbfd 100644 --- a/engines/engine.go +++ b/engines/engine.go @@ -24,7 +24,6 @@ type Language map[string]string var Engines = map[string]Engine{ "google": &GoogleTranslate{}, "reverso": &Reverso{}, - "iciba": &ICIBA{}, "libretranslate": &LibreTranslate{ InstanceURL: os.Getenv("MAI_LIBRETRANSLATE_INSTANCE"), APIKey: os.Getenv("MAI_LIBRETRANSLATE_API"), diff --git a/engines/iciba.go b/engines/iciba.go deleted file mode 100644 index 42da7b6..0000000 --- a/engines/iciba.go +++ /dev/null @@ -1,283 +0,0 @@ -package engines - -import ( - "crypto/md5" - "encoding/hex" - "encoding/json" - "fmt" - "net/http" - "net/url" -) - -// iCIBA is an engine that fetches data from https://www.iciba.com. -type ICIBA struct{} - -func (_ *ICIBA) DisplayName() string { return "iCIBA" } - -var icibaLanguages = Language{ - // ICIBA does have an API, but they return Chinese names. - // For languages already present in Google translate, the English - // names in that engine file are used; Otherwise official names - // as researched on Wikipedia are used. They're validated against - // the Chinese names to the best of my ability. - // Missing "cni", "kbh", "tmh" - // due to conflict between ISO-639 table and Chinese label - // one "//" means on iciba but not on google - "ace": "Achinese", // - "acu": "Achuar-Shiwiar", // - "af": "Afrikaans", - "agr": "Aguaruna", // - "ake": "Akawaio", // - "sq": "Albanian", - "am": "Amharic", - "ar": "Arabic", - "hy": "Armenian", - "az": "Azerbaijani", - "bsn": "Barasana-Eduria", // - "ba": "Bashkir", // - "eu": "Basque", - "be": "Belarusian", - "bem": "Bemba", // - "bn": "Bengali", - "ber": "Berber", // - "bi": "Bislama", // - "bs": "Bosnian", - "br": "Breton", // - "bg": "Bulgarian", - "cjp": "Cabécar", // - "yue": "Cantonese", - "ca": "Catalan", - "ceb": "Cebuano", - "cha": "Chamorro", // - "chr": "Cherokee", // - "ny": "Chichewa", - "zh": "Chinese (Simplified)", // "zh-cn" on Google - "cht": "Chinese (Traditional)", // "zh-tw" on Google - "cv": "Chuvash", - "cop": "Coptic", // - "co": "Corsican", - "hr": "Croatian", - "cs": "Czech", - "da": "Danish", - "dv": "Dhivehi", // - "dik": "Dinka", // - "nl": "Dutch", - "dz": "Dzongkha", // - "en": "English", - "eo": "Esperanto", - "et": "Estonian", - "ee": "Ewe", // - "fo": "Faroese", // - "fj": "Fijian", // - "fil": "Filipino", // "tl" on Google - "fi": "Finnish", - "fr": "French", - "fy": "Frisian", - "gbi": "Galela", // - "gl": "Galician", - "lg": "Ganda", // - "jy": "Georgian", // "ka" on Google - "de": "German", - "el": "Greek", - "amu": "Guerrero Amuzgo", // - "gu": "Gujarati", - "ht": "Haitian Creole", - "ha": "Hausa", - "haw": "Hawaiian", - "he": "Hebrew", // "iw" on Google - "hi": "Hindi", - "mww": "Hmong Daw", // - "hmn": "Hmong", // not in iciba - "hu": "Hungarian", - "is": "Icelandic", - "ig": "Igbo", - "id": "Indonesian", - "ga": "Irish", - "it": "Italian", - "jac": "Jacalteco", // - "ja": "Japanese", - "jv": "Javanese", // "jw" on Google - "kab": "Kabyle", // - "kn": "Kannada", - "cak": "Kaqchikel", // - "ka": "Kazakh", // Google only has "kk" - "kk": "Kazakh (Cyrillic)", // Google has it as just "Kazakh" - "kek": "Kekchí", // - "km": "Khmer", - "rw": "Kinyarwanda", - "kg": "Kongo", // - "ko": "Korean", - "ku": "Kurdish (Kurmanji)", - "ky": "Kyrgyz", - "lo": "Lao", - "la": "Latin", - "lv": "Latvian", - "ln": "Lingala", // - "lt": "Lithuanian", - "dop": "Lukpa", // - "lb": "Luxembourgish", - "mk": "Macedonian", - "mg": "Malagasy", - "ms": "Malay", - "ml": "Malayalam", - "mt": "Maltese", - "mam": "Mam", // - "gv": "Manx", // - "mi": "Maori", - "mr": "Marathi", - "mhr": "Mari (Eastern)", // - "mrj": "Mari (Western)", // - "mn": "Mongolian", - "me": "Montenegrin", // - "my": "Myanmar (Burmese)", - "nhg": "Nahuatl", // - "djk": "Ndyuka", // - "ne": "Nepali", - "no": "Norwegian", - "or": "Odia (Oriya)", - "ojb": "Ojibwa", - "om": "Oromo", // - "os": "Ossetian", // - "pck": "Paite", // - "pap": "Papiamento", // - "ps": "Pashto", - "fa": "Persian", - "pl": "Polish", - "pt": "Portuguese", - "pot": "Potawatomi", // - "pa": "Punjabi", - "otq": "Querétaro Otomi", // - "quc": "Quiché", // - "quw": "Quichua", // - "chq": "Quiotepec Chinantec", // - "rmn": "Romani", // - "ro": "Romanian", - "rn": "Rundi", // - "ru": "Russian", - "sm": "Samoan", - "sg": "Sango", // - "gd": "Scots Gaelic", - "sr": "Serbian", - "crs": "Seselwa Creole French", // - "st": "Sesotho", - "sn": "Shona", - "jiv": "Shuar", // - "sd": "Sindhi", - "si": "Sinhala", - "sk": "Slovak", - "sl": "Slovenian", - "so": "Somali", - "es": "Spanish", - "su": "Sundanese", - "sw": "Swahili", - "sv": "Swedish", - "syc": "Syriac", // considered "extinct" but is somehow supported - "shi": "Tachelhit", // - "ty": "Tahitian", // - "tg": "Tajik", - "ta": "Tamil", - "tt": "Tatar", - "te": "Telugu", - "tet": "Tetum", // - "th": "Thai", - "ti": "Tigre", // - "tw": "Tiwi", // - "tpi": "Tok Pisin", // - "to": "Tonga", // - "ts": "Tsonga", - "tn": "Tswana", // - "tr": "Turkish", - "tk": "Turkmen", - "udm": "Udmurt", // - "uk": "Ukrainian", - "ppk": "Uma", // - "ur": "Urdu", - "usp": "Uspanteco", // - "uy": "Uyghur", // "ug" on Google - "uz": "Uzbek", - "ve": "Venda", // - "vi": "Vietnamese", - "war": "Waray", // - "cy": "Welsh", - "wal": "Wolaitta", // - "wol": "Wolof", - "xh": "Xhosa", - "yi": "Yiddish", - "yo": "Yoruba", - "yua": "Yucatán Maya", // - "dje": "Zarma", // - "zu": "Zulu", -} - -func (_ *ICIBA) SourceLanguages() (Language, error) { - icibaLanguagesCopy := make(Language) - for k, v := range icibaLanguages { - icibaLanguagesCopy[k] = v - } - - icibaLanguagesCopy["auto"] = "Detect Language" - return icibaLanguagesCopy, nil -} - -func (_ *ICIBA) TargetLanguages() (Language, error) { return icibaLanguages, nil } - -func (_ *ICIBA) Translate(text string, from, to string) (TranslationResult, error) { - requestURL, _ := url.Parse("https://ifanyi.iciba.com/index.php") - - query := url.Values{} - query.Add("c", "trans") - query.Add("m", "fy") - query.Add("client", "6") - query.Add("auth_user", "key_web_fanyi") - - sum := md5.Sum([]byte(("6key_web_fanyiifanyiweb8hc9s98e" + text))) - query.Add("sign", hex.EncodeToString(sum[:])[:16]) - - requestURL.RawQuery = query.Encode() - - formData := url.Values{} - formData.Add("from", from) - formData.Add("to", to) - formData.Add("q", text) - - response, err := http.PostForm(requestURL.String(), formData) - if err != nil { - return TranslationResult{}, err - } - - defer response.Body.Close() - - if response.StatusCode != 200 { - return TranslationResult{}, fmt.Errorf("got status code %d from iCIBA", response.StatusCode) - } - - var responseJSON struct { - Content struct { - From string `json:"from"` - Out string `json:"out"` - } `json:"content"` - } - - if err := json.NewDecoder(response.Body).Decode(&responseJSON); err != nil { - return TranslationResult{}, err - } - - for code := range icibaLanguages { - if code == responseJSON.Content.From { - from = code - break - } - } - - if from == "" { - return TranslationResult{TranslatedText: responseJSON.Content.Out}, - fmt.Errorf("language code \"%s\" is not in iCIBA's language list", responseJSON.Content.From) - } - - return TranslationResult{ - SourceLanguage: from, - TranslatedText: responseJSON.Content.Out, - }, nil -} - -func (_ *ICIBA) Tts(text, lang string) (string, error) { return "", nil } diff --git a/example/mai.ini b/example/mai.ini index 2e69394..e697070 100644 --- a/example/mai.ini +++ b/example/mai.ini @@ -2,4 +2,3 @@ listen = "127.0.0.1:5000" rootdir = "./static" tmplpath = "./views" -user = "www" diff --git a/mai.1 b/mai.1 index 815203e..17b7bbc 100644 --- a/mai.1 +++ b/mai.1 @@ -7,6 +7,8 @@ .Sh SYNOPSIS .Nm .Op Fl f Ar config-file +.Op Fl u Ar user +.Op Fl g Ar group .Sh DESCRIPTION This project has been forked from the remains of the rewrite of the SimplyTranslate project, which is currently @@ -14,11 +16,19 @@ maintained by ManeraKai, but as time passed, this fork diverged wildly, and was renamed. Much to anyone's dismay, this was named after .Lk https://en.touhouwiki.net/wiki/Mai Mai from Mystic Square +.Sh FEATURES +.Bl -tag -width 11n -compact +.It Command-line tool +See +.Xr suwako 1 +.It Privilege dropping +Stolen from +.Xr partage 1 +just so you do not run this as root +.El .Sh AUTHORS .An fattalion .An metalune .An ManeraKai Lk https://manerakai.com .Sh MAINTAINERS .An Izuru Yakumo Aq Mt yakumo.izuru@chaotic.ninja -.Sh BUGS -iCIBA engine doesn't work, throws HTTP 500 diff --git a/mai.ini.5 b/mai.ini.5 index 0f6c194..7f05709 100644 --- a/mai.ini.5 +++ b/mai.ini.5 @@ -7,9 +7,6 @@ .Sh OPTIONS .Ss [mai] section .Bl -tag -width 11n -.It group -Group ID for dropping privileges to. -If unset, assume the GID of user .It listen HTTP port for the server to listen. Default is "localhost:5000" @@ -19,8 +16,6 @@ Default is "./static" .It templates Directory where the templates are located. Default is "./views" -.It user -User ID for dropping privileges to. .El .Sh ENVIRONMENT .Bl -tag -width 11n diff --git a/rc.d/FreeBSD b/rc.d/FreeBSD index a63d87c..05c4233 100644 --- a/rc.d/FreeBSD +++ b/rc.d/FreeBSD @@ -20,7 +20,7 @@ load_rc_config $name pidfile="/var/run/${name}.pid" command="/usr/sbin/daemon" procname="/usr/local/bin/${name}" -mai_args="-f ${mai_config}" +mai_args="-f ${mai_config} -u www -g www" command_args="-S -m 3 -s info -l daemon -p ${pidfile} /usr/bin/env ${procname} ${mai_args}" required_files="${mai_config}" diff --git a/rc.d/NetBSD b/rc.d/NetBSD index 0ff793f..8133c4e 100644 --- a/rc.d/NetBSD +++ b/rc.d/NetBSD @@ -11,7 +11,7 @@ $_rc_subr_loaded . /etc/rc.subr name="mai" rcvar=$name command="/usr/pkg/bin/mai" -command_args="-f /usr/pkg/etc/mai/mai.ini" +command_args="-f /usr/pkg/etc/mai/mai.ini -u www -g www" pidfile="/var/run/${name}.pid" start_cmd="mai_start" diff --git a/rc.d/OpenBSD b/rc.d/OpenBSD index e36e8fe..a223415 100644 --- a/rc.d/OpenBSD +++ b/rc.d/OpenBSD @@ -2,7 +2,7 @@ # $TheSupernovaDuo$ daemon="/usr/local/bin/mai" -daemon_flags="-f /usr/local/etc/mai/mai.ini" +daemon_flags="-f /usr/local/etc/mai/mai.ini -u www -g www" . /etc/rc.d/rc.subr diff --git a/rc.d/immortal.yml b/rc.d/immortal.yml index f4a5477..9013888 100644 --- a/rc.d/immortal.yml +++ b/rc.d/immortal.yml @@ -1 +1,2 @@ -cmd: /usr/local/bin/mai -f /usr/local/etc/mai/mai.ini +cmd: /usr/local/bin/mai -f /usr/local/etc/mai/mai.ini -g www -u www +cwd: /usr/local/share/mai diff --git a/views/index.html b/views/index.html index f0357a1..89b3a77 100644 --- a/views/index.html +++ b/views/index.html @@ -127,8 +127,10 @@