cli.go (3810B)
1 /* 2 Copyright 2021 Mark Wilkerson 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program. If not, see <https://www.gnu.org/licenses/> 15 */ 16 package main 17 18 import ( 19 "fmt" 20 "io" 21 "os" 22 23 flag "github.com/spf13/pflag" 24 25 "markhuge.com/donate" 26 ) 27 28 type options struct { 29 BindAddr, NameSpace, Dest string 30 Port int 31 Debug bool 32 SSLCert string 33 SSLKeyFile string 34 } 35 36 func Init() options { 37 var opts options 38 39 flags := flag.NewFlagSet(os.Args[0], flag.ExitOnError) 40 41 flags.StringVarP(&opts.Dest, "dest", "d", "", "Destination URI. Ex: https://git.markhuge.com") 42 flags.IntVarP(&opts.Port, "port", "p", 0, "Port to listen on") 43 flags.StringVar(&opts.BindAddr, "bind", "0.0.0.0", "Optional bind address") 44 flags.StringVarP(&opts.NameSpace, "namespace", "n", "", "Optional namespace Ex: markhuge.com. Default is the host in the request header") 45 flags.BoolVar(&opts.Debug, "verbose", false, "Verbose logging") 46 47 flags.StringVar(&opts.SSLCert, "ssl-cert", "", "Path to fully concatinated SSL certificate. Used optionally to enable SSL and serve HTTPS. (--ssl-key is also required with this option)") 48 flags.StringVar(&opts.SSLKeyFile, "ssl-key", "", "Path to SSL Keyfile (ex: key.pem). Used in conjunction with --ssl-cert") 49 50 askedForVersion := flags.Bool("v", false, "Print version") 51 askedForHelp := flags.BoolP("help", "h", false, "Print this help") 52 donationType := flags.String("donate", "", "Display QR code to donate to the project. possible values: btc, xmr, eth") 53 54 flags.SortFlags = false 55 flags.Usage = usage(os.Stderr, flags) 56 57 err := flags.Parse(os.Args[1:]) 58 59 if err != nil { 60 flags.Usage() 61 os.Exit(1) 62 } 63 64 if flags.Lookup("donate").Changed { 65 switch *donationType { 66 case "xmr": 67 fmt.Println(donate.XMR.QRCode) 68 os.Exit(0) 69 case "eth": 70 fmt.Println(donate.ETH.QRCode) 71 os.Exit(0) 72 case "btc": 73 fmt.Println(donate.BTC.QRCode) 74 os.Exit(0) 75 default: 76 flags.Usage() 77 os.Exit(1) 78 79 } 80 81 } 82 83 if *askedForVersion { 84 fmt.Printf("vanity v%s\n", VERSION) 85 os.Exit(0) 86 } 87 88 if *askedForHelp { 89 usage(os.Stdout, flags)() 90 os.Exit(0) 91 } 92 93 // Ensure both ssl keys have the same state 94 if flags.Lookup("ssl-cert").Changed != flags.Lookup("ssl-key").Changed { 95 flags.Usage() 96 os.Exit(1) 97 } 98 99 if flags.Lookup("ssl-cert").Changed && flags.Lookup("ssl-key").Changed { 100 if len(opts.SSLCert) == 0 || len(opts.SSLKeyFile) == 0 { 101 flags.Usage() 102 os.Exit(1) 103 } 104 } 105 106 if len(opts.Dest) == 0 || opts.Port == 0 { 107 flags.Usage() 108 os.Exit(1) 109 } 110 return opts 111 } 112 113 // This is me being a pedant about help output going to Stdout but 114 // incorrect syntax going to Stderr 115 func usage(w io.Writer, f *flag.FlagSet) func() { 116 return func() { 117 fmt.Fprintf(w, versionFmt, VERSION) 118 fmt.Fprint(w, f.FlagUsages()) 119 fmt.Fprintf(w, footer, donate.XMR, donate.BTC, donate.ETH) 120 } 121 } 122 123 const versionFmt = "vanity v%s - A tiny server for golang vanity redirects\n\nUsage: vanity -d <destination URI>\n\n" 124 125 const footer = ` 126 127 Copyright 2021 Mark Wilkerson <mark@markhuge.com> 128 This is free software licensed under the GPLv3 <https://www.gnu.org/licenses/> 129 130 Source: https://git.markhuge.com/vanity 131 Bugs: bugs@markhuge.com 132 Patches: patches@markhuge.com 133 134 Donate to this project: 135 Monero (XMR): %s 136 Bitcoin (BTC): %s 137 Ethereum (ETH): %s 138 139 `