]> andersk Git - openssh.git/blob - servconf.c
- (djm) OpenBSD CVS updates
[openssh.git] / servconf.c
1 /*
2  *
3  * servconf.c
4  *
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  *
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  *
10  * Created: Mon Aug 21 15:48:58 1995 ylo
11  *
12  */
13
14 #include "includes.h"
15 RCSID("$OpenBSD: servconf.c,v 1.49 2000/07/14 22:59:46 markus Exp $");
16
17 #include "ssh.h"
18 #include "servconf.h"
19 #include "xmalloc.h"
20 #include "compat.h"
21
22 /* add listen address */
23 void add_listen_addr(ServerOptions *options, char *addr);
24
25 /* Initializes the server options to their default values. */
26
27 void
28 initialize_server_options(ServerOptions *options)
29 {
30         memset(options, 0, sizeof(*options));
31         options->num_ports = 0;
32         options->ports_from_cmdline = 0;
33         options->listen_addrs = NULL;
34         options->host_key_file = NULL;
35         options->host_dsa_key_file = NULL;
36         options->pid_file = NULL;
37         options->server_key_bits = -1;
38         options->login_grace_time = -1;
39         options->key_regeneration_time = -1;
40         options->permit_root_login = -1;
41         options->ignore_rhosts = -1;
42         options->ignore_user_known_hosts = -1;
43         options->print_motd = -1;
44         options->check_mail = -1;
45         options->x11_forwarding = -1;
46         options->x11_display_offset = -1;
47         options->xauth_location = NULL;
48         options->strict_modes = -1;
49         options->keepalives = -1;
50         options->log_facility = (SyslogFacility) - 1;
51         options->log_level = (LogLevel) - 1;
52         options->rhosts_authentication = -1;
53         options->rhosts_rsa_authentication = -1;
54         options->rsa_authentication = -1;
55         options->dsa_authentication = -1;
56 #ifdef KRB4
57         options->kerberos_authentication = -1;
58         options->kerberos_or_local_passwd = -1;
59         options->kerberos_ticket_cleanup = -1;
60 #endif
61 #ifdef AFS
62         options->kerberos_tgt_passing = -1;
63         options->afs_token_passing = -1;
64 #endif
65         options->password_authentication = -1;
66 #ifdef SKEY
67         options->skey_authentication = -1;
68 #endif
69         options->permit_empty_passwd = -1;
70         options->use_login = -1;
71         options->num_allow_users = 0;
72         options->num_deny_users = 0;
73         options->num_allow_groups = 0;
74         options->num_deny_groups = 0;
75         options->ciphers = NULL;
76         options->protocol = SSH_PROTO_UNKNOWN;
77         options->gateway_ports = -1;
78         options->num_subsystems = 0;
79         options->max_startups = -1;
80 }
81
82 void
83 fill_default_server_options(ServerOptions *options)
84 {
85         if (options->num_ports == 0)
86                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
87         if (options->listen_addrs == NULL)
88                 add_listen_addr(options, NULL);
89         if (options->host_key_file == NULL)
90                 options->host_key_file = HOST_KEY_FILE;
91         if (options->host_dsa_key_file == NULL)
92                 options->host_dsa_key_file = HOST_DSA_KEY_FILE;
93         if (options->pid_file == NULL)
94                 options->pid_file = SSH_DAEMON_PID_FILE;
95         if (options->server_key_bits == -1)
96                 options->server_key_bits = 768;
97         if (options->login_grace_time == -1)
98                 options->login_grace_time = 600;
99         if (options->key_regeneration_time == -1)
100                 options->key_regeneration_time = 3600;
101         if (options->permit_root_login == -1)
102                 options->permit_root_login = 1;                 /* yes */
103         if (options->ignore_rhosts == -1)
104                 options->ignore_rhosts = 1;
105         if (options->ignore_user_known_hosts == -1)
106                 options->ignore_user_known_hosts = 0;
107         if (options->check_mail == -1)
108                 options->check_mail = 0;
109         if (options->print_motd == -1)
110                 options->print_motd = 1;
111         if (options->x11_forwarding == -1)
112                 options->x11_forwarding = 0;
113         if (options->x11_display_offset == -1)
114                 options->x11_display_offset = 10;
115 #ifdef XAUTH_PATH
116         if (options->xauth_location == NULL)
117                 options->xauth_location = XAUTH_PATH;
118 #endif /* XAUTH_PATH */
119         if (options->strict_modes == -1)
120                 options->strict_modes = 1;
121         if (options->keepalives == -1)
122                 options->keepalives = 1;
123         if (options->log_facility == (SyslogFacility) (-1))
124                 options->log_facility = SYSLOG_FACILITY_AUTH;
125         if (options->log_level == (LogLevel) (-1))
126                 options->log_level = SYSLOG_LEVEL_INFO;
127         if (options->rhosts_authentication == -1)
128                 options->rhosts_authentication = 0;
129         if (options->rhosts_rsa_authentication == -1)
130                 options->rhosts_rsa_authentication = 0;
131         if (options->rsa_authentication == -1)
132                 options->rsa_authentication = 1;
133         if (options->dsa_authentication == -1)
134                 options->dsa_authentication = 1;
135 #ifdef KRB4
136         if (options->kerberos_authentication == -1)
137                 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
138         if (options->kerberos_or_local_passwd == -1)
139                 options->kerberos_or_local_passwd = 1;
140         if (options->kerberos_ticket_cleanup == -1)
141                 options->kerberos_ticket_cleanup = 1;
142 #endif /* KRB4 */
143 #ifdef AFS
144         if (options->kerberos_tgt_passing == -1)
145                 options->kerberos_tgt_passing = 0;
146         if (options->afs_token_passing == -1)
147                 options->afs_token_passing = k_hasafs();
148 #endif /* AFS */
149         if (options->password_authentication == -1)
150                 options->password_authentication = 1;
151 #ifdef SKEY
152         if (options->skey_authentication == -1)
153                 options->skey_authentication = 1;
154 #endif
155         if (options->permit_empty_passwd == -1)
156                 options->permit_empty_passwd = 0;
157         if (options->use_login == -1)
158                 options->use_login = 0;
159         if (options->protocol == SSH_PROTO_UNKNOWN)
160                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
161         if (options->gateway_ports == -1)
162                 options->gateway_ports = 0;
163         if (options->max_startups == -1)
164                 options->max_startups = 10;
165 }
166
167 /* Keyword tokens. */
168 typedef enum {
169         sBadOption,             /* == unknown option */
170         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
171         sPermitRootLogin, sLogFacility, sLogLevel,
172         sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
173 #ifdef KRB4
174         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
175 #endif
176 #ifdef AFS
177         sKerberosTgtPassing, sAFSTokenPassing,
178 #endif
179 #ifdef SKEY
180         sSkeyAuthentication,
181 #endif
182         sPasswordAuthentication, sListenAddress,
183         sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
184         sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
185         sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
186         sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
187         sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups
188 } ServerOpCodes;
189
190 /* Textual representation of the tokens. */
191 static struct {
192         const char *name;
193         ServerOpCodes opcode;
194 } keywords[] = {
195         { "port", sPort },
196         { "hostkey", sHostKeyFile },
197         { "hostdsakey", sHostDSAKeyFile },
198         { "pidfile", sPidFile },
199         { "serverkeybits", sServerKeyBits },
200         { "logingracetime", sLoginGraceTime },
201         { "keyregenerationinterval", sKeyRegenerationTime },
202         { "permitrootlogin", sPermitRootLogin },
203         { "syslogfacility", sLogFacility },
204         { "loglevel", sLogLevel },
205         { "rhostsauthentication", sRhostsAuthentication },
206         { "rhostsrsaauthentication", sRhostsRSAAuthentication },
207         { "rsaauthentication", sRSAAuthentication },
208         { "dsaauthentication", sDSAAuthentication },
209 #ifdef KRB4
210         { "kerberosauthentication", sKerberosAuthentication },
211         { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
212         { "kerberosticketcleanup", sKerberosTicketCleanup },
213 #endif
214 #ifdef AFS
215         { "kerberostgtpassing", sKerberosTgtPassing },
216         { "afstokenpassing", sAFSTokenPassing },
217 #endif
218         { "passwordauthentication", sPasswordAuthentication },
219 #ifdef SKEY
220         { "skeyauthentication", sSkeyAuthentication },
221 #endif
222         { "checkmail", sCheckMail },
223         { "listenaddress", sListenAddress },
224         { "printmotd", sPrintMotd },
225         { "ignorerhosts", sIgnoreRhosts },
226         { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
227         { "x11forwarding", sX11Forwarding },
228         { "x11displayoffset", sX11DisplayOffset },
229         { "xauthlocation", sXAuthLocation },
230         { "strictmodes", sStrictModes },
231         { "permitemptypasswords", sEmptyPasswd },
232         { "uselogin", sUseLogin },
233         { "randomseed", sRandomSeedFile },
234         { "keepalive", sKeepAlives },
235         { "allowusers", sAllowUsers },
236         { "denyusers", sDenyUsers },
237         { "allowgroups", sAllowGroups },
238         { "denygroups", sDenyGroups },
239         { "ciphers", sCiphers },
240         { "protocol", sProtocol },
241         { "gatewayports", sGatewayPorts },
242         { "subsystem", sSubsystem },
243         { "maxstartups", sMaxStartups },
244         { NULL, 0 }
245 };
246
247 /*
248  * Returns the number of the token pointed to by cp of length len. Never
249  * returns if the token is not known.
250  */
251
252 static ServerOpCodes
253 parse_token(const char *cp, const char *filename,
254             int linenum)
255 {
256         unsigned int i;
257
258         for (i = 0; keywords[i].name; i++)
259                 if (strcasecmp(cp, keywords[i].name) == 0)
260                         return keywords[i].opcode;
261
262         fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
263                 filename, linenum, cp);
264         return sBadOption;
265 }
266
267 /*
268  * add listen address
269  */
270 void
271 add_listen_addr(ServerOptions *options, char *addr)
272 {
273         extern int IPv4or6;
274         struct addrinfo hints, *ai, *aitop;
275         char strport[NI_MAXSERV];
276         int gaierr;
277         int i;
278
279         if (options->num_ports == 0)
280                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
281         for (i = 0; i < options->num_ports; i++) {
282                 memset(&hints, 0, sizeof(hints));
283                 hints.ai_family = IPv4or6;
284                 hints.ai_socktype = SOCK_STREAM;
285                 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
286                 snprintf(strport, sizeof strport, "%d", options->ports[i]);
287                 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
288                         fatal("bad addr or host: %s (%s)\n",
289                             addr ? addr : "<NULL>",
290                             gai_strerror(gaierr));
291                 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
292                         ;
293                 ai->ai_next = options->listen_addrs;
294                 options->listen_addrs = aitop;
295         }
296 }
297
298 /* Reads the server configuration file. */
299
300 void
301 read_server_config(ServerOptions *options, const char *filename)
302 {
303         FILE *f;
304         char line[1024];
305         char *cp, **charptr, *arg;
306         int linenum, *intptr, value;
307         int bad_options = 0;
308         ServerOpCodes opcode;
309         int i;
310
311         f = fopen(filename, "r");
312         if (!f) {
313                 perror(filename);
314                 exit(1);
315         }
316         linenum = 0;
317         while (fgets(line, sizeof(line), f)) {
318                 linenum++;
319                 cp = line;
320                 arg = strdelim(&cp);
321                 /* Ignore leading whitespace */
322                 if (*arg == '\0')
323                         arg = strdelim(&cp);
324                 if (!*arg || *arg == '#')
325                         continue;
326                 opcode = parse_token(arg, filename, linenum);
327                 switch (opcode) {
328                 case sBadOption:
329                         bad_options++;
330                         continue;
331                 case sPort:
332                         /* ignore ports from configfile if cmdline specifies ports */
333                         if (options->ports_from_cmdline)
334                                 continue;
335                         if (options->listen_addrs != NULL)
336                                 fatal("%s line %d: ports must be specified before "
337                                     "ListenAdress.\n", filename, linenum);
338                         if (options->num_ports >= MAX_PORTS)
339                                 fatal("%s line %d: too many ports.\n",
340                                     filename, linenum);
341                         arg = strdelim(&cp);
342                         if (!arg || *arg == '\0')
343                                 fatal("%s line %d: missing port number.\n",
344                                     filename, linenum);
345                         options->ports[options->num_ports++] = atoi(arg);
346                         break;
347
348                 case sServerKeyBits:
349                         intptr = &options->server_key_bits;
350 parse_int:
351                         arg = strdelim(&cp);
352                         if (!arg || *arg == '\0') {
353                                 fprintf(stderr, "%s line %d: missing integer value.\n",
354                                         filename, linenum);
355                                 exit(1);
356                         }
357                         value = atoi(arg);
358                         if (*intptr == -1)
359                                 *intptr = value;
360                         break;
361
362                 case sLoginGraceTime:
363                         intptr = &options->login_grace_time;
364                         goto parse_int;
365
366                 case sKeyRegenerationTime:
367                         intptr = &options->key_regeneration_time;
368                         goto parse_int;
369
370                 case sListenAddress:
371                         arg = strdelim(&cp);
372                         if (!arg || *arg == '\0')
373                                 fatal("%s line %d: missing inet addr.\n",
374                                     filename, linenum);
375                         add_listen_addr(options, arg);
376                         break;
377
378                 case sHostKeyFile:
379                 case sHostDSAKeyFile:
380                         charptr = (opcode == sHostKeyFile ) ?
381                             &options->host_key_file : &options->host_dsa_key_file;
382 parse_filename:
383                         arg = strdelim(&cp);
384                         if (!arg || *arg == '\0') {
385                                 fprintf(stderr, "%s line %d: missing file name.\n",
386                                     filename, linenum);
387                                 exit(1);
388                         }
389                         if (*charptr == NULL)
390                                 *charptr = tilde_expand_filename(arg, getuid());
391                         break;
392
393                 case sPidFile:
394                         charptr = &options->pid_file;
395                         goto parse_filename;
396
397                 case sRandomSeedFile:
398                         fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
399                                 filename, linenum);
400                         arg = strdelim(&cp);
401                         break;
402
403                 case sPermitRootLogin:
404                         intptr = &options->permit_root_login;
405                         arg = strdelim(&cp);
406                         if (!arg || *arg == '\0') {
407                                 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
408                                         filename, linenum);
409                                 exit(1);
410                         }
411                         if (strcmp(arg, "without-password") == 0)
412                                 value = 2;
413                         else if (strcmp(arg, "yes") == 0)
414                                 value = 1;
415                         else if (strcmp(arg, "no") == 0)
416                                 value = 0;
417                         else {
418                                 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
419                                         filename, linenum, arg);
420                                 exit(1);
421                         }
422                         if (*intptr == -1)
423                                 *intptr = value;
424                         break;
425
426                 case sIgnoreRhosts:
427                         intptr = &options->ignore_rhosts;
428 parse_flag:
429                         arg = strdelim(&cp);
430                         if (!arg || *arg == '\0') {
431                                 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
432                                         filename, linenum);
433                                 exit(1);
434                         }
435                         if (strcmp(arg, "yes") == 0)
436                                 value = 1;
437                         else if (strcmp(arg, "no") == 0)
438                                 value = 0;
439                         else {
440                                 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
441                                         filename, linenum, arg);
442                                 exit(1);
443                         }
444                         if (*intptr == -1)
445                                 *intptr = value;
446                         break;
447
448                 case sIgnoreUserKnownHosts:
449                         intptr = &options->ignore_user_known_hosts;
450                         goto parse_flag;
451
452                 case sRhostsAuthentication:
453                         intptr = &options->rhosts_authentication;
454                         goto parse_flag;
455
456                 case sRhostsRSAAuthentication:
457                         intptr = &options->rhosts_rsa_authentication;
458                         goto parse_flag;
459
460                 case sRSAAuthentication:
461                         intptr = &options->rsa_authentication;
462                         goto parse_flag;
463
464                 case sDSAAuthentication:
465                         intptr = &options->dsa_authentication;
466                         goto parse_flag;
467
468 #ifdef KRB4
469                 case sKerberosAuthentication:
470                         intptr = &options->kerberos_authentication;
471                         goto parse_flag;
472
473                 case sKerberosOrLocalPasswd:
474                         intptr = &options->kerberos_or_local_passwd;
475                         goto parse_flag;
476
477                 case sKerberosTicketCleanup:
478                         intptr = &options->kerberos_ticket_cleanup;
479                         goto parse_flag;
480 #endif
481
482 #ifdef AFS
483                 case sKerberosTgtPassing:
484                         intptr = &options->kerberos_tgt_passing;
485                         goto parse_flag;
486
487                 case sAFSTokenPassing:
488                         intptr = &options->afs_token_passing;
489                         goto parse_flag;
490 #endif
491
492                 case sPasswordAuthentication:
493                         intptr = &options->password_authentication;
494                         goto parse_flag;
495
496                 case sCheckMail:
497                         intptr = &options->check_mail;
498                         goto parse_flag;
499
500 #ifdef SKEY
501                 case sSkeyAuthentication:
502                         intptr = &options->skey_authentication;
503                         goto parse_flag;
504 #endif
505
506                 case sPrintMotd:
507                         intptr = &options->print_motd;
508                         goto parse_flag;
509
510                 case sX11Forwarding:
511                         intptr = &options->x11_forwarding;
512                         goto parse_flag;
513
514                 case sX11DisplayOffset:
515                         intptr = &options->x11_display_offset;
516                         goto parse_int;
517
518                 case sXAuthLocation:
519                         charptr = &options->xauth_location;
520                         goto parse_filename;
521                         
522                 case sStrictModes:
523                         intptr = &options->strict_modes;
524                         goto parse_flag;
525
526                 case sKeepAlives:
527                         intptr = &options->keepalives;
528                         goto parse_flag;
529
530                 case sEmptyPasswd:
531                         intptr = &options->permit_empty_passwd;
532                         goto parse_flag;
533
534                 case sUseLogin:
535                         intptr = &options->use_login;
536                         goto parse_flag;
537
538                 case sGatewayPorts:
539                         intptr = &options->gateway_ports;
540                         goto parse_flag;
541
542                 case sLogFacility:
543                         intptr = (int *) &options->log_facility;
544                         arg = strdelim(&cp);
545                         value = log_facility_number(arg);
546                         if (value == (SyslogFacility) - 1)
547                                 fatal("%.200s line %d: unsupported log facility '%s'\n",
548                                     filename, linenum, arg ? arg : "<NONE>");
549                         if (*intptr == -1)
550                                 *intptr = (SyslogFacility) value;
551                         break;
552
553                 case sLogLevel:
554                         intptr = (int *) &options->log_level;
555                         arg = strdelim(&cp);
556                         value = log_level_number(arg);
557                         if (value == (LogLevel) - 1)
558                                 fatal("%.200s line %d: unsupported log level '%s'\n",
559                                     filename, linenum, arg ? arg : "<NONE>");
560                         if (*intptr == -1)
561                                 *intptr = (LogLevel) value;
562                         break;
563
564                 case sAllowUsers:
565                         while ((arg = strdelim(&cp)) && *arg != '\0') {
566                                 if (options->num_allow_users >= MAX_ALLOW_USERS)
567                                         fatal("%s line %d: too many allow users.\n",
568                                             filename, linenum);
569                                 options->allow_users[options->num_allow_users++] = xstrdup(arg);
570                         }
571                         break;
572
573                 case sDenyUsers:
574                         while ((arg = strdelim(&cp)) && *arg != '\0') {
575                                 if (options->num_deny_users >= MAX_DENY_USERS)
576                                         fatal( "%s line %d: too many deny users.\n",
577                                             filename, linenum);
578                                 options->deny_users[options->num_deny_users++] = xstrdup(arg);
579                         }
580                         break;
581
582                 case sAllowGroups:
583                         while ((arg = strdelim(&cp)) && *arg != '\0') {
584                                 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
585                                         fatal("%s line %d: too many allow groups.\n",
586                                             filename, linenum);
587                                 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
588                         }
589                         break;
590
591                 case sDenyGroups:
592                         while ((arg = strdelim(&cp)) && *arg != '\0') {
593                                 if (options->num_deny_groups >= MAX_DENY_GROUPS)
594                                         fatal("%s line %d: too many deny groups.\n",
595                                             filename, linenum);
596                                 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
597                         }
598                         break;
599
600                 case sCiphers:
601                         arg = strdelim(&cp);
602                         if (!arg || *arg == '\0')
603                                 fatal("%s line %d: Missing argument.", filename, linenum);
604                         if (!ciphers_valid(arg))
605                                 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
606                                     filename, linenum, arg ? arg : "<NONE>");
607                         if (options->ciphers == NULL)
608                                 options->ciphers = xstrdup(arg);
609                         break;
610
611                 case sProtocol:
612                         intptr = &options->protocol;
613                         arg = strdelim(&cp);
614                         if (!arg || *arg == '\0')
615                                 fatal("%s line %d: Missing argument.", filename, linenum);
616                         value = proto_spec(arg);
617                         if (value == SSH_PROTO_UNKNOWN)
618                                 fatal("%s line %d: Bad protocol spec '%s'.",
619                                       filename, linenum, arg ? arg : "<NONE>");
620                         if (*intptr == SSH_PROTO_UNKNOWN)
621                                 *intptr = value;
622                         break;
623
624                 case sSubsystem:
625                         if(options->num_subsystems >= MAX_SUBSYSTEMS) {
626                                 fatal("%s line %d: too many subsystems defined.",
627                                       filename, linenum);
628                         }
629                         arg = strdelim(&cp);
630                         if (!arg || *arg == '\0')
631                                 fatal("%s line %d: Missing subsystem name.",
632                                       filename, linenum);
633                         for (i = 0; i < options->num_subsystems; i++)
634                                 if(strcmp(arg, options->subsystem_name[i]) == 0)
635                                         fatal("%s line %d: Subsystem '%s' already defined.",
636                                               filename, linenum, arg);
637                         options->subsystem_name[options->num_subsystems] = xstrdup(arg);
638                         arg = strdelim(&cp);
639                         if (!arg || *arg == '\0')
640                                 fatal("%s line %d: Missing subsystem command.",
641                                       filename, linenum);
642                         options->subsystem_command[options->num_subsystems] = xstrdup(arg);
643                         options->num_subsystems++;
644                         break;
645
646                 case sMaxStartups:
647                         intptr = &options->max_startups;
648                         goto parse_int;
649
650                 default:
651                         fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
652                                 filename, linenum, arg, opcode);
653                         exit(1);
654                 }
655                 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
656                         fprintf(stderr, 
657                                 "%s line %d: garbage at end of line; \"%.200s\".\n",
658                                 filename, linenum, arg);
659                         exit(1);
660                 }
661         }
662         fclose(f);
663         if (bad_options > 0) {
664                 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
665                         filename, bad_options);
666                 exit(1);
667         }
668 }
This page took 0.366994 seconds and 5 git commands to generate.