Added lance entry to drivers.conf.
[minix3-old.git] / commands / httpd / config.c
blobdce4ef849ebbce71972dfdc491813efa4f5c2410
1 /* config.c by Michael Temari 02/26/96
3 * This file is part of httpd.
5 * 02/26/1996 Michael Temari <Michael@TemWare.Com>
6 * 07/07/1996 Initial Release Michael Temari <Michael@TemWare.Com>
7 * 12/29/2002 Michael Temari <Michael@TemWare.Com>
9 */
10 #include <sys/types.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <ctype.h>
15 #include <pwd.h>
17 #include "utility.h"
18 #include "config.h"
20 struct mtype *mtype = NULL;
21 struct msufx *msufx = NULL;
22 struct vhost *vhost = NULL;
23 struct vpath *vpath = NULL;
24 struct dirsend *dirsend = NULL;
25 struct auth *auth = NULL;
26 struct auth *proxyauth = NULL;
27 char *direxec = NULL;
28 char *srvrroot = "";
29 char *LogFile = NULL;
30 char *DbgFile = NULL;
31 char *User = NULL;
32 char *Chroot = NULL;
34 _PROTOTYPE(static int doconfig, (char *cfg_file));
35 _PROTOTYPE(static int doinclude, (char *parms[], int np));
36 _PROTOTYPE(static int domtype, (char *parms[], int np));
37 _PROTOTYPE(static struct auth *findauth, (char *name));
38 _PROTOTYPE(static int dovhost, (char *parms[], int np));
39 _PROTOTYPE(static int dovpath, (char *parms[], int np));
40 _PROTOTYPE(static int dosrvrroot, (char *parms[], int np));
41 _PROTOTYPE(static int dodirsend, (char *parms[], int np));
42 _PROTOTYPE(static int dodirexec, (char *parms[], int np));
43 _PROTOTYPE(static char *subvpath, (char *s));
44 _PROTOTYPE(static int dologfile, (char *parms[], int np));
45 _PROTOTYPE(static int dodbgfile, (char *parms[], int np));
46 _PROTOTYPE(static int douser, (char *parms[], int np));
47 _PROTOTYPE(static int dochroot, (char *parms[], int np));
48 _PROTOTYPE(static int adduser, (struct auth *pauth, char *user));
49 _PROTOTYPE(static int doauth, (char *parms[], int np));
50 _PROTOTYPE(static int doproxyauth, (char *parms[], int np));
52 int readconfig(cfg_file, testing)
53 char *cfg_file;
54 int testing;
56 int s;
57 char *cfg;
58 struct msufx *ps;
59 struct mtype *pt;
60 struct vhost *ph;
61 struct vpath *pv;
62 struct dirsend *pd;
63 struct auth *pa;
65 cfg = HTTPD_CONFIG_FILE;
66 if(cfg_file != (char *)NULL)
67 if(*cfg_file)
68 cfg = cfg_file;
70 s = doconfig(cfg);
72 if(testing) {
73 printf("ServerRoot: %s\n", srvrroot);
74 printf("UserName: %s\n", User == NULL ? "" : User);
75 printf("Chroot: %s\n", Chroot == NULL ? "" : Chroot);
76 printf("LogFile: %s\n", LogFile == NULL ? "" : LogFile);
77 printf("DbgFile: %s\n", DbgFile == NULL ? "" : DbgFile);
78 printf("DirSend:");
79 for(pd = dirsend; pd != NULL; pd = pd->next)
80 printf(" %s", pd->file);
81 printf("\n");
82 printf("DirExec: %s\n", direxec == NULL ? "" : direxec);
83 for(ph = vhost; ph != NULL; ph = ph->next)
84 printf("VHost: %s %s\n", ph->hname, ph->root);
85 for(pa = auth; pa != NULL; pa = pa->next)
86 printf("Auth: %s %s %d %s\n",
87 pa->name, pa->desc, pa->urlaccess, pa->passwdfile);
88 for(pa = proxyauth; pa != NULL; pa = pa->next)
89 printf("ProxyAuth: %s %s %d %s\n",
90 pa->name, pa->desc, pa->urlaccess, pa->passwdfile);
91 for(pv = vpath; pv != NULL; pv = pv->next)
92 printf("Vpath: %s %s %s %d\n",
93 pv->from, pv->to, pv->auth->name, pv->urlaccess);
94 for(pt = mtype; pt != NULL; pt = pt->next) {
95 printf("MType: %s :", pt->mimetype);
96 for(ps = pt->msufx; ps != NULL; ps = ps->tnext)
97 printf(" '%s'", ps->suffix);
98 printf("\n");
100 for(ps = msufx; ps != NULL; ps = ps->snext)
101 printf("Suffix: %s\t%s\n", ps->suffix, ps->mtype->mimetype);
104 return(s);
107 static int doconfig(cfg_file)
108 char *cfg_file;
110 FILE *fp;
111 int np;
112 int s;
113 char *p;
114 char ltype[40];
115 char *parms[30];
116 static char buffer[2048];
118 if((fp = fopen(cfg_file, "r")) == (FILE *)NULL) {
119 fprintf(stderr, "httpd: Could not read %s config file.\n", cfg_file);
120 return(-1);
123 *ltype = '\0';
125 while(fgets(buffer, sizeof(buffer), fp) != (char *)NULL) {
126 if(buffer[0] == '#') continue; /* skip comments */
127 np = getparms(buffer, parms, sizeof(parms)/sizeof(parms[0]));
128 if(np == 0) continue; /* blank line */
129 if(parms[0] == (char *)NULL)
130 parms[0] = ltype;
131 else {
132 p = parms[0];
133 while(*p) *p++ = tolower(*p);
134 strncpy(ltype, parms[0], sizeof(ltype));
136 s = 0;
137 if(!strcmp(parms[0], "mtype")) s = domtype(parms, np);
138 else
139 if(!strcmp(parms[0], "vhost")) s = dovhost(parms, np);
140 else
141 if(!strcmp(parms[0], "vpath")) s = dovpath(parms, np);
142 else
143 if(!strcmp(parms[0], "serverroot")) s = dosrvrroot(parms, np);
144 else
145 if(!strcmp(parms[0], "dirsend")) s = dodirsend(parms, np);
146 else
147 if(!strcmp(parms[0], "direxec")) s = dodirexec(parms, np);
148 else
149 if(!strcmp(parms[0], "logfile")) s = dologfile(parms, np);
150 else
151 if(!strcmp(parms[0], "dbgfile")) s = dodbgfile(parms, np);
152 else
153 if(!strcmp(parms[0], "user")) s = douser(parms, np);
154 else
155 if(!strcmp(parms[0], "chroot")) s = dochroot(parms, np);
156 else
157 if(!strcmp(parms[0], "auth")) s = doauth(parms, np);
158 else
159 if(!strcmp(parms[0], "proxyauth")) s = doproxyauth(parms, np);
160 else
161 if(!strcmp(parms[0], "include")) s = doinclude(parms, np);
162 else
163 fprintf(stderr, "httpd: Unknown directive: %s\n", parms[0]);
164 if(s) {
165 fprintf(stderr, "httpd: Error processing config file\n");
166 fclose(fp);
167 return(-1);
171 fclose(fp);
173 return(0);
176 static int doinclude(parms, np)
177 char *parms[];
178 int np;
180 char *p;
182 if(np < 2) return(0);
184 p = subvpath(parms[1]);
186 return(doconfig(p));
189 static int domtype(parms, np)
190 char *parms[];
191 int np;
193 int i;
194 struct mtype *pt, *lpt, *newpt;
195 struct msufx *ps, *lps, *newps, *psend;
197 if(np < 2) return(0);
200 /* check if this mime type already exists in the list */
201 for(pt = mtype, lpt = NULL; pt != NULL; lpt = pt, pt = pt->next)
202 if(!strcmp(parms[1], pt->mimetype))
203 break;
205 if(pt == NULL) { /* not there so add it */
206 newpt = malloc(sizeof(struct mtype));
207 if(newpt == NULL) {
208 fprintf(stderr, "httpd: malloc failed in domtype\n");
209 return(-1);
211 newpt->mimetype = malloc(strlen(parms[1])+1);
212 if(newpt->mimetype == NULL) {
213 fprintf(stderr, "httpd: malloc failed in domtype\n");
214 return(-1);
216 strcpy(newpt->mimetype, parms[1]);
217 newpt->msufx = NULL;
218 newpt->next = NULL;
219 if(lpt == NULL)
220 mtype = newpt;
221 else
222 lpt->next = newpt;
223 } else
224 newpt = pt;
226 /* find end of suffix list */
227 for(ps = newpt->msufx, lps = NULL; ps != NULL; lps = ps, ps = ps->tnext) ;
228 psend = lps;
230 /* if no suffix given then add empty suffix for default */
231 if(np == 2)
232 strcpy(parms[np++], "");
234 /* add each suffix to the mime type */
235 for(i = 2; i < np; i++) {
236 /* a suffix can only be for a single mime type */
237 for(ps = msufx, lps = NULL; ps != NULL; lps = ps, ps = ps->snext) {
238 if(!strcmp(ps->suffix, parms[i])) {
239 fprintf(stderr, "httpd: Suffix already found\n");
240 return(-1);
242 if(strlen(parms[i]) > strlen(ps->suffix)) break;
244 newps = malloc(sizeof(struct msufx));
245 if(newps == NULL) {
246 fprintf(stderr, "httpd: malloc failed in domtype\n");
247 return(-1);
249 newps->suffix = malloc(strlen(parms[i])+1);
250 if(newps->suffix == NULL) {
251 fprintf(stderr, "httpd: malloc failed in domtype\n");
252 return(-1);
254 strcpy(newps->suffix, parms[i]);
255 newps->mtype = newpt;
256 newps->snext = NULL;
257 newps->tnext = NULL;
258 if(lps == NULL) {
259 msufx = newps;
260 newps->snext = ps;
261 } else {
262 lps->snext = newps;
263 newps->snext = ps;
265 if(psend == NULL)
266 newpt->msufx = newps;
267 else
268 psend->tnext = newps;
269 psend = newps;
272 return(0);
275 static struct auth *findauth(name)
276 char *name;
278 char lname[80];
279 char *p, *p2;
280 struct auth *a = NULL;
282 if(sizeof(lname) < (strlen(name)+1)) {
283 fprintf(stderr, "httpd: lname too small in findauth\n");
284 return(a);
286 p = name; p2 = lname;
287 while(*p)
288 *p2++ = tolower(*p++);
289 *p2 = '\0';
291 for(a = auth; a != NULL; a = a->next)
292 if(!strcmp(a->name, lname)) break;
294 return(a);
297 static int dovhost(parms, np)
298 char *parms[];
299 int np;
301 char *hname, *root;
302 struct vhost *ph, *lph, *newph;
304 if(np < 2) return(0);
306 hname = parms[1];
308 if(np < 3)
309 root = "";
310 else
311 root = parms[2];
313 for(ph = vhost, lph = NULL; ph != NULL; lph = ph, ph = ph->next)
316 newph = malloc(sizeof(struct vhost));
317 if(newph == NULL) {
318 fprintf(stderr, "httpd: malloc failed in dovhost\n");
319 return(-1);
321 newph->hname = malloc(strlen(hname)+1);
322 if(newph->hname == NULL) {
323 fprintf(stderr, "httpd: malloc failed in dovhost\n");
324 return(-1);
326 strcpy(newph->hname, hname);
328 root = subvpath(root);
330 newph->root = malloc(strlen(root)+1);
331 if(newph->root == NULL) {
332 fprintf(stderr, "httpd: malloc failed in dovhost\n");
333 return(-1);
335 strcpy(newph->root, root);
337 if(np > 3)
338 if(parms[3][0] != '#') {
339 fprintf(stderr, "httpd: junk at end of vhost line\n");
340 return(-1);
343 newph->next = NULL;
344 if(lph == NULL) {
345 vhost = newph;
346 newph->next = ph;
347 } else {
348 lph->next = newph;
349 newph->next = ph;
352 return(0);
355 static int dovpath(parms, np)
356 char *parms[];
357 int np;
359 char *from, *to;
360 struct vpath *pv, *lpv, *newpv;
362 if(np < 3) return(0);
364 from = parms[1];
365 to = parms[2];
367 for(pv = vpath, lpv = NULL; pv != NULL; lpv = pv, pv = pv->next)
370 newpv = malloc(sizeof(struct vpath));
371 if(newpv == NULL) {
372 fprintf(stderr, "httpd: malloc failed in dovpath\n");
373 return(-1);
375 newpv->from = malloc(strlen(from)+1);
376 if(newpv->from == NULL) {
377 fprintf(stderr, "httpd: malloc failed in dovpath\n");
378 return(-1);
380 strcpy(newpv->from, from);
382 to = subvpath(to);
384 newpv->to = malloc(strlen(to)+1);
385 if(newpv->to == NULL) {
386 fprintf(stderr, "httpd: malloc failed in dovpath\n");
387 return(-1);
389 strcpy(newpv->to, to);
391 newpv->auth = NULL;
392 newpv->urlaccess = -1;
394 if(np > 3)
395 if(parms[3][0] != '#') {
396 newpv->auth = findauth(parms[3]);
397 if(np > 4)
398 if(parms[4][0] != '#') {
399 newpv->urlaccess = mkurlaccess(parms[4]);
400 if(np > 5)
401 if(parms[5][0] != '#') {
402 fprintf(stderr, "httpd: junk at end of vpath line\n");
403 return(-1);
408 newpv->next = NULL;
409 if(lpv == NULL) {
410 vpath = newpv;
411 newpv->next = pv;
412 } else {
413 lpv->next = newpv;
414 newpv->next = pv;
417 return(0);
420 static int dosrvrroot(parms, np)
421 char *parms[];
422 int np;
424 char *newroot;
426 if(np < 2) return(0);
428 newroot = subvpath(parms[1]);
430 srvrroot = malloc(strlen(newroot)+1);
431 if(srvrroot == NULL) {
432 fprintf(stderr, "httpd: malloc failed in dosrvrroot\n");
433 return(-1);
435 strcpy(srvrroot, newroot);
436 if(srvrroot[strlen(srvrroot)-1] == '/')
437 srvrroot[strlen(srvrroot)-1] = '\0';
439 return(0);
442 static int dodirsend(parms, np)
443 char *parms[];
444 int np;
446 char *file;
447 int i;
448 struct dirsend *pd, *lpd, *npd;
450 if(np < 2) return(0);
452 /* find end of the list */
453 for(pd = dirsend, lpd = NULL; pd != NULL; lpd = pd, pd = pd->next) ;
455 for(i = 1; i < np; i++) {
456 file = parms[i];
457 if(file[0] == '#') break;
458 npd = malloc(sizeof(struct dirsend));
459 if(npd == NULL) {
460 fprintf(stderr, "httpd: malloc failed in dodirsend\n");
461 return(-1);
463 npd->file = malloc(strlen(file)+1);
464 if(npd->file == NULL) {
465 fprintf(stderr, "httpd: malloc failed in dodirsend\n");
466 return(-1);
468 strcpy(npd->file, file);
469 npd->next = NULL;
470 if(lpd == NULL)
471 dirsend = npd;
472 else
473 lpd->next = npd;
474 lpd = npd;
477 return(0);
480 static int dodirexec(parms, np)
481 char *parms[];
482 int np;
484 char *file;
486 if(np < 2) return(0);
488 if(direxec != NULL) {
489 fprintf(stderr, "httpd: Error direxec line already present\n");
490 return(-1);
493 file = subvpath(parms[1]);
495 direxec = malloc(strlen(file)+1);
497 if(direxec == NULL) {
498 fprintf(stderr, "httpd: malloc failed in dodirexec\n");
499 return(-1);
502 strcpy(direxec, file);
504 if(np > 2)
505 if(parms[2][0] != '#') {
506 fprintf(stderr, "httpd: garbage on end of direxec line\n");
507 return(-1);
510 return(0);
513 static char *subvpath(s)
514 char *s;
516 char *p, *p2;
517 int len;
518 static char buffer[1024];
519 char user[80];
520 struct passwd *pwd;
522 /* replace beginning // with srvrroot */
523 if(s[0] == '/' && s[1] == '/')
524 /* but not /// if we have VHOST's */
525 if(vhost == NULL || s[2] != '/') {
526 strcpy(buffer, srvrroot);
527 strncat(buffer, s+1, sizeof(buffer) - strlen(buffer));
528 buffer[sizeof(buffer)-1] = '\0';
529 return(buffer);
532 if(s[0] != '/' || s[1] != '~') return(s);
534 /* replace beginning /~user with user home directory */
535 p = s + 2;
536 p2 = user;
537 len = sizeof(user) - 1;
538 while(*p && *p != '/' && len-- > 0) *p2++ = *p++;
539 *p2 = '\0';
540 if(*p != '\0' && *p != '/') return(s);
541 if((pwd = getpwnam(user)) == (struct passwd *)NULL) return(s);
542 strcpy(buffer, pwd->pw_dir);
543 strncat(buffer, p, sizeof(buffer) - strlen(buffer));
544 buffer[sizeof(buffer)-1] = '\0';
546 return(buffer);
549 static int dologfile(parms, np)
550 char *parms[];
551 int np;
553 char *p;
555 if(np < 2) return(0);
557 p = subvpath(parms[1]);
558 LogFile = malloc(strlen(p)+1);
559 if(LogFile == NULL) {
560 fprintf(stderr, "httpd: malloc failed in dologfile\n");
561 return(-1);
563 strcpy(LogFile, p);
565 return(0);
568 static int dodbgfile(parms, np)
569 char *parms[];
570 int np;
572 char *p;
574 if(np < 2) return(0);
576 p = subvpath(parms[1]);
577 DbgFile = malloc(strlen(p)+1);
578 if(DbgFile == NULL) {
579 fprintf(stderr, "httpd: malloc failed in dodbgfile\n");
580 return(-1);
582 strcpy(DbgFile, p);
584 return(0);
587 static int douser(parms, np)
588 char *parms[];
589 int np;
591 if(np < 2) return(0);
593 User = malloc(strlen(parms[1])+1);
594 if(User == NULL) {
595 fprintf(stderr, "httpd: malloc failed in douser\n");
596 return(-1);
598 strcpy(User, parms[1]);
600 return(0);
603 static int dochroot(parms, np)
604 char *parms[];
605 int np;
607 char *newroot;
609 if(np < 2) return(0);
611 newroot = subvpath(parms[1]);
613 Chroot = malloc(strlen(newroot)+1);
614 if(Chroot == NULL) {
615 fprintf(stderr, "httpd: malloc failed in dochroot\n");
616 return(-1);
618 strcpy(Chroot, newroot);
620 return(0);
623 static int adduser(pauth, user)
624 struct auth *pauth;
625 char *user;
627 struct authuser *pa, *lpa, *newpa;
629 for(pa = pauth->users, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next)
632 newpa = malloc(sizeof(struct authuser));
633 if(newpa == NULL) {
634 fprintf(stderr, "httpd: malloc failed in adduser\n");
635 return(-1);
637 newpa->user = malloc(strlen(user)+1);
638 if(newpa->user == NULL) {
639 fprintf(stderr, "httpd: malloc failed in adduser\n");
640 return(-1);
642 strcpy(newpa->user, user);
644 newpa->next = NULL;
645 if(lpa == NULL) {
646 pauth->users = newpa;
647 newpa->next = pa;
648 } else {
649 lpa->next = newpa;
650 newpa->next = pa;
653 return(0);
656 static int doauth(parms, np)
657 char *parms[];
658 int np;
660 int i;
661 char *name, *desc, *pf;
662 char *p, *p2;
663 struct auth *pa, *lpa, *newpa;
665 if(np < 3) return(0);
667 name = parms[1];
668 desc = parms[2];
670 for(pa = auth, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next)
673 newpa = malloc(sizeof(struct auth));
674 if(newpa == NULL) {
675 fprintf(stderr, "httpd: malloc failed in doauth\n");
676 return(-1);
678 newpa->name = malloc(strlen(name)+1);
679 if(newpa->name == NULL) {
680 fprintf(stderr, "httpd: malloc failed in doauth\n");
681 return(-1);
683 p = name; p2 = newpa->name;
684 while(*p)
685 *p2++ = tolower(*p++);
686 *p2 = '\0';
688 newpa->desc = malloc(strlen(desc)+1);
689 if(newpa->desc == NULL) {
690 fprintf(stderr, "httpd: malloc failed in doauth\n");
691 return(-1);
693 strcpy(newpa->desc, desc);
695 newpa->urlaccess = mkurlaccess(parms[3]);
696 newpa->passwdfile = NULL;
697 newpa->users = NULL;
699 if(np > 4)
700 if(parms[4][0] != '#') {
701 if(!strcmp(parms[4], "."))
702 pf = "/etc/passwd";
703 else
704 pf = subvpath(parms[4]);
705 newpa->passwdfile = malloc(strlen(pf)+1);
706 if(newpa->passwdfile == NULL) {
707 fprintf(stderr, "httpd: malloc failed in doauth\n");
708 return(-1);
710 strcpy(newpa->passwdfile, pf);
711 i = 5;
712 while(i < np) {
713 if(parms[i][0] == '#')
714 break;
715 if(adduser(newpa, parms[i]))
716 return(-1);
717 i++;
721 newpa->next = NULL;
722 if(lpa == NULL) {
723 auth = newpa;
724 newpa->next = pa;
725 } else {
726 lpa->next = newpa;
727 newpa->next = pa;
730 return(0);
733 static int doproxyauth(parms, np)
734 char *parms[];
735 int np;
737 int i;
738 char *name, *desc, *pf;
739 char *p, *p2;
740 struct auth *pa, *lpa, *newpa;
742 if(np < 3) return(0);
744 name = parms[1];
745 desc = parms[2];
747 if(proxyauth != (struct auth *)NULL) {
748 fprintf(stderr, "httpd: ProxyAuth defined multiple times using 1st only\n");
749 return(0);
752 for(pa = proxyauth, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next)
755 newpa = malloc(sizeof(struct auth));
756 if(newpa == NULL) {
757 fprintf(stderr, "httpd: malloc failed in doproxyauth\n");
758 return(-1);
760 newpa->name = malloc(strlen(name)+1);
761 if(newpa->name == NULL) {
762 fprintf(stderr, "httpd: malloc failed in doproxyauth\n");
763 return(-1);
765 p = name; p2 = newpa->name;
766 while(*p)
767 *p2++ = tolower(*p++);
768 *p2 = '\0';
770 newpa->desc = malloc(strlen(desc)+1);
771 if(newpa->desc == NULL) {
772 fprintf(stderr, "httpd: malloc failed in doproxyauth\n");
773 return(-1);
775 strcpy(newpa->desc, desc);
777 newpa->urlaccess = mkurlaccess(parms[3]);
778 newpa->passwdfile = NULL;
779 newpa->users = NULL;
781 if(np > 4)
782 if(parms[4][0] != '#') {
783 if(!strcmp(parms[4], "."))
784 pf = "/etc/passwd";
785 else
786 pf = subvpath(parms[4]);
787 newpa->passwdfile = malloc(strlen(pf)+1);
788 if(newpa->passwdfile == NULL) {
789 fprintf(stderr, "httpd: malloc failed in doauth\n");
790 return(-1);
792 strcpy(newpa->passwdfile, pf);
793 i = 5;
794 while(i < np) {
795 if(parms[i][0] == '#')
796 break;
797 if(adduser(newpa, parms[i]))
798 return(-1);
799 i++;
803 newpa->next = NULL;
804 if(lpa == NULL) {
805 proxyauth = newpa;
806 newpa->next = pa;
807 } else {
808 lpa->next = newpa;
809 newpa->next = pa;
812 return(0);