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>
10 #include <sys/types.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
;
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
)
65 cfg
= HTTPD_CONFIG_FILE
;
66 if(cfg_file
!= (char *)NULL
)
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
);
79 for(pd
= dirsend
; pd
!= NULL
; pd
= pd
->next
)
80 printf(" %s", pd
->file
);
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
);
100 for(ps
= msufx
; ps
!= NULL
; ps
= ps
->snext
)
101 printf("Suffix: %s\t%s\n", ps
->suffix
, ps
->mtype
->mimetype
);
107 static int doconfig(cfg_file
)
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
);
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
)
133 while(*p
) *p
++ = tolower(*p
);
134 strncpy(ltype
, parms
[0], sizeof(ltype
));
137 if(!strcmp(parms
[0], "mtype")) s
= domtype(parms
, np
);
139 if(!strcmp(parms
[0], "vhost")) s
= dovhost(parms
, np
);
141 if(!strcmp(parms
[0], "vpath")) s
= dovpath(parms
, np
);
143 if(!strcmp(parms
[0], "serverroot")) s
= dosrvrroot(parms
, np
);
145 if(!strcmp(parms
[0], "dirsend")) s
= dodirsend(parms
, np
);
147 if(!strcmp(parms
[0], "direxec")) s
= dodirexec(parms
, np
);
149 if(!strcmp(parms
[0], "logfile")) s
= dologfile(parms
, np
);
151 if(!strcmp(parms
[0], "dbgfile")) s
= dodbgfile(parms
, np
);
153 if(!strcmp(parms
[0], "user")) s
= douser(parms
, np
);
155 if(!strcmp(parms
[0], "chroot")) s
= dochroot(parms
, np
);
157 if(!strcmp(parms
[0], "auth")) s
= doauth(parms
, np
);
159 if(!strcmp(parms
[0], "proxyauth")) s
= doproxyauth(parms
, np
);
161 if(!strcmp(parms
[0], "include")) s
= doinclude(parms
, np
);
163 fprintf(stderr
, "httpd: Unknown directive: %s\n", parms
[0]);
165 fprintf(stderr
, "httpd: Error processing config file\n");
176 static int doinclude(parms
, np
)
182 if(np
< 2) return(0);
184 p
= subvpath(parms
[1]);
189 static int domtype(parms
, np
)
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
))
205 if(pt
== NULL
) { /* not there so add it */
206 newpt
= malloc(sizeof(struct mtype
));
208 fprintf(stderr
, "httpd: malloc failed in domtype\n");
211 newpt
->mimetype
= malloc(strlen(parms
[1])+1);
212 if(newpt
->mimetype
== NULL
) {
213 fprintf(stderr
, "httpd: malloc failed in domtype\n");
216 strcpy(newpt
->mimetype
, parms
[1]);
226 /* find end of suffix list */
227 for(ps
= newpt
->msufx
, lps
= NULL
; ps
!= NULL
; lps
= ps
, ps
= ps
->tnext
) ;
230 /* if no suffix given then add empty suffix for default */
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");
242 if(strlen(parms
[i
]) > strlen(ps
->suffix
)) break;
244 newps
= malloc(sizeof(struct msufx
));
246 fprintf(stderr
, "httpd: malloc failed in domtype\n");
249 newps
->suffix
= malloc(strlen(parms
[i
])+1);
250 if(newps
->suffix
== NULL
) {
251 fprintf(stderr
, "httpd: malloc failed in domtype\n");
254 strcpy(newps
->suffix
, parms
[i
]);
255 newps
->mtype
= newpt
;
266 newpt
->msufx
= newps
;
268 psend
->tnext
= newps
;
275 static struct auth
*findauth(name
)
280 struct auth
*a
= NULL
;
282 if(sizeof(lname
) < (strlen(name
)+1)) {
283 fprintf(stderr
, "httpd: lname too small in findauth\n");
286 p
= name
; p2
= lname
;
288 *p2
++ = tolower(*p
++);
291 for(a
= auth
; a
!= NULL
; a
= a
->next
)
292 if(!strcmp(a
->name
, lname
)) break;
297 static int dovhost(parms
, np
)
302 struct vhost
*ph
, *lph
, *newph
;
304 if(np
< 2) return(0);
313 for(ph
= vhost
, lph
= NULL
; ph
!= NULL
; lph
= ph
, ph
= ph
->next
)
316 newph
= malloc(sizeof(struct vhost
));
318 fprintf(stderr
, "httpd: malloc failed in dovhost\n");
321 newph
->hname
= malloc(strlen(hname
)+1);
322 if(newph
->hname
== NULL
) {
323 fprintf(stderr
, "httpd: malloc failed in dovhost\n");
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");
335 strcpy(newph
->root
, root
);
338 if(parms
[3][0] != '#') {
339 fprintf(stderr
, "httpd: junk at end of vhost line\n");
355 static int dovpath(parms
, np
)
360 struct vpath
*pv
, *lpv
, *newpv
;
362 if(np
< 3) return(0);
367 for(pv
= vpath
, lpv
= NULL
; pv
!= NULL
; lpv
= pv
, pv
= pv
->next
)
370 newpv
= malloc(sizeof(struct vpath
));
372 fprintf(stderr
, "httpd: malloc failed in dovpath\n");
375 newpv
->from
= malloc(strlen(from
)+1);
376 if(newpv
->from
== NULL
) {
377 fprintf(stderr
, "httpd: malloc failed in dovpath\n");
380 strcpy(newpv
->from
, from
);
384 newpv
->to
= malloc(strlen(to
)+1);
385 if(newpv
->to
== NULL
) {
386 fprintf(stderr
, "httpd: malloc failed in dovpath\n");
389 strcpy(newpv
->to
, to
);
392 newpv
->urlaccess
= -1;
395 if(parms
[3][0] != '#') {
396 newpv
->auth
= findauth(parms
[3]);
398 if(parms
[4][0] != '#') {
399 newpv
->urlaccess
= mkurlaccess(parms
[4]);
401 if(parms
[5][0] != '#') {
402 fprintf(stderr
, "httpd: junk at end of vpath line\n");
420 static int dosrvrroot(parms
, np
)
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");
435 strcpy(srvrroot
, newroot
);
436 if(srvrroot
[strlen(srvrroot
)-1] == '/')
437 srvrroot
[strlen(srvrroot
)-1] = '\0';
442 static int dodirsend(parms
, np
)
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
++) {
457 if(file
[0] == '#') break;
458 npd
= malloc(sizeof(struct dirsend
));
460 fprintf(stderr
, "httpd: malloc failed in dodirsend\n");
463 npd
->file
= malloc(strlen(file
)+1);
464 if(npd
->file
== NULL
) {
465 fprintf(stderr
, "httpd: malloc failed in dodirsend\n");
468 strcpy(npd
->file
, file
);
480 static int dodirexec(parms
, np
)
486 if(np
< 2) return(0);
488 if(direxec
!= NULL
) {
489 fprintf(stderr
, "httpd: Error direxec line already present\n");
493 file
= subvpath(parms
[1]);
495 direxec
= malloc(strlen(file
)+1);
497 if(direxec
== NULL
) {
498 fprintf(stderr
, "httpd: malloc failed in dodirexec\n");
502 strcpy(direxec
, file
);
505 if(parms
[2][0] != '#') {
506 fprintf(stderr
, "httpd: garbage on end of direxec line\n");
513 static char *subvpath(s
)
518 static char buffer
[1024];
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';
532 if(s
[0] != '/' || s
[1] != '~') return(s
);
534 /* replace beginning /~user with user home directory */
537 len
= sizeof(user
) - 1;
538 while(*p
&& *p
!= '/' && len
-- > 0) *p2
++ = *p
++;
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';
549 static int dologfile(parms
, np
)
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");
568 static int dodbgfile(parms
, np
)
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");
587 static int douser(parms
, np
)
591 if(np
< 2) return(0);
593 User
= malloc(strlen(parms
[1])+1);
595 fprintf(stderr
, "httpd: malloc failed in douser\n");
598 strcpy(User
, parms
[1]);
603 static int dochroot(parms
, np
)
609 if(np
< 2) return(0);
611 newroot
= subvpath(parms
[1]);
613 Chroot
= malloc(strlen(newroot
)+1);
615 fprintf(stderr
, "httpd: malloc failed in dochroot\n");
618 strcpy(Chroot
, newroot
);
623 static int adduser(pauth
, 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
));
634 fprintf(stderr
, "httpd: malloc failed in adduser\n");
637 newpa
->user
= malloc(strlen(user
)+1);
638 if(newpa
->user
== NULL
) {
639 fprintf(stderr
, "httpd: malloc failed in adduser\n");
642 strcpy(newpa
->user
, user
);
646 pauth
->users
= newpa
;
656 static int doauth(parms
, np
)
661 char *name
, *desc
, *pf
;
663 struct auth
*pa
, *lpa
, *newpa
;
665 if(np
< 3) return(0);
670 for(pa
= auth
, lpa
= NULL
; pa
!= NULL
; lpa
= pa
, pa
= pa
->next
)
673 newpa
= malloc(sizeof(struct auth
));
675 fprintf(stderr
, "httpd: malloc failed in doauth\n");
678 newpa
->name
= malloc(strlen(name
)+1);
679 if(newpa
->name
== NULL
) {
680 fprintf(stderr
, "httpd: malloc failed in doauth\n");
683 p
= name
; p2
= newpa
->name
;
685 *p2
++ = tolower(*p
++);
688 newpa
->desc
= malloc(strlen(desc
)+1);
689 if(newpa
->desc
== NULL
) {
690 fprintf(stderr
, "httpd: malloc failed in doauth\n");
693 strcpy(newpa
->desc
, desc
);
695 newpa
->urlaccess
= mkurlaccess(parms
[3]);
696 newpa
->passwdfile
= NULL
;
700 if(parms
[4][0] != '#') {
701 if(!strcmp(parms
[4], "."))
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");
710 strcpy(newpa
->passwdfile
, pf
);
713 if(parms
[i
][0] == '#')
715 if(adduser(newpa
, parms
[i
]))
733 static int doproxyauth(parms
, np
)
738 char *name
, *desc
, *pf
;
740 struct auth
*pa
, *lpa
, *newpa
;
742 if(np
< 3) return(0);
747 if(proxyauth
!= (struct auth
*)NULL
) {
748 fprintf(stderr
, "httpd: ProxyAuth defined multiple times using 1st only\n");
752 for(pa
= proxyauth
, lpa
= NULL
; pa
!= NULL
; lpa
= pa
, pa
= pa
->next
)
755 newpa
= malloc(sizeof(struct auth
));
757 fprintf(stderr
, "httpd: malloc failed in doproxyauth\n");
760 newpa
->name
= malloc(strlen(name
)+1);
761 if(newpa
->name
== NULL
) {
762 fprintf(stderr
, "httpd: malloc failed in doproxyauth\n");
765 p
= name
; p2
= newpa
->name
;
767 *p2
++ = tolower(*p
++);
770 newpa
->desc
= malloc(strlen(desc
)+1);
771 if(newpa
->desc
== NULL
) {
772 fprintf(stderr
, "httpd: malloc failed in doproxyauth\n");
775 strcpy(newpa
->desc
, desc
);
777 newpa
->urlaccess
= mkurlaccess(parms
[3]);
778 newpa
->passwdfile
= NULL
;
782 if(parms
[4][0] != '#') {
783 if(!strcmp(parms
[4], "."))
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");
792 strcpy(newpa
->passwdfile
, pf
);
795 if(parms
[i
][0] == '#')
797 if(adduser(newpa
, parms
[i
]))