Mercurial > hg > xemacs-beta
comparison lib-src/gnuserv.c @ 149:538048ae2ab8 r20-3b1
Import from CVS: tag r20-3b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:36:16 +0200 |
parents | 360340f9fd5f |
children | 0132846995bd |
comparison
equal
deleted
inserted
replaced
148:f659db2a1f73 | 149:538048ae2ab8 |
---|---|
49 | 49 |
50 #include <stdlib.h> | 50 #include <stdlib.h> |
51 #include <stdio.h> | 51 #include <stdio.h> |
52 #include <sys/types.h> | 52 #include <sys/types.h> |
53 #include <sys/stat.h> | 53 #include <sys/stat.h> |
54 | |
55 #ifdef HAVE_UNISTD_H | |
54 #include <unistd.h> | 56 #include <unistd.h> |
57 #endif /* HAVE_UNISTD_H */ | |
58 #ifdef HAVE_STRING_H | |
55 #include <string.h> | 59 #include <string.h> |
60 #endif /* HAVE_STRING_H */ | |
56 | 61 |
57 #if !defined(SYSV_IPC) && !defined(UNIX_DOMAIN_SOCKETS) && \ | 62 #if !defined(SYSV_IPC) && !defined(UNIX_DOMAIN_SOCKETS) && \ |
58 !defined(INTERNET_DOMAIN_SOCKETS) | 63 !defined(INTERNET_DOMAIN_SOCKETS) |
59 main () | 64 main () |
60 { | 65 { |
72 | 77 |
73 /* | 78 /* |
74 ipc_exit -- clean up the queue id and queue, then kill the watchdog task | 79 ipc_exit -- clean up the queue id and queue, then kill the watchdog task |
75 if it exists. exit with the given status. | 80 if it exists. exit with the given status. |
76 */ | 81 */ |
77 void ipc_exit(stat) | 82 void |
78 int stat; | 83 ipc_exit (int stat) |
79 { | 84 { |
80 msgctl(ipc_qid,IPC_RMID,0); | 85 msgctl (ipc_qid,IPC_RMID,0); |
81 | 86 |
82 if (ipc_wpid != 0) | 87 if (ipc_wpid != 0) |
83 kill(ipc_wpid,SIGKILL); | 88 kill (ipc_wpid, SIGKILL); |
84 | 89 |
85 exit(stat); | 90 exit (stat); |
86 } /* ipc_exit */ | 91 } /* ipc_exit */ |
87 | 92 |
88 | 93 |
89 /* | 94 /* |
90 ipc_handle_signal -- catch the signal given and clean up. | 95 ipc_handle_signal -- catch the signal given and clean up. |
91 */ | 96 */ |
92 void ipc_handle_signal(sig) | 97 void |
93 int sig; | 98 ipc_handle_signal(int sig) |
94 { | 99 { |
95 ipc_exit(0); | 100 ipc_exit (0); |
96 } /* ipc_handle_signal */ | 101 } /* ipc_handle_signal */ |
97 | 102 |
98 | 103 |
99 /* | 104 /* |
100 ipc_spawn_watchdog -- spawn a watchdog task to clean up the message queue should the | 105 ipc_spawn_watchdog -- spawn a watchdog task to clean up the message queue should the |
101 server process die. | 106 server process die. |
102 */ | 107 */ |
103 void ipc_spawn_watchdog() | 108 void |
104 { | 109 ipc_spawn_watchdog (void) |
105 if ((ipc_wpid = fork()) == 0) { /* child process */ | 110 { |
106 int ppid = getppid(); /* parent's process id */ | 111 if ((ipc_wpid = fork ()) == 0) |
107 | 112 { /* child process */ |
108 setpgrp(); /* gnu kills process group on exit */ | 113 int ppid = getppid (); /* parent's process id */ |
109 | 114 |
110 while (1) { | 115 setpgrp(); /* gnu kills process group on exit */ |
111 if (kill(ppid,0) < 0) { /* ppid is no longer valid, parent may have died */ | 116 |
112 ipc_exit(0); | 117 while (1) |
113 } /* if */ | 118 { |
114 | 119 if (kill (ppid, 0) < 0) /* ppid is no longer valid, parent |
115 sleep(10); /* have another go later */ | 120 may have died */ |
116 } /* while */ | 121 { |
117 } /* if */ | 122 ipc_exit (0); |
123 } /* if */ | |
124 | |
125 sleep(10); /* have another go later */ | |
126 } /* while */ | |
127 } /* if */ | |
118 | 128 |
119 } /* ipc_spawn_watchdog */ | 129 } /* ipc_spawn_watchdog */ |
120 | 130 |
121 | 131 |
122 /* | 132 /* |
123 ipc_init -- initialize server, setting the global msqid that can be listened on. | 133 ipc_init -- initialize server, setting the global msqid that can be listened on. |
124 */ | 134 */ |
125 void ipc_init(msgpp) | 135 void |
126 struct msgbuf **msgpp; | 136 ipc_init (struct msgbuf **msgpp) |
127 { | 137 { |
128 key_t key; /* messge key */ | 138 key_t key; /* messge key */ |
129 char buf[GSERV_BUFSZ]; /* pathname for key */ | 139 char buf[GSERV_BUFSZ]; /* pathname for key */ |
130 | 140 |
131 sprintf(buf,"/tmp/gsrv%d",(int)geteuid()); | 141 sprintf (buf,"/tmp/gsrv%d",(int)geteuid ()); |
132 creat(buf,0600); | 142 creat (buf,0600); |
133 key = ftok(buf,1); | 143 key = ftok (buf,1); |
134 | 144 |
135 if ((ipc_qid = msgget(key,0600|IPC_CREAT)) == -1) { | 145 if ((ipc_qid = msgget (key,0600|IPC_CREAT)) == -1) |
136 perror(progname); | 146 { |
137 fprintf(stderr,"%s: unable to create msg queue\n",progname); | 147 perror (progname); |
138 ipc_exit(1); | 148 fprintf (stderr, "%s: unable to create msg queue\n", progname); |
139 } /* if */ | 149 ipc_exit (1); |
140 | 150 } /* if */ |
141 ipc_spawn_watchdog(); | 151 |
142 | 152 ipc_spawn_watchdog (); |
143 signal(SIGTERM,ipc_handle_signal); | 153 |
144 signal(SIGINT,ipc_handle_signal); | 154 signal (SIGTERM,ipc_handle_signal); |
145 | 155 signal (SIGINT,ipc_handle_signal); |
146 if ((*msgpp = (struct msgbuf *) | 156 |
147 malloc(sizeof **msgpp + GSERV_BUFSZ)) == NULL) { | 157 if ((*msgpp = (struct msgbuf *) |
148 fprintf(stderr, | 158 malloc (sizeof **msgpp + GSERV_BUFSZ)) == NULL) |
149 "%s: unable to allocate space for message buffer\n",progname); | 159 { |
150 ipc_exit(1); | 160 fprintf (stderr, |
151 } /* if */ | 161 "%s: unable to allocate space for message buffer\n", progname); |
152 | 162 ipc_exit(1); |
163 } /* if */ | |
153 } /* ipc_init */ | 164 } /* ipc_init */ |
154 | 165 |
155 | 166 |
156 /* | 167 /* |
157 handle_ipc_request -- accept a request from a client, pass the request on | 168 handle_ipc_request -- accept a request from a client, pass the request on |
158 to the GNU Emacs process, then wait for its reply and | 169 to the GNU Emacs process, then wait for its reply and |
159 pass that on to the client. | 170 pass that on to the client. |
160 */ | 171 */ |
161 void handle_ipc_request(msgp) | 172 void |
162 struct msgbuf *msgp; /* message buffer */ | 173 handle_ipc_request (struct msgbuf *msgp) |
163 { | 174 { |
164 struct msqid_ds msg_st; /* message status */ | 175 struct msqid_ds msg_st; /* message status */ |
165 char buf[GSERV_BUFSZ]; | 176 char buf[GSERV_BUFSZ]; |
166 int len; /* length of message / read */ | 177 int len; /* length of message / read */ |
167 int s, result_len; /* tag fields on the response from emacs */ | 178 int s, result_len; /* tag fields on the response from emacs */ |
168 int offset = 0; | 179 int offset = 0; |
169 int total = 1; /* # bytes that will actually be sent off */ | 180 int total = 1; /* # bytes that will actually be sent off */ |
170 | 181 |
171 if ((len = msgrcv(ipc_qid,msgp,GSERV_BUFSZ-1,1,0)) < 0) { | 182 if ((len = msgrcv (ipc_qid, msgp, GSERV_BUFSZ - 1, 1, 0)) < 0) |
172 perror(progname); | 183 { |
173 fprintf(stderr,"%s: unable to receive\n",progname); | 184 perror (progname); |
174 ipc_exit(1); | 185 fprintf (stderr, "%s: unable to receive\n", progname); |
175 } /* if */ | 186 ipc_exit (1); |
176 | 187 } /* if */ |
177 msgctl(ipc_qid,IPC_STAT,&msg_st); | 188 |
178 strncpy(buf,msgp->mtext,len); | 189 msgctl (ipc_qid, IPC_STAT, &msg_st); |
190 strncpy (buf, msgp->mtext, len); | |
179 buf[len] = '\0'; /* terminate */ | 191 buf[len] = '\0'; /* terminate */ |
180 | 192 |
181 printf("%d %s",ipc_qid,buf); | 193 printf ("%d %s", ipc_qid, buf); |
182 fflush(stdout); | 194 fflush (stdout); |
183 | 195 |
184 /* now for the response from gnu */ | 196 /* now for the response from gnu */ |
185 msgp->mtext[0] = '\0'; | 197 msgp->mtext[0] = '\0'; |
186 | 198 |
187 #if 0 | 199 #if 0 |
188 if ((len = read(0,buf,GSERV_BUFSZ-1)) < 0) { | 200 if ((len = read(0,buf,GSERV_BUFSZ-1)) < 0) |
201 { | |
202 perror (progname); | |
203 fprintf (stderr, "%s: unable to read\n", progname); | |
204 ipc_exit (1); | |
205 } /* if */ | |
206 | |
207 sscanf (buf, "%d:%[^\n]\n", &junk, msgp->mtext); | |
208 #else | |
209 | |
210 /* read in "n/m:" (n=client fd, m=message length) */ | |
211 | |
212 while (offset < (GSERV_BUFSZ-1) && | |
213 ((len = read (0, buf + offset, 1)) > 0) && | |
214 buf[offset] != ':') | |
215 { | |
216 offset += len; | |
217 } | |
218 | |
219 if (len < 0) | |
220 { | |
221 perror (progname); | |
222 fprintf (stderr, "%s: unable to read\n", progname); | |
223 exit(1); | |
224 } | |
225 | |
226 /* parse the response from emacs, getting client fd & result length */ | |
227 buf[offset] = '\0'; | |
228 sscanf (buf, "%d/%d", &s, &result_len); | |
229 | |
230 while (result_len > 0) | |
231 { | |
232 if ((len = read(0, buf, min2 (result_len, GSERV_BUFSZ - 1))) < 0) | |
233 { | |
234 perror (progname); | |
235 fprintf (stderr, "%s: unable to read\n", progname); | |
236 exit (1); | |
237 } | |
238 | |
239 /* Send this string off, but only if we have enough space */ | |
240 | |
241 if (GSERV_BUFSZ > total) | |
242 { | |
243 if (total + len <= GSERV_BUFSZ) | |
244 buf[len] = 0; | |
245 else | |
246 buf[GSERV_BUFSZ - total] = 0; | |
247 | |
248 send_string(s,buf); | |
249 total += strlen(buf); | |
250 } | |
251 | |
252 result_len -= len; | |
253 } | |
254 | |
255 /* eat the newline */ | |
256 while ((len = read (0,buf,1)) == 0) | |
257 ; | |
258 if (len < 0) | |
259 { | |
260 perror(progname); | |
261 fprintf (stderr,"%s: unable to read\n", progname); | |
262 exit (1); | |
263 } | |
264 if (buf[0] != '\n') | |
265 { | |
266 fprintf (stderr,"%s: garbage after result [%c]\n", progname, buf[0]); | |
267 exit (1); | |
268 } | |
269 #endif | |
270 | |
271 /* Send a response back to the client. */ | |
272 | |
273 msgp->mtype = msg_st.msg_lspid; | |
274 if (msgsnd (ipc_qid,msgp,strlen(msgp->mtext)+1,0) < 0) | |
275 perror ("msgsend(gnuserv)"); | |
276 | |
277 } /* handle_ipc_request */ | |
278 #endif /* SYSV_IPC */ | |
279 | |
280 | |
281 #if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS) | |
282 /* | |
283 echo_request -- read request from a given socket descriptor, and send the information | |
284 to stdout (the gnu process). | |
285 */ | |
286 static void | |
287 echo_request (int s) | |
288 { | |
289 char buf[GSERV_BUFSZ]; | |
290 int len; | |
291 | |
292 printf("%d ",s); | |
293 | |
294 /* read until we get a newline or no characters */ | |
295 while ((len = recv(s,buf,GSERV_BUFSZ-1,0)) > 0) { | |
296 buf[len] = '\0'; | |
297 printf("%s",buf); | |
298 | |
299 if (buf[len-1] == EOT_CHR) { | |
300 fflush(stdout); | |
301 break; /* end of message */ | |
302 } | |
303 | |
304 } /* while */ | |
305 | |
306 if (len < 0) { | |
189 perror(progname); | 307 perror(progname); |
190 fprintf(stderr,"%s: unable to read\n",progname); | 308 fprintf(stderr,"%s: unable to recv\n",progname); |
191 ipc_exit(1); | 309 exit(1); |
192 } /* if */ | 310 } /* if */ |
193 | 311 |
194 sscanf(buf,"%d:%[^\n]\n",&junk,msgp->mtext); | 312 } /* echo_request */ |
195 #else | 313 |
314 | |
315 /* | |
316 handle_response -- accept a response from stdin (the gnu process) and pass the | |
317 information on to the relevant client. | |
318 */ | |
319 static void | |
320 handle_response (void) | |
321 { | |
322 char buf[GSERV_BUFSZ+1]; | |
323 int offset=0; | |
324 int s; | |
325 int len; | |
326 int result_len; | |
196 | 327 |
197 /* read in "n/m:" (n=client fd, m=message length) */ | 328 /* read in "n/m:" (n=client fd, m=message length) */ |
198 | 329 while (offset < GSERV_BUFSZ && |
199 while (offset < (GSERV_BUFSZ-1) && | |
200 ((len = read(0,buf+offset,1)) > 0) && | 330 ((len = read(0,buf+offset,1)) > 0) && |
201 buf[offset] != ':') { | 331 buf[offset] != ':') { |
202 offset += len; | 332 offset += len; |
203 } | 333 } |
204 | 334 |
211 /* parse the response from emacs, getting client fd & result length */ | 341 /* parse the response from emacs, getting client fd & result length */ |
212 buf[offset] = '\0'; | 342 buf[offset] = '\0'; |
213 sscanf(buf,"%d/%d", &s, &result_len); | 343 sscanf(buf,"%d/%d", &s, &result_len); |
214 | 344 |
215 while (result_len > 0) { | 345 while (result_len > 0) { |
216 if ((len = read(0,buf,min2(result_len, GSERV_BUFSZ - 1))) < 0) { | |
217 perror(progname); | |
218 fprintf(stderr,"%s: unable to read\n",progname); | |
219 exit(1); | |
220 } | |
221 | |
222 /* Send this string off, but only if we have enough space */ | |
223 | |
224 if (GSERV_BUFSZ > total) { | |
225 if (total + len <= GSERV_BUFSZ) | |
226 buf[len] = 0; | |
227 else | |
228 buf[GSERV_BUFSZ - total] = 0; | |
229 | |
230 send_string(s,buf); | |
231 total += strlen(buf); | |
232 } | |
233 | |
234 result_len -= len; | |
235 } | |
236 | |
237 /* eat the newline */ | |
238 while ((len = read(0,buf,1)) == 0) | |
239 ; | |
240 if (len < 0) { | |
241 perror(progname); | |
242 fprintf(stderr,"%s: unable to read\n",progname); | |
243 exit(1); | |
244 } | |
245 if (buf[0] != '\n') { | |
246 fprintf(stderr,"%s: garbage after result [%c]\n",progname, buf[0]); | |
247 exit(1); | |
248 } | |
249 #endif | |
250 | |
251 /* Send a response back to the client. */ | |
252 | |
253 msgp->mtype = msg_st.msg_lspid; | |
254 if (msgsnd(ipc_qid,msgp,strlen(msgp->mtext)+1,0) < 0) | |
255 perror("msgsend(gnuserv)"); | |
256 | |
257 } /* handle_ipc_request */ | |
258 #endif /* SYSV_IPC */ | |
259 | |
260 | |
261 #if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS) | |
262 /* | |
263 echo_request -- read request from a given socket descriptor, and send the information | |
264 to stdout (the gnu process). | |
265 */ | |
266 static void | |
267 echo_request (int s) | |
268 { | |
269 char buf[GSERV_BUFSZ]; | |
270 int len; | |
271 | |
272 printf("%d ",s); | |
273 | |
274 /* read until we get a newline or no characters */ | |
275 while ((len = recv(s,buf,GSERV_BUFSZ-1,0)) > 0) { | |
276 buf[len] = '\0'; | |
277 printf("%s",buf); | |
278 | |
279 if (buf[len-1] == EOT_CHR) { | |
280 fflush(stdout); | |
281 break; /* end of message */ | |
282 } | |
283 | |
284 } /* while */ | |
285 | |
286 if (len < 0) { | |
287 perror(progname); | |
288 fprintf(stderr,"%s: unable to recv\n",progname); | |
289 exit(1); | |
290 } /* if */ | |
291 | |
292 } /* echo_request */ | |
293 | |
294 | |
295 /* | |
296 handle_response -- accept a response from stdin (the gnu process) and pass the | |
297 information on to the relevant client. | |
298 */ | |
299 static void | |
300 handle_response (void) | |
301 { | |
302 char buf[GSERV_BUFSZ+1]; | |
303 int offset=0; | |
304 int s; | |
305 int len; | |
306 int result_len; | |
307 | |
308 /* read in "n/m:" (n=client fd, m=message length) */ | |
309 while (offset < GSERV_BUFSZ && | |
310 ((len = read(0,buf+offset,1)) > 0) && | |
311 buf[offset] != ':') { | |
312 offset += len; | |
313 } | |
314 | |
315 if (len < 0) { | |
316 perror(progname); | |
317 fprintf(stderr,"%s: unable to read\n",progname); | |
318 exit(1); | |
319 } | |
320 | |
321 /* parse the response from emacs, getting client fd & result length */ | |
322 buf[offset] = '\0'; | |
323 sscanf(buf,"%d/%d", &s, &result_len); | |
324 | |
325 while (result_len > 0) { | |
326 if ((len = read(0,buf,min2(result_len,GSERV_BUFSZ))) < 0) { | 346 if ((len = read(0,buf,min2(result_len,GSERV_BUFSZ))) < 0) { |
327 perror(progname); | 347 perror(progname); |
328 fprintf(stderr,"%s: unable to read\n",progname); | 348 fprintf(stderr,"%s: unable to read\n",progname); |
329 exit(1); | 349 exit(1); |
330 } | 350 } |
334 } | 354 } |
335 | 355 |
336 /* eat the newline */ | 356 /* eat the newline */ |
337 while ((len = read(0,buf,1)) == 0) | 357 while ((len = read(0,buf,1)) == 0) |
338 ; | 358 ; |
339 if (len < 0) { | 359 if (len < 0) |
340 perror(progname); | 360 { |
341 fprintf(stderr,"%s: unable to read\n",progname); | 361 perror(progname); |
342 exit(1); | 362 fprintf(stderr,"%s: unable to read\n",progname); |
343 } | 363 exit(1); |
344 if (buf[0] != '\n') { | 364 } |
345 fprintf(stderr,"%s: garbage after result\n",progname); | 365 if (buf[0] != '\n') |
346 exit(1); | 366 { |
347 } | 367 fprintf(stderr,"%s: garbage after result\n",progname); |
368 exit(1); | |
369 } | |
348 /* send the newline */ | 370 /* send the newline */ |
349 buf[1] = '\0'; | 371 buf[1] = '\0'; |
350 send_string(s,buf); | 372 send_string(s,buf); |
351 close(s); | 373 close(s); |
352 | 374 |
382 tv.tv_usec = 0; | 404 tv.tv_usec = 0; |
383 | 405 |
384 FD_ZERO(&rmask); | 406 FD_ZERO(&rmask); |
385 FD_SET(fd, &rmask); | 407 FD_SET(fd, &rmask); |
386 | 408 |
387 do { | 409 do |
388 r = select(fd + 1, &rmask, NULL, NULL, &tv); | 410 { |
389 | 411 r = select(fd + 1, &rmask, NULL, NULL, &tv); |
390 if (r > 0) { | 412 |
391 if (read (fd, &c, 1) == 1 ){ | 413 if (r > 0) |
392 *buf++ = c; | 414 { |
393 ++nbytes; | 415 if (read (fd, &c, 1) == 1 ) |
394 } else { | 416 { |
395 printf ("read error on socket\004\n"); | 417 *buf++ = c; |
396 return -1; | 418 ++nbytes; |
397 } | 419 } |
398 } else if (r == 0) { | 420 else |
399 printf ("read timed out\004\n"); | 421 { |
400 return -1; | 422 printf ("read error on socket\004\n"); |
401 } else { | 423 return -1; |
402 printf ("error in select\004\n"); | 424 } |
403 return -1; | 425 } |
404 } | 426 else if (r == 0) |
405 } while ((nbytes < max) && !(one_line && (c == '\n'))); | 427 { |
428 printf ("read timed out\004\n"); | |
429 return -1; | |
430 } | |
431 else | |
432 { | |
433 printf ("error in select\004\n"); | |
434 return -1; | |
435 } | |
436 } while ((nbytes < max) && !(one_line && (c == '\n'))); | |
406 | 437 |
407 --buf; | 438 --buf; |
408 if (one_line && *buf == '\n') { | 439 if (one_line && *buf == '\n') |
409 *buf = 0; | 440 { |
410 } | 441 *buf = 0; |
442 } | |
411 | 443 |
412 return nbytes; | 444 return nbytes; |
413 } | 445 } |
414 | 446 |
415 | 447 |
425 | 457 |
426 char auth_protocol[128]; | 458 char auth_protocol[128]; |
427 char buf[1024]; | 459 char buf[1024]; |
428 int auth_data_len; | 460 int auth_data_len; |
429 | 461 |
430 if (fd > 0) { | 462 if (fd > 0) |
431 /* we are checking permission on a real connection */ | 463 { |
432 | 464 /* we are checking permission on a real connection */ |
433 /* Read auth protocol name */ | 465 |
434 | 466 /* Read auth protocol name */ |
435 if (timed_read(fd, auth_protocol, AUTH_NAMESZ, AUTH_TIMEOUT, 1) <= 0) | 467 |
436 return FALSE; | 468 if (timed_read(fd, auth_protocol, AUTH_NAMESZ, AUTH_TIMEOUT, 1) <= 0) |
437 | 469 return FALSE; |
438 if (strcmp (auth_protocol, DEFAUTH_NAME) && | 470 |
439 strcmp (auth_protocol, MCOOKIE_NAME)) { | 471 if (strcmp (auth_protocol, DEFAUTH_NAME) && |
440 printf ("authentication protocol (%s) from client is invalid...\n", | 472 strcmp (auth_protocol, MCOOKIE_NAME)) |
441 auth_protocol); | 473 { |
442 printf ("... Was the client an old version of gnuclient/gnudoit?\004\n"); | 474 printf ("authentication protocol (%s) from client is invalid...\n", |
475 auth_protocol); | |
476 printf ("... Was the client an old version of gnuclient/gnudoit?\004\n"); | |
443 | 477 |
444 return FALSE; | 478 return FALSE; |
445 } | 479 } |
446 | 480 |
447 if (!strcmp(auth_protocol, MCOOKIE_NAME)) { | 481 if (!strcmp(auth_protocol, MCOOKIE_NAME)) |
448 | 482 { |
449 /* | 483 |
450 * doing magic cookie auth | 484 /* |
451 */ | 485 * doing magic cookie auth |
452 | 486 */ |
453 if (timed_read(fd, buf, 10, AUTH_TIMEOUT, 1) <= 0) | 487 |
454 return FALSE; | 488 if (timed_read(fd, buf, 10, AUTH_TIMEOUT, 1) <= 0) |
455 | 489 return FALSE; |
456 auth_data_len = atoi(buf); | 490 |
457 | 491 auth_data_len = atoi(buf); |
458 if (timed_read(fd, buf, auth_data_len, AUTH_TIMEOUT, 0) != auth_data_len) | 492 |
459 return FALSE; | 493 if (timed_read(fd, buf, auth_data_len, AUTH_TIMEOUT, 0) != auth_data_len) |
494 return FALSE; | |
460 | 495 |
461 #ifdef AUTH_MAGIC_COOKIE | 496 #ifdef AUTH_MAGIC_COOKIE |
462 if (server_xauth && server_xauth->data && | 497 if (server_xauth && server_xauth->data && |
463 !memcmp(buf, server_xauth->data, auth_data_len)) { | 498 !memcmp(buf, server_xauth->data, auth_data_len)) |
464 return TRUE; | 499 { |
465 } | 500 return TRUE; |
501 } | |
466 #else | 502 #else |
467 printf ("client tried Xauth, but server is not compiled with Xauth\n"); | 503 printf ("client tried Xauth, but server is not compiled with Xauth\n"); |
468 #endif | 504 #endif |
469 | 505 |
470 /* | 506 /* |
471 * auth failed, but allow this to fall through to the GNU_SECURE | 507 * auth failed, but allow this to fall through to the GNU_SECURE |
472 * protocol.... | 508 * protocol.... |
473 */ | 509 */ |
474 | 510 |
475 printf ("Xauth authentication failed, trying GNU_SECURE auth...\004\n"); | 511 printf ("Xauth authentication failed, trying GNU_SECURE auth...\004\n"); |
476 | 512 |
477 } | 513 } |
478 | 514 |
479 /* Other auth protocols go here, and should execute only if the | 515 /* Other auth protocols go here, and should execute only if the |
480 * auth_protocol name matches. | 516 * auth_protocol name matches. |
481 */ | 517 */ |
482 | 518 |
483 } | 519 } |
484 | 520 |
485 | 521 |
486 /* Now, try the old GNU_SECURE stuff... */ | 522 /* Now, try the old GNU_SECURE stuff... */ |
487 | 523 |
488 /* First find the hash key */ | 524 /* First find the hash key */ |
506 add_host (u_long host_addr) | 542 add_host (u_long host_addr) |
507 { | 543 { |
508 int key; | 544 int key; |
509 struct entry *new_entry; | 545 struct entry *new_entry; |
510 | 546 |
511 if (!permitted(host_addr, -1)) { | 547 if (!permitted(host_addr, -1)) |
512 if ((new_entry = (struct entry *) malloc(sizeof(struct entry))) == NULL) { | 548 { |
513 fprintf(stderr,"%s: unable to malloc space for permitted host entry\n", | 549 if ((new_entry = (struct entry *) malloc(sizeof(struct entry))) == NULL) { |
514 progname); | 550 fprintf(stderr,"%s: unable to malloc space for permitted host entry\n", |
515 exit(1); | 551 progname); |
516 } /* if */ | 552 exit(1); |
517 | 553 } /* if */ |
518 new_entry->host_addr = host_addr; | 554 |
519 key = HASH(host_addr) % TABLE_SIZE; | 555 new_entry->host_addr = host_addr; |
520 new_entry->next = permitted_hosts[key]; | 556 key = HASH(host_addr) % TABLE_SIZE; |
521 permitted_hosts[key] = new_entry; | 557 new_entry->next = permitted_hosts[key]; |
522 } /* if */ | 558 permitted_hosts[key] = new_entry; |
559 } /* if */ | |
523 | 560 |
524 } /* add_host */ | 561 } /* add_host */ |
525 | 562 |
526 | 563 |
527 /* | 564 /* |
545 for (i=0; i<TABLE_SIZE; i++) | 582 for (i=0; i<TABLE_SIZE; i++) |
546 permitted_hosts[i] = NULL; | 583 permitted_hosts[i] = NULL; |
547 | 584 |
548 gethostname(hostname,HOSTNAMSZ); | 585 gethostname(hostname,HOSTNAMSZ); |
549 | 586 |
550 if ((host_addr = internet_addr(hostname)) == -1) { | 587 if ((host_addr = internet_addr(hostname)) == -1) |
551 fprintf(stderr,"%s: unable to find %s in /etc/hosts or from YP", | 588 { |
552 progname,hostname); | 589 fprintf(stderr,"%s: unable to find %s in /etc/hosts or from YP", |
553 exit(1); | 590 progname,hostname); |
554 } /* if */ | 591 exit(1); |
592 } /* if */ | |
555 | 593 |
556 #ifdef AUTH_MAGIC_COOKIE | 594 #ifdef AUTH_MAGIC_COOKIE |
557 | 595 |
558 server_xauth = XauGetAuthByAddr (FamilyInternet, | 596 server_xauth = XauGetAuthByAddr (FamilyInternet, |
559 sizeof(host_addr), (char *)&host_addr, | 597 sizeof(host_addr), (char *)&host_addr, |
567 #if 0 /* Don't even want to allow access from the local host by default */ | 605 #if 0 /* Don't even want to allow access from the local host by default */ |
568 add_host(host_addr); /* add local host */ | 606 add_host(host_addr); /* add local host */ |
569 #endif | 607 #endif |
570 | 608 |
571 if (((file_name = getenv("GNU_SECURE")) != NULL && /* security file */ | 609 if (((file_name = getenv("GNU_SECURE")) != NULL && /* security file */ |
572 (host_file = fopen(file_name,"r")) != NULL)) { /* opened ok */ | 610 (host_file = fopen(file_name,"r")) != NULL)) /* opened ok */ |
573 while ((fscanf(host_file,"%s",hostname) != EOF)) /* find a host */ | 611 { |
574 if ((host_addr = internet_addr(hostname)) != -1) {/* get its addr */ | 612 while ((fscanf(host_file,"%s",hostname) != EOF)) /* find a host */ |
575 add_host(host_addr); /* add the addr */ | 613 if ((host_addr = internet_addr(hostname)) != -1)/* get its addr */ |
576 hosts++; | 614 { |
577 } | 615 add_host(host_addr); /* add the addr */ |
578 fclose(host_file); | 616 hosts++; |
579 } /* if */ | 617 } |
618 fclose(host_file); | |
619 } /* if */ | |
580 | 620 |
581 return hosts; | 621 return hosts; |
582 } /* setup_table */ | 622 } /* setup_table */ |
583 | 623 |
584 | 624 |
613 server.sin_port = htons(DEFAULT_PORT+getuid()); | 653 server.sin_port = htons(DEFAULT_PORT+getuid()); |
614 else | 654 else |
615 server.sin_port = sp->s_port; | 655 server.sin_port = sp->s_port; |
616 | 656 |
617 /* Create the listen socket. */ | 657 /* Create the listen socket. */ |
618 if ((ls = socket (AF_INET,SOCK_STREAM, 0)) == -1) { | 658 if ((ls = socket (AF_INET,SOCK_STREAM, 0)) == -1) |
619 perror(progname); | 659 { |
620 fprintf(stderr,"%s: unable to create socket\n",progname); | 660 perror(progname); |
621 exit(1); | 661 fprintf(stderr,"%s: unable to create socket\n",progname); |
622 } /* if */ | 662 exit(1); |
663 } /* if */ | |
623 | 664 |
624 /* Bind the listen address to the socket. */ | 665 /* Bind the listen address to the socket. */ |
625 if (bind(ls,(struct sockaddr *) &server,sizeof(struct sockaddr_in)) == -1) { | 666 if (bind(ls,(struct sockaddr *) &server,sizeof(struct sockaddr_in)) == -1) |
626 perror(progname); | 667 { |
627 fprintf(stderr,"%s: unable to bind socket\n",progname); | 668 perror(progname); |
628 exit(1); | 669 fprintf(stderr,"%s: unable to bind socket\n",progname); |
629 } /* if */ | 670 exit(1); |
671 } /* if */ | |
630 | 672 |
631 /* Initiate the listen on the socket so remote users | 673 /* Initiate the listen on the socket so remote users |
632 * can connect. | 674 * can connect. |
633 */ | 675 */ |
634 if (listen(ls,20) == -1) { | 676 if (listen(ls,20) == -1) |
635 perror(progname); | 677 { |
636 fprintf(stderr,"%s: unable to listen\n",progname); | 678 perror(progname); |
637 exit(1); | 679 fprintf(stderr,"%s: unable to listen\n",progname); |
638 } /* if */ | 680 exit(1); |
681 } /* if */ | |
639 | 682 |
640 return(ls); | 683 return(ls); |
641 | 684 |
642 } /* internet_init */ | 685 } /* internet_init */ |
643 | 686 |
653 int addrlen = sizeof(struct sockaddr_in); | 696 int addrlen = sizeof(struct sockaddr_in); |
654 struct sockaddr_in peer; /* for peer socket address */ | 697 struct sockaddr_in peer; /* for peer socket address */ |
655 | 698 |
656 memset((char *)&peer,0,sizeof(struct sockaddr_in)); | 699 memset((char *)&peer,0,sizeof(struct sockaddr_in)); |
657 | 700 |
658 if ((s = accept(ls,(struct sockaddr *)&peer,&addrlen)) == -1) { | 701 if ((s = accept(ls,(struct sockaddr *)&peer,&addrlen)) == -1) |
659 perror(progname); | 702 { |
660 fprintf(stderr,"%s: unable to accept\n",progname); | 703 perror(progname); |
661 exit(1); | 704 fprintf(stderr,"%s: unable to accept\n",progname); |
662 } /* if */ | 705 exit(1); |
706 } /* if */ | |
663 | 707 |
664 /* Check that access is allowed - if not return crud to the client */ | 708 /* Check that access is allowed - if not return crud to the client */ |
665 if (!permitted(peer.sin_addr.s_addr, s)) { | 709 if (!permitted(peer.sin_addr.s_addr, s)) |
666 send_string(s,"gnudoit: Connection refused\ngnudoit: unable to connect to remote"); | 710 { |
667 close(s); | 711 send_string(s,"gnudoit: Connection refused\ngnudoit: unable to connect to remote"); |
668 | 712 close(s); |
669 printf("Refused connection from %s\004\n", inet_ntoa(peer.sin_addr)); | 713 |
670 return; | 714 printf("Refused connection from %s\004\n", inet_ntoa(peer.sin_addr)); |
671 } /* if */ | 715 return; |
716 } /* if */ | |
672 | 717 |
673 echo_request(s); | 718 echo_request(s); |
674 | 719 |
675 } /* handle_internet_request */ | 720 } /* handle_internet_request */ |
676 #endif /* INTERNET_DOMAIN_SOCKETS */ | 721 #endif /* INTERNET_DOMAIN_SOCKETS */ |
686 { | 731 { |
687 int ls; /* socket descriptor */ | 732 int ls; /* socket descriptor */ |
688 struct sockaddr_un server; /* unix socket address */ | 733 struct sockaddr_un server; /* unix socket address */ |
689 int bindlen; | 734 int bindlen; |
690 | 735 |
691 if ((ls = socket(AF_UNIX,SOCK_STREAM, 0)) < 0) { | 736 if ((ls = socket(AF_UNIX,SOCK_STREAM, 0)) < 0) |
692 perror(progname); | 737 { |
693 fprintf(stderr,"%s: unable to create socket\n",progname); | 738 perror(progname); |
694 exit(1); | 739 fprintf(stderr,"%s: unable to create socket\n",progname); |
695 } /* if */ | 740 exit(1); |
741 } /* if */ | |
696 | 742 |
697 /* Set up address structure for the listen socket. */ | 743 /* Set up address structure for the listen socket. */ |
698 #ifdef HIDE_UNIX_SOCKET | 744 #ifdef HIDE_UNIX_SOCKET |
699 sprintf(server.sun_path,"/tmp/gsrvdir%d",(int)geteuid()); | 745 sprintf(server.sun_path,"/tmp/gsrvdir%d",(int)geteuid()); |
700 if (mkdir(server.sun_path, 0700) < 0) { | 746 if (mkdir(server.sun_path, 0700) < 0) |
701 /* assume it already exists, and try to set perms */ | 747 { |
702 if (chmod(server.sun_path, 0700) < 0) { | 748 /* assume it already exists, and try to set perms */ |
703 perror(progname); | 749 if (chmod(server.sun_path, 0700) < 0) |
704 fprintf(stderr,"%s: can't set permissions on %s\n", | 750 { |
705 progname, server.sun_path); | 751 perror(progname); |
706 exit(1); | 752 fprintf(stderr,"%s: can't set permissions on %s\n", |
707 } | 753 progname, server.sun_path); |
708 } | 754 exit(1); |
755 } | |
756 } | |
709 strcat(server.sun_path,"/gsrv"); | 757 strcat(server.sun_path,"/gsrv"); |
710 unlink(server.sun_path); /* remove old file if it exists */ | 758 unlink(server.sun_path); /* remove old file if it exists */ |
711 #else /* HIDE_UNIX_SOCKET */ | 759 #else /* HIDE_UNIX_SOCKET */ |
712 sprintf(server.sun_path,"/tmp/gsrv%d",(int)geteuid()); | 760 sprintf(server.sun_path,"/tmp/gsrv%d",(int)geteuid()); |
713 unlink(server.sun_path); /* remove old file if it exists */ | 761 unlink(server.sun_path); /* remove old file if it exists */ |
722 server.sun_len = bindlen; | 770 server.sun_len = bindlen; |
723 #else | 771 #else |
724 bindlen = strlen (server.sun_path) + sizeof (server.sun_family); | 772 bindlen = strlen (server.sun_path) + sizeof (server.sun_family); |
725 #endif | 773 #endif |
726 | 774 |
727 if (bind(ls,(struct sockaddr *)&server,bindlen) < 0) { | 775 if (bind(ls,(struct sockaddr *)&server,bindlen) < 0) |
728 perror(progname); | 776 { |
729 fprintf(stderr,"%s: unable to bind socket\n",progname); | 777 perror(progname); |
730 exit(1); | 778 fprintf(stderr,"%s: unable to bind socket\n",progname); |
731 } /* if */ | 779 exit(1); |
780 } /* if */ | |
732 | 781 |
733 chmod(server.sun_path,0700); /* only this user can send commands */ | 782 chmod(server.sun_path,0700); /* only this user can send commands */ |
734 | 783 |
735 if (listen(ls,20) < 0) { | 784 if (listen(ls,20) < 0) { |
736 perror(progname); | 785 perror(progname); |
767 int len = sizeof(struct sockaddr_un); | 816 int len = sizeof(struct sockaddr_un); |
768 struct sockaddr_un server; /* for unix socket address */ | 817 struct sockaddr_un server; /* for unix socket address */ |
769 | 818 |
770 server.sun_family = AF_UNIX; | 819 server.sun_family = AF_UNIX; |
771 | 820 |
772 if ((s = accept(ls,(struct sockaddr *)&server,&len)) < 0) { | 821 if ((s = accept(ls,(struct sockaddr *)&server,&len)) < 0) |
773 perror(progname); | 822 { |
774 fprintf(stderr,"%s: unable to accept\n",progname); | 823 perror(progname); |
775 } /* if */ | 824 fprintf(stderr,"%s: unable to accept\n",progname); |
825 } /* if */ | |
776 | 826 |
777 echo_request(s); | 827 echo_request(s); |
778 | 828 |
779 } /* handle_unix_request */ | 829 } /* handle_unix_request */ |
780 #endif /* UNIX_DOMAIN_SOCKETS */ | 830 #endif /* UNIX_DOMAIN_SOCKETS */ |
832 FD_SET(uls, &rmask); | 882 FD_SET(uls, &rmask); |
833 if (ils >= 0) | 883 if (ils >= 0) |
834 FD_SET(ils, &rmask); | 884 FD_SET(ils, &rmask); |
835 | 885 |
836 if (select(max2(fileno(stdin),max2(uls,ils)) + 1, &rmask, | 886 if (select(max2(fileno(stdin),max2(uls,ils)) + 1, &rmask, |
837 (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)NULL) < 0) { | 887 (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)NULL) < 0) |
838 perror(progname); | 888 { |
839 fprintf(stderr,"%s: unable to select\n",progname); | 889 perror(progname); |
840 exit(1); | 890 fprintf(stderr,"%s: unable to select\n",progname); |
841 } /* if */ | 891 exit(1); |
892 } /* if */ | |
842 | 893 |
843 #ifdef UNIX_DOMAIN_SOCKETS | 894 #ifdef UNIX_DOMAIN_SOCKETS |
844 if (uls > 0 && FD_ISSET(uls, &rmask)) | 895 if (uls > 0 && FD_ISSET(uls, &rmask)) |
845 handle_unix_request(uls); | 896 handle_unix_request(uls); |
846 #endif | 897 #endif |