home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / EMACSOS2.ZIP / OS2.C < prev    next >
C/C++ Source or Header  |  1988-10-10  |  9KB  |  371 lines

  1. /*    OS2.C:        Operating specific I/O and Spawning functions
  2.             for the OS/2 operating system
  3.             for MicroEMACS 3.9
  4.             (C)opyright 1988 by Daniel M. Lawrence
  5.  
  6. Modifications needed: check that we don't construct command lines and
  7. temporary filenames which are too large for their buffers.
  8.  
  9. */
  10.  
  11. #include        <stdio.h>
  12.  
  13. #include    "estruct.h"
  14. #include    "etype.h"
  15.  
  16. #if    OS2
  17. #define INCL_BASE
  18. #include    "os2.h"
  19.  
  20. #include    "edef.h"
  21.  
  22.  
  23. /*
  24.  * Create a subjob with a copy of the command intrepreter in it. When the
  25.  * command interpreter exits, mark the screen as garbage so that you do a full
  26.  * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
  27.  * Under some (unknown) condition, you don't get one free when DCL starts up.
  28.  */
  29. spawncli(f, n)
  30. {
  31.     /* don't allow this command if restricted */
  32.     if (restflag)
  33.         return(resterr());
  34.  
  35.         movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  36.         TTflush();
  37.     TTkclose();
  38.     shell();
  39.     TTkopen();
  40.         sgarbf = TRUE;
  41.         return(TRUE);
  42. }
  43.  
  44.  
  45. /*
  46.  * Run a one-liner in a subjob. When the command returns, wait for a single
  47.  * character to be typed, then mark the screen as garbage so a full repaint is
  48.  * done. Bound to "C-X !".
  49.  */
  50. spawn(f, n)
  51. {
  52.         register int s;
  53.         char line[NLINE];
  54.  
  55.     /* don't allow this command if restricted */
  56.     if (restflag)
  57.         return(resterr());
  58.  
  59.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  60.                 return(s);
  61.     movecursor(term.t_nrow - 1, 0);
  62.     TTkclose();
  63.     system(line);
  64.     TTkopen();
  65.     /* if we are interactive, pause here */
  66.     if (clexec == FALSE) {
  67.             puts("\r\n\n[End]");
  68.             tgetc();
  69.         }
  70.         sgarbf = TRUE;
  71.         return (TRUE);
  72. }
  73.  
  74.  
  75. /*
  76.  * Run an external program with arguments. When it returns, wait for a single
  77.  * character to be typed, then mark the screen as garbage so a full repaint is
  78.  * done. Bound to "C-X $".
  79.  */
  80.  
  81. execprg(f, n)
  82. {
  83.         register int s;
  84.         char line[NLINE];
  85.  
  86.     /* don't allow this command if restricted */
  87.     if (restflag)
  88.         return(resterr());
  89.  
  90.         if ((s=mlreply("$", line, NLINE)) != TRUE)
  91.                 return(s);
  92.     movecursor(term.t_nrow - 1, 0);
  93.     TTkclose();
  94.         execprog(line);
  95.     TTkopen();
  96.     /* if we are interactive, pause here */
  97.     if (clexec == FALSE) {
  98.             puts("\r\n\n[End]");
  99.             tgetc();
  100.         }
  101.         sgarbf = TRUE;
  102.         return (TRUE);
  103. }
  104.  
  105. /*
  106.  * Pipe a one line command into a window
  107.  * Bound to ^X @
  108.  * We use a unique temporary file name so that multiple instances of
  109.  * MicroEMACS don't try to use the same file.
  110.  */
  111. pipecmd(f, n)
  112. {
  113.     register WINDOW *wp;    /* pointer to new window */
  114.     register BUFFER *bp;    /* pointer to buffer to zot */
  115.     register char *tmp;    /* ptr to TMP DOS environment variable */
  116.     char line[NLINE];    /* command line send to shell */
  117.     static char bname[] = "command";
  118.     static char filnam[NSTRING];
  119.     char *getenv();
  120.  
  121.     /* don't allow this command if restricted */
  122.     if (restflag)
  123.         return(resterr());
  124.  
  125.     /* get rid of the command output buffer if it exists */
  126.         if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
  127.         /* try to make sure we are off screen */
  128.         wp = wheadp;
  129.         while (wp != NULL) {
  130.             if (wp->w_bufp == bp) {
  131.                 onlywind(FALSE, 1);
  132.                 break;
  133.             }
  134.             wp = wp->w_wndp;
  135.         }
  136.         /* get rid of the existing command buffer */
  137.         if (zotbuf(bp) != TRUE)
  138.             return(FALSE);
  139.     }
  140.  
  141.     /* get the command to pipe in */
  142.         if (mlreply("@", line, NLINE) != TRUE)
  143.                 return(FALSE);
  144.  
  145.     /* Call mktemp() to get a unique filename in the tmp directory. */
  146.     if ((tmp = getenv("TMP")) == NULL)
  147.         filnam[0] = 0;
  148.     else {
  149.         strcpy(filnam, tmp);
  150.         if (filnam[strlen(filnam) - 1] != '\\')
  151.             strcat(filnam, "\\");
  152.         }
  153.     strcat(filnam,"eXXXXXX");
  154.     mktemp(filnam);
  155.  
  156.     /* redirect the command output to the output file */
  157.     strcat(line, " >>");
  158.     strcat(line, filnam);
  159.     movecursor(term.t_nrow - 1, 0);
  160.  
  161.     /* execute the command */
  162.     TTkclose();
  163.     system(line);
  164.     TTkopen();
  165.         sgarbf = TRUE;
  166.  
  167.     /* did the output file get generated? */
  168.     if (access( filnam, 0) != 0)
  169.         return(FALSE);
  170.         
  171.     /* split the current window to make room for the command output */
  172.     if (splitwind(FALSE, 1) == FALSE)
  173.             return(FALSE);
  174.  
  175.     /* and read the stuff in */
  176.     if (getfile(filnam, FALSE) == FALSE)
  177.         return(FALSE);
  178.  
  179.     /* rename the buffer */
  180.     strcpy( curwp->w_bufp->b_bname, "command");
  181.     /* make this window in VIEW mode, update all mode lines */
  182.     curwp->w_bufp->b_mode |= MDVIEW;
  183.     wp = wheadp;
  184.     while (wp != NULL) {
  185.         wp->w_flag |= WFMODE;
  186.         wp = wp->w_wndp;
  187.     }
  188.  
  189.     /* and get rid of the temporary file */
  190.     unlink(filnam);
  191.     return(TRUE);
  192. }
  193.  
  194.  
  195. /*
  196.  * filter a buffer through an external DOS program
  197.  * Bound to ^X #
  198.  * We use unique temporary file names so that multiple instances of
  199.  * MicroEMACS don't try to use the same file.
  200.  */
  201. filter(f, n)
  202.  
  203. {
  204.     register int    s;    /* return status from CLI */
  205.     register BUFFER *bp;    /* pointer to buffer to zot */
  206.     char line[NLINE];    /* command line send to shell */
  207.     char tmpnam[NFILEN];    /* place to store real file name */
  208.     char *tmp;        /* ptr to TMP DOS environment variable */
  209.  
  210.     static char filnam1[NSTRING];
  211.     static char filnam2[NSTRING];
  212.  
  213.     /* don't allow this command if restricted */
  214.     if (restflag)
  215.         return(resterr());
  216.  
  217.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  218.         return(rdonly());    /* we are in read only mode    */
  219.  
  220.     /* get the filter name and its args */
  221.         if ((s=mlreply("#", line, NLINE)) != TRUE)
  222.                 return(s);
  223.  
  224.     /* Call mktemp() to get unique filenames in the tmp directory. */
  225.     if ((tmp = getenv("TMP")) == NULL)
  226.         filnam1[0] = filnam2[0] = 0;
  227.     else {
  228.         strcpy(filnam1, tmp);
  229.         strcpy(filnam2, tmp);
  230.         if (filnam1[strlen(filnam1) - 1] != '\\') {
  231.             strcat(filnam1, "\\");
  232.             strcat(filnam2, "\\");
  233.         }
  234.         }
  235.     strcat(filnam1,"eXXXXXX");
  236.     strcat(filnam2,"eXXXXXX");
  237.     mktemp(filnam1);
  238.     mktemp(filnam2);
  239.                 
  240.     /* setup the proper file names */
  241.     bp = curbp;
  242.     strcpy(tmpnam, bp->b_fname);    /* save the original name */
  243.     strcpy(bp->b_fname, filnam1);    /* set it to our new one */
  244.  
  245.     /* write it out, checking for errors */
  246.     if (writeout(filnam1) != TRUE) {
  247.         mlwrite("[Cannot write filter file]");
  248.         strcpy(bp->b_fname, tmpnam);
  249.         return(FALSE);
  250.     }
  251.  
  252.     strcat(line, " <");        /* construct the command line */
  253.     strcat(line, filnam1);
  254.     strcat(line, " >");
  255.     strcat(line, filnam2);
  256.     
  257.     movecursor(term.t_nrow - 1, 0);
  258.     TTkclose();
  259.         system(line);
  260.     TTkopen();
  261.         sgarbf = TRUE;
  262.     s = TRUE;
  263.  
  264.     /* on failure, escape gracefully */
  265.     if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
  266.         mlwrite("[Execution failed]");
  267.         strcpy(bp->b_fname, tmpnam);
  268.         unlink(filnam1);
  269.         unlink(filnam2);
  270.         return(s);
  271.     }
  272.  
  273.     /* reset file name */
  274.     strcpy(bp->b_fname, tmpnam);    /* restore name */
  275.     bp->b_flag |= BFCHG;        /* flag it as changed */
  276.  
  277.     /* and get rid of the temporary file */
  278.     unlink(filnam1);
  279.     unlink(filnam2);
  280.     return(TRUE);
  281. }
  282.  
  283.  
  284.  
  285. /*    SHELL: Bring up a shell. */
  286.  
  287. shell(void)
  288. {
  289.     char *shell;        /* Name of system command processor */
  290.  
  291.  
  292.     /*  get name of system shell  */
  293.     if ((shell = getenv("COMSPEC")) == NULL) {
  294.         return(FALSE);        /*  No shell located  */
  295.     }
  296.  
  297.     /*
  298.      * We are actually setting up a shell inside a shell here.
  299.      * Is there a better way?
  300.      */
  301.     return(system(shell));
  302. }
  303.  
  304.  
  305.  
  306. execprog( char *cmd)
  307. {
  308.     char         args[NSTRING];        /* args passed to program */
  309.     char        *sp;
  310.     char         failName[1];
  311.     char         prog[NSTRING];        /* name of program */
  312.     USHORT         i;
  313.     PRESULTCODES    *results;
  314.     
  315.  
  316.     /*
  317.      * Parse the command name from the command line and copy it
  318.      * into the prog and args arrays.
  319.      */
  320.     i = 0;
  321.     while (cmd[i]  &&  (cmd[i] != ' ')  &&  (cmd[i] != '\t')) {
  322.         prog[i] = args[i] = cmd[i];
  323.         i++;
  324.     }
  325.     prog[i] = args[i] = 0;        /* terminate with a null */
  326.  
  327.     /* skip whitespace and copy the args */
  328.     while (cmd[i]  &&  ((cmd[i] == ' ')  ||  (cmd[i] == '\t')))
  329.         i++;
  330.     while (cmd[i]) {
  331.         args[i] = cmd[i];
  332.         i++;
  333.     }
  334.     args[i] = args[i + 1] = 0;    /* terminate with 2 nulls */
  335.     
  336.     
  337.     /* look up the program on the path, trying various extentions */
  338.     if ((sp = flook(prog, TRUE)) == NULL)
  339.         if ((sp = flook(strcat(prog, ".exe"), TRUE)) == NULL) {
  340.             strcpy(&prog[strlen(prog)-4], ".com");
  341.             if ((sp = flook(prog, TRUE)) == NULL)
  342.                 return(FALSE);
  343.         }
  344.     strcpy(prog, sp);
  345.  
  346.     /*
  347.      * Execute the program synchronously.  We wait for child
  348.      * to return.
  349.      */
  350.     return (0 == DosExecPgm( &failName, 1, EXEC_SYNC,
  351.                      args, 0, results, prog));
  352. }
  353.  
  354.     
  355. /* return a system dependant string with the current time */
  356.  
  357. char *stime()
  358.  
  359. {
  360.     register char *sp;    /* temp string pointer */
  361.     char buf[16];        /* time data buffer */
  362.     extern char *ctime();
  363.  
  364.     time(buf);
  365.     sp = ctime(buf);
  366.     sp[strlen(sp)-1] = 0;
  367.     return(sp);
  368. }
  369. #endif
  370.  
  371.