1: char *userv = "User Interface 5A(092), 23 Nov 92"; 2: 3: /* C K U U S R -- "User Interface" for Unix Kermit (Part 1) */ 4: 5: /* 6: Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET), 7: Columbia University Center for Computing Activities. 8: First released January 1985. 9: Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New 10: York. Permission is granted to any individual or institution to use this 11: software as long as it is not sold for profit. This copyright notice must be 12: retained. This software may not be included in commercial products without 13: written permission of Columbia University. 14: */ 15: 16: /* 17: NOTE: Because of the massive additions in functionality, and therefore 18: the increase in the number of commands, much code was moved from here to 19: the two new modules, ckuus4.c and ckuus5.c. This module now contains only 20: the top-level command keyword table, the SET command keyword table, and 21: the top-level interactive command parser/dispatcher. ckuus3.c contains the 22: rest of the SET and REMOTE command parsers; ckuus2.c contains the help 23: command parser and help text strings, and ckuus4.c and ckuus5.c contain 24: miscellaneous pieces that logically belong in the ckuusr.c file but had to 25: be moved because of size problems with some C compilers / linkers. 26: Later... as the other modules became too large, a ckuus6.c was created. 27: Still later... ckuus7.c. 28: Also: ckuusy.c contains the UNIX-style command-line interface; 29: ckuusx.c contains routines needed by both the command-line interface and 30: the interactive command parser. 31: */ 32: 33: /* 34: The ckuus*.c modules depend on the existence of C library features like fopen, 35: fgets, feof, (f)printf, argv/argc, etc. Other functions that are likely to 36: vary among Unix implementations -- like setting terminal modes or interrupts 37: -- are invoked via calls to functions that are defined in the system- 38: dependent modules, ck?[ft]io.c. The command line parser processes any 39: arguments found on the command line, as passed to main() via argv/argc. The 40: interactive parser uses the facilities of the cmd package (developed for this 41: program, but usable by any program). Any command parser may be substituted 42: for this one. The only requirements for the Kermit command parser are these: 43: 44: 1. Set parameters via global variables like duplex, speed, ttname, etc. See 45: ckmain.c for the declarations and descriptions of these variables. 46: 47: 2. If a command can be executed without the use of Kermit protocol, then 48: execute the command directly and set the variable sstate to 0. Examples 49: include 'set' commands, local directory listings, the 'connect' command. 50: 51: 3. If a command requires the Kermit protocol, set the following variables: 52: 53: sstate string data 54: 'x' (enter server mode) (none) 55: 'r' (send a 'get' command) cmarg, cmarg2 56: 'v' (enter receive mode) cmarg2 57: 'g' (send a generic command) cmarg 58: 's' (send files) nfils, cmarg & cmarg2 OR cmlist 59: 'c' (send a remote host command) cmarg 60: 61: cmlist is an array of pointers to strings. 62: cmarg, cmarg2 are pointers to strings. 63: nfils is an integer. 64: 65: cmarg can be a filename string (possibly wild), or 66: a pointer to a prefabricated generic command string, or 67: a pointer to a host command string. 68: cmarg2 is the name to send a single file under, or 69: the name under which to store an incoming file; must not be wild. 70: If it's the name for receiving, a null value means to store the 71: file under the name it arrives with. 72: cmlist is a list of nonwild filenames, such as passed via argv. 73: nfils is an integer, interpreted as follows: 74: -1: filespec (possibly wild) in cmarg, must be expanded internally. 75: 0: send from stdin (standard input). 76: >0: number of files to send, from cmlist. 77: 78: The screen() function is used to update the screen during file transfer. 79: The tlog() function writes to a transaction log. 80: The debug() function writes to a debugging log. 81: The intmsg() and chkint() functions provide the user i/o for interrupting 82: file transfers. 83: */ 84: 85: #ifndef NOICP 86: /* Includes */ 87: 88: #include "ckcdeb.h" 89: #include "ckcasc.h" 90: #include "ckcker.h" 91: #include "ckuusr.h" 92: #include "ckcxla.h" 93: #include "ckcnet.h" /* Network symbols */ 94: 95: #ifdef datageneral 96: #include <packets:common.h> 97: #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd) 98: #endif /* datageneral */ 99: 100: /* External Kermit Variables, see ckmain.c for description. */ 101: 102: extern int size, local, sndsrc, xitsta, server, displa, binary, msgflg, 103: escape, duplex, nfils, quiet, tlevel, pflag, zincnt, atcapr, atdiso, verwho; 104: 105: extern long vernum; 106: extern char *versio; 107: extern char *ckxsys, *cmarg, *cmarg2, **cmlist; 108: #ifndef NOHELP 109: extern char *introtxt[]; 110: #endif /* NOHELP */ 111: extern char *PWDCMD, *WHOCMD, *TYPCMD; 112: extern char ttname[]; 113: #ifndef NOFRILLS 114: extern int rmailf; /* MAIL command items */ 115: extern char optbuf[]; 116: #endif /* NOFRILLS */ 117: extern CHAR sstate; 118: 119: #ifdef NETCONN 120: extern int network; /* Have active network connection */ 121: #endif /* NETCONN */ 122: 123: #ifndef NOMSEND /* Multiple SEND */ 124: extern char *msfiles[]; 125: #endif /* NOMSEND */ 126: extern char fspec[]; /* Most recent filespec */ 127: 128: #ifndef NOCSETS 129: extern int nfilc; 130: extern struct keytab fcstab[]; 131: #endif /* NOCSETS */ 132: 133: int rcflag = 0; /* Pointer to home directory string */ 134: int repars, /* Reparse needed */ 135: techo = 0, /* Take echo */ 136: terror = 0; /* Take error action, 1 = quit */ 137: #ifndef NOSCRIPT 138: int secho = 1; 139: #endif /* NOSCRIPT */ 140: 141: #ifndef NOXMIT 142: /* Variables for TRANSMIT command */ 143: 144: int xmitx = 1; /* Whether to echo during TRANSMIT */ 145: int xmitf = 0; /* Character to fill empty lines */ 146: int xmitl = 0; /* 0 = Don't send linefeed too */ 147: int xmitp = LF; /* Host line prompt */ 148: int xmits = 0; /* Use shift-in/shift-out, 0 = no */ 149: int xmitw = 0; /* Milliseconds to pause during TRANSMIT */ 150: #endif /* NOXMIT */ 151: 152: /* Declarations from ck?fio.c module */ 153: 154: extern char *SPACMD, *SPACM2; /* SPACE commands */ 155: 156: /* Command-oriented items */ 157: 158: #ifdef DCMDBUF 159: extern char *cmdbuf; /* Command buffers */ 160: extern char *atmbuf; 161: extern char *line; /* Character buffer for anything */ 162: extern int *ifcmd; 163: #else 164: extern char cmdbuf[]; /* Command buffers */ 165: extern char atmbuf[]; 166: extern char line[]; /* Character buffer for anything */ 167: extern int ifcmd[]; 168: #endif /* DCMDBUF */ 169: 170: char *lp; /* Pointer to line buffer */ 171: 172: #ifndef NOSPL 173: extern char inpbuf[]; /* Buffer for INPUT and REINPUT */ 174: char *inpbp = inpbuf; /* And pointer to same */ 175: extern char lblbuf[]; /* Buffer for labels */ 176: #endif /* NOSPL */ 177: 178: char psave[80] = { NUL }; /* For saving & restoring prompt */ 179: 180: extern char tmpbuf[]; /* Temporary buffer */ 181: 182: extern int success; /* Command success/failure flag */ 183: 184: #ifndef NOSPL 185: int /* SET INPUT parameters. */ 186: indef = 5, /* 5 seconds default timeout */ 187: intime = 0, /* 0 = proceed */ 188: incase = 0, /* 0 = ignore */ 189: inecho = 1, /* 1 = echo on */ 190: insilence = 0; /* 0 = no silence constraint */ 191: 192: int maclvl = -1; /* Macro nesting level */ 193: int mecho = 0; /* Macro echo, 0 = don't */ 194: int merror = 0; /* Macro error action */ 195: char varnam[6]; /* For variable names */ 196: extern int macargc[]; /* ARGC from macro invocation */ 197: 198: extern char *m_arg[MACLEVEL][NARGS]; /* Stack of macro arguments */ 199: 200: extern char **a_ptr[]; /* Array pointers */ 201: extern int a_dim[]; /* Array dimensions */ 202: 203: #ifdef DCMDBUF 204: extern struct cmdptr *cmdstk; /* The command stack itself */ 205: #else 206: extern struct cmdptr cmdstk[]; /* The command stack itself */ 207: #endif /* DCMDBUF */ 208: extern int cmdlvl; /* Current position in command stack */ 209: #endif /* NOSPL */ 210: 211: static int x, y, z = 0; /* Local workers */ 212: static char *s; 213: 214: #define xsystem(s) zsyscmd(s) 215: 216: /* Top-Level Interactive Command Keyword Table */ 217: 218: struct keytab cmdtab[] = { 219: #ifndef NOPUSH 220: "!", XXSHE, CM_INV, /* shell escape */ 221: #endif /* NOPUSH */ 222: "#", XXCOM, CM_INV, /* comment */ 223: #ifndef NOSPL 224: ":", XXLBL, CM_INV, /* label */ 225: #endif /* NOSPL */ 226: #ifndef NOPUSH 227: "@", XXSHE, CM_INV, /* DCL escape */ 228: #endif /* NOPUSH */ 229: #ifndef NOSPL 230: "asg", XXASS, CM_INV, /* invisible synonym for assign */ 231: "ask", XXASK, 0, /* ask */ 232: "askq", XXASKQ,0, /* ask quietly */ 233: "assign", XXASS, 0, /* assign */ 234: #endif /* NOSPL */ 235: #ifndef NOFRILLS 236: "bug", XXBUG, 0, /* bug report instructions */ 237: #endif /* NOFRILLS */ 238: "bye", XXBYE, 0, /* bye to remote server */ 239: "c", XXCON, CM_INV|CM_ABR, /* invisible synonym for connect */ 240: #ifndef NOFRILLS 241: "cat", XXTYP, CM_INV, /* display a local file */ 242: #endif /* NOFRILLS */ 243: "cd", XXCWD, 0, /* change directory */ 244: "check", XXCHK, 0, /* check for a feature */ 245: #ifndef NOFRILLS 246: "clear", XXCLE, 0, /* clear input buffer */ 247: #endif /* NOFRILLS */ 248: "close", XXCLO, 0, /* close a log file */ 249: #ifdef NOFRILLS 250: "comment", XXCOM, CM_INV, /* comment */ 251: #else 252: "comment", XXCOM, 0, /* comment */ 253: #endif /* NOFRILLS */ 254: "connect", XXCON, 0, /* connect to remote system */ 255: "cwd", XXCWD, CM_INV, /* invisisble synonym for cd */ 256: #ifndef NOSPL 257: "dcl", XXDCL, CM_INV, /* declare an array */ 258: "declare", XXDCL, 0, /* declare an array */ 259: "decrement", XXDEC, 0, /* decrement a numeric variable */ 260: "define", XXDEF, 0, /* define a macro */ 261: #endif /* NOSPL */ 262: #ifndef NOFRILLS 263: "delete", XXDEL, 0, /* delete a file */ 264: #endif /* NOFRILLS */ 265: #ifndef NODIAL 266: "dial", XXDIAL,0, /* dial a phone number */ 267: #endif /* NODIAL */ 268: #ifndef MAC 269: "directory", XXDIR, 0, /* directory of files */ 270: #endif /* MAC */ 271: #ifndef NOFRILLS 272: "disable", XXDIS, 0, /* disable server function */ 273: #endif /* NOFRILLS */ 274: #ifndef NOSPL 275: "do", XXDO, 0, /* execute a macro */ 276: #endif /* NOSPL */ 277: #ifndef NOFRILLS 278: "e-packet", XXERR, CM_INV, /* Send an Error packet */ 279: #endif /* NOFRILLS */ 280: "echo", XXECH, 0, /* echo argument */ 281: #ifndef NOSPL 282: "else", XXELS, CM_INV, /* ELSE part of IF statement */ 283: #endif /* NOSPL */ 284: #ifndef NOFRILLS 285: "enable", XXENA, 0, /* ENABLE a server function */ 286: #endif /* NOFRILLS */ 287: #ifndef NOSPL 288: "end", XXEND, 0, /* END command file or macro */ 289: #endif /* NOSPL */ 290: "ex", XXEXI, CM_INV|CM_ABR, /* Let "ex" still be EXIT */ 291: "exit", XXEXI, 0, /* exit the program */ 292: "extproc", XXCOM, CM_INV, /* dummy command */ 293: "finish", XXFIN, 0, /* FINISH */ 294: #ifndef NOSPL 295: "for", XXFOR, 0, /* FOR loop */ 296: #endif /* NOSPL */ 297: #ifndef NOFRILLS 298: #ifndef MAC 299: "fot", XXDIR, CM_INV, /* "fot" = "dir" (for Chris) */ 300: #endif /* MAC */ 301: #endif /* NOFRILLS */ 302: "g", XXGET, CM_INV|CM_ABR, /* Invisible abbreviation for GET */ 303: #ifndef NOSPL 304: "ge", XXGET, CM_INV|CM_ABR, /* Ditto */ 305: #endif /* NOSPL */ 306: "get", XXGET, 0, /* GET */ 307: #ifndef NOSPL 308: #ifndef NOFRILLS 309: "getok", XXGOK, 0, /* GETOK (ask for Yes/No) */ 310: #endif /* NOFRILLS */ 311: #endif /* NOSPL */ 312: #ifndef NOSPL 313: "goto", XXGOTO,0, /* goto label in take file or macro */ 314: #endif /* NOSPL */ 315: "hangup", XXHAN, 0, /* hangup dialed phone connection */ 316: "help", XXHLP, 0, /* display help text */ 317: #ifndef NOSPL 318: "i", XXINP, CM_INV|CM_ABR, /* invisible synonym for INPUT */ 319: "if", XXIF, 0, /* if (condition) command */ 320: "in", XXINP, CM_INV|CM_ABR, /* invisible synonym for INPUT */ 321: "increment", XXINC, 0, /* increment a numeric variable */ 322: "input", XXINP, 0, /* input string from comm line */ 323: #endif /* NOSPL */ 324: #ifndef NOHELP 325: "introduction", XXINT, 0, /* Print introductory text */ 326: #endif /* NOHELP */ 327: #ifndef NOFRILLS 328: "l", XXLOG, CM_INV|CM_ABR,/* invisible synonym for log */ 329: #endif /* NOFRILLS */ 330: "log", XXLOG, 0, /* open a log file */ 331: #ifndef NOFRILLS 332: #ifndef MAC 333: "ls", XXDIR, CM_INV, /* invisible synonym for directory */ 334: #endif /* MAC */ 335: "mail", XXMAI, 0, /* mail file to user */ 336: "man", XXHLP, CM_INV, /* Synonym for help */ 337: #endif /* NOFRILLS */ 338: #ifndef NOMSEND 339: "mget", XXGET, CM_INV, /* MGET = GET */ 340: #endif /* NOMSEND */ 341: #ifndef NOSPL 342: "mpause", XXMSL, CM_INV, /* Millisecond sleep */ 343: #endif /* NOSPL */ 344: #ifndef NOMSEND 345: "ms", XXMSE, CM_INV|CM_ABR, 346: "msend", XXMSE, 0, /* Multiple SEND */ 347: #endif /* NOMSEND */ 348: #ifndef NOSPL 349: "msleep", XXMSL, 0, /* Millisecond sleep */ 350: #endif /* NOSPL */ 351: #ifndef NOMSEND 352: "mput", XXMSE, CM_INV, /* MPUT = MSEND */ 353: #endif /* NOMSEND */ 354: #ifndef NOFRILLS 355: "mv", XXREN, CM_INV, /* rename a local file */ 356: #endif /* NOFRILLS */ 357: #ifndef NOSPL 358: "o", XXOUT, CM_INV|CM_ABR,/* invisible synonym for OUTPUT */ 359: "open", XXOPE, 0, /* open file for reading or writing */ 360: "output", XXOUT, 0, /* output string to comm line */ 361: #endif /* NOSPL */ 362: #ifdef SUNX25 363: "pad", XXPAD, 0, /* PAD commands */ 364: #endif /* SUNX25 */ 365: #ifndef NOSPL 366: "pause", XXPAU, 0, /* sleep for specified interval */ 367: #ifdef TCPSOCKET 368: "ping", XXPNG, 0, /* PING (for TCP/IP) */ 369: #endif /* TCPSOCKET */ 370: "pop", XXEND, CM_INV, /* allow POP as synonym for END */ 371: #endif /* NOSPL */ 372: #ifndef NOFRILLS 373: "print", XXPRI, 0, /* PRINT */ 374: #ifndef NOPUSH 375: "pu", XXSHE, CM_INV, /* PU = PUSH */ 376: "push", XXSHE, 0, /* PUSH command (like RUN, !) */ 377: #endif /* NOPUSH */ 378: "put", XXSEN, CM_INV, /* PUT = SEND */ 379: #ifndef MAC 380: "pwd", XXPWD, 0, /* print working directory */ 381: #endif /* MAC */ 382: #endif /* NOFRILLS */ 383: "quit", XXQUI, 0, /* quit from program = exit */ 384: "r", XXREC, CM_INV, /* invisible synonym for receive */ 385: #ifndef NOSPL 386: "read", XXREA, 0, /* read */ 387: #endif /* NOSPL */ 388: "receive", XXREC, 0, /* receive files */ 389: #ifndef NODIAL 390: "redial", XXRED, 0, /* redial */ 391: #endif /* NODIAL */ 392: #ifndef NOSPL 393: "reinput", XXREI, 0, /* reinput */ 394: #endif /* NOSPL */ 395: "remote", XXREM, 0, /* send generic command to server */ 396: #ifndef NOFRILLS 397: "rename", XXREN, 0, /* rename a local file */ 398: "replay", XXTYP, CM_INV, /* replay (for now, just type) */ 399: #endif /* NOFRILLS */ 400: #ifndef NOSPL 401: "return", XXRET, 0, /* return from function */ 402: #endif /* NOSPL */ 403: #ifndef NOFRILLS 404: "rm", XXDEL, CM_INV, /* invisible synonym for delete */ 405: #endif /* NOFRILLS */ 406: #ifndef NOPUSH 407: "run", XXSHE, 0, /* run a program or command */ 408: #endif /* NOPUSH */ 409: "s", XXSEN, CM_INV|CM_ABR, /* invisible synonym for send */ 410: #ifndef NOSCRIPT 411: "script", XXLOGI,0, /* execute a uucp-style script */ 412: #endif /* NOSCRIPT */ 413: "send", XXSEN, 0, /* send files */ 414: #ifndef NOSERVER 415: "server", XXSER, 0, /* be a server */ 416: #endif /* NOSERVER */ 417: "set", XXSET, 0, /* set parameters */ 418: #ifndef NOSHOW 419: "show", XXSHO, 0, /* show parameters */ 420: #endif /* NOSHOW */ 421: #ifndef NOSPL 422: #ifndef NOFRILLS 423: "sleep", XXPAU, CM_INV, /* sleep for specified interval */ 424: #endif /* NOFRILLS */ 425: #endif /* NOSPL */ 426: #ifndef MAC 427: #ifndef NOFRILLS 428: "sp", XXSPA, CM_INV|CM_ABR, 429: "spa", XXSPA, CM_INV|CM_ABR, 430: #endif /* NOFRILLS */ 431: "space", XXSPA, 0, /* show available disk space */ 432: #endif /* MAC */ 433: #ifndef NOFRILLS 434: #ifndef NOPUSH 435: "spawn", XXSHE, CM_INV, /* synonym for PUSH, RUN */ 436: #endif /* NOPUSH */ 437: #endif /* NOFRILLS */ 438: "statistics", XXSTA, 0, /* display file transfer stats */ 439: #ifndef NOSPL 440: "stop", XXSTO, 0, /* stop all take files */ 441: #endif /* NOSPL */ 442: #ifndef NOJC 443: "suspend", XXSUS, 0, /* Suspend */ 444: #endif /* NOJC */ 445: "take", XXTAK, 0, /* take commands from file */ 446: #ifndef NOFRILLS 447: #ifdef NETCONN 448: "telnet", XXTEL, 0, /* telnet */ 449: #endif /* NETCONN */ 450: "test", XXTES, CM_INV, /* (for testing) */ 451: #endif /* NOFRILLS */ 452: #ifndef NOCSETS 453: "translate", XXXLA, 0, /* translate local file char sets */ 454: #endif 455: #ifndef NOXMIT 456: "transmit", XXTRA, 0, /* raw upload file */ 457: #endif /* NOXMIT */ 458: #ifndef NOFRILLS 459: "type", XXTYP, 0, /* display a local file */ 460: #endif /* NOFRILLS */ 461: "version", XXVER, 0 /* version number display */ 462: #ifndef NOSPL 463: , "wait", XXWAI, 0 /* wait (like pause) */ 464: , "while", XXWHI, 0 /* while */ 465: #endif /* NOSPL */ 466: #ifndef MAC 467: #ifndef NOFRILLS 468: , "who", XXWHO, 0 /* who */ 469: #endif /* NOFRILLS */ 470: #endif /* MAC */ 471: #ifndef NOSPL 472: , "write", XXWRI, 0 /* write */ 473: , "xif", XXIFX, 0 /* Extended IF */ 474: #endif /* NOSPL */ 475: #ifndef NOCSETS 476: , "xlate", XXXLA, CM_INV /* translate local file char sets */ 477: #endif 478: #ifndef NOXMIT 479: , "xmit", XXTRA, CM_INV /* raw upload file */ 480: #endif /* NOXMIT */ 481: , "z", XXSUS, CM_INV /* Suspend */ 482: #ifndef NOSPL 483: , "_assign", XXASX, CM_INV /* used internally by FOR, etc */ 484: , "_define", XXDFX, CM_INV /* used internally by FOR, etc */ 485: , "_getargs", XXGTA, CM_INV /* used internally by FOR, etc */ 486: , "_putargs", XXPTA, CM_INV /* used internally by FOR, etc */ 487: #endif /* NOSPL */ 488: }; 489: int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)); 490: 491: char toktab[] = { 492: #ifndef NOPUSH 493: '!', /* Shell escape */ 494: #endif /* NOPUSH */ 495: '#', /* Comment */ 496: ';', /* Comment */ 497: #ifndef NOSPL 498: ':', /* Label */ 499: #endif /* NOSPL */ 500: #ifndef NOPUSH 501: '@', /* DCL escape */ 502: #endif /* NOPUSH */ 503: '\0' /* End of this string */ 504: }; 505: 506: #ifndef NOSPL 507: #ifndef NOFRILLS 508: struct keytab yesno[] = { 509: "no", 0, 0, 510: "ok", 1, 0, 511: "yes", 1, 0 512: }; 513: int nyesno = (sizeof(yesno) / sizeof(struct keytab)); 514: #endif /* NOFRILLS */ 515: #endif /* NOSPL */ 516: 517: /* Parameter keyword table */ 518: 519: struct keytab prmtab[] = { 520: "attributes", XYATTR, 0, 521: "b", XYBACK, CM_INV|CM_ABR, 522: "ba", XYBACK, CM_INV|CM_ABR, 523: "background", XYBACK, 0, 524: "baud", XYSPEE, CM_INV, 525: "block-check", XYCHKT, 0, 526: #ifdef DYNAMIC 527: "buffers", XYBUF, 0, 528: #endif /* DYNAMIC */ 529: #ifndef MAC 530: "carrier", XYCARR, 0, 531: #endif /* MAC */ 532: #ifndef NOSPL 533: "case", XYCASE, 0, 534: #endif /* NOSPL */ 535: "command", XYCMD, 0, 536: #ifndef NOSPL 537: "count", XYCOUN, 0, 538: #endif /* NOSPL */ 539: "d", XYDELA, CM_INV|CM_ABR, 540: "de", XYDELA, CM_INV|CM_ABR, 541: "debug", XYDEBU, CM_INV, 542: #ifdef VMS 543: "default", XYDFLT, 0, 544: #else 545: #ifndef MAC 546: "default", XYDFLT, CM_INV, 547: #endif /* MAC */ 548: #endif /* VMS */ 549: "delay", XYDELA, 0, 550: #ifndef NODIAL 551: "dial", XYDIAL, 0, 552: #endif /* NODIAL */ 553: "duplex", XYDUPL, 0, 554: "escape-character", XYESC, 0, 555: "file", XYFILE, 0, 556: "flow-control", XYFLOW, 0, 557: "handshake", XYHAND, 0, 558: #ifdef NETCONN 559: "host", XYHOST, 0, 560: #endif /* NETCONN */ 561: "incomplete", XYIFD, CM_INV, 562: #ifndef NOSPL 563: "i", XYINPU, CM_INV|CM_ABR, 564: "in", XYINPU, CM_INV|CM_ABR, 565: "input", XYINPU, 0, 566: #ifndef MAC 567: #ifndef NOSETKEY 568: "key", XYKEY, 0, 569: #endif /* NOSETKEY */ 570: #endif /* MAC */ 571: #endif /* NOSPL */ 572: "l", XYLINE, CM_INV|CM_ABR, 573: #ifndef NOCSETS 574: "language", XYLANG, 0, 575: #endif /* NOCSETS */ 576: "line", XYLINE, 0, 577: "local-echo", XYLCLE, CM_INV, 578: #ifndef NOSPL 579: "macro", XYMACR, 0, 580: #endif /* NOSPL */ 581: #ifdef COMMENT 582: #ifdef VMS 583: "messages", XYMSGS, 0, 584: #endif /* VMS */ 585: #endif /* COMMENT */ 586: #ifndef NODIAL 587: "modem-dialer", XYMODM, 0, 588: #endif 589: #ifdef NETCONN 590: "network", XYNET, 0, 591: #endif /* NETCONN */ 592: #ifdef SUNX25 593: "pad", XYPAD, 0, 594: #endif /* SUNX25 */ 595: "parity", XYPARI, 0, 596: "port", XYLINE, CM_INV, 597: #ifndef NOFRILLS 598: "prompt", XYPROM, 0, 599: #endif /* NOFRILLS */ 600: "quiet", XYQUIE, 0, 601: "receive", XYRECV, 0, 602: "retry-limit", XYRETR, 0, 603: #ifndef NOSCRIPT 604: "script", XYSCRI, 0, 605: #endif /* NOSCRIPT */ 606: "send", XYSEND, 0, 607: #ifndef NOSERVER 608: "server", XYSERV, 0, 609: #endif /* NOSERVER */ 610: #ifdef UNIX 611: "session-log", XYSESS, 0, 612: #endif /* UNIX */ 613: "speed", XYSPEE, 0, 614: #ifndef NOJC 615: "suspend", XYSUSP, 0, 616: #endif /* NOJC */ 617: "take", XYTAKE, 0, 618: #ifdef TNCODE 619: "telnet", XYTEL, 0, 620: #endif /* TNCODE */ 621: "terminal", XYTERM, 0, 622: "transfer", XYXFER, 0, 623: #ifndef NOXMIT 624: "transmit", XYXMIT, 0, 625: #endif /* NOXMIT */ 626: #ifndef NOCSETS 627: "unknown-char-set", XYUNCS, 0, 628: #endif /* NOCSETS */ 629: "window-size", XYWIND, 0 630: #ifdef UNIX 631: , "wildcard-expansion", XYWILD, 0 632: #endif /* UNIX */ 633: #ifdef SUNX25 634: , "x.25", XYX25, 0, 635: "x25", XYX25, CM_INV 636: #endif /* SUNX25 */ 637: #ifndef NOCSETS 638: , "xfer", XYXFER, CM_INV 639: #endif /* NOCSETS */ 640: #ifndef NOXMIT 641: , "xmit", XYXMIT, CM_INV 642: #endif /* NOXMIT */ 643: }; 644: int nprm = (sizeof(prmtab) / sizeof(struct keytab)); /* How many parameters */ 645: 646: /* Table of networks */ 647: #ifdef NETCONN 648: struct keytab netcmd[] = { 649: #ifdef DECNET 650: "decnet", NET_DEC, 0, 651: #endif /* DECNET */ 652: #ifdef NPIPE 653: "named-pipe", NET_PIPE, 0, 654: #endif /* NPIPE */ 655: #ifdef TCPSOCKET 656: "tcp/ip", NET_TCPB, 0 657: #endif /* TCPSOCKET */ 658: #ifdef SUNX25 659: , "x", NET_SX25, CM_INV|CM_ABR, 660: "x.25", NET_SX25, 0, 661: "x25", NET_SX25, CM_INV 662: #endif /* SUNX25 */ 663: }; 664: int nnets = (sizeof(netcmd) / sizeof(struct keytab)); /* How many networks */ 665: #endif /* NETCONN */ 666: 667: /* Remote Command Table */ 668: 669: struct keytab remcmd[] = { 670: "cd", XZCWD, 0, 671: "cwd", XZCWD, CM_INV, 672: "delete", XZDEL, 0, 673: "directory", XZDIR, 0, 674: "help", XZHLP, 0, 675: #ifndef NOPUSH 676: "host", XZHOS, 0, 677: #endif /* NOPUSH */ 678: #ifndef NOFRILLS 679: "kermit", XZKER, 0, 680: "login", XZLGI, 0, 681: "logout", XZLGO, 0, 682: "print", XZPRI, 0, 683: #endif /* NOFRILLS */ 684: "set", XZSET, 0, 685: "space", XZSPA, 0 686: #ifndef NOFRILLS 687: , "type", XZTYP, 0, 688: "who", XZWHO, 0 689: #endif /* NOFRILLS */ 690: }; 691: int nrmt = (sizeof(remcmd) / sizeof(struct keytab)); 692: 693: struct keytab logtab[] = { 694: #ifdef DEBUG 695: "debugging", LOGD, 0, 696: #endif /* DEBUG */ 697: "packets", LOGP, 0, 698: "session", LOGS, 0 699: #ifdef TLOG 700: , "transactions", LOGT, 0 701: #endif /* TLOG */ 702: }; 703: int nlog = (sizeof(logtab) / sizeof(struct keytab)); 704: 705: struct keytab writab[] = { 706: #ifndef NOSPL 707: "append-file", LOGW, CM_INV, 708: #endif /* NOSPL */ 709: "debug-log", LOGD, 0, 710: "error", LOGE, 0, 711: #ifndef NOSPL 712: "file", LOGW, 0, 713: #endif /* NOSPL */ 714: "packet-log", LOGP, 0, 715: "screen", LOGX, 0, 716: "session-log", LOGS, 0, 717: "sys$output", LOGX, CM_INV, 718: "transaction-log", LOGT, 0 719: }; 720: int nwri = (sizeof(writab) / sizeof(struct keytab)); 721: 722: #define CLR_DEV 1 723: #define CLR_INP 2 724: 725: static struct keytab clrtab[] = { /* Keywords for CLEAR command */ 726: #ifndef NOSPL 727: "both", CLR_DEV|CLR_INP, 0, 728: #endif /* NOSPL */ 729: "device-buffer", CLR_DEV, 0, 730: #ifndef NOSPL 731: "input-buffer", CLR_INP, 0 732: #endif /* NOSPL */ 733: }; 734: int nclear = (sizeof(clrtab) / sizeof(struct keytab)); 735: 736: struct keytab clstab[] = { /* Keywords for CLOSE command */ 737: #ifndef NOSPL 738: "append-file", LOGW, CM_INV, 739: #endif /* NOSPL */ 740: #ifdef DEBUG 741: "debug-log", LOGD, 0, 742: #endif /* DEBUG */ 743: "packet-log", LOGP, 0, 744: #ifndef NOSPL 745: "read-file", LOGR, 0, 746: #endif /* NOSPL */ 747: "session-log", LOGS, 0 748: #ifdef TLOG 749: , "transaction-log", LOGT, 0 750: #endif /* TLOG */ 751: #ifndef NOSPL 752: , "write-file", LOGW, 0 753: #endif /* NOSPL */ 754: }; 755: int ncls = (sizeof(clstab) / sizeof(struct keytab)); 756: 757: /* SHOW command arguments */ 758: 759: struct keytab shotab[] = { 760: #ifndef NOSPL 761: "arguments", SHARG, 0, 762: "arrays", SHARR, 0, 763: #endif /* NOSPL */ 764: "attributes", SHATT, 0, 765: "character-sets", SHCSE, 0, 766: "communications", SHCOM, 0, 767: #ifndef NOSPL 768: "count", SHCOU, 0, 769: #endif /* NOSPL */ 770: #ifdef VMS 771: "default", SHDFLT, 0, 772: #else 773: "default", SHDFLT, CM_INV, 774: #endif /* VMS */ 775: #ifndef NODIAL 776: "dial", SHDIA, 0, 777: #endif /* NODIAL */ 778: "escape", SHESC, 0, 779: "features", SHFEA, 0, 780: "file", SHFIL, 0, 781: #ifndef NOSPL 782: "functions", SHFUN, 0, 783: "globals", SHVAR, 0, 784: #endif /* NOSPL */ 785: #ifndef NOSETKEY 786: "key", SHKEY, 0, 787: #endif /* NOSETKEY */ 788: #ifdef VMS 789: "labeled-file-info", SHLBL, 0, 790: #endif /* VMS */ 791: #ifndef NOCSETS 792: "languages", SHLNG, 0, 793: #endif /* NOCSETS */ 794: #ifndef NOSPL 795: "macros", SHMAC, 0, 796: #endif /* NOSPL */ 797: "modem-signals", SHMOD, 0, 798: "network", SHNET, 0, 799: #ifdef SUNX25 800: "pad", SHPAD, 0, 801: #endif /* SUNX25 */ 802: "parameters", SHPAR, CM_INV, 803: "protocol", SHPRO, 0, 804: #ifndef NOSPL 805: "scripts", SHSCR, 0, 806: #endif /* NOSPL */ 807: #ifndef NOSERVER 808: "server", SHSER, 0, 809: #endif /* NOSERVER */ 810: "status", SHSTA, 0, 811: #ifdef MAC 812: "stack", SHSTK, 0, /* debugging */ 813: #endif /* MAC */ 814: "terminal", SHTER, 0 815: #ifndef NOXMIT 816: , "transmit", SHXMI, 0 817: #endif /* NOXMIT */ 818: #ifndef NOSPL 819: , "variables", SHBUI, 0 820: #endif /* NOSPL */ 821: #ifndef NOFRILLS 822: , "versions", SHVER, 0 823: #endif /* NOFRILLS */ 824: #ifndef NOXMIT 825: , "xmit", SHXMI, CM_INV 826: #endif /* NOXMIT */ 827: }; 828: int nsho = (sizeof(shotab) / sizeof(struct keytab)); 829: 830: #ifdef SUNX25 831: struct keytab padtab[] = { /* PAD commands */ 832: "clear", XYPADL, 0, 833: "interrupt", XYPADI, 0, 834: "reset", XYPADR, 0, 835: "status", XYPADS, 0 836: }; 837: int npadc = (sizeof(padtab) / sizeof(struct keytab)); 838: #endif /* SUNX25 */ 839: 840: struct keytab enatab[] = { /* ENABLE commands */ 841: "all", EN_ALL, 0, 842: #ifndef datageneral 843: "bye", EN_BYE, 0, 844: #endif /* datageneral */ 845: "cd", EN_CWD, 0, 846: "cwd", EN_CWD, CM_INV, 847: "delete", EN_DEL, 0, 848: "directory", EN_DIR, 0, 849: "finish", EN_FIN, 0, 850: "get", EN_GET, 0, 851: "host", EN_HOS, 0, 852: "send", EN_SEN, 0, 853: "set", EN_SET, 0, 854: "space", EN_SPA, 0, 855: "type", EN_TYP, 0, 856: "who", EN_WHO, 0 857: }; 858: int nena = (sizeof(enatab) / sizeof(struct keytab)); 859: 860: #ifndef NOSPL 861: #ifdef COMMENT 862: struct mtab mactab[MAC_MAX] = { /* Preinitialized macro table */ 863: NULL, NULL, 0 864: }; 865: #else 866: struct mtab *mactab; /* Dynamically allocated macro table */ 867: #endif /* COMMENT */ 868: int nmac = 0; 869: 870: struct keytab mackey[MAC_MAX]; /* Macro names as command keywords */ 871: #endif /* NOSPL */ 872: 873: /* Forward declarations of functions */ 874: 875: _PROTOTYP (int doask, ( int ) ); 876: _PROTOTYP (int dodef, ( int ) ); 877: _PROTOTYP (int dodel, ( void ) ); 878: _PROTOTYP (int dodial, ( int ) ); 879: _PROTOTYP (int dodir, ( void ) ); 880: _PROTOTYP (int doelse, ( void ) ); 881: _PROTOTYP (int dofor, ( void ) ); 882: _PROTOTYP (int dogta, ( int ) ); 883: _PROTOTYP (int doincr, ( int ) ); 884: _PROTOTYP (int dopaus, ( int ) ); 885: _PROTOTYP (int doping, ( void ) ); 886: _PROTOTYP (int dorenam, ( void ) ); 887: 888: #ifdef TCPSOCKET 889: int 890: doping() { 891: char *p; 892: int x; 893: 894: if (network) /* If we have a current connection */ 895: strcpy(line,ttname); /* get the host name */ 896: else *line = '\0'; /* as default host to be pinged. */ 897: for (p = line; *p; p++) /* Remove ":service" from end. */ 898: if (*p == ':') { *p = '\0'; break; } 899: if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0) 900: return(x); 901: /* Construct PING command */ 902: #ifdef VMS 903: #ifdef MULTINET /* TGV MultiNet */ 904: sprintf(line,"multinet ping %s /num=1",s); 905: #else 906: sprintf(line,"ping %s 56 1",s); /* Other VMS TCP/IP's */ 907: #endif /* MULTINET */ 908: #else /* Not VMS */ 909: sprintf(line,"ping %s",s); 910: #endif /* VMS */ 911: conres(); /* Make console normal */ 912: #ifdef DEC_TCPIP 913: printf("\n"); /* Prevent prompt-stomping */ 914: #endif /* DEC_TCPIP */ 915: x = zshcmd(line); 916: concb((char)escape); 917: return(success = 1); /* We don't know the status */ 918: } 919: #endif /* TCPSOCKET */ 920: 921: /* D O C M D -- Do a command */ 922: 923: /* 924: Returns: 925: -2: user typed an illegal command 926: -1: reparse needed 927: 0: parse was successful (even tho command may have failed). 928: */ 929: int 930: docmd(cx) int cx; { 931: 932: debug(F101,"docmd entry, cx","",cx); 933: 934: /* 935: Massive switch() broken up into many smaller ones, for the benefit of 936: compilers that run out of space when trying to handle large switch 937: statements. 938: */ 939: switch (cx) { 940: case -4: /* EOF */ 941: #ifdef OSK 942: if (msgflg) printf("\n"); 943: #else 944: if (msgflg) printf("\r\n"); 945: #endif /* OSK */ 946: doexit(GOOD_EXIT,xitsta); 947: case -3: /* Null command */ 948: return(0); 949: case -9: /* Like -2, but errmsg already done */ 950: case -1: /* Reparse needed */ 951: return(cx); 952: case -6: /* Special */ 953: case -2: /* Error, maybe */ 954: #ifndef NOSPL 955: /* 956: Maybe they typed a macro name. Let's look it up and see. 957: */ 958: if (cx == -6) /* If they typed CR */ 959: strcat(cmdbuf,"\015"); /* add it back to command buffer. */ 960: if (ifcmd[cmdlvl] == 2) /* Watch out for IF commands. */ 961: ifcmd[cmdlvl]--; 962: repars = 1; /* Force reparse */ 963: cmres(); 964: cx = XXDO; /* Try DO command */ 965: #else 966: return(cx); 967: #endif /* NOSPL */ 968: default: 969: break; 970: } 971: 972: #ifndef NOSPL 973: /* Copy macro args from/to two levels up, used internally by _floop et al. */ 974: if (cx == XXGTA || cx == XXPTA) { /* _GETARGS, _PUTARGS */ 975: int x; 976: debug(F101,"docmd XXGTA","",XXGTA); 977: debug(F101,"docmd cx","",cx); 978: debug(F101,"docmd XXGTA maclvl","",maclvl); 979: x = dogta(cx); 980: debug(F101,"docmd dogta returns","",x); 981: debug(F101,"docmd dogta maclvl","",maclvl); 982: return(x); 983: } 984: #endif /* NOSPL */ 985: 986: #ifndef NOSPL 987: /* ASK, ASKQ, READ */ 988: if (cx == XXASK || cx == XXASKQ || cx == XXREA) { 989: return(doask(cx)); 990: } 991: #endif /* NOSPL */ 992: 993: #ifndef NOFRILLS 994: if (cx == XXBUG) { /* BUG */ 995: if ((x = cmcfm()) < 0) return(x); 996: return(dobug()); 997: } 998: #endif /* NOFRILLS */ 999: 1000: if (cx == XXBYE) { /* BYE */ 1001: if ((x = cmcfm()) < 0) return(x); 1002: sstate = setgen('L',"","",""); 1003: if (local) ttflui(); /* If local, flush tty input buffer */ 1004: return(0); 1005: } 1006: 1007: #ifndef NOFRILLS 1008: if (cx == XXCLE) { /* CLEAR */ 1009: if ((x = cmkey(clrtab,nclear,"buffer(s) to clear", 1010: #ifdef NOSPL 1011: "device-buffer" 1012: #else 1013: "both" 1014: #endif /* NOSPL */ 1015: ,xxstring)) < 0) return(x); 1016: if ((y = cmcfm()) < 0) return(y); 1017: 1018: /* Clear device input buffer if requested */ 1019: y = (x & CLR_DEV) ? ttflui() : 0; 1020: #ifndef NOSPL 1021: /* Clear INPUT command buffer if requested */ 1022: if (x & CLR_INP) { 1023: for (x = 0; x < INPBUFSIZ; x++) 1024: inpbuf[x] = 0; 1025: inpbp = inpbuf; 1026: } 1027: #endif /* NOSPL */ 1028: return(success = (y == 0)); 1029: } 1030: #endif /* NOFRILLS */ 1031: 1032: if (cx == XXCOM) { /* COMMENT */ 1033: if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0) 1034: return(x); 1035: /* Don't change SUCCESS flag for this one */ 1036: return(0); 1037: } 1038: 1039: if (cx == XXCON) { /* CONNECT */ 1040: if ((x = cmcfm()) < 0) 1041: return(x); 1042: return(success = doconect()); 1043: } 1044: 1045: if (cx == XXCWD) /* CWD */ 1046: return(success = docd()); 1047: 1048: if (cx == XXCHK) /* CHECK */ 1049: return(success = dochk()); 1050: 1051: if (cx == XXCLO) { /* CLOSE */ 1052: x = cmkey(clstab,ncls,"Which log or file to close","",xxstring); 1053: if (x == -3) { 1054: printf("?You must say which file or log\n"); 1055: return(-9); 1056: } 1057: if (x < 0) return(x); 1058: if ((y = cmcfm()) < 0) return(y); 1059: y = doclslog(x); 1060: success = (y == 1); 1061: return(success); 1062: } 1063: 1064: #ifndef NOSPL 1065: if (cx == XXDEC || cx == XXINC) /* DECREMENT, INCREMENT */ 1066: return(doincr(cx)); 1067: #endif /* NOSPL */ 1068: 1069: #ifndef NOSPL 1070: if (cx == XXDEF || cx == XXASS || cx == XXASX || cx == XXDFX) 1071: return(dodef(cx)); /* DEFINE, ASSIGN */ 1072: #endif /* NOSPL */ 1073: 1074: #ifndef NOSPL 1075: if (cx == XXDCL) { /* DECLARE an array */ 1076: if ((y = cmfld("Array name","",&s,NULL)) < 0) { 1077: if (y == -3) { 1078: printf("?Array name required\n"); 1079: return(-9); 1080: } else return(y); 1081: } 1082: if ((y = arraynam(s,&x,&z)) < 0) return(y); 1083: if ((y = cmcfm()) < 0) return(y); 1084: if (dclarray((char)x,z) < 0) { 1085: printf("?Declare failed\n"); 1086: return(success = 0); 1087: } 1088: return(success = 1); 1089: } 1090: #endif /* NOSPL */ 1091: 1092: 1093: #ifndef NODIAL 1094: if (cx == XXRED || cx == XXDIAL) /* DIAL or REDIAL */ 1095: return(dodial(cx)); 1096: #endif /* NODIAL */ 1097: 1098: #ifndef NOFRILLS 1099: if (cx == XXDEL) /* DELETE */ 1100: return(dodel()); 1101: #endif /* NOFRILLS */ 1102: 1103: #ifndef MAC 1104: if (cx == XXDIR) /* DIRECTORY */ 1105: return(dodir()); 1106: #endif /* MAC */ 1107: 1108: #ifndef NOSPL 1109: if (cx == XXELS) /* ELSE */ 1110: return(doelse()); 1111: #endif /* NOSPL */ 1112: 1113: #ifndef NOFRILLS 1114: if (cx == XXENA || cx == XXDIS) { /* ENABLE, DISABLE */ 1115: s = (cx == XXENA) ? 1116: "Server function to enable" : 1117: "Server function to disable"; 1118: 1119: if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) { 1120: if (x == -3) { 1121: printf("?Name of server function required\n"); 1122: return(-9); 1123: } else return(x); 1124: } 1125: if ((y = cmcfm()) < 0) return(y); 1126: return(doenable(cx,x)); 1127: } 1128: #endif /* NOFRILLS */ 1129: 1130: #ifndef NOSPL 1131: if (cx == XXRET) { /* RETURN */ 1132: if (cmdlvl == 0) { /* At top level, nothing happens... */ 1133: if ((x = cmcfm()) < 0) 1134: return(x); 1135: return(success = 1); 1136: } else if (cmdstk[cmdlvl].src == CMD_TF) { /* In TAKE file, like POP */ 1137: if ((x = cmtxt("optional return value","",&s,NULL)) < 0) 1138: return(x); /* Allow trailing text, but ignore. */ 1139: if ((x = cmcfm()) < 0) 1140: return(x); 1141: popclvl(); /* pop command level */ 1142: return(success = 1); /* always succeeds */ 1143: } else if (cmdstk[cmdlvl].src == CMD_MD) { /* Within macro */ 1144: if ((x = cmtxt("optional return value","",&s,NULL)) < 0) 1145: return(x); 1146: return(doreturn(s)); /* Trailing text is return value. */ 1147: } else return(-2); 1148: } 1149: #endif /* NOSPL */ 1150: 1151: #ifndef NOSPL 1152: if (cx == XXDO) { /* DO (a macro) */ 1153: if (nmac == 0) { 1154: printf("\n?No macros defined\n"); 1155: return(-2); 1156: } 1157: for (y = 0; y < nmac; y++) { /* copy the macro table */ 1158: mackey[y].kwd = mactab[y].kwd; /* into a regular keyword table */ 1159: mackey[y].kwval = y; /* with value = pointer to macro tbl */ 1160: mackey[y].flgs = mactab[y].flgs; 1161: } 1162: /* parse name as keyword */ 1163: if ((x = cmkey(mackey,nmac,"macro","",xxstring)) < 0) { 1164: if (x == -3) { 1165: printf("?Macro name required\n"); 1166: return(-9); 1167: } else return(x); 1168: } 1169: if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0) 1170: return(y); /* get args */ 1171: return(dodo(x,s) < 1 ? (success = 0) : 1); 1172: } 1173: #endif /* NOSPL */ 1174: 1175: if (cx == XXECH) { /* ECHO */ 1176: if ((x = cmtxt("Material to be echoed","",&s,xxstring)) < 0) 1177: return(x); 1178: if (*s == '{') { /* Strip enclosing braces */ 1179: x = (int)strlen(s); 1180: if (s[x-1] == '}') { 1181: s[x-1] = NUL; 1182: s++; 1183: } 1184: } 1185: printf("%s\n",s); 1186: return(1); /* Always succeeds */ 1187: } 1188: 1189: #ifndef NOSPL 1190: if (cx == XXOPE) /* OPEN */ 1191: return(doopen()); 1192: #endif /* NOSPL */ 1193: 1194: #ifndef NOSPL 1195: if (cx == XXOUT) { /* OUTPUT */ 1196: if ((x = cmtxt("Text to be output","",&s,NULL)) < 0) 1197: return(x); 1198: debug(F110,"OUTPUT 1",s,0); 1199: if (*s == '{') { /* Strip enclosing braces, */ 1200: x = (int)strlen(s); /* if any. */ 1201: if (s[x-1] == '}') { 1202: s[x-1] = NUL; 1203: s++; 1204: } 1205: } 1206: debug(F110,"OUTPUT 2",s,0); 1207: for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \B, \L to \\B, \\L */ 1208: if (x > 0 && 1209: (s[x] == 'B' || s[x] == 'b' || s[x] == 'L' || s[x] == 'l')) 1210: if ((x == 1 && s[x-1] == CMDQ) || 1211: (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) 1212: line[y++] = CMDQ; 1213: line[y] = s[x]; 1214: } 1215: line[y++] = '\0'; /* Now expand variables, etc. */ 1216: debug(F110,"OUTPUT 3",line,0); 1217: s = line+y+1; 1218: x = LINBUFSIZ - strlen(line) - 1; 1219: debug(F101,"OUTPUT size","",x); 1220: if (xxstring(line,&s,&x) < 0) 1221: return(success = 0); 1222: s = line+y+1; 1223: debug(F110,"OUTPUT 4",s,0); 1224: return(success = dooutput(s)); 1225: } 1226: #endif /* NOSPL */ 1227: 1228: #ifdef SUNX25 1229: if (cx == XXPAD) { /* PAD commands */ 1230: x = cmkey(padtab,npadc,"PAD command","",xxstring); 1231: if (x == -3) { 1232: printf("?You must specify a PAD command to execute\n"); 1233: return(-2); 1234: } 1235: if (x < 0) return(x); 1236: 1237: switch (x) { 1238: case XYPADL: 1239: if (x25stat() < 0) 1240: printf("Sorry, you must 'set network' & 'set host' first\r\n"); 1241: else { 1242: x25clear(); 1243: initpad(); 1244: } 1245: break; 1246: case XYPADS: 1247: if (x25stat() < 0) 1248: printf("Not connected\r\n"); 1249: else { 1250: extern int linkid, lcn; 1251: conol("Connected thru "); 1252: conol(ttname); 1253: printf(", Link id %d, Logical channel number %d\r\n", 1254: linkid,lcn); 1255: } 1256: break; 1257: case XYPADR: 1258: if (x25stat() < 0) 1259: printf("Sorry, you must 'set network' & 'set host' first\r\n"); 1260: else 1261: x25reset(0,0); 1262: break; 1263: case XYPADI: 1264: if (x25stat() < 0) 1265: printf("Sorry, you must 'set network' & 'set host' first\r\n"); 1266: else 1267: x25intr(0); 1268: } 1269: return(0); 1270: } 1271: #endif /* SUNX25 */ 1272: 1273: #ifndef NOSPL 1274: if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */ 1275: return(dopaus(cx)); 1276: #endif /* NOSPL */ 1277: 1278: #ifndef NOFRILLS 1279: if (cx == XXPRI) { 1280: if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) { 1281: if (x == -3) { 1282: printf("?A file specification is required\n"); 1283: return(-9); 1284: } else return(x); 1285: } 1286: if (y != 0) { 1287: printf("?Wildcards not allowed\n"); 1288: return(-9); 1289: } 1290: strcpy(line,s); 1291: if ((x = cmtxt("Local print command options, or carriage return","",&s, 1292: xxstring)) < 0) return(x); 1293: return(success = (zprint(s,line) == 0) ? 1 : 0); 1294: } 1295: 1296: #ifdef TCPSOCKET 1297: if (cx == XXPNG) /* PING an IP host */ 1298: return(doping()); 1299: #endif /* TCPSOCKET */ 1300: 1301: #ifndef MAC 1302: if (cx == XXPWD) { /* PWD */ 1303: if ((x = cmcfm()) < 0) return(x); 1304: xsystem(PWDCMD); 1305: return(success = 1); /* blind faith */ 1306: } 1307: #endif /* MAC */ 1308: #endif /* NOFRILLS */ 1309: 1310: if (cx == XXQUI || cx == XXEXI) { /* EXIT, QUIT */ 1311: if ((y = cmnum("exit status code","",10,&x,xxstring)) < 0) { 1312: if (y == -3) 1313: x = xitsta; 1314: else return(y); 1315: } 1316: if ((y = cmcfm()) < 0) return(y); 1317: #ifdef VMS 1318: doexit(GOOD_EXIT,x); 1319: #else 1320: #ifdef OSK 1321: /* Returning any codes here makes the OS-9 shell print an error message. */ 1322: doexit(GOOD_EXIT,-1); 1323: #else 1324: #ifdef datageneral 1325: doexit(GOOD_EXIT,x); 1326: #else 1327: doexit(x,-1); 1328: #endif /* datageneral */ 1329: #endif /* OSK */ 1330: #endif /* VMS */ 1331: } 1332: 1333: #ifndef NOFRILLS 1334: if (cx == XXERR) { /* ERROR */ 1335: if ((x = cmcfm()) < 0) return(x); 1336: ttflui(); 1337: sstate = 'a'; 1338: return(0); 1339: } 1340: #endif /* NOFRILLS */ 1341: 1342: if (cx == XXFIN) { /* FINISH */ 1343: if ((x = cmcfm()) < 0) return(x); 1344: sstate = setgen('F',"","",""); 1345: if (local) ttflui(); /* If local, flush tty input buffer */ 1346: return(0); 1347: } 1348: 1349: #ifndef NOSPL 1350: if (cx == XXFOR) /* FOR loop */ 1351: return(dofor()); 1352: #endif /* NOSPL */ 1353: 1354: if (cx == XXGET) { /* GET */ 1355: x = cmtxt("Name of remote file(s), or carriage return","",&cmarg, 1356: xxstring); 1357: #ifndef NOFRILLS 1358: if ((x == -2) || (x == -1)) return(x); 1359: #else 1360: if (x < 0) return(x); 1361: #endif /* NOFRILLS */ 1362: if (*cmarg == '{') { /* Strip any enclosing braces */ 1363: x = (int)strlen(cmarg); /* This allows preservation of */ 1364: if (cmarg[x-1] == '}') { /* leading and/or trailing */ 1365: cmarg[x-1] = NUL; /* spaces. */ 1366: cmarg++; 1367: } 1368: } 1369: x = doget(); 1370: #ifdef MAC 1371: if (sstate == 'r') 1372: scrcreate(); 1373: #endif /* MAC */ 1374: return(x); 1375: } 1376: 1377: #ifndef NOSPL 1378: #ifndef NOFRILLS 1379: if (cx == XXGOK) { /* GETOK */ 1380: return(success = doask(cx)); 1381: } 1382: #endif /* NOFRILLS */ 1383: #endif /* NOSPL */ 1384: 1385: if (cx == XXHLP) { /* HELP */ 1386: #ifdef NOHELP 1387: return(dohlp(XXHLP)); 1388: #else 1389: x = cmkey2(cmdtab,ncmd,"C-Kermit command","help",toktab,xxstring); 1390: debug(F101,"HELP command x","",x); 1391: if (x == -5) { 1392: y = chktok(toktab); 1393: debug(F101,"top-level cmkey token","",y); 1394: ungword(); 1395: switch (y) { 1396: #ifndef NOPUSH 1397: case '!': x = XXSHE; break; 1398: #endif /* NOPUSH */ 1399: case '#': x = XXCOM; break; 1400: case ';': x = XXCOM; break; 1401: #ifndef NOSPL 1402: case ':': x = XXLBL; break; 1403: #endif /* NOSPL */ 1404: case '&': x = XXECH; break; 1405: default: 1406: printf("\n?Invalid - %s\n",cmdbuf); 1407: x = -2; 1408: } 1409: } 1410: return(dohlp(x)); 1411: #endif /* NOHELP */ 1412: } 1413: 1414: #ifndef NOHELP 1415: if (cx == XXINT) /* INTRO */ 1416: return(hmsga(introtxt)); 1417: #endif /* NOHELP */ 1418: 1419: if (cx == XXHAN) { /* HANGUP */ 1420: if ((x = cmcfm()) < 0) return(x); 1421: #ifndef NODIAL 1422: if ((x = mdmhup()) < 1) 1423: #endif /* NODIAL */ 1424: x = (tthang() > -1); 1425: return(success = x); 1426: } 1427: 1428: #ifndef NOSPL 1429: if (cx == XXGOTO) { /* GOTO */ 1430: /* Note, here we don't set SUCCESS/FAILURE flag */ 1431: if ((y = cmfld("label","",&s,xxstring)) < 0) { 1432: if (y == -3) { 1433: printf("?Label name required\n"); 1434: return(-9); 1435: } else return(y); 1436: } 1437: strcpy(lblbuf,s); 1438: if ((x = cmcfm()) < 0) return(x); 1439: s = lblbuf; 1440: return(dogoto(s)); 1441: } 1442: #endif /* NOSPL */ 1443: 1444: #ifndef NOSPL 1445: /* IF, Extended IF, WHILE */ 1446: if (cx == XXIF || cx == XXIFX || cx == XXWHI) { 1447: return(doif(cx)); 1448: } 1449: #endif /* NOSPL */ 1450: 1451: #ifndef NOSPL 1452: if (cx == XXINP || cx == XXREI) { /* INPUT and REINPUT */ 1453: y = cmnum("seconds to wait for input","1",10,&x,xxstring); 1454: if (y < 0) { 1455: return(y); 1456: } 1457: if (x <= 0) x = 1; 1458: if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0) 1459: return(y); 1460: #ifdef COMMENT 1461: /* 1462: Now it's ok -- null argument means wait for any character. 1463: */ 1464: if (*s == '\0') { 1465: printf("?Text required\n"); 1466: return(-9); 1467: } 1468: #endif /* COMMENT */ 1469: if (*s == '{') { 1470: y = (int)strlen(s); 1471: if (s[y-1] == '}') { 1472: s[y-1] = NUL; 1473: s++; 1474: } 1475: } 1476: if (cx == XXINP) { /* INPUT */ 1477: debug(F110,"calling doinput",s,0); 1478: success = doinput(x,s); /* Go try to input the search string */ 1479: } else { /* REINPUT */ 1480: debug(F110,"xxrei line",s,0); 1481: success = doreinp(x,s); 1482: } 1483: if (intime && !success) { /* TIMEOUT-ACTION = QUIT? */ 1484: popclvl(); /* If so, pop command level. */ 1485: if (pflag && cmdlvl == 0) { 1486: if (cx == XXINP) printf("?Input timed out\n"); 1487: if (cx == XXREI) printf("?Reinput failed\n"); 1488: } 1489: } 1490: return(success); /* Return do(re)input's return code */ 1491: } 1492: #endif /* NOSPL */ 1493: 1494: #ifndef NOSPL 1495: if (cx == XXLBL) { /* LABEL */ 1496: if ((x = cmfld("label","",&s,xxstring)) < 0) { 1497: if (x == -3) { 1498: printf("?Label name required\n"); 1499: return(-9); 1500: } else return(x); 1501: } 1502: if ((x = cmcfm()) < 0) return(x); 1503: return(0); 1504: } 1505: #endif /* NOSPL */ 1506: 1507: if (cx == XXLOG) { /* LOG */ 1508: x = cmkey(logtab,nlog,"What to log","",xxstring); 1509: if (x == -3) { 1510: printf("?Type of log required\n"); 1511: return(-9); 1512: } 1513: if (x < 0) return(x); 1514: x = dolog(x); 1515: if (x < 0) 1516: return(x); 1517: else 1518: return(success = x); 1519: } 1520: 1521: #ifndef NOSCRIPT 1522: if (cx == XXLOGI) { /* UUCP-style script */ 1523: if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0) 1524: return(x); 1525: #ifdef VMS 1526: conres(); /* For Ctrl-C to work... */ 1527: #endif /* VMS */ 1528: return(success = dologin(s)); /* Return 1=completed, 0=failed */ 1529: } 1530: #endif /* NOSCRIPT */ 1531: 1532: if (cx == XXREC) { /* RECEIVE */ 1533: cmarg2 = ""; 1534: x = cmofi("Name under which to store the file, or CR","",&s, 1535: xxstring); 1536: if ((x == -1) || (x == -2)) return(x); 1537: if ((x = cmcfm()) < 0) return(x); 1538: strcpy(line,s); 1539: cmarg2 = line; 1540: debug(F111,"cmofi cmarg2",cmarg2,x); 1541: sstate = 'v'; 1542: #ifdef MAC 1543: scrcreate(); 1544: #endif /* MAC */ 1545: if (local) displa = 1; 1546: return(0); 1547: } 1548: 1549: if (cx == XXREM) { /* REMOTE */ 1550: x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring); 1551: if (x == -3) { 1552: printf("?You must specify a command for the remote server\n"); 1553: return(-9); 1554: } 1555: return(dormt(x)); 1556: } 1557: 1558: #ifndef NOFRILLS 1559: if (cx == XXREN) /* RENAME */ 1560: return(dorenam()); 1561: #endif /* NOFRILLS */ 1562: 1563: if (cx == XXSEN || cx == XXMAI) { /* SEND, MAIL */ 1564: cmarg = cmarg2 = ""; 1565: if ((x = cmifi("File(s) to send","",&s,&y,xxstring)) < 0) { 1566: if (x == -3) { 1567: printf("?A file specification is required\n"); 1568: return(-9); 1569: } else return(x); 1570: } 1571: nfils = -1; /* Files come from internal list. */ 1572: strcpy(line,s); /* Save copy of string just parsed. */ 1573: strncpy(fspec,s,FSPECL); /* and here for \v(filespec) */ 1574: if (cx == XXSEN) { /* SEND command */ 1575: debug(F101,"Send: wild","",y); 1576: if (y == 0) { 1577: if ((x = cmtxt("Name to send it with","",&cmarg2, 1578: xxstring)) < 0) 1579: return(x); 1580: } else { 1581: if ((x = cmcfm()) < 0) return(x); 1582: } 1583: cmarg = line; /* File to send */ 1584: debug(F110,"Sending:",cmarg,0); 1585: if (*cmarg2 != '\0') debug(F110," as:",cmarg2,0); 1586: } else { /* MAIL */ 1587: #ifndef NOFRILLS 1588: if (!atdiso || !atcapr) { /* Disposition attribute off? */ 1589: printf("?Disposition Attribute is Off\n"); 1590: return(-2); 1591: } 1592: debug(F101,"Mail: wild","",y); 1593: *optbuf = NUL; /* Wipe out any old options */ 1594: if ((x = cmtxt("Address to mail to","",&s,xxstring)) < 0) 1595: return(x); 1596: if ((int)strlen(s) == 0) { 1597: printf("?Address required\n"); 1598: return(-9); 1599: } 1600: strcpy(optbuf,s); 1601: if ((int)strlen(optbuf) > 94) { /* Ensure legal size */ 1602: printf("?Option string too long\n"); 1603: return(-2); 1604: } 1605: cmarg = line; /* File to send */ 1606: debug(F110,"Mailing:",cmarg,0); 1607: debug(F110,"To:",optbuf,0); 1608: rmailf = 1; /* MAIL modifier flag for SEND */ 1609: #else 1610: printf("?Sorry, MAIL feature not configured.\n"); 1611: return(-2); 1612: #endif /* NOFRILLS */ 1613: } 1614: sstate = 's'; /* Set start state to SEND */ 1615: #ifdef MAC 1616: scrcreate(); 1617: #endif /* MAC */ 1618: if (local) { /* If in local mode, */ 1619: displa = 1; /* turn on file transfer display */ 1620: #ifdef COMMENT 1621: /* Redundant -- this is done later in sipkt() */ 1622: ttflui(); /* and flush tty input buffer. */ 1623: #endif /* COMMENT */ 1624: } 1625: return(0); 1626: } 1627: 1628: #ifndef NOMSEND 1629: if (cx == XXMSE) { /* MSEND command */ 1630: nfils = 0; /* Like getting a list of */ 1631: lp = line; /* files on the command line */ 1632: while (1) { 1633: char *p; 1634: if ((x = cmifi("Names of files to send, separated by spaces","", 1635: &s,&y,xxstring)) < 0) { 1636: if (x == -3) { 1637: if (nfils <= 0) { 1638: printf("?A file specification is required\n"); 1639: return(-9); 1640: } else break; 1641: } 1642: return(x); 1643: } 1644: msfiles[nfils++] = lp; /* Got one, count it, point to it, */ 1645: p = lp; /* remember pointer, */ 1646: while (*lp++ = *s++) ; /* and copy it into buffer */ 1647: debug(F111,"msfiles",msfiles[nfils-1],nfils-1); 1648: if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */ 1649: if (((int)strlen(fspec) + (int)strlen(p) + 1) < FSPECL) { 1650: strcat(fspec,p); 1651: strcat(fspec," "); 1652: } 1653: } 1654: cmlist = msfiles; /* Point cmlist to pointer array */ 1655: cmarg2 = ""; /* No internal expansion list (yet) */ 1656: sndsrc = nfils; /* Filenames come from cmlist */ 1657: sstate = 's'; /* Set start state to SEND */ 1658: #ifdef MAC 1659: scrcreate(); 1660: #endif /* MAC */ 1661: if (local) { /* If in local mode, */ 1662: displa = 1; /* turn on file transfer display */ 1663: ttflui(); /* and flush tty input buffer. */ 1664: } 1665: return(0); 1666: } 1667: #endif /* NOMSEND */ 1668: 1669: #ifndef NOSERVER 1670: if (cx == XXSER) { /* SERVER */ 1671: if ((x = cmcfm()) < 0) return(x); 1672: sstate = 'x'; 1673: #ifdef MAC 1674: scrcreate(); 1675: #endif /* MAC */ 1676: if (local) displa = 1; 1677: #ifdef AMIGA 1678: reqoff(); /* No DOS requestors while server */ 1679: #endif /* AMIGA */ 1680: return(0); 1681: } 1682: #endif /* NOSERVER */ 1683: 1684: if (cx == XXSET) { /* SET command */ 1685: x = cmkey(prmtab,nprm,"Parameter","",xxstring); 1686: if (x == -3) { 1687: printf("?You must specify a parameter to set\n"); 1688: return(-9); 1689: } 1690: if (x < 0) return(x); 1691: /* have to set success separately for each item in doprm()... */ 1692: /* actually not really, could have just had doprm return 0 or 1 */ 1693: /* and set success here... */ 1694: y = doprm(x,0); 1695: if (y == -3) { 1696: printf("?More fields required\n"); 1697: return(-9); 1698: } else return(y); 1699: } 1700: 1701: #ifndef NOPUSH 1702: if (cx == XXSHE) { /* SHELL (system) command */ 1703: if (cmtxt("System command to execute","",&s,xxstring) < 0) 1704: return(-1); 1705: conres(); /* Make console normal */ 1706: x = zshcmd(s); 1707: concb((char)escape); 1708: return(success = x); 1709: } 1710: #endif /* NOPUSH */ 1711: 1712: #ifndef NOSHOW 1713: if (cx == XXSHO) { /* SHOW */ 1714: x = cmkey(shotab,nsho,"","parameters",xxstring); 1715: if (x < 0) return(x); 1716: return(doshow(x)); 1717: } 1718: #endif /* NOSHOW */ 1719: 1720: #ifndef MAC 1721: if (cx == XXSPA) { /* SPACE */ 1722: #ifdef datageneral 1723: /* AOS/VS can take an argument after its "space" command. */ 1724: if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0) 1725: return(x); 1726: if (*s == NUL) xsystem(SPACMD); 1727: else { 1728: sprintf(line,"space %s",s); 1729: xsystem(line); 1730: } 1731: #else 1732: #ifdef OS2 1733: if ((x = cmtxt("Press Enter for current disk,\n\ 1734: or specify a disk letter like A:","",&s,xxstring)) < 0) 1735: return(x); 1736: if (*s == NUL) { /* Current disk */ 1737: printf(" Free space: %ldK\n", zdskspace(0)/1024L); 1738: } else { 1739: int drive = toupper(*s); 1740: printf(" Drive %c: %ldK free\n", drive, 1741: zdskspace(drive - 'A' + 1) / 1024L); 1742: } 1743: #else 1744: #ifdef UNIX 1745: #ifdef COMMENT 1746: if ((x = cmtxt("Confirm for current disk,\n\ 1747: or specify a disk device or directory","",&s,xxstring)) < 0) 1748: return(x); 1749: #else 1750: x = cmdir("Confirm for current disk,\n\ 1751: or specify a disk device or directory","",&s,xxstring); 1752: if (x == -3) 1753: s = ""; 1754: else if (x < 0) 1755: return(x); 1756: if ((x = cmcfm()) < 0) return(x); 1757: #endif /* COMMENT */ 1758: if (*s == NUL) { /* Current disk */ 1759: xsystem(SPACMD); 1760: } else { /* Specified disk */ 1761: sprintf(line,"%s %s",SPACM2,s); 1762: xsystem(line); 1763: } 1764: #else 1765: if ((x = cmcfm()) < 0) return(x); 1766: xsystem(SPACMD); 1767: #endif /* UNIX */ 1768: #endif /* OS2 */ 1769: #endif /* datageneral */ 1770: return(success = 1); /* Pretend it worked */ 1771: } 1772: #endif /* MAC */ 1773: 1774: if (cx == XXSTA) { /* STATISTICS */ 1775: if ((x = cmcfm()) < 0) return(x); 1776: return(success = dostat()); 1777: } 1778: 1779: if (cx == XXSTO || cx == XXEND) { /* STOP, END, or POP */ 1780: if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0) 1781: return(y); 1782: if ((y = cmtxt("Message to print","",&s,xxstring)) < 0) 1783: return(y); 1784: if (*s == '{') { /* Strip any enclosing braces */ 1785: x = (int)strlen(s); 1786: if (s[x-1] == '}') { 1787: s[x-1] = NUL; 1788: s++; 1789: } 1790: } 1791: if (*s) printf("%s\n",s); 1792: if (cx == XXSTO) dostop(); else popclvl(); 1793: return(success = (x == 0)); 1794: } 1795: 1796: if (cx == XXSUS) { /* SUSPEND */ 1797: if ((y = cmcfm()) < 0) return(y); 1798: #ifdef NOJC 1799: printf("Sorry, this version of Kermit cannot be suspended\n"); 1800: #else 1801: stptrap(0); 1802: #endif /* NOJC */ 1803: return(0); 1804: } 1805: 1806: if (cx == XXTAK) { /* TAKE */ 1807: if (tlevel > MAXTAKE-1) { 1808: printf("?Take files nested too deeply\n"); 1809: return(-2); 1810: } 1811: if ((y = cmifi("C-Kermit command file","",&s,&x,xxstring)) < 0) { 1812: if (y == -3) { 1813: printf("?A file name is required\n"); 1814: return(-9); 1815: } else return(y); 1816: } 1817: if (x != 0) { 1818: printf("?Wildcards not allowed in command file name\n"); 1819: return(-9); 1820: } 1821: strcpy(line,s); 1822: if ((y = cmcfm()) < 0) return(y); 1823: return(success = dotake(line)); 1824: } 1825: 1826: #ifdef NETCONN 1827: if (cx == XXTEL) { /* TELNET */ 1828: if ((y = setlin(XYHOST,0)) < 0) return(y); 1829: return (success = (y == 0) ? 0 : doconect()); 1830: } 1831: #endif /* NETCONN */ 1832: 1833: #ifndef NOXMIT 1834: if (cx == XXTRA) { /* TRANSMIT */ 1835: if ((x = cmifi("File to transmit","",&s,&y,xxstring)) < 0) { 1836: if (x == -3) { 1837: printf("?Name of an existing file\n"); 1838: return(-9); 1839: } else return(x); 1840: } 1841: if (y != 0) { 1842: printf("?Only a single file may be transmitted\n"); 1843: return(-2); 1844: } 1845: strcpy(line,s); /* Save copy of string just parsed. */ 1846: if ((y = cmcfm()) < 0) return(y); /* Confirm the command */ 1847: debug(F111,"calling transmit",line,xmitp); 1848: return(success = transmit(line,(char)xmitp)); /* Do the command */ 1849: } 1850: #endif /* NOXMIT */ 1851: 1852: #ifndef NOFRILLS 1853: if (cx == XXTYP) { /* TYPE */ 1854: #ifndef MAC 1855: char *tc; 1856: #endif /* MAC */ 1857: if ((x = cmifi("File to type","",&s,&y,xxstring)) < 0) { 1858: if (x == -3) { 1859: printf("?Name of an existing file\n"); 1860: return(-9); 1861: } else return(x); 1862: } 1863: if (y != 0) { 1864: printf("?A single file please\n"); 1865: return(-2); 1866: } 1867: #ifndef MAC 1868: if (!(tc = getenv("CK_TYPE"))) tc = TYPCMD; 1869: sprintf(line,"%s %s",tc,s); 1870: if ((y = cmcfm()) < 0) return(y); /* Confirm the command */ 1871: xsystem(line); 1872: return(success = 1); 1873: #else 1874: strcpy(line,s); 1875: if ((y = cmcfm()) < 0) return(y); /* Confirm the command */ 1876: return(success = dotype(line)); 1877: #endif /* MAC */ 1878: } 1879: #endif /* NOFRILLS */ 1880: 1881: #ifndef NOFRILLS 1882: if (cx == XXTES) { /* TEST */ 1883: /* Fill this in with whatever is being tested... */ 1884: if ((y = cmcfm()) < 0) return(y); /* Confirm the command */ 1885: 1886: #ifndef NOSPL 1887: #ifdef COMMENT 1888: { int d, i, j; /* Dump all arrays */ 1889: char c, **p; 1890: for (i = 0; i < 27; i++) { 1891: p = a_ptr[i]; 1892: d = a_dim[i]; 1893: c = (i == 0) ? 64 : i + 96; 1894: if (d && p) { 1895: fprintf(stderr,"&%c[%d]\n",c,d); 1896: for (j = 0; j <= d; j++) { 1897: if (p[j]) { 1898: fprintf(stderr," &%c[%2d] = [%s]\n",c,j,p[j]); 1899: } 1900: } 1901: } 1902: } 1903: } 1904: #else /* Not COMMENT */ 1905: printf("cmdlvl = %d, tlevel = %d, maclvl = %d\n",cmdlvl,tlevel,maclvl); 1906: if (maclvl < 0) { 1907: printf("%s\n", 1908: "Call me from inside a macro and I'll dump the argument stack"); 1909: return(0); 1910: } 1911: printf("Macro level: %d, ARGC = %d\n ",maclvl,macargc[maclvl]); 1912: for (y = 0; y < 10; y++) printf("%7d",y); 1913: for (x = 0; x <= maclvl; x++) { 1914: printf("\n%2d: ",x); 1915: for (y = 0; y < 10; y++) { 1916: s = m_arg[x][y]; 1917: printf("%7s",s ? s : "(none)"); 1918: } 1919: } 1920: printf("\n"); 1921: #endif /* COMMENT */ 1922: #endif /* NOSPL */ 1923: return(0); 1924: } 1925: #endif /* NOFRILLS */ 1926: 1927: #ifndef NOCSETS 1928: if (cx == XXXLA) { /* TRANSLATE <ifn> from-cs to-cs <ofn> */ 1929: int incs, outcs; 1930: if ((x = cmifi("File to translate","",&s,&y,xxstring)) < 0) { 1931: if (x == -3) { 1932: printf("?Name of an existing file\n"); 1933: return(-9); 1934: } else return(x); 1935: } 1936: if (y != 0) { 1937: printf("?A single file please\n"); 1938: return(-2); 1939: } 1940: strcpy(line,s); /* Save copy of string just parsed. */ 1941: 1942: if ((incs = cmkey(fcstab,nfilc,"from character-set","",xxstring)) < 0) 1943: return(incs); 1944: if ((outcs = cmkey(fcstab,nfilc,"to character-set","",xxstring)) < 0) 1945: return(outcs); 1946: if ((x = cmofi("output file",CTTNAM,&s,xxstring)) < 0) return(x); 1947: strncpy(tmpbuf,s,50); 1948: if ((y = cmcfm()) < 0) return(y); /* Confirm the command */ 1949: return(success = xlate(line,tmpbuf,incs,outcs)); /* Execute it */ 1950: } 1951: #endif /* NOCSETS */ 1952: 1953: if (cx == XXVER) { /* VERSION */ 1954: if ((y = cmcfm()) < 0) return(y); 1955: printf("%s,%s\n Numeric: %ld",versio,ckxsys,vernum); 1956: if (verwho) printf("-%d\n",verwho); else printf("\n"); 1957: return(success = 1); 1958: } 1959: 1960: #ifndef MAC 1961: #ifndef NOFRILLS 1962: if (cx == XXWHO) { /* WHO */ 1963: char *wc; 1964: #ifdef datageneral 1965: xsystem(WHOCMD); 1966: #else 1967: if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y); 1968: if (!(wc = getenv("CK_WHO"))) wc = WHOCMD; 1969: sprintf(line,"%s %s",wc,s); 1970: xsystem(line); 1971: #endif /* datageneral */ 1972: return(success = 1); 1973: } 1974: #endif /* NOFRILLS */ 1975: #endif /* MAC */ 1976: 1977: #ifndef NOFRILLS 1978: if (cx == XXWRI) { /* WRITE */ 1979: if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) { 1980: if (x == -3) printf("?Write to what?\n"); 1981: return(x); 1982: } 1983: if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y); 1984: if (*s == '{') { /* Strip enclosing braces */ 1985: y = (int)strlen(s); 1986: if (s[y-1] == '}') { 1987: s[y-1] = NUL; 1988: s++; 1989: } 1990: } 1991: switch (x) { 1992: case LOGD: y = ZDFILE; break; 1993: case LOGP: y = ZPFILE; break; 1994: case LOGS: y = ZSFILE; break; 1995: case LOGT: y = ZTFILE; break; 1996: #ifndef NOSPL 1997: case LOGW: y = ZWFILE; break; 1998: #endif /* NOSPL */ 1999: case LOGX: 2000: case LOGE: 2001: 2002: #ifndef MAC 2003: if (x == LOGE) fprintf(stderr,"%s",s); 2004: else 2005: #endif /* MAC */ 2006: printf("%s",s); 2007: if ( 2008: #ifndef NOSPL 2009: cmdlvl == 0 2010: #else 2011: tlevel == -1 2012: #endif /* NOSPL */ 2013: ) 2014: #ifndef MAC 2015: if (x == LOGE) fprintf(stderr,"\n"); 2016: else 2017: #endif /* MAC */ 2018: printf("\n"); 2019: return(success = 1); 2020: default: return(-2); 2021: } 2022: if ((x = zsout(y,s)) < 0) 2023: printf("?File or log not open\n"); 2024: return(success = (x == 0) ? 1 : 0); 2025: } 2026: #endif /* NOFRILLS */ 2027: 2028: debug(F101,"docmd unk arg","",cx); 2029: return(-2); /* None of the above. */ 2030: } /* end of docmnd() */ 2031: 2032: #endif /* NOICP */