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

  1. /*
  2.  * This file is part of the Minicom Communications Program,
  3.  * written by Miquel van Smoorenburg 1991/1992/1993.
  4.  */
  5.  
  6. /*
  7.  * fastsystem.c - scan command for shell metacharacters.
  8.  *          If they aren't there, just do a path-searching
  9.  *          exec. Elsewise, fork a shell.
  10.  *
  11.  *          Miquel van Smoorenburg, June 1991.
  12.  */
  13.  
  14. #include <sys/types.h>
  15. #include <string.h>
  16. #ifdef _MINIX
  17. #  undef NULL
  18. #endif
  19. #include <fcntl.h>
  20. #if defined (_POSIX_SOURCE) || defined(_BSD43)
  21. #  include <unistd.h>
  22. #  include <stdlib.h>
  23. #endif
  24. #include <stdio.h>
  25. #include <setjmp.h>
  26. #include "window.h"
  27. #include "minicom.h"
  28.  
  29. #define CNULL ((char *)0)
  30.  
  31. extern int errno;
  32.  
  33. /*
  34.  * A modified version of the getargs routine.
  35.  */
  36. static int getargs(s, arps, maxargs)
  37. register char *s;
  38. char *arps[];
  39. int maxargs;
  40. {
  41.     register int i;
  42.     register char *sp;
  43.     register char qchar;
  44.     int literal = 0;
  45.  
  46.     i = 0;
  47.     while (i < maxargs) {
  48.         while (*s == ' ' || *s == '\t')
  49.             ++s;
  50.         if (*s == '\n' || *s == '\0')
  51.             break;
  52.         arps[i++] = sp = s;
  53.         qchar = 0;
  54.         while(*s != '\0'  &&  *s != '\n') {
  55.             if (literal) {
  56.                 literal = 0;
  57.                 *sp++ = *s++;
  58.                 continue;
  59.             }
  60.             literal = 0;
  61.             if (qchar == 0 && (*s == ' ' || *s == '\t')) {
  62.                 ++s;
  63.                 break;
  64.             }
  65.             switch(*s) {
  66.             default:
  67.                 *sp++ = *s++;
  68.                 break;
  69.             case '\\':
  70.                 literal = 1;
  71.                 s++;
  72.                 break;    
  73.             case '"':
  74.             case '\'':
  75.                 if(qchar == *s) {
  76.                     qchar = 0;
  77.                     ++s;
  78.                     break;
  79.                 }
  80.                 if(qchar)
  81.                     *sp++ = *s++;
  82.                 else
  83.                     qchar = *s++;
  84.                 break;
  85.             }
  86.         }
  87.         *sp++ = 0;
  88.     }
  89.     if (i >= maxargs)
  90.         return -1;
  91.     arps[i] = (char *)0;
  92.     return i;
  93. }
  94.  
  95. /*
  96.  * Is a character from s2 in s1?
  97.  */
  98. static int anys(s1, s2)
  99. char *s1, *s2;
  100. {
  101.   while(*s2)
  102.       if (strchr(s1, *s2++) != CNULL) return(1);
  103.   return(0);
  104. }
  105.  
  106. /*
  107.  * If there is a shell-metacharacter in "cmd",
  108.  * call a shell to do the dirty work.
  109.  */
  110. int fastexec(cmd)
  111. char *cmd;
  112. {
  113.   char *words[128];
  114.   char *p;
  115.  
  116.   if (anys(cmd, "~`$&*()=|{};?><"))
  117.       return(execl("/bin/sh", "sh", "-c", cmd, (char *)0));
  118.  
  119.   /* Delete escape-characters ment for the shell */
  120.   p = cmd;
  121.   while((p = strchr(p, '\\')) != CNULL)
  122.       strcpy(p, p + 1);
  123.  
  124.   /* Split line into words */
  125.   if (getargs(cmd, words, 127) < 0) {
  126.       return(-1);
  127.   }
  128.   return (execvp(words[0], words));
  129. }
  130.  
  131. /*
  132.  * Fork, then redirect I/O if neccesary.
  133.  * in    : new stdin
  134.  * out   : new stdout
  135.  * err   : new stderr
  136.  * Returns exit status of "cmd" on success, -1 on error.
  137.  */
  138. int fastsystem(cmd, in, out, err)
  139. char *cmd, *in, *out, *err;
  140. {
  141.   int pid;
  142.   int st;
  143.   int async = 0;
  144.   char *p;
  145.  
  146.   /* If the command line ends with '&', don't wait for child. */
  147.   p = strrchr(cmd, '&');
  148.   if (p != (char *)0 && !p[1]) {
  149.       *p = 0;
  150.       async = 1;
  151.   }
  152.   
  153.   /* Fork. */
  154.   if ((pid = fork()) == 0) { /* child */
  155.       if (in != CNULL) {
  156.           close(0);
  157.           if (open(in, O_RDONLY) < 0) exit(-1);
  158.       }
  159.       if (out != CNULL) {
  160.           close(1);
  161.           if (open(out, O_WRONLY) < 0) exit(-1);
  162.       }
  163.       if (err != CNULL) {
  164.           close(2);
  165.           if (open(err, O_RDWR) < 0) exit(-1);
  166.       }
  167.       exit(fastexec(cmd));
  168.   } else if (pid > 0) { /* parent */
  169.       if (async) return(0);
  170.       pid = m_wait(&st);
  171.       if (pid < 0) return(-1);
  172.       return(st);
  173.   }
  174.   return(-1);
  175. }
  176.