|
@@ -23,7 +23,6 @@ import (
|
|
|
"flag"
|
|
"flag"
|
|
|
"io"
|
|
"io"
|
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
|
- "log"
|
|
|
|
|
"os"
|
|
"os"
|
|
|
"os/signal"
|
|
"os/signal"
|
|
|
"runtime/pprof"
|
|
"runtime/pprof"
|
|
@@ -50,42 +49,56 @@ func main() {
|
|
|
|
|
|
|
|
flag.Parse()
|
|
flag.Parse()
|
|
|
|
|
|
|
|
|
|
+ // Initialize default Notice output (stderr)
|
|
|
|
|
+
|
|
|
|
|
+ var noticeWriter io.Writer
|
|
|
|
|
+ noticeWriter = os.Stderr
|
|
|
|
|
+ if formatNotices {
|
|
|
|
|
+ noticeWriter = psiphon.NewNoticeConsoleRewriter(noticeWriter)
|
|
|
|
|
+ }
|
|
|
|
|
+ psiphon.SetNoticeOutput(noticeWriter)
|
|
|
|
|
+
|
|
|
// Handle required config file parameter
|
|
// Handle required config file parameter
|
|
|
|
|
|
|
|
if configFilename == "" {
|
|
if configFilename == "" {
|
|
|
- log.Fatalf("configuration file is required")
|
|
|
|
|
|
|
+ psiphon.NoticeError("configuration file is required")
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
configFileContents, err := ioutil.ReadFile(configFilename)
|
|
configFileContents, err := ioutil.ReadFile(configFilename)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error loading configuration file: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error loading configuration file: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
config, err := psiphon.LoadConfig(configFileContents)
|
|
config, err := psiphon.LoadConfig(configFileContents)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error processing configuration file: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error processing configuration file: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Initialize notice output; use logfile, if configured
|
|
|
|
|
|
|
+ // When a logfile is configured, reinitialize Notice output
|
|
|
|
|
|
|
|
- var noticeWriter io.Writer
|
|
|
|
|
- noticeWriter = os.Stderr
|
|
|
|
|
if config.LogFilename != "" {
|
|
if config.LogFilename != "" {
|
|
|
logFile, err := os.OpenFile(config.LogFilename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
|
|
logFile, err := os.OpenFile(config.LogFilename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error opening log file: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error opening log file: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
defer logFile.Close()
|
|
defer logFile.Close()
|
|
|
|
|
+ var noticeWriter io.Writer
|
|
|
|
|
+ noticeWriter = logFile
|
|
|
|
|
+ if formatNotices {
|
|
|
|
|
+ noticeWriter = psiphon.NewNoticeConsoleRewriter(noticeWriter)
|
|
|
|
|
+ }
|
|
|
|
|
+ psiphon.SetNoticeOutput(noticeWriter)
|
|
|
}
|
|
}
|
|
|
- if formatNotices {
|
|
|
|
|
- noticeWriter = psiphon.NewNoticeConsoleRewriter(noticeWriter)
|
|
|
|
|
- }
|
|
|
|
|
- psiphon.SetNoticeOutput(noticeWriter)
|
|
|
|
|
|
|
|
|
|
// Handle optional profiling parameter
|
|
// Handle optional profiling parameter
|
|
|
|
|
|
|
|
if profileFilename != "" {
|
|
if profileFilename != "" {
|
|
|
profileFile, err := os.Create(profileFilename)
|
|
profileFile, err := os.Create(profileFilename)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error opening profile file: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error opening profile file: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
pprof.StartCPUProfile(profileFile)
|
|
pprof.StartCPUProfile(profileFile)
|
|
|
defer pprof.StopCPUProfile()
|
|
defer pprof.StopCPUProfile()
|
|
@@ -95,7 +108,8 @@ func main() {
|
|
|
|
|
|
|
|
err = psiphon.InitDataStore(config)
|
|
err = psiphon.InitDataStore(config)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error initializing datastore: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error initializing datastore: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Handle optional embedded server list file parameter
|
|
// Handle optional embedded server list file parameter
|
|
@@ -105,18 +119,21 @@ func main() {
|
|
|
if embeddedServerEntryListFilename != "" {
|
|
if embeddedServerEntryListFilename != "" {
|
|
|
serverEntryList, err := ioutil.ReadFile(embeddedServerEntryListFilename)
|
|
serverEntryList, err := ioutil.ReadFile(embeddedServerEntryListFilename)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error loading embedded server entry list file: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error loading embedded server entry list file: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
// TODO: stream embedded server list data? also, the cast makaes an unnecessary copy of a large buffer?
|
|
// TODO: stream embedded server list data? also, the cast makaes an unnecessary copy of a large buffer?
|
|
|
serverEntries, err := psiphon.DecodeAndValidateServerEntryList(string(serverEntryList))
|
|
serverEntries, err := psiphon.DecodeAndValidateServerEntryList(string(serverEntryList))
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error decoding embedded server entry list file: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error decoding embedded server entry list file: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
// Since embedded server list entries may become stale, they will not
|
|
// Since embedded server list entries may become stale, they will not
|
|
|
// overwrite existing stored entries for the same server.
|
|
// overwrite existing stored entries for the same server.
|
|
|
err = psiphon.StoreServerEntries(serverEntries, false)
|
|
err = psiphon.StoreServerEntries(serverEntries, false)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error storing embedded server entry list data: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error storing embedded server entry list data: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -124,7 +141,8 @@ func main() {
|
|
|
|
|
|
|
|
controller, err := psiphon.NewController(config)
|
|
controller, err := psiphon.NewController(config)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("error creating controller: %s", err)
|
|
|
|
|
|
|
+ psiphon.NoticeError("error creating controller: %s", err)
|
|
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
controllerStopSignal := make(chan struct{}, 1)
|
|
controllerStopSignal := make(chan struct{}, 1)
|