home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CBASE101.ZIP / BLKIO112.ZIP / BUOPS.C < prev    next >
Text File  |  1990-06-20  |  15KB  |  602 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "@(#)buops.c    1.4 - 90/06/20" */
  5.  
  6. /* local headers */
  7. #include "blkio_.h"
  8.  
  9. /* check host definition */
  10. #ifndef HOST
  11. /*#error HOST macro not defined.*/
  12. #endif
  13. #if HOST != UNIX && HOST != MS_DOS
  14. /*#error Invalid HOST macro definition.*/
  15. #endif
  16.  
  17. /* ansi headers */
  18. #include <errno.h>
  19.  
  20. /* system headers */
  21. #if HOST == UNIX        /* UNIX */
  22. #include <fcntl.h>        /* open() macro definitions */
  23. #include <unistd.h>        /* lseek() macro definitions */
  24. #ifdef AC_PROTO
  25. int    close(int fd);        /* system call declarations */
  26. long    lseek(int fd, long offset, int whence);
  27. int    open(const char *path, int flags, ...);
  28. int    read(int fd, char *buf, unsigned n);
  29. int    write(int fd, const char *buf, unsigned n);
  30. #else
  31. int    close();
  32. long    lseek();
  33. int    open();
  34. int    read();
  35. int    write();
  36. #endif    /* #ifdef AC_PROTO */
  37. #define MODE    (0666)        /* file permissions for new files */
  38. #elif HOST == MS_DOS        /* MS-DOS */
  39. #if MSDOSC == TURBOC        /* Turbo C */
  40. #include <fcntl.h>        /* open() macro definitions */
  41. #include <io.h>            /* system call decls, lseek() macro defs */
  42. #define MODE    (0x100 | 0x080)    /* file permissions for new files */
  43. #elif MSDOSC == MSC        /* Microsoft C */
  44. #include <fcntl.h>        /* open() macro definitions */
  45. /*#include <io.h>        /* system call decls, lseek() macro defs */
  46. /* NOTE:  <io.h> not used for MSC because const qualifier missing from
  47.    open and write decls */
  48. #ifdef AC_PROTO
  49. int    close(int fd);        /* system call declarations */
  50. long    lseek(int fd, long offset, int whence);
  51. int    open(const char *path, int flags, ...);
  52. int    read(int fd, char *buf, unsigned n);
  53. int    write(int fd, const char *buf, unsigned n);
  54. #else
  55. int    close();
  56. long    lseek();
  57. int    open();
  58. int    read();
  59. int    write();
  60. #endif    /* #ifdef AC_PROTO */
  61. #define MODE    (0x100 | 0x080)    /* file permissions for new files */
  62. #elif MSDOSC == MSQC        /* Microsoft Quick C */
  63. #include <fcntl.h>        /* open() macro definitions */
  64. /*#include <io.h>        /* system call decls, lseek() macro defs */
  65. /* NOTE:  <io.h> not used for MSQC because const qualifier missing from
  66.    open and write decls */
  67. #ifdef AC_PROTO
  68. int    close(int fd);        /* system call declarations */
  69. long    lseek(int fd, long offset, int whence);
  70. int    open(const char *path, int flags, ...);
  71. int    read(int fd, char *buf, unsigned n);
  72. int    write(int fd, const char *buf, unsigned n);
  73. #else
  74. int    close();
  75. long    lseek();
  76. int    open();
  77. int    read();
  78. int    write();
  79. #endif    /* #ifdef AC_PROTO */
  80. #define MODE    (0x100 | 0x080)        /* file permissions for new files */
  81. #endif    /* #if MSDOSC == TURBOC */
  82. #endif    /* #if HOST == MS_DOS */
  83.  
  84. /*man---------------------------------------------------------------------------
  85. NAME
  86.      b_uclose - unbuffered close block file
  87.  
  88. SYNOPSIS
  89.      #include "blkio_.h"
  90.  
  91.      int b_uclose(bp)
  92.      BLKFILE *bp;
  93.  
  94. DESCRIPTION
  95.      The b_uclose function closes the file associated with the BLKFILE
  96.      pointer bp.
  97.  
  98.      b_uclose will fail if one or more of the following is true:
  99.  
  100.      [EINVAL]       bp is not a valid BLKFILE pointer.
  101.      [BENOPEN]      bp is not open.
  102.  
  103. SEE ALSO
  104.      b_uopen.
  105.  
  106. DIAGNOSTICS
  107.      Upon successful completion, a value of 0 is returned.  Otherwise,
  108.      a value of -1 is returned, and errno set to indicate the error.
  109.  
  110. ------------------------------------------------------------------------------*/
  111. int b_uclose(bp)
  112. BLKFILE *bp;
  113. {
  114. #ifdef DEBUG
  115.     /* validate arguments */
  116.     if (!b_valid(bp)) {
  117.         BEPRINT;
  118.         errno = EINVAL;
  119.         return -1;
  120.     }
  121.  
  122.     /* check if not open */
  123.     if (!(bp->flags & BIOOPEN)) {
  124.         BEPRINT;
  125.         errno = BENOPEN;
  126.         return -1;
  127.     }
  128. #endif
  129.     /* close file */
  130. #if HOST == UNIX
  131.     if (close(bp->fd.ifd) == -1) {
  132.         BEPRINT;
  133.         return -1;
  134.     }
  135. #elif HOST == MS_DOS
  136.     if (close(bp->fd.ifd) == -1) {
  137.         BEPRINT;
  138.         return -1;
  139.     }
  140. #endif
  141.     errno = 0;
  142.     return 0;
  143. }
  144.  
  145. /*man---------------------------------------------------------------------------
  146. NAME
  147.      b_uendblk - unbuffered find end block
  148.  
  149. SYNOPSIS
  150.      #include "blkio_.h"
  151.  
  152.      int b_uendblk(bp, endblkp)
  153.      BLKFILE *bp;
  154.      bpos_t *endblkp;
  155.  
  156. DESCRIPTION
  157.      The b_uendblk function finds the block number of the first block
  158.      past the end of file of the file associated with BLKFILE pointer
  159.      bp.  This value is returned in the storage location pointed to by
  160.      endblkp.  Blocks in buffer storage and not yet written to the
  161.      file are not counted, so this function should normally be used
  162.      when the file is first opened or preceded by a call to bsync.
  163.  
  164.      If the file does not end on a block boundary, the result is the
  165.      same as if the partial block (or header) at the end of the file
  166.      did not exist.
  167.  
  168.      b_uendblk will fail if one or more of the following is true:
  169.  
  170.      [EINVAL]       bp is not a valid BLKFILE pointer.
  171.      [BENOPEN]      bp is not open.
  172.  
  173. DIAGNOSTICS
  174.      Upon successful completion, a value of 0 is returned.  Otherwise,
  175.      a value of -1 is returned, and errno set to indicate the error.
  176.  
  177. ------------------------------------------------------------------------------*/
  178. int b_uendblk(bp, endblkp)
  179. BLKFILE *bp;
  180. bpos_t *endblkp;
  181. {
  182. #if HOST == UNIX
  183.     long pos = 0;
  184. #elif HOST == MS_DOS
  185.     long pos = 0;
  186. #endif
  187.  
  188. #ifdef DEBUG
  189.     /* validate arguments */
  190.     if (!b_valid(bp)) {
  191.         BEPRINT;
  192.         errno = EINVAL;
  193.         return -1;
  194.     }
  195.  
  196.     /* check if not open */
  197.     if (!(bp->flags & BIOOPEN)) {
  198.         BEPRINT;
  199.         errno = BENOPEN;
  200.         return -1;
  201.     }
  202. #endif
  203.  
  204. #if HOST == UNIX || HOST == MS_DOS
  205.     /* find position of end of file */
  206.     pos = lseek(bp->fd.ifd, (long)0, SEEK_END);
  207.     if (pos == -1) {
  208.         BEPRINT;
  209.         return -1;
  210.     }
  211.  
  212.     /* check if empty file (or incomplete header) */
  213.     if (pos < bp->hdrsize) {
  214.         *endblkp = 0;
  215.         errno = 0;
  216.         return 0;
  217.     }
  218.  
  219.     /* find length past end of header */
  220.     pos -= bp->hdrsize;
  221.  
  222.     /* set return argument */
  223.     *endblkp = (pos / bp->blksize) + 1;
  224. #endif
  225.     errno = 0;
  226.     return 0;
  227. }
  228.  
  229. /*man---------------------------------------------------------------------------
  230. NAME
  231.      b_ugetf - unbuffered get field from block file
  232.  
  233. SYNOPSIS
  234.      #include "blkio_.h"
  235.  
  236.      int b_ugetf(bp, bn, offset, buf, bufsize)
  237.      BLKFILE *bp;
  238.      bpos_t bn;
  239.      size_t offset;
  240.      void *buf;
  241.      size_t bufsize;
  242.  
  243. DESCRIPTION
  244.      The b_ugetf function reads bufsize characters from block number
  245.      bn of the block file associated with BLKFILE pointer bp into the
  246.      buffer pointed to by buf.  A value of 0 for bn indicates the file
  247.      header.  The read starts offset characters from the beginning of
  248.      the block.  The sum of the offset and the bufsize must not exceed
  249.      the header size if bn is equal to zero, or the block size if bn
  250.      is not equal to zero.
  251.  
  252.      b_ugetf will fail if one or more of the following is true:
  253.  
  254.      [EINVAL]       bp is not a valid BLKFILE pointer.
  255.      [EINVAL]       buf is NULL.
  256.      [EINVAL]       bufsize is less than 1.
  257.      [BEBOUND]      offset + bufsize extends across a block
  258.                     boundary.
  259.      [BEEOF]        Block bn is past the end of file.
  260.      [BEEOF]        End of file encountered within block bn.
  261.      [BENOPEN]      bp is not open.
  262.  
  263. SEE ALSO
  264.      b_uputf.
  265.  
  266. DIAGNOSTICS
  267.      Upon successful completion, a value of 0 is returned.  Otherwise,
  268.      a value of -1 is returned, and errno set to indicate the error.
  269.  
  270. ------------------------------------------------------------------------------*/
  271. int b_ugetf(bp, bn, offset, buf, bufsize)
  272. BLKFILE *bp;
  273. bpos_t bn;
  274. size_t offset;
  275. void *buf;
  276. size_t bufsize;
  277. {
  278. #if HOST == UNIX
  279.     long pos = 0;
  280.     int nr = 0;
  281. #elif HOST == MS_DOS
  282.     long pos = 0;
  283.     int nr = 0;
  284. #endif
  285.  
  286. #ifdef DEBUG
  287.     /* validate arguments */
  288.     if (!b_valid(bp) || buf == NULL || bufsize < 1) {
  289.         BEPRINT;
  290.         errno = EINVAL;
  291.         return -1;
  292.     }
  293.  
  294.     /* check if not open */
  295.     if (!(bp->flags & BIOOPEN)) {
  296.         BEPRINT;
  297.         errno = BENOPEN;
  298.         return -1;
  299.     }
  300.  
  301.     /* check if block boundary is crossed */
  302.     if (bn == 0) {
  303.         if ((offset + bufsize) > bp->hdrsize) {
  304.             BEPRINT;
  305.             errno = BEBOUND;
  306.             return -1;
  307.         }
  308.     } else {
  309.         if ((offset + bufsize) > bp->blksize) {
  310.             BEPRINT;
  311.             errno = BEBOUND;
  312.             return -1;
  313.         }
  314.     }
  315. #endif
  316.  
  317. #if HOST == UNIX
  318.     /* read from file into buffer */
  319.     if (bn == 0) {            /* header */
  320.         pos = 0;
  321.     } else {            /* block */
  322.         pos = bp->hdrsize + (bn - 1) * bp->blksize;
  323.     }
  324.     pos += offset;
  325.     if (lseek(bp->fd.ifd, pos, SEEK_SET) == -1) {
  326.         BEPRINT;
  327.         return -1;
  328.     }
  329.     nr = read(bp->fd.ifd, (char *)buf, (unsigned)bufsize);
  330.     if (nr == -1) {
  331.         BEPRINT;
  332.         return -1;
  333.     }
  334.     if (nr != bufsize) {
  335.         BEPRINT;
  336.         errno = BEEOF;
  337.         return -1;
  338.     }
  339. #elif HOST == MS_DOS
  340.     /* read from file into buffer */
  341.     if (bn == 0) {            /* header */
  342.         pos = 0;
  343.     } else {            /* block */
  344.         pos = bp->hdrsize + (bn - 1) * bp->blksize;
  345.     }
  346.     pos += offset;
  347.     if (lseek(bp->fd.ifd, pos, SEEK_SET) == -1) {
  348.         BEPRINT;
  349.         return -1;
  350.     }
  351.     nr = read(bp->fd.ifd, buf, (unsigned)bufsize);
  352.     if (nr == -1) {
  353.         BEPRINT;
  354.         return -1;
  355.     }
  356.     if (nr != bufsize) {
  357.         BEPRINT;
  358.         errno = BEEOF;
  359.         return -1;
  360.     }
  361. #endif
  362.     errno = 0;
  363.     return 0;
  364. }
  365.  
  366. /*man---------------------------------------------------------------------------
  367. NAME
  368.      b_uopen - unbuffered open block file
  369.  
  370. SYNOPSIS
  371.      #include "blkio_.h"
  372.  
  373.      int b_uopen(bp, filename, type)
  374.      BLKFILE *bp;
  375.      const char *filename;
  376.      const char *type;
  377.  
  378. DESCRIPTION
  379.      The b_uopen function opens the physical file associated with the
  380.      BLKFILE pointer bp.
  381.  
  382.      b_uopen will fail if one or more of the following is true:
  383.  
  384.      [EINVAL]       bp is not a valid BLKFILE pointer.
  385.      [EINVAL]       filename or type is the NULL pointer.
  386.  
  387. SEE ALSO
  388.      b_uclose.
  389.  
  390. DIAGNOSTICS
  391.      Upon successful completion, a value of 0 is returned.  Otherwise,
  392.      a value of -1 is returned, and errno set to indicate the error.
  393.  
  394. ------------------------------------------------------------------------------*/
  395. int b_uopen(bp, filename, type)
  396. BLKFILE *bp;
  397. const char *filename;
  398. const char *type;
  399. {
  400. #if HOST == UNIX
  401.     int oflag = 0;
  402.     int fd = 0;
  403. #elif HOST == MS_DOS
  404.     int oflag = 0;
  405.     int fd = 0;
  406. #endif
  407.  
  408. #ifdef DEBUG
  409.     /* validate arguments */
  410.     if (!b_valid(bp) || filename == NULL || type == NULL) {
  411.         BEPRINT;
  412.         errno = EINVAL;
  413.         return -1;
  414.     }
  415. #endif
  416.     /* open file */
  417. #if HOST == UNIX
  418.     oflag = 0;
  419.     if (strcmp(type, BF_READ) == 0) {
  420.         oflag |= O_RDONLY;
  421.     } else if (strcmp(type, BF_RDWR) == 0) {
  422.         oflag |= O_RDWR;
  423.     } else if (strcmp(type, BF_CREATE) == 0) {
  424.         oflag |= O_RDWR | O_CREAT | O_EXCL;
  425.     } else if (strcmp(type, BF_CRTR) == 0) {
  426.         oflag |= O_RDWR | O_CREAT | O_TRUNC;
  427.     } else {
  428.         errno = EINVAL;
  429.         return -1;
  430.     }
  431.     fd = open(filename, oflag, MODE);
  432.     if (fd == -1) {
  433.         if ((errno != EACCES) && (errno != EEXIST) && (errno != ENOENT)) BEPRINT;
  434.         return -1;
  435.     }
  436.     bp->fd.ifd = fd;
  437. #elif HOST == MS_DOS
  438.     oflag = O_BINARY;
  439.     if (strcmp(type, BF_READ) == 0) {
  440.         oflag |= O_RDONLY;
  441.     } else if (strcmp(type, BF_RDWR) == 0) {
  442.         oflag |= O_RDWR;
  443.     } else if (strcmp(type, BF_CREATE) == 0) {
  444.         oflag |= O_RDWR | O_CREAT | O_EXCL;
  445.     } else if (strcmp(type, BF_CRTR) == 0) {
  446.         oflag |= O_RDWR | O_CREAT | O_TRUNC;
  447.     } else {
  448.         errno = EINVAL;
  449.         return -1;
  450.     }
  451.     fd = open(filename, oflag, (unsigned)MODE);
  452.     if (fd == -1) {
  453.         if ((errno != EACCES) && (errno != EEXIST) && (errno != ENOENT)) BEPRINT;
  454.         return -1;
  455.     }
  456.     bp->fd.ifd = fd;
  457. #endif
  458.     errno = 0;
  459.     return 0;
  460. }
  461.  
  462. /*man---------------------------------------------------------------------------
  463. NAME
  464.      b_uputf - unbuffered put field to block file
  465.  
  466. SYNOPSIS
  467.      #include "blkio_.h"
  468.  
  469.      int b_uputf(bp, bn, offset, buf, bufsize)
  470.      BLKFILE *bp;
  471.      bpos_t bn;
  472.      size_t offset;
  473.      const void *buf;
  474.      size_t bufsize;
  475.  
  476. DESCRIPTION
  477.      The b_uputf function writes bufsize characters from the buffer
  478.      pointed to by buf to block number bn of the block file associated
  479.      with BLKFILE pointer bp.  A value of zero for bn indicates the
  480.      file header.  The write starts offset characters from the
  481.      beginning of the block.  The sum of offset bufsize must not
  482.      exceed the header size if bn is equal to zero, or the block size
  483.      if bn is not equal to zero.
  484.  
  485.      b_uputf will fail if one or more of the following is true:
  486.  
  487.      [EINVAL]       bp is not a valid BLKFILE pointer.
  488.      [EINVAL]       buf is the NULL pointer.
  489.      [EINVAL]       bufsize is less than 1.
  490.      [BEBOUND]      offset + bufsize extends beyond the block
  491.                     boundary.
  492.      [BEEOF]        Partial block being written and block bn
  493.                     is past the end of file.
  494.      [BEEOF]        Complete block being written and block bn
  495.                     is more than 1 past the end of file.
  496.      [BENOPEN]      bp is not open for writing.
  497.  
  498. SEE ALSO
  499.      b_ugetf.
  500.  
  501. DIAGNOSTICS
  502.      Upon successful completion, a value of 0 is returned.  Otherwise,
  503.      a value of -1 is returned, and errno set to indicate the error.
  504.  
  505. ------------------------------------------------------------------------------*/
  506. int b_uputf(bp, bn, offset, buf, bufsize)
  507. BLKFILE *bp;
  508. bpos_t bn;
  509. size_t offset;
  510. const void *buf;
  511. size_t bufsize;
  512. {
  513. #if HOST == UNIX
  514.     long pos = 0;
  515.     int nw = 0;
  516. #elif HOST == MS_DOS
  517.     long pos = 0;
  518.     int nw = 0;
  519. #endif
  520.  
  521. #ifdef DEBUG
  522.     /* validate arguments */
  523.     if (!b_valid(bp) || buf == NULL || bufsize < 1) {
  524.         BEPRINT;
  525.         errno = EINVAL;
  526.         return -1;
  527.     }
  528.  
  529.     /* check if not open */
  530.     if (!(bp->flags & BIOWRITE)) {
  531.         BEPRINT;
  532.         errno = BENOPEN;
  533.         return -1;
  534.     }
  535.  
  536.     /* check if block boundary is crossed */
  537.     if (bn == 0) {
  538.         if ((offset + bufsize) > bp->hdrsize) {
  539.             BEPRINT;
  540.             errno = BEBOUND;
  541.             return -1;
  542.         }
  543.     } else {
  544.         if ((offset + bufsize) > bp->blksize) {
  545.             BEPRINT;
  546.             errno = BEBOUND;
  547.             return -1;
  548.         }
  549.     }
  550. #endif
  551.  
  552. #if HOST == UNIX || HOST == MS_DOS
  553.     /* write buffer to file */
  554.     if (bn == 0) {            /* header */
  555.         pos = 0;
  556.     } else {            /* block */
  557.         pos = bp->hdrsize + (bn - 1) * bp->blksize;
  558.     }
  559.     pos += offset;
  560.     if (lseek(bp->fd.ifd, pos, SEEK_SET) == -1) {
  561.         BEPRINT;
  562.         return -1;
  563.     }
  564.     nw = write(bp->fd.ifd, (char *)buf, (unsigned)bufsize);
  565.     if (nw == -1) {
  566.         BEPRINT;
  567.         return -1;
  568.     }
  569.     if (nw != bufsize) {
  570.         BEPRINT;
  571.         /* call write again to set errno (EFBIG or ENOSPC) */
  572.         nw = write(bp->fd.ifd, (char *)buf, (unsigned)1);
  573.         if (nw != -1) errno = BEPANIC;
  574.         return -1;
  575.     }
  576. #elif HOST == MS_DOS
  577.     /* write buffer to file */
  578.     if (bn == 0) {            /* header */
  579.         pos = 0;
  580.     } else {            /* block */
  581.         pos = bp->hdrsize + (bn - 1) * bp->blksize;
  582.     }
  583.     pos += offset;
  584.     if (lseek(bp->fd.ifd, pos, SEEK_SET) == -1) {
  585.         BEPRINT;
  586.         return -1;
  587.     }
  588.     nw = write(bp->fd.ifd, buf, (unsigned)bufsize);
  589.     if (nw == -1) {
  590.         BEPRINT;
  591.         return -1;
  592.     }
  593.     if (nw != bufsize) {
  594.         BEPRINT;
  595.         errno = BEPANIC;
  596.         return -1;
  597.     }
  598. #endif
  599.     errno = 0;
  600.     return 0;
  601. }
  602.