aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/qchat/main.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/cmd/qchat/main.go b/cmd/qchat/main.go
new file mode 100644
index 0000000..0e28ab5
--- /dev/null
+++ b/cmd/qchat/main.go
@@ -0,0 +1,93 @@
+package main
+
+import (
+ "context"
+ "encoding/pem"
+ "errors"
+ "flag"
+ "fmt"
+ "log/slog"
+ "os"
+ "os/signal"
+
+ "go.neonxp.ru/qchat/internal/chat"
+ "go.neonxp.ru/qchat/internal/config"
+ "go.neonxp.ru/qchat/internal/server"
+ "golang.org/x/crypto/ed25519"
+ "golang.org/x/crypto/ssh"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ configFile = flag.String("config", "./config.json", "Config file")
+ debug = flag.Bool("debug", false, "Debug mode")
+ version string
+)
+
+func main() {
+ flag.Parse()
+ if *configFile == "" {
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
+ defer cancel()
+
+ slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{})))
+ if *debug {
+ slog.SetLogLoggerLevel(slog.LevelDebug)
+ }
+
+ slog.InfoContext(ctx, "qChat by NeonXP. https://neonxp.ru/", slog.String("version", version))
+
+ cfg, err := config.Load(*configFile)
+ if err != nil && !errors.Is(err, os.ErrNotExist) {
+ panic(err)
+ }
+ if err != nil {
+ hostname, err := os.Hostname()
+ if err != nil {
+ panic(err)
+ }
+ _, privKey, err := ed25519.GenerateKey(nil)
+ if err != nil {
+ panic(err)
+ }
+
+ privateKeyOpenSSH, err := ssh.MarshalPrivateKey(privKey, "")
+ if err != nil {
+ panic(fmt.Sprintf("Failed to marshal private key: %v", err))
+ }
+
+ cfg = &config.Config{
+ Server: config.Server{
+ PrivateKey: string(pem.EncodeToMemory(privateKeyOpenSSH)),
+ Addr: ":1337",
+ Name: hostname,
+ },
+ Channels: []config.Channel{
+ {Name: "main"},
+ },
+ }
+
+ slog.InfoContext(ctx, "no config file. creating new.", slog.String("config", *configFile))
+ if err := config.Save(*configFile, cfg); err != nil {
+ panic(err)
+ }
+ }
+
+ ch := chat.New(cfg)
+
+ serv := server.New(cfg, ch)
+
+ eg, ectx := errgroup.WithContext(ctx)
+
+ eg.Go(func() error { return ch.Run(ectx) })
+
+ eg.Go(func() error { return serv.Run(ectx) })
+
+ if err := eg.Wait(); err != nil {
+ panic(err)
+ }
+}