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

  1. /*
  2.  * This file is part of the Minicom Communications Program,
  3.  * written by Miquel van Smoorenburg 1991/1992/1993.
  4.  */
  5. #include <sys/types.h>
  6. #if defined (_POSIX_SOURCE) || defined(_BSD43)
  7. #  include <stdlib.h>
  8. #  include <unistd.h>
  9. #else
  10.   char *getenv();
  11. #endif
  12. #undef NULL
  13. #include <stdio.h>
  14. #include <signal.h>
  15. #include <setjmp.h>
  16. #include <fcntl.h>
  17. #include <ctype.h>
  18. #include <string.h>
  19. #include "window.h"
  20. #include "minicom.h"
  21. #include "configsym.h"
  22. #include "vt100.h"
  23.  
  24. #ifndef _NSIG
  25. # define _NSIG NSIG
  26. #endif
  27.  
  28. static int udpid;
  29.  
  30. /*
  31.  * Change to a directory.
  32.  */
  33. static int mcd(dir)
  34. char *dir;
  35. {
  36.   char buf[256];
  37.   char err[50];
  38.   static char odir[256];
  39.   static int init = 0;
  40.  
  41.   if (!init) {
  42.       if (*dir == 0) return(0);
  43.       init = 1;
  44. #ifdef _COH3
  45.     getwd(odir);
  46. #else
  47.       getcwd(odir, 255);
  48. #endif
  49.   }
  50.   if (*dir == 0) {
  51.       chdir(odir);
  52.       return(0);
  53.   }
  54.   
  55.   if(*dir != '/') {
  56.       sprintf(buf, "%s/%s", homedir, dir);
  57.       dir = buf;
  58.   }
  59.   if (chdir(dir) < 0) {
  60.       sprintf(err, "Cannot chdir to %.30s", dir);
  61.       werror(err);
  62.       return(-1);
  63.   }
  64.   return(0);
  65. }
  66.  
  67. /*
  68.  * Catch the CTRL-C signal.
  69.  */
  70. /*ARGSUSED*/
  71. static void udcatch(dummy)
  72. int dummy;
  73. {
  74.   signal(SIGINT, udcatch);
  75.   if (udpid) kill(udpid, SIGKILL);
  76. }
  77.  
  78. /*
  79.  * Translate %b to the current baudrate, and
  80.  *           %l to the current tty port.
  81.  */
  82. static char *translate(s)
  83. char *s;
  84. {
  85.   static char buf[128];
  86.   int i;
  87.  
  88.   for(i = 0; *s && i < 127; i++, s++) {
  89.       if (*s != '%') {
  90.           buf[i] = *s;
  91.           continue;
  92.       }
  93.       switch(*++s) {
  94.           case 'l':
  95.               strcpy(buf + i, P_PORT);
  96.               i += strlen(P_PORT) - 1;
  97.               break;
  98.           case 'b':
  99.               strcpy(buf + i, P_BAUDRATE);
  100.               i += strlen(P_BAUDRATE) - 1;
  101.               break;
  102.           default:
  103.               buf[i++] = '%';
  104.               buf[i] = *s;
  105.               break;
  106.       }
  107.   }
  108.   buf[i] = 0;
  109.   return(buf);
  110. }
  111.  
  112. /*
  113.  * Choose from numerous up and download protocols!
  114.  */
  115. void updown(what)
  116. int what;
  117. {
  118.   char *name[13];
  119.   int idx[13];
  120.   int r, f, g = 0;
  121.   char *t = what == 'U' ? "Upload" : "Download";
  122.   char buf[128];
  123.   char title[64];
  124.   char *s ="";
  125.   int pipefd[2];
  126.   int n, status;
  127.   char cmdline[128];
  128.   WIN *win = (WIN *)NULL;
  129. #if defined (__linux__) && defined(_SELECT)
  130.   extern void music(void);
  131. #endif
  132.  
  133.   if (mcd(what == 'U' ? P_UPDIR : P_DOWNDIR) < 0)
  134.       return;
  135.  
  136.   for(f = 0; f < 12; f++) {
  137.       if (P_PNAME(f)[0] && P_PUD(f) == what) {
  138.           name[g] = P_PNAME(f);
  139.           idx[g++] = f;
  140.       }
  141.   }
  142.   name[g] = CNULL;
  143.   if (g == 0) return;
  144.  
  145.   r = wselect(30, 7, name, NIL_FUNLIST, t, stdattr, MFG, MBG) - 1;
  146.   if (r < 0) return;
  147.  
  148.   g = idx[r];
  149.   buf[0] = 0;
  150.  
  151.   if (P_PNN(g) == 'Y') {
  152.       s = input("Please enter file names", buf);
  153.       if (s == CNULL || *s == 0) return;
  154.   }
  155.  
  156.   sprintf(cmdline, "%s %s", P_PPROG(g), s);
  157.  
  158.   if (P_PFULL(g) == 'N') {
  159.     win = wopen(10, 7, 70, 13, BSINGLE, stdattr, MFG, MBG, 1, 0, 1);
  160.     sprintf(title, "%.30s %s - Press CTRL-C to quit", P_PNAME(g),
  161.         what == 'U' ? "upload" : "download");
  162.     wtitle(win, TMID, title);
  163.     pipe(pipefd);
  164.   } else
  165.     wleave();
  166.  
  167.   switch(udpid = fork()) {
  168.       case -1:
  169.           werror("Out of memory: could not fork()");
  170.         if (win) {
  171.               close(pipefd[0]);
  172.               close(pipefd[1]);
  173.               wclose(win, 1);
  174.         } else
  175.             wreturn();
  176.           (void) mcd("");
  177.           return;
  178.       case 0: /* Child */
  179.         if (P_PIORED(g) == 'Y') {
  180.               dup2(portfd, 0);
  181.               dup2(portfd, 1);
  182.         }
  183.         if (win) {
  184.               dup2(pipefd[1], 2);
  185.               close(pipefd[0]);
  186.               if (pipefd[1] != 2) close(pipefd[1]);
  187.           }
  188.           for(n = 1; n < _NSIG; n++) signal(n, SIG_DFL);
  189.           
  190.         setgid(real_gid);
  191.           setuid(real_uid);
  192.           (void) fastexec(translate(cmdline));
  193.           exit(1);
  194.       default: /* Parent */
  195.           break;
  196.   }
  197.   if (win) {
  198.     (void) setcbreak(1); /* Cbreak, no echo. */
  199.     enab_sig(1);           /* But enable SIGINT */
  200.   }
  201.   signal(SIGINT, udcatch);
  202.   if (P_PIORED(g) == 'Y') {
  203.     close(pipefd[1]);
  204.     while((n = read(pipefd[0], buf, 80)) > 0) {
  205.           buf[n] = '\0';
  206.           wputs(win, buf);
  207.     }
  208.   }
  209.   while( udpid != m_wait(&status) );
  210.   if (win) {
  211.     enab_sig(0);
  212.     signal(SIGINT, SIG_IGN);
  213.   }
  214.  
  215.   if (win == (WIN *)0) wreturn();
  216.  
  217.   /* If we got interrupted, status != 0 */
  218.   if (win && (status & 0xFF00) == 0) {
  219. #if defined (__linux__) && defined(_SELECT)
  220.     wprintf(win, "\n READY : press any key to continue..");
  221.     music();
  222. #else
  223.     sleep(1);
  224. #endif
  225.   }
  226.   if (win) wclose(win, 1);
  227.   m_flush(portfd);
  228.   m_setparms(portfd, P_BAUDRATE, P_PARITY, P_BITS);
  229.   (void) setcbreak(2); /* Raw, no echo. */
  230.   close(pipefd[0]);
  231.   (void) mcd("");
  232. }
  233.  
  234. /*
  235.  * Run kermit. Used to do this in the main window, but newer
  236.  * versions of kermit are too intelligent and just want a tty
  237.  * for themselves or they won't function ok. Shame.
  238.  */
  239. void kermit()
  240. {
  241.   int status;
  242.   int pid, n;
  243.   char buf[81];
  244.   int fd;
  245.  
  246.   /* Clear screen, set keyboard modes etc. */
  247.   wleave();
  248.  
  249.   switch(pid = fork()) {
  250.       case -1:
  251.         wreturn();
  252.           werror("Out of memory: could not fork()");
  253.           return;
  254.       case 0: /* Child */
  255.           /* Remove lockfile */
  256.           if (lockfile[0]) unlink(lockfile);
  257.         setgid(real_gid);
  258.         setuid(real_uid);
  259.  
  260.           for(n = 0; n < _NSIG; n++) signal(n, SIG_DFL);
  261.  
  262.           (void) fastexec(translate(P_KERMIT));
  263.           exit(1);
  264.       default: /* Parent */
  265.           break;
  266.   }
  267.  
  268.   (void) m_wait(&status);
  269.  
  270.   /* Restore screen and keyboard modes */
  271.   wreturn();
  272.  
  273.   /* Re-create lockfile */
  274.   if (lockfile[0]) 
  275.       /* Create lockfile compatible with UUCP-1.2 */
  276.       if ((fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0) {
  277.           werror("Cannot re-create lockfile!");
  278.       } else {
  279.           sprintf(buf, "%05d minicom %.20s", getpid(), username);
  280.           write(fd, buf, strlen(buf));
  281.           close(fd);
  282.       }
  283.   m_flush(portfd);
  284. }
  285.  
  286. /* ============ Here begins the setenv function ============= */
  287. /*
  288.  * Compare two strings up to '='
  289.  */
  290. static int varcmp(s1, s2)
  291. char *s1, *s2;
  292. {
  293.   while(*s1 && *s2) {
  294.       if (*s1 == '=' && *s2 == '=') return(1);
  295.       if (*s1++ != *s2++) return(0);
  296.   }
  297.   return(1);
  298. }
  299.  
  300. /*
  301.  * Generate a name=value string.
  302.  */
  303. static char *makenv(name, value)
  304. char *name, *value;
  305. {
  306.   char *p;
  307.   
  308.   if ((p = (char *)malloc(strlen(name) + strlen(value) + 3)) == CNULL)
  309.     return(p);
  310.   sprintf(p, "%s=%s", name, value);
  311.   return(p);
  312. }
  313.  
  314. /*
  315.  * Set a environment variable. 
  316.  */
  317. int mc_setenv(name, value)
  318. char *name, *value;
  319. {
  320.   static int init = 0;
  321.   extern char **environ;
  322.   char *p, **e, **newe;
  323.   int count = 0;
  324.  
  325.   if ((p = makenv(name, value)) == CNULL) return(-1);
  326.  
  327.   for(e = environ; *e; e++) {
  328.       count++;
  329.       if(varcmp(name, *e)) {
  330.           *e = p;
  331.           return(0);
  332.       }
  333.   }
  334.   count += 2;
  335.   if ((newe = (char **)malloc(sizeof(char *) * count)) == (char **)0) {
  336.       free(p);
  337.       return(-1);
  338.   }
  339.   memcpy((char *)newe, (char *)environ , (int) (count * sizeof(char *)));
  340.   if (init) free((char *)environ);
  341.   init = 1;
  342.   environ = newe;
  343.   for(e = environ; *e; e++)
  344.       ;
  345.   *e++ = p;
  346.   *e = CNULL;
  347.   return(0);
  348. }
  349.  
  350. /* ============ This is the end of the setenv function ============= */
  351.  
  352. /*
  353.  * Run an external script.
  354.  * ask = 1 if first ask for confirmation.
  355.  * s = scriptname, l=loginname, p=password.
  356.  */
  357. void runscript(ask, s, l, p)
  358. int ask;
  359. char *s, *l, *p;
  360. {
  361.   int status;
  362.   int n;
  363.   int pipefd[2];
  364.   char buf[81];
  365.   char cmdline[128];
  366.   char *ptr;
  367.   WIN *w;
  368.   int done = 0;
  369.   char *msg = "Same as last";
  370.  
  371.   if (ask) {
  372.     w = wopen(10, 5, 70, 10, BDOUBLE, stdattr, MFG, MBG, 0, 0, 1);
  373.     wtitle(w, TMID, "Run a script");
  374.     wputs(w, "\n");
  375.     wprintf(w, " A -   Username        : %s\n",
  376.                     scr_user[0] ? msg : "");
  377.     wprintf(w, " B -   Password        : %s\n",
  378.                     scr_passwd[0] ? msg : "");
  379.     wprintf(w, " C -   Name of script  : %s\n", scr_name);
  380.     wlocate(w, 4, 5);
  381.     wputs(w, "Change which setting?     (Return to run, ESC to stop)");
  382.     wredraw(w, 1);
  383.  
  384.     while(!done) {
  385.         wlocate(w, 26, 5);
  386.         n = getch();
  387.         if (islower(n)) n = toupper(n);
  388.         switch(n) {
  389.         case '\r':
  390.         case '\n':
  391.             if (scr_name[0] == '\0') {
  392.                 wbell();
  393.                 break;
  394.             }
  395.             wclose(w, 1);
  396.             done = 1;
  397.             break;
  398.         case 27: /* ESC */
  399.             wclose(w, 1);
  400.             return;
  401.         case 'A':
  402.             wlocate(w, 25, 1);
  403.             wclreol(w);
  404.             scr_user[0] = 0;
  405.             wgets(w, scr_user, 32, 32);
  406.             break;
  407.         case 'B':
  408.             wlocate(w, 25, 2);
  409.             wclreol(w);
  410.             scr_passwd[0] = 0;
  411.             wgets(w, scr_passwd, 32, 32);
  412.             break;
  413.         case 'C':
  414.             wlocate(w, 25, 3);
  415.             wgets(w, scr_name, 32, 32);
  416.             break;
  417.         default:
  418.             break;
  419.         }
  420.     }
  421.   } else {
  422.       strcpy(scr_user, l);
  423.       strcpy(scr_name, s);
  424.       strcpy(scr_passwd, p);
  425.   }
  426.  
  427.   /* Throw away status line if temporary */
  428.   if (tempst) {
  429.       wclose(st, 1);
  430.       tempst = 0;
  431.       st = NIL_WIN;
  432.   }
  433.   scriptname(scr_name);
  434.   
  435.   pipe(pipefd);
  436.  
  437.   if (mcd(P_SCRIPTDIR) < 0) return;
  438.  
  439.   sprintf(cmdline, "%s %s", P_SCRIPTPROG, scr_name);
  440.  
  441.   switch(udpid = fork()) {
  442.       case -1:
  443.           werror("Out of memory: could not fork()");
  444.           close(pipefd[0]);
  445.           close(pipefd[1]);
  446.           (void) mcd("");
  447.           return;
  448.       case 0: /* Child */
  449.           dup2(portfd, 0);
  450.           dup2(portfd, 1);
  451.           dup2(pipefd[1], 2);
  452.           close(pipefd[0]);
  453.           close(pipefd[1]);
  454.           
  455.           for(n = 1; n < _NSIG; n++) signal(n, SIG_DFL);
  456.           
  457.         setgid(real_gid);
  458.           setuid(real_uid);
  459.           mc_setenv("LOGIN", scr_user);
  460.           mc_setenv("PASS", scr_passwd);
  461.           (void) fastexec(translate(cmdline));
  462.           exit(1);
  463.       default: /* Parent */
  464.           break;
  465.   }
  466.   (void) setcbreak(1); /* Cbreak, no echo */
  467.   enab_sig(1);           /* But enable SIGINT */
  468.   signal(SIGINT, udcatch);
  469.   close(pipefd[1]);
  470.   
  471.   /* pipe output from "runscript" program to terminal emulator */
  472.   while((n = read(pipefd[0], buf, 80)) > 0) {
  473.       ptr = buf;
  474.       while(n--)
  475.           vt_out(*ptr++);
  476.       wflush();
  477.   }
  478.   
  479.   /* Collect status, and clean up. */
  480.   (void) m_wait(&status);
  481.   enab_sig(0);
  482.   signal(SIGINT, SIG_IGN);
  483.   (void) setcbreak(2); /* Raw, no echo */
  484.   close(pipefd[0]);
  485.   scriptname("");
  486.   (void) mcd("");
  487. }
  488.