123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // This file is subject to a 1-clause BSD license.
- // Its contents can be found in the enclosed LICENSE file.
- package main
- import (
- "flag"
- "fmt"
- "log"
- "os"
- "path/filepath"
- "notabug.org/mouz/bot/app"
- "notabug.org/mouz/bot/app/logger"
- "notabug.org/mouz/bot/irc"
- "notabug.org/mouz/bot/plugins"
- )
- func main() {
- // Parse command line arguments and load the bot profile.
- profile := parseArgs()
- // Write PID file. It may be needed by a process supervisor.
- writePid()
- // Create and run the bot.
- err := run(profile)
- if err != nil {
- log.Fatal("[bot]", err)
- }
- }
- // writePid writes a file with process' pid. This is used by supervisors.
- // like systemd to track the process state.
- func writePid() {
- fd, err := os.Create("app.pid")
- if err != nil {
- log.Println("[bot] Create PID file:", err)
- return
- }
- fmt.Fprintf(fd, "%d", os.Getpid())
- fd.Close()
- }
- // parseArgs parses and validates command line arguments.
- func parseArgs() irc.Profile {
- flag.Usage = func() {
- fmt.Println("usage:", os.Args[0], "[options] <profile directory>")
- flag.PrintDefaults()
- }
- newconf := flag.Bool("new", false, "Create a new, default configuration file and exit.")
- version := flag.Bool("version", false, "Display version information.")
- flag.Parse()
- if *version {
- fmt.Println(app.Version())
- os.Exit(0)
- }
- if flag.NArg() == 0 {
- flag.Usage()
- os.Exit(1)
- }
- // Read and validate the profile root directory.
- root, err := filepath.Abs(flag.Arg(0))
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- // Set root as current working directory.
- err = os.Chdir(root)
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- // Create a new bot profile instance.
- profile := irc.NewProfile(root)
- // If applicable, save a new, default profile and exit.
- if *newconf {
- err := profile.Save()
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- fmt.Println("New configuration saved.")
- fmt.Println("Please edit it and relaunch the program.")
- os.Exit(0)
- }
- // Load an existing profile.
- err = profile.Load()
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- return profile
- }
- // run creates a new connection to the server and begins processing
- // incoming messages and OS signals. This call will not return for as long
- // as the connection is active.
- func run(p irc.Profile) error {
- // Initialize the log and ensure it is properly stopped when we are done.
- logger.Init("logs")
- defer logger.Shutdown()
- log.Printf("[bot] Running %s version %d.%d.%s",
- app.Name, app.VersionMajor, app.VersionMinor, app.VersionRevision)
- defer log.Println("[bot] Shutting down")
- // Initialize plugins.
- plugins.Load(p)
- defer plugins.Unload(p)
- // Create te bot, open the connection and spin up the client's read loop
- // in a separate goroutine.
- var bot Bot
- bot.profile = p
- bot.client = NewClient(bot.PayloadHandler)
- return bot.Run()
- }
|