()
| 332 | } |
| 333 | |
| 334 | func main() { |
| 335 | executable, _ := os.Executable() |
| 336 | |
| 337 | logFlags := flag.String("log_flags", "stdFlags", |
| 338 | "Comma-separated list of log flags (as defined in https://golang.org/pkg/log/#pkg-constants without the L prefix)") |
| 339 | configfile := flag.String("config", "tinode.conf", "Path to config file.") |
| 340 | // Path to static content. |
| 341 | staticPath := flag.String("static_data", defaultStaticPath, "File path to directory with static files to be served.") |
| 342 | listenOn := flag.String("listen", "", "Override address and port to listen on for HTTP(S) clients.") |
| 343 | apiPath := flag.String("api_path", "", "Override the base URL path where API is served.") |
| 344 | listenGrpc := flag.String("grpc_listen", "", "Override address and port to listen on for gRPC clients.") |
| 345 | tlsEnabled := flag.Bool("tls_enabled", false, "Override config value for enabling TLS.") |
| 346 | clusterSelf := flag.String("cluster_self", "", "Override the name of the current cluster node.") |
| 347 | expvarPath := flag.String("expvar", "", "Override the URL path where runtime stats are exposed. Use '-' to disable.") |
| 348 | serverStatusPath := flag.String("server_status", "", |
| 349 | "Override the URL path where the server's internal status is displayed. Use '-' to disable.") |
| 350 | pprofFile := flag.String("pprof", "", "File name to save profiling info to. Disabled if not set.") |
| 351 | pprofUrl := flag.String("pprof_url", "", "Debugging only! URL path for exposing profiling info. Disabled if not set.") |
| 352 | flag.Parse() |
| 353 | |
| 354 | logs.Init(os.Stderr, *logFlags) |
| 355 | |
| 356 | curwd, err := os.Getwd() |
| 357 | if err != nil { |
| 358 | logs.Err.Fatal("Couldn't get current working directory: ", err) |
| 359 | } |
| 360 | |
| 361 | logs.Info.Printf("Server v%s:%s:%s; pid %d; %d process(es)", |
| 362 | currentVersion, executable, buildstamp, |
| 363 | os.Getpid(), runtime.GOMAXPROCS(runtime.NumCPU())) |
| 364 | |
| 365 | *configfile = toAbsolutePath(curwd, *configfile) |
| 366 | logs.Info.Printf("Using config from '%s'", *configfile) |
| 367 | |
| 368 | var config configType |
| 369 | if file, err := os.Open(*configfile); err != nil { |
| 370 | logs.Err.Fatal("Failed to read config file: ", err) |
| 371 | } else { |
| 372 | jr := jcr.New(file) |
| 373 | if err = json.NewDecoder(jr).Decode(&config); err != nil { |
| 374 | switch jerr := err.(type) { |
| 375 | case *json.UnmarshalTypeError: |
| 376 | lnum, cnum, _ := jr.LineAndChar(jerr.Offset) |
| 377 | logs.Err.Fatalf("Unmarshall error in config file in %s at %d:%d (offset %d bytes): %s", |
| 378 | jerr.Field, lnum, cnum, jerr.Offset, jerr.Error()) |
| 379 | case *json.SyntaxError: |
| 380 | lnum, cnum, _ := jr.LineAndChar(jerr.Offset) |
| 381 | logs.Err.Fatalf("Syntax error in config file at %d:%d (offset %d bytes): %s", |
| 382 | lnum, cnum, jerr.Offset, jerr.Error()) |
| 383 | default: |
| 384 | logs.Err.Fatal("Failed to parse config file: ", err) |
| 385 | } |
| 386 | } |
| 387 | file.Close() |
| 388 | } |
| 389 | |
| 390 | if *listenOn != "" { |
| 391 | config.Listen = *listenOn |
nothing calls this directly
no test coverage detected
searching dependent graphs…