Commit | Line | Data |
---|---|---|
051b1e55 | 1 | /* |
c9686c12 KB |
2 | * Copyright (c) 1983 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
6 | * provided that the above copyright notice and this paragraph are | |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
051b1e55 DF |
16 | */ |
17 | ||
05862919 | 18 | #ifndef lint |
435e8dff | 19 | static char sccsid[] = "@(#)cmds.c 5.10 (Berkeley) %G%"; |
c9686c12 | 20 | #endif /* not lint */ |
05862919 | 21 | |
22daf918 | 22 | #include "tip.h" |
435e8dff KB |
23 | #include "pathnames.h" |
24 | ||
22daf918 BJ |
25 | /* |
26 | * tip | |
27 | * | |
28 | * miscellaneous commands | |
29 | */ | |
30 | ||
31 | int quant[] = { 60, 60, 24 }; | |
32 | ||
33 | char null = '\0'; | |
34 | char *sep[] = { "second", "minute", "hour" }; | |
35 | static char *argv[10]; /* argument vector for take and put */ | |
36 | ||
37 | int timeout(); /* timeout function called on alarm */ | |
38 | int stopsnd(); /* SIGINT handler during file transfers */ | |
39 | int intprompt(); /* used in handling SIG_INT during prompt */ | |
40 | int intcopy(); /* interrupt routine for file transfers */ | |
41 | ||
42 | /* | |
43 | * FTP - remote ==> local | |
44 | * get a file from the remote host | |
45 | */ | |
46 | getfl(c) | |
47 | char c; | |
48 | { | |
05862919 | 49 | char buf[256], *cp, *expand(); |
22daf918 BJ |
50 | |
51 | putchar(c); | |
52 | /* | |
53 | * get the UNIX receiving file's name | |
54 | */ | |
55 | if (prompt("Local file name? ", copyname)) | |
56 | return; | |
05862919 SL |
57 | cp = expand(copyname); |
58 | if ((sfd = creat(cp, 0666)) < 0) { | |
22daf918 BJ |
59 | printf("\r\n%s: cannot creat\r\n", copyname); |
60 | return; | |
61 | } | |
62 | ||
63 | /* | |
64 | * collect parameters | |
65 | */ | |
66 | if (prompt("List command for remote system? ", buf)) { | |
67 | unlink(copyname); | |
68 | return; | |
69 | } | |
70 | transfer(buf, sfd, value(EOFREAD)); | |
71 | } | |
72 | ||
73 | /* | |
74 | * Cu-like take command | |
75 | */ | |
76 | cu_take(cc) | |
77 | char cc; | |
78 | { | |
79 | int fd, argc; | |
05862919 | 80 | char line[BUFSIZ], *expand(), *cp; |
22daf918 BJ |
81 | |
82 | if (prompt("[take] ", copyname)) | |
83 | return; | |
84 | if ((argc = args(copyname, argv)) < 1 || argc > 2) { | |
85 | printf("usage: <take> from [to]\r\n"); | |
86 | return; | |
87 | } | |
88 | if (argc == 1) | |
89 | argv[1] = argv[0]; | |
05862919 SL |
90 | cp = expand(argv[1]); |
91 | if ((fd = creat(cp, 0666)) < 0) { | |
22daf918 BJ |
92 | printf("\r\n%s: cannot create\r\n", argv[1]); |
93 | return; | |
94 | } | |
6b46907f | 95 | sprintf(line, "cat %s;echo \01", argv[0]); |
22daf918 BJ |
96 | transfer(line, fd, "\01"); |
97 | } | |
98 | ||
05862919 | 99 | static jmp_buf intbuf; |
22daf918 BJ |
100 | /* |
101 | * Bulk transfer routine -- | |
102 | * used by getfl(), cu_take(), and pipefile() | |
103 | */ | |
104 | transfer(buf, fd, eofchars) | |
105 | char *buf, *eofchars; | |
106 | { | |
107 | register int ct; | |
108 | char c, buffer[BUFSIZ]; | |
109 | register char *p = buffer; | |
110 | register int cnt, eof; | |
111 | time_t start; | |
05862919 | 112 | int (*f)(); |
22daf918 | 113 | |
6b46907f | 114 | pwrite(FD, buf, size(buf)); |
22daf918 | 115 | quit = 0; |
22daf918 BJ |
116 | kill(pid, SIGIOT); |
117 | read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ | |
118 | ||
119 | /* | |
120 | * finish command | |
121 | */ | |
6b46907f | 122 | pwrite(FD, "\r", 1); |
22daf918 BJ |
123 | do |
124 | read(FD, &c, 1); | |
125 | while ((c&0177) != '\n'); | |
126 | ioctl(0, TIOCSETC, &defchars); | |
127 | ||
ab76a038 | 128 | (void) setjmp(intbuf); |
05862919 | 129 | f = signal(SIGINT, intcopy); |
22daf918 BJ |
130 | start = time(0); |
131 | for (ct = 0; !quit;) { | |
132 | eof = read(FD, &c, 1) <= 0; | |
133 | c &= 0177; | |
134 | if (quit) | |
135 | continue; | |
136 | if (eof || any(c, eofchars)) | |
137 | break; | |
138 | if (c == 0) | |
139 | continue; /* ignore nulls */ | |
140 | if (c == '\r') | |
141 | continue; | |
142 | *p++ = c; | |
143 | ||
144 | if (c == '\n' && boolean(value(VERBOSE))) | |
145 | printf("\r%d", ++ct); | |
146 | if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { | |
147 | if (write(fd, buffer, cnt) != cnt) { | |
148 | printf("\r\nwrite error\r\n"); | |
149 | quit = 1; | |
150 | } | |
151 | p = buffer; | |
152 | } | |
153 | } | |
154 | if (cnt = (p-buffer)) | |
155 | if (write(fd, buffer, cnt) != cnt) | |
156 | printf("\r\nwrite error\r\n"); | |
157 | ||
158 | if (boolean(value(VERBOSE))) | |
159 | prtime(" lines transferred in ", time(0)-start); | |
160 | ioctl(0, TIOCSETC, &tchars); | |
161 | write(fildes[1], (char *)&ccc, 1); | |
ab76a038 | 162 | signal(SIGINT, f); |
22daf918 BJ |
163 | close(fd); |
164 | } | |
165 | ||
166 | /* | |
167 | * FTP - remote ==> local process | |
168 | * send remote input to local process via pipe | |
169 | */ | |
170 | pipefile() | |
171 | { | |
172 | int cpid, pdes[2]; | |
173 | char buf[256]; | |
174 | int status, p; | |
175 | extern int errno; | |
176 | ||
177 | if (prompt("Local command? ", buf)) | |
178 | return; | |
179 | ||
180 | if (pipe(pdes)) { | |
181 | printf("can't establish pipe\r\n"); | |
182 | return; | |
183 | } | |
184 | ||
185 | if ((cpid = fork()) < 0) { | |
186 | printf("can't fork!\r\n"); | |
187 | return; | |
188 | } else if (cpid) { | |
189 | if (prompt("List command for remote system? ", buf)) { | |
190 | close(pdes[0]), close(pdes[1]); | |
191 | kill (cpid, SIGKILL); | |
192 | } else { | |
193 | close(pdes[0]); | |
194 | signal(SIGPIPE, intcopy); | |
195 | transfer(buf, pdes[1], value(EOFREAD)); | |
196 | signal(SIGPIPE, SIG_DFL); | |
197 | while ((p = wait(&status)) > 0 && p != cpid) | |
198 | ; | |
199 | } | |
200 | } else { | |
201 | register int f; | |
202 | ||
203 | dup2(pdes[0], 0); | |
204 | close(pdes[0]); | |
205 | for (f = 3; f < 20; f++) | |
206 | close(f); | |
207 | execute(buf); | |
208 | printf("can't execl!\r\n"); | |
209 | exit(0); | |
210 | } | |
211 | } | |
212 | ||
213 | /* | |
214 | * Interrupt service routine for FTP | |
215 | */ | |
216 | stopsnd() | |
217 | { | |
05862919 | 218 | |
22daf918 BJ |
219 | stop = 1; |
220 | signal(SIGINT, SIG_IGN); | |
221 | } | |
222 | ||
223 | /* | |
224 | * FTP - local ==> remote | |
225 | * send local file to remote host | |
226 | * terminate transmission with pseudo EOF sequence | |
227 | */ | |
228 | sendfile(cc) | |
229 | char cc; | |
230 | { | |
231 | FILE *fd; | |
6b46907f RC |
232 | char *fnamex; |
233 | char *expand(); | |
22daf918 BJ |
234 | |
235 | putchar(cc); | |
236 | /* | |
237 | * get file name | |
238 | */ | |
239 | if (prompt("Local file name? ", fname)) | |
240 | return; | |
241 | ||
242 | /* | |
243 | * look up file | |
244 | */ | |
6b46907f RC |
245 | fnamex = expand(fname); |
246 | if ((fd = fopen(fnamex, "r")) == NULL) { | |
22daf918 BJ |
247 | printf("%s: cannot open\r\n", fname); |
248 | return; | |
249 | } | |
250 | transmit(fd, value(EOFWRITE), NULL); | |
a2c6551c SL |
251 | if (!boolean(value(ECHOCHECK))) { |
252 | struct sgttyb buf; | |
253 | ||
254 | ioctl(FD, TIOCGETP, &buf); /* this does a */ | |
255 | ioctl(FD, TIOCSETP, &buf); /* wflushtty */ | |
256 | } | |
22daf918 BJ |
257 | } |
258 | ||
259 | /* | |
260 | * Bulk transfer routine to remote host -- | |
261 | * used by sendfile() and cu_put() | |
262 | */ | |
263 | transmit(fd, eofchars, command) | |
264 | FILE *fd; | |
265 | char *eofchars, *command; | |
266 | { | |
6b46907f | 267 | char *pc, lastc; |
22daf918 BJ |
268 | int c, ccount, lcount; |
269 | time_t start_t, stop_t; | |
ab76a038 | 270 | int (*f)(); |
22daf918 BJ |
271 | |
272 | kill(pid, SIGIOT); /* put TIPOUT into a wait state */ | |
22daf918 | 273 | stop = 0; |
ab76a038 | 274 | f = signal(SIGINT, stopsnd); |
22daf918 BJ |
275 | ioctl(0, TIOCSETC, &defchars); |
276 | read(repdes[0], (char *)&ccc, 1); | |
277 | if (command != NULL) { | |
278 | for (pc = command; *pc; pc++) | |
279 | send(*pc); | |
a2c6551c SL |
280 | if (boolean(value(ECHOCHECK))) |
281 | read(FD, (char *)&c, 1); /* trailing \n */ | |
282 | else { | |
283 | struct sgttyb buf; | |
284 | ||
285 | ioctl(FD, TIOCGETP, &buf); /* this does a */ | |
286 | ioctl(FD, TIOCSETP, &buf); /* wflushtty */ | |
287 | sleep(5); /* wait for remote stty to take effect */ | |
288 | } | |
22daf918 BJ |
289 | } |
290 | lcount = 0; | |
291 | lastc = '\0'; | |
292 | start_t = time(0); | |
3f48242d | 293 | while (1) { |
22daf918 BJ |
294 | ccount = 0; |
295 | do { | |
296 | c = getc(fd); | |
297 | if (stop) | |
298 | goto out; | |
299 | if (c == EOF) | |
300 | goto out; | |
6b46907f | 301 | if (c == 0177 && !boolean(value(RAWFTP))) |
22daf918 BJ |
302 | continue; |
303 | lastc = c; | |
304 | if (c < 040) { | |
6b46907f RC |
305 | if (c == '\n') { |
306 | if (!boolean(value(RAWFTP))) | |
307 | c = '\r'; | |
308 | } | |
22daf918 | 309 | else if (c == '\t') { |
6b46907f RC |
310 | if (!boolean(value(RAWFTP))) { |
311 | if (boolean(value(TABEXPAND))) { | |
22daf918 | 312 | send(' '); |
6b46907f RC |
313 | while ((++ccount % 8) != 0) |
314 | send(' '); | |
315 | continue; | |
316 | } | |
22daf918 | 317 | } |
6b46907f RC |
318 | } else |
319 | if (!boolean(value(RAWFTP))) | |
320 | continue; | |
22daf918 BJ |
321 | } |
322 | send(c); | |
6b46907f | 323 | } while (c != '\r' && !boolean(value(RAWFTP))); |
22daf918 BJ |
324 | if (boolean(value(VERBOSE))) |
325 | printf("\r%d", ++lcount); | |
a2c6551c | 326 | if (boolean(value(ECHOCHECK))) { |
a2c6551c | 327 | timedout = 0; |
ab76a038 | 328 | alarm(value(ETIMEOUT)); |
a2c6551c | 329 | do { /* wait for prompt */ |
6b46907f | 330 | read(FD, (char *)&c, 1); |
a2c6551c SL |
331 | if (timedout || stop) { |
332 | if (timedout) | |
333 | printf("\r\ntimed out at eol\r\n"); | |
334 | alarm(0); | |
335 | goto out; | |
336 | } | |
6b46907f | 337 | } while ((c&0177) != character(value(PROMPT))); |
a2c6551c SL |
338 | alarm(0); |
339 | } | |
22daf918 BJ |
340 | } |
341 | out: | |
6b46907f | 342 | if (lastc != '\n' && !boolean(value(RAWFTP))) |
22daf918 BJ |
343 | send('\r'); |
344 | for (pc = eofchars; *pc; pc++) | |
345 | send(*pc); | |
346 | stop_t = time(0); | |
347 | fclose(fd); | |
ab76a038 | 348 | signal(SIGINT, f); |
22daf918 | 349 | if (boolean(value(VERBOSE))) |
6b46907f RC |
350 | if (boolean(value(RAWFTP))) |
351 | prtime(" chars transferred in ", stop_t-start_t); | |
352 | else | |
353 | prtime(" lines transferred in ", stop_t-start_t); | |
22daf918 BJ |
354 | write(fildes[1], (char *)&ccc, 1); |
355 | ioctl(0, TIOCSETC, &tchars); | |
356 | } | |
357 | ||
358 | /* | |
359 | * Cu-like put command | |
360 | */ | |
361 | cu_put(cc) | |
362 | char cc; | |
363 | { | |
364 | FILE *fd; | |
365 | char line[BUFSIZ]; | |
366 | int argc; | |
6b46907f RC |
367 | char *expand(); |
368 | char *copynamex; | |
22daf918 BJ |
369 | |
370 | if (prompt("[put] ", copyname)) | |
371 | return; | |
372 | if ((argc = args(copyname, argv)) < 1 || argc > 2) { | |
373 | printf("usage: <put> from [to]\r\n"); | |
374 | return; | |
375 | } | |
376 | if (argc == 1) | |
377 | argv[1] = argv[0]; | |
6b46907f RC |
378 | copynamex = expand(argv[0]); |
379 | if ((fd = fopen(copynamex, "r")) == NULL) { | |
380 | printf("%s: cannot open\r\n", copynamex); | |
22daf918 BJ |
381 | return; |
382 | } | |
a2c6551c | 383 | if (boolean(value(ECHOCHECK))) |
6b46907f | 384 | sprintf(line, "cat>%s\r", argv[1]); |
a2c6551c | 385 | else |
6b46907f | 386 | sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); |
22daf918 BJ |
387 | transmit(fd, "\04", line); |
388 | } | |
389 | ||
390 | /* | |
391 | * FTP - send single character | |
392 | * wait for echo & handle timeout | |
393 | */ | |
394 | send(c) | |
395 | char c; | |
396 | { | |
96ad7152 | 397 | char cc; |
22daf918 BJ |
398 | int retry = 0; |
399 | ||
400 | cc = c; | |
6b46907f RC |
401 | pwrite(FD, &cc, 1); |
402 | #ifdef notdef | |
403 | if (number(value(CDELAY)) > 0 && c != '\r') | |
404 | nap(number(value(CDELAY))); | |
405 | #endif | |
406 | if (!boolean(value(ECHOCHECK))) { | |
407 | #ifdef notdef | |
408 | if (number(value(LDELAY)) > 0 && c == '\r') | |
409 | nap(number(value(LDELAY))); | |
410 | #endif | |
a2c6551c | 411 | return; |
6b46907f | 412 | } |
22daf918 BJ |
413 | tryagain: |
414 | timedout = 0; | |
6b46907f RC |
415 | alarm(value(ETIMEOUT)); |
416 | read(FD, &cc, 1); | |
22daf918 BJ |
417 | alarm(0); |
418 | if (timedout) { | |
419 | printf("\r\ntimeout error (%s)\r\n", ctrl(c)); | |
420 | if (retry++ > 3) | |
421 | return; | |
6b46907f | 422 | pwrite(FD, &null, 1); /* poke it */ |
22daf918 BJ |
423 | goto tryagain; |
424 | } | |
425 | } | |
426 | ||
427 | timeout() | |
428 | { | |
429 | signal(SIGALRM, timeout); | |
430 | timedout = 1; | |
431 | } | |
432 | ||
67d9cc23 DS |
433 | /* |
434 | * Stolen from consh() -- puts a remote file on the output of a local command. | |
435 | * Identical to consh() except for where stdout goes. | |
436 | */ | |
437 | pipeout(c) | |
438 | { | |
439 | char buf[256]; | |
440 | int cpid, status, p; | |
441 | time_t start; | |
442 | ||
443 | putchar(c); | |
444 | if (prompt("Local command? ", buf)) | |
445 | return; | |
446 | kill(pid, SIGIOT); /* put TIPOUT into a wait state */ | |
447 | signal(SIGINT, SIG_IGN); | |
448 | signal(SIGQUIT, SIG_IGN); | |
449 | ioctl(0, TIOCSETC, &defchars); | |
450 | read(repdes[0], (char *)&ccc, 1); | |
451 | /* | |
452 | * Set up file descriptors in the child and | |
453 | * let it go... | |
454 | */ | |
455 | if ((cpid = fork()) < 0) | |
456 | printf("can't fork!\r\n"); | |
457 | else if (cpid) { | |
458 | start = time(0); | |
459 | while ((p = wait(&status)) > 0 && p != cpid) | |
460 | ; | |
461 | } else { | |
462 | register int i; | |
463 | ||
464 | dup2(FD, 1); | |
465 | for (i = 3; i < 20; i++) | |
466 | close(i); | |
467 | signal(SIGINT, SIG_DFL); | |
468 | signal(SIGQUIT, SIG_DFL); | |
469 | execute(buf); | |
470 | printf("can't find `%s'\r\n", buf); | |
471 | exit(0); | |
472 | } | |
473 | if (boolean(value(VERBOSE))) | |
474 | prtime("away for ", time(0)-start); | |
475 | write(fildes[1], (char *)&ccc, 1); | |
476 | ioctl(0, TIOCSETC, &tchars); | |
477 | signal(SIGINT, SIG_DFL); | |
478 | signal(SIGQUIT, SIG_DFL); | |
479 | } | |
480 | ||
22daf918 BJ |
481 | #ifdef CONNECT |
482 | /* | |
483 | * Fork a program with: | |
484 | * 0 <-> local tty in | |
485 | * 1 <-> local tty out | |
486 | * 2 <-> local tty out | |
487 | * 3 <-> remote tty in | |
488 | * 4 <-> remote tty out | |
489 | */ | |
490 | consh(c) | |
491 | { | |
492 | char buf[256]; | |
493 | int cpid, status, p; | |
494 | time_t start; | |
495 | ||
496 | putchar(c); | |
497 | if (prompt("Local command? ", buf)) | |
498 | return; | |
499 | kill(pid, SIGIOT); /* put TIPOUT into a wait state */ | |
500 | signal(SIGINT, SIG_IGN); | |
501 | signal(SIGQUIT, SIG_IGN); | |
502 | ioctl(0, TIOCSETC, &defchars); | |
503 | read(repdes[0], (char *)&ccc, 1); | |
504 | /* | |
505 | * Set up file descriptors in the child and | |
506 | * let it go... | |
507 | */ | |
508 | if ((cpid = fork()) < 0) | |
509 | printf("can't fork!\r\n"); | |
510 | else if (cpid) { | |
511 | start = time(0); | |
512 | while ((p = wait(&status)) > 0 && p != cpid) | |
513 | ; | |
514 | } else { | |
515 | register int i; | |
516 | ||
517 | dup2(FD, 3); | |
518 | dup2(3, 4); | |
519 | for (i = 5; i < 20; i++) | |
520 | close(i); | |
521 | signal(SIGINT, SIG_DFL); | |
522 | signal(SIGQUIT, SIG_DFL); | |
523 | execute(buf); | |
524 | printf("can't find `%s'\r\n", buf); | |
525 | exit(0); | |
526 | } | |
527 | if (boolean(value(VERBOSE))) | |
528 | prtime("away for ", time(0)-start); | |
529 | write(fildes[1], (char *)&ccc, 1); | |
530 | ioctl(0, TIOCSETC, &tchars); | |
531 | signal(SIGINT, SIG_DFL); | |
532 | signal(SIGQUIT, SIG_DFL); | |
533 | } | |
534 | #endif | |
535 | ||
536 | /* | |
537 | * Escape to local shell | |
538 | */ | |
539 | shell() | |
540 | { | |
541 | int shpid, status; | |
542 | extern char **environ; | |
543 | char *cp; | |
544 | ||
545 | printf("[sh]\r\n"); | |
546 | signal(SIGINT, SIG_IGN); | |
547 | signal(SIGQUIT, SIG_IGN); | |
548 | unraw(); | |
549 | if (shpid = fork()) { | |
550 | while (shpid != wait(&status)); | |
551 | raw(); | |
552 | printf("\r\n!\r\n"); | |
553 | signal(SIGINT, SIG_DFL); | |
554 | signal(SIGQUIT, SIG_DFL); | |
555 | return; | |
556 | } else { | |
557 | signal(SIGQUIT, SIG_DFL); | |
558 | signal(SIGINT, SIG_DFL); | |
559 | if ((cp = rindex(value(SHELL), '/')) == NULL) | |
560 | cp = value(SHELL); | |
561 | else | |
562 | cp++; | |
45d9e9af | 563 | shell_uid(); |
22daf918 BJ |
564 | execl(value(SHELL), cp, 0); |
565 | printf("\r\ncan't execl!\r\n"); | |
566 | exit(1); | |
567 | } | |
568 | } | |
569 | ||
570 | /* | |
571 | * TIPIN portion of scripting | |
572 | * initiate the conversation with TIPOUT | |
573 | */ | |
574 | setscript() | |
575 | { | |
576 | char c; | |
577 | /* | |
578 | * enable TIPOUT side for dialogue | |
579 | */ | |
580 | kill(pid, SIGEMT); | |
581 | if (boolean(value(SCRIPT))) | |
582 | write(fildes[1], value(RECORD), size(value(RECORD))); | |
583 | write(fildes[1], "\n", 1); | |
584 | /* | |
585 | * wait for TIPOUT to finish | |
586 | */ | |
587 | read(repdes[0], &c, 1); | |
588 | if (c == 'n') | |
589 | printf("can't create %s\r\n", value(RECORD)); | |
590 | } | |
591 | ||
592 | /* | |
593 | * Change current working directory of | |
594 | * local portion of tip | |
595 | */ | |
596 | chdirectory() | |
597 | { | |
05862919 | 598 | char dirname[80]; |
22daf918 BJ |
599 | register char *cp = dirname; |
600 | ||
05862919 | 601 | if (prompt("[cd] ", dirname)) { |
22daf918 BJ |
602 | if (stoprompt) |
603 | return; | |
05862919 SL |
604 | cp = value(HOME); |
605 | } | |
22daf918 BJ |
606 | if (chdir(cp) < 0) |
607 | printf("%s: bad directory\r\n", cp); | |
608 | printf("!\r\n"); | |
609 | } | |
610 | ||
e2326c44 SL |
611 | abort(msg) |
612 | char *msg; | |
22daf918 | 613 | { |
6b46907f | 614 | |
22daf918 | 615 | kill(pid, SIGTERM); |
e2326c44 SL |
616 | disconnect(msg); |
617 | if (msg != NOSTR) | |
618 | printf("\r\n%s", msg); | |
22daf918 | 619 | printf("\r\n[EOT]\r\n"); |
45d9e9af | 620 | daemon_uid(); |
5d369851 | 621 | (void)uu_unlock(uucplock); |
22daf918 BJ |
622 | unraw(); |
623 | exit(0); | |
624 | } | |
625 | ||
e2326c44 SL |
626 | finish() |
627 | { | |
628 | char *dismsg; | |
629 | ||
630 | if ((dismsg = value(DISCONNECT)) != NOSTR) { | |
631 | write(FD, dismsg, strlen(dismsg)); | |
632 | sleep(5); | |
633 | } | |
634 | abort(NOSTR); | |
635 | } | |
636 | ||
22daf918 BJ |
637 | intcopy() |
638 | { | |
05862919 | 639 | |
22daf918 BJ |
640 | raw(); |
641 | quit = 1; | |
05862919 | 642 | longjmp(intbuf, 1); |
22daf918 BJ |
643 | } |
644 | ||
645 | execute(s) | |
646 | char *s; | |
647 | { | |
648 | register char *cp; | |
649 | ||
650 | if ((cp = rindex(value(SHELL), '/')) == NULL) | |
651 | cp = value(SHELL); | |
652 | else | |
653 | cp++; | |
29eaa516 | 654 | shell_uid(); |
22daf918 BJ |
655 | execl(value(SHELL), cp, "-c", s, 0); |
656 | } | |
657 | ||
658 | args(buf, a) | |
659 | char *buf, *a[]; | |
660 | { | |
661 | register char *p = buf, *start; | |
662 | register char **parg = a; | |
663 | register int n = 0; | |
664 | ||
665 | do { | |
666 | while (*p && (*p == ' ' || *p == '\t')) | |
667 | p++; | |
668 | start = p; | |
669 | if (*p) | |
670 | *parg = p; | |
671 | while (*p && (*p != ' ' && *p != '\t')) | |
672 | p++; | |
673 | if (p != start) | |
674 | parg++, n++; | |
675 | if (*p) | |
676 | *p++ = '\0'; | |
677 | } while (*p); | |
678 | ||
679 | return(n); | |
680 | } | |
681 | ||
682 | prtime(s, a) | |
683 | char *s; | |
684 | time_t a; | |
685 | { | |
686 | register i; | |
687 | int nums[3]; | |
688 | ||
689 | for (i = 0; i < 3; i++) { | |
690 | nums[i] = (int)(a % quant[i]); | |
691 | a /= quant[i]; | |
692 | } | |
693 | printf("%s", s); | |
694 | while (--i >= 0) | |
ab76a038 | 695 | if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) |
22daf918 BJ |
696 | printf("%d %s%c ", nums[i], sep[i], |
697 | nums[i] == 1 ? '\0' : 's'); | |
698 | printf("\r\n!\r\n"); | |
699 | } | |
700 | ||
701 | variable() | |
702 | { | |
703 | char buf[256]; | |
704 | ||
705 | if (prompt("[set] ", buf)) | |
706 | return; | |
707 | vlex(buf); | |
708 | if (vtable[BEAUTIFY].v_access&CHANGED) { | |
709 | vtable[BEAUTIFY].v_access &= ~CHANGED; | |
3463e9c6 | 710 | kill(pid, SIGSYS); |
22daf918 BJ |
711 | } |
712 | if (vtable[SCRIPT].v_access&CHANGED) { | |
713 | vtable[SCRIPT].v_access &= ~CHANGED; | |
714 | setscript(); | |
7367df0e SL |
715 | /* |
716 | * So that "set record=blah script" doesn't | |
717 | * cause two transactions to occur. | |
718 | */ | |
719 | if (vtable[RECORD].v_access&CHANGED) | |
720 | vtable[RECORD].v_access &= ~CHANGED; | |
22daf918 BJ |
721 | } |
722 | if (vtable[RECORD].v_access&CHANGED) { | |
723 | vtable[RECORD].v_access &= ~CHANGED; | |
724 | if (boolean(value(SCRIPT))) | |
725 | setscript(); | |
726 | } | |
6b46907f RC |
727 | if (vtable[TAND].v_access&CHANGED) { |
728 | vtable[TAND].v_access &= ~CHANGED; | |
729 | if (boolean(value(TAND))) | |
730 | tandem("on"); | |
731 | else | |
732 | tandem("off"); | |
733 | } | |
734 | if (vtable[LECHO].v_access&CHANGED) { | |
735 | vtable[LECHO].v_access &= ~CHANGED; | |
736 | HD = boolean(value(LECHO)); | |
737 | } | |
738 | if (vtable[PARITY].v_access&CHANGED) { | |
739 | vtable[PARITY].v_access &= ~CHANGED; | |
740 | setparity(); | |
741 | } | |
742 | } | |
743 | ||
744 | /* | |
05862919 | 745 | * Turn tandem mode on or off for remote tty. |
6b46907f | 746 | */ |
6b46907f | 747 | tandem(option) |
05862919 | 748 | char *option; |
6b46907f RC |
749 | { |
750 | struct sgttyb rmtty; | |
751 | ||
752 | ioctl(FD, TIOCGETP, &rmtty); | |
753 | if (strcmp(option,"on") == 0) { | |
754 | rmtty.sg_flags |= TANDEM; | |
755 | arg.sg_flags |= TANDEM; | |
05862919 | 756 | } else { |
6b46907f RC |
757 | rmtty.sg_flags &= ~TANDEM; |
758 | arg.sg_flags &= ~TANDEM; | |
759 | } | |
760 | ioctl(FD, TIOCSETP, &rmtty); | |
761 | ioctl(0, TIOCSETP, &arg); | |
22daf918 | 762 | } |
061754f3 SL |
763 | |
764 | /* | |
765 | * Send a break. | |
061754f3 SL |
766 | */ |
767 | genbrk() | |
768 | { | |
05862919 | 769 | |
061754f3 SL |
770 | ioctl(FD, TIOCSBRK, NULL); |
771 | sleep(1); | |
772 | ioctl(FD, TIOCCBRK, NULL); | |
061754f3 | 773 | } |
3f48242d | 774 | |
3f48242d SL |
775 | /* |
776 | * Suspend tip | |
777 | */ | |
72b2a7a5 SL |
778 | suspend(c) |
779 | char c; | |
3f48242d | 780 | { |
05862919 | 781 | |
3f48242d | 782 | unraw(); |
3cd1a53c | 783 | kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); |
3f48242d SL |
784 | raw(); |
785 | } | |
6b46907f RC |
786 | |
787 | /* | |
788 | * expand a file name if it includes shell meta characters | |
789 | */ | |
790 | ||
791 | char * | |
792 | expand(name) | |
793 | char name[]; | |
794 | { | |
795 | static char xname[BUFSIZ]; | |
796 | char cmdbuf[BUFSIZ]; | |
797 | register int pid, l, rc; | |
798 | register char *cp, *Shell; | |
799 | int s, pivec[2], (*sigint)(); | |
800 | ||
801 | if (!anyof(name, "~{[*?$`'\"\\")) | |
802 | return(name); | |
803 | /* sigint = signal(SIGINT, SIG_IGN); */ | |
804 | if (pipe(pivec) < 0) { | |
805 | perror("pipe"); | |
806 | /* signal(SIGINT, sigint) */ | |
807 | return(name); | |
808 | } | |
809 | sprintf(cmdbuf, "echo %s", name); | |
810 | if ((pid = vfork()) == 0) { | |
811 | Shell = value(SHELL); | |
812 | if (Shell == NOSTR) | |
435e8dff | 813 | Shell = _PATH_BSHELL; |
6b46907f RC |
814 | close(pivec[0]); |
815 | close(1); | |
816 | dup(pivec[1]); | |
817 | close(pivec[1]); | |
818 | close(2); | |
45d9e9af | 819 | shell_uid(); |
6b46907f RC |
820 | execl(Shell, Shell, "-c", cmdbuf, 0); |
821 | _exit(1); | |
822 | } | |
823 | if (pid == -1) { | |
824 | perror("fork"); | |
825 | close(pivec[0]); | |
826 | close(pivec[1]); | |
827 | return(NOSTR); | |
828 | } | |
829 | close(pivec[1]); | |
830 | l = read(pivec[0], xname, BUFSIZ); | |
831 | close(pivec[0]); | |
832 | while (wait(&s) != pid); | |
833 | ; | |
834 | s &= 0377; | |
835 | if (s != 0 && s != SIGPIPE) { | |
836 | fprintf(stderr, "\"Echo\" failed\n"); | |
837 | return(NOSTR); | |
838 | } | |
839 | if (l < 0) { | |
840 | perror("read"); | |
841 | return(NOSTR); | |
842 | } | |
843 | if (l == 0) { | |
844 | fprintf(stderr, "\"%s\": No match\n", name); | |
845 | return(NOSTR); | |
846 | } | |
847 | if (l == BUFSIZ) { | |
848 | fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); | |
849 | return(NOSTR); | |
850 | } | |
851 | xname[l] = 0; | |
852 | for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) | |
853 | ; | |
854 | *++cp = '\0'; | |
855 | return(xname); | |
856 | } | |
857 | ||
858 | /* | |
859 | * Are any of the characters in the two strings the same? | |
860 | */ | |
861 | ||
862 | anyof(s1, s2) | |
863 | register char *s1, *s2; | |
864 | { | |
865 | register int c; | |
866 | ||
867 | while (c = *s1++) | |
868 | if (any(c, s2)) | |
869 | return(1); | |
870 | return(0); | |
871 | } |