1 /*        $NetBSD: cmd_args.c,v 1.8 2024/08/18 20:47:17 christos Exp $          */
2 
3 /*
4  * cmd_args.c = command-line argument processing
5  */
6 #ifdef HAVE_CONFIG_H
7 # include <config.h>
8 #endif
9 
10 #include "ntpd.h"
11 #include "ntp_stdlib.h"
12 #include "ntp_config.h"
13 #include "ntp_cmdargs.h"
14 
15 #include "ntpd-opts.h"
16 
17 /*
18  * Definitions of things either imported from or exported to outside
19  */
20 extern char const *progname;
21 
22 #ifdef HAVE_NETINFO
23 extern int          check_netinfo;
24 #endif
25 
26 
27 /*
28  * getCmdOpts - apply most command line options
29  *
30  * A few options are examined earlier in ntpd.c ntpdmain() and
31  * ports/winnt/ntpd/ntservice.c main().
32  */
33 void
getCmdOpts(int argc,char ** argv)34 getCmdOpts(
35           int       argc,
36           char **   argv
37           )
38 {
39           extern const char *config_file;
40           int errflg;
41 
42           /*
43            * Initialize, initialize
44            */
45           errflg = 0;
46 
47           if (ipv4_works && ipv6_works) {
48                     if (HAVE_OPT( IPV4 ))
49                               ipv6_works = 0;
50                     else if (HAVE_OPT( IPV6 ))
51                               ipv4_works = 0;
52           } else if (!ipv4_works && !ipv6_works) {
53                     msyslog(LOG_ERR, "Neither IPv4 nor IPv6 networking detected, fatal.");
54                     exit(1);
55           } else if (HAVE_OPT( IPV4 ) && !ipv4_works)
56                     msyslog(LOG_WARNING, "-4/--ipv4 ignored, IPv4 networking not found.");
57           else if (HAVE_OPT( IPV6 ) && !ipv6_works)
58                     msyslog(LOG_WARNING, "-6/--ipv6 ignored, IPv6 networking not found.");
59 
60           if (HAVE_OPT( AUTHREQ ))
61                     proto_config(PROTO_AUTHENTICATE, 1, 0., NULL);
62           else if (HAVE_OPT( AUTHNOREQ ))
63                     proto_config(PROTO_AUTHENTICATE, 0, 0., NULL);
64 
65           if (HAVE_OPT( BCASTSYNC ))
66                     proto_config(PROTO_BROADCLIENT, 1, 0., NULL);
67 
68           if (HAVE_OPT( CONFIGFILE )) {
69                     config_file = OPT_ARG( CONFIGFILE );
70 #ifdef HAVE_NETINFO
71                     check_netinfo = 0;
72 #endif
73           }
74 
75           if (HAVE_OPT( DRIFTFILE ))
76               stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE ), 1);
77 
78           if (HAVE_OPT( PANICGATE ))
79                     allow_panic = TRUE;
80 
81           if (HAVE_OPT( FORCE_STEP_ONCE ))
82                     force_step_once = TRUE;
83 
84 #ifdef HAVE_DROPROOT
85           if (HAVE_OPT( JAILDIR )) {
86                     droproot = 1;
87                     chrootdir = OPT_ARG( JAILDIR );
88           }
89 #endif
90 
91           if (HAVE_OPT( KEYFILE ))
92                     getauthkeys(OPT_ARG( KEYFILE ));
93 
94           if (HAVE_OPT( PIDFILE ))
95               stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE ), 1);
96 
97           if (HAVE_OPT( QUIT ))
98                     mode_ntpdate = TRUE;
99 
100           if (HAVE_OPT( PROPAGATIONDELAY ))
101                     do {
102                               double tmp;
103                               const char *my_ntp_optarg = OPT_ARG( PROPAGATIONDELAY );
104 
105                               if (sscanf(my_ntp_optarg, "%lf", &tmp) != 1) {
106                                         msyslog(LOG_ERR,
107                                                   "command line broadcast delay value %s undecodable",
108                                                   my_ntp_optarg);
109                               } else {
110                                         proto_config(PROTO_BROADDELAY, 0, tmp, NULL);
111                               }
112                     } while (0);
113 
114           if (HAVE_OPT( STATSDIR ))
115               stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR ), 1);
116 
117           if (HAVE_OPT( TRUSTEDKEY )) {
118                     int                 ct = STACKCT_OPT(  TRUSTEDKEY );
119                     const char**        pp = STACKLST_OPT( TRUSTEDKEY );
120 
121                     do  {
122                               u_long tkey;
123                               const char* p = *pp++;
124 
125                               tkey = (int)atol(p);
126                               if (tkey == 0 || tkey > NTP_MAXKEY) {
127                                         msyslog(LOG_ERR,
128                                             "command line trusted key %s is invalid",
129                                             p);
130                               } else {
131                                         authtrust(tkey, 1);
132                               }
133                     } while (--ct > 0);
134           }
135 
136 #ifdef HAVE_DROPROOT
137           if (HAVE_OPT( USER )) {
138                     droproot = 1;
139                     user = estrdup(OPT_ARG( USER ));
140                     group = strrchr(user, ':');
141                     if (group != NULL) {
142                               size_t    len;
143 
144                               *group++ = '\0'; /* get rid of the ':' */
145                               len = group - user;
146                               group = estrdup(group);
147                               user = erealloc(user, len);
148                     }
149           }
150 #endif
151 
152           if (HAVE_OPT( VAR )) {
153                     int                 ct;
154                     const char **       pp;
155                     const char *        v_assign;
156 
157                     ct = STACKCT_OPT(  VAR );
158                     pp = STACKLST_OPT( VAR );
159 
160                     do  {
161                               v_assign = *pp++;
162                               set_sys_var(v_assign, strlen(v_assign) + 1, RW);
163                     } while (--ct > 0);
164           }
165 
166           if (HAVE_OPT( DVAR )) {
167                     int                 ct = STACKCT_OPT(  DVAR );
168                     const char**        pp = STACKLST_OPT( DVAR );
169 
170                     do  {
171                               const char* my_ntp_optarg = *pp++;
172 
173                               set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1,
174                                   (u_short) (RW | DEF));
175                     } while (--ct > 0);
176           }
177 
178           if (HAVE_OPT( SLEW ))
179                     loop_config(LOOP_MAX, 600);
180 
181           if (HAVE_OPT( UPDATEINTERVAL )) {
182                     long val = OPT_VALUE_UPDATEINTERVAL;
183                     const char errfmt[] =
184                               "-U/--updateinterval %ld must be >= 0\n";
185 
186                     if (val >= 0) {
187                               endpt_scan_period = val;
188                     } else {
189                               fprintf(stderr, errfmt, val);
190                               msyslog(LOG_ERR, errfmt, val);
191                               errflg++;
192                     }
193           }
194 
195 
196           /* save list of servers from cmd line for config_peers() use */
197           if (argc > 0) {
198                     cmdline_server_count = argc;
199                     cmdline_servers = argv;
200           }
201 
202           /* display usage & exit with any option processing errors */
203           if (errflg)
204                     optionUsage(&ntpdOptions, 2); /* does not return */
205 }
206