1 bcf3fb81 2023-08-16 continue /** Parse command line arguments */
3 bcf3fb81 2023-08-16 continue #include "args.h"
4 bcf3fb81 2023-08-16 continue #include "error.h"
6 bcf3fb81 2023-08-16 continue #include <unistd.h>
7 bcf3fb81 2023-08-16 continue #include <fcntl.h>
10 bcf3fb81 2023-08-16 continue namespace vostok
12 bcf3fb81 2023-08-16 continue namespace
15 bcf3fb81 2023-08-16 continue /** Print usage and return false */
16 bcf3fb81 2023-08-16 continue bool usage(const char *program)
18 bcf3fb81 2023-08-16 continue const char *file_name = strrchr(program, '/');
19 bcf3fb81 2023-08-16 continue if (!file_name)
20 bcf3fb81 2023-08-16 continue file_name = program;
22 bcf3fb81 2023-08-16 continue ++file_name;
24 bcf3fb81 2023-08-16 continue error::g_log << "Usage: " << file_name << " [OPTS]" << std::endl << std::endl;
25 bcf3fb81 2023-08-16 continue error::g_log << "OPTS may be: " << std::endl;
26 bcf3fb81 2023-08-16 continue error::g_log << "\t-a ADDR : listening network address (127.0.0.1 by default)" << std::endl;
27 bcf3fb81 2023-08-16 continue error::g_log << "\t-p PORT : TCP/IP port number (1965 by default)" << std::endl;
28 bcf3fb81 2023-08-16 continue error::g_log << "\t-c FILE : Server certificate file [REQUIRED]" << std::endl;
29 bcf3fb81 2023-08-16 continue error::g_log << "\t-k FILE : Server key file [REQUIRED]" << std::endl;
30 bcf3fb81 2023-08-16 continue error::g_log << "\t-f PATH : Path to file system data [REQUIRED]" << std::endl;
31 e0af76a7 2023-09-05 continue error::g_log << "\t-m FILE : Path to file mime.types" << std::endl;
32 3304ae77 2024-07-06 continue error::g_log << "\t-g PATH : VGI (CGI-like) path prefix (case sensitive, without normalization)" << std::endl;
33 a2471084 2024-07-06 continue error::g_log << "\t-e CMD : VGI (CGI-like) command" << std::endl;
35 bcf3fb81 2023-08-16 continue return false;
38 bcf3fb81 2023-08-16 continue } // namespace <unnamed>
42 d6e3180e 2023-08-30 continue parse_command_line_arguments(
43 d6e3180e 2023-08-30 continue /* in */ int argc,
44 d6e3180e 2023-08-30 continue /* in */ char *argv[],
45 d6e3180e 2023-08-30 continue /* out */ CommandLineArguments &args
49 bcf3fb81 2023-08-16 continue char *p = nullptr;
50 3304ae77 2024-07-06 continue while ((ch = getopt(argc, argv, "a:p:c:k:f:m:g:e:")) != -1) {
51 bcf3fb81 2023-08-16 continue switch (ch) {
52 bcf3fb81 2023-08-16 continue case 'a':
53 d6e3180e 2023-08-30 continue args.addr = optarg;
55 bcf3fb81 2023-08-16 continue case 'p':
56 bcf3fb81 2023-08-16 continue p = nullptr;
57 d6e3180e 2023-08-30 continue args.port = std::strtoul(optarg, &p, 10);
58 d6e3180e 2023-08-30 continue if (!args.port)
60 bcf3fb81 2023-08-16 continue error::g_log << "Invalid PORT value: " << optarg << std::endl;
61 bcf3fb81 2023-08-16 continue return usage(argv[0]);
64 bcf3fb81 2023-08-16 continue case 'c':
65 d6e3180e 2023-08-30 continue args.cert_file = optarg;
67 bcf3fb81 2023-08-16 continue case 'k':
68 d6e3180e 2023-08-30 continue args.key_file = optarg;
70 bcf3fb81 2023-08-16 continue case 'f':
71 d6e3180e 2023-08-30 continue args.directory.reset(open(optarg, O_RDONLY));
72 d6e3180e 2023-08-30 continue if (!args.directory)
74 bcf3fb81 2023-08-16 continue error::occurred(
77 bcf3fb81 2023-08-16 continue error::g_log << "Open directory \"" << optarg << "\"";
79 d6e3180e 2023-08-30 continue error::Print{}
81 bcf3fb81 2023-08-16 continue return false;
84 e0af76a7 2023-09-05 continue case 'm':
85 e0af76a7 2023-09-05 continue if (!args.mime.parse_db(optarg))
86 e0af76a7 2023-09-05 continue return false;
88 01105a54 2024-07-04 continue case 'g':
89 3304ae77 2024-07-06 continue args.vgi_prefix = Span<const char>{optarg, strlen(optarg)};
91 3304ae77 2024-07-06 continue case 'e':
92 3304ae77 2024-07-06 continue args.vgi_command = optarg;
95 bcf3fb81 2023-08-16 continue default:
96 bcf3fb81 2023-08-16 continue return usage(argv[0]);
99 d6e3180e 2023-08-30 continue if (!args.cert_file)
101 bcf3fb81 2023-08-16 continue error::g_log << "Invalid command line: -c option required" << std::endl;
102 bcf3fb81 2023-08-16 continue return usage(argv[0]);
104 d6e3180e 2023-08-30 continue if (!args.key_file)
106 bcf3fb81 2023-08-16 continue error::g_log << "Invalid command line: -k option required" << std::endl;
107 bcf3fb81 2023-08-16 continue return usage(argv[0]);
109 d6e3180e 2023-08-30 continue if (!args.directory)
111 bcf3fb81 2023-08-16 continue error::g_log << "Invalid command line: -d option required" << std::endl;
112 bcf3fb81 2023-08-16 continue return usage(argv[0]);
114 3304ae77 2024-07-06 continue if ( (args.vgi_prefix.size() && !args.vgi_command) ||
115 3304ae77 2024-07-06 continue (!args.vgi_prefix.size() && args.vgi_command) )
117 3304ae77 2024-07-06 continue error::g_log << "Invalid command line: options -g and -e can only be specified together" << std::endl;
118 3304ae77 2024-07-06 continue return usage(argv[0]);
120 bcf3fb81 2023-08-16 continue return true;
124 bcf3fb81 2023-08-16 continue } // namespace vostok