all repos — honk @ c49b59dc8956fd6bea51e422e124d52945017183

my fork of honk

main.go (view raw)

  1//
  2// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com>
  3//
  4// Permission to use, copy, modify, and distribute this software for any
  5// purpose with or without fee is hereby granted, provided that the above
  6// copyright notice and this permission notice appear in all copies.
  7//
  8// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15
 16package main
 17
 18import (
 19	"flag"
 20	"fmt"
 21	"html/template"
 22	golog "log"
 23	"log/syslog"
 24	notrand "math/rand"
 25	"os"
 26	"runtime/pprof"
 27	"time"
 28
 29	"humungus.tedunangst.com/r/webs/log"
 30)
 31
 32var softwareVersion = "develop"
 33
 34func init() {
 35	notrand.Seed(time.Now().Unix())
 36}
 37
 38var serverName string
 39var serverPrefix string
 40var masqName string
 41var dataDir = "."
 42var viewDir = "."
 43var iconName = "icon.png"
 44var serverMsg template.HTML
 45var aboutMsg template.HTML
 46var loginMsg template.HTML
 47
 48func serverURL(u string, args ...interface{}) string {
 49	return fmt.Sprintf("https://"+serverName+u, args...)
 50}
 51
 52func ElaborateUnitTests() {
 53	user, _ := butwhatabout("test")
 54	syndicate(user, "https://mastodon.social/tags/mastoadmin.rss")
 55}
 56
 57func unplugserver(hostname string) {
 58	db := opendatabase()
 59	xid := fmt.Sprintf("https://%s", hostname)
 60	db.Exec("delete from honkers where xid = ? and flavor = 'dub'", xid)
 61	db.Exec("delete from doovers where rcpt = ?", xid)
 62	xid += "/%"
 63	db.Exec("delete from honkers where xid like ? and flavor = 'dub'", xid)
 64	db.Exec("delete from doovers where rcpt like ?", xid)
 65}
 66
 67func reexecArgs(cmd string) []string {
 68	args := []string{"-datadir", dataDir}
 69	args = append(args, log.Args()...)
 70	args = append(args, cmd)
 71	return args
 72}
 73
 74var elog, ilog, dlog *golog.Logger
 75
 76func errx(msg string, args ...interface{}) {
 77	fmt.Fprintf(os.Stderr, msg+"\n", args...)
 78	os.Exit(1)
 79}
 80
 81var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
 82var memprofile = flag.String("memprofile", "", "write memory profile to this file")
 83var memprofilefd *os.File
 84
 85func main() {
 86	flag.StringVar(&dataDir, "datadir", dataDir, "data directory")
 87	flag.StringVar(&viewDir, "viewdir", viewDir, "view directory")
 88	flag.Usage = func() {
 89		flag.PrintDefaults()
 90		helpText := "\n  available honk commands:\n"
 91		for n, c := range commands {
 92			helpText += fmt.Sprintf("    %s: %s\n", n, c.help)
 93		}
 94
 95		fmt.Fprint(flag.CommandLine.Output(), helpText)
 96	}
 97
 98	flag.Parse()
 99	if *cpuprofile != "" {
100		f, err := os.Create(*cpuprofile)
101		if err != nil {
102			errx("can't open cpu profile: %s", err)
103		}
104		pprof.StartCPUProfile(f)
105	}
106	if *memprofile != "" {
107		f, err := os.Create(*memprofile)
108		if err != nil {
109			errx("can't open mem profile: %s", err)
110		}
111		memprofilefd = f
112	}
113
114	log.Init(log.Options{Progname: "honk", Facility: syslog.LOG_UUCP})
115	elog = log.E
116	ilog = log.I
117	dlog = log.D
118
119	if os.Geteuid() == 0 {
120		elog.Fatalf("do not run honk as root")
121	}
122
123	args := flag.Args()
124	cmd := "run"
125	if len(args) > 0 {
126		cmd = args[0]
127	}
128	switch cmd {
129	case "init":
130		commands["init"].callback(args)
131	case "upgrade":
132		commands["upgrade"].callback(args)
133	case "version":
134		commands["version"].callback(args)
135	}
136	db := opendatabase()
137	dbversion := 0
138	getconfig("dbversion", &dbversion)
139	if dbversion != myVersion {
140		elog.Fatal("incorrect database version. run upgrade.")
141	}
142	getconfig("servermsg", &serverMsg)
143	getconfig("aboutmsg", &aboutMsg)
144	getconfig("loginmsg", &loginMsg)
145	getconfig("servername", &serverName)
146	getconfig("masqname", &masqName)
147	if masqName == "" {
148		masqName = serverName
149	}
150	serverPrefix = serverURL("/")
151	getconfig("usersep", &userSep)
152	getconfig("honksep", &honkSep)
153	getconfig("devel", &develMode)
154	if develMode {
155		gogglesDoNothing()
156	}
157	getconfig("fasttimeout", &fastTimeout)
158	getconfig("slowtimeout", &slowTimeout)
159	getconfig("honkwindow", &honkwindow)
160	honkwindow *= 24 * time.Hour
161
162	prepareStatements(db)
163
164	c, ok := commands[cmd]
165	if !ok {
166		errx("don't know about %q", cmd)
167	}
168
169	c.callback(args)
170}