Commit | Line | Data |
---|---|---|
a8e0ea6c | 1 | #ifndef lint |
ac09522b | 2 | static char sccsid[] = "@(#)conn.c 5.15 (Berkeley) %G%"; |
a8e0ea6c | 3 | #endif |
55a580e3 | 4 | |
55a580e3 | 5 | #include <signal.h> |
941b257e | 6 | #include "uucp.h" |
55a580e3 SL |
7 | #include <setjmp.h> |
8 | #include <ctype.h> | |
55a580e3 | 9 | #include <errno.h> |
46b15d8a | 10 | #ifdef USG |
55a580e3 SL |
11 | #include <termio.h> |
12 | #include <fcntl.h> | |
13 | #endif | |
46b15d8a | 14 | #ifndef USG |
55a580e3 SL |
15 | #include <sgtty.h> |
16 | #endif | |
46b15d8a RC |
17 | #ifdef BSD4_2 |
18 | #include <sys/time.h> | |
19 | #else | |
20 | #include <time.h> | |
21 | #endif | |
55a580e3 SL |
22 | |
23 | #define MAXC 1000 | |
24 | ||
25 | extern jmp_buf Sjbuf; | |
46b15d8a | 26 | jmp_buf Cjbuf; |
1a85e9d2 | 27 | extern int errno, onesys; |
46b15d8a | 28 | extern char *sys_errlist[]; |
1a85e9d2 | 29 | extern char MaxGrade, DefMaxGrade; |
55a580e3 SL |
30 | |
31 | /* Parity control during login procedure */ | |
32 | #define P_ZERO 0 | |
33 | #define P_ONE 1 | |
34 | #define P_EVEN 2 | |
35 | #define P_ODD 3 | |
55a580e3 | 36 | |
46b15d8a RC |
37 | #define ABORT -2 |
38 | ||
39 | char *AbortOn = NULL; | |
40 | char par_tab[128]; /* must be power of two */ | |
41 | int linebaudrate; /* used for the sleep test in pk1.c */ | |
55a580e3 | 42 | int next_fd = -1; /* predicted fd to close interrupted opens */ |
2af814a5 JB |
43 | |
44 | char *PCP = "PCP"; /* PC Pursuit device type */ | |
01af9d69 JB |
45 | /* |
46 | * catch alarm routine for "expect". | |
55a580e3 SL |
47 | */ |
48 | alarmtr() | |
49 | { | |
50 | signal(SIGALRM, alarmtr); | |
51 | if (next_fd >= 0) { | |
52 | if (close(next_fd)) | |
53 | logent("FAIL", "ACU LINE CLOSE"); | |
54 | next_fd = -1; | |
55 | } | |
56 | longjmp(Sjbuf, 1); | |
57 | } | |
58 | ||
2af814a5 JB |
59 | /* This template is for seismo to call ihnp4 |
60 | * the 3 lines marked ---> will be overwritten for the appropriate city | |
61 | */ | |
62 | #define PCP_BAUD 3 | |
63 | #define PCP_PHONE 4 | |
f43a5ec5 RA |
64 | #define PCP_CITY 14 |
65 | #define PCP_PASSWORD 16 | |
66 | #define PCP_RPHONE 20 | |
67 | #define NPCFIELDS 23 | |
2af814a5 JB |
68 | |
69 | static char *PCFlds[] = { | |
70 | "PC-PURSUIT", | |
71 | "Any", | |
72 | "ACU", | |
73 | "1200", | |
f43a5ec5 RA |
74 | CNULL, |
75 | CNULL, | |
76 | "P_ZERO", /* Telenet insists on zero parity */ | |
2af814a5 | 77 | "ABORT", |
f43a5ec5 RA |
78 | "BUSY", /* Abort on Busy Signal */ |
79 | CNULL, | |
80 | "\\d\\d\\r\\d\\r", /* Get telenet's attention */ | |
81 | "TERMINAL=~3-\r-TERM~3-\r-TERM~5", /* Terminal type ? */ | |
82 | "\\r", | |
83 | "@", /* telenet's prompt */ | |
84 | "D/DCWAS/21,telenetloginstring", /* overwritten later */ | |
85 | "PASSWORD", | |
86 | CNULL, /* telenet password */ | |
87 | "CONNECTED", /* We're now talking to a Hayes in the remote city */ | |
88 | "ATZ", /* Reset it */ | |
89 | "OK", | |
90 | "ATDT6907171", /* overwritten */ | |
91 | "CONNECT", | |
92 | "\\d\\r", /* We're in !*/ | |
93 | CNULL, | |
2af814a5 JB |
94 | }; |
95 | ||
f43a5ec5 | 96 | static char PCP_brand[25]; |
ac09522b RA |
97 | int Dcf = -1; |
98 | char *Flds[MAXC/10]; | |
99 | char LineType[10]; | |
100 | extern int LocalOnly; | |
2af814a5 | 101 | |
1a85e9d2 RC |
102 | /* |
103 | * place a telephone call to system and login, etc. | |
55a580e3 SL |
104 | * |
105 | * return codes: | |
106 | * CF_SYSTEM: don't know system | |
107 | * CF_TIME: wrong time to call | |
108 | * CF_DIAL: call failed | |
109 | * CF_NODEV: no devices available to place call | |
110 | * CF_LOGIN: login/password dialog failed | |
111 | * | |
112 | * >0 - file no. - connect ok | |
55a580e3 | 113 | */ |
55a580e3 SL |
114 | conn(system) |
115 | char *system; | |
116 | { | |
2af814a5 | 117 | int nf; |
1a85e9d2 | 118 | char info[MAXC], wkpre[NAMESIZE], file[NAMESIZE]; |
55a580e3 SL |
119 | register FILE *fsys; |
120 | int fcode = 0; | |
121 | ||
122 | nf = 0; | |
55a580e3 SL |
123 | |
124 | fsys = fopen(SYSFILE, "r"); | |
7dd5932d RA |
125 | if (fsys == NULL) { |
126 | syslog(LOG_ERR, "fopen(%s) failed: %m", SYSFILE); | |
127 | cleanup(FAIL); | |
128 | } | |
55a580e3 | 129 | |
46b15d8a | 130 | DEBUG(4, "finds (%s) called\n", system); |
01af9d69 | 131 | keeplooking: |
46b15d8a | 132 | while((nf = finds(fsys, system, info, Flds)) > 0) { |
9313cec6 | 133 | strncpy(LineType, Flds[F_LINE], 10); |
46b15d8a | 134 | if (LocalOnly) { |
9313cec6 JB |
135 | if (strcmp("TCP", LineType) |
136 | && strcmp("DIR", LineType) | |
137 | && strcmp("LOCAL", LineType) ) { | |
2af814a5 JB |
138 | fcode = CF_TIME; |
139 | continue; | |
140 | } | |
46b15d8a | 141 | } |
941b257e | 142 | sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname); |
1a85e9d2 | 143 | if (!onesys && MaxGrade != DefMaxGrade && |
2af814a5 JB |
144 | !iswrk(file, "chk", Spool, wkpre)) { |
145 | fcode = CF_TIME; | |
146 | continue; | |
55a580e3 | 147 | } |
2af814a5 | 148 | /* For GTE's PC Pursuit */ |
9313cec6 | 149 | if (snccmp(LineType, PCP) == SAME) { |
2af814a5 JB |
150 | FILE *dfp; |
151 | int status; | |
152 | static struct Devices dev; | |
f43a5ec5 | 153 | |
2af814a5 | 154 | dfp = fopen(DEVFILE, "r"); |
7dd5932d RA |
155 | if (dfp == NULL) { |
156 | syslog(LOG_ERR, "fopen(%s) failed: %m", | |
157 | DEVFILE); | |
158 | cleanup(FAIL); | |
159 | } | |
2af814a5 JB |
160 | while ((status=rddev(dfp, &dev)) != FAIL |
161 | && strcmp(PCP, dev.D_type) != SAME) | |
162 | ; | |
163 | fclose(dfp); | |
164 | if (status == FAIL) | |
165 | continue; | |
166 | if (mlock(PCP) == FAIL) { | |
167 | fcode = CF_NODEV; | |
168 | logent("DEVICE", "NO"); | |
169 | continue; | |
170 | } | |
171 | PCFlds[PCP_BAUD] = dev.D_class; | |
172 | PCFlds[PCP_PHONE] = dev.D_calldev; | |
f43a5ec5 RA |
173 | sprintf(PCFlds[PCP_CITY], "c d/%s%s,%s", |
174 | Flds[F_CLASS], | |
175 | index(Flds[F_CLASS], '/') == NULL ? "/12" : "", | |
176 | dev.D_arg[D_CHAT]); | |
177 | PCFlds[PCP_PASSWORD] = dev.D_line; | |
178 | strncpy(&PCFlds[PCP_RPHONE][4], Flds[F_PHONE], 7); | |
2af814a5 | 179 | strncpy(PCP_brand, dev.D_brand, sizeof(PCP_brand)); |
f43a5ec5 RA |
180 | if ((fcode = getto(PCFlds)) < 0) { |
181 | rmlock(PCP); | |
2af814a5 | 182 | continue; |
f43a5ec5 | 183 | } |
2af814a5 JB |
184 | Dcf = fcode; |
185 | fcode = login(NPCFIELDS, PCFlds, Dcf); | |
f43a5ec5 RA |
186 | if (fcode == SUCCESS) |
187 | break; | |
188 | fcode = CF_DIAL; | |
189 | rmlock(PCP); | |
190 | /* end PC Pursuit */ | |
191 | } else if ((fcode = getto(Flds)) > 0) { | |
192 | Dcf = fcode; | |
2af814a5 | 193 | break; |
f43a5ec5 | 194 | } |
55a580e3 | 195 | } |
55a580e3 | 196 | |
01af9d69 JB |
197 | if (nf <= 0) { |
198 | fclose(fsys); | |
46b15d8a | 199 | return fcode ? fcode : nf; |
01af9d69 | 200 | } |
55a580e3 | 201 | |
2af814a5 | 202 | |
2af814a5 JB |
203 | if (fcode >= 0) { |
204 | DEBUG(4, "login %s\n", "called"); | |
ac09522b | 205 | setproctitle("login"); |
f43a5ec5 | 206 | fcode = login(nf, Flds, Dcf); } |
2af814a5 | 207 | if (fcode < 0) { |
55a580e3 | 208 | clsacu(); |
2af814a5 | 209 | if (fcode == ABORT) { |
01af9d69 JB |
210 | fcode = CF_DIAL; |
211 | goto keeplooking; | |
212 | } else { | |
213 | fclose(fsys); | |
941b257e | 214 | return CF_LOGIN; |
01af9d69 | 215 | } |
55a580e3 | 216 | } |
01af9d69 | 217 | fclose(fsys); |
2af814a5 JB |
218 | fioclex(Dcf); |
219 | return Dcf; | |
55a580e3 SL |
220 | } |
221 | ||
ac09522b RA |
222 | int nulldev(); |
223 | int (*CU_end)() = nulldev; | |
224 | ||
01af9d69 JB |
225 | /* |
226 | * connect to remote machine | |
55a580e3 SL |
227 | * |
228 | * return codes: | |
229 | * >0 - file number - ok | |
230 | * FAIL - failed | |
231 | */ | |
55a580e3 SL |
232 | getto(flds) |
233 | register char *flds[]; | |
234 | { | |
235 | register struct condev *cd; | |
21038734 | 236 | int diropn(); |
01af9d69 | 237 | char *line; |
55a580e3 | 238 | |
46b15d8a | 239 | DEBUG(4, "getto: call no. %s ", flds[F_PHONE]); |
55a580e3 SL |
240 | DEBUG(4, "for sys %s\n", flds[F_NAME]); |
241 | ||
01af9d69 JB |
242 | if (snccmp(flds[F_LINE], "LOCAL") == SAME) |
243 | line = "ACU"; | |
244 | else | |
245 | line = flds[F_LINE]; | |
246 | #ifdef DIALINOUT | |
247 | if (snccmp(line, "ACU") != SAME) | |
248 | reenable(); | |
249 | #endif DIALINOUT | |
55a580e3 | 250 | CU_end = nulldev; |
2af814a5 JB |
251 | if (snccmp(line, PCP) == SAME) { |
252 | for(cd = condevs; cd->CU_meth != NULL; cd++) { | |
253 | if (snccmp(PCP_brand, cd->CU_brand) == SAME) { | |
254 | CU_end = cd->CU_clos; | |
255 | return diropn(flds); | |
256 | } | |
55a580e3 | 257 | } |
2af814a5 JB |
258 | logent(PCP_brand, "UNSUPPORTED ACU TYPE"); |
259 | } else { | |
260 | for (cd = condevs; cd->CU_meth != NULL; cd++) { | |
261 | if (snccmp(cd->CU_meth, line) == SAME) { | |
262 | DEBUG(4, "Using %s to call\n", cd->CU_meth); | |
263 | return (*(cd->CU_gen))(flds); | |
264 | } | |
265 | } | |
266 | DEBUG(1, "Can't find %s, assuming DIR\n", flds[F_LINE]); | |
55a580e3 | 267 | } |
46b15d8a RC |
268 | return diropn(flds); /* search failed, so use direct */ |
269 | } | |
55a580e3 | 270 | |
01af9d69 JB |
271 | /* |
272 | * close call unit | |
55a580e3 SL |
273 | * |
274 | * return codes: none | |
275 | */ | |
55a580e3 SL |
276 | clsacu() |
277 | { | |
46b15d8a RC |
278 | /* make *sure* Dcf is no longer exclusive. |
279 | * Otherwise dual call-in/call-out modems could get stuck. | |
280 | * Unfortunately, doing this here is not ideal, but it is the | |
281 | * easiest place to put the call. | |
282 | * Hopefully everyone honors the LCK protocol, of course | |
283 | */ | |
2af814a5 | 284 | #ifdef TIOCNXCL |
941b257e JB |
285 | if (!IsTcpIp && Dcf >= 0 && ioctl(Dcf, TIOCNXCL, STBNULL) < 0) |
286 | DEBUG(5, "clsacu ioctl %s\n", sys_errlist[errno]); | |
46b15d8a RC |
287 | #endif |
288 | if (setjmp(Sjbuf)) | |
289 | logent(Rmtname, "CLOSE TIMEOUT"); | |
290 | else { | |
291 | signal(SIGALRM, alarmtr); | |
292 | alarm(20); | |
293 | (*(CU_end))(Dcf); | |
294 | alarm(0); | |
295 | } | |
55a580e3 SL |
296 | if (close(Dcf) == 0) { |
297 | DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf); | |
298 | logent("clsacu", "NOT CLOSED by CU_clos"); | |
299 | } | |
300 | Dcf = -1; | |
301 | CU_end = nulldev; | |
302 | } | |
303 | ||
01af9d69 JB |
304 | /* |
305 | * expand phone number for given prefix and number | |
55a580e3 | 306 | */ |
55a580e3 SL |
307 | exphone(in, out) |
308 | register char *in, *out; | |
309 | { | |
310 | FILE *fn; | |
311 | char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH]; | |
312 | char buf[BUFSIZ]; | |
313 | register char *s1; | |
314 | ||
46b15d8a | 315 | if (!isascii(*in) || !isalpha(*in)) { |
55a580e3 SL |
316 | strcpy(out, in); |
317 | return; | |
318 | } | |
319 | ||
320 | s1=pre; | |
46b15d8a | 321 | while (isascii(*in) && isalpha(*in)) |
55a580e3 SL |
322 | *s1++ = *in++; |
323 | *s1 = '\0'; | |
324 | s1 = npart; | |
325 | while (*in != '\0') | |
326 | *s1++ = *in++; | |
327 | *s1 = '\0'; | |
328 | ||
329 | tpre[0] = '\0'; | |
330 | if ((fn = fopen(DIALFILE, "r")) == NULL) | |
331 | DEBUG(2, "CAN'T OPEN %s\n", DIALFILE); | |
332 | else { | |
333 | while (cfgets(buf, BUFSIZ, fn)) { | |
46b15d8a RC |
334 | if (sscanf(buf, "%s%s", p, tpre) != 2) |
335 | continue; | |
55a580e3 SL |
336 | if (strcmp(p, pre) == SAME) |
337 | goto found; | |
338 | tpre[0] = '\0'; | |
339 | } | |
340 | DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre); | |
341 | found:; | |
342 | fclose(fn); | |
343 | } | |
344 | ||
345 | strcpy(out, tpre); | |
346 | strcat(out, npart); | |
55a580e3 SL |
347 | } |
348 | ||
1a85e9d2 RC |
349 | /* |
350 | * read and decode a line from device file | |
55a580e3 SL |
351 | * |
352 | * return code - FAIL at end-of file; 0 otherwise | |
353 | */ | |
55a580e3 SL |
354 | rddev(fp, dev) |
355 | register struct Devices *dev; | |
356 | FILE *fp; | |
357 | { | |
46b15d8a RC |
358 | register int na; |
359 | ||
360 | if (!cfgets(dev->D_argbfr, sizeof(dev->D_argbfr), fp)) | |
361 | return FAIL; | |
362 | na = getargs(dev->D_argbfr, dev->D_arg, 20); | |
7dd5932d RA |
363 | if (na < 4) { |
364 | syslog(LOG_ERR, "%s: invalid device entry", dev->D_argbfr); | |
365 | cleanup(FAIL); | |
366 | } | |
46b15d8a RC |
367 | if (na == 4) { |
368 | dev->D_brand = ""; | |
369 | na++; | |
370 | } | |
55a580e3 | 371 | dev->D_speed = atoi(fdig(dev->D_class)); |
46b15d8a RC |
372 | dev->D_numargs = na; |
373 | return 0; | |
55a580e3 SL |
374 | } |
375 | ||
1a85e9d2 RC |
376 | /* |
377 | * set system attribute vector | |
55a580e3 SL |
378 | * |
379 | * return codes: | |
380 | * >0 - number of arguments in vector - succeeded | |
381 | * CF_SYSTEM - system name not found | |
382 | * CF_TIME - wrong time to call | |
383 | */ | |
55a580e3 SL |
384 | finds(fsys, sysnam, info, flds) |
385 | char *sysnam, info[], *flds[]; | |
386 | FILE *fsys; | |
387 | { | |
55a580e3 SL |
388 | int na; |
389 | int fcode = 0; | |
390 | ||
391 | /* format of fields | |
392 | * 0 name; | |
393 | * 1 time | |
394 | * 2 acu/hardwired | |
395 | * 3 speed | |
396 | * etc | |
397 | */ | |
398 | while (cfgets(info, MAXC, fsys) != NULL) { | |
46b15d8a | 399 | na = getargs(info, flds, MAXC/10); |
941b257e | 400 | if (strncmp(sysnam, flds[F_NAME], MAXBASENAME) != SAME) |
55a580e3 | 401 | continue; |
1a85e9d2 | 402 | if (ifdate(flds[F_TIME]) != FAIL) |
55a580e3 | 403 | /* found a good entry */ |
46b15d8a | 404 | return na; |
55a580e3 SL |
405 | DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]); |
406 | fcode = CF_TIME; | |
407 | } | |
46b15d8a | 408 | return fcode ? fcode : CF_SYSTEM; |
55a580e3 SL |
409 | } |
410 | ||
1a85e9d2 RC |
411 | /* |
412 | * do login conversation | |
55a580e3 | 413 | * |
941b257e | 414 | * return codes: SUCCESS | FAIL |
55a580e3 | 415 | */ |
55a580e3 SL |
416 | login(nf, flds, fn) |
417 | register char *flds[]; | |
418 | int nf, fn; | |
419 | { | |
420 | register char *want, *altern; | |
55a580e3 SL |
421 | int k, ok; |
422 | ||
7dd5932d RA |
423 | if (nf < 4) { |
424 | syslog(LOG_ERR, "Too few log fields: %d", nf); | |
425 | cleanup(FAIL); | |
426 | } | |
46b15d8a RC |
427 | if (setjmp(Cjbuf)) |
428 | return FAIL; | |
429 | AbortOn = NULL; | |
55a580e3 SL |
430 | for (k = F_LOGIN; k < nf; k += 2) { |
431 | want = flds[k]; | |
f43a5ec5 RA |
432 | if (want == NULL) |
433 | want = ""; | |
55a580e3 | 434 | ok = FAIL; |
46b15d8a | 435 | while (ok != SUCCESS) { |
55a580e3 SL |
436 | altern = index(want, '-'); |
437 | if (altern != NULL) | |
438 | *altern++ = '\0'; | |
46b15d8a RC |
439 | if (strcmp(want, "ABORT") == 0) { |
440 | AbortOn = flds[k+1]; | |
441 | DEBUG(4, "ABORT ON: %s\n", AbortOn); | |
442 | goto nextfield; | |
55a580e3 | 443 | } |
2af814a5 | 444 | DEBUG(4, "wanted \"%s\"\n", want); |
46b15d8a RC |
445 | ok = expect(want, fn); |
446 | DEBUG(4, "got: %s\n", ok ? "?" : "that"); | |
447 | if (ok == FAIL) { | |
448 | if (altern == NULL) { | |
449 | logent("LOGIN", _FAILED); | |
450 | return FAIL; | |
451 | } | |
452 | want = index(altern, '-'); | |
453 | if (want != NULL) | |
454 | *want++ = '\0'; | |
455 | sendthem(altern, fn); | |
456 | } else | |
457 | if (ok == ABORT) { | |
f43a5ec5 RA |
458 | char sbuf[MAXFULLNAME]; |
459 | sprintf(sbuf, "LOGIN ABORTED on \"%s\"", AbortOn); | |
460 | logent(sbuf, _FAILED); | |
941b257e | 461 | return ABORT; |
46b15d8a | 462 | } |
55a580e3 | 463 | } |
46b15d8a | 464 | sleep(1); |
55a580e3 SL |
465 | if (k+1 < nf) |
466 | sendthem(flds[k+1], fn); | |
46b15d8a | 467 | nextfield: ; |
55a580e3 | 468 | } |
46b15d8a | 469 | return SUCCESS; |
55a580e3 SL |
470 | } |
471 | ||
472 | ||
46b15d8a | 473 | /* conditional table generation to support odd speeds */ |
55a580e3 SL |
474 | struct sg_spds {int sp_val, sp_name;} spds[] = { |
475 | #ifdef B50 | |
476 | { 50, B50}, | |
477 | #endif | |
478 | #ifdef B75 | |
479 | { 75, B75}, | |
480 | #endif | |
481 | #ifdef B110 | |
482 | { 110, B110}, | |
483 | #endif | |
484 | #ifdef B150 | |
485 | { 150, B150}, | |
486 | #endif | |
487 | #ifdef B200 | |
488 | { 200, B200}, | |
489 | #endif | |
490 | #ifdef B300 | |
491 | { 300, B300}, | |
492 | #endif | |
493 | #ifdef B600 | |
494 | {600, B600}, | |
495 | #endif | |
496 | #ifdef B1200 | |
497 | {1200, B1200}, | |
498 | #endif | |
499 | #ifdef B1800 | |
500 | {1800, B1800}, | |
501 | #endif | |
502 | #ifdef B2000 | |
503 | {2000, B2000}, | |
504 | #endif | |
505 | #ifdef B2400 | |
506 | {2400, B2400}, | |
507 | #endif | |
508 | #ifdef B3600 | |
509 | {3600, B3600}, | |
510 | #endif | |
511 | #ifdef B4800 | |
512 | {4800, B4800}, | |
513 | #endif | |
514 | #ifdef B7200 | |
515 | {7200, B7200}, | |
516 | #endif | |
517 | #ifdef B9600 | |
518 | {9600, B9600}, | |
519 | #endif | |
520 | #ifdef B19200 | |
46b15d8a RC |
521 | {19200, B19200}, |
522 | #endif | |
523 | #ifdef EXTA | |
524 | {19200, EXTA}, | |
55a580e3 SL |
525 | #endif |
526 | {0, 0} | |
527 | }; | |
528 | ||
1a85e9d2 RC |
529 | /* |
530 | * set speed/echo/mode... | |
55a580e3 SL |
531 | * |
532 | * return codes: none | |
533 | */ | |
55a580e3 SL |
534 | fixline(tty, spwant) |
535 | int tty, spwant; | |
536 | { | |
46b15d8a | 537 | #ifdef USG |
55a580e3 | 538 | struct termio ttbuf; |
46b15d8a | 539 | #else !USG |
55a580e3 | 540 | struct sgttyb ttbuf; |
46b15d8a | 541 | #endif !USG |
55a580e3 SL |
542 | register struct sg_spds *ps; |
543 | int speed = -1; | |
55a580e3 SL |
544 | |
545 | for (ps = spds; ps->sp_val; ps++) | |
546 | if (ps->sp_val == spwant) | |
547 | speed = ps->sp_name; | |
7dd5932d RA |
548 | if (speed < 0) { |
549 | syslog(LOG_ERR, "unrecognized speed: %d", speed); | |
550 | cleanup(FAIL); | |
551 | } | |
46b15d8a | 552 | #ifdef USG |
941b257e JB |
553 | if (ioctl(tty, TCGETA, &ttbuf) < 0) |
554 | return FAIL; | |
55a580e3 SL |
555 | /* ttbuf.sg_flags = (ANYP|RAW); |
556 | ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; */ | |
557 | ttbuf.c_iflag = (ushort)0; | |
558 | ttbuf.c_oflag = (ushort)0; | |
559 | ttbuf.c_cflag = (speed|CS8|HUPCL|CREAD); | |
560 | ttbuf.c_lflag = (ushort)0; | |
561 | ttbuf.c_cc[VMIN] = 6; | |
562 | ttbuf.c_cc[VTIME] = 1; | |
941b257e JB |
563 | if (ioctl(tty, TCSETA, &ttbuf) < 0) |
564 | return FAIL; | |
46b15d8a | 565 | #else !USG |
941b257e JB |
566 | if (ioctl(tty, TIOCGETP, &ttbuf) < 0) |
567 | return FAIL; | |
55a580e3 SL |
568 | ttbuf.sg_flags = (ANYP|RAW); |
569 | ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; | |
941b257e JB |
570 | if (ioctl(tty, TIOCSETP, &ttbuf) < 0) |
571 | return FAIL; | |
55a580e3 | 572 | #endif |
46b15d8a | 573 | #ifndef USG |
941b257e JB |
574 | if (ioctl(tty, TIOCHPCL, STBNULL) < 0) |
575 | return FAIL; | |
576 | if (ioctl(tty, TIOCEXCL, STBNULL) < 0) | |
577 | return FAIL; | |
55a580e3 | 578 | #endif |
46b15d8a | 579 | linebaudrate = spwant; |
941b257e | 580 | return SUCCESS; |
55a580e3 SL |
581 | } |
582 | ||
46b15d8a | 583 | #define MR 100 |
55a580e3 | 584 | |
1a85e9d2 RC |
585 | /* |
586 | * look for expected string | |
55a580e3 SL |
587 | * |
588 | * return codes: | |
589 | * 0 - found | |
590 | * FAIL - lost line or too many characters read | |
591 | * some character - timed out | |
592 | */ | |
55a580e3 SL |
593 | expect(str, fn) |
594 | register char *str; | |
595 | int fn; | |
596 | { | |
50cde384 | 597 | char rdvec[MR]; |
46b15d8a RC |
598 | register char *rp = rdvec, *strptr; |
599 | int kr, cnt_char; | |
55a580e3 | 600 | char nextch; |
01af9d69 | 601 | int timo = MAXMSGTIME; |
55a580e3 | 602 | |
46b15d8a RC |
603 | if (*str == '\0' || strcmp(str, "\"\"") == SAME) |
604 | return SUCCESS; | |
605 | /* Cleanup str, convert \0xx strings to one char */ | |
606 | for (strptr = str; *strptr; strptr++) { | |
607 | if (*strptr == '\\') | |
608 | switch(*++strptr) { | |
609 | case 's': | |
610 | DEBUG(5, "BLANK\n", CNULL); | |
ac09522b | 611 | strptr--; |
46b15d8a | 612 | *strptr = ' '; |
ac09522b | 613 | strcpy(&strptr[1], &strptr[4]); |
46b15d8a RC |
614 | break; |
615 | default: | |
616 | strptr--; /* back up to backslash */ | |
617 | sscanf(strptr + 1,"%o", &cnt_char); | |
618 | DEBUG(6, "BACKSLASHED %02xH\n", cnt_char); | |
619 | *strptr = (char) (cnt_char); | |
620 | strcpy(&strptr[1], &strptr[4]); | |
621 | } | |
55a580e3 | 622 | } |
46b15d8a | 623 | |
01af9d69 JB |
624 | strptr = index(str, '~'); |
625 | if (strptr != NULL) { | |
626 | *strptr++ = '\0'; | |
627 | timo = atoi(strptr); | |
628 | if (timo <= 0) | |
629 | timo = MAXMSGTIME; | |
630 | } | |
631 | ||
46b15d8a RC |
632 | if (setjmp(Sjbuf)) |
633 | return FAIL; | |
55a580e3 | 634 | signal(SIGALRM, alarmtr); |
01af9d69 JB |
635 | alarm(timo); |
636 | *rp = 0; | |
55a580e3 | 637 | while (notin(str, rdvec)) { |
2af814a5 | 638 | int c; |
46b15d8a RC |
639 | if(AbortOn != NULL && !notin(AbortOn, rdvec)) { |
640 | DEBUG(1, "Call aborted on '%s'\n", AbortOn); | |
641 | alarm(0); | |
642 | return ABORT; | |
643 | } | |
55a580e3 SL |
644 | kr = read(fn, &nextch, 1); |
645 | if (kr <= 0) { | |
646 | alarm(0); | |
647 | DEBUG(4, "lost line kr - %d\n, ", kr); | |
648 | logent("LOGIN", "LOST LINE"); | |
46b15d8a | 649 | return FAIL; |
55a580e3 | 650 | } |
55a580e3 | 651 | c = nextch & 0177; |
2af814a5 JB |
652 | if (c == '\0') |
653 | continue; | |
654 | DEBUG(4, (isprint(c) || isspace(c)) ? "%c" : "\\%03o", c); | |
655 | *rp++ = c; | |
55a580e3 | 656 | if (rp >= rdvec + MR) { |
46b15d8a RC |
657 | register char *p; |
658 | for (p = rdvec+MR/2; p < rp; p++) | |
659 | *(p-MR/2) = *p; | |
660 | rp -= MR/2; | |
55a580e3 SL |
661 | } |
662 | *rp = '\0'; | |
663 | } | |
664 | alarm(0); | |
46b15d8a | 665 | return SUCCESS; |
55a580e3 SL |
666 | } |
667 | ||
668 | ||
669 | /* | |
670 | * Determine next file descriptor that would be allocated. | |
671 | * This permits later closing of a file whose open was interrupted. | |
672 | * It is a UNIX kernel problem, but it has to be handled. | |
673 | * unc!smb (Steve Bellovin) probably first discovered it. | |
674 | */ | |
675 | getnextfd() | |
676 | { | |
677 | close(next_fd = open("/", 0)); | |
678 | } | |
679 | ||
46b15d8a RC |
680 | /* |
681 | * send line of login sequence | |
55a580e3 SL |
682 | * |
683 | * return codes: none | |
684 | */ | |
55a580e3 SL |
685 | sendthem(str, fn) |
686 | register char *str; | |
687 | int fn; | |
688 | { | |
689 | register char *strptr; | |
690 | int i, n, cr = 1; | |
46b15d8a | 691 | register char c; |
55a580e3 SL |
692 | static int p_init = 0; |
693 | ||
2af814a5 | 694 | DEBUG(5, "send \"%s\"\n", str); |
55a580e3 SL |
695 | |
696 | if (!p_init) { | |
697 | p_init++; | |
7dd5932d | 698 | bld_partab(P_ZERO); |
55a580e3 SL |
699 | } |
700 | ||
701 | if (prefix("BREAK", str)) { | |
702 | sscanf(&str[5], "%1d", &i); | |
703 | if (i <= 0 || i > 10) | |
704 | i = 3; | |
705 | /* send break */ | |
706 | genbrk(fn, i); | |
707 | return; | |
708 | } | |
709 | ||
710 | if (prefix("PAUSE", str)) { | |
711 | sscanf(&str[5], "%1d", &i); | |
712 | if (i <= 0 || i > 10) | |
713 | i = 3; | |
714 | /* pause for a while */ | |
715 | sleep((unsigned)i); | |
716 | return; | |
717 | } | |
718 | ||
719 | if (strcmp(str, "EOT") == SAME) { | |
720 | p_chwrite(fn, '\04'); | |
721 | return; | |
722 | } | |
723 | ||
55a580e3 | 724 | /* Send a '\n' */ |
2af814a5 JB |
725 | if (strcmp(str, "LF") == SAME) { |
726 | p_chwrite(fn, '\n'); | |
727 | return; | |
728 | } | |
55a580e3 SL |
729 | |
730 | /* Send a '\r' */ | |
2af814a5 JB |
731 | if (strcmp(str, "CR") == SAME) { |
732 | p_chwrite(fn, '\r'); | |
733 | return; | |
734 | } | |
55a580e3 SL |
735 | |
736 | /* Set parity as needed */ | |
737 | if (strcmp(str, "P_ZERO") == SAME) { | |
738 | bld_partab(P_ZERO); | |
739 | return; | |
740 | } | |
741 | if (strcmp(str, "P_ONE") == SAME) { | |
742 | bld_partab(P_ONE); | |
743 | return; | |
744 | } | |
745 | if (strcmp(str, "P_EVEN") == SAME) { | |
746 | bld_partab(P_EVEN); | |
747 | return; | |
748 | } | |
749 | if (strcmp(str, "P_ODD") == SAME) { | |
750 | bld_partab(P_ODD); | |
751 | return; | |
752 | } | |
753 | ||
754 | /* If "", just send '\r' */ | |
46b15d8a RC |
755 | if (strcmp(str, "\"\"") == SAME) { |
756 | p_chwrite(fn, '\r'); | |
757 | return; | |
758 | } | |
759 | ||
2af814a5 JB |
760 | strptr = str; |
761 | while ((c = *strptr++) != '\0') { | |
46b15d8a RC |
762 | if (c == '\\') { |
763 | switch(*strptr++) { | |
2af814a5 JB |
764 | case '\0': |
765 | DEBUG(5, "TRAILING BACKSLASH IGNORED\n", CNULL); | |
766 | --strptr; | |
767 | continue; | |
46b15d8a RC |
768 | case 's': |
769 | DEBUG(5, "BLANK\n", CNULL); | |
2af814a5 | 770 | c = ' '; |
46b15d8a RC |
771 | break; |
772 | case 'd': | |
773 | DEBUG(5, "DELAY\n", CNULL); | |
774 | sleep(1); | |
775 | continue; | |
2af814a5 JB |
776 | case 'n': |
777 | DEBUG(5, "NEW LINE\n", CNULL); | |
778 | c = '\n'; | |
779 | break; | |
46b15d8a RC |
780 | case 'r': |
781 | DEBUG(5, "RETURN\n", CNULL); | |
2af814a5 | 782 | c = '\r'; |
46b15d8a RC |
783 | break; |
784 | case 'b': | |
785 | if (isdigit(*strptr)) { | |
786 | i = (*strptr++ - '0'); | |
787 | if (i <= 0 || i > 10) | |
788 | i = 3; | |
789 | } else | |
55a580e3 | 790 | i = 3; |
46b15d8a RC |
791 | /* send break */ |
792 | genbrk(fn, i); | |
793 | if (*strptr == '\0') | |
794 | cr = 0; | |
55a580e3 | 795 | continue; |
46b15d8a RC |
796 | case 'c': |
797 | if (*strptr == '\0') { | |
798 | DEBUG(5, "NO CR\n", CNULL); | |
799 | cr = 0; | |
2af814a5 JB |
800 | } else |
801 | DEBUG(5, "NO CR - IGNORED NOT EOL\n", CNULL); | |
55a580e3 | 802 | continue; |
2af814a5 | 803 | #define isoctal(x) ((x >= '0') && (x <= '7')) |
46b15d8a | 804 | default: |
2af814a5 | 805 | if (isoctal(strptr[-1])) { |
46b15d8a RC |
806 | i = 0; |
807 | n = 0; | |
2af814a5 JB |
808 | --strptr; |
809 | while (isoctal(*strptr) && ++n <= 3) | |
810 | i = i * 8 + (*strptr++ - '0'); | |
811 | DEBUG(5, "\\%o\n", i); | |
46b15d8a RC |
812 | p_chwrite(fn, (char)i); |
813 | continue; | |
814 | } | |
55a580e3 | 815 | } |
2af814a5 JB |
816 | } |
817 | p_chwrite(fn, c); | |
55a580e3 SL |
818 | } |
819 | ||
55a580e3 SL |
820 | if (cr) |
821 | p_chwrite(fn, '\r'); | |
822 | return; | |
823 | } | |
824 | ||
825 | p_chwrite(fd, c) | |
826 | int fd; | |
46b15d8a | 827 | char c; |
55a580e3 | 828 | { |
46b15d8a RC |
829 | c = par_tab[c&0177]; |
830 | if (write(fd, &c, 1) != 1) { | |
831 | logent(sys_errlist[errno], "BAD WRITE"); | |
832 | longjmp(Cjbuf, 2); | |
833 | } | |
55a580e3 SL |
834 | } |
835 | ||
836 | /* | |
837 | * generate parity table for use by p_chwrite. | |
838 | */ | |
839 | bld_partab(type) | |
840 | int type; | |
841 | { | |
842 | register int i, j, n; | |
843 | ||
844 | for (i = 0; i < sizeof(par_tab); i++) { | |
845 | n = 0; | |
846 | for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j) | |
847 | n++; | |
848 | par_tab[i] = i; | |
849 | if (type == P_ONE | |
850 | || (type == P_EVEN && (n&01) != 0) | |
851 | || (type == P_ODD && (n&01) == 0)) | |
852 | par_tab[i] |= sizeof(par_tab); | |
853 | } | |
854 | } | |
855 | ||
1a85e9d2 RC |
856 | /* |
857 | * check for occurrence of substring "sh" | |
55a580e3 SL |
858 | * |
859 | * return codes: | |
860 | * 0 - found the string | |
861 | * 1 - not in the string | |
862 | */ | |
55a580e3 SL |
863 | notin(sh, lg) |
864 | register char *sh, *lg; | |
865 | { | |
866 | while (*lg != '\0') { | |
55a580e3 | 867 | if (wprefix(sh, lg)) |
1a85e9d2 | 868 | return 0; |
55a580e3 SL |
869 | else |
870 | lg++; | |
871 | } | |
1a85e9d2 | 872 | return 1; |
55a580e3 SL |
873 | } |
874 | ||
1a85e9d2 | 875 | /* |
941b257e | 876 | * Allow multiple date specifications separated by ','. |
55a580e3 | 877 | */ |
1a85e9d2 RC |
878 | ifdate(p) |
879 | register char *p; | |
55a580e3 | 880 | { |
2af814a5 | 881 | register char *np; |
1a85e9d2 | 882 | register int ret, g; |
941b257e JB |
883 | int rtime, i; |
884 | ||
885 | /* pick up retry time for failures */ | |
886 | /* global variable Retrytime is set here */ | |
887 | if ((np = index(p, ';')) == NULL) { | |
888 | Retrytime = RETRYTIME; | |
889 | } else { | |
890 | i = sscanf(np+1, "%d", &rtime); | |
891 | if (i < 1 || rtime < 0) | |
892 | rtime = 5; | |
893 | Retrytime = rtime * 60; | |
894 | } | |
1a85e9d2 RC |
895 | |
896 | ret = FAIL; | |
897 | MaxGrade = '\0'; | |
898 | do { | |
941b257e JB |
899 | np = strpbrk(p, ",|"); /* prefer , but allow | for compat */ |
900 | if (np) | |
901 | *np = '\0'; | |
1a85e9d2 RC |
902 | g = ifadate(p); |
903 | DEBUG(11,"ifadate returns %o\n", g); | |
904 | if (g != FAIL) { | |
905 | ret = SUCCESS; | |
906 | if (g > MaxGrade) | |
907 | MaxGrade = g; | |
908 | } | |
941b257e JB |
909 | if (np) |
910 | *np = ','; | |
911 | p = np + 1; | |
912 | } while (np); | |
913 | if (MaxGrade == '\0') | |
914 | MaxGrade = DefMaxGrade; | |
1a85e9d2 | 915 | return ret; |
55a580e3 SL |
916 | } |
917 | ||
1a85e9d2 RC |
918 | /* |
919 | * this routine will check a string (string) | |
55a580e3 SL |
920 | * like "MoTu0800-1730" to see if the present |
921 | * time is within the given limits. | |
922 | * SIDE EFFECT - Retrytime is set | |
923 | * | |
55a580e3 SL |
924 | * return codes: |
925 | * 0 - not within limits | |
926 | * 1 - within limits | |
927 | */ | |
928 | ||
1a85e9d2 RC |
929 | ifadate(string) |
930 | char *string; | |
55a580e3 SL |
931 | { |
932 | static char *days[]={ | |
933 | "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 | |
934 | }; | |
935 | time_t clock; | |
1a85e9d2 | 936 | register char *s = string; |
46b15d8a | 937 | int i, tl, th, tn, dayok=0; |
55a580e3 SL |
938 | struct tm *localtime(); |
939 | struct tm *tp; | |
1a85e9d2 | 940 | char *p, MGrade; |
55a580e3 | 941 | |
941b257e | 942 | if ((p = index(s, '/')) == NULL) |
1a85e9d2 RC |
943 | MGrade = DefMaxGrade; |
944 | else | |
945 | MGrade = p[1]; | |
946 | ||
55a580e3 SL |
947 | time(&clock); |
948 | tp = localtime(&clock); | |
46b15d8a | 949 | while (isascii(*s) && isalpha(*s)) { |
55a580e3 SL |
950 | for (i = 0; days[i]; i++) { |
951 | if (prefix(days[i], s)) | |
952 | if (tp->tm_wday == i) | |
953 | dayok = 1; | |
954 | } | |
955 | ||
956 | if (prefix("Wk", s)) | |
957 | if (tp->tm_wday >= 1 && tp->tm_wday <= 5) | |
958 | dayok = 1; | |
959 | if (prefix("Any", s)) | |
960 | dayok = 1; | |
46b15d8a RC |
961 | if (prefix("Evening", s)) { |
962 | /* Sat or Sun */ | |
963 | if (tp->tm_wday == 6 || tp->tm_wday == 0 | |
964 | || tp->tm_hour >= 17 || tp->tm_hour < 8) | |
965 | dayok = 1; | |
966 | } | |
967 | if (prefix("Night", s)) { | |
968 | if (tp->tm_wday == 6 /* Sat */ | |
1a85e9d2 RC |
969 | || tp->tm_hour >= 23 || tp->tm_hour < 8 |
970 | /* Sunday before 5pm */ | |
971 | || (tp->tm_wday == 0 && tp->tm_hour < 17)) | |
46b15d8a RC |
972 | dayok = 1; |
973 | } | |
2af814a5 JB |
974 | if (prefix("NonPeak", s)) { /* For Tymnet and PC Pursuit */ |
975 | /* Sat or Sun */ | |
976 | if (tp->tm_wday == 6 || tp->tm_wday == 0 | |
977 | || tp->tm_hour >= 18 || tp->tm_hour < 7) | |
978 | dayok = 1; | |
979 | } | |
55a580e3 SL |
980 | s++; |
981 | } | |
982 | ||
1a85e9d2 RC |
983 | if (dayok == 0 && s != string) |
984 | return FAIL; | |
55a580e3 | 985 | i = sscanf(s, "%d-%d", &tl, &th); |
1a85e9d2 RC |
986 | if (i < 2) |
987 | return MGrade; | |
46b15d8a | 988 | tn = tp->tm_hour * 100 + tp->tm_min; |
1a85e9d2 RC |
989 | if (th < tl) { /* crosses midnight */ |
990 | if (tl <= tn || tn < th) | |
991 | return MGrade; | |
9313cec6 | 992 | } else { |
46b15d8a | 993 | if (tl <= tn && tn < th) |
1a85e9d2 | 994 | return MGrade; |
9313cec6 | 995 | } |
1a85e9d2 | 996 | return FAIL; |
55a580e3 SL |
997 | } |
998 | ||
1a85e9d2 RC |
999 | /* |
1000 | * find first digit in string | |
55a580e3 SL |
1001 | * |
1002 | * return - pointer to first digit in string or end of string | |
1003 | */ | |
55a580e3 SL |
1004 | char * |
1005 | fdig(cp) | |
1006 | register char *cp; | |
1007 | { | |
1008 | register char *c; | |
1009 | ||
1010 | for (c = cp; *c; c++) | |
1011 | if (*c >= '0' && *c <= '9') | |
1012 | break; | |
46b15d8a | 1013 | return c; |
55a580e3 SL |
1014 | } |
1015 | ||
55a580e3 SL |
1016 | /* |
1017 | * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 | |
1018 | * Strings are compared as if they contain all capital letters. | |
1019 | */ | |
55a580e3 SL |
1020 | snccmp(s1, s2) |
1021 | register char *s1, *s2; | |
1022 | { | |
1023 | char c1, c2; | |
1024 | ||
01af9d69 JB |
1025 | if (islower(*s1)) |
1026 | c1 = toupper(*s1); | |
1027 | else | |
1028 | c1 = *s1; | |
1029 | if (islower(*s2)) | |
1030 | c2 = toupper(*s2); | |
1031 | else | |
1032 | c2 = *s2; | |
55a580e3 SL |
1033 | |
1034 | while (c1 == c2) { | |
01af9d69 | 1035 | if (*s1++ == '\0') |
46b15d8a | 1036 | return 0; |
55a580e3 | 1037 | s2++; |
01af9d69 JB |
1038 | if (islower(*s1)) |
1039 | c1 = toupper(*s1); | |
1040 | else | |
1041 | c1 = *s1; | |
1042 | if (islower(*s2)) | |
1043 | c2 = toupper(*s2); | |
1044 | else | |
1045 | c2 = *s2; | |
55a580e3 | 1046 | } |
46b15d8a RC |
1047 | return c1 - c2; |
1048 | } | |
01af9d69 JB |
1049 | |
1050 | /* | |
1051 | * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 | |
1052 | * Strings are compared as if they contain all capital letters. | |
1053 | */ | |
1054 | sncncmp(s1, s2, n) | |
1055 | register char *s1, *s2; | |
1056 | register int n; | |
1057 | { | |
1058 | char c1, c2; | |
1059 | ||
1060 | if (islower(*s1)) | |
1061 | c1 = toupper(*s1); | |
1062 | else | |
1063 | c1 = *s1; | |
1064 | if (islower(*s2)) | |
1065 | c2 = toupper(*s2); | |
1066 | else | |
1067 | c2 = *s2; | |
1068 | ||
1069 | while ( --n >= 0 && c1 == c2) { | |
1070 | if (*s1++ == '\0') | |
1071 | return 0; | |
1072 | s2++; | |
1073 | if (islower(*s1)) | |
1074 | c1 = toupper(*s1); | |
1075 | else | |
1076 | c1 = *s1; | |
1077 | if (islower(*s2)) | |
1078 | c2 = toupper(*s2); | |
1079 | else | |
1080 | c2 = *s2; | |
1081 | } | |
1082 | return n<0 ? 0 : (c1 - c2); | |
1083 | } | |
46b15d8a RC |
1084 | /* |
1085 | * do chat script | |
1086 | * occurs after local port is opened, | |
1087 | * before 'dialing' the other machine. | |
1088 | */ | |
1089 | dochat(dev, flds, fd) | |
1090 | register struct Devices *dev; | |
1091 | char *flds[]; | |
1092 | int fd; | |
1093 | { | |
1094 | register int i; | |
1095 | register char *p; | |
1096 | char bfr[sizeof(dev->D_argbfr)]; | |
1097 | ||
1098 | if (dev->D_numargs <= 5) | |
1099 | return(0); | |
1100 | DEBUG(4, "dochat called %d\n", dev->D_numargs); | |
1101 | for (i = 0; i < dev->D_numargs-5; i++) { | |
1102 | sprintf(bfr, dev->D_arg[D_CHAT+i], flds[F_PHONE]); | |
1103 | if (strcmp(bfr, dev->D_arg[D_CHAT+i])) { | |
1104 | p = malloc((unsigned)strlen(bfr)+1); | |
1105 | if (p != NULL) { | |
1106 | strcpy(p, bfr); | |
1107 | dev->D_arg[D_CHAT+i] = p; | |
1108 | } | |
1109 | } | |
1110 | } | |
1111 | /* following is a kludge because login() arglist is a kludge */ | |
1112 | i = login(dev->D_numargs, &dev->D_arg[D_CHAT-5], fd); | |
1113 | /* | |
1114 | * If login() last did a sendthem(), must pause so things can settle. | |
1115 | * But don't bother if chat failed. | |
1116 | */ | |
1117 | if (i == 0 && (dev->D_numargs&01)) | |
1118 | sleep(2); | |
1119 | return(i); | |
55a580e3 | 1120 | } |
2af814a5 JB |
1121 | |
1122 | /* | |
1123 | * fix kill/echo/raw on line | |
1124 | * | |
1125 | * return codes: none | |
1126 | */ | |
1127 | fixmode(tty) | |
1128 | register int tty; | |
1129 | { | |
1130 | #ifdef USG | |
1131 | struct termio ttbuf; | |
1132 | #else !USG | |
1133 | struct sgttyb ttbuf; | |
1134 | #endif !USG | |
1135 | register struct sg_spds *ps; | |
1136 | int speed; | |
1137 | ||
1138 | if (IsTcpIp) | |
1139 | return; | |
1140 | #ifdef USG | |
1141 | ioctl(tty, TCGETA, &ttbuf); | |
1142 | ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; | |
1143 | speed = ttbuf.c_cflag &= (CBAUD); | |
1144 | ttbuf.c_cflag |= (CS8|CREAD); | |
1145 | ttbuf.c_cc[VMIN] = 6; | |
1146 | ttbuf.c_cc[VTIME] = 1; | |
1147 | ioctl(tty, TCSETA, &ttbuf); | |
1148 | #else !USG | |
1149 | ioctl(tty, TIOCGETP, &ttbuf); | |
1150 | ttbuf.sg_flags = (ANYP | RAW); | |
1151 | ioctl(tty, TIOCSETP, &ttbuf); | |
1152 | speed = ttbuf.sg_ispeed; | |
1153 | ioctl(tty, TIOCEXCL, STBNULL); | |
1154 | #endif !USG | |
1155 | ||
1156 | for (ps = spds; ps->sp_val; ps++) | |
1157 | if (ps->sp_name == speed) { | |
1158 | linebaudrate = ps->sp_val; | |
1159 | DEBUG(9,"Incoming baudrate is %d\n", linebaudrate); | |
1160 | return; | |
1161 | } | |
7dd5932d RA |
1162 | if (linebaudrate < 0) { |
1163 | syslog(LOG_ERR, "unrecognized speed: %d", linebaudrate); | |
1164 | cleanup(FAIL); | |
1165 | } | |
2af814a5 | 1166 | } |