home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / DOOG / CBASE09.ZIP / BLKIO10.ZIP / BUOPS.C < prev    next >
Text File  |  1989-08-30  |  12KB  |  505 lines

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