home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / mincom15.zip / minicom.c < prev    next >
C/C++ Source or Header  |  1993-10-16  |  17KB  |  756 lines

  1. /*
  2.  * This file is part of the Minicom Communications Program,
  3.  * written by Miquel van Smoorenburg 1991/1992/1993.
  4.  *
  5.  * minicom.c - main program.
  6.  */
  7. #include <sys/types.h>
  8. #if defined (_POSIX_SOURCE) || defined(_BSD43)
  9. #  include <unistd.h>
  10. #  include <stdlib.h>
  11. #else
  12.    char *getenv();
  13. #endif
  14. #undef NULL
  15. #include <signal.h>
  16. #include <fcntl.h>
  17. #include <setjmp.h>
  18. #include <sys/stat.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include <pwd.h>
  22. #include <ctype.h>
  23.  
  24. #include "window.h"
  25. #include "keyboard.h"
  26. #include "vt100.h"
  27. #define EXTERN
  28. #include "minicom.h"
  29. #include "configsym.h"
  30.  
  31. #ifndef _NSIG
  32. #  define _NSIG NSIG
  33. #endif
  34.  
  35. #define RESET 1
  36. #define NORESET 2
  37.  
  38. #ifdef _SVR2
  39. extern struct passwd *getpwuid();
  40. #endif
  41.  
  42. #ifdef DEBUG
  43. /* Show signals when debug is on. */
  44. static void signore(sig)
  45. int sig;
  46. {
  47.   if (stdwin != NIL_WIN)
  48.     werror("Got signal %d", sig);
  49.   else
  50.     printf("Got signal %d\r\n", sig);
  51. }
  52. #endif
  53.  
  54. /*
  55.  * Sub - menu's.
  56.  */
  57.  
  58. static char *c1[] = { "   Yes  ", "   No   ", CNULL };
  59. static char *c2[] = { "  Close ", " Pause  ", "  Exit  ", CNULL };
  60. static char *c3[] = { "  Close ", " Unpause", "  Exit  ", CNULL };
  61. static char *c7[] = { "   Yes  ", "   No   ", CNULL };
  62. static char *c8[] = { " vt100", " Minix", " Ansi", CNULL };
  63.  
  64. static void do_hang(askit)
  65. int askit;
  66. {
  67.   int c = 0;
  68.  
  69.   if (askit) c = ask("Hang-up line?", c7);
  70.   if (c == 0) hangup();
  71. }
  72.  
  73. /*
  74.  * We've got the hangup or term signal.
  75.  */
  76. static void hangsig(sig)
  77. int sig;
  78. {
  79. #if DEBUG
  80.   char txt[80];
  81. #else
  82.   char *txt = "\n"; /* "Thanks for using Minicom\n"; */
  83.               /* Allright Will, this is probably overdone :-) */
  84. #endif
  85.   
  86.   werror("Killed by signal %d !\n", sig);
  87.   if (capfp != (FILE *)0) fclose(capfp);
  88.   keyboard(KUNINSTALL, 0);
  89.   hangup();
  90.   modemreset();
  91.   leave(txt);
  92. }
  93.  
  94. /*
  95.  * Jump to a shell
  96.  */
  97. static void shjump()
  98. {
  99.   char *sh;
  100.   int pid;
  101.   int status;
  102.   int f;
  103.  
  104.   sh = getenv("SHELL");
  105.   if (sh == CNULL) {
  106.       werror("SHELL variable not set");
  107.       return;
  108.   }
  109.   if ((pid = fork()) == -1) {
  110.       werror("Out of memory: could not fork()");
  111.       return;
  112.   }
  113.   if (pid != 0) wleave();
  114.   if (pid == 0) {
  115.     for(f = 1; f < _NSIG; f++) signal(f, SIG_DFL);
  116.       for(f = 3; f < 20; f++) close(f);
  117.     setgid(real_gid);
  118.       setuid(real_uid);
  119.       execl(sh, sh, CNULL);
  120.       exit(1);
  121.   }
  122.   (void) m_wait(&status);
  123.   wreturn();
  124. }
  125.  
  126. #if HISTORY
  127. /* Get a line from either window or scroll back buffer. */
  128. static ELM *getline(w, no)
  129. WIN *w;
  130. int no;
  131. {
  132.   int i;
  133.  
  134.   if (no < us->histlines) {
  135.     i = no + us->histline - 1;
  136.     if (i >= us->histlines) i -= us->histlines;
  137.     if (i < 0) i = us->histlines - 1;
  138.     return(us->histbuf + (i * us->xs));
  139.   }
  140.  
  141.   no -= us->histlines;
  142.   if (no >= w->ys) no = w->ys - 1;
  143.   return(w->map + (no * us->xs));
  144. }
  145.  
  146. /* Redraw the window. */
  147. static void drawhist(w, y, r)
  148. WIN *w;
  149. int y;
  150. int r;
  151. {
  152.   int f;
  153.  
  154.   w->direct = 0;
  155.   for(f = 0; f < w->ys; f++)
  156.     wdrawelm(w, f, getline(w, y++));
  157.   if (r) wredraw(w, 1);
  158.   w->direct = 1;
  159. }
  160.  
  161. /* Scroll back */
  162. static void scrollback()
  163. {
  164.   int y;
  165.   WIN *b_us, *b_st;
  166.   int c;
  167.   char hline[128];
  168.  
  169.   /* Find out how big a window we must open. */
  170.   y = us->y2;
  171.   if (st == (WIN *)0 || (st && tempst)) y--;
  172.  
  173.   /* Open a window. */ 
  174.   b_us = wopen(0, 0, us->x2, y, 0, us->attr, COLFG(us->color),
  175.         COLBG(us->color), 0, 0, 0);
  176.   wcursor(b_us, CNONE);
  177.  
  178.   /* Open a help line window. */
  179.   b_st = wopen(0, y+1, us->x2, y+1, 0, A_REVERSE, WHITE, BLACK, 0, 0, 0);
  180.   b_st->doscroll = 0;
  181.   b_st->wrap = 0;
  182.  
  183.   /* Make sure help line is as wide as window. */
  184.   strcpy(hline, "   SCROLL MODE    U=up D=down F=page-forward B=page-backward ESC=exit                    ");
  185.   if (b_st->xs < 127) hline[b_st->xs] = 0;
  186.   wprintf(b_st, hline);
  187.   wredraw(b_st, 1);
  188.   wflush();
  189.  
  190.   /* And do the job. */
  191.   y = us->histlines;
  192.  
  193.   drawhist(b_us, y, 0);
  194.  
  195.   while((c = getch()) != K_ESC) {
  196.     switch(c) {
  197.       case 'u':
  198.       case K_UP:
  199.         if (y <= 0) break;
  200.         y--;
  201.         wscroll(b_us, S_DOWN);
  202.         wdrawelm(b_us, 0, getline(b_us, y));
  203.         wflush();
  204.         break;
  205.       case 'd':
  206.       case K_DN:
  207.         if (y >= us->histlines) break;
  208.         y++;
  209.         wscroll(b_us, S_UP);
  210.         wdrawelm(b_us, b_us->ys - 1, getline(b_us, y + b_us->ys - 1));
  211.         wflush();
  212.         break;
  213.       case 'b':
  214.       case K_PGUP:
  215.         if (y <= 0) break;
  216.         y -= b_us->ys;
  217.         if (y < 0) y = 0;
  218.         drawhist(b_us, y, 1);
  219.         break;
  220.       case 'f':
  221.       case K_PGDN:
  222.         if (y >= us->histlines) break;
  223.         y += b_us->ys;
  224.         if (y > us->histlines) y = us->histlines;
  225.         drawhist(b_us, y, 1);
  226.         break;
  227.     }
  228.   }
  229.   /* Cleanup. */
  230.   wclose(b_us, y == us->histlines ? 0 : 1);
  231.   wclose(b_st, 1);
  232.   wlocate(us, us->curx, us->cury);
  233.   wflush();
  234. }
  235. #endif
  236.  
  237. #ifdef SIGWINCH
  238. /* The window size has changed. Re-initialize. */
  239. static void change_size(sig)
  240. int sig;
  241. {
  242.   (void)sig;
  243.   size_changed = 1;
  244.   signal(SIGWINCH, change_size);
  245. }
  246. #endif
  247.  
  248. /*
  249.  * Read a word from strings 's' and advance pointer.
  250.  */
  251. static char *getword(s)
  252. char **s;
  253. {
  254.   char *begin;
  255.  
  256.   /* Skip space */
  257.   while(**s == ' ' || **s == '\t') (*s)++;
  258.   /* End of line? */
  259.   if (**s == '\0' || **s == '\n') return((char *)0);
  260.   
  261.   begin = *s;
  262.   /* Skip word */
  263.   while(**s != ' ' && **s != '\t' && **s != '\n' && **s) (*s)++;
  264.   /* End word with '\0' */
  265.   if (**s) {
  266.       **s = 0;
  267.       (*s)++;
  268.   }
  269.   return(begin);
  270. }
  271.  
  272. static char *bletch = 
  273.   "Usage: minicom [-soml] [-c on|off] [-a on|off] [-t TERM] [configuration]\n";
  274.  
  275. static void usage(env_args, optind, mc)
  276. int env_args, optind;
  277. char *mc;
  278. {
  279.   if (env_args >= optind && mc)
  280.       fprintf(stderr, "Wrong option in environment MINICOM=%s\n", mc);
  281.   fprintf(stderr, bletch);
  282.   fprintf(stderr, "Type \"minicom -h\" for help.\n");
  283.   exit(1);
  284. }
  285.  
  286. /* Give some help information */
  287. static void helpthem()
  288. {
  289.   char *mc = getenv("MINICOM");
  290.  
  291.   printf("\n%s", Version);
  292. #ifdef __DATE__
  293.   printf(" (compiled %s)", __DATE__);
  294. #endif
  295.   printf("\n\n%s\n", bletch);
  296.   printf("  -s             : enter setup mode (only as root)\n");
  297.   printf("  -o             : do not initialize modem & lockfiles at startup\n");
  298.   printf("  -m             : use meta or alt key for commands\n");
  299.   printf("  -l             : literal ; do not translate characters < 32 or > 127\n");
  300.   printf("  -c [on | off]  : ANSI style color usage on or off\n");
  301.   printf("  -a [on | off]  : use reverse or highlight attributes on or off\n");
  302.   printf("  -t term        : override TERM environment variable\n");
  303.   printf("  configuration  : configuration file to use\n\n");
  304.   printf("These options can also be specified in the MINICOM environment variable.\n");
  305.   printf("This variable is currently %s%s.\n", mc ? "set to " : "unset",
  306.     mc ? mc : "");
  307.   printf("\nThe LIBDIR to find the configuration files and the\n");
  308.   printf("access file minicom.users is compiled as %s.\n\n", LIBDIR);
  309. }
  310.  
  311. int main(argc, argv)
  312. int argc;
  313. char **argv;
  314. {
  315.   int c;            /* Command character */
  316.   int quit = 0;            /* 'q' or 'x' pressed */
  317.   char *s, *bufp;        /* Scratch pointers */
  318.   int dosetup = 0, doinit = 1;    /* -o and -s options */
  319.   char buf[80];            /* Keyboard input buffer */
  320.   char capname[128];        /* Name of capture file */
  321.   struct passwd *pwd;        /* To look up user name */
  322.   int userok = 0;        /* Scratch variables */
  323.   FILE *fp;            /* Scratch file pointer */
  324.   char userfile[256];        /* Locate user file */
  325.   char *use_port;        /* Name of initialization file */
  326.   char *args[20];        /* New argv pointer */
  327.   int argk = 1;            /* New argc */
  328.   extern int getopt(), optind;
  329.   extern char *optarg;        /* From getopt (3) package */
  330.   char *mc;            /* For 'MINICOM' env. variable */
  331.   int env_args;            /* Number of args in env. variable */
  332.  
  333.   /* Initialize global variables */
  334.   portfd = -1;
  335.   capfp = (FILE *)NULL;
  336.   docap = 0;
  337.   online = linewrap = -1;
  338.   stdattr = A_NORMAL;
  339.   us = NIL_WIN;
  340.   addlf = 0;
  341.   local_echo = 0;
  342.   strcpy(capname, "minicom.cap");
  343.   lockfile[0] = 0;
  344.   tempst = 0;
  345.   st = NIL_WIN;
  346.   us = NIL_WIN;
  347.   bogus_dcd = 0;
  348.   usecolor = 0;
  349.   literal = 0;
  350.   useattr = 1;
  351.   strcpy(termtype, getenv("TERM") ? getenv("TERM") : "dumb");
  352.   stdattr = A_NORMAL;
  353.   use_port = "dfl";
  354.   alt_override = 0;
  355.   scr_name[0] = 0;
  356.   scr_user[0] = 0;
  357.   scr_passwd[0] = 0;
  358.   dial_name = (char *)NULL;
  359.   dial_number = (char *)NULL;
  360.   size_changed = 0;
  361.   escape = 1;
  362. #ifndef DEBUG
  363.   real_uid = getuid();
  364.   real_gid = getgid();
  365. #else
  366.   real_uid = 0;
  367.   real_gid = 0;
  368. #endif
  369.  
  370.   /* Before processing the options, first add options
  371.    * from the environment variable 'MINICOM'.
  372.    */
  373.   args[0] = "minicom";
  374.   if ((mc = getenv("MINICOM")) != CNULL) {
  375.      strncpy(buf, mc, 80);
  376.      bufp = buf;
  377.      buf[79] = 0;
  378.      while(isspace(*bufp)) bufp++;
  379.      while(*bufp) {
  380.          for(s = bufp; !isspace(*bufp) && *bufp; bufp++)
  381.              ;
  382.          args[argk++] = s;
  383.          while(isspace(*bufp)) *bufp++ = 0;
  384.      }
  385.   }
  386.   env_args = argk;
  387.  
  388.   /* Add command - line options */
  389.   for(c = 1; c < argc; c++) args[argk++] = argv[c];
  390.   args[argk] = CNULL;
  391.  
  392.   do {
  393.     /* Process options with getopt */
  394.     while((c = getopt(argk, args, "hlsomc:a:t:")) != EOF) switch(c) {
  395.           case 's': /* setup */
  396.               if (real_uid != 0) {
  397.         fprintf(stderr, "minicom: -s switch needs root privilige\n");
  398.                 exit(1);
  399.             }
  400.               dosetup = 1;
  401.               break;
  402.         case 'h':
  403.             helpthem();
  404.             exit(1);
  405.             break;
  406.           case 'm': /* metakey */
  407.               alt_override++;
  408.               break;
  409.         case 'l': /* Literal ANSI chars */
  410.             literal++;
  411.             break;
  412.         case 't': /* Terminal type */
  413.             strcpy(termtype, optarg);
  414.             break;
  415.           case 'o': /* DON'T initialize */
  416.               doinit = 0;
  417.               break;
  418.           case 'c': /* Color on/off */
  419.               if (strcmp("on", optarg) == 0) {
  420.                   usecolor = 1;
  421.                   stdattr = A_BOLD;
  422.                   break;
  423.               }
  424.               if (strcmp("off", optarg) == 0) {
  425.                   usecolor = 0;
  426.                   stdattr = A_NORMAL;
  427.                   break;
  428.               }
  429.               usage(env_args, optind - 1, mc);
  430.               break;
  431.           case 'a': /* Attributes on/off */
  432.               if (strcmp("on", optarg) == 0) {
  433.                   useattr = 1;
  434.                   break;
  435.               }
  436.               if (strcmp("off", optarg) == 0) {
  437.                   useattr = 0;
  438.                   break;
  439.               }
  440.               usage(env_args, optind - 1, mc);
  441.               break;
  442.           default:
  443.               usage(env_args, optind, mc);
  444.               break;
  445.       }
  446.  
  447.       /* Now, get portname if mentioned. Stop at end or '-'. */
  448.      while(optind < argk && args[optind][0] != '-')
  449.           use_port = args[optind++];
  450.  
  451.     /* Loop again if more options */
  452.   } while(optind < argk);
  453.  
  454.   if (real_uid == 0 && dosetup == 0) {
  455.     fprintf(stderr, "%s%s%s",
  456.   "minicom: WARNING: please don't run minicom as root when not maintaining\n",
  457.   "                  it (with the -s switch) since all changes to the\n",
  458.   "                  configuration will be GLOBAL !.\n");
  459.     sleep(5);
  460.   }
  461.  
  462.   /* Avoid fraude ! */    
  463.   for(s = use_port; *s; s++) if (*s == '/') *s = '_';
  464.   sprintf(parfile, "%s/minirc.%s", LIBDIR, use_port);
  465.  
  466.   /* Get password file information of this user. */
  467.   if ((pwd = getpwuid(real_uid)) == (struct passwd *)0) {
  468.       fprintf(stderr, "You don't exist. Go away.\n");
  469.       exit(1);
  470.   }
  471.  
  472.   /* Remember home directory and username. */
  473.   if ((s = getenv("HOME")) == CNULL)
  474.     strcpy(homedir, pwd->pw_dir);
  475.   else
  476.     strcpy(homedir, s);
  477.   strcpy(username, pwd->pw_name);
  478.  
  479.   /* Get personal parameter file */
  480.   sprintf(pparfile, "%s/.minirc.%s", homedir, use_port);
  481.  
  482.   /* Check this user in the USERFILE */
  483.   if (real_uid != 0) {
  484.       sprintf(userfile, "%s/minicom.users", LIBDIR);
  485.     if ((fp = fopen(userfile, "r")) != (FILE *)0) {
  486.         while(fgets(buf, 70, fp) != CNULL && !userok) {
  487.             /* Read first word */
  488.             bufp = buf;
  489.             s = getword(&bufp);
  490.             /* See if the "use_port" matches */
  491.             if (s && !strcmp(pwd->pw_name, s)) {
  492.                 if ((s = getword(&bufp)) == CNULL)
  493.                     userok = 1;
  494.                 else do {
  495.                     if (!strcmp(s, use_port)) {
  496.                         userok = 1;
  497.                         break;
  498.                     }
  499.                 } while((s = getword(&bufp)) != CNULL);
  500.             }
  501.         }
  502.         fclose(fp);
  503.         if (!userok) {
  504.             fprintf(stderr,
  505.    "Sorry %s. You are not allowed to use configuration %s.\n",
  506.                 pwd->pw_name, use_port);
  507.             exit(1);
  508.         }
  509.     }
  510.   }
  511.   buf[0] = 0;
  512.  
  513.   read_parms();
  514.   stdwin = NIL_WIN; /* It better be! */
  515.   if (!dosetup && open_term(doinit) < 0) exit(1);
  516.  
  517. #ifdef _SECURE
  518.   /* After open /dev/tty..., we can run setgid uucp instead of setuid root.
  519.    * We have to run setgid uucp to be able to create lockfiles, and
  520.    * to execute the callin and callout programs.
  521.    * To do this, minicom should be installed setuid root/setgid uucp.
  522.    */
  523.   if (real_uid != 0 && geteuid() == 0 && getegid() != real_gid)
  524.       setuid(real_uid);
  525. #endif
  526.  
  527.   mc_setenv("TERM", termtype);
  528.  
  529.   if (win_init(SFG, SBG, A_NORMAL) < 0) leave("");
  530.  
  531.   if (COLS < 40 || LINES < 10) {
  532.       leave("Sorry. Your screen is too small.\n");
  533.   }
  534.  
  535.   if (dosetup) {
  536.       if (config(1)) {
  537.           wclose(stdwin, 1);
  538.           exit(0);
  539.       }
  540.       if (open_term(doinit) < 0) exit(1);
  541.   }
  542.  
  543.   /* Signal handling */
  544.   for(c = 1; c <= _NSIG; c++) {
  545. #ifdef SIGCLD /* Better not mess with those */
  546.     if (c == SIGCLD) continue;
  547. #endif
  548. #ifdef SIGCHLD
  549.     if (c == SIGCHLD) continue;
  550. #endif
  551.     signal(c, hangsig);
  552.   }
  553.  
  554.   signal(SIGHUP, SIG_IGN);
  555.   signal(SIGINT, SIG_IGN);
  556.   signal(SIGQUIT, SIG_IGN);
  557.   signal(SIGPIPE, SIG_IGN);
  558.  
  559. #ifdef SIGTSTP
  560.   signal(SIGTSTP, SIG_IGN);
  561.   signal(SIGTTIN, SIG_IGN);
  562.   signal(SIGTTOU, SIG_IGN);
  563. #endif
  564. #ifdef SIGTINT
  565.     signal(SIGTINT, SIG_IGN);
  566. #endif
  567. #ifdef SIGWINCH
  568.   signal(SIGWINCH, change_size);
  569. #endif
  570.  
  571. #if DEBUG
  572.   for(c = 1; c < _NSIG; c++) {
  573.     if (c == SIGTERM) continue; /* Saviour when hung */
  574.     signal(c, signore);
  575.   }
  576. #endif
  577.  
  578.   keyboard(KINSTALL, 0);
  579.  
  580.   if (strcmp(P_BACKSPACE, "BS") != 0) 
  581.     keyboard(KSETBS, P_BACKSPACE[0] == 'B' ? 8 : 127);
  582.   if (alt_override)
  583.     keyboard(KSETESC, 128);
  584.   else if (strcmp(P_ESCAPE, "^A") != 0)
  585.     keyboard(KSETESC, P_ESCAPE[0] == '^' ? P_ESCAPE[1] & 31 : 128);
  586.  
  587.   st = NIL_WIN;
  588.   us = NIL_WIN;
  589.  
  590.   init_emul(VT100);
  591.  
  592.   if (doinit) modeminit();
  593.  
  594.   wputs(us, "\nMinicom 1.5 Beta Copyright (c) 1993 Miquel van Smoorenburg\r\n");
  595.   wprintf(us, "\nPress %sZ for help on special keys\r\n\n", esc_key());
  596.  
  597.   readdialdir();
  598.  
  599.   /* The main loop calls do_terminal and gets a function key back. */
  600.   do {
  601.     c = do_terminal();
  602. dirty_goto:    
  603.     switch(c + 32 *(c >= 'A' && c <= 'Z')) {
  604.         case 'a': /* Add line feed */
  605.             addlf = !addlf;
  606.             vt_set(addlf, -1, NULL, -1, -1, -1, -1);
  607.             s = addlf ? "Add linefeed ON" : "Add linefeed OFF";
  608.             werror(s);
  609.             break;
  610. #if _SELECT
  611.         case 'e': /* Local echo on/off. */
  612.             local_echo = !local_echo;
  613.             vt_set(-1, -1, NULL, -1, -1, local_echo, -1);
  614.             s = local_echo ? "Local echo ON" : "Local echo OFF";
  615.             werror(s);
  616.             break;
  617. #endif
  618.         case 'z': /* Help */
  619.             c = help();
  620.             if (c != 'z') goto dirty_goto;
  621.             break;
  622.         case 'c': /* Clear screen */
  623.             winclr(us);
  624.             break;    
  625.         case 'f': /* Send break */
  626.             sendbreak();
  627.             break;
  628. #if HISTORY
  629.         case 'b': /* Scroll back */
  630.             scrollback();
  631.             break;
  632. #endif
  633.         case 'm': /* Initialize modem */
  634.             modeminit();
  635.             break;    
  636.         case 'q': /* Exit without resetting */
  637.             c = ask("Leave without reset?", c1);
  638.             if (c == 0) quit = NORESET;
  639.             break;
  640.         case 'x': /* Exit Minicom */
  641.             c = ask("Leave Minicom?", c1);
  642.             if (c == 0) {
  643.                 quit = RESET;
  644.                 if(online >= 0)
  645.                     do_hang(0);
  646.                 modemreset();     
  647.             }
  648.             break;
  649.         case 'l': /* Capture file */
  650.             if (capfp == (FILE *)0 && !docap) {
  651.                 s = input("Capture to which file? ", capname);
  652.                 if (s == CNULL || *s == 0) break;
  653.                 if ((c = waccess(s)) < 0 ||
  654.                     (capfp = fopen(s, "a")) == (FILE *)NULL) {
  655.                     werror("Cannot open capture file");
  656.                     break;
  657.                 } else if (c == A_OK_NOTEXIST)
  658. #ifndef DEBUG
  659. #ifndef HAS_FCHOWN
  660.                         /* FIXME: should use fchown */
  661.                         chown(s, real_uid, real_gid);
  662. #else
  663.                         fchown(fileno(capfp), real_uid,
  664.                                 real_gid);
  665. #endif
  666. #endif
  667.                 docap = 1;
  668.             } else if (capfp != (FILE *)0 && !docap) {
  669.                 c = ask("Capture file", c3);
  670.                 if (c == 0) {
  671.                     fclose(capfp);
  672.                     capfp = (FILE *)NULL;
  673.                     docap = 0;
  674.                 }
  675.                 if (c == 1) docap = 1;
  676.             } else if (capfp != (FILE *)0 && docap) {
  677.                 c = ask("Capture file", c2);
  678.                 if (c == 0) {
  679.                     fclose(capfp);
  680.                     capfp = (FILE *)NULL;
  681.                     docap = 0;
  682.                 }
  683.                 if (c == 1) docap = 0;
  684.             }
  685.             vt_set(addlf, linewrap, capfp, docap, -1, -1, -1);
  686.             break;
  687.         case 'p': /* Set parameters */
  688.             get_bbp(P_BAUDRATE, P_BITS, P_PARITY);
  689.             m_setparms(portfd, P_BAUDRATE, P_PARITY, P_BITS);
  690.             if (st != NIL_WIN) mode_status();
  691.             quit = 0;
  692.             break;
  693.         case 'k': /* Run kermit */
  694.             kermit();
  695.             break;
  696.         case 'h': /* Hang up */
  697.             do_hang(1);
  698.             break;
  699.         case 'd': /* Dial */
  700.             dialdir();
  701.             break;        
  702.         case 't': /* Terminal emulation */
  703.             c = wselect(13, 3, c8, NIL_FUNLIST,
  704.                 "Emulation", stdattr, MFG, MBG);
  705.             if (c > 0) init_emul(c);
  706.             break;
  707.         case 'w': /* Line wrap on-off */    
  708.             if (linewrap < 0) linewrap = 0;
  709.             linewrap = !linewrap;
  710.             vt_set(addlf, linewrap, capfp, docap, -1, -1, -1);
  711.             s = linewrap ? "Linewrap ON" : "Linewrap OFF";
  712.             werror(s);
  713.             break;
  714.         case 'o': /* Configure Minicom */
  715.             (void) config(0);
  716.             break;
  717.         case 's': /* Upload */
  718.             updown('U');
  719.             break;
  720.         case 'r': /* Download */
  721.             updown('D');
  722.             break;    
  723.         case 'j': /* Jump to a shell */
  724.             shjump();
  725.             break;
  726.         case 'g': /* Run script */    
  727.             runscript(1, "", "", "");
  728.             break;
  729.         case 'i': /* Re-init, re-open portfd. */
  730.             cursormode = (cursormode == NORMAL) ? APPL : NORMAL;
  731.             keyboard(cursormode == NORMAL ? KCURST : KCURAPP, 0);
  732.             if (st) curs_status();
  733.             break;
  734.         default:
  735.             break;
  736.     }
  737.   } while(!quit);
  738.  
  739.   /* Reset parameters */
  740.   if (quit != NORESET)
  741.     m_restorestate(portfd);
  742.   else
  743.     m_hupcl(portfd, 0);
  744.   if (capfp != (FILE *)0) fclose(capfp);
  745.   wclose(us, 0);
  746.   wclose(st, 0);
  747.   wclose(stdwin, 1);
  748.   keyboard(KUNINSTALL, 0);
  749.   if (lockfile[0]) unlink(lockfile);
  750.   close(portfd);
  751.   chown(P_PORT, portuid, portgid);
  752.   if (quit != NORESET && P_CALLIN[0])
  753.     (void) fastsystem(P_CALLIN, CNULL, CNULL, CNULL);
  754.   return(0);
  755. }
  756.