]> git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/conf.c
Y2k copyright changes.
[thirdparty/cups.git] / scheduler / conf.c
1 /*
2 * "$Id: conf.c,v 1.39 2000/01/04 13:46:09 mike Exp $"
3 *
4 * Configuration routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2000 by Easy Software Products, all rights reserved.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
26 * ReadConfiguration() - Read the cupsd.conf file.
27 * read_configuration() - Read a configuration file.
28 * read_location() - Read a <Location path> definition.
29 * get_address() - Get an address + port number from a line.
30 */
31
32 /*
33 * Include necessary headers...
34 */
35
36 #include "cupsd.h"
37 #include <stdarg.h>
38 #include <pwd.h>
39 #include <grp.h>
40 #include <sys/resource.h>
41
42
43 /*
44 * Possibly missing network definitions...
45 */
46
47 #ifndef INADDR_NONE
48 # define INADDR_NONE 0xffffffff
49 #endif /* !INADDR_NONE */
50
51
52 /*
53 * Configuration variable structure...
54 */
55
56 typedef struct
57 {
58 char *name; /* Name of variable */
59 void *ptr; /* Pointer to variable */
60 int type, /* Type (int, string, address) */
61 size; /* Size of string */
62 } var_t;
63
64 #define VAR_INTEGER 0
65 #define VAR_STRING 1
66 #define VAR_BOOLEAN 2
67
68
69 /*
70 * Local globals...
71 */
72
73 static var_t variables[] =
74 {
75 { "ServerName", ServerName, VAR_STRING, sizeof(ServerName) },
76 { "ServerAdmin", ServerAdmin, VAR_STRING, sizeof(ServerAdmin) },
77 { "ServerRoot", ServerRoot, VAR_STRING, sizeof(ServerRoot) },
78 { "ServerBin", ServerBin, VAR_STRING, sizeof(ServerBin) },
79 { "DocumentRoot", DocumentRoot, VAR_STRING, sizeof(DocumentRoot) },
80 { "RequestRoot", RequestRoot, VAR_STRING, sizeof(RequestRoot) },
81 { "SystemGroup", SystemGroup, VAR_STRING, sizeof(SystemGroup) },
82 { "AccessLog", AccessLog, VAR_STRING, sizeof(AccessLog) },
83 { "ErrorLog", ErrorLog, VAR_STRING, sizeof(ErrorLog) },
84 { "PageLog", PageLog, VAR_STRING, sizeof(PageLog) },
85 { "DefaultCharset", DefaultCharset, VAR_STRING, sizeof(DefaultCharset) },
86 { "DefaultLanguage", DefaultLanguage, VAR_STRING, sizeof(DefaultLanguage) },
87 { "RIPCache", RIPCache, VAR_STRING, sizeof(RIPCache) },
88 { "TempDir", TempDir, VAR_STRING, sizeof(TempDir) },
89 { "HostNameLookups", &HostNameLookups, VAR_BOOLEAN, 0 },
90 { "Timeout", &Timeout, VAR_INTEGER, 0 },
91 { "KeepAlive", &KeepAlive, VAR_BOOLEAN, 0 },
92 { "KeepAliveTimeout", &KeepAliveTimeout, VAR_INTEGER, 0 },
93 { "ImplicitClasses", &ImplicitClasses, VAR_BOOLEAN, 0 },
94 { "Browsing", &Browsing, VAR_BOOLEAN, 0 },
95 { "BrowsePort", &BrowsePort, VAR_INTEGER, 0 },
96 { "BrowseInterval", &BrowseInterval, VAR_INTEGER, 0 },
97 { "BrowseTimeout", &BrowseTimeout, VAR_INTEGER, 0 },
98 { "MaxClients", &MaxClients, VAR_INTEGER, 0 },
99 { "MaxLogSize", &MaxLogSize, VAR_INTEGER, 0 },
100 { "MaxRequestSize", &MaxRequestSize, VAR_INTEGER, 0 },
101 { "PreserveJobHistory", &JobHistory, VAR_BOOLEAN, 0 },
102 { "PreserveJobFiles", &JobFiles, VAR_BOOLEAN, 0 }
103 };
104 #define NUM_VARS (sizeof(variables) / sizeof(variables[0]))
105
106
107 /*
108 * Local functions...
109 */
110
111 static int read_configuration(FILE *fp);
112 static int read_location(FILE *fp, char *name, int linenum);
113 static int get_address(char *value, unsigned defaddress, int defport,
114 struct sockaddr_in *address);
115
116
117 /*
118 * 'ReadConfiguration()' - Read the cupsd.conf file.
119 */
120
121 int /* O - 1 if file read successfully, 0 otherwise */
122 ReadConfiguration(void)
123 {
124 FILE *fp; /* Configuration file */
125 int status; /* Return status */
126 char directory[1024];/* Configuration directory */
127 struct rlimit limit; /* Runtime limit */
128 char *language; /* Language string */
129 struct passwd *user; /* Default user */
130 struct group *group; /* Default group */
131
132
133 /*
134 * Close all network clients and stop all jobs...
135 */
136
137 CloseAllClients();
138 StopListening();
139 StopBrowsing();
140
141 if (Clients != NULL)
142 {
143 free(Clients);
144 Clients = NULL;
145 }
146
147 StopAllJobs();
148
149 if (AccessFile != NULL)
150 {
151 fclose(AccessFile);
152
153 AccessFile = NULL;
154 }
155
156 if (ErrorFile != NULL)
157 {
158 fclose(ErrorFile);
159
160 ErrorFile = NULL;
161 }
162
163 if (PageFile != NULL)
164 {
165 fclose(PageFile);
166
167 PageFile = NULL;
168 }
169
170 /*
171 * Clear the current configuration...
172 */
173
174 NeedReload = FALSE;
175
176 FD_ZERO(&InputSet);
177 FD_ZERO(&OutputSet);
178
179 DeleteAllLocations();
180
181 DeleteAllClasses();
182
183 gethostname(ServerName, sizeof(ServerName));
184 sprintf(ServerAdmin, "root@%s", ServerName);
185 strcpy(ServerRoot, CUPS_SERVERROOT);
186 strcpy(ServerBin, CUPS_SERVERBIN);
187 strcpy(RequestRoot, CUPS_REQUESTS);
188 strcpy(DocumentRoot, CUPS_DOCROOT);
189 strcpy(AccessLog, CUPS_LOGDIR "/access_log");
190 strcpy(ErrorLog, CUPS_LOGDIR "/error_log");
191 strcpy(PageLog, CUPS_LOGDIR "/page_log");
192
193 if ((language = DEFAULT_LANGUAGE) == NULL)
194 language = "en";
195 else if (strcmp(language, "C") == 0 || strcmp(language, "POSIX") == 0)
196 language = "en";
197
198 strncpy(DefaultLanguage, language, sizeof(DefaultLanguage) - 1);
199 DefaultLanguage[sizeof(DefaultLanguage) - 1] = '\0';
200
201 strcpy(DefaultCharset, DEFAULT_CHARSET);
202 strcpy(RIPCache, "8m");
203 if (getenv("TMPDIR") == NULL)
204 strcpy(TempDir, "/var/tmp");
205 else
206 {
207 strncpy(TempDir, getenv("TMPDIR"), sizeof(TempDir) - 1);
208 TempDir[sizeof(TempDir) - 1] = '\0';
209 }
210
211 /*
212 * Find the default system group: "sys", "system", or "root"...
213 */
214
215 group = getgrnam("sys");
216 endgrent();
217
218 if (group != NULL)
219 {
220 strcpy(SystemGroup, "sys");
221 Group = group->gr_gid;
222 }
223 else
224 {
225 group = getgrnam("system");
226 endgrent();
227
228 if (group != NULL)
229 {
230 strcpy(SystemGroup, "system");
231 Group = group->gr_gid;
232 }
233 else
234 {
235 group = getgrnam("root");
236 endgrent();
237
238 if (group != NULL)
239 {
240 strcpy(SystemGroup, "root");
241 Group = group->gr_gid;
242 }
243 else
244 {
245 strcpy(SystemGroup, "unknown");
246 Group = 0;
247 }
248 }
249 }
250
251 /*
252 * Find the default user...
253 */
254
255 if ((user = getpwnam("lp")) == NULL)
256 User = 1; /* Force to a non-priviledged account */
257 else
258 User = user->pw_uid;
259
260 endpwent();
261
262 LogLevel = LOG_ERROR;
263 HostNameLookups = FALSE;
264 Timeout = DEFAULT_TIMEOUT;
265 KeepAlive = TRUE;
266 KeepAliveTimeout = DEFAULT_KEEPALIVE;
267 ImplicitClasses = TRUE;
268
269 MaxClients = 100;
270
271 MaxLogSize = 1024 * 1024;
272 MaxRequestSize = 0;
273
274 Browsing = TRUE;
275 BrowsePort = ippPort();
276 BrowseInterval = DEFAULT_INTERVAL;
277 BrowseTimeout = DEFAULT_TIMEOUT;
278 NumBrowsers = 0;
279
280 NumListeners = 0;
281
282 DefaultPrinter = NULL;
283
284 DeleteAllPrinters();
285
286 if (MimeDatabase != NULL)
287 mimeDelete(MimeDatabase);
288
289 JobHistory = DEFAULT_HISTORY;
290 JobFiles = DEFAULT_FILES;
291
292 if ((fp = fopen(ConfigurationFile, "r")) == NULL)
293 return (0);
294
295 status = read_configuration(fp);
296
297 fclose(fp);
298
299 if (!status)
300 return (0);
301
302 if (DocumentRoot[0] != '/')
303 {
304 snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, DocumentRoot);
305 strcpy(DocumentRoot, directory);
306 }
307
308 if (RequestRoot[0] != '/')
309 {
310 snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, RequestRoot);
311 strcpy(RequestRoot, directory);
312 }
313
314 if (ServerBin[0] != '/')
315 {
316 snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, ServerBin);
317 strcpy(ServerBin, directory);
318 }
319
320 LogMessage(LOG_DEBUG, "ReadConfiguration() ConfigurationFile=\"%s\"",
321 ConfigurationFile);
322
323 /*
324 * Check the MaxClients setting, and then allocate memory for it...
325 */
326
327 getrlimit(RLIMIT_NOFILE, &limit);
328
329 if (MaxClients > (limit.rlim_max / 3))
330 MaxClients = limit.rlim_max / 3;
331
332 if ((Clients = calloc(sizeof(client_t), MaxClients)) == NULL)
333 {
334 LogMessage(LOG_ERROR, "ReadConfiguration() FATAL: unable to allocate memory for %d clients!",
335 MaxClients);
336 exit(1);
337 }
338 else
339 LogMessage(LOG_INFO, "ReadConfiguration() Configured for up to %d clients.",
340 MaxClients);
341
342 /*
343 * Read the MIME type and conversion database...
344 */
345
346 snprintf(directory, sizeof(directory), "%s/conf", ServerRoot);
347
348 MimeDatabase = mimeNew();
349 mimeMerge(MimeDatabase, directory);
350
351 /*
352 * Load printers, classes, and jobs...
353 */
354
355 LoadAllPrinters();
356 LoadAllClasses();
357
358 /*
359 * Add a default browser if browsing is enabled and no browser addresses
360 * were defined...
361 */
362
363 if (Browsing && NumBrowsers == 0)
364 {
365 NumBrowsers ++;
366
367 memset(Browsers + 0, 0, sizeof(Browsers[0]));
368 Browsers[0].sin_addr.s_addr = htonl(INADDR_BROADCAST);
369 Browsers[0].sin_family = AF_INET;
370 Browsers[0].sin_port = htons(BrowsePort);
371 }
372
373 /*
374 * Startup all the networking stuff...
375 */
376
377 StartListening();
378 StartBrowsing();
379
380 /*
381 * Check for queued jobs...
382 */
383
384 CheckJobs();
385
386 return (1);
387 }
388
389
390 /*
391 * 'read_configuration()' - Read a configuration file.
392 */
393
394 static int /* O - 1 on success, 0 on failure */
395 read_configuration(FILE *fp) /* I - File to read from */
396 {
397 int i; /* Looping var */
398 int linenum; /* Current line number */
399 int len; /* Length of line */
400 char line[HTTP_MAX_BUFFER], /* Line from file */
401 name[256], /* Parameter name */
402 *nameptr, /* Pointer into name */
403 *value; /* Pointer to value */
404 var_t *var; /* Current variable */
405
406
407 /*
408 * Loop through each line in the file...
409 */
410
411 linenum = 0;
412
413 while (fgets(line, sizeof(line), fp) != NULL)
414 {
415 linenum ++;
416
417 /*
418 * Skip comment lines...
419 */
420
421 if (line[0] == '#')
422 continue;
423
424 /*
425 * Strip trailing newline, if any...
426 */
427
428 len = strlen(line);
429
430 if (line[len - 1] == '\n')
431 {
432 len --;
433 line[len] = '\0';
434 }
435
436 /*
437 * Extract the name from the beginning of the line...
438 */
439
440 for (value = line; isspace(*value); value ++);
441
442 for (nameptr = name; *value != '\0' && !isspace(*value);)
443 *nameptr++ = *value++;
444 *nameptr = '\0';
445
446 while (isspace(*value))
447 value ++;
448
449 if (name[0] == '\0')
450 continue;
451
452 /*
453 * Decode the directive...
454 */
455
456 if (strcmp(name, "<Location") == 0)
457 {
458 /*
459 * <Location path>
460 */
461
462 if (line[len - 1] == '>')
463 {
464 line[len - 1] = '\0';
465
466 linenum = read_location(fp, value, linenum);
467 if (linenum == 0)
468 return (0);
469 }
470 else
471 {
472 LogMessage(LOG_ERROR, "ReadConfiguration() Syntax error on line %d.",
473 linenum);
474 return (0);
475 }
476 }
477 else if (strcmp(name, "Port") == 0 ||
478 strcmp(name, "Listen") == 0)
479 {
480 /*
481 * Add a listening address to the list...
482 */
483
484 if (NumListeners < MAX_BROWSERS)
485 {
486 if (get_address(value, INADDR_ANY, IPP_PORT,
487 &(Listeners[NumListeners].address)))
488 {
489 LogMessage(LOG_INFO, "Listening to %x:%d\n",
490 ntohl(Listeners[NumListeners].address.sin_addr.s_addr),
491 ntohs(Listeners[NumListeners].address.sin_port));
492 NumListeners ++;
493 }
494 else
495 LogMessage(LOG_ERROR, "Bad %s address %s at line %d.", name,
496 value, linenum);
497 }
498 else
499 LogMessage(LOG_WARN, "Too many %s directives at line %d.", name,
500 linenum);
501 }
502 else if (strcmp(name, "BrowseAddress") == 0)
503 {
504 /*
505 * Add a browse address to the list...
506 */
507
508 if (NumBrowsers < MAX_BROWSERS)
509 {
510 if (get_address(value, INADDR_NONE, BrowsePort, Browsers + NumBrowsers))
511 {
512 LogMessage(LOG_INFO, "Sending browsing info to %x:%d\n",
513 ntohl(Browsers[NumBrowsers].sin_addr.s_addr),
514 ntohs(Browsers[NumBrowsers].sin_port));
515 NumBrowsers ++;
516 }
517 else
518 LogMessage(LOG_ERROR, "Bad BrowseAddress %s at line %d.", value,
519 linenum);
520 }
521 else
522 LogMessage(LOG_WARN, "Too many BrowseAddress directives at line %d.",
523 linenum);
524 }
525 else if (strcmp(name, "User") == 0)
526 {
527 /*
528 * User ID to run as...
529 */
530
531 if (isdigit(value[0]))
532 User = atoi(value);
533 else
534 {
535 struct passwd *p; /* Password information */
536
537 endpwent();
538 p = getpwnam(value);
539
540 if (p != NULL)
541 User = p->pw_uid;
542 else
543 LogMessage(LOG_WARN, "ReadConfiguration() Unknown username \"%s\"",
544 value);
545 }
546 }
547 else if (strcmp(name, "Group") == 0)
548 {
549 /*
550 * Group ID to run as...
551 */
552
553 if (isdigit(value[0]))
554 Group = atoi(value);
555 else
556 {
557 struct group *g; /* Group information */
558
559 endgrent();
560 g = getgrnam(value);
561
562 if (g != NULL)
563 Group = g->gr_gid;
564 else
565 LogMessage(LOG_WARN, "ReadConfiguration() Unknown groupname \"%s\"",
566 value);
567 }
568 }
569 else if (strcmp(name, "LogLevel") == 0)
570 {
571 /*
572 * Amount of logging to do...
573 */
574
575 if (strcmp(value, "debug") == 0)
576 LogLevel = LOG_DEBUG;
577 else if (strcmp(value, "info") == 0)
578 LogLevel = LOG_INFO;
579 else if (strcmp(value, "warn") == 0)
580 LogLevel = LOG_WARN;
581 else if (strcmp(value, "error") == 0)
582 LogLevel = LOG_ERROR;
583 else if (strcmp(value, "none") == 0)
584 LogLevel = LOG_NONE;
585 }
586 else
587 {
588 /*
589 * Find a simple variable in the list...
590 */
591
592 for (i = NUM_VARS, var = variables; i > 0; i --, var ++)
593 if (strcmp(name, var->name) == 0)
594 break;
595
596 if (i == 0)
597 {
598 /*
599 * Unknown directive! Output an error message and continue...
600 */
601
602 LogMessage(LOG_ERROR, "Unknown directive %s on line %d.", name,
603 linenum);
604 continue;
605 }
606
607 switch (var->type)
608 {
609 case VAR_INTEGER :
610 *((int *)var->ptr) = atoi(value);
611 break;
612
613 case VAR_BOOLEAN :
614 if (strcasecmp(value, "true") == 0 ||
615 strcasecmp(value, "on") == 0 ||
616 strcasecmp(value, "enabled") == 0 ||
617 atoi(value) != 0)
618 *((int *)var->ptr) = TRUE;
619 else if (strcasecmp(value, "false") == 0 ||
620 strcasecmp(value, "off") == 0 ||
621 strcasecmp(value, "disabled") == 0 ||
622 strcasecmp(value, "0") == 0)
623 *((int *)var->ptr) = FALSE;
624 else
625 LogMessage(LOG_ERROR, "Unknown boolean value %s on line %d.",
626 value, linenum);
627 break;
628
629 case VAR_STRING :
630 strncpy((char *)var->ptr, value, var->size - 1);
631 value[var->size - 1] = '\0';
632 break;
633 }
634 }
635 }
636
637 return (1);
638 }
639
640
641 /*
642 * 'read_location()' - Read a <Location path> definition.
643 */
644
645 static int /* O - New line number or 0 on error */
646 read_location(FILE *fp, /* I - Configuration file */
647 char *location, /* I - Location name/path */
648 int linenum) /* I - Current line number */
649 {
650 location_t *loc; /* New location */
651 int len; /* Length of line */
652 char line[HTTP_MAX_BUFFER], /* Line buffer */
653 name[256], /* Configuration directive */
654 *nameptr, /* Pointer into name */
655 *value; /* Value for directive */
656 unsigned address, /* Address value */
657 netmask; /* Netmask value */
658 int ip[4], /* IP address components */
659 ipcount, /* Number of components provided */
660 mask[4]; /* IP netmask components */
661 static unsigned netmasks[4] = /* Standard netmasks... */
662 {
663 0xff000000,
664 0xffff0000,
665 0xffffff00,
666 0xffffffff
667 };
668
669
670 if ((loc = AddLocation(location)) == NULL)
671 return (0);
672
673 while (fgets(line, sizeof(line), fp) != NULL)
674 {
675 linenum ++;
676
677 /*
678 * Skip comment lines...
679 */
680
681 if (line[0] == '#')
682 continue;
683
684 /*
685 * Strip trailing newline, if any...
686 */
687
688 len = strlen(line);
689
690 if (line[len - 1] == '\n')
691 {
692 len --;
693 line[len] = '\0';
694 }
695
696 /*
697 * Extract the name from the beginning of the line...
698 */
699
700 for (value = line; isspace(*value); value ++);
701
702 for (nameptr = name; *value != '\0' && !isspace(*value);)
703 *nameptr++ = *value++;
704 *nameptr = '\0';
705
706 while (isspace(*value))
707 value ++;
708
709 if (name[0] == '\0')
710 continue;
711
712 /*
713 * Decode the directive...
714 */
715
716 if (strcmp(name, "</Location>") == 0)
717 return (linenum);
718 else if (strcmp(name, "Order") == 0)
719 {
720 /*
721 * "Order Deny,Allow" or "Order Allow,Deny"...
722 */
723
724 if (strncasecmp(value, "deny", 4) == 0)
725 loc->order_type = AUTH_ALLOW;
726 else if (strncasecmp(value, "allow", 5) == 0)
727 loc->order_type = AUTH_DENY;
728 else
729 LogMessage(LOG_ERROR, "Unknown Order value %s on line %d.",
730 value, linenum);
731 }
732 else if (strcmp(name, "Allow") == 0 ||
733 strcmp(name, "Deny") == 0)
734 {
735 /*
736 * Allow [From] host/ip...
737 * Deny [From] host/ip...
738 */
739
740 if (strncasecmp(value, "from", 4) == 0)
741 {
742 /*
743 * Strip leading "from"...
744 */
745
746 value += 4;
747
748 while (isspace(*value))
749 value ++;
750 }
751
752 /*
753 * Figure out what form the allow/deny address takes:
754 *
755 * All
756 * None
757 * *.domain.com
758 * .domain.com
759 * host.domain.com
760 * nnn.*
761 * nnn.nnn.*
762 * nnn.nnn.nnn.*
763 * nnn.nnn.nnn.nnn
764 * nnn.nnn.nnn.nnn/mm
765 * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
766 */
767
768 if (strcasecmp(value, "all") == 0)
769 {
770 /*
771 * All hosts...
772 */
773
774 if (strcmp(name, "Allow") == 0)
775 AllowIP(loc, 0, 0);
776 else
777 DenyIP(loc, 0, 0);
778 }
779 else if (strcasecmp(value, "none") == 0)
780 {
781 /*
782 * No hosts...
783 */
784
785 if (strcmp(name, "Allow") == 0)
786 AllowIP(loc, ~0, 0);
787 else
788 DenyIP(loc, ~0, 0);
789 }
790 else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0]))
791 {
792 /*
793 * Host or domain name...
794 */
795
796 if (value[0] == '*')
797 value ++;
798
799 if (strcmp(name, "Allow") == 0)
800 AllowHost(loc, value);
801 else
802 DenyHost(loc, value);
803 }
804 else
805 {
806 /*
807 * One of many IP address forms...
808 */
809
810 memset(ip, 0, sizeof(ip));
811 ipcount = sscanf(value, "%d.%d.%d.%d", ip + 0, ip + 1, ip + 2, ip + 3);
812 address = (((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3];
813
814 if ((value = strchr(value, '/')) != NULL)
815 {
816 value ++;
817 memset(mask, 0, sizeof(mask));
818 switch (sscanf(value, "%d.%d.%d.%d", mask + 0, mask + 1,
819 mask + 2, mask + 3))
820 {
821 case 1 :
822 netmask = (0xffffffff << (32 - mask[0])) & 0xffffffff;
823 break;
824 case 4 :
825 netmask = (((((mask[0] << 8) | mask[1]) << 8) |
826 mask[2]) << 8) | mask[3];
827 break;
828 default :
829 LogMessage(LOG_ERROR, "Bad netmask value %s on line %d.",
830 value, linenum);
831 netmask = 0xffffffff;
832 break;
833 }
834 }
835 else
836 netmask = netmasks[ipcount - 1];
837
838 if (strcmp(name, "Allow") == 0)
839 AllowIP(loc, address, netmask);
840 else
841 DenyIP(loc, address, netmask);
842 }
843 }
844 else if (strcmp(name, "AuthType") == 0)
845 {
846 /*
847 * AuthType Basic
848 */
849
850 if (strcasecmp(value, "basic") != 0)
851 LogMessage(LOG_WARN, "Unknown authorization type %s on line %d.",
852 value, linenum);
853 }
854 else if (strcmp(name, "AuthClass") == 0)
855 {
856 /*
857 * AuthClass anonymous, user, system, group
858 */
859
860 if (strcasecmp(value, "anonymous") == 0)
861 loc->level = AUTH_ANON;
862 else if (strcasecmp(value, "user") == 0)
863 loc->level = AUTH_USER;
864 else if (strcasecmp(value, "group") == 0)
865 loc->level = AUTH_GROUP;
866 else if (strcasecmp(value, "system") == 0)
867 {
868 loc->level = AUTH_GROUP;
869 strcpy(loc->group_name, SystemGroup);
870 }
871 else
872 LogMessage(LOG_WARN, "Unknown authorization class %s on line %d.",
873 value, linenum);
874 }
875 else if (strcmp(name, "AuthGroupName") == 0)
876 strncpy(loc->group_name, value, sizeof(loc->group_name) - 1);
877 else
878 LogMessage(LOG_ERROR, "Unknown Location directive %s on line %d.",
879 name, linenum);
880 }
881
882 return (0);
883 }
884
885
886 /*
887 * 'get_address()' - Get an address + port number from a line.
888 */
889
890 static int /* O - 1 if address good, 0 if bad */
891 get_address(char *value, /* I - Value string */
892 unsigned defaddress, /* I - Default address */
893 int defport, /* I - Default port */
894 struct sockaddr_in *address) /* O - Socket address */
895 {
896 char hostname[256], /* Hostname or IP */
897 portname[256]; /* Port number or name */
898 struct hostent *host; /* Host address */
899 struct servent *port; /* Port number */
900
901
902 /*
903 * Initialize the socket address to the defaults...
904 */
905
906 memset(address, 0, sizeof(struct sockaddr_in));
907 address->sin_family = AF_INET;
908 address->sin_addr.s_addr = htonl(defaddress);
909 address->sin_port = htons(defport);
910
911 /*
912 * Try to grab a hostname and port number...
913 */
914
915 switch (sscanf(value, "%255[^:]:%255s", hostname, portname))
916 {
917 case 1 :
918 if (strchr(hostname, '.') == NULL)
919 {
920 /*
921 * Hostname is a port number...
922 */
923
924 strcpy(portname, hostname);
925 hostname[0] = '\0';
926 }
927 else
928 portname[0] = '\0';
929 break;
930 case 2 :
931 break;
932 default :
933 LogMessage(LOG_ERROR, "Unable to decode address \"%s\"!", value);
934 return (0);
935 }
936
937 /*
938 * Decode the hostname and port number as needed...
939 */
940
941 if (hostname[0] != '\0')
942 {
943 if (isdigit(hostname[0]))
944 address->sin_addr.s_addr = inet_addr(hostname);
945 else
946 {
947 if ((host = gethostbyname(hostname)) == NULL)
948 {
949 LogMessage(LOG_ERROR, "gethostbyname(\"%s\") failed - %s!", hostname,
950 strerror(errno));
951 return (0);
952 }
953
954 memcpy(&(address->sin_addr), host->h_addr, host->h_length);
955 address->sin_port = htons(defport);
956 }
957 }
958
959 if (portname[0] != '\0')
960 {
961 if (isdigit(portname[0]))
962 address->sin_port = htons(atoi(portname));
963 else
964 {
965 if ((port = getservbyname(portname, NULL)) == NULL)
966 {
967 LogMessage(LOG_ERROR, "getservbyname(\"%s\") failed - %s!", portname,
968 strerror(errno));
969 return (0);
970 }
971 else
972 address->sin_port = htons(port->s_port);
973 }
974 }
975
976 return (1);
977 }
978
979
980 /*
981 * End of "$Id: conf.c,v 1.39 2000/01/04 13:46:09 mike Exp $".
982 */