home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / xyz.lzh / ftdisk.c < prev    next >
Text File  |  1995-08-18  |  20KB  |  719 lines

  1. /*
  2.    Printed form of this source is Copyright (C) 1995 Coriolis
  3.    Group, Inc.  All rights reserved.  Individual users may
  4.    make printed copies for their own personal use.
  5.  
  6.    All other forms are Copyright (C) 1995 Tim Kientzle. All
  7.    rights reserved.
  8.  
  9. Redistribution in source or binary form is permitted only under
  10. the following conditions:
  11. 1. If you own a copy of `The Working Programmer's Guide To Serial
  12.    Protocols,' then you may redistribute this code as part of
  13.    a complete application program under the conditions
  14.    described in that book.  (See pages xiv, xv.)  In any case,
  15.    you must abide by terms 4-7 below.
  16. 2. Otherwise, if you have received this code as a part of an
  17.    application program, it may only be redistributed with the
  18.    complete source of that program, under whatever conditions
  19.    apply to redistribution of that program as a whole.
  20. 3. If you have received this source code by some other means,
  21.    you may not redistribute it without explicit written
  22.    permission from Tim Kientzle.
  23. 4. All advertising materials mentioning features or use of this
  24.    software must prominently display the following acknowledgement:
  25.       This product is partially based on source code appearing in
  26.       `The Working Programmer's Guide to Serial Protocols,'
  27.       Copyright (C) 1995 Coriolis Group, Inc. and Tim Kientzle.
  28. 5. All programs using this source code must display the above
  29.    acknowledgement prominently in the program documentation
  30.    and user interface.
  31. 6. Neither the name of the Tim Kientzle nor the Coriolis Group, Inc.,
  32.    may be used to endorse or promote products derived from this
  33.    software without specific prior written permission.
  34. 7. Any redistribution in source form must retain the above copyright
  35.    notice, this list of conditions, and the disclaimer below.
  36.  
  37. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  38. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  39. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  40. IN NO EVENT SHALL TIM KIENTZLE OR THE CORIOLIS GROUP BE LIABLE FOR
  41. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  42. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  43. GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  44. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  45. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  46. OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  47. IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48.  
  49. */
  50.  
  51. #define debugWarn (1)
  52. #define debugDisk (1024)
  53. #define StsRet(expr) \
  54. do{ \
  55. int tmpErrorVal= (expr); \
  56. if(tmpErrorVal!=diskOK)return StsWarn(tmpErrorVal); \
  57. }while(FALSE)
  58. #define StsWarn(s)DiskDebugWarn(pF,(s),__FILE__,__LINE__)
  59. #define DiskWriteEOL_CR(f)putc(CR,(f))
  60. #define DiskWriteEOL_LF(f)putc(LF,(f))
  61. #define DiskWriteEOL_CRLF(f)putc(CR,(f));putc(LF,(f)) \
  62.  
  63. #define DiskWriteEOL(f)DiskWriteEOL_CR(f) \
  64.  
  65. #include <stddef.h>
  66. #include <direct.h>
  67. #include <ctype.h>
  68. #include <time.h>
  69. #include <stdio.h>
  70. #ifdef _UCC
  71. #include <string.h>
  72. #include <stdlib.h>
  73. #else
  74. #include <strings.h>
  75. #endif
  76. #ifndef FALSE
  77. #define FALSE (0)
  78. #endif
  79. #ifndef NULL
  80. #define NULL ((void *)0)
  81. #endif
  82. #define STATIC static
  83. #define FileExists(fname)    (access(fname,0)==0)
  84. int     access (const char *name, int mode);
  85.  
  86. #include "ftdisk.h"
  87. #define BUFFERSIZE  4096
  88. #define SHORTBUFF 1100
  89. #define C_NULL       0x00
  90. #define TAB          0x09
  91. #define LF           0x0a
  92. #define CR           0x0d
  93. #define SUB          0x1a
  94. typedef struct {
  95.    FILE   *f;
  96.    DEBUG   debug;
  97.    int     fileType;
  98.    long    fileMode;
  99.    struct tm fileDate;
  100.    long    fileSize;
  101.    char   *fileName;
  102.    char    lastChar;
  103.    char   *buffer;
  104.    unsigned bufferSize;
  105.    unsigned bufferLimit;
  106.    unsigned bufferBegin;
  107.    unsigned bufferEnd;
  108. } DISKFILE_PRIVATE;
  109. STATIC int DiskDebugWarn
  110.         (DISKFILE_PRIVATE *pF, int s, const char *file, int line) {
  111.    const char *msg = NULL;
  112.  
  113.    if (!pF->debug)
  114.       return s;
  115.    if (s != diskOK) {
  116.       DebugBeginInternal (pF->debug, debugWarn, file, line);
  117.       DebugString (pF->debug, "?!?!?!:");
  118.    }
  119.    switch (s) {
  120.    case diskOK:
  121.       return diskOK;;
  122.    case diskError:
  123.       msg = "diskError";
  124.       break;
  125.    case diskFatal:
  126.       msg = "diskFatal";
  127.       break;
  128.    case diskNoSuchFile:
  129.       msg = "diskNoSuchFile";
  130.       break;
  131.    case diskCantRead:
  132.       msg = "diskCantRead";
  133.       break;
  134.    case diskEOF:
  135.       msg = "diskEOF";
  136.       break;
  137.    }
  138.    if (msg != NULL)
  139.       DebugString (pF->debug, msg);
  140.    else {
  141.       DebugString (pF->debug, "Disk Error ");
  142.       DebugInt (pF->debug, s);
  143.    }
  144.    DebugEnd (pF->debug);
  145.    return s;
  146. }
  147. STATIC void DiskConvertName
  148.         (char *resultName, const char *initialName) {
  149.    char   *p = resultName;
  150.    const char *q = initialName;
  151.  
  152.    if (!isalpha (*q)) {
  153.       *p++ = 'x';
  154.       *p++ = '_';
  155.    }
  156.    for (; *q != '\0'; q++) {
  157.       *p = isupper (*q) ? tolower (*q) : *q;
  158.       if (!isalpha (*p) && !isdigit (*p) && (*p != '.'))
  159.          *p = '_';
  160.       p++;
  161.    }
  162.    while (*--p == '_') ;
  163.    *(++p) = '\0';
  164.    resultName[26] = '\0';
  165. }
  166. STATIC int DiskMakeNameUnique
  167.         (DISKFILE_PRIVATE *pF, char *fname) {
  168.    char   *p;
  169.    char   *dot = NULL;
  170.  
  171.    for (p = fname; *p; p++) {
  172.       if (*p == '.')
  173.          dot = p;
  174.    }
  175.    p--;
  176.    while (FileExists (fname)) {
  177.       if (!dot || !isdigit (*p)) {
  178.          if (!dot) {
  179.             *++p = '.';
  180.             dot = p;
  181.          }
  182.          while (p - dot < 3)
  183.             *++p = '0';
  184.          *p = '1';
  185.          p[1] = 0;
  186.       } else {
  187.          char   *p1 = p;
  188.  
  189.          while ((*p1 == '9') && (p1 > fname))
  190.             *(p1--) = '0';
  191.          if ((*p1 == '.') && (p1 > fname))
  192.             p1--;
  193.          while ((*p1 == '9') && (p1 > fname))
  194.             *(p1--) = '0';
  195.          if ((*p1 == '.') && (p1 > fname))
  196.             p1--;
  197.          if ((p1 == fname) && ((*p1 == '.') || (*p1 == '9')))
  198.             return StsWarn (diskError);
  199.          if (!isdigit (*p1))
  200.             *p1 = '1';
  201.          else
  202.             (*p1)++;
  203.       }
  204.    }
  205.    return diskOK;
  206. }
  207. STATIC int DiskGuessType
  208.         (const char *buff, unsigned long size) {
  209.    int     i;
  210.    const char *p;
  211.    register int c;
  212.  
  213.    if (size == 0)
  214.       return diskFileBinary;
  215.    p = buff;
  216.    i = size;
  217.    c = ((int) *p) & 0xFF;
  218.    if ((c == C_NULL) || (c == SUB))
  219.       return diskFileBinary;
  220.    while (i-- > 0) {
  221.       c = *p++ & 0xff;
  222.       if ((c >= 0x7f)
  223.           || ((c < 0x20) && (c != CR) && (c != LF)
  224.               && (c != TAB) && (c != SUB) && (c != C_NULL)))
  225.          return diskFileBinary;
  226.    }
  227.    p = buff;
  228.    i = size;
  229.    while ((i > 0) && ((c = *p++) != SUB) && (c != C_NULL)) {
  230.       i--;
  231.    }
  232.    while ((i > 0) && (*p++ == c)) {
  233.       i--;
  234.    }
  235.    if (i > 0)
  236.       return diskFileBinary;
  237.    return diskFileText;
  238. }
  239. STATIC int DiskWriteText
  240.         (DISKFILE fPublic) {
  241.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  242.    char   *p = pF->buffer;
  243.    long    num = pF->bufferEnd;
  244.    char    lastChar = pF->lastChar;
  245.    register int c;
  246.  
  247.    for (; num; --num) {
  248.       c = *p++;
  249.       if ((c) && (c != LF) && (c != SUB) && (c != CR))
  250.          putc (c, pF->f);
  251.       else if (c == CR) {
  252.          DiskWriteEOL (pF->f);
  253.       } else if ((c == LF) && (lastChar != CR)) {
  254.          DiskWriteEOL (pF->f);
  255.       }
  256.       lastChar = c;
  257.    }
  258.    pF->lastChar = lastChar;
  259.    return diskOK;
  260. }
  261. STATIC int DiskWriteFlush
  262.         (DISKFILE fPublic) {
  263.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  264.    int     returnVal = diskOK;
  265.  
  266.    if (pF->bufferEnd == 0)
  267.       return (diskOK);
  268.    if (pF->fileType == diskFileUnknown)
  269.       pF->fileType = DiskGuessType (pF->buffer, pF->bufferEnd);
  270.    if (pF->debug) {
  271.       DebugBegin (pF->debug, debugDisk);
  272.       DebugString (pF->debug, "Flushing ");
  273.       DebugString (pF->debug, (pF->fileType >= diskFileText) ? "Text" : "Binary");
  274.       DebugString (pF->debug, " file ``");
  275.       DebugString (pF->debug, pF->fileName);
  276.       DebugString (pF->debug, "'' to disk: ");
  277.       DebugInt (pF->debug, pF->bufferEnd);
  278.       DebugString (pF->debug, "bytes.");
  279.       DebugEnd (pF->debug);
  280.    }
  281.    switch (pF->fileType) {
  282.    case diskFileBinary:
  283.    case diskFileUnknown:
  284.       if (fwrite (pF->buffer, 1, pF->bufferEnd, pF->f) != pF->bufferEnd)
  285.          returnVal = StsWarn (diskFatal);
  286.       break;
  287.    case diskFileText:
  288.    case diskFileAscii:
  289.    case diskFileLatin1:
  290.       returnVal = StsWarn (DiskWriteText (pF));
  291.       break;
  292.    default:
  293.       returnVal = StsWarn (DiskWriteText (pF));
  294.       break;
  295.    }
  296.    pF->bufferEnd = 0;
  297.    pF->bufferLimit = pF->bufferSize;
  298.    return returnVal;
  299. }
  300. int     DiskWriteInit
  301.         (DISKFILE *pFPublic, DEBUG debug) {
  302.    DISKFILE_PRIVATE *pF;
  303.  
  304.    *pFPublic = NULL;
  305.    pF = malloc (sizeof (*pF));
  306.    if (pF == NULL)
  307.       return StsWarn (diskFatal);
  308.    memset (pF, 0, sizeof (*pF));
  309.    pF->buffer = malloc (BUFFERSIZE);
  310.    if (pF->buffer == NULL) {
  311.       free (pF);
  312.       return StsWarn (diskFatal);
  313.    } {
  314.       time_t  t = time (NULL);
  315.  
  316.       pF->fileDate = *localtime (&t);
  317.    }
  318.    pF->fileType = diskFileUnknown;
  319.    pF->fileMode = 0;
  320.    pF->fileSize = 0;
  321.    pF->bufferSize = BUFFERSIZE;
  322.    pF->bufferLimit = SHORTBUFF;
  323.    pF->bufferBegin = pF->bufferEnd = 0;
  324.    pF->debug = debug;
  325.    *pFPublic = pF;
  326.    return diskOK;
  327. }
  328. int     DiskWriteName
  329.         (DISKFILE fPublic, const char *preferredName) {
  330.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  331.    char    fileName[256];
  332.  
  333.    if (pF->debug) {
  334.       DebugBegin (pF->debug, debugDisk);
  335.       DebugString (pF->debug, "DiskWriteName(``");
  336.       DebugString (pF->debug, preferredName);
  337.       DebugString (pF->debug, "'')");
  338.       DebugEnd (pF->debug);
  339.    }
  340.    DiskConvertName (fileName, preferredName);
  341.    pF->fileName = malloc (strlen (fileName) + 1);
  342.    if (pF->fileName == NULL) {
  343.       return StsWarn (diskFatal);
  344.    }
  345.    strcpy (pF->fileName, fileName);
  346.    return diskOK;
  347. }
  348. int     DiskWriteSize
  349.         (DISKFILE fPublic, long fileSize) {
  350.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  351.  
  352.    if (pF->debug) {
  353.       DebugBegin (pF->debug, debugDisk);
  354.       DebugString (pF->debug, "DiskWriteSize(");
  355.       DebugInt (pF->debug, fileSize);
  356.       DebugString (pF->debug, ")");
  357.       DebugEnd (pF->debug);
  358.    }
  359.    pF->fileSize = fileSize;
  360.    return diskOK;
  361. }
  362. int     DiskWriteDate
  363.         (DISKFILE fPublic, struct tm *pFileDate) {
  364.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  365.  
  366.    if (pF->debug) {
  367.       DebugBegin (pF->debug, debugDisk);
  368.       DebugString (pF->debug, "DiskWriteDate");
  369.       DebugEnd (pF->debug);
  370.    }
  371.    pF->fileDate = *pFileDate;
  372.    return diskOK;
  373. }
  374. int     DiskWriteMode
  375.         (DISKFILE fPublic, long fileMode) {
  376.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  377.  
  378.    if (pF->debug) {
  379.       DebugBegin (pF->debug, debugDisk);
  380.       DebugString (pF->debug, "DiskWriteMode(");
  381.       DebugIntHex (pF->debug, fileMode);
  382.       DebugString (pF->debug, ")");
  383.       DebugEnd (pF->debug);
  384.    }
  385.    pF->fileMode = fileMode;
  386.    return diskOK;
  387. }
  388. int     DiskWriteType
  389.         (DISKFILE fPublic, int fileType) {
  390.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  391.  
  392.    if (pF->debug) {
  393.       DebugBegin (pF->debug, debugDisk);
  394.       DebugString (pF->debug, "DiskWriteType(");
  395.       DebugInt (pF->debug, fileType);
  396.       DebugString (pF->debug, ")");
  397.       DebugEnd (pF->debug);
  398.    }
  399.    pF->fileType = fileType;
  400.    return diskOK;
  401. }
  402. int     DiskWriteOpen
  403.         (DISKFILE fPublic) {
  404.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  405.    char    fileName[256];
  406.  
  407.    strcpy (fileName, pF->fileName);
  408.    StsRet (DiskMakeNameUnique (pF, fileName));
  409.    free (pF->fileName);
  410.    pF->fileName = malloc (strlen (fileName) + 1);
  411.    if (pF->fileName == NULL) {
  412.       free (pF->buffer);
  413.       free (pF);
  414.       return StsWarn (diskFatal);
  415.    }
  416.    strcpy (pF->fileName, fileName);
  417.    if (pF->debug) {
  418.       DebugBegin (pF->debug, debugDisk);
  419.       DebugString (pF->debug, "DiskWriteOpen: opening ``");
  420.       DebugString (pF->debug, pF->fileName);
  421.       DebugString (pF->debug, "''");
  422.       DebugEnd (pF->debug);
  423.    }
  424.    return DiskReplaceOpen (fPublic);
  425. }
  426. int     DiskReplaceOpen
  427.         (DISKFILE fPublic) {
  428.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  429.  
  430.    if (pF->debug) {
  431.       DebugBegin (pF->debug, debugDisk);
  432.       DebugString (pF->debug, "DiskReplaceOpen: replacing ``");
  433.       DebugString (pF->debug, pF->fileName);
  434.       DebugString (pF->debug, "''");
  435.       DebugEnd (pF->debug);
  436.    }
  437.    pF->f = fopen (pF->fileName, "w");
  438.    if (pF->f == NULL) {
  439.       free (pF->buffer);
  440.       free (pF->fileName);
  441.       free (pF);
  442.       return StsWarn (diskError);
  443.    }
  444.    return diskOK;
  445. }
  446. int     DiskAppendOpen
  447.         (DISKFILE fPublic) {
  448.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  449.  
  450.    if (pF->debug) {
  451.       DebugBegin (pF->debug, debugDisk);
  452.       DebugString (pF->debug, "DiskAppendOpen: opening ``");
  453.       DebugString (pF->debug, pF->fileName);
  454.       DebugString (pF->debug, "''");
  455.       DebugEnd (pF->debug);
  456.    }
  457.    pF->f = fopen (pF->fileName, "w+");
  458.    if (pF->f == NULL) {
  459.       free (pF->buffer);
  460.       free (pF->fileName);
  461.       free (pF);
  462.       return StsWarn (diskError);
  463.    }
  464.    return diskOK;
  465. }
  466. int     DiskWrite
  467.         (DISKFILE fPublic, const void *buff, unsigned long cnt) {
  468.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  469.    const char *pSource = (const char *) buff;
  470.    unsigned long size;
  471.  
  472.    while (cnt > 0) {
  473.       if ((pF->bufferEnd + cnt) > pF->bufferLimit)
  474.          StsRet (DiskWriteFlush (pF));
  475.       if ((pF->bufferEnd + cnt) > pF->bufferLimit)
  476.          size = pF->bufferLimit - pF->bufferEnd - 1;
  477.       else
  478.          size = cnt;
  479.       memcpy (pF->buffer + pF->bufferEnd, pSource, size);
  480.       cnt -= size;
  481.       pSource += size;
  482.       pF->bufferEnd += size;
  483.    }
  484.    return diskOK;
  485. }
  486. int     DiskWriteClose
  487.         (DISKFILE fPublic) {
  488.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  489.    int     returnVal = diskOK;
  490.  
  491.    returnVal = StsWarn (DiskWriteFlush (pF));
  492.    if (pF->debug) {
  493.       DebugBegin (pF->debug, debugDisk);
  494.       DebugString (pF->debug, "DiskWriteClose: closing ``");
  495.       DebugString (pF->debug, pF->fileName);
  496.       DebugString (pF->debug, "''");
  497.       DebugEnd (pF->debug);
  498.    }
  499.    if ((returnVal == diskOK) && (fclose (pF->f)))
  500.       returnVal = StsWarn (diskError);
  501.    if (pF->buffer != NULL)
  502.       free (pF->buffer);
  503.    if (pF->fileName != NULL)
  504.       free (pF->fileName);
  505.    free (pF);
  506.    return returnVal;
  507. }
  508. STATIC void DiskCopyText
  509.         (char *dest, unsigned *pDestSize,
  510.          const char *source, unsigned sourceSize,
  511.          char *pLastChar) {
  512.    char    lastChar = *pLastChar;
  513.    const char *p = source;
  514.    char   *q = dest;
  515.    int     c;
  516.  
  517.    for (; sourceSize; --sourceSize) {
  518.       c = *p++;
  519.       if ((c) && (c != LF) && (c != SUB) && (c != CR))
  520.          *q++ = c;
  521.       else if (c == CR) {
  522.          *q++ = CR;
  523.          *q++ = LF;
  524.       } else if ((c == LF) && (lastChar != CR)) {
  525.          *q++ = CR;
  526.          *q++ = LF;
  527.       }
  528.       lastChar = c;
  529.    }
  530.    *pLastChar = lastChar;
  531.    *pDestSize = q - dest;
  532. }
  533. STATIC char diskReadBuff[BUFFERSIZE];
  534. STATIC int DiskReadFillBuffer
  535.         (DISKFILE fPublic) {
  536.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  537.  
  538.    if (pF->fileType >= diskFileText) {
  539.       unsigned sizeRead;
  540.  
  541.       sizeRead = fread (diskReadBuff, 1, pF->bufferSize / 2, pF->f);
  542.       pF->bufferBegin = 0;
  543.       if (sizeRead == 0) {
  544.          pF->bufferEnd = 0;
  545.          return diskEOF;
  546.       } else {
  547.          DiskCopyText (pF->buffer, &(pF->bufferEnd), diskReadBuff, sizeRead,
  548.                        &(pF->lastChar));
  549.       }
  550.    } else {
  551.       pF->bufferEnd = fread (pF->buffer, 1, pF->bufferSize, pF->f);
  552.       pF->bufferBegin = 0;
  553.       if (pF->bufferEnd == 0)
  554.          return diskEOF;
  555.    }
  556.    return diskOK;
  557. }
  558. int     DiskReadOpen
  559.         (DISKFILE *pFPublic, const char *name, int fileType) {
  560.    DISKFILE_PRIVATE *pF;
  561.  
  562.    *pFPublic = NULL;
  563.    pF = malloc (sizeof (*pF));
  564.    if (pF == NULL)
  565.       return StsWarn (diskFatal);
  566.    memset (pF, 0, sizeof (*pF));
  567.    pF->buffer = malloc (BUFFERSIZE);
  568.    if (pF->buffer == NULL) {
  569.       free (pF);
  570.       return StsWarn (diskFatal);
  571.    }
  572.    pF->bufferSize = BUFFERSIZE;
  573.    pF->bufferLimit = SHORTBUFF;
  574.    pF->bufferBegin = pF->bufferEnd = 0;
  575.    pF->f = fopen (name, "r");
  576.    if (pF->f == NULL) {
  577.       free (pF);
  578.       return StsWarn (diskNoSuchFile);
  579.    }
  580.    pF->fileMode = -1;
  581.    pF->fileSize = -1;
  582.    {
  583.       time_t  t = time (NULL);
  584.  
  585.       pF->fileDate = *localtime (&t);
  586.    }
  587.    pF->fileName = malloc (strlen (name) + 1);
  588.    if (pF->fileName == NULL) {
  589.       free (pF);
  590.       return StsWarn (diskFatal);
  591.    }
  592.    strcpy (pF->fileName, name);
  593.    pF->fileType = fileType;
  594.    if (pF->fileType == diskFileUnknown) {
  595.       unsigned sizeRead;
  596.  
  597.       sizeRead = fread (diskReadBuff, 1, pF->bufferSize / 2, pF->f);
  598.       pF->fileType = DiskGuessType (diskReadBuff, sizeRead);
  599.       pF->lastChar = 0;
  600.       if (pF->fileType >= diskFileText)
  601.          DiskCopyText (pF->buffer, &(pF->bufferEnd), diskReadBuff, sizeRead,
  602.                        &(pF->lastChar));
  603.       else {
  604.          memcpy (pF->buffer, diskReadBuff, sizeRead);
  605.          pF->bufferEnd = sizeRead;
  606.       }
  607.    } {
  608.       int     _gs_gfd (int path, struct fildes *buffer, int count);
  609.       struct fildes fd;
  610.  
  611.       _gs_gfd (fileno (pF->f), &fd, sizeof (fd));
  612.       {
  613.          unsigned char *p = (unsigned char *) fd.fd_fsize;
  614.  
  615.          pF->fileSize = *p++;
  616.          pF->fileSize = pF->fileSize * 256 + *p++;
  617.          pF->fileSize = pF->fileSize * 256 + *p++;
  618.          pF->fileSize = pF->fileSize * 256 + *p++;
  619.       }
  620.       {
  621.          pF->fileDate.tm_year = fd.fd_date[0];
  622.          pF->fileDate.tm_mon = fd.fd_date[1] - 1;
  623.          pF->fileDate.tm_mday = fd.fd_date[2];
  624.          pF->fileDate.tm_hour = fd.fd_date[3];
  625.          pF->fileDate.tm_min = fd.fd_date[4];
  626.          pF->fileDate.tm_sec = fd.fd_date[5];
  627.       }
  628.       pF->fileMode = (fd.fd_att & 070 >> 3)
  629.             | ((fd.fd_att & 070))
  630.             | ((fd.fd_att & 070) << 3);
  631.    }
  632.    *pFPublic = pF;
  633.    return diskOK;
  634. }
  635. int     DiskRead
  636.         (DISKFILE fPublic, void *buff,
  637.          unsigned long requestedSize, unsigned long *pSizeRead) {
  638.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  639.    char   *cbuff = buff;
  640.    int     err;
  641.  
  642.    *pSizeRead = 0;
  643.    if (requestedSize == 0)
  644.       return diskOK;
  645.    while (requestedSize > 0) {
  646.       unsigned bufferSize = pF->bufferEnd - pF->bufferBegin;
  647.  
  648.       if (requestedSize >= bufferSize) {
  649.          memcpy (cbuff, pF->buffer + pF->bufferBegin, bufferSize);
  650.          requestedSize -= bufferSize;
  651.          *pSizeRead += bufferSize;
  652.          cbuff += bufferSize;
  653.          err = DiskReadFillBuffer (pF);
  654.          if (err == diskEOF)
  655.             break;
  656.          if (err != diskOK)
  657.             return err;
  658.       } else {
  659.          memcpy (cbuff, pF->buffer + pF->bufferBegin, requestedSize);
  660.          *pSizeRead += requestedSize;
  661.          pF->bufferBegin += requestedSize;
  662.          requestedSize = 0;
  663.       }
  664.    }
  665.    if (*pSizeRead == 0)
  666.       return diskEOF;
  667.    return diskOK;
  668. }
  669. int     DiskReadClose
  670.         (DISKFILE fPublic) {
  671.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  672.    int     returnVal = diskOK;
  673.  
  674.    if (pF->f != NULL)
  675.       if (fclose (pF->f))
  676.          returnVal = StsWarn (diskError);
  677.    if (pF->buffer != NULL)
  678.       free (pF->buffer);
  679.    if (pF->fileName != NULL)
  680.       free (pF->fileName);
  681.    free (pF);
  682.    return returnVal;
  683. }
  684. int     DiskFileType
  685.         (DISKFILE fPublic, int *pType) {
  686.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  687.  
  688.    *pType = pF->fileType;
  689.    return 0;
  690. }
  691. int     DiskFileMode
  692.         (DISKFILE fPublic, long *pMode) {
  693.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  694.  
  695.    *pMode = pF->fileMode;
  696.    return 0;
  697. }
  698. int     DiskFileDate
  699.         (DISKFILE fPublic, struct tm *pTm) {
  700.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  701.  
  702.    *pTm = pF->fileDate;
  703.    return 0;
  704. }
  705. int     DiskFileSize
  706.         (DISKFILE fPublic, long *pSize) {
  707.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  708.  
  709.    *pSize = pF->fileSize;
  710.    return 0;
  711. }
  712. int     DiskFileName
  713.         (DISKFILE fPublic, const char **pName) {
  714.    DISKFILE_PRIVATE *pF = (DISKFILE_PRIVATE *) fPublic;
  715.  
  716.    *pName = pF->fileName;
  717.    return 0;
  718. }
  719.