-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
139 lines (118 loc) · 3.79 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//go:generate rice embed-go
package main
import (
"errors"
"flag"
"fmt"
"log"
"os"
"os/signal"
rice "github.com/GeertJohan/go.rice"
"github.com/nicksnyder/go-i18n/i18n"
)
var (
appName = "obijudge"
appVersion = "testing"
appBuild = "testing"
appInfo = "Created by Gabriel Simões ([email protected])"
appHelp = "Usage: %s run OR builddb OR info\nAppend -h or --help to display general or subcommand usage\n"
appErrorMessage = "[OBIJUDGE] "
testingFlag bool
)
func main() {
runCommand := flag.NewFlagSet("run", flag.ExitOnError)
builddbCommand := flag.NewFlagSet("builddb", flag.ExitOnError)
portPtr := runCommand.Int("port", 80, "Port where interface will listen (localhost-only")
referencePtr := runCommand.String("reference", "reference.zip", "File where language reference is stored")
workersPtr := runCommand.Int("workers", 2, "Number of simultaneous judge workers")
localePtr := runCommand.String("locale", "en-US", "Default localization to use in web interface")
contestsFolderPtr := runCommand.String("contestsfolder", "/obicontests", "Folder to store contests uploaded by users")
runCommand.BoolVar(&testingFlag, "testing", false, "Whether to use testing features or not (no authentication, reads password from ./pass file, uses judge_test as the contest, uses testing cookies session, prints debug messages)")
sourcePtr := builddbCommand.String("source", "contest", "Folder where contests data is located")
targetPtr := builddbCommand.String("target", "contest.zip", "File where the database will be created (erases if already exists)")
passwordPtr := builddbCommand.String("password", "", "16 letters password to encrypt database (will generate one if empty)")
writePasswordPtr := builddbCommand.Bool("writepassword", false, "Write password to ./pass file.")
if len(os.Args) < 2 {
fmt.Printf(appHelp, os.Args[0])
os.Exit(0)
}
switch os.Args[1] {
case "run":
runCommand.Parse(os.Args[2:])
case "builddb":
builddbCommand.Parse(os.Args[2:])
case "info":
fmt.Println(appName, "version", appVersion)
fmt.Println(appInfo)
case "-h":
fmt.Printf(appHelp, os.Args[0])
case "--help":
fmt.Printf(appHelp, os.Args[0])
default:
fmt.Printf(appHelp, os.Args[0])
}
logger := log.New(os.Stderr, appErrorMessage, log.Ltime)
if runCommand.Parsed() {
err := func() error {
if os.Geteuid() != 0 {
return errors.New("Must be run as root")
}
if os.Getegid() != 0 {
return errors.New("Must be run as root group")
}
// setup folders
os.RemoveAll(*contestsFolderPtr)
if err := os.MkdirAll(*contestsFolderPtr, 0777); err != nil {
return err
}
// setup translations
localesBox := rice.MustFindBox("locales")
if err := localesBox.Walk("", func(path string, info os.FileInfo, _ error) error {
if path == "" {
return nil
}
localeBytes, err := localesBox.Bytes(path)
if err != nil {
return err
}
return i18n.ParseTranslationFileBytes(path, localeBytes)
}); err != nil {
return err
}
ref, err := OpenReference(*referencePtr)
if err != nil {
return err
}
judge := &Judge{NumWorkers: *workersPtr}
judge.Start()
defer judge.Stop()
server := &Server{
Port: *portPtr,
DatabasePath: *contestsFolderPtr,
Reference: ref,
Judge: judge,
Logger: logger,
DefaultLocale: *localePtr,
}
if err := server.Start(); err != nil {
return err
}
defer server.Stop()
stopChan := make(chan os.Signal, 1)
signal.Notify(stopChan, os.Interrupt)
select {
case <-stopChan:
}
return nil
}()
if err != nil {
logger.Print(err)
}
}
if builddbCommand.Parsed() {
err := BuildDatabase(*sourcePtr, *targetPtr, []byte(*passwordPtr), *writePasswordPtr)
if err != nil {
logger.Fatal(err)
}
}
}