QDNix
Quick’n’dirty *NIX
main.c
1 #include <netinet/in.h>
2 #include <openssl/prov_ssl.h>
3 #include <openssl/types.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdint.h>
8 #include <unistd.h>
9 #include <signal.h>
10 #include <sys/socket.h>
11 #include <arpa/inet.h>
12 #include <sys/select.h>
13 #include <openssl/ssl.h>
14 #include <openssl/err.h>
15 
16 #include "geminid.h"
17 
18 #define IS_OPTARG(a, s, l) a[1] == s || \
19  strcmp(a + 1, "-" l) == 0
20 
21 static const char *prg_name;
22 static uint16_t srv_port = 1965;
23 static const char *cert_file = "cert.pem";
24 static const char *key_file = "key.pem";
25 static const char *srv_dir = "/var/gemini";
26 
27 static void
28 version(void)
29 {
30  printf("%s v%s\n", prg_name, GEMINID_VERSION);
31  printf("Copyright (C) 2023 d0p1\n");
32  printf("License BSD-3: <https://directory.fsf.org/wiki/License:BSD-3-Clause>\n");
33  printf("This is free software: you are free to change and redistribute it.\n");
34  printf("There is NO WARRANTY, to the extent permitted by law.\n");
35  exit(EXIT_SUCCESS);
36 }
37 
38 static void
39 usage(int retval)
40 {
41  printf("Usage: %s [OPTION]... [DIR]\n\n", prg_name);
42  printf("Arguments:\n");
43  printf("\tDIR\t\tGemini page directory (default: %s)\n", srv_dir);
44  printf("Options:\n");
45  printf("\t-h, --help\tdisplay this help and exit\n");
46  printf("\t-V, --version\toutput version information and exit\n");
47  printf("\t-p,--port PORT\tListen port (default: %u)\n", srv_port);
48  printf("\t-c,--cert FILE\t(default: %s)\n", cert_file);
49  printf("\t-k,--key FILE\t(default: %s)\n", key_file);
50  exit(retval);
51 }
52 
53 int
54 main(int argc, char *const argv[])
55 {
56  size_t idx;
57  /*
58  * QDNix will always provide argv[0] so we won't care about
59  * things like: CVE-2021-4034 and broken sys
60  */
61  prg_name = *argv++; /* save and skip program name */
62  argc--;
63 
64  tls_init();
65 
66  /* Ignore broken pipe signals */
67  signal(SIGPIPE, SIG_IGN);
68 
69  for (idx = 0; idx < argc; idx++)
70  {
71  if (argv[idx][0] == '-')
72  {
73  if (IS_OPTARG(argv[idx], 'h', "help"))
74  {
75  usage(EXIT_SUCCESS);
76  }
77  else if (IS_OPTARG(argv[idx], 'V', "version"))
78  {
79  version();
80  }
81  else
82  {
83  usage(EXIT_FAILURE);
84  }
85  }
86  else
87  {
88  break;
89  }
90  }
91 
92  server(srv_dir, srv_port, cert_file, key_file);
93 
94  return (EXIT_SUCCESS);
95 }