|
|
1.1 root 1: /* C K U U S 3 -- "User Interface" for Unix Kermit, part 3 */
2:
3: /*
4: Author: Frank da Cruz (SY.FDC@CU20B),
5: Columbia University Center for Computing Activities, January 1985.
6: Copyright (C) 1985, Trustees of Columbia University in the City of New York.
7: Permission is granted to any individual or institution to use, copy, or
8: redistribute this software so long as it is not sold for profit, provided this
9: copyright notice is retained.
10: */
11:
12: /* SET and REMOTE commands; screen, debug, interrupt, and logging functions */
13:
14: /* Includes */
15:
16: #include "ckcdeb.h"
17: #include <stdio.h>
18: #include <ctype.h>
19: #include "ckcker.h"
20: #include "ckucmd.h"
21: #include "ckuusr.h"
22: #ifdef UXIII
23: #include <termio.h>
24: #endif
25:
26: #ifdef datageneral
27: extern int con_reads_mt, /* Flag if console read asynch is active */
28: conint_ch, /* The character read by asynch read */
29: conint_avl; /* Flag that char available */
30: #endif
31:
32: /* Variables */
33:
34: extern int size, spsiz, rpsiz, urpsiz, npad, timint, rtimo, speed,
35: local, server, lpcapr, fmask, cmask, backgrd,
36: flow, displa, binary, fncnv, delay, parity, deblog, escape, xargc,
37: turn, duplex, cxseen, czseen, nfils, ckxech, pktlog, seslog, tralog, stdouf,
38: turnch, bctr, bctu, dfloc, mdmtyp, keep, maxtry,
39: rptflg, ebqflg, warn, quiet, cnflg, timef, spsizf, mypadn;
40:
41: extern long filcnt, tlci, tlco, ffc, tfc, fsize;
42:
43: extern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
44: extern char *cmarg, *cmarg2, **xargv, **cmlist;
45: extern CHAR stchr, mystch, sstate, padch, mypadc, eol, seol, ctlq;
46: extern CHAR filnam[], ttname[];
47: char *strcpy();
48:
49: /* Declarations from cmd package */
50:
51: extern char cmdbuf[]; /* Command buffer */
52:
53: /* From main ckuser module... */
54:
55: extern char line[100], *lp; /* Character buffer for anything */
56: extern char debfil[50], /* Debugging log file name */
57: pktfil[50], /* Packet log file name */
58: sesfil[50], /* Session log file name */
59: trafil[50]; /* Transaction log file name */
60:
61: extern int tlevel; /* Take Command file level */
62: extern FILE *tfile[]; /* Array of take command fd's */
63:
64:
65: /* Keyword tables for SET commands */
66:
67:
68: /* Block checks */
69:
70: struct keytab blktab[] = {
71: "1", 1, 0,
72: "2", 2, 0,
73: "3", 3, 0
74: };
75:
76: /* Duplex keyword table */
77:
78: struct keytab dpxtab[] = {
79: "full", 0, 0,
80: "half", 1, 0
81: };
82:
83: struct keytab filtab[] = {
84: "display", XYFILD, 0,
85: "names", XYFILN, 0,
86: "type", XYFILT, 0,
87: "warning", XYFILW, 0
88: };
89: int nfilp = (sizeof(filtab) / sizeof(struct keytab));
90:
91: /* Send/Receive Parameters */
92:
93: struct keytab srtab[] = {
94: "end-of-packet", XYEOL, 0,
95: "packet-length", XYLEN, 0,
96: "pad-character", XYPADC, 0,
97: "padding", XYNPAD, 0,
98: "start-of-packet", XYMARK, 0,
99: "timeout", XYTIMO, 0
100: };
101: int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
102:
103: /* Flow Control */
104:
105: struct keytab flotab[] = {
106: "none", 0, 0,
107: "xon/xoff", 1, 0
108: };
109: int nflo = (sizeof(flotab) / sizeof(struct keytab));
110:
111: /* Handshake characters */
112:
113: struct keytab hshtab[] = {
114: "bell", 007, 0,
115: "cr", 015, 0,
116: "esc", 033, 0,
117: "lf", 012, 0,
118: "none", 999, 0, /* (can't use negative numbers) */
119: "xoff", 023, 0,
120: "xon", 021, 0
121: };
122: int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
123:
124: struct keytab fntab[] = { /* File naming */
125: "converted", 1, 0,
126: "literal", 0, 0
127: };
128:
129: struct keytab fttab[] = { /* File types */
130: "binary", 1, 0,
131: "text", 0, 0
132: };
133:
134: extern struct keytab mdmtab[] ; /* Modem types (in module ckudia.c) */
135: extern int nmdm;
136:
137: /* Parity keyword table */
138:
139: struct keytab partab[] = {
140: "even", 'e', 0,
141: "mark", 'm', 0,
142: "none", 0, 0,
143: "odd", 'o', 0,
144: "space", 's', 0
145: };
146: int npar = (sizeof(partab) / sizeof(struct keytab));
147:
148:
149: /* On/Off table */
150:
151: struct keytab onoff[] = {
152: "off", 0, 0,
153: "on", 1, 0
154: };
155:
156: /* Incomplete File Disposition table */
157:
158: struct keytab ifdtab[] = {
159: "discard", 0, 0,
160: "keep", 1, 0
161: };
162:
163: /* Terminal parameters table */
164:
165: struct keytab trmtab[] = {
166: "bytesize", 0, 0
167: };
168:
169: /* D O P R M -- Set a parameter. */
170: /*
171: Returns:
172: -2: illegal input
173: -1: reparse needed
174: 0: success
175: */
176: doprm(xx) int xx; {
177: int x, y, z;
178: char *s;
179:
180: switch (xx) {
181:
182:
183: case XYEOL: /* These have all been moved to set send/receive... */
184: case XYLEN: /* Let the user know what to do. */
185: case XYMARK:
186: case XYNPAD:
187: case XYPADC:
188: case XYTIMO:
189: printf("...Use 'set send' or 'set receive' instead.\n");
190: printf("Type 'help set send' or 'help set receive' for more info.\n");
191: return(0);
192:
193: case XYIFD: /* Incomplete file disposition */
194: if ((y = cmkey(ifdtab,2,"","discard")) < 0) return(y);
195: if ((x = cmcfm()) < 0) return(x);
196: keep = y;
197: return(0);
198:
199: case XYLINE:
200: if ((x = cmtxt("Device name",dftty,&s)) < 0) return(x);
201: ttclos(); /* close old line, if any was open */
202:
203: x = strcmp(s,dftty) ? -1 : dfloc; /* Maybe let ttopen figure it out... */
204: if (ttopen(s,&x,mdmtyp) < 0 ) { /* Can we open the new line? */
205: perror("Sorry, can't open line");
206: return(-2); /* If not, give bad return */
207: }
208: if (x > -1) local = x; /* Set local/remote status. */
209: strcpy(ttname,s); /* OK, copy name into real place. */
210: if (!local) speed = -1; /* If remote, say speed unknown. */
211: debug(F111,"set line ",ttname,local);
212: return(0);
213:
214: case XYCHKT:
215: if ((y = cmkey(blktab,3,"","1")) < 0) return(y);
216: if ((x = cmcfm()) < 0) return(x);
217: bctr = y;
218: return(0);
219:
220: case XYDEBU:
221: return(seton(&deblog));
222:
223: case XYDELA:
224: y = cmnum("Number of seconds before starting to send","5",10,&x);
225: debug(F101,"XYDELA: y","",y);
226: return(setnum(&delay,x,y,94));
227:
228: case XYDUPL:
229: if ((y = cmkey(dpxtab,2,"","full")) < 0) return(y);
230: if ((x = cmcfm()) < 0) return(x);
231: duplex = y;
232: return(0);
233:
234: case XYESC:
235: y = cmnum("Decimal ASCII code for escape character","",10,&x);
236: return(setcc(&escape,x,y));
237:
238: case XYFILE:
239: if ((y = cmkey(filtab,nfilp,"File parameter","")) < 0) return(y);
240: switch (y) {
241: int z;
242: case XYFILD: /* Display */
243: y = seton(&z);
244: if (y < 0) return(y);
245: quiet = !z;
246: return(0);
247:
248: case XYFILN: /* Names */
249: if ((x = cmkey(fntab,2,"how to handle filenames","converted")) < 0)
250: return(x);
251: if ((z = cmcfm()) < 0) return(z);
252: fncnv = x;
253: return(0);
254:
255: case XYFILT: /* Type */
256: if ((x = cmkey(fttab,2,"type of file","text")) < 0)
257: return(x);
258: if ((y = cmnum("file byte size (7 or 8)","8",10,&z)) < 0)
259: return(y);
260: if (z != 7 && z != 8) {
261: printf("\n?The choices are 7 and 8\n");
262: return(-2);
263: }
264: if ((y = cmcfm()) < 0) return(y);
265: binary = x;
266: if (z == 7) fmask = 0177;
267: else if (z == 8) fmask = 0377;
268: return(0);
269:
270: case XYFILW: /* Warning/Write-Protect */
271: return(seton(&warn));
272:
273: default:
274: printf("?unexpected file parameter\n");
275: return(-2);
276: }
277:
278: case XYFLOW: /* Flow control */
279: if ((y = cmkey(flotab,nflo,"","xon/xoff")) < 0) return(y);
280: if ((x = cmcfm()) < 0) return(x);
281: flow = y;
282: return(0);
283:
284: case XYHAND: /* Handshake */
285: if ((y = cmkey(hshtab,nhsh,"","none")) < 0) return(y);
286: if ((x = cmcfm()) < 0) return(x);
287: turn = (y > 0127) ? 0 : 1 ;
288: turnch = y;
289: return(0);
290:
291: case XYMODM:
292: if ((x=cmkey(mdmtab,nmdm,"type of modem, direct means none","direct")) < 0)
293: return(x);
294: if ((z = cmcfm()) < 0) return(z);
295: mdmtyp = x;
296: return(0);
297:
298: case XYPARI: /* Parity */
299: if ((y = cmkey(partab,npar,"","none")) < 0) return(y);
300: if ((x = cmcfm()) < 0) return(x);
301:
302: /* If parity not none, then we also want 8th-bit prefixing */
303:
304: if (parity = y) ebqflg = 1; else ebqflg = 0;
305: return(0);
306:
307: case XYPROM:
308: if ((x = cmtxt("Program's command prompt","C-Kermit>",&s)) < 0) return(x);
309: if (*s == '\42') { /* Quoted string? */
310: x = strlen(s) - 1; /* Yes, strip quotes. */
311: if (*(s+x) == '\42') /* This allows leading or trailing */
312: *(s+x) = '\0'; /* blanks. */
313: s++;
314: }
315: cmsetp(s);
316: return(0);
317:
318: case XYRETR: /* Per-packet retry limit */
319: y = cmnum("Maximum retries per packet","10",10,&x);
320: return(setnum(&maxtry,x,y,94));
321:
322: case XYTERM: /* Terminal parameters */
323: if ((y = cmkey(trmtab,1,"","bytesize")) < 0) return(y);
324: switch (y) {
325: case 0:
326: if ((y = cmnum("bytesize for terminal connection","8",10,&x)) < 0)
327: return(y);
328: if (x != 7 && x != 8) {
329: printf("\n?The choices are 7 and 8\n");
330: return(-2);
331: }
332: if ((y = cmcfm()) < 0) return(y);
333: if (x == 7) cmask = 0177;
334: else if (x == 8) cmask = 0377;
335: return(y);
336: default: /* Add more cases when we think of more parameters */
337: return(-2);
338: }
339:
340: /* SET SEND/RECEIVE... */
341:
342: case XYRECV:
343: case XYSEND:
344: if (xx == XYRECV)
345: strcpy(line,"Parameter for inbound packets");
346: else
347: strcpy(line,"Parameter for outbound packets");
348:
349: if ((y = cmkey(srtab,nsrtab,line,"")) < 0) return(y);
350: switch (y) {
351:
352: case XYEOL:
353: y = cmnum("Decimal ASCII code for packet terminator","13",10,&x);
354: if ((y = setcc(&z,x,y)) < 0) return(y);
355: if (xx == XYRECV) eol = z; else seol = z;
356: return(y);
357:
358: case XYLEN:
359: y = cmnum("Maximum number of characters in a packet","90",10,&x);
360: if (xx == XYRECV) { /* Receive... */
361: if ((y = setnum(&z,x,y,MAXRP)) < 0)
362: return(y);
363: urpsiz = z;
364: rpsiz = (z > 94) ? 94 : z;
365: } else { /* Send... */
366: if ((y = setnum(&z,x,y,MAXSP)) < 0)
367: return(y);
368: spsiz = z; /* Set it and flag that it was set */
369: spsizf = 1; /* to allow overriding Send-Init. */
370: }
371: if (z > 94 && !backgrd) printf("Extended-length packets requested\n");
372: return(y);
373:
374: case XYMARK:
375: y = cmnum("Decimal ASCII code for packet-start character","1",10,&x);
376: if ((y = setcc(&z,x,y)) < 0) return(y);
377: if (xx == XYRECV) stchr = z; else mystch = z;
378: return(y);
379:
380: case XYNPAD: /* Padding */
381: y = cmnum("How many padding characters for inbound packets","0",10,&x);
382: if ((y = setnum(&z,x,y,94)) < 0) return(y);
383: if (xx == XYRECV) mypadn = z; else npad = z;
384: return(y);
385:
386: case XYPADC: /* Pad character */
387: y = cmnum("Decimal ASCII code for inbound pad character","0",10,&x);
388: if ((y = setcc(&z,x,y)) < 0) return(y);
389: if (xx == XYRECV) mypadc = z; else padch = z;
390: return(y);
391:
392: case XYTIMO:
393: y = cmnum("Interpacket timeout interval","5",10,&x);
394: if ((y = setnum(&z,x,y,94)) < 0) return(y);
395: if (xx == XYRECV) {
396: timef = 1;
397: timint = z;
398: } else rtimo = z;
399: return(y);
400:
401: }
402:
403: case XYSPEE:
404: if (!local) {
405: printf("\nSpeed setting can only be done on an external line\n");
406: printf("You must 'set line' before issuing this command\n");
407: return(0);
408: }
409: lp = line;
410: sprintf(lp,"Baud rate for %s",ttname);
411: if ((y = cmnum(line,"",10,&x)) < 0) return(y);
412: if (y = (cmcfm()) < 0) return(y);
413: y = chkspd(x);
414: if (y < 0)
415: printf("?Unsupported line speed - %d\n",x);
416: else {
417: speed = y;
418: if (!backgrd) printf("%s: %d baud\n",ttname,speed);
419: }
420: return(0);
421:
422: default:
423: if ((x = cmcfm()) < 0) return(x);
424: printf("Not working yet - %s\n",cmdbuf);
425: return(0);
426: }
427: }
428:
429: /* C H K S P D -- Check if argument is a valid baud rate */
430:
431: chkspd(x) int x; {
432: switch (x) {
433: #ifndef AMIGA
434: case 0:
435: #endif
436: #ifndef datageneral
437: case 110:
438: case 150:
439: case 300:
440: case 600:
441: case 1200:
442: case 1800:
443: case 2400:
444: case 4800:
445: case 9600:
446: #ifdef apollo
447: case 19200:
448: #else
449: #ifdef AMIGA
450: case 19200:
451: case 38400:
452: case 57600:
453: #else
454: /* #ifdef B19200 (this high speed stuff needs much more work...)
455: /* case 19200: (have to make corresponding changes in ckuus2, ckutio)
456: /* #else
457: /* #ifdef B38400
458: /* case 38400:
459: /* #endif
460: /* #endif
461: */
462: #endif
463: #endif
464: #endif
465:
466: #ifdef datageneral
467: case 50:
468: case 75:
469: case 134:
470: case 3600:
471: case 7200:
472: case 19200:
473: case 38400:
474: #endif
475: return(x);
476: default:
477: #ifdef AMIGA
478: if (ttsspd(x) > 0)
479: {
480: printf("Warning: non-standard baud rate - %d\n", x);
481: return(x);
482: }
483: #endif
484: return(-1);
485: }
486: }
487:
488: /* S E T O N -- Parse on/off (default on), set parameter to result */
489:
490: seton(prm) int *prm; {
491: int x, y;
492: if ((y = cmkey(onoff,2,"","on")) < 0) return(y);
493: if ((x = cmcfm()) < 0) return(x);
494: *prm = y;
495: return(0);
496: }
497:
498: /* S E T N U M -- Set parameter to result of cmnum() parse. */
499: /*
500: Call with x - number from cnum parse, y - return code from cmnum
501: */
502: setnum(prm,x,y,max) int x, y, *prm, max; {
503: debug(F101,"setnum","",y);
504: if (y < 0) return(y);
505: if (x > max) {
506: printf("\n?Sorry, %d is the maximum\n",max);
507: return(-2);
508: }
509: if ((y = cmcfm()) < 0) return(y);
510: *prm = x;
511: return(0);
512: }
513:
514: /* S E T C C -- Set parameter to an ASCII control character value. */
515:
516: setcc(prm,x,y) int x, y, *prm; {
517: if (y < 0) return(y);
518: if ((x > 037) && (x != 0177)) {
519: printf("\n?Not in ASCII control range - %d\n",x);
520: return(-2);
521: }
522: if ((y = cmcfm()) < 0) return(y);
523: *prm = x;
524: return(0);
525: }
526:
527: /* D O R M T -- Do a remote command */
528:
529: dormt(xx) int xx; {
530: int x;
531: char *s, sbuf[50], *s2;
532:
533: if (xx < 0) return(xx);
534: switch (xx) {
535:
536: case XZCWD: /* CWD */
537: if ((x = cmtxt("Remote directory name","",&s)) < 0) return(x);
538: debug(F111,"XZCWD: ",s,x);
539: *sbuf = NUL;
540: s2 = sbuf;
541: if (*s != NUL) { /* If directory name given, */
542: /* get password on separate line. */
543: if (tlevel > -1) { /* From take file... */
544:
545: if (fgets(sbuf,50,tfile[tlevel]) == NULL)
546: fatal("take file ends prematurely in 'remote cwd'");
547: debug(F110," pswd from take file",s2,0);
548: for (x = strlen(sbuf);
549: x > 0 && (sbuf[x-1] == '\n' || sbuf[x-1] == '\r');
550: x--)
551: sbuf[x-1] = '\0';
552:
553: } else { /* From terminal... */
554:
555: printf(" Password: "); /* get a password */
556: while (((x = getchar()) != NL) && (x != CR)) { /* with no echo */
557: if ((x &= 0177) == '?') {
558: printf("? Password of remote directory\n Password: ");
559: s2 = sbuf;
560: *sbuf = NUL;
561: }
562: else if (x == ESC) /* Mini command line editor... */
563: putchar(BEL);
564: else if (x == BS || x == 0177)
565: s2--;
566: else if (x == 025) { /* Ctrl-U */
567: s2 = sbuf;
568: *sbuf = NUL;
569: }
570: else
571: *s2++ = x;
572: }
573: *s2 = NUL;
574: putchar('\n');
575: }
576: s2 = sbuf;
577: } else s2 = "";
578: debug(F110," password",s2,0);
579: sstate = setgen('C',s,s2,"");
580: return(0);
581:
582: case XZDEL: /* Delete */
583: if ((x = cmtxt("Name of remote file(s) to delete","",&s)) < 0) return(x);
584: return(sstate = rfilop(s,'E'));
585:
586: case XZDIR: /* Directory */
587: if ((x = cmtxt("Remote directory or file specification","",&s)) < 0)
588: return(x);
589: return(sstate = setgen('D',s,"",""));
590:
591: case XZHLP: /* Help */
592: if (x = (cmcfm()) < 0) return(x);
593: sstate = setgen('H',"","","");
594: return(0);
595:
596: case XZHOS: /* Host */
597: if ((x = cmtxt("Command for remote system","",&cmarg)) < 0) return(x);
598: return(sstate = 'c');
599:
600: case XZPRI: /* Print */
601: if ((x = cmtxt("Remote file(s) to print on remote printer","",&s)) < 0)
602: return(x);
603: return(sstate = rfilop(s,'S'));
604:
605: case XZSPA: /* Space */
606: if ((x = cmtxt("Confirm, or remote directory name","",&s)) < 0) return(x);
607: return(sstate = setgen('U',s,"",""));
608:
609: case XZTYP: /* Type */
610: if ((x = cmtxt("Remote file specification","",&s)) < 0) return(x);
611: return(sstate = rfilop(s,'T'));
612:
613: case XZWHO:
614: if ((x = cmtxt("Remote user name, or carriage return","",&s)) < 0)
615: return(x);
616: return(sstate = setgen('W',s,"",""));
617:
618: default:
619: if (x = (cmcfm()) < 0) return(x);
620: printf("not working yet - %s\n",cmdbuf);
621: return(-2);
622: }
623: }
624:
625:
626:
627: /* R F I L O P -- Remote File Operation */
628:
629: rfilop(s,t) char *s, t; {
630: if (*s == NUL) {
631: printf("?File specification required\n");
632: return(-2);
633: }
634: debug(F111,"rfilop",s,t);
635: return(setgen(t,s,"",""));
636: }
637:
638: /* S C R E E N -- Screen display function */
639:
640: /* screen(f,c,n,s)
641: f - argument descriptor
642: c - a character or small integer
643: n - a long integer
644: s - a string.
645: Fill in this routine with the appropriate display update for the system.
646: This version is for a dumb tty.
647: */
648: screen(f,c,n,s) int f; long n; char c; char *s; {
649: static int p = 0; /* Screen position */
650: int len; /* Length of string */
651: char buf[80]; /* Output buffer */
652: len = strlen(s); /* Length of string */
653: if (!displa || quiet) return; /* No update if display flag off */
654:
655: switch (f) {
656:
657: case SCR_FN: /* filename */
658: conoll(""); conol(s); conoc(SP); p = len + 1; return;
659:
660: case SCR_AN: /* as-name */
661: if (p + len > 75) { conoll(""); p = 0; }
662: conol("=> "); conol(s); if ((p += (len + 3)) > 78) { conoll(""); p = 0; }
663: return;
664:
665: case SCR_FS: /* file-size */
666: sprintf(buf,", Size: %ld",n); conoll(buf); p = 0; return;
667:
668: case SCR_XD: /* x-packet data */
669: conoll(""); conoll(s); p = 0; return;
670:
671: case SCR_ST: /* File status */
672: switch (c) {
673: case ST_OK: /* Transferred OK */
674: if ((p += 5) > 78) { conoll(""); p = 0; }
675: conoll(" [OK]"); p += 5; return;
676:
677: case ST_DISC: /* Discarded */
678: if ((p += 12) > 78) { conoll(""); p = 0; }
679: conoll(" [discarded]"); p += 12; return;
680:
681: case ST_INT: /* Interrupted */
682: if ((p += 14) > 78) { conoll(""); p = 0; }
683: conoll(" [interrupted]"); p += 14; return;
684:
685: case ST_SKIP: /* Skipped */
686: conoll("");
687: conol("Skipping "); conoll(s); p = 0;
688: return;
689:
690: default:
691: conoll("*** screen() called with bad status ***"); p = 0; return;
692: }
693:
694: case SCR_PN: /* Packet number */
695: sprintf(buf,"%s: %ld",s,n); conol(buf); p += strlen(buf); return;
696:
697: case SCR_PT: /* Packet type or pseudotype */
698: if (c == 'Y') return; /* Don't bother with ACKs */
699: if (c == 'D') { /* Only show every 4th data packet */
700: if (n % 4) return;
701: c = '.';
702: }
703: #ifndef AMIGA
704: if (p++ > 78) { /* If near right margin, */
705: conoll(""); /* Start new line */
706: p = 0; /* and reset counter. */
707: }
708: #endif
709: conoc(c); /* Display the character. */
710: #ifdef AMIGA
711: if (c == 'G') conoll(""); /* new line after G packets */
712: #endif
713: return;
714:
715: case SCR_TC: /* transaction complete */
716: conoc(BEL); return;
717:
718: case SCR_EM: /* Error message */
719: conoll(""); conoc('?'); conoll(s); p = 0; return; /* +1 */
720:
721: case SCR_WM: /* Warning message */
722: conoll(""); conoll(s); p = 0; return;
723:
724: case SCR_TU: /* Undelimited text */
725: if ((p += len) > 78) { conoll(""); p = len; }
726: conol(s); return;
727:
728: case SCR_TN: /* Text delimited at beginning */
729: conoll(""); conol(s); p = len; return;
730:
731: case SCR_TZ: /* Text delimited at end */
732: if ((p += len) > 78) { conoll(""); p = len; }
733: conoll(s); return;
734:
735: case SCR_QE: /* Quantity equals */
736: sprintf(buf,"%s: %ld",s,n);
737: conoll(buf); p = 0; return;
738:
739: default:
740: conoll("*** screen() called with bad object ***"); p = 0; return;
741: }
742: }
743:
744: /* I N T M S G -- Issue message about terminal interrupts */
745:
746: intmsg(n) long n; {
747: extern char *chstr();
748: char buf[80];
749:
750: if ((!displa) || (quiet)) return;
751: #ifdef UXIII
752: (void) conchk(); /* clear out pending escape-signals in ckxbsd.c */
753: #endif
754: if (n == 1) {
755: #ifdef UXIII
756:
757: #ifndef apollo
758: #ifndef datageneral
759: /* we need to signal before kb input */
760: sprintf(buf,"Type escape (%s) followed by:",chstr(escape));
761: screen(SCR_TN,0,0l,buf);
762: #endif
763: #endif
764: #endif
765: screen(SCR_TN,0,0l,"CTRL-F to cancel file, CTRL-R to resend current packet");
766: screen(SCR_TN,0,0l,"CTRL-B to cancel batch, CTRL-A for status report: ");
767: }
768: else screen(SCR_TU,0,0l," ");
769: }
770:
771: /* C H K I N T -- Check for console interrupts */
772:
773: /*** should rework not to destroy typeahead ***/
774:
775: chkint() {
776: int ch, cn;
777:
778: if ((!local) || (quiet)) return(0); /* Only do this if local & not quiet */
779: #ifdef datageneral
780: cn = (con_reads_mt) ? 1 : conchk(); /* Any input waiting? */
781: #else
782: cn = conchk(); /* Any input waiting? */
783: #endif
784: debug(F101,"conchk","",cn);
785:
786: while (cn > 0) { /* Yes, read it. */
787: cn--;
788: /* give read 5 seconds for interrupt character */
789: #ifdef datageneral
790: /* We must be careful to just print out one result for each character
791: * read. The flag, conint_avl, controls duplication of characters.
792: * Only one character is handled at a time, which is a reasonable
793: * limit. More complicated schemes could handle a buffer.
794: */
795: if (con_reads_mt) {
796: if ((ch = conint_ch) <= 0) return(0); /* I/O error, or no data */
797: else if (conint_avl == 0) return(0); /* Char already read */
798: else conint_avl = 0; /* Flag character as read */
799: }
800: else { if ((ch = coninc(5)) < 0) return(0); }
801: #else
802: if ((ch = coninc(5)) < 0) return(0);
803: #endif
804: switch (ch & 0177) {
805: case 0001: /* CTRL-A */
806: screen(SCR_TN,0,0l,"^A Status report:");
807: screen(SCR_TN,0,0l," file type: ");
808: if (binary) screen(SCR_TZ,0,0l,"binary");
809: else screen(SCR_TZ,0,0l,"text");
810: screen(SCR_QE,0,(long)filcnt," file number");
811: screen(SCR_QE,0,(long)ffc, " characters ");
812: screen(SCR_QE,0,(long)bctu, " block check");
813: screen(SCR_QE,0,(long)rptflg," compression");
814: screen(SCR_QE,0,(long)ebqflg," 8th-bit prefixing");
815: continue;
816: case 0002: /* CTRL-B */
817: screen(SCR_TN,0,0l,"^B - Cancelling Batch ");
818: czseen = 1;
819: continue;
820: case 0006: /* CTRL-F */
821: screen(SCR_TN,0,0l,"^F - Cancelling File ");
822: cxseen = 1;
823: continue;
824: case 0022: /* CTRL-R */
825: screen(SCR_TN,0,0l,"^R - Resending ");
826: resend();
827: return(1);
828: default: /* Anything else, just ignore */
829: screen(SCR_TU,0,0l," [Ignored] ");
830: continue;
831: }
832: }
833: return(0);
834: }
835:
836: /* D E B U G -- Enter a record in the debugging log */
837:
838: /*
839: Call with a format, two strings, and a number:
840: f - Format, a bit string in range 0-7.
841: If bit x is on, then argument number x is printed.
842: s1 - String, argument number 1. If selected, printed as is.
843: s2 - String, argument number 2. If selected, printed in brackets.
844: n - Int, argument 3. If selected, printed preceded by equals sign.
845:
846: f=0 is special: print s1,s2, and interpret n as a char.
847: */
848: #ifdef DEBUG
849: #define DBUFL 1000
850: debug(f,s1,s2,n) int f, n; char *s1, *s2; {
851: static char s[DBUFL];
852: char *sp = s;
853:
854: if (!deblog) return; /* If no debug log, don't */
855: switch (f) {
856: case F000: /* 0, print both strings, */
857: if (strlen(s1) + strlen(s2) + 3 > DBUFL)
858: sprintf(sp,"DEBUG string too long\n");
859: else sprintf(sp,"%s%s%c\n",s1,s2,n); /* interpret n as a char */
860: zsout(ZDFILE,s);
861: break;
862: case F001: /* 1, "=n" */
863: sprintf(sp,"=%d\n",n);
864: zsout(ZDFILE,s);
865: break;
866: case F010: /* 2, "[s2]" */
867: if (strlen(s2) + 4 > DBUFL)
868: sprintf(sp,"DEBUG string too long\n");
869: else sprintf(sp,"[%s]\n",s2);
870: zsout(ZDFILE,"");
871: break;
872: case F011: /* 3, "[s2]=n" */
873: if (strlen(s2) + 15 > DBUFL)
874: sprintf(sp,"DEBUG string too long\n");
875: else sprintf(sp,"[%s]=%d\n",s2,n);
876: zsout(ZDFILE,s);
877: break;
878: case F100: /* 4, "s1" */
879: zsoutl(ZDFILE,s1);
880: break;
881: case F101: /* 5, "s1=n" */
882: if (strlen(s1) + 15 > DBUFL)
883: sprintf(sp,"DEBUG string too long\n");
884: else sprintf(sp,"%s=%d\n",s1,n);
885: zsout(ZDFILE,s);
886: break;
887: case F110: /* 6, "s1[s2]" */
888: if (strlen(s1) + strlen(s2) + 4 > DBUFL)
889: sprintf(sp,"DEBUG string too long\n");
890: else sprintf(sp,"%s[%s]\n",s1,s2);
891: zsout(ZDFILE,s);
892: break;
893: case F111: /* 7, "s1[s2]=n" */
894: if (strlen(s1) + strlen(s2) + 15 > DBUFL)
895: sprintf(sp,"DEBUG string too long\n");
896: else sprintf(sp,"%s[%s]=%d\n",s1,s2,n);
897: zsout(ZDFILE,s);
898: break;
899: default:
900: sprintf(sp,"\n?Invalid format for debug() - %d\n",n);
901: zsout(ZDFILE,s);
902: }
903: }
904: #endif
905:
906: #ifdef TLOG
907: #define TBUFL 300
908: /* T L O G -- Log a record in the transaction file */
909: /*
910: Call with a format and 3 arguments: two strings and a number:
911: f - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
912: s1,s2 - String arguments 1 and 2.
913: n - Int, argument 3.
914: */
915: tlog(f,s1,s2,n) int f; long n; char *s1, *s2; {
916: static char s[TBUFL];
917: char *sp = s; int x;
918:
919: if (!tralog) return; /* If no transaction log, don't */
920: switch (f) {
921: case F000: /* 0 (special) "s1 n s2" */
922: if (strlen(s1) + strlen(s2) + 15 > TBUFL)
923: sprintf(sp,"?T-Log string too long\n");
924: else sprintf(sp,"%s %ld %s\n",s1,n,s2);
925: zsout(ZTFILE,s);
926: break;
927: case F001: /* 1, " n" */
928: sprintf(sp," %ld\n",n);
929: zsout(ZTFILE,s);
930: break;
931: case F010: /* 2, "[s2]" */
932: x = strlen(s2);
933: if (s2[x] == '\n') s2[x] = '\0';
934: if (x + 6 > TBUFL)
935: sprintf(sp,"?T-Log string too long\n");
936: else sprintf(sp,"[%s]\n",s2);
937: zsout(ZTFILE,"");
938: break;
939: case F011: /* 3, "[s2] n" */
940: x = strlen(s2);
941: if (s2[x] == '\n') s2[x] = '\0';
942: if (x + 6 > TBUFL)
943: sprintf(sp,"?T-Log string too long\n");
944: else sprintf(sp,"[%s] %ld\n",s2,n);
945: zsout(ZTFILE,s);
946: break;
947: case F100: /* 4, "s1" */
948: zsoutl(ZTFILE,s1);
949: break;
950: case F101: /* 5, "s1: n" */
951: if (strlen(s1) + 15 > TBUFL)
952: sprintf(sp,"?T-Log string too long\n");
953: else sprintf(sp,"%s: %ld\n",s1,n);
954: zsout(ZTFILE,s);
955: break;
956: case F110: /* 6, "s1 s2" */
957: x = strlen(s2);
958: if (s2[x] == '\n') s2[x] = '\0';
959: if (strlen(s1) + x + 4 > TBUFL)
960: sprintf(sp,"?T-Log string too long\n");
961: else sprintf(sp,"%s %s\n",s1,s2);
962: zsout(ZTFILE,s);
963: break;
964: case F111: /* 7, "s1 s2: n" */
965: x = strlen(s2);
966: if (s2[x] == '\n') s2[x] = '\0';
967: if (strlen(s1) + x + 15 > TBUFL)
968: sprintf(sp,"?T-Log string too long\n");
969: else sprintf(sp,"%s %s: %ld\n",s1,s2,n);
970: zsout(ZTFILE,s);
971: break;
972: default:
973: sprintf(sp,"\n?Invalid format for tlog() - %ld\n",n);
974: zsout(ZTFILE,s);
975: }
976: }
977: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.