home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / memacs400_src.lzh / MEMACS400 / SRC / os2.c < prev    next >
Text File  |  1996-04-25  |  14KB  |  567 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)Copyright 1995 by Daniel M. Lawrence
  5.  
  6. Note:  don't try to compile this on non OS/2 systems.... the OS/2
  7.     includes MUST come before ours.....
  8.  
  9. Modifications needed: check that we don't construct command lines and
  10. temporary filenames which are too large for their buffers.
  11.  
  12. */
  13.  
  14. #define INCL_DOS
  15. #include "os2.h"
  16.  
  17. #include        <stdio.h>
  18.  
  19. #undef    PASCAL
  20. #undef    NEAR
  21. #undef    HIBYTE
  22.  
  23. #include    "estruct.h"
  24. #include    "eproto.h"
  25.  
  26. #if    OS2
  27. #define INCL_BASE
  28.  
  29. #include "elang.h"
  30. #include "edef.h"
  31.  
  32.  
  33. /*
  34.  * Create a subjob with a copy of the command intrepreter in it. When the
  35.  * command interpreter exits, mark the screen as garbage so that you do a full
  36.  * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
  37.  * Under some (unknown) condition, you don't get one free when DCL starts up.
  38.  */
  39. spawncli(f, n)
  40. {
  41.     /* don't allow this command if restricted */
  42.     if (restflag)
  43.         return(resterr());
  44.  
  45.         movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  46.         TTflush();
  47.     TTkclose();
  48.     shell();
  49.     TTkopen();
  50.         sgarbf = TRUE;
  51.         return(TRUE);
  52. }
  53.  
  54.  
  55. /*
  56.  * Run a one-liner in a subjob. When the command returns, wait for a single
  57.  * character to be typed, then mark the screen as garbage so a full repaint is
  58.  * done. Bound to "C-X !".
  59.  */
  60. spawn(f, n)
  61. {
  62.         register int s;
  63.         char line[NLINE];
  64.  
  65.     /* don't allow this command if restricted */
  66.     if (restflag)
  67.         return(resterr());
  68.  
  69.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  70.                 return(s);
  71.     movecursor(term.t_nrow - 1, 0);
  72.     TTkclose();
  73.     system(line);
  74.     TTkopen();
  75.     /* if we are interactive, pause here */
  76.     if (clexec == FALSE) {
  77.             puts(TEXT6);
  78. /*                     "\r\n\n[End]" */
  79.             tgetc();
  80.         }
  81.         sgarbf = TRUE;
  82.         return (TRUE);
  83. }
  84.  
  85.  
  86. /*
  87.  * Run an external program with arguments. When it returns, wait for a single
  88.  * character to be typed, then mark the screen as garbage so a full repaint is
  89.  * done. Bound to "C-X $".
  90.  */
  91.  
  92. execprg(f, n)
  93. {
  94.         register int s;
  95.         char line[NLINE];
  96.  
  97.     /* don't allow this command if restricted */
  98.     if (restflag)
  99.         return(resterr());
  100.  
  101.         if ((s=mlreply("$", line, NLINE)) != TRUE)
  102.                 return(s);
  103.     movecursor(term.t_nrow - 1, 0);
  104.     TTkclose();
  105.         execprog(line);
  106.     TTkopen();
  107.     /* if we are interactive, pause here */
  108.     if (clexec == FALSE) {
  109.             puts(TEXT6);
  110. /*                     "\r\n\n[End]" */
  111.             tgetc();
  112.         }
  113.         sgarbf = TRUE;
  114.         return (TRUE);
  115. }
  116.  
  117. /*
  118.  * Pipe a one line command into a window
  119.  * Bound to ^X @
  120.  * We use a unique temporary file name so that multiple instances of
  121.  * MicroEMACS don't try to use the same file.
  122.  */
  123. pipecmd(f, n)
  124. {
  125.     register EWINDOW *wp;    /* pointer to new window */
  126.     register BUFFER *bp;    /* pointer to buffer to zot */
  127.     register char *tmp;    /* ptr to TMP DOS environment variable */
  128.     char line[NLINE];    /* command line send to shell */
  129.     static char bname[] = "command";
  130.     static char filnam[NSTRING];
  131.  
  132.     /* don't allow this command if restricted */
  133.     if (restflag)
  134.         return(resterr());
  135.  
  136.     /* get rid of the command output buffer if it exists */
  137.         if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
  138.         /* try to make sure we are off screen */
  139.         wp = wheadp;
  140.         while (wp != NULL) {
  141.             if (wp->w_bufp == bp) {
  142.                 onlywind(FALSE, 1);
  143.                 break;
  144.             }
  145.             wp = wp->w_wndp;
  146.         }
  147.         /* get rid of the existing command buffer */
  148.         if (zotbuf(bp) != TRUE)
  149.             return(FALSE);
  150.     }
  151.  
  152.     /* get the command to pipe in */
  153.         if (mlreply("@", line, NLINE) != TRUE)
  154.                 return(FALSE);
  155.  
  156.     /* Call mktemp() to get a unique filename in the tmp directory. */
  157.     if ((tmp = getenv("TMP")) == NULL)
  158.         filnam[0] = 0;
  159.     else {
  160.         strcpy(filnam, tmp);
  161.         if (filnam[strlen(filnam) - 1] != '\\')
  162.             strcat(filnam, "\\");
  163.         }
  164.     strcat(filnam,"eXXXXXX");
  165.     mktemp(filnam);
  166.  
  167.     /* redirect the command output to the output file */
  168.     strcat(line, " >>");
  169.     strcat(line, filnam);
  170.     movecursor(term.t_nrow - 1, 0);
  171.  
  172.     /* execute the command */
  173.     TTkclose();
  174.     system(line);
  175.     TTkopen();
  176.         sgarbf = TRUE;
  177.  
  178.     /* did the output file get generated? */
  179.     if (access( filnam, 0) != 0)
  180.         return(FALSE);
  181.         
  182.     /* split the current window to make room for the command output */
  183.     if (splitwind(FALSE, 1) == FALSE)
  184.             return(FALSE);
  185.  
  186.     /* and read the stuff in */
  187.     if (getfile(filnam, FALSE) == FALSE)
  188.         return(FALSE);
  189.  
  190.     /* rename the buffer */
  191.     strcpy( curwp->w_bufp->b_bname, "command");
  192.     /* make this window in VIEW mode, update all mode lines */
  193.     curwp->w_bufp->b_mode |= MDVIEW;
  194.     wp = wheadp;
  195.     while (wp != NULL) {
  196.         wp->w_flag |= WFMODE;
  197.         wp = wp->w_wndp;
  198.     }
  199.  
  200.     /* and get rid of the temporary file */
  201.     unlink(filnam);
  202.     return(TRUE);
  203. }
  204.  
  205.  
  206. /*
  207.  * filter a buffer through an external DOS program
  208.  * Bound to ^X #
  209.  * We use unique temporary file names so that multiple instances of
  210.  * MicroEMACS don't try to use the same file.
  211.  */
  212. filter(f, n)
  213.  
  214. {
  215.     register int    s;    /* return status from CLI */
  216.     register BUFFER *bp;    /* pointer to buffer to zot */
  217.     char line[NLINE];    /* command line send to shell */
  218.     char tmpnam[NFILEN];    /* place to store real file name */
  219.     char *tmp;        /* ptr to TMP DOS environment variable */
  220.  
  221.     static char filnam1[NSTRING];
  222.     static char filnam2[NSTRING];
  223.  
  224.     /* don't allow this command if restricted */
  225.     if (restflag)
  226.         return(resterr());
  227.  
  228.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  229.         return(rdonly());    /* we are in read only mode    */
  230.  
  231.     /* get the filter name and its args */
  232.         if ((s=mlreply("#", line, NLINE)) != TRUE)
  233.                 return(s);
  234.  
  235.     /* Call mktemp() to get unique filenames in the tmp directory. */
  236.     if ((tmp = getenv("TMP")) == NULL)
  237.         filnam1[0] = filnam2[0] = 0;
  238.     else {
  239.         strcpy(filnam1, tmp);
  240.         strcpy(filnam2, tmp);
  241.         if (filnam1[strlen(filnam1) - 1] != '\\') {
  242.             strcat(filnam1, "\\");
  243.             strcat(filnam2, "\\");
  244.         }
  245.         }
  246.     strcat(filnam1,"eXXXXXX");
  247.     strcat(filnam2,"eXXXXXX");
  248.     mktemp(filnam1);
  249.                 
  250.     /* setup the proper file names */
  251.     bp = curbp;
  252.     strcpy(tmpnam, bp->b_fname);    /* save the original name */
  253.     strcpy(bp->b_fname, filnam1);    /* set it to our new one */
  254.  
  255.     /* write it out, checking for errors */
  256.     if (writeout(filnam1, "w") != TRUE) {
  257.         mlwrite(TEXT2);
  258. /*                      "[Cannot write filter file]" */
  259.         strcpy(bp->b_fname, tmpnam);
  260.         return(FALSE);
  261.     }
  262.  
  263.     mktemp(filnam2);
  264.     strcat(line, " <");        /* construct the command line */
  265.     strcat(line, filnam1);
  266.     strcat(line, " >");
  267.     strcat(line, filnam2);
  268.     
  269.     movecursor(term.t_nrow - 1, 0);
  270.     TTkclose();
  271.         system(line);
  272.     TTkopen();
  273.         sgarbf = TRUE;
  274.     s = TRUE;
  275.  
  276.     /* on failure, escape gracefully */
  277.     if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
  278.         mlwrite(TEXT3);
  279. /*                      "[Execution failed]" */
  280.         strcpy(bp->b_fname, tmpnam);
  281.         unlink(filnam1);
  282.         unlink(filnam2);
  283.         return(s);
  284.     }
  285.  
  286.     /* reset file name */
  287.     strcpy(bp->b_fname, tmpnam);    /* restore name */
  288.     bp->b_flag |= BFCHG;        /* flag it as changed */
  289.  
  290.     /* and get rid of the temporary file */
  291.     unlink(filnam1);
  292.     unlink(filnam2);
  293.     return(TRUE);
  294. }
  295.  
  296.  
  297.  
  298. /*    SHELL: Bring up a shell. */
  299.  
  300. shell(void)
  301. {
  302.     char *shell;        /* Name of system command processor */
  303.  
  304.  
  305.     /*  get name of system shell  */
  306.     if ((shell = getenv("COMSPEC")) == NULL) {
  307.         return(FALSE);        /*  No shell located  */
  308.     }
  309.  
  310.     /*
  311.      * We are actually setting up a shell inside a shell here.
  312.      * Is there a better way?
  313.      */
  314.     return(system(shell));
  315. }
  316.  
  317.  
  318.  
  319. execprog( char *cmd)
  320. {
  321.     char         args[NSTRING];        /* args passed to program */
  322.     char        *sp;
  323.     char         failName[NFILEN];
  324.     char         prog[NSTRING];        /* name of program */
  325.     USHORT         i;
  326.     PRESULTCODES     results;
  327.     
  328.  
  329.     /*
  330.      * Parse the command name from the command line and copy it
  331.      * into the prog and args arrays.
  332.      */
  333.     i = 0;
  334.     while (cmd[i]  &&  (cmd[i] != ' ')  &&  (cmd[i] != '\t')) {
  335.         prog[i] = args[i] = cmd[i];
  336.         i++;
  337.     }
  338.     prog[i] = args[i] = 0;        /* terminate with a null */
  339.  
  340.     /* skip whitespace and copy the args */
  341.     while (cmd[i]  &&  ((cmd[i] == ' ')  ||  (cmd[i] == '\t')))
  342.         i++;
  343.     while (cmd[i]) {
  344.         args[i] = cmd[i];
  345.         i++;
  346.     }
  347.     args[i] = args[i + 1] = 0;    /* terminate with 2 nulls */
  348.     
  349.     
  350.     /* look up the program on the path, trying various extentions */
  351.     if ((sp = flook(prog, TRUE)) == NULL)
  352.         if ((sp = flook(strcat(prog, ".exe"), TRUE)) == NULL) {
  353.             strcpy(&prog[strlen(prog)-4], ".com");
  354.             if ((sp = flook(prog, TRUE)) == NULL)
  355.                 return(FALSE);
  356.         }
  357.     strcpy(prog, sp);
  358.  
  359.     /*
  360.      * Execute the program synchronously.  We wait for child
  361.      * to return.
  362.      */
  363.     return (0 == DosExecPgm( failName, NFILEN, EXEC_SYNC,
  364.                      args, 0, results, prog));
  365. }
  366.  
  367.     
  368. /*    FILE Directory routines        */
  369.  
  370. FILEFINDBUF pBuf;    /* buffer to hold file information */
  371. HDIR hDir;        /* directory handle */
  372. int num_found;        /* number of directory entries found/to find */
  373.  
  374. char path[NFILEN];    /* path of file to find */
  375. char rbuf[NFILEN];    /* return file buffer */
  376.  
  377. /*    do a wild card directory search (for file name completion) */
  378.  
  379. char *PASCAL NEAR getffile(fspec)
  380.  
  381. char *fspec;    /* pattern to match */
  382.  
  383. {
  384.     register int index;        /* index into various strings */
  385.     register int point;        /* index into other strings */
  386.     register int extflag;        /* does the file have an extention? */
  387.     char fname[NFILEN];        /* file/path for DOS call */
  388.  
  389.     /* first parse the file path off the file spec */
  390.     strcpy(path, fspec);
  391.     index = strlen(path) - 1;
  392.     while (index >= 0 && (path[index] != '/' &&
  393.                 path[index] != '\\' && path[index] != ':'))
  394.         --index;
  395.     path[index+1] = 0;
  396.  
  397.     /* check for an extension */
  398.     point = strlen(fspec) - 1;
  399.     extflag = FALSE;
  400.     while (point > index) {
  401.         if (fspec[point] == '.') {
  402.             extflag = TRUE;
  403.             break;
  404.         }
  405.         point--;
  406.     }
  407.  
  408.     /* construct the composite wild card spec */
  409.     strcpy(fname, path);
  410.     strcat(fname, &fspec[index+1]);
  411.     strcat(fname, "*");
  412.     if (extflag == FALSE)
  413.         strcat(fname, ".*");
  414.  
  415.     /* and call for the first file */
  416.     num_found = 1;
  417.     hDir = HDIR_CREATE;
  418.     if (DosFindFirst(fname, &hDir, FILE_NORMAL|FILE_DIRECTORY,
  419.               &pBuf, sizeof(pBuf), &num_found, 0L) != 0)
  420.         return(NULL);
  421.  
  422.     /* return the first file name! */
  423.     strcpy(rbuf, path);
  424.     strcat(rbuf, pBuf.achName);
  425.     mklower(rbuf);
  426.     if (pBuf.attrFile == FILE_DIRECTORY)
  427.         strcat(rbuf, DIRSEPSTR);
  428.     return(rbuf);
  429. }
  430.  
  431. char *PASCAL NEAR getnfile()
  432.  
  433. {
  434.     register int index;        /* index into various strings */
  435.     register int point;        /* index into other strings */
  436.     register int extflag;        /* does the file have an extention? */
  437.     char fname[NFILEN];        /* file/path for DOS call */
  438.  
  439.     /* and call for the next file */
  440.     if (DosFindNext(hDir, (void *)&pBuf, sizeof(pBuf), &num_found) != 0)
  441.         return(NULL);
  442.  
  443.     /* return the first file name! */
  444.     strcpy(rbuf, path);
  445.     strcat(rbuf, pBuf.achName);
  446.     mklower(rbuf);
  447.     if (pBuf.attrFile == FILE_DIRECTORY)
  448.         strcat(rbuf, DIRSEPSTR);
  449.     return(rbuf);
  450. }
  451.  
  452. /* return a system dependant string with the current time */
  453.  
  454. char *timeset()
  455.  
  456. {
  457.     register char *sp;    /* temp string pointer */
  458.     char buf[16];        /* time data buffer */
  459.     extern char *ctime();
  460.  
  461.     time(buf);
  462.     sp = ctime(buf);
  463.     sp[strlen(sp)-1] = 0;
  464.     return(sp);
  465. }
  466.  
  467. #if    OBSOLETE
  468. /*    extcode:    resolve MSDOS extended character codes
  469.             encoding the proper sequences into emacs
  470.             printable character specifications
  471. */
  472.  
  473. int extcode(
  474.     unsigned c    /* byte following a zero extended char byte */
  475. )
  476.  
  477. {
  478.     /* function keys 1 through 9 */
  479.     if (c >= 59 && c < 68)
  480.         return(SPEC | c - 58 + '0');
  481.  
  482.     /* function key 10 */
  483.     if (c == 68)
  484.         return(SPEC | '0');
  485.  
  486.     /* shifted function keys */
  487.     if (c >= 84 && c < 93)
  488.         return(SPEC | SHFT | c - 83 + '0');
  489.     if (c == 93)
  490.         return(SPEC | SHFT | '0');
  491.  
  492.     /* control function keys */
  493.     if (c >= 94 && c < 103)
  494.         return(SPEC | CTRL | c - 93 + '0');
  495.     if (c == 103)
  496.         return(SPEC | CTRL | '0');
  497.  
  498.     /* ALTed function keys */
  499.     if (c >= 104 && c < 113)
  500.         return(SPEC | ALTD | c - 103 + '0');
  501.     if (c == 113)
  502.         return(SPEC | ALTD | '0');
  503.  
  504.     /* ALTed number keys */
  505.     if (c >= 120 && c < 129)
  506.         return(ALTD | c - 119 + '0');
  507.     if (c == 130)
  508.         return(ALTD | '0');
  509.  
  510.     /* some others as well */
  511.     switch (c) {
  512.         case 3:        return(0);        /* null */
  513.         case 15:    return(SHFT | CTRL | 'I');    /* backtab */
  514.  
  515.         case 16:    return(ALTD | 'Q');
  516.         case 17:    return(ALTD | 'W');
  517.         case 18:    return(ALTD | 'E');
  518.         case 19:    return(ALTD | 'R');
  519.         case 20:    return(ALTD | 'T');
  520.         case 21:    return(ALTD | 'Y');
  521.         case 22:    return(ALTD | 'U');
  522.         case 23:    return(ALTD | 'I');
  523.         case 24:    return(ALTD | 'O');
  524.         case 25:    return(ALTD | 'P');
  525.  
  526.         case 30:    return(ALTD | 'A');
  527.         case 31:    return(ALTD | 'S');
  528.         case 32:    return(ALTD | 'D');
  529.         case 33:    return(ALTD | 'F');
  530.         case 34:    return(ALTD | 'G');
  531.         case 35:    return(ALTD | 'H');
  532.         case 36:    return(ALTD | 'J');
  533.         case 37:    return(ALTD | 'K');
  534.         case 38:    return(ALTD | 'L');
  535.  
  536.         case 44:    return(ALTD | 'Z');
  537.         case 45:    return(ALTD | 'X');
  538.         case 46:    return(ALTD | 'C');
  539.         case 47:    return(ALTD | 'V');
  540.         case 48:    return(ALTD | 'B');
  541.         case 49:    return(ALTD | 'N');
  542.         case 50:    return(ALTD | 'M');
  543.  
  544.         case 71:    return(SPEC | '<');    /* HOME */
  545.         case 72:    return(SPEC | 'P');    /* cursor up */
  546.         case 73:    return(SPEC | 'Z');    /* page up */
  547.         case 75:    return(SPEC | 'B');    /* cursor left */
  548.         case 77:    return(SPEC | 'F');    /* cursor right */
  549.         case 79:    return(SPEC | '>');    /* end */
  550.         case 80:    return(SPEC | 'N');    /* cursor down */
  551.         case 81:    return(SPEC | 'V');    /* page down */
  552.         case 82:    return(SPEC | 'C');    /* insert */
  553.         case 83:    return(SPEC | 'D');    /* delete */
  554.         case 115:    return(SPEC | CTRL | 'B');    /* control left */
  555.         case 116:    return(SPEC | CTRL | 'F');    /* control right */
  556.         case 117:    return(SPEC | CTRL | '>');    /* control END */
  557.         case 118:    return(SPEC | CTRL | 'V');    /* control page down */
  558.         case 119:    return(SPEC | CTRL | '<');    /* control HOME */
  559.         case 132:    return(SPEC | CTRL | 'Z');    /* control page up */
  560.     }
  561.  
  562.     return(ALTD | c);
  563. }
  564. #endif    /* obsolete */
  565. #endif
  566.  
  567.