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