home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / UE311C.ZIP / TOS.C < prev    next >
C/C++ Source or Header  |  1991-05-02  |  12KB  |  490 lines

  1. /*    TOS.C:        Operating specific I/O and Spawning functions
  2.             for the ATARI ST operating system (GEMDOS)
  3.             for MicroEMACS 3.10
  4.             (C)Copyright 1988 by Daniel M. Lawrence
  5. */
  6.  
  7. #include        <stdio.h>
  8. #include    "estruct.h"
  9. #include    "eproto.h"
  10. #if    TOS
  11. #include        "edef.h"
  12. #include    "elang.h"
  13. #include    "osbind.h"
  14. #include    "stat.h"    /* DMABUFFER is here */
  15. #include    "errno.h"
  16.  
  17. /****    ST Internals definitions        *****/
  18.  
  19. /*    BIOS calls */
  20.  
  21. #define    BCONSTAT    1    /* return input device status */
  22. #define    CONIN        2    /* read character from device */
  23. #define    BCONOUT        3    /* write character to device */
  24.  
  25. /*    XBIOS calls */
  26.  
  27. #define    INITMOUS    0    /* initialize the mouse */
  28. #define    GETREZ        4    /* get current resolution */
  29. #define    SETSCREEN    5    /* set screen resolution */
  30. #define    SETPALETTE    6    /* set the color pallette */
  31. #define    SETCOLOR    7    /* set or read a color */
  32. #define    CURSCONF    21    /* set cursor configuration */
  33. #define    IKBDWS        25    /* intelligent keyboard send command */
  34. #define    KBDVBASE    34    /* get keyboard table base */
  35.  
  36. /*    GEMDOS calls */
  37.  
  38. #define    EXEC        0x4b    /* Exec off a process */
  39.  
  40. #define    CON        2    /* CON: Keyboard and screen device */
  41.  
  42. /*
  43.  * This function is called once to set up the terminal device streams.
  44.  * On VMS, it translates TT until it finds the terminal, then assigns
  45.  * a channel to it and sets it raw. On CPM it is a no-op.
  46.  */
  47. ttopen()
  48. {
  49.     /* on all screens we are not sure of the initial position
  50.        of the cursor                    */
  51.     ttrow = 999;
  52.     ttcol = 999;
  53. }
  54.  
  55. /*
  56.  * This function gets called just before we go back home to the command
  57.  * interpreter. On VMS it puts the terminal back in a reasonable state.
  58.  * Another no-operation on CPM.
  59.  */
  60. ttclose()
  61. {
  62. }
  63.  
  64. /*
  65.  * Write a character to the display. On VMS, terminal output is buffered, and
  66.  * we just put the characters in the big array, after checking for overflow.
  67.  * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  68.  * MS-DOS (use the very very raw console output routine).
  69.  */
  70. ttputc(c)
  71.  
  72. char c;
  73.  
  74. {
  75. }
  76.  
  77. /*
  78.  * Flush terminal buffer. Does real work where the terminal output is buffered
  79.  * up. A no-operation on systems where byte at a time terminal I/O is done.
  80.  */
  81. ttflush()
  82. {
  83. }
  84.  
  85. /*
  86.  * Read a character from the terminal, performing no editing and doing no echo
  87.  * at all. More complex in VMS that almost anyplace else, which figures. Very
  88.  * simple on CPM, because the system can do exactly what you want.
  89.  */
  90. ttgetc()
  91. {
  92. }
  93.  
  94. #if    TYPEAH
  95. typahead()
  96.  
  97. {
  98.     int rval;    /* return value from BIOS call */
  99.  
  100.     /* get the status of the console */
  101.     rval = bios(BCONSTAT, CON);
  102.  
  103.     /* end return the results */
  104.     if (rval == 0)
  105.         return(FALSE);
  106.     else
  107.         return(TRUE);
  108. }
  109. #endif
  110.  
  111. /*
  112.  * Create a subjob with a copy of the command intrepreter in it. When the
  113.  * command interpreter exits, mark the screen as garbage so that you do a full
  114.  * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
  115.  * Under some (unknown) condition, you don't get one free when DCL starts up.
  116.  */
  117. spawncli(f, n)
  118.  
  119. {
  120. #if    ENVFUNC
  121.     char *shell;    /* ptr to the name of the shell to execute */
  122.     char *getenv();
  123. #endif
  124.  
  125.     /* don't allow this command if restricted */
  126.     if (restflag)
  127.         return(resterr());
  128.  
  129. #if    ENVFUNC
  130.     shell = getenv("SHELL");
  131.     if (shell == (char *)NULL)
  132.         return(FALSE);
  133.  
  134.     /* Prepare to Jump.... */
  135.     mlerase();
  136.         TTflush();
  137.     TTkclose();
  138.  
  139.     /* Execute the shell */
  140.     system(shell);
  141.  
  142.     /* Re-enable EMACS's environment, flag junked screen */
  143.     TTkopen();
  144.         sgarbf = TRUE;
  145.         return(TRUE);
  146. #else
  147.     return(FALSE);
  148. #endif
  149. }
  150.  
  151. /*
  152.  * Run a one-liner in a subjob. When the command returns, wait for a single
  153.  * character to be typed, then mark the screen as garbage so a full repaint is
  154.  * done. Bound to "C-X !".
  155.  */
  156. spawn(f, n)
  157. {
  158.         register int    s;
  159.         char            line[NLINE];
  160.  
  161.     /* don't allow this command if restricted */
  162.     if (restflag)
  163.         return(resterr());
  164.  
  165.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  166.                 return(s);
  167.     mlerase();
  168.     TTkclose();
  169.         system(line);
  170.     TTkopen();
  171.     /* if we are interactive, pause here */
  172.     if (clexec == FALSE) {
  173.             mlputs(TEXT6);
  174. /*                     "\r\n\n[End]" */
  175.             tgetc();
  176.         }
  177.         sgarbf = TRUE;
  178.         return (TRUE);
  179. }
  180.  
  181. /*
  182.  * Run an external program with arguments. When it returns, wait for a single
  183.  * character to be typed, then mark the screen as garbage so a full repaint is
  184.  * done. Bound to "C-X $".
  185.  */
  186.  
  187. execprg(f, n)
  188.  
  189. {
  190.         register int    s;
  191.         char            line[NLINE];
  192.  
  193.     /* don't allow this command if restricted */
  194.     if (restflag)
  195.         return(resterr());
  196.  
  197.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  198.                 return(s);
  199.     mlerase();
  200.     TTkclose();
  201.         system(line);
  202.     TTkopen();
  203.     /* if we are interactive, pause here */
  204.     if (clexec == FALSE) {
  205.             mlputs(TEXT6);
  206. /*                     "\r\n\n[End]" */
  207.             tgetc();
  208.         }
  209.         sgarbf = TRUE;
  210.         return (TRUE);
  211. }
  212.  
  213. /*
  214.  * Pipe a one line command into a window
  215.  * Bound to ^X @
  216.  */
  217. pipecmd(f, n)
  218. {
  219.         register int    s;    /* return status from CLI */
  220.     register WINDOW *wp;    /* pointer to new window */
  221.     register BUFFER *bp;    /* pointer to buffer to zot */
  222.         char    line[NLINE];    /* command line send to shell */
  223.     static char bname[] = "command";
  224.     FILE *fp;
  225.  
  226.     static char filnam[NSTRING] = "command";
  227.  
  228.     /* don't allow this command if restricted */
  229.     if (restflag)
  230.         return(resterr());
  231.  
  232.     /* get the command to pipe in */
  233.         if ((s=mlreply("@", line, NLINE)) != TRUE)
  234.                 return(s);
  235.  
  236.     /* get rid of the command output buffer if it exists */
  237.         if ((bp=bfind(bname, FALSE, 0)) != (BUFFER *)NULL) {
  238.         /* try to make sure we are off screen */
  239.         wp = wheadp;
  240.         while (wp != NULL) {
  241.             if (wp->w_bufp == bp) {
  242.                 onlywind(FALSE, 1);
  243.                 break;
  244.             }
  245.             wp = wp->w_wndp;
  246.         }
  247.         if (zotbuf(bp) != TRUE)
  248.  
  249.             return(FALSE);
  250.     }
  251.  
  252.     strcat(line," >>");
  253.     strcat(line,filnam);
  254.     movecursor(term.t_nrow - 1, 0);
  255.     TTkclose();
  256.     system(line);
  257.     TTkopen();
  258.         sgarbf = TRUE;
  259.     if ((fp = fopen(filnam, "r")) == NULL) {
  260.         s = FALSE;
  261.     } else {
  262.         fclose(fp);
  263.         s = TRUE;
  264.     }
  265.  
  266.     if (s != TRUE)
  267.         return(s);
  268.  
  269.     /* split the current window to make room for the command output */
  270.     if (splitwind(FALSE, 1) == FALSE)
  271.             return(FALSE);
  272.  
  273.     /* and read the stuff in */
  274.     if (getfile(filnam, FALSE) == FALSE)
  275.         return(FALSE);
  276.  
  277.     /* make this window in VIEW mode, update all mode lines */
  278.     curwp->w_bufp->b_mode |= MDVIEW;
  279.     upmode();
  280.  
  281.     /* and get rid of the temporary file */
  282.     unlink(filnam);
  283.     return(TRUE);
  284. }
  285.  
  286. /*
  287.  * filter a buffer through an external DOS program
  288.  * Bound to ^X #
  289.  */
  290. filter(f, n)
  291.  
  292. {
  293.         register int    s;    /* return status from CLI */
  294.     register BUFFER *bp;    /* pointer to buffer to zot */
  295.         char line[NLINE];    /* command line send to shell */
  296.     char tmpnam[NFILEN];    /* place to store real file name */
  297.     static char bname1[] = "fltinp";
  298.  
  299.     static char filnam1[] = "fltinp";
  300.     static char filnam2[] = "fltout";
  301.  
  302.     /* don't allow this command if restricted */
  303.     if (restflag)
  304.         return(resterr());
  305.  
  306.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  307.         return(rdonly());    /* we are in read only mode    */
  308.  
  309.     /* get the filter name and its args */
  310.         if ((s=mlreply("#", line, NLINE)) != TRUE)
  311.                 return(s);
  312.  
  313.     /* setup the proper file names */
  314.     bp = curbp;
  315.     strcpy(tmpnam, bp->b_fname);    /* save the original name */
  316.     strcpy(bp->b_fname, bname1);    /* set it to our new one */
  317.  
  318.     /* write it out, checking for errors */
  319.     if (writeout(filnam1, "w") != TRUE) {
  320.         mlwrite(TEXT2);
  321. /*                      "[Cannot write filter file]" */
  322.         strcpy(bp->b_fname, tmpnam);
  323.         return(FALSE);
  324.     }
  325.  
  326.     strcat(line," <fltinp >fltout");
  327.     movecursor(term.t_nrow, 0);
  328.     TTkclose();
  329.     system(line);
  330.     TTkopen();
  331.         sgarbf = TRUE;
  332.     s = TRUE;
  333.  
  334.     /* on failure, escape gracefully */
  335.     if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
  336.         mlwrite(TEXT3);
  337. /*                      "[Execution failed]" */
  338.         strcpy(bp->b_fname, tmpnam);
  339.         unlink(filnam1);
  340.         unlink(filnam2);
  341.         return(s);
  342.     }
  343.  
  344.     /* reset file name */
  345.     strcpy(bp->b_fname, tmpnam);    /* restore name */
  346.     bp->b_flag |= BFCHG;        /* flag it as changed */
  347.     upmode();
  348.  
  349.     /* and get rid of the temporary file */
  350.     unlink(filnam1);
  351.     unlink(filnam2);
  352.     return(TRUE);
  353. }
  354.  
  355. rename(oldname, newname)    /* rename a file */
  356.  
  357. char *oldname;        /* original file name */
  358. char *newname;        /* new file name */
  359.  
  360. {
  361.     Frename(0, oldname, newname);
  362. }
  363.  
  364. /* return a system dependant string with the current time */
  365.  
  366. char *PASCAL NEAR timeset()
  367.  
  368. {
  369.     register char *sp;    /* temp string pointer */
  370.     char buf[16];        /* time data buffer */
  371.  
  372.     time(buf);
  373.     sp = ctime(buf);
  374.     sp[strlen(sp)-1] = 0;
  375.     return(sp);
  376. }
  377.  
  378. /*    FILE Directory routines        */
  379.  
  380. static DMABUFFER info;        /* Info about the file */
  381. char xpath[NFILEN];        /* path of file to find */
  382. char rbuf[NFILEN];        /* return file buffer */
  383.  
  384. /*    do a wild card directory search (for file name completion) */
  385.  
  386. char *PASCAL NEAR getffile(fspec)
  387.  
  388. char *fspec;    /* file to match */
  389.  
  390. {
  391.     register int index;        /* index into various strings */
  392.     register int point;        /* index into other strings */
  393.     register int extflag;        /* does the file have an extention? */
  394.     char fname[NFILEN];        /* file/path for DOS call */
  395.  
  396.     /* first parse the file path off the file spec */
  397.     strcpy(path, fspec);
  398.     index = strlen(xpath) - 1;
  399.     while (index >= 0 && (xpath[index] != '/' &&
  400.                 xpath[index] != '\\' && xpath[index] != ':'))
  401.         --index;
  402.     xpath[index+1] = 0;
  403.  
  404.     /* check for an extension */
  405.     point = strlen(fspec) - 1;
  406.     extflag = FALSE;
  407.     while (point >= index) {
  408.         if (fspec[point] == '.') {
  409.             extflag = TRUE;
  410.             break;
  411.         }
  412.         point--;
  413.     }
  414.  
  415.     /* construct the composite wild card spec */
  416.     strcpy(fname, xpath);
  417.     strcat(fname, &fspec[index+1]);
  418.     strcat(fname, "*");
  419.     if (extflag == FALSE)
  420.         strcat(fname, ".*");
  421.  
  422.     /* and call for the first file */
  423.     Fsetdta(&info);        /* Initialize buffer for our search */
  424.     if (Fsfirst(fname, 0xF7) != AE_OK)
  425.         return(NULL);
  426.  
  427.     /* skip over the . and .. entries */
  428.     while (strncmp(info.d_fname, "..", strlen(info.d_fname)) == 0)
  429.         if (Fsnext != AE_OK)
  430.             return(NULL);
  431.  
  432.     /* return the first file name! */
  433.     strcpy(rbuf, xpath);
  434.     strcat(rbuf, info.d_fname);
  435.     mklower(rbuf);
  436.     if (info.d_fattr & 0x10)
  437.         strcat(rbuf, DIRSEPSTR);
  438.     return(rbuf);
  439. }
  440.  
  441. char *PASCAL NEAR getnfile()
  442.  
  443. {
  444.  
  445.     /* and call for the first file */
  446.     if (Fsnext() != AE_OK)
  447.         return(NULL);
  448.  
  449.     /* return the first file name! */
  450.     strcpy(rbuf, xpath);
  451.     strcat(rbuf, info.d_fname);
  452.     mklower(rbuf);
  453.     return(rbuf);
  454. }
  455.  
  456. #if    LATTICE
  457. system(cmd)    /* call the system to execute a new program */
  458.  
  459. char *cmd;    /* command to execute */
  460.  
  461. {
  462.     char *pptr;            /* pointer into program name */
  463.     char pname[NSTRING];        /* name of program to execute */
  464.     char tail[NSTRING];        /* command tail */
  465.  
  466.     /* scan off program name.... */
  467.     pptr = pname;
  468.     while (*cmd && (*cmd != ' ' && *cmd != '\t'))
  469.         *pptr++ = *cmd++;
  470.     *pptr = 0;
  471.  
  472.     /* create program name length/string */
  473.     tail[0] = strlen(cmd);
  474.     strcpy(&tail[1], cmd);
  475.  
  476.     /* go do it! */
  477.     return(gemdos(        (int)EXEC,
  478.                 (int)0,
  479.                 (char *)pname,
  480.                 (char *)tail,
  481.                 (char *)NULL));
  482. }
  483. #endif
  484.  
  485. #else
  486. TOShello()
  487. {
  488. }
  489. #endif
  490.