home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / INTERNET / UPC2S1.ZIP / MLIB.C < prev    next >
C/C++ Source or Header  |  1993-09-20  |  15KB  |  436 lines

  1. /*--------------------------------------------------------------------*/
  2. /*       m l i b . c                                                  */
  3. /*--------------------------------------------------------------------*/
  4.  
  5. /*--------------------------------------------------------------------*/
  6. /*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
  7. /*       Wonderworks.                                                 */
  8. /*                                                                    */
  9. /*       All rights reserved except those explicitly granted by       */
  10. /*       the UUPC/extended license agreement.                         */
  11. /*--------------------------------------------------------------------*/
  12.  
  13. /*--------------------------------------------------------------------*/
  14. /*                          RCS Information                           */
  15. /*--------------------------------------------------------------------*/
  16.  
  17. /*
  18.  *    $Id: mlib.c 1.6 1993/09/20 04:39:51 ahd Exp $
  19.  *
  20.  *    Revision history:
  21.  *    $Log: mlib.c $
  22.  * Revision 1.6  1993/09/20  04:39:51  ahd
  23.  * OS/2 2.x support
  24.  *
  25.  * Revision 1.5  1993/08/11  02:31:12  ahd
  26.  * Use standard denormalize() macro for slash --> back slashes
  27.  *
  28.  * Revision 1.4  1993/08/03  03:11:49  ahd
  29.  * Further Windows 3.x fixes
  30.  *
  31.  * Revision 1.3  1993/07/31  16:26:01  ahd
  32.  * Changes in support of Robert Denny's Windows support
  33.  *
  34.  *
  35.  * 13 May 89      Use PC format path names for editor
  36.  * 01 Oct 89      Make Console_fgets use far pointers
  37.  *                Alter Console_fgets and Is_Console to type boolean
  38.  *
  39.  * 29 Jul 90      Use PC format path names for pager
  40.  */
  41.  
  42. /*
  43.    ibmpc/mlib.c   by <skl@van-bc.UUCP>   August/87
  44.  
  45.    Mailer UA system-dependent library
  46.  
  47.    Services to provide in mlib.c:
  48.  
  49.    Get a single character from the console.
  50.    Invoke the local editor on a given file.
  51.    Determine if a given file stream points to the console.
  52.    Get a line from the console.
  53.    Invoke a local pager on a given file.
  54.  
  55. */
  56.  
  57. /*--------------------------------------------------------------------*/
  58. /*                        System include files                        */
  59. /*--------------------------------------------------------------------*/
  60.  
  61. #include <stdlib.h>
  62. #include <stdio.h>
  63. #include <string.h>
  64. #include <conio.h>
  65. #include <io.h>
  66. #include <dos.h>
  67.  
  68. #if defined(WIN32)
  69. #include <windows.h>
  70. #endif
  71.  
  72. /*--------------------------------------------------------------------*/
  73. /*                    UUPC/extended include files                     */
  74. /*--------------------------------------------------------------------*/
  75.  
  76. #include "lib.h"
  77. #include "hlib.h"
  78. #include "execute.h"
  79.  
  80. /*--------------------------------------------------------------------*/
  81. /*                    Set up for console services                     */
  82. /*--------------------------------------------------------------------*/
  83.  
  84. #if defined(FAMILYAPI) || defined(BIT32ENV) || defined(_Windows)
  85. #define SIMPLE_CONSOLE_FGETS
  86. #else
  87.  
  88. #define MULTIPLEX 0x2f        /* 8086 DOS Interrupt for multiplexing */
  89.  
  90. static int DOSRead( char *buff, const int buflen);
  91.  
  92. static boolean DOSKeyActive( void );
  93.  
  94. static int DOSKeyRead( char *buff , int buflen );
  95.  
  96. #endif
  97.  
  98. /*--------------------------------------------------------------------*/
  99. /*       G e t _ O n e                                                */
  100. /*                                                                    */
  101. /*       Get a single character from the console                      */
  102. /*--------------------------------------------------------------------*/
  103.  
  104. int Get_One()
  105. {
  106.  
  107.    return getch();
  108.  
  109. } /*Get_One*/
  110.  
  111. /*--------------------------------------------------------------------*/
  112. /*       I n v o k e                                                  */
  113. /*                                                                    */
  114. /*       Invoke the user's editor or pager to handle a text file      */
  115. /*--------------------------------------------------------------------*/
  116.  
  117. int Invoke(const char *ecmd, const char *filename)
  118. {
  119.    char command[FILENAME_MAX*2 + 1];
  120.    char tempname[FILENAME_MAX];
  121.  
  122.    if (ecmd == nil(char))
  123.    {
  124.       printf("Invoke: No program specified to invoke.\n");
  125.       return 1;
  126.    }
  127.  
  128.    strcpy(tempname,filename);
  129.    denormalize( tempname );
  130.  
  131.    sprintf(command, ecmd, tempname);
  132.  
  133.    if(executeCommand(command, NULL, NULL, TRUE, TRUE ) != 0)
  134.    {
  135.       printf("Invoke: \"%s\" failed.\n", command);
  136.       return(2);
  137.    }
  138.  
  139.    return 0;
  140.  
  141. } /* Invoke */
  142.  
  143. /*--------------------------------------------------------------------*/
  144. /*       I s _ C o n s o l e                                          */
  145. /*                                                                    */
  146. /*       Determine if stream is from the console                      */
  147. /*                                                                    */
  148. /*       Note:  isatty() actually returns if the stream is a          */
  149. /*       character device, thus causing device NUL to appear          */
  150. /*       interactive; this is not acceptable, but there is not a      */
  151. /*       trivial fix.                                                 */
  152. /*--------------------------------------------------------------------*/
  153.  
  154. boolean Is_Console(FILE *stream)
  155. {
  156.  
  157.    return isatty(fileno(stream));
  158.  
  159. } /*Is_Console*/
  160.  
  161. #ifdef SIMPLE_CONSOLE_FGETS
  162.  
  163. /*--------------------------------------------------------------------*/
  164. /*       C o n s o l e _ f g e t s                                    */
  165. /*                                                                    */
  166. /*       Read a full line from the console under non-DOS systems      */
  167. /*--------------------------------------------------------------------*/
  168.  
  169. boolean Console_fgets(char *buff, int buflen, char *prompt)
  170. {
  171.  
  172.    if (bflag[F_DOSKEY] )
  173.    {
  174.      printmsg(0,"DOSKEY support not available, option disabled");
  175.      bflag[F_DOSKEY] = FALSE;
  176.    }
  177.  
  178.    fputs(prompt, stdout);
  179.  
  180.    return (fgets(buff, buflen, stdin) != nil(char)) ? TRUE : FALSE;
  181.  
  182. } /*Console_fgets*/
  183.  
  184. #else
  185.  
  186. /*--------------------------------------------------------------------*/
  187. /*       C o n s o l e _ f g e t s                                    */
  188. /*                                                                    */
  189. /*       Get a line of input from the local console                   */
  190. /*                                                                    */
  191. /*       This is a hook to allow for using the local system's         */
  192. /*       facility for input line editing.  We call DOS to perform     */
  193. /*       a line read, thus allowing utilities like DOSEDIT or CED     */
  194. /*       to do their fancy work.                                      */
  195. /*--------------------------------------------------------------------*/
  196.  
  197. boolean Console_fgets(char *buff, int buflen, char *prompt)
  198. {
  199.    static boolean eof = FALSE;    /* pending EOF flag  */
  200.  
  201.    char *eofptr;
  202.  
  203.    if (eof) {           /* have a pending EOF?  */
  204.       eof = FALSE;      /* no more pending EOF  */
  205.       return FALSE;     /* signal the EOF    */
  206.    }
  207.  
  208. /*--------------------------------------------------------------------*/
  209. /*      Prompt the user, read the data, and then go to a new line     */
  210. /*--------------------------------------------------------------------*/
  211.  
  212.    fputs(prompt, stdout);
  213.  
  214.    if ( DOSKeyActive() )
  215.       buflen = DOSKeyRead( buff, buflen );
  216.    else
  217.       buflen = DOSRead( buff, buflen );
  218.     putchar('\n');
  219.  
  220. /*--------------------------------------------------------------------*/
  221. /*             Determine if we hit end of file on the read            */
  222. /*--------------------------------------------------------------------*/
  223.  
  224.    if ( buflen == -1 )
  225.    {
  226.       *buff = '\0';
  227.       return FALSE;
  228.    }
  229.  
  230. /*--------------------------------------------------------------------*/
  231. /*                        Terminate the buffer                        */
  232. /*--------------------------------------------------------------------*/
  233.  
  234.    buff[buflen] = '\n';
  235.    buff[buflen + 1] = '\0';
  236.  
  237.    if ((eofptr = strchr(buff, '\x1a')) == nil(char))
  238.       return TRUE;      /* an ordinary successful read   */
  239.    else if (eofptr == buff)
  240.    {
  241.       return FALSE;     /* signal EOF right away      */
  242.    }
  243.    else {
  244.       eof = TRUE;       /* we now have a pending EOF  */
  245.       *eofptr = '\0';
  246.       return TRUE;      /* read successful but EOF next  */
  247.    } /* else */
  248.  
  249. } /*Console_fgets*/
  250.  
  251. /*--------------------------------------------------------------------*/
  252. /*       D O S R e a d                                                */
  253. /*                                                                    */
  254. /*       Read from console under DOS without DOSKEY.  We use DOS      */
  255. /*       services rather than the C library to insure we such hooks   */
  256. /*       are CED are used if the user installed them.                 */
  257. /*--------------------------------------------------------------------*/
  258.  
  259. static int DOSRead( char *buff, const int buflen)
  260. {
  261.    union REGS regs;
  262.    struct SREGS sregs;
  263.  
  264.    struct {
  265.       unsigned char maximum, actual;
  266.       char buffer[255];
  267.    } request;
  268.  
  269.    char far *p = (char far *) &request;
  270.  
  271. /*--------------------------------------------------------------------*/
  272. /*            Set up the address of our read buffer for DOS           */
  273. /*--------------------------------------------------------------------*/
  274.  
  275.    sregs.ds = FP_SEG( p );    /* Use segment of the buffer           */
  276.    regs.x.dx = (unsigned int)(&request);
  277.    request.maximum = (unsigned char) min( buflen - 1,
  278.                                           sizeof request.buffer);
  279.    regs.h.ah = 0x0a;          /* Buffered keyboard input             */
  280.  
  281. /*--------------------------------------------------------------------*/
  282. /*                  Invoke the buffered console read                  */
  283. /*--------------------------------------------------------------------*/
  284.  
  285.    intdosx(®s, ®s, &sregs);
  286.  
  287. /*--------------------------------------------------------------------*/
  288. /*                        Now return the result                       */
  289. /*--------------------------------------------------------------------*/
  290.  
  291.    memcpy( buff, request.buffer, request.actual );
  292.    return (unsigned int) request.actual;
  293.  
  294. } /* DOSRead */
  295.  
  296. /*--------------------------------------------------------------------*/
  297. /*       D O S K e y A c t i v e                                      */
  298. /*                                                                    */
  299. /*       Determine if the DOS Key command line editor is active       */
  300. /*--------------------------------------------------------------------*/
  301.  
  302. static boolean DOSKeyActive( void )
  303. {
  304.    static boolean first_pass = TRUE;
  305.    static boolean active = FALSE;
  306.  
  307.    if ( first_pass )
  308.    {
  309.       first_pass = FALSE;
  310.       if ((_osmajor > 4) )
  311.       {
  312.          union REGS regs;
  313.  
  314. #ifdef __TURBOC__
  315.          if ( getvect( MULTIPLEX ) == NULL )
  316. #else
  317.          if ( _dos_getvect( MULTIPLEX ) == NULL )
  318. #endif
  319.             printmsg(0,"Multiplex interrupt not installed???\n");
  320.          else {
  321.             regs.x.ax = 0x4800;     /* Request for DOS Key active */
  322.             int86( MULTIPLEX , ®s, ®s );
  323.             if ( regs.h.al != 0x00 )
  324.                active = TRUE;
  325.          }
  326.       } /* if (_osmajor > 4 ) */
  327.    } /* if ( first_pass ) */
  328.  
  329. /*--------------------------------------------------------------------*/
  330. /*                          Return to caller                          */
  331. /*--------------------------------------------------------------------*/
  332.  
  333.    if ( bflag[F_DOSKEY] && ! active )
  334.    {
  335.      printmsg(0,"DOSKEY support not installed, option disabled");
  336.      bflag[F_DOSKEY] = FALSE;
  337.    }
  338.  
  339.    return active;
  340.  
  341. } /* DOSKeyActive */
  342.  
  343.  
  344. /*--------------------------------------------------------------------*/
  345. /*    D O S K e y R e a d                                             */
  346. /*                                                                    */
  347. /*    Read a line from the terminal using DOS Key                     */
  348. /*--------------------------------------------------------------------*/
  349.  
  350. static int DOSKeyRead( char *buff , int buflen )
  351. {
  352.    union REGS regs;
  353.    struct SREGS sregs;
  354.  
  355.    struct {
  356.       unsigned char maximum, actual;
  357.       char buffer[126];
  358.    } request;
  359.  
  360.    char far *p = (char far *) &request;
  361.  
  362. /*--------------------------------------------------------------------*/
  363. /*                   Set up for the DOSKEY read call                  */
  364. /*--------------------------------------------------------------------*/
  365.  
  366.    sregs.ds = FP_SEG( p );    /* Use segment of the buffer           */
  367.    regs.x.dx = (unsigned int)(&request);
  368.    regs.x.ax = 0x4810;
  369.    request.maximum = (unsigned char) min( buflen - 1, sizeof request );
  370.  
  371. /*--------------------------------------------------------------------*/
  372. /*                      Issue the call to DOSKEY                      */
  373. /*--------------------------------------------------------------------*/
  374.  
  375.    int86x( MULTIPLEX, ®s, ®s, &sregs );
  376.  
  377. /*--------------------------------------------------------------------*/
  378. /*                          Check the result                          */
  379. /*--------------------------------------------------------------------*/
  380.  
  381.    if ( regs.x.ax == 0 )      /* Function succeed?                */
  382.    {
  383.       buflen = request.actual;
  384.       memcpy( buff, request.buffer , buflen );
  385.    } /* if ( regs.x.ax == 0 ) */
  386.    else {                        /* Function failed, report it    */
  387.       printmsg(0,"DOSKEY read failed!");
  388.       buflen = -1;
  389.    } /* else */
  390.  
  391. /*--------------------------------------------------------------------*/
  392. /*                          Return to caller                          */
  393. /*--------------------------------------------------------------------*/
  394.  
  395.    return buflen;
  396.  
  397. } /* DOSKeyRead */
  398.  
  399. #endif
  400.  
  401. /*--------------------------------------------------------------------*/
  402. /*       C l e a r                                                    */
  403. /*                                                                    */
  404. /*       Clear the screen                                             */
  405. /*--------------------------------------------------------------------*/
  406.  
  407. void ClearScreen()
  408. {
  409.  
  410. #ifdef __TURBOC__
  411.  
  412.    clrscr();
  413.  
  414. #elif defined(WIN32)
  415.  
  416.    long mode;
  417.    static COORD coord = {0, 0};
  418.    static HANDLE cons_hnd = INVALID_HANDLE_VALUE;
  419.  
  420.    if (cons_hnd == INVALID_HANDLE_VALUE)
  421.    {
  422.       cons_hnd = GetStdHandle(STD_OUTPUT_HANDLE);
  423.       GetConsoleMode(cons_hnd, &mode);
  424.       mode |= ENABLE_PROCESSED_OUTPUT;
  425.       SetConsoleMode(cons_hnd, mode);
  426.    }
  427.  
  428.    SetConsoleCursorPosition(cons_hnd, coord);
  429.    FillConsoleOutputCharacter(cons_hnd, 0x20, 60*132, coord, &mode);
  430.  
  431. #else
  432.    fputs("\033[2J", stdout);        /* ANSI Erase screen           */
  433. #endif
  434.  
  435. } /* ClearScreen */
  436.