home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / QPROC.ZIP / QPSEPRAT.C < prev    next >
C/C++ Source or Header  |  1990-10-18  |  18KB  |  822 lines

  1. /********************************************************************/
  2. /**                     Microsoft LAN Manager                      **/
  3. /**               Copyright(c) Microsoft Corp., 1987-1990          **/
  4. /********************************************************************/
  5.  
  6. /*
  7.  * @(#) separat.c
  8.  *        Spooler Separator utility 
  9.  * 
  10.  * Copyright (C) Microsoft Corporation, 1986
  11.  * Portions of this program have been prerecorded.
  12.  *
  13.  *    Exports:
  14.  *        PrintSep
  15.  *
  16.  */
  17.  
  18.  
  19.  
  20. #define INCL_DEV
  21. #define INCL_DOSINFOSEG
  22.  
  23. #include "pmprint.h"
  24.  
  25. #include <netlib.h>
  26. #include "strapi.h"
  27.  
  28. #define FileFindBuf FILEFINDBUF
  29. #define file_size cbFile
  30.  
  31. #include <ctype.h>
  32. #include <time.h>
  33.  
  34.  
  35. /*
  36.  *
  37.  *    Forward ref. and external ref.
  38.  */
  39.  
  40. extern void    GetFullNameFromId(char far *, char far *, USHORT, BOOL);
  41. extern void    GetNameFromId( char far *, USHORT, BOOL);
  42. /*
  43. int cdecl    net_format_time_of_day(long far *, char far *, int);
  44. int cdecl    net_ctime(struct time_t far *, char far *, int, int);
  45. */
  46.  
  47. int        SeparatBlockWrite(PDEVICESPL, char far *, USHORT);
  48. int        SeparatDevWrite(PDEVICESPL, char far *, USHORT);
  49. int        SeparatSepWrite(PDEVICESPL, char far *, USHORT);
  50. int        DoDefaultPrintSep(PDEVICESPL);
  51. int        DoPrintSep(PDEVICESPL, char far *);
  52. int        convert(int);
  53. int        SeparatFileWrite(PDEVICESPL, char far *);
  54. VOID        GetSpoolDir(PDEVICESPL);
  55.  
  56. void        GetDateString(char far *, int);
  57. void        GetTimeString(char far *, int);
  58. void        itoa2(char far *, unsigned);
  59.  
  60. /*
  61.  * external variable
  62.  *
  63.  */
  64.  
  65.  
  66. /*
  67.  *    Contents of default separator
  68.  */
  69. char *PQ_SEP = "@@B@S@N@4 @B@S@I@4  @U@L   @D@1 @E";
  70.  
  71. /*
  72.  *  10 newlines
  73.  */
  74. char  *newline = "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n";
  75.  
  76. /*
  77.  *    Local Literal
  78.  *
  79.  */
  80.  
  81. #define    PAGECHAR        '\14'
  82.  
  83. char PageChar = PAGECHAR;
  84.  
  85.  
  86. /*
  87.  *    GetDateString  -- Get date in standard format
  88.  *        NOTE: This routine will print the current date NOT the spooled date
  89.  *    Input:
  90.  *        Buf pointer to contain mm/dd/yy (or NLS equivalent)
  91.  *
  92.  */
  93. void
  94. GetDateString(buf, size)
  95. char far *buf;
  96. int size;
  97. {
  98.     char tmpbuf[32];
  99.     char far * ptmp;
  100.     GINFOSEG FAR * pInfoSeg = MAKEPGINFOSEG(selGlobalSeg);
  101.     ULONG ltime;
  102.  
  103.     ltime = pInfoSeg->time;
  104.     net_ctime(<ime, tmpbuf, sizeof(tmpbuf), 2);
  105.     ptmp = strchrf(tmpbuf, ' ');
  106.     *ptmp = '\0';
  107.     strncpyf(buf, tmpbuf, size);
  108.     return;
  109. }
  110.  
  111.  
  112. /*
  113.  *    GetTimeString  -- Get time,in hh:mm:ss(or NLS equivalent) form
  114.  *
  115.  *        NOTE: This routine will print the current time NOT the spooled time
  116.  *
  117.  */
  118. void
  119. GetTimeString(buf, size)
  120. char far *buf;
  121. int size;
  122. {
  123.  
  124.     char tmpbuf[32];
  125.     char far * ptmp;
  126.     GINFOSEG FAR * pInfoSeg = MAKEPGINFOSEG(selGlobalSeg);
  127.     ULONG ltime;
  128.  
  129.     ltime = pInfoSeg->time;
  130.     net_ctime(<ime, tmpbuf, (int)sizeof(tmpbuf), 2);
  131.     ptmp = strchrf(tmpbuf, ' ');
  132.  
  133.     while(*ptmp == ' ') ptmp++;
  134.  
  135.     strncpyf(buf, ptmp, size);
  136.     return;
  137. }
  138.  
  139.  
  140. /****
  141.  *    Note that we will ignore the restart signal when writing
  142.  *    Separator
  143.  *
  144.  */
  145.  
  146. int convert(c)
  147. int c;
  148. {
  149.     if (isdigit(c))
  150.         return (c-'0');
  151.     else if (isupper(c))
  152.         return ( c-'A'+10);
  153.     else 
  154.         return ( c- 'a'+10);
  155.  
  156. }
  157.  
  158. /***    SeparatBlockWrite - do the actual block printing
  159.  *
  160.  *    SeparatBlockWrite( dev, string, length)
  161.  *
  162.  *    Inputs: fd    - dos file descriptor
  163.  *        string    - the ascii characters to be printed
  164.  *        length    - the number of characters to be printed
  165.  *              if zero do nothing
  166.  *    Returns 
  167.  *              OKSIG, KILLSIG
  168.  */
  169.  
  170. int
  171. SeparatBlockWrite( pdev, string, length )
  172. PDEVICESPL pdev;
  173. char far *string;
  174. USHORT      length;
  175. {
  176.     register int k;
  177.     register int j;
  178.     int  i, n;
  179.     char bfr[MAXLINE+2];
  180.     unsigned char c;
  181.     extern unsigned char Font_Bits[];
  182.     int Linelength;
  183.     int mode;
  184.     int sts;
  185.  
  186.     mode = pdev->d_mode;
  187.     Linelength = pdev->d_linelen;
  188.  
  189.  
  190.     n = (mode == 'M' ? 16 : 8);    /* width of one block char. */
  191.     if (length == 0)
  192.         return (OKSIG);
  193.     else if (length > Linelength / n)
  194.         length = Linelength / n;
  195.  
  196.  
  197.     for(i=8; i > 0; i--) {            /* 8 lines */
  198.         k = 0;
  199.         for(j = 0; j < length; j++) {        /* characters in string */
  200.             /*
  201.              * find this character in the font table
  202.              * and byte for this row  ( + 8-i )
  203.              */
  204.             c = Font_Bits[ ( (unsigned)string[ j ] * 8 ) + 8 - i ];
  205.  
  206.             if( mode == 'M' ) {
  207.                 /*
  208.                  * double width characters are just two '*'
  209.                  * per bit in the font table
  210.                  */
  211.                 n = k + 8*2;    /* 16 bytes */
  212.                 for (; k < n; k+= 2) {
  213.                     if( c & 0x80 ) {
  214.                         bfr[k] = '@';
  215.                         bfr[k+1] = '@';
  216.                     } else {
  217.                         bfr[k] = ' ';
  218.                         bfr[k+1] = ' ';
  219.                     }
  220.                     c = c << 1;
  221.                 }
  222.             } else {
  223.                 n = k + 8;        /* 8 bytes */
  224.                 while (k  < n)  {    /* bits in a byte */
  225.                     if( c & 0x80 )
  226.                         bfr[k] = '@';
  227.                     else
  228.                         bfr[k] = ' ';
  229.                     c = c << 1;
  230.                     k++;
  231.                 }
  232.             }
  233.         }
  234.         bfr[k++]  = '\n';
  235.         bfr[k++]  = '\r';
  236.         if ((sts =SeparatDevWrite(pdev, bfr, (unsigned) k)) == KILLSIG)
  237.             return (sts);
  238.     }
  239.     return (OKSIG);
  240.         
  241. }
  242.  
  243.  
  244.  
  245. /*
  246.  *    SeparatSepWrite --
  247.  */
  248. int 
  249. SeparatSepWrite(pdev, buf, len)
  250. PDEVICESPL pdev;
  251. char far *buf;
  252. USHORT len;
  253. {
  254.     if (pdev->d_mode == 'U' )
  255.         return SeparatDevWrite(pdev,buf,len);
  256.     else
  257.         return SeparatBlockWrite(pdev,buf,len);
  258. }
  259.  
  260. /*
  261.  *    DoPrintSep
  262.  *    Input:
  263.  *        dev -- pointer to the active PDEVICESPL.
  264.  *        buf -- in-memory separator macro, null-terminated
  265.  */
  266. int
  267. DoPrintSep(pdev, buf)
  268. PDEVICESPL pdev;
  269. char far *buf;
  270. {
  271.     register int i;
  272.     register char    c;
  273.     char  esc;
  274.     char    ch;
  275.     int    n;
  276.     int status;
  277.     char far *end;
  278.     char far *endln;
  279.     char date[50];
  280.     int pos=0;    /* current position */
  281.     int len;
  282.     int new;
  283.         char line[MAXLINE+2*10];        /* plus ten cr-lf */
  284.         PSZ psz;
  285.  
  286.  
  287.     /*
  288.      * the very first character defines the escape character
  289.      */
  290.     esc = *buf; 
  291.  
  292.     status = OKSIG;
  293.  
  294.     for( i=1 ;status != KILLSIG;) {
  295.  
  296.         /*
  297.          * if we are not on an escape character, get a new character
  298.          * and exit loop when no more characters incomming
  299.          */
  300.         while ((c = buf[i]) !=esc && c != '\0')
  301.             i++;
  302.  
  303.  
  304.         if( (c = buf[i++]) == '\0' )
  305.             break;
  306.  
  307.         /*
  308.          * get the next character (after the escape) and
  309.          * exit loop when no more characters incomming
  310.          */
  311.         if( (c = buf[i++]) == '\0' )
  312.             break;
  313.  
  314.  
  315.                 psz = NULL;
  316.  
  317.         /*
  318.          * THE BIG SWITCH STATEMENT
  319.          * we have <esc> followed by a control character
  320.          */
  321.         switch( c ) {
  322.  
  323.         case 'L':            /* @Lstring */
  324.             end = strchrf(buf+i, esc);
  325.  
  326.             if((endln = strchrf(buf+i, '\r')) != NULL)
  327.                 if(*(endln+1) != '\n')
  328.                 endln = NULL;
  329.  
  330.             while((status != KILLSIG)&&
  331.                   (endln != NULL)&&
  332.                   ((endln < end)||(end == NULL)))
  333.             {
  334.  
  335.                 n = endln+2 - buf-i;
  336.  
  337.                 if (n > 0) {
  338.                     if (pdev->d_mode != 'U')
  339.                         status = SeparatBlockWrite(pdev,buf+i, n);
  340.                     else    {
  341.                         new = pos+n;
  342.                         if (new > MAXLINE)
  343.                         new = MAXLINE;
  344.  
  345.                         memcpyf(line+pos, buf+i, new-pos);
  346.  
  347.                         if (pdev->d_linelen  < new)
  348.                         new = pdev->d_linelen;
  349.  
  350.                         status = SeparatDevWrite(pdev,(char far *)line, new);
  351.                         pos = 0;
  352.                     }
  353.                     i += n;
  354.                 };
  355.  
  356.             if((endln = strchrf(buf+i, '\r')) != NULL)
  357.                 if(*(endln+1) != '\n')
  358.                 endln = NULL;
  359.             };
  360.  
  361.  
  362.             if (end == NULL) 
  363.                 n = SafeStrlen(buf+i);
  364.             else
  365.                 n = end - buf-i;
  366.  
  367.             if (n > 0) {
  368.                 if (pdev->d_mode != 'U')
  369.                     status = SeparatBlockWrite(pdev,buf+i, n);
  370.                 else    {
  371.                     new = pos+n;
  372.                     if (new > MAXLINE)
  373.                         new = MAXLINE;
  374.  
  375.                     memcpyf(line+pos, buf+i, new-pos);
  376.                     pos = new;
  377.                 }
  378.                 i += n;
  379.             }
  380.             break;
  381.  
  382.         case 'F':            /* @F"filespec" */
  383.             /*
  384.              * Flush the line buffer
  385.               * truncate the rest of it
  386.               */
  387.             if (pdev->d_linelen  < pos)
  388.                 pos = pdev->d_linelen;
  389.             status = SeparatDevWrite(pdev, line, pos);
  390.             pos = 0;
  391.             end = strchrf(buf+i, esc);
  392.             if (end == NULL) 
  393.                 n = SafeStrlen(buf+i);
  394.             else
  395.                 n = end - buf-i;
  396.                         /*  line to store file name */
  397.             memcpyf(line, buf+i, n);
  398.             i += n;            /* forward ptr */
  399.             line[n] = '\0';
  400.             status = SeparatFileWrite(pdev, line);    /* write the file */
  401.             
  402.             break;
  403.  
  404.  
  405.         case 'D':            /* @D - print date */
  406.                         /* in mm/dd/yy form */
  407.         case 'T':            /* @T - print time */
  408.                         /* in hh:mm:ss form */
  409.             if (c == 'D' )
  410.                 GetDateString(date, sizeof(date));
  411.             else
  412.                 GetTimeString(date, sizeof(date));
  413.  
  414.                         psz = date;
  415.             break;
  416.  
  417.  
  418.         case 'N':            /* @N - print Net Name */
  419.                         if (!*(psz = pdev->d_szUser))
  420.                             psz = NULL;
  421.             break;
  422.  
  423.         case 'I':            /* @I - print queue id    (Name)*/
  424.                         psz = pdev->d_pQProc->pszQName;
  425.             break;
  426.  
  427.         case 'H':            /* @Hnn - print char equ of */
  428.                         /* hex nn */
  429.  
  430.             if (buf[i] != '\0' && buf[i+1] != '\0' && pos < MAXLINE) {
  431.                 if (isxdigit(buf[i]) && isxdigit(buf[i+1]) ) {
  432.                     ch = (char) (convert(buf[i])*16 + 
  433.                     convert(buf[i+1])); 
  434.                     i+= 2;
  435.                     if (pdev->d_mode != 'U')
  436.                         status = SeparatBlockWrite(pdev,&ch, 1 );
  437.                     else    
  438.                         line[pos++] = ch;
  439.                 }
  440.             }
  441.  
  442.             break;
  443.  
  444.         case 'W':        /* set output page width in chars */
  445.             /* The old value remains unchanged if new one is
  446.              * unreasonable. */
  447.             n = 0;
  448.             while ( isdigit(buf[i])) {
  449.                 n = 10 * n + ((int)buf[i] - (int)'0');
  450.                 i++;
  451.             }
  452.             if ( n > 40 && n <= MAXLINE)
  453.                 pdev->d_linelen  =  n;
  454.             break;
  455.  
  456.     /*
  457.      * line skipping
  458.      */
  459.         case '9':            /* skip 9 lines */
  460.         case '8':            /* skip 8 lines */
  461.         case '7':            /* skip 7 lines */
  462.         case '6':            /* skip 6 lines */
  463.         case '5':            /* skip 5 lines */
  464.         case '4':            /* skip 4 lines */
  465.         case '3':            /* skip 3 lines */
  466.         case '2':            /* skip 2 lines */
  467.         case '1':            /* skip 1 line */
  468.         case '0':            /* end of line */
  469.             n =  (c-'0')*2+ 2;
  470.             /*
  471.              * truncate the rest of it
  472.              */
  473.             if (pdev->d_linelen  < pos)
  474.                 pos = pdev->d_linelen;
  475.             memcpyf(line+pos, newline, n);
  476.             pos +=n;
  477.             status = SeparatDevWrite(pdev,(char far *)line, pos);
  478.  
  479.             pos = 0;
  480.             break;
  481.     /*
  482.      * mode switching
  483.      */
  484.         case 'S':            /* single width */
  485.         case 'M':            /* double width */
  486.         case 'B':            /* set block character mode */
  487.         case 'U':            /* turn off block characters */
  488.             pdev->d_mode = c;
  489.             if (pos > 0 ) {
  490.                 /*
  491.                   * truncate the rest of it
  492.                   */
  493.                 if (pdev->d_linelen  < pos)
  494.                     pos = pdev->d_linelen;
  495.                 status = SeparatDevWrite(pdev, line, pos);
  496.                 pos = 0;
  497.             }
  498.             break;
  499.         case 'E':            /* eject page */
  500.             /*
  501.              * truncate the rest of it
  502.              */
  503.             if (pdev->d_linelen  < pos)
  504.                 pos = pdev->d_linelen;
  505.             line[pos++] = PageChar;
  506.             status = SeparatDevWrite(pdev, line, pos);
  507.             pos = 0;
  508.             break;
  509.         default:
  510.             break;
  511.         } //End of Switch
  512.  
  513.                 if (psz) {
  514.                     len = SafeStrlen(psz);
  515.                     if (pdev->d_mode != 'U') {
  516.                         status = SeparatBlockWrite(pdev, psz, len);
  517.                     } else {
  518.                         new = pos+len;
  519.                         if (new > MAXLINE)
  520.                             new = MAXLINE;
  521.  
  522.                         memcpyf(line+pos, psz, new-pos);
  523.                         pos = new;
  524.                     }
  525.                  }
  526.  
  527.         }  //End of For Loop
  528.  
  529.         //Now Flush The Buffer 
  530.         if (pos) {
  531.  
  532.            if (pdev->d_linelen < pos)
  533.                pos = pdev->d_linelen;
  534.            status = SeparatDevWrite(pdev, line, pos);
  535.  
  536.         }
  537.  
  538.     return (status);
  539. }
  540.  
  541.  
  542.  
  543. /*
  544.  * GetSepInfo -- Get Separator page info
  545.  *        Input:
  546.  *
  547.  *        Output:
  548.  *
  549.  *        We will open the separator mac file, if there is any
  550.  *        If there is anything wrong, we will always use the default
  551.  *
  552.  */
  553. int
  554. GetSepInfo(pQProc, pdev)
  555. PQPROCINST pQProc;
  556. PDEVICESPL pdev;
  557. {
  558.     register USHORT status;
  559.     PSZ separator ;
  560.     USHORT action, err;
  561.     CHAR buf1[512];
  562.     USHORT needed;
  563.     PPRJINFO3 pprj = (PPRJINFO3)buf1;
  564.     PPRQINFO pprq = (PPRQINFO)buf1;
  565.  
  566.  
  567.     pdev->d_mode = 'U';              /* no block **/
  568.     pdev->d_linelen = 80;            /* 80 characters per line */
  569.  
  570.     pdev->d_pQProc = pQProc;
  571.     pdev->d_pszPath = NULL;
  572.  
  573.  
  574.     /* get the job information */
  575.     if (!(err = DosPrintJobGetInfo(NULL, pQProc->uJobId, 3,
  576.                                    buf1, sizeof(buf1), &needed)) ||
  577.         err == ERROR_MORE_DATA && pprj->pszUserName &&
  578.         pprj->pszQueue) {
  579.         ;
  580.     } else {
  581.         return PROCERRORSIG;
  582.     }
  583.  
  584.     pdev->d_time = pprj->ulSubmitted;
  585.     strncpyf(pdev->d_szUser, pprj->pszUserName, UNLEN);
  586.  
  587.     /* using the queue name of the job information now get queue information */
  588.     if (!(err = DosPrintQGetInfo(NULL, pprj->pszQueue, 1,
  589.                                  buf1, sizeof(buf1), &needed)) ||
  590.         err == ERROR_MORE_DATA && pprq->pszSepFile) {
  591.         ;
  592.     } else {
  593.         LETGOSTRMEM(pdev);
  594.         return PROCERRORSIG;
  595.     }
  596.  
  597.     separator = pprq->pszSepFile;
  598.  
  599.     if (stricmpf(separator, DEFAULT_SEPARATOR) == 0) {
  600.         pdev->d_handle = NULL_HFILE;
  601.     } else {
  602.         if ((isascii(*separator) && *(separator+1) == ':' ) ) {
  603.             strcpyf(buf1, separator);
  604.         } else {
  605.             PSZ psz;
  606.  
  607.             GetSpoolDir(pdev);
  608.             psz = buf1;
  609.             if (pdev->d_pszPath)
  610.                 psz = strcpyf(buf1, pdev->d_pszPath);
  611.  
  612.             SafeStrcpy(EndStrcat(psz, "\\"), separator);
  613.         }
  614.  
  615.         /*
  616.          * Let's open the separator file
  617.          */
  618.  
  619.         status = DosOpen((PSZ)buf1,
  620.                          &pdev->d_handle,
  621.                          &action,
  622.                          0L,             /* size */
  623.                          FILE_READONLY,
  624.                          FILE_OPEN,                   /* fail, if not exists */
  625.                          OPEN_SHARE_DENYWRITE,
  626.                          0L);
  627.  
  628.         if (status) {
  629.             LETGOSTRMEM(pdev);
  630.             return SEPERRORSIG;
  631.         }
  632.     }
  633.     return OKSIG;
  634. }
  635.  
  636.  
  637.  
  638. /*
  639.  * PrintSep -- Print Separator file
  640.  *        Input:
  641.  *
  642.  *        Output:
  643.  *                      ...SIG
  644.  *
  645.  *              Print the separater page
  646.  *
  647.  */
  648. int
  649. PrintSep(pdev)
  650. PDEVICESPL pdev;
  651. {
  652.     INT status = OKSIG;
  653.     SEL selector = 0;
  654.     PBYTE segptr;
  655.     USHORT bytesread;
  656.     USHORT size;
  657.     FILEFINDBUF buf;
  658.     CHAR buf1[512];
  659.  
  660.     if (pdev->d_handle == NULL_HFILE) {
  661.         segptr = PQ_SEP;
  662.     } else {
  663.     /*
  664.      * Find the file size of separator
  665.          * should be very small
  666.      */
  667.     status = DosQFileInfo(pdev->d_handle, 1, (char far *)&buf, sizeof(buf) );
  668.  
  669.     if (status || buf.file_size > 65534)
  670.     {
  671.         LETGOSTRMEM(pdev);
  672.         return SEPERRORSIG;
  673.     }
  674.  
  675.     size = (USHORT)buf.file_size;
  676.  
  677.         segptr = buf1;
  678.  
  679.     if (size > sizeof(buf1) ) {
  680.             /* Allocate a seg so we can read at one time */
  681.             if (DosAllocSeg(size+1, &selector, 0 ) ) {
  682.                 LETGOSTRMEM(pdev);
  683.                 return PROCERRORSIG;
  684.             }
  685.  
  686.             segptr = MAKEP(selector, 0);
  687.     }
  688.  
  689.     status = OKSIG;
  690.     if (DosRead(pdev->d_handle, segptr, size,&bytesread)
  691.             || bytesread != size  )
  692.             status = PROCERRORSIG;
  693.  
  694.     DosClose(pdev->d_handle);
  695.  
  696.     segptr[size] = '\0';        /* Null terminated */
  697.     }
  698.     if (status == OKSIG)
  699.         status = DoPrintSep(pdev, segptr);
  700.  
  701.     if (selector)
  702.         DosFreeSeg(selector);
  703.  
  704.     LETGOSTRMEM(pdev);
  705.     return (status);
  706. }
  707.  
  708.  
  709.  
  710. int
  711. SeparatFileWrite(pdev, name)
  712. PDEVICESPL pdev;
  713. char far *name;
  714. {
  715.     int status;
  716.     char far * ptmp;
  717.     char buf[512];
  718.     HFILE handle;
  719.     USHORT    action;
  720.     USHORT bytesread;
  721.     ULONG    newpos;
  722.     USHORT      Restart;
  723.         USHORT namelen;
  724.  
  725.     /* remove newline chars and extra blanks from the name */
  726.     if((ptmp = strchrf(name,0x0D)) != NULL)
  727.         *ptmp = '\0';
  728.     if((ptmp = strchrf(name,0x0A)) != NULL)
  729.         *ptmp = '\0';
  730.  
  731.         //Parse The Quotes 
  732.         if (name 
  733.            && (*name == '\"') 
  734.            && (* (name + (namelen = strlenf(name)) - 1) == '\"')) {
  735.                  * (name + namelen - 1) = '\0';
  736.                  name++;
  737.         }
  738.          
  739.     if ((isascii(*name) && *(name+1) == ':' ) )
  740.         strcpyf(buf, name);
  741.     else {
  742.         if(pdev->d_pszPath == NULL)
  743.         {
  744.             GetSpoolDir(pdev);
  745.             if(pdev->d_pszPath == NULL)
  746.             return PROCERRORSIG;
  747.         };
  748.  
  749.         strcpyf(buf, pdev->d_pszPath);
  750.         strcatf(buf, "\\");
  751.         strcatf(buf, name);
  752.          }
  753.  
  754.     /* Open File */
  755.     status = DosOpen((PSZ)buf,
  756.               &handle,
  757.               &action,
  758.              (ULONG) 0,
  759.              FILE_READONLY,
  760.              FILE_OPEN,              /* fail, if not exists */
  761.              OPEN_SHARE_DENYWRITE,
  762.              (ULONG) 0 );
  763.  
  764.     /* 
  765.      * if file cannot be found just pretend to be successful 
  766.      */
  767.     if (status )
  768.         return (OKSIG);
  769.  
  770.     (void) DosChgFilePtr(handle, (ULONG)0, 0, &newpos);
  771.     Restart = FALSE;
  772.  
  773.     status = OKSIG;
  774.     while (status == OKSIG &&
  775.            !DosRead(handle,buf, 512, &bytesread) &&
  776.            bytesread > 0 )
  777.         status = SeparatDevWrite(pdev,buf, bytesread);
  778.  
  779.     DosClose(handle);
  780.     return status;
  781.         
  782. }
  783.  
  784.  
  785. int SeparatDevWrite(pdev, pb, cb)
  786. PDEVICESPL pdev;
  787. char far * pb;
  788. USHORT cb;
  789. {
  790.     return DevEscape(pdev->d_pQProc->hdc,
  791.                      (LONG)DEVESC_RAWDATA,
  792.                      (LONG)cb,
  793.                      pb,
  794.                      (PLONG)NULL,
  795.                      (PLONG)NULL) == 1L ? OKSIG : KILLSIG;
  796. }
  797.  
  798.  
  799.  
  800. /* Get the path of the spool directory */
  801. VOID GetSpoolDir(pdev)
  802. PDEVICESPL pdev;
  803. {
  804.  
  805.     ULONG size;
  806.     char far * pctmp;
  807.  
  808.     PrfQueryProfileSize(HINI_SYSTEM, "PM_SPOOLER", "DIR", &size);
  809.  
  810.     EnterSplSem();
  811.     pdev->d_pszPath = (NPSZ)AllocSplMem((pdev->d_uPathSize = (USHORT)size+2));
  812.     LeaveSplSem();
  813.  
  814.     if(pdev->d_pszPath == NULL) return;
  815.  
  816.     PrfQueryProfileString(HINI_SYSTEM, "PM_SPOOLER", "DIR", "", pdev->d_pszPath, size+1);
  817.  
  818.     if((pctmp = strchrf(pdev->d_pszPath, ';')) != NULL)
  819.     *pctmp = '\0';
  820.  
  821. }
  822.