Rev 3841 | Rev 8342 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3841 | Rev 8177 | ||
---|---|---|---|
Line 15... | Line 15... | ||
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
16 | */ |
16 | */ |
17 | 17 | ||
18 | /* http dawmon for WIMS */ |
18 | /* http dawmon for WIMS */ |
19 | 19 | ||
20 | #include "../wims.h" |
- | |
21 | #include <netdb.h> |
20 | #include <netdb.h> |
22 | #include <sys/socket.h> |
21 | #include <sys/socket.h> |
23 | #include <netinet/in.h> |
22 | #include <netinet/in.h> |
24 | #include <arpa/inet.h> |
23 | #include <arpa/inet.h> |
- | 24 | #include "../wims.h" |
|
25 | 25 | ||
26 | #if !HAVE_SOCKLEN_T |
26 | #if !HAVE_SOCKLEN_T |
27 | typedef size_t socklen_t; |
27 | typedef size_t socklen_t; |
28 | #endif |
28 | #endif |
29 | 29 | ||
30 | #define WIMS_TIMEOUT 200 |
30 | #define WIMS_TIMEOUT 200 |
31 | #define WIMSD_TICK 10 |
31 | #define WIMSD_TICK 10 |
32 | #define WIMSD_IDLE 500 |
32 | #define WIMSD_IDLE 500 |
33 | #define PIDLIM 100 |
33 | #define PIDLIM 100 |
34 | 34 | ||
Line 38... | Line 38... | ||
38 | int pidcnt; |
38 | int pidcnt; |
39 | 39 | ||
40 | int sock; |
40 | int sock; |
41 | int sport; |
41 | int sport; |
42 | int idle; /* limited to WIMSD_TICK * WIMSD_IDLE */ |
42 | int idle; /* limited to WIMSD_TICK * WIMSD_IDLE */ |
43 | 43 | ||
44 | void errorquit(char *msg) |
44 | void errorquit(char *msg) |
45 | { |
45 | { |
46 | fprintf(stderr,"%s: %s\n",msg,strerror(errno)); exit(1); |
46 | fprintf(stderr,"%s: %s\n",msg,strerror(errno)); exit(1); |
47 | } |
47 | } |
48 | 48 | ||
Line 52... | Line 52... | ||
52 | for(i=0;i<pidcnt;i++) { |
52 | for(i=0;i<pidcnt;i++) { |
53 | waitpid(pidtab[i],&k,WNOHANG); |
53 | waitpid(pidtab[i],&k,WNOHANG); |
54 | if(WIFEXITED(k)) { |
54 | if(WIFEXITED(k)) { |
55 | memmove(pidtab+i,pidtab+i+1,(pidcnt-i-1)*sizeof(pidtab[0])); |
55 | memmove(pidtab+i,pidtab+i+1,(pidcnt-i-1)*sizeof(pidtab[0])); |
56 | pidcnt--; |
56 | pidcnt--; |
57 | } |
57 | } |
58 | } |
58 | } |
59 | } |
59 | } |
60 | 60 | ||
61 | void addpid(int pid) |
61 | void addpid(int pid) |
62 | { |
62 | { |
Line 65... | Line 65... | ||
65 | } |
65 | } |
66 | pidtab[pidcnt++]=pid; |
66 | pidtab[pidcnt++]=pid; |
67 | } |
67 | } |
68 | 68 | ||
69 | void alarm1(int s) |
69 | void alarm1(int s) |
70 | { |
70 | { |
71 | fprintf(stderr,"Time out.\n"); close(sock); exit(1); |
71 | fprintf(stderr,"Time out.\n"); close(sock); exit(1); |
72 | } |
72 | } |
73 | 73 | ||
74 | void alarm2(int s) |
74 | void alarm2(int s) |
75 | { |
75 | { |
76 | checkpid(); idle++; alarm(WIMSD_TICK); |
76 | checkpid(); idle++; alarm(WIMSD_TICK); |
77 | if(idle>=WIMSD_IDLE) alarm1(0); |
77 | if(idle>=WIMSD_IDLE) alarm1(0); |
78 | } |
78 | } |
79 | 79 | ||
80 | /* Points to the end of the word */ |
80 | /* Points to the end of the word */ |
Line 89... | Line 89... | ||
89 | char *find_word_start(char *p) |
89 | char *find_word_start(char *p) |
90 | { |
90 | { |
91 | int i; |
91 | int i; |
92 | for(i=0; isspace(*p) && i<MAX_LINELEN; p++,i++); |
92 | for(i=0; isspace(*p) && i<MAX_LINELEN; p++,i++); |
93 | return p; |
93 | return p; |
94 | } |
94 | } |
95 | 95 | ||
96 | /* Read/write to a file with variable parms to print filename */ |
96 | /* Read/write to a file with variable parms to print filename */ |
97 | void accessfile(char *content, char *type, char *s,...) |
97 | void accessfile(char *content, char *type, char *s,...) |
98 | { |
98 | { |
99 | va_list vp; |
99 | va_list vp; |
100 | char buf[MAX_LINELEN+1]; |
100 | char buf[MAX_LINELEN+1]; |
Line 104... | Line 104... | ||
104 | va_start(vp,s); |
104 | va_start(vp,s); |
105 | vsnprintf(buf,sizeof(buf),s,vp); |
105 | vsnprintf(buf,sizeof(buf),s,vp); |
106 | va_end(vp); |
106 | va_end(vp); |
107 | f=fopen(buf,type); if(f==NULL) { |
107 | f=fopen(buf,type); if(f==NULL) { |
108 | if(*type=='r') content[0]=0; return; |
108 | if(*type=='r') content[0]=0; return; |
109 | } |
109 | } |
110 | switch(*type) { |
110 | switch(*type) { |
111 | case 'a': |
111 | case 'a': |
112 | case 'w': { |
112 | case 'w': { |
113 | l=strlen(content); fwrite(content,1,l,f); break; |
113 | l=strlen(content); fwrite(content,1,l,f); break; |
114 | } |
114 | } |
115 | case 'r': { |
115 | case 'r': { |
116 | l=fread(content,1,MAX_LINELEN-1,f); |
116 | l=fread(content,1,MAX_LINELEN-1,f); |
117 | if(l>0 && l<MAX_LINELEN) content[l]=0; |
117 | if(l>0 && l<MAX_LINELEN) content[l]=0; |
118 | else content[0]=0; |
118 | else content[0]=0; |
119 | break; |
119 | break; |
Line 126... | Line 126... | ||
126 | } |
126 | } |
127 | 127 | ||
128 | void badreq(void) |
128 | void badreq(void) |
129 | { |
129 | { |
130 | printf("HTTP/1.0 400 Bad Request\r\n\r\nBad Request.\r\n"); |
130 | printf("HTTP/1.0 400 Bad Request\r\n\r\nBad Request.\r\n"); |
131 | exit(0); |
131 | exit(0); |
132 | } |
132 | } |
133 | 133 | ||
134 | /* open a TCP/IP socket with host/port |
134 | /* open a TCP/IP socket with host/port |
135 | * returns the file descriptor for the socket */ |
135 | * returns the file descriptor for the socket */ |
136 | int net_connect(int port) |
136 | int net_connect(int port) |
137 | { |
137 | { |
138 | struct sockaddr_in sin; |
138 | struct sockaddr_in sin; |
139 | int soc, vrai; |
139 | int soc, vrai; |
140 | 140 | ||
141 | if ((soc = socket(AF_INET, SOCK_STREAM, 0)) == -1) |
141 | if ((soc = socket(AF_INET, SOCK_STREAM, 0)) == -1) |
142 | errorquit("socket() error"); |
142 | errorquit("socket() error"); |
143 | if(setsockopt(soc, SOL_SOCKET, SO_REUSEADDR, &vrai, sizeof(vrai)) == -1) |
143 | if(setsockopt(soc, SOL_SOCKET, SO_REUSEADDR, &vrai, sizeof(vrai)) == -1) |
144 | errorquit("setsockopt() error"); |
144 | errorquit("setsockopt() error"); |
145 | 145 | ||
146 | sin.sin_port=htons(port); |
146 | sin.sin_port=htons(port); |
Line 158... | Line 158... | ||
158 | long int siz; |
158 | long int siz; |
159 | char *p, namebuf[4096], buf[4096]; |
159 | char *p, namebuf[4096], buf[4096]; |
160 | char cbuf[MAX_LINELEN+1]; |
160 | char cbuf[MAX_LINELEN+1]; |
161 | struct stat st; |
161 | struct stat st; |
162 | FILE *f; |
162 | FILE *f; |
163 | 163 | ||
164 | if(fname[strlen(fname)-1]=='/') |
164 | if(fname[strlen(fname)-1]=='/') |
165 | snprintf(namebuf,sizeof(namebuf),"%sindex.html",fname); |
165 | snprintf(namebuf,sizeof(namebuf),"%sindex.html",fname); |
166 | else snprintf(namebuf,sizeof(namebuf),"%s",fname); |
166 | else snprintf(namebuf,sizeof(namebuf),"%s",fname); |
167 | statit: if(stat(namebuf,&st)!=0) badreq(); |
167 | statit: if(stat(namebuf,&st)!=0) badreq(); |
168 | if(S_ISDIR(st.st_mode)) { |
168 | if(S_ISDIR(st.st_mode)) { |
Line 244... | Line 244... | ||
244 | setenv("REQUEST_METHOD",query_method,1); |
244 | setenv("REQUEST_METHOD",query_method,1); |
245 | setenv("SERVER_SOFTWARE","WIMS",1); |
245 | setenv("SERVER_SOFTWARE","WIMS",1); |
246 | snprintf(buf2,sizeof(buf2),"%d",sport); |
246 | snprintf(buf2,sizeof(buf2),"%d",sport); |
247 | setenv("SERVER_PORT",buf2,1); |
247 | setenv("SERVER_PORT",buf2,1); |
248 | for(; *parms; parms=p) { |
248 | for(; *parms; parms=p) { |
249 | p=strchr(parms,'\n'); |
249 | p=strchr(parms,'\n'); |
250 | if(p==NULL) p=parms+strlen(parms); |
250 | if(p==NULL) p=parms+strlen(parms); |
251 | else { |
251 | else { |
252 | if(*(p-1)=='\r') *(p-1)=0; |
252 | if(*(p-1)=='\r') *(p-1)=0; |
253 | *p++=0; |
253 | *p++=0; |
254 | } |
254 | } |
Line 259... | Line 259... | ||
259 | if(*p2=='-') *p2='_'; else *p2=toupper(*p2); |
259 | if(*p2=='-') *p2='_'; else *p2=toupper(*p2); |
260 | } |
260 | } |
261 | if(strcmp(parms,"CONTENT_LENGTH")==0 || |
261 | if(strcmp(parms,"CONTENT_LENGTH")==0 || |
262 | strcmp(parms,"CONTENT_TYPE")==0) { |
262 | strcmp(parms,"CONTENT_TYPE")==0) { |
263 | snprintf(buf2,sizeof(buf2),"%s",parms); |
263 | snprintf(buf2,sizeof(buf2),"%s",parms); |
264 | setenv(buf2,pp,1); |
264 | setenv(buf2,pp,1); |
265 | } |
265 | } |
266 | snprintf(buf2,sizeof(buf2),"HTTP_%s",parms); |
266 | snprintf(buf2,sizeof(buf2),"HTTP_%s",parms); |
267 | setenv(buf2,pp,1); |
267 | setenv(buf2,pp,1); |
268 | } |
268 | } |
269 | } |
269 | } |
270 | setenv("REMOTE_ADDR",inet_ntoa(saddr.sin_addr),1); |
270 | setenv("REMOTE_ADDR",inet_ntoa(saddr.sin_addr),1); |
271 | snprintf(buf2,sizeof(buf2),"%u",ntohs(saddr.sin_port)); |
271 | snprintf(buf2,sizeof(buf2),"%u",ntohs(saddr.sin_port)); |
272 | setenv("REMOTE_PORT",buf2,1); |
272 | setenv("REMOTE_PORT",buf2,1); |
273 | 273 | ||
274 | snprintf(buf2,sizeof(buf2),".%s",query_url); |
274 | snprintf(buf2,sizeof(buf2),".%s",query_url); |
275 | execl(buf2,buf2,NULL); |
275 | execl(buf2,buf2,NULL); |
276 | 276 | ||
277 | /* fclose(fout); fclose(fin); */ close(soc); exit(0); |
277 | /* fclose(fout); fclose(fin); */ close(soc); exit(0); |
278 | } |
278 | } |
279 | 279 | ||
280 | void serve(int soc) |
280 | void serve(int soc) |
281 | { |
281 | { |
282 | int newsoc; |
282 | int newsoc; |
283 | socklen_t slen=sizeof(saddr); |
283 | socklen_t slen=sizeof(saddr); |
284 | 284 | ||
285 | wait: |
285 | wait: |
286 | alarm(WIMSD_TICK); |
286 | alarm(WIMSD_TICK); |
287 | newsoc=accept(soc,(struct sockaddr *)&saddr, &slen); |
287 | newsoc=accept(soc,(struct sockaddr *)&saddr, &slen); |
288 | if(newsoc==-1) errorquit("accept() error"); |
288 | if(newsoc==-1) errorquit("accept() error"); |
289 | checkpid(); idle=0; |
289 | checkpid(); idle=0; |
Line 323... | Line 323... | ||
323 | for security reasons!\n\n\ |
323 | for security reasons!\n\n\ |
324 | Run bin/wrapuid as root to set things up correctly.\n"); exit(1); |
324 | Run bin/wrapuid as root to set things up correctly.\n"); exit(1); |
325 | } |
325 | } |
326 | */ setreuid(geteuid(),getuid());setregid(getegid(),getgid()); |
326 | */ setreuid(geteuid(),getuid());setregid(getegid(),getgid()); |
327 | sock=net_connect(sport); |
327 | sock=net_connect(sport); |
328 | 328 | ||
329 | serve(sock); |
329 | serve(sock); |
330 | close(sock); return 0; |
330 | close(sock); return 0; |
331 | } |
331 | } |
332 | 332 |