reverse src and dst to raw_input
[unix-history] / usr / src / usr.bin / tip / tip.c
CommitLineData
c731dacc 1/* tip.c 4.11 81/12/16 */
3f48242d 2
5f50159a 3/*
3f48242d 4 * tip - UNIX link to other systems
5f50159a 5 * tip [-v] [-speed] system-name
3f48242d
SL
6 * or
7 * cu phone-number [-s speed] [-l line] [-a acu]
5f50159a 8 */
5f50159a
BJ
9#include "tip.h"
10
11/*
12 * Baud rate mapping table
13 */
14int bauds[] = {
15 0, 50, 75, 110, 134, 150, 200, 300, 600,
16 1200, 1800, 2400, 4800, 9600, 19200, -1
17};
18
4b675d70
SL
19#ifdef VMUNIX
20int disc = OTTYDISC; /* tip normally runs this way */
21#endif
22
5f50159a
BJ
23int intprompt();
24int timeout();
3f48242d 25int cleanup();
c731dacc
BS
26char *sname();
27extern char *sprintf();
5f50159a
BJ
28
29main(argc, argv)
d8feebc2 30 char *argv[];
5f50159a
BJ
31{
32 char *system = NOSTR;
33 register int i;
c731dacc
BS
34 register char *p;
35 char sbuf[12];
5f50159a 36
c731dacc 37 if (equal(sname(argv[0]), "cu")) {
3f48242d
SL
38 cumain(argc, argv);
39 cumode = 1;
40 goto cucommon;
41 }
42
5f50159a
BJ
43 if (argc > 4) {
44 fprintf(stderr, "usage: tip [-v] [-speed] [system-name]\n");
45 exit(1);
46 }
47 if (!isatty(0)) {
48 fprintf(stderr, "tip: must be interactive\n");
49 exit(1);
50 }
c731dacc
BS
51
52 for (; argc > 1; argv++, argc--) {
53 if (argv[1][0] != '-')
54 system = argv[1];
55 else switch (argv[1][1]) {
56
57 case 'v':
58 vflag++;
59 break;
60
61 case '0': case '1': case '2': case '3': case '4':
62 case '5': case '6': case '7': case '8': case '9':
63 BR = atoi(&argv[1][1]);
64 break;
65
66 default:
67 fprintf(stderr, "tip: %s, unknown option\n", argv[1]);
68 break;
69 }
70 }
71
72 for (p = system; *p; p++)
73 if (isalpha(*p))
74 goto notnumber;
75 PN = system; /* system name is really a phone number */
76 system = sprintf(sbuf, "tip%d", BR);
77
78notnumber:
5f50159a
BJ
79 signal(SIGINT, cleanup);
80 signal(SIGQUIT, cleanup);
81 signal(SIGHUP, cleanup);
82 signal(SIGTERM, cleanup);
f0211bf2 83
5f50159a
BJ
84 if ((i = hunt(system)) == 0) {
85 printf("all ports busy\n");
86 exit(3);
87 }
88 if (i == -1) {
89 printf("link down\n");
1603e05e 90 delock(uucplock);
5f50159a
BJ
91 exit(3);
92 }
eaa86232 93 setbuf(stdout, NULL);
5f50159a
BJ
94 loginit();
95 /*
96 * Now that we have the logfile and the ACU open
97 * return to the real uid and gid. These things will
98 * be closed on exit. Note that we can't run as root,
99 * because locking mechanism on the tty and the accounting
100 * will be bypassed.
101 */
102 setuid(getuid());
103 setgid(getgid());
c731dacc 104
5f50159a
BJ
105 /*
106 * Kludge, their's no easy way to get the initialization
107 * in the right order, so force it here
108 */
109 if ((PH = getenv("PHONES")) == NOSTR)
110 PH = "/etc/phones";
111 vinit(); /* init variables */
4b675d70 112 if ((i = speed(number(value(BAUDRATE)))) == NULL) {
5f50159a
BJ
113 printf("tip: bad baud rate %d\n", number(value(BAUDRATE)));
114 delock(uucplock);
115 exit(3);
116 }
f0211bf2 117
4b675d70
SL
118 /*
119 * Hardwired connections require the
120 * line speed set before they make any transmissions
121 * (this is particularly true of things like a DF03-AC)
122 */
123 if (HW)
124 ttysetup(i);
f0211bf2
SL
125 if (p = connect()) {
126 printf("\07%s\n[EOT]\n", p);
127 delock(uucplock);
128 exit(1);
129 }
4b675d70
SL
130 if (!HW)
131 ttysetup(i);
3f48242d 132cucommon:
5f50159a 133 /*
3f48242d
SL
134 * From here down the code is shared with
135 * the "cu" version of tip.
5f50159a 136 */
4b675d70
SL
137 ioctl(0, TIOCGETP, (char *)&defarg);
138 ioctl(0, TIOCGETC, (char *)&defchars);
5d1f1475 139#ifdef VMUNIX
4b675d70 140 ioctl(0, TIOCGETD, (char *)&odisc);
5d1f1475 141#endif
5f50159a
BJ
142 arg = defarg;
143 arg.sg_flags = ANYP | CBREAK;
144 tchars = defchars;
145 tchars.t_intrc = tchars.t_quitc = -1;
5f50159a 146 raw();
4b675d70 147
5f50159a
BJ
148 pipe(fildes); pipe(repdes);
149 signal(SIGALRM, timeout);
f0211bf2
SL
150
151 /*
152 * Everything's set up now:
153 * connection established (hardwired or diaulup)
154 * line conditioned (baud rate, mode, etc.)
155 * internal data structures (variables)
156 * so, fork one process for local side and one for remote.
157 */
3f48242d 158 printf(cumode ? "Connected\r\n" : "\07connected\r\n");
5f50159a
BJ
159 if (pid = fork())
160 tipin();
161 else
162 tipout();
163 /*NOTREACHED*/
164}
165
5f50159a
BJ
166cleanup()
167{
168 delock(uucplock);
f0211bf2
SL
169#ifdef VMUNIX
170 if (odisc)
171 ioctl(0, TIOCSETD, (char *)&odisc);
172#endif
5f50159a
BJ
173 exit(0);
174}
175
176/*
177 * put the controlling keyboard into raw mode
178 */
179raw()
180{
181 ioctl(0, TIOCSETP, &arg);
182 ioctl(0, TIOCSETC, &tchars);
4b675d70
SL
183#ifdef VMUNIX
184 ioctl(0, TIOCSETD, (char *)&disc);
185#endif
5f50159a
BJ
186}
187
188
189/*
190 * return keyboard to normal mode
191 */
192unraw()
193{
4b675d70
SL
194#ifdef VMUNIX
195 ioctl(0, TIOCSETD, (char *)&odisc);
196#endif
197 ioctl(0, TIOCSETP, (char *)&defarg);
198 ioctl(0, TIOCSETC, (char *)&defchars);
5f50159a
BJ
199}
200
201/*
202 * Print string ``s'', then read a string
203 * in from the terminal. Handles signals & allows use of
204 * normal erase and kill characters.
205 */
206prompt(s, p)
207 char *s;
208 register char *p;
209{
210 register char *b = p;
211
212 stoprompt = 0;
213 signal(SIGINT, intprompt);
214 signal(SIGQUIT, SIG_IGN);
215 unraw();
216 printf("%s", s);
217 while ((*p = getchar()) != EOF && *p != '\n') {
218 if (stoprompt)
219 goto pbreak;
220 p++;
221 }
222 *p = '\0';
223pbreak:
224 raw();
225 signal(SIGINT, SIG_DFL);
226 signal(SIGQUIT,SIG_DFL);
227 return(stoprompt || p == b);
228}
229
230/*
231 * Interrupt service routine during prompting
232 */
233intprompt()
234{
235 signal(SIGINT, SIG_IGN);
236 stoprompt = 1;
237 printf("\r\n");
238}
239
240/*
241 * ****TIPIN TIPIN****
242 */
243tipin()
244{
245 char gch, bol = 1;
246
388a70dc
SL
247 /*
248 * Kinda klugey here...
249 * check for scripting being turned on from the .tiprc file,
250 * but be careful about just using setscript(), as we may
251 * send a SIGEMT before tipout has a chance to set up catching
252 * it; so wait a second, then setscript()
253 */
254 if (boolean(value(SCRIPT))) {
255 sleep(1);
256 setscript();
257 }
258
5f50159a
BJ
259 while (1) {
260 gch = getchar()&0177;
261 if ((gch == character(value(ESCAPE))) && bol) {
262 if (!(gch = escape()))
263 continue;
3f48242d 264 } else if (!cumode && gch == character(value(RAISECHAR))) {
5f50159a 265 boolean(value(RAISE)) = !boolean(value(RAISE));
5f50159a
BJ
266 continue;
267 } else if (gch == '\r') {
268 bol = 1;
269 write(FD, &gch, 1);
270 continue;
3f48242d 271 } else if (!cumode && gch == character(value(FORCE)))
5f50159a 272 gch = getchar()&0177;
5f50159a
BJ
273 bol = any(gch, value(EOL));
274 if (boolean(value(RAISE)) && islower(gch))
275 toupper(gch);
276 write(FD, &gch, 1);
277 }
278}
279
280/*
281 * Escape handler --
282 * called on recognition of ``escapec'' at the beginning of a line
283 */
284escape()
285{
286 register char gch;
287 register esctable_t *p;
288 char c = character(value(ESCAPE));
289 extern esctable_t etable[];
290
291 gch = (getchar()&0177);
292 for (p = etable; p->e_char; p++)
293 if (p->e_char == gch) {
294 if ((p->e_flags&PRIV) && getuid())
295 continue;
296 printf("%s", ctrl(c));
297 (*p->e_func)(gch);
298 return(0);
299 }
62f62be8
SL
300 /* ESCAPE ESCAPE forces ESCAPE */
301 if (c != gch)
302 write(FD, &c, 1);
5f50159a
BJ
303 return(gch);
304}
305
306speed(n)
307{
308 register int *p;
309
310 for (p = bauds; *p != -1; p++)
311 if (*p == n)
312 return(p-bauds);
313 return(NULL);
314}
315
316any(c, p)
317 register char c, *p;
318{
319 while (*p)
320 if (*p++ == c)
321 return(1);
322 return(0);
323}
324
325size(s)
326 register char *s;
327{
328 register int i = 0;
329
330 while (*s++) i++;
331 return(i);
332}
333
334char *
335interp(s)
336 register char *s;
337{
338 static char buf[256];
339 register char *p = buf, c, *q;
340
341 while (c = *s++) {
342 for (q = "\nn\rr\tt\ff\033E\bb"; *q; q++)
343 if (*q++ == c) {
344 *p++ = '\\'; *p++ = *q;
345 goto next;
346 }
347 if (c < 040) {
348 *p++ = '^'; *p++ = c + 'A'-1;
349 } else if (c == 0177) {
350 *p++ = '^'; *p++ = '?';
351 } else
352 *p++ = c;
353 next:
354 ;
355 }
356 *p = '\0';
357 return(buf);
358}
359
360char *
361ctrl(c)
362 char c;
363{
364 static char s[3];
365
366 if (c < 040 || c == 0177) {
367 s[0] = '^';
368 s[1] = c == 0177 ? '?' : c+'A'-1;
369 s[2] = '\0';
370 } else {
371 s[0] = c;
372 s[1] = '\0';
373 }
374 return(s);
375}
376
377/*
378 * Help command
379 */
380help(c)
381 char c;
382{
383 register esctable_t *p;
384 extern esctable_t etable[];
385
386 printf("%c\r\n", c);
387 for (p = etable; p->e_char; p++) {
388 if ((p->e_flags&PRIV) && getuid())
389 continue;
390 printf("%2s", ctrl(character(value(ESCAPE))));
391 printf("%-2s %c %s\r\n", ctrl(p->e_char),
392 p->e_flags&EXP ? '*': ' ', p->e_help);
393 }
394}
4b675d70
SL
395
396/*
397 * Set up the "remote" tty's state
398 */
4b675d70
SL
399ttysetup(speed)
400{
401#ifdef VMUNIX
402 unsigned bits = LDECCTQ;
403#endif
404
405 arg.sg_ispeed = arg.sg_ospeed = speed;
406 arg.sg_flags = TANDEM|RAW;
407 ioctl(FD, TIOCSETP, (char *)&arg);
408#ifdef VMUNIX
409 ioctl(FD, TIOCLBIS, (char *)&bits);
410#endif
411}
c731dacc
BS
412
413/*
414 * Return "simple" name from a file name,
415 * strip leading directories.
416 */
417char *
418sname(s)
419 register char *s;
420{
421 register char *p = s;
422
423 while (*s)
424 if (*s++ == '/')
425 p = s;
426 return (p);
427}