home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / xc-4.1 / part02 / xcmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  16.7 KB  |  903 lines

  1. /*    xcmain.c -- main module for XC
  2.     This file uses 4-character tabstops
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <sys/types.h>
  8. #include <signal.h>
  9. #include <ctype.h>
  10. #include <termio.h>
  11. #include <sys/ioctl.h>
  12. #include <setjmp.h>
  13. #include "xc.h"
  14.  
  15. #define Resume_Not_Allowed    1
  16.  
  17. short
  18.     autoflag =    FALSE,    /* Automatic capturing */
  19.     cismode =    FALSE,    /* Automatic response to CIS "ENQ" */
  20.     cr_add =    TRUE,    /* Add cr to nl in B+ uploads */
  21.     hdplxflag =    FALSE,    /* Half-duplex mode */
  22.      menuflag =    TRUE,    /* Show mini-menu */
  23.     nl2cr =        TRUE,    /* Map nl to cr when transmitting ASCII */
  24.     reterm =    FALSE,    /* Jumping into terminal mode */
  25.     statflag =    FALSE,    /* Flag for status display */
  26.     eofflag =    FALSE;    /* Flag to quit a script */
  27. int s_cis(), s_set(), s_exit(), s_shell();
  28. char Msg[SM_BUFF];
  29. unchar BS, LK;
  30. FILE *tfp;
  31. struct termio newmode, oldmode, sigmode;
  32. static char    *statfmt = "\r\t\t%-8s %25s %s\r\n",
  33.             version[]="@(#)XC 4.1 JPRadley 10 April 1993",
  34.             oldshell[SM_BUFF],
  35.             *babble[] = {
  36.                 "\r\nUsage: xc [-l device] [-s file | -t]",
  37.                 "\t-l device\tUse 'device' as the modem port",
  38.                 "\t-s script\tExecute 'script' immediately",
  39.                 "\t-t\t\tEnter terminal mode immediately",
  40.                 NIL(char)
  41.             };
  42. static s_script(), s_xmodem(), s_term(), s_help(), s_dial(), puttake(),
  43.     SET_proto(), SET_cr(), SET_cis(), SET_nl(), SET_xon(), SET_xcape(),
  44.     SET_menu(), SET_hdplx(), SET_bps(), SET_autocapt(), SET_cfile(),
  45.     SET_pfile();
  46. extern short scriptflag;
  47. extern void B_Transfer(), dbglog(), mattach(), terminal(), xreceive(), xsend(),
  48.     get_ttype(), unlock_tty();
  49. jmp_buf erret;            /* non-local error return */
  50.  
  51. struct kw {                /* Used by command parsing routines */
  52.     char *keyword;
  53.     int (*rtn)();
  54. };
  55.  
  56. static struct kw cmds[] = {
  57.     {"c",        s_cis},
  58.     {"cis",        s_cis},
  59.     {"s",        s_script},
  60.     {"script",    s_script},
  61.     {"h",        hangup},
  62.     {"hangup",    hangup},
  63.     {"bindings",show_bindings},
  64.     {"rb",        s_xmodem},
  65.     {"rt",        s_xmodem},
  66.     {"sb",        s_xmodem},
  67.     {"st",        s_xmodem},
  68.     {"set",        s_set},
  69.     {"t",        s_term},
  70.     {"term",    s_term},
  71.     {"d",        s_dial},
  72.     {"dial",    s_dial},
  73.     {"q",        s_exit},
  74.     {"quit",    s_exit},
  75.     {"exit",    s_exit},
  76.     {"x",        s_exit},
  77.     {"!",        s_shell},
  78.     {"!!",        s_shell},
  79.     {"$",        s_shell},
  80.     {"%p",        puttake},
  81.     {"%t",        puttake},
  82.     {"help",    s_help},
  83.     {"?",        s_help},
  84.     {NIL(char),    0}
  85. };
  86.  
  87. static struct kw setlist[] = {
  88.     {"auto",    SET_autocapt},
  89.     {"baud",    SET_bps},
  90.     {"bps",        SET_bps},
  91.     {"cfile",    SET_cfile},
  92.     {"cis",        SET_cis},
  93.     {"cr",        SET_cr},
  94.     {"hdplx",    SET_hdplx},
  95.     {"menu",    SET_menu},
  96.     {"nl",        SET_nl},
  97.     {"pfile",    SET_pfile},
  98.     {"proto",    SET_proto},
  99.     {"escape",    SET_xcape},
  100.     {"xcape",    SET_xcape},
  101.     {"xon",        SET_xon},
  102.     {"xoff",    SET_xon},
  103.     {NIL(char),    0}
  104. };
  105.  
  106. /* Print the status of the program */
  107. static void
  108. status()
  109. {
  110.     struct kw *ptr;
  111.     char p[30];
  112.     int (*fct)() = 0;
  113.  
  114.     statflag = TRUE;
  115.  
  116.     cls();
  117.     cur_off();
  118.     sprintf(p,"Modem Port: %s",mport(NIL(char)));
  119.     drawline(0, 0, CO);
  120.     ttgoto(1, 9);
  121.     sprintf(Msg,"%-29s%29s",&version[4], p);
  122.     S;
  123.     drawline(2, 0, CO);
  124.     ttgoto(3, 0);
  125.     fprintf(tfp, statfmt, "Keyword", "Description", "Status");
  126.     fprintf(tfp, statfmt, "--------", "-------------------------", "-----------");
  127.  
  128.     for (ptr = setlist; ptr->keyword; ptr++)
  129.         if (ptr->rtn != fct){
  130.             fct = ptr->rtn;
  131.             (*fct)();
  132.         }
  133.  
  134.     ttgoto(18, 25);
  135.     S1("Type \"help\" or ? for help");
  136.     statflag = FALSE;
  137.     cur_on();
  138. }
  139.  
  140. /* Catch a signal and jump to main. Reset signal and do a longjmp */
  141. static void
  142. catch(junk)
  143. int junk;
  144. {
  145.     if (! isatty(2))
  146.         hangup(),
  147.         s_exit();
  148.  
  149.     S2("XC: Interrupt");
  150.  
  151.     signal(SIGINT,catch);
  152.     signal(SIGQUIT,catch);
  153.     longjmp(erret,1);
  154. }
  155.  
  156. static void
  157. usage()
  158. {
  159.     char **ptr;
  160.  
  161.     for (ptr = babble; *ptr; ptr++)
  162.         fprintf(tfp, "%s\r\n", *ptr);
  163. }
  164.  
  165. main(argc, argv)
  166. int argc;
  167. char **argv;
  168. {
  169.     char *script = NIL(char);
  170.     extern char *optarg;
  171.     int c;
  172.     extern int optind;
  173.  
  174.     struct kw *ptr;
  175.     tfp = stderr;
  176.     if (isatty(2))
  177.         get_ttype();
  178.  
  179.     ioctl(0, TCGETA, &oldmode);    /* get current tty mode    */
  180.  
  181.     /* trap for SIGHUP and SIGTERM, make sure LCKfile gets killed */
  182.     signal(SIGHUP,(void *)s_exit);
  183.     signal(SIGTERM,(void *)s_exit);
  184.  
  185.     newmode = oldmode;
  186.  
  187.     newmode.c_iflag &= ~(IXON | IXOFF | IXANY);
  188.     newmode.c_lflag &= ~(ICANON | ISIG | ECHO);
  189.     newmode.c_oflag = 0;
  190.     newmode.c_cc[VMIN] = 1;
  191.     newmode.c_cc[VTIME] = 1;
  192.     BS = newmode.c_cc[VERASE];
  193.     LK = newmode.c_cc[VKILL];
  194.  
  195.     sigmode = newmode;
  196.     sigmode.c_lflag |= ISIG;
  197.  
  198.     oldshell[0] = '\0';    /* set last command to blank */
  199.     if (setjmp(erret))    /* set error handler to exit */
  200.         exit(0);        /*  while parsing command line */
  201.     signal(SIGINT,catch);    /* catch break & quit signals/keys */
  202.     signal(SIGQUIT,catch);
  203.  
  204.     default_bindings();
  205.  
  206.     while ((c = getopt(argc, argv, "s:l:t")) != -1)
  207.         switch (c){
  208.         case 'l':    /* set modem port name */
  209.             mport(optarg);
  210.             break;
  211.         case 's':    /* Execute SCRIPT file */
  212.             script = optarg;
  213.             break;
  214.         case 't':    /* jump into terminal mode */
  215.             reterm = TRUE;
  216.             break;
  217.         default:    /* Bad command .. print help */
  218.             usage();
  219.             exit(1);
  220.         }
  221.  
  222.     setuid(geteuid());
  223.     setgid(getegid());
  224.  
  225.     mopen();    /* opens and configures modem port, or exits */
  226.  
  227.     setuid(getuid());
  228.     setgid(getgid());
  229.  
  230.     do_script(STARTUP);
  231.  
  232. #if DEBUG
  233.     dbglog();
  234. #endif
  235.  
  236.     if (!script)
  237.         status();
  238.  
  239.     for (;;){
  240.         setjmp(erret);
  241.         signal(SIGQUIT,(void *)s_exit);
  242.         mode(SIGMODE);
  243.  
  244.         if (script)
  245.             do_script(script),
  246.             script = NIL(char),
  247.             reterm = TRUE;
  248.  
  249.         if (reterm && isatty(2)){
  250.             s_term();
  251.             continue;
  252.         }
  253.  
  254.         fputc('\r',tfp),
  255.         fputc('\n',tfp);
  256.          if (menuflag)
  257.             fputc('\t',tfp),
  258.              S1("[d]ial directory  [t]erminal mode  [q]uit  [s]cript  [?]help");
  259.         show(-1,"<XC>");
  260.         fputc(' ',tfp);
  261.  
  262.         lptr = line;
  263.         getline();
  264.         fputc('\r',tfp),
  265.         fputc('\n',tfp);
  266.  
  267.         getword();
  268.         lc_word(word);
  269.         if (word[0] == '\0')        /* If blank line... reprompt */
  270.             continue;
  271.  
  272.         for (ptr = cmds; ptr->keyword; ptr++)
  273.             if (!strcmp(word, ptr->keyword))
  274.                 break;
  275.  
  276.         if (ptr->keyword)
  277.             (*ptr->rtn)();
  278.         else
  279.             sprintf(Msg,"Unrecognized command: %s",word),
  280.             S;
  281.     }
  282. }
  283.  
  284. static
  285. s_script()
  286. {
  287.     getword();
  288.  
  289.     if (word[0] == '\0'){
  290.         S1("Script file not specified");
  291.         return;
  292.     }
  293.  
  294.     sprintf(ddsname,"%s",word);
  295.     do_script(ddsname);
  296.     reterm = TRUE;
  297. }
  298.  
  299. static
  300. s_xmodem()
  301. {
  302.     char d = word[0];
  303.     char c = word[1];
  304.     char oldproto[4];
  305.  
  306.     strcpy(oldproto, protocol);
  307.  
  308.     xc_setflow(FALSE);
  309.     xc_setproto("8N1");
  310.  
  311.     getword();
  312.     if (word[0] == '\0')
  313.         S1("Transfer file not specified");
  314.     else if (d == 's')
  315.         xsend(c);
  316.     else
  317.         xreceive(c);
  318.  
  319.     reterm = TRUE;
  320.     xc_setflow(flowflag);
  321.     xc_setproto(oldproto);
  322. }
  323.  
  324. static
  325. s_term()
  326. {
  327.     terminal(FALSE);
  328.     if (cismode != 2)
  329.         return;
  330.     cismode = 1;
  331.     s_cis();
  332. }
  333.  
  334. static
  335. s_dial()
  336. {
  337.     terminal(TRUE);
  338.     if (cismode != 2)
  339.         return;
  340.     cismode = 1;
  341.     s_cis();
  342. }
  343.  
  344. s_cis()
  345. {
  346.     char oldproto[4];
  347.  
  348.     strcpy(oldproto, protocol);
  349.  
  350.     xc_setflow(FALSE);
  351.     xc_setproto("8N1");
  352.     mode(SIGMODE);
  353.  
  354.     B_Transfer();
  355.  
  356.     reterm = TRUE;
  357.     xc_setflow(flowflag);
  358.     xc_setproto(oldproto);
  359. }
  360.  
  361. s_shell()
  362. {
  363.     int stat_loc = 0;
  364.     char c = word[0];
  365.     static char *shell = NIL(char);
  366.     void (*oldvec)();
  367.  
  368. #if NOSHELL
  369.     return(0);
  370. #endif
  371.     if (word[0] == word[1])
  372.         strcpy(wptr = word, oldshell);
  373.     else {
  374.         getword();
  375.         if (*wptr)
  376.             strcpy(oldshell, wptr);
  377.     }
  378.  
  379.     if (!shell){
  380.         shell = getenv("SHELL");
  381.         if (!shell)
  382.             shell = "/bin/sh";
  383.     }
  384.  
  385.     fputc('\r',tfp),
  386.     fputc('\n',tfp);
  387.     mode(OLDMODE);
  388.  
  389.     if (!forkem()){
  390.         if (c == '$')    /* Attach modem to stdin, stdout */
  391.             mattach();
  392.         signal(SIGCLD,SIG_DFL);
  393.         signal(SIGINT,SIG_DFL);
  394.         signal(SIGQUIT,SIG_DFL);
  395.         if (word[0] == '\0')
  396.             execl(shell, shell, "-i", NIL(char));
  397.         else
  398.             execl(shell, shell, "-c", wptr, NIL(char));
  399.         S1("Exec failed!");
  400.         exit(2);
  401.     }
  402.  
  403.     oldvec = signal(SIGINT,SIG_IGN);
  404.     wait(&stat_loc);
  405.     signal(SIGINT,oldvec);
  406.  
  407.     strcpy(oldshell, wptr);
  408.     return(!!stat_loc);
  409. }
  410.  
  411. static char    *cmdlist[] = {
  412.     "\tXC Command Summary",
  413.     "",
  414.     "\tc",
  415.     "\tcis\t\tInitiate CIS B+ File Transfer (Upload and Download)",
  416.     "",
  417.     "\td",
  418.     "\tdial\t\tDialing directory",
  419.     "",
  420.     "\tx",
  421.     "\tq",
  422.     "\texit",
  423.     "\tquit\t\tExit XC",
  424.     "",
  425.     "\th",
  426.     "\thangup\t\tHang up the modem",
  427.     "",
  428.     "\trb file\t\tXMODEM receive file 'file' (binary mode)",
  429.     "\trt file\t\tXMODEM receive file 'file' (Ascii mode)",
  430.     "",
  431.     "\tsb file...\tXMODEM send file 'file' (binary mode)",
  432.     "\tst file...\tXMODEM send file 'file' (Ascii mode)",
  433.     "",
  434.     "\tset\t\tDisplay XC parameters",
  435.     "\tset kw\t\tDisplay XC parameter for 'kw'",
  436.     "\tset kw val\tSet XC keyword 'kw' to 'val'",
  437.     "",
  438.     "\ts file",
  439.     "\tscript file\tExecute XC script 'file'",
  440.     "",
  441.     "\tt",
  442.     "\tterm\t\tEnter terminal mode",
  443.     "",
  444. #if !NOSHELL
  445.     "\t!\t\tExecute a local interactive shell",
  446.     "\t! cmd\t\tExecute shell command string on the local system",
  447.     "\t!!\t\tRe-execute the last shell command string",
  448.     "",
  449.     "\t$ cmd\t\tShell command with stdin and stdout redirected to modem",
  450.     "",
  451. #endif
  452.     "\t%p loc [rem]\tPut local file to a UNIX system",
  453.     "",
  454.     "\t%t rem [loc]\tTake remote file from a UNIX system",
  455.     "",
  456.     "\t?",
  457.     "\thelp\t\tPrint (this) help text",
  458.     " ",
  459.     "\tSET Keywords:",
  460.     "",
  461.     "\tset\t\t\tDisplay current XC status",
  462.     "",
  463.     "\tset auto on|off\t\tSet|Unset automatic capturing",
  464.     "",
  465.     "\tset bps value",
  466.     "\tset baud value\t\tSet Bits/Second to 'value'",
  467.     "",
  468.     "\tset cfile name\t\tChange name of capture file",
  469.     "",
  470.     "\tset cis on\t\tSet CIS <ENQ> mode (Auto up/download)",
  471.     "\tset cis off\t\tDo not respond to <ENQ>",
  472.     "",
  473.     "\tset cr on|off\t\tSet|Unset Carriage Return Injection mode",
  474.     "",
  475.     "\tset xcape char",
  476.     "\tset escape char\t\tSet the Terminal mode escape character",
  477.     "",
  478.     "\tset hdplx on\t\tSet half-duplex mode",
  479.     "\tset hdplx off\t\tUnset half-duplex mode (use full-duplex)",
  480.     "",
  481.      "\tset menu on|off\t\tDo|Don't show mini-menu before XC prompt",
  482.     "",
  483.     "\tset nl on|off\t\tSet|Unset newline translation",
  484.     "",
  485.     "\tset pfile name\t\tChange name of phonelist file",
  486.     "",
  487.     "\tset proto 7E2\t\tSet 7-bit character size, even parity",
  488.     "\tset proto 7O2\t\tSet 7-bit character size, odd parity",
  489.     "\tset proto 8N1\t\tSet 8-bit character size, no parity",
  490.     "",
  491.     "\tset xon on|off",
  492.     "\tset xoff on|off\t\tSet|Unset XON/XOFF flow control",
  493.     "",
  494.     " ",
  495.     NIL(char) };
  496.  
  497. static
  498. s_help()
  499. {
  500.     char **ptr = cmdlist;
  501.     int curline = 0;
  502.  
  503.     mode(OLDMODE);
  504.     cls();
  505.     cur_off();
  506.     for ( ; *ptr; ptr++) {
  507.         if (**ptr != ' ') {
  508.             if (curline >= LI-2){
  509.                 S0("PRESS ENTER");
  510.                 getline();
  511.                 cls();
  512.                 curline = 0;
  513.             }
  514.             fprintf(tfp, "%s\r\n", *ptr);
  515.             curline++;
  516.         } else {
  517.             S0("PRESS ENTER");
  518.             getline();
  519.             cls();
  520.             curline = 0;
  521.         }
  522.     }
  523.     show_bindings();
  524.     S0("PRESS ENTER");
  525.     getline();
  526.     cls();
  527.     status();
  528. }
  529.  
  530. s_set()
  531. {
  532.     struct kw *ptr;
  533.  
  534.     getword();
  535.  
  536.     if (word[0] == '\0' && !scriptflag){
  537.         status();
  538.         return;
  539.     } else if (word[0] == '\0'){
  540.         S1("SET keyword requires an argument");
  541.         eofflag++;
  542.         return;
  543.     }
  544.  
  545.     lc_word(word);
  546.  
  547.     for (ptr = setlist; ptr->keyword; ptr++)
  548.         if (!strcmp(ptr->keyword, word)){
  549.             (*ptr->rtn)();
  550.             return;
  551.         }
  552.  
  553.     sprintf(Msg,"Invalid SET keyword: %s", word);
  554.     S;
  555.     eofflag++;
  556. }
  557.  
  558. void
  559. set_onoff(flag)
  560. short *flag;
  561. {
  562.     char *ptr = strdup(word);
  563.  
  564.     uc_word(ptr);
  565.     getword();
  566.     lc_word(word);
  567.  
  568.     if (!strcmp(word, "on"))
  569.         *flag = TRUE;
  570.     else if (!strcmp(word, "off"))
  571.         *flag = FALSE;
  572.     else
  573.         sprintf(Msg,"Set '%s' value must be 'on' or 'off'",ptr),
  574.         S,
  575.         eofflag++;
  576.  
  577.     free(ptr);
  578. }
  579.  
  580. static
  581. SET_proto()
  582. {
  583.     if (statflag){
  584.         fprintf(tfp, statfmt, "proto", "Port set to", protocol);
  585.         return;
  586.     }
  587.  
  588.     getword();
  589.     uc_word(word);
  590.     if (word[0] == '\0')
  591.         S1("Set proto must be 7E2, 7O2, or 8N1");
  592.     else if (!xc_setproto(word))
  593.         sprintf(Msg,"Unsupported protocol %s",word),
  594.         S;
  595.     eofflag++;
  596.  
  597.     if (!scriptflag)
  598.         sprintf(Msg,"Port set to %s", protocol),
  599.         S;
  600. }
  601.  
  602. static
  603. SET_cr()
  604. {
  605.     if (statflag){
  606.         fprintf(tfp, statfmt, "cr", "Carriage Return Injection",
  607.             cr_add ? "ON" : "OFF");
  608.         return;
  609.     }
  610.  
  611.     set_onoff(&cr_add);
  612.  
  613.     if (!scriptflag)
  614.         sprintf(Msg,"Carriage Returns %s injected in B+ ASCII uploads",
  615.             cr_add ? "ARE" : "are NOT"),
  616.         S;
  617. }
  618.  
  619. static
  620. SET_xcape()
  621. {
  622.     if (statflag) {
  623.         fprintf(tfp, statfmt, "xcape", "Terminal Escape Character",
  624.                  unctrl(my_escape));
  625.         return;
  626.     }
  627.  
  628.     getword();
  629.     if (word[0] == '\0') {
  630.         show(1,"Set ESCAPE must specify escape character");
  631.         eofflag++;
  632.         return;
  633.     }
  634.  
  635.     my_escape = word[0];
  636.  
  637.     if (!scriptflag)
  638.         sprintf(Msg,"Terminal mode escape character set to '%s'",
  639.                 unctrl(my_escape)),
  640.         S;
  641. }
  642.  
  643. static
  644. SET_nl()
  645. {
  646.     if (statflag){
  647.         fprintf(tfp, statfmt, "nl", "Newline Translation",
  648.             nl2cr ? "ON" : "OFF");
  649.         return;
  650.     }
  651.  
  652.     set_onoff(&nl2cr);
  653.  
  654.     if (!scriptflag)
  655.         sprintf(Msg,"Newlines %s changed to Carriage Returns",
  656.             nl2cr ? "ARE" : "are NOT"),
  657.         S;
  658. }
  659.  
  660. static
  661. SET_cis()
  662. {
  663.     if (statflag){
  664.         fprintf(tfp, statfmt, "cis", "CIS <ENQ> Auto Download",
  665.             cismode ? "ON" : "OFF");
  666.         return;
  667.     }
  668.  
  669.     set_onoff(&cismode);
  670.  
  671.     if (!scriptflag)
  672.         sprintf(Msg,"CIS <ENQ> Auto Download is %s", cismode ? "ON" : "OFF"),
  673.         S;
  674. }
  675.  
  676. static
  677. SET_xon()
  678. {
  679.     if (statflag){
  680.         fprintf(tfp, statfmt, "xoff", "Terminal Mode XON/XOFF",
  681.             flowflag ? "ON" : "OFF");
  682.         return;
  683.     }
  684.  
  685.     set_onoff(&flowflag);
  686.     xc_setflow(flowflag);
  687.  
  688.     if (!scriptflag)
  689.         sprintf(Msg,"XON/XOFF Flow control is %s", flowflag ? "ON" : "OFF"),
  690.         S;
  691. }
  692.  
  693. static
  694. SET_bps()
  695. {
  696.     if (statflag){
  697.         char br[6];
  698.         sprintf(br, "%d", mrate(NIL(char)));
  699.         fprintf(tfp, statfmt, "bps", "Bits per Second", br);
  700.         return;
  701.     }
  702.  
  703.     getword();
  704.     if (word[0] == '\0')
  705.         S1("Set BPS (or BAUD) must have a rate");
  706.     else if (!mrate(word))
  707.         sprintf(Msg,"Unsupported bps rate %s",word),
  708.         S;
  709.     eofflag++;
  710.     if (!scriptflag)
  711.         sprintf(Msg,"Bits/Second set to %d",mrate(NIL(char))),
  712.         S;
  713. }
  714.  
  715. static
  716. SET_hdplx()
  717. {
  718.     if (statflag){
  719.         fprintf(tfp, statfmt, "hdplx", "Half-duplex Mode",
  720.             hdplxflag ? "ON" : "OFF");
  721.         return;
  722.     }
  723.  
  724.     set_onoff(&hdplxflag);
  725.  
  726.     if (!scriptflag)
  727.         sprintf(Msg,"Half-duplex Mode is %s", hdplxflag ? "ON" : "OFF"),
  728.         S;
  729. }
  730.  
  731. static
  732. SET_menu()
  733. {
  734.      if (statflag){
  735.          fprintf(tfp, statfmt, "menu", "Mini-menu mode",
  736.              menuflag ? "ON" : "OFF");
  737.          return;
  738.     }
  739.  
  740.      set_onoff(&menuflag);
  741.  
  742.      if (!scriptflag)
  743.          sprintf(Msg,"Mini-menu is %s shown", menuflag ? "" : "NOT"),
  744.         S;
  745. }
  746.  
  747. static
  748. SET_autocapt()
  749. {
  750.     if (statflag){
  751.         fprintf(tfp, statfmt, "auto", "Auto Capture",
  752.             autoflag ? "ON" : "OFF");
  753.         return;
  754.     }
  755.  
  756.     set_onoff(&autoflag);
  757.  
  758.     if (!scriptflag)
  759.         sprintf(Msg,"Auto Capture is %s", autoflag ? "ON" : "OFF"),
  760.         S;
  761. }
  762.  
  763. static
  764. SET_cfile()
  765. {
  766.     if (statflag){
  767.         fprintf(tfp, statfmt, "cfile", "Capture File", captfile);
  768.         return;
  769.     }
  770.  
  771.     getword();
  772.     if (word[0] == '\0'){
  773.         S1("Set CFILE must have file name");
  774.         eofflag++;
  775.         return;
  776.     }
  777.  
  778.     strcpy(captfile, word);
  779.  
  780.     if (!scriptflag)
  781.         sprintf(Msg,"Capture file set to '%s'",captfile),
  782.         S;
  783. }
  784.  
  785. static
  786. SET_pfile()
  787. {
  788.     if (statflag){
  789.         fprintf(tfp, statfmt, "pfile", "Phone Number File", phonefile);
  790.         return;
  791.     }
  792.  
  793.     getword();
  794.     if (word[0] == '\0'){
  795.         S1("Set PFILE must have file name");
  796.         eofflag++;
  797.         return;
  798.     }
  799.  
  800.     strcpy(phonefile, word);
  801.  
  802.     if (!scriptflag)
  803.         sprintf(Msg,"Phone number file set to '%s'",phonefile),
  804.         S;
  805. }
  806.  
  807. /*    Put and Take a file to/from a UNIX-type "cu" system. Unfortunately,
  808.     the stty command is one of those commands that always gets changed
  809.     with different UNIX systems, so you will get (at least) a file full of
  810.     ^M on the take command for systems later than V7 or work-alikes.
  811.  
  812.     Additionally, the Take command takes a bit too much!
  813.  
  814.     Fixed a lot of this: JPRadley 89/07/27
  815. */
  816.  
  817. static
  818. puttake()
  819. {
  820.     FILE *fp;
  821.     int i, Ch;
  822.     char c = word[1], fname[SM_BUFF], tname[SM_BUFF], wrkbuf[SM_BUFF];
  823.  
  824.     getword();
  825.  
  826.     signal(SIGINT,catch);
  827.     signal(SIGQUIT,catch);
  828.     xc_setflow(TRUE);
  829.     if (word[0] == '\0'){
  830.         sprintf(Msg,"Must give a filename with the '%%%c' option",c);
  831.         S;
  832.         return;
  833.     }
  834.  
  835.     strcpy(fname, word);
  836.     getword();
  837.     if (word[0] == '\0')
  838.         strcpy(tname, fname);
  839.     else
  840.         strcpy(tname, word);
  841.     switch (c){
  842.     case 'p':
  843.         if (!(fp = fopen(fname, "r")))
  844.             sprintf(Msg,"Can't open '%s'",fname),
  845.             S;
  846.         else {
  847.             fprintf(tfp, "\r\nPutting file '%s' to '%s' on remote UNIX\r\n",
  848.                 fname, tname);
  849.             sprintf(wrkbuf,
  850.                 "sh -c \"stty -echo;(cat >%s)||cat >/dev/null;stty echo\"\n",
  851.                     tname);
  852.             send_string(wrkbuf);    /* send command string to remote shell */
  853.             i = 64;
  854.             while ((Ch = getc(fp)) != EOF){
  855.                 if (++i > 64){        /* this prevents an overload on the */
  856.                     i = 0;            /* receiver's input buffer (64=kludge) */
  857.                     msecs((1+CBAUD-cbaud) * 100);
  858.                 }
  859.                 sendbyte(Ch);        /* send characters to cat command */
  860.             }
  861.             fclose(fp);
  862.             sendbyte(EOT);            /* send a ^D to cat */
  863.             purge();                /* get rid of whatever was sent back */
  864.             sendbyte('\n');
  865.         }
  866.         break;
  867.  
  868.     case 't':
  869.         strcpy(Name, tname);
  870.         if ((fp=QueryCreate(Resume_Not_Allowed))){
  871.             fprintf(tfp, "\r\nTaking file '%s' from remote UNIX to '%s'\r\n",
  872.                 fname, tname);    
  873.             purge();
  874.             sprintf(wrkbuf,
  875.                 "sh -c \"stty nl;test -r %s&&cat %s;echo %c;stty -nl\"\n",
  876.                     fname, fname, DLE);    /* if 'fname' has a DLE, we'll die */
  877.             send_string(wrkbuf);        /* send command to remote shell */
  878.             while (readbyte(3) != '\n')    /* discard up to the \n in wrkbuf */
  879.                 ;
  880.             while ((Ch=readbyte(0)) != -1    /* while chars are being sent */
  881.                      && Ch != DLE)            /* and we haven't seen our DLE */
  882.                 fputc(Ch,fp);
  883.             fclose(fp);
  884.         }
  885.         break;
  886.     }
  887.     xc_setflow(flowflag);
  888.     reterm = TRUE;
  889. }
  890.  
  891. s_exit()
  892. {
  893.     signal(SIGHUP,SIG_IGN);
  894.     signal(SIGINT,SIG_IGN);
  895.     signal(SIGQUIT,SIG_IGN);
  896.     signal(SIGTERM,SIG_IGN);
  897.  
  898.     mode(OLDMODE);
  899.     unlock_tty();
  900.  
  901.     exit(0);
  902. }
  903.