home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / win95 / ext2tool.exe / SRC / MSDOS_IO.C < prev    next >
C/C++ Source or Header  |  1995-05-10  |  5KB  |  212 lines

  1. /***************************************************************************
  2.  * msdos_io.c --- This is the MS-DOS I/O interface to the I/O manager.
  3.  *
  4.  * Copyright (C) 1995 Claus Tondering, ct@login.dknet.dk
  5.  *
  6.  * Based on unix_io.c, which is copyright (C) 1993 Theodore Ts'o.
  7.  *
  8.  * This file may be redistributed under the terms of the GNU Public License.
  9.  ***************************************************************************/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include <stdlib.h>
  15. #include <fcntl.h>
  16. #include <time.h>
  17. #include <sys/stat.h>
  18. #include <errno.h>
  19. #include <sys/types.h>
  20.  
  21. #include "ext2fs/com_err.h"
  22. #include "ext2fs/ext2_err.h"
  23. #include "ext2fs/io.h"
  24. #include "diskio.h"
  25. #include "ldisk.h"
  26. /*
  27.  * For checking structure magic numbers...
  28.  */
  29.  
  30. #define EXT2_CHECK_MAGIC(struct, code) \
  31.       if ((struct)->magic != (code)) return (code)
  32.   
  33. struct msdos_private_data {
  34.     long    magic;
  35.     int        diskno;
  36.     long    offset;
  37.     long    length;
  38.     int        flags;
  39.     char    *buf;
  40.     int    buf_block_nr;
  41. };
  42.  
  43. static errcode_t msdos_open(const char *name, int flags, io_channel *channel);
  44. static errcode_t msdos_close(io_channel channel);
  45. static errcode_t msdos_set_blksize(io_channel channel, int blksize);
  46. static errcode_t msdos_read_blk(io_channel channel, unsigned long block,
  47.                    int count, void *data);
  48. static errcode_t msdos_write_blk(io_channel channel, unsigned long block,
  49.                 int count, const void *data);
  50. static errcode_t msdos_flush(io_channel channel);
  51.  
  52. static struct struct_io_manager struct_msdos_manager = {
  53.     EXT2_ET_MAGIC_IO_MANAGER,
  54.     "MS-DOS I/O Manager",
  55.     msdos_open,
  56.     msdos_close,
  57.     msdos_set_blksize,
  58.     msdos_read_blk,
  59.     msdos_write_blk,
  60.     msdos_flush
  61. };
  62.  
  63. io_manager msdos_io_manager = &struct_msdos_manager;
  64.  
  65. static errcode_t msdos_open(const char *name, int flags, io_channel *channel)
  66. {
  67.     io_channel    io = NULL;
  68.     struct msdos_private_data *data = NULL;
  69.     errcode_t    retval;
  70.  
  71.     io = (io_channel) malloc(sizeof(struct struct_io_channel));
  72.     if (!io)
  73.         return ENOMEM;
  74.     io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
  75.     data = (struct msdos_private_data *)
  76.         malloc(sizeof(struct msdos_private_data));
  77.     if (!data) {
  78.         retval = ENOMEM;
  79.         goto cleanup;
  80.     }
  81.     io->manager = msdos_io_manager;
  82.     io->private_data = data;
  83.     io->block_size = 1024;
  84.  
  85.     memset(data, 0, sizeof(struct msdos_private_data));
  86.     data->magic = EXT2_ET_MAGIC_MSDOS_IO_CHANNEL;
  87.     data->buf = malloc(io->block_size);
  88.     data->buf_block_nr = -1;
  89.     if (!data->buf) {
  90.         retval = ENOMEM;
  91.         goto cleanup;
  92.     }
  93.     
  94.     retval=nametodisk(&data->diskno, &data->offset, &data->length);
  95.     if (retval)
  96.         goto cleanup;
  97.  
  98.     if (flags&IO_FLAG_RW) {
  99.         retval = EACCES;
  100.         goto cleanup;
  101.     }
  102.     
  103.     *channel = io;
  104.     return 0;
  105.  
  106.  cleanup:
  107.     if (io)
  108.         free(io);
  109.     if (data) {
  110.         if (data->buf)
  111.             free(data->buf);
  112.         free(data);
  113.     }
  114.     return retval;
  115. }
  116.  
  117. static errcode_t msdos_close(io_channel channel)
  118. {
  119.     struct msdos_private_data *data;
  120.     errcode_t    retval = 0;
  121.  
  122.     EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
  123.     data = (struct msdos_private_data *) channel->private_data;
  124.     EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_MSDOS_IO_CHANNEL);
  125.     
  126.     if (data->buf)
  127.         free(data->buf);
  128.     if (channel->private_data)
  129.         free(channel->private_data);
  130.     if (channel->name)
  131.         free(channel->name);
  132.     free(channel);
  133.     return retval;
  134. }
  135.  
  136. static errcode_t msdos_set_blksize(io_channel channel, int blksize)
  137. {
  138.     struct msdos_private_data *data;
  139.  
  140.     EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
  141.     data = (struct msdos_private_data *) channel->private_data;
  142.     EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_MSDOS_IO_CHANNEL);
  143.  
  144.     if (channel->block_size != blksize) {
  145.         channel->block_size = blksize;
  146.         free(data->buf);
  147.         data->buf = malloc(blksize);
  148.         if (!data->buf)
  149.             return ENOMEM;
  150.         data->buf_block_nr = -1;
  151.     }
  152.     return 0;
  153. }
  154.  
  155.  
  156. static errcode_t msdos_read_blk(io_channel channel, unsigned long block,
  157.                    int count, void *buf)
  158. {
  159.     struct msdos_private_data *data;
  160.     errcode_t    retval;
  161.     size_t        size;
  162.     ext2_loff_t    location;
  163.     int        actual = 0;
  164.  
  165.     EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
  166.     data = (struct msdos_private_data *) channel->private_data;
  167.     EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_MSDOS_IO_CHANNEL);
  168.  
  169.     /*
  170.      * If it's in the cache, use it!
  171.      */
  172.     if ((count == 1) && (block == data->buf_block_nr)) {
  173.         memcpy(buf, data->buf, channel->block_size);
  174.         return 0;
  175.     }
  176.     size = (count < 0) ? -count : count * channel->block_size;
  177.     location = (ext2_loff_t) block * channel->block_size;
  178.  
  179.     retval = readdisk(data->diskno, data->offset + location/512, size/512, buf);
  180.     if (retval)
  181.         goto error_out;
  182.  
  183.     if (count == 1) {
  184.         data->buf_block_nr = block;
  185.         memcpy(data->buf, buf, size);    /* Update the cache */
  186.     }
  187.     return 0;
  188.     
  189. error_out:
  190.     memset((char *) buf+actual, 0, size-actual);
  191.     if (channel->read_error)
  192.         retval = (channel->read_error)(channel, block, count, buf,
  193.                            size, actual, retval);
  194.     return retval;
  195. }
  196.  
  197. static errcode_t msdos_write_blk(io_channel channel, unsigned long block,
  198.                 int count, const void *buf)
  199. {
  200.     return EACCES;
  201. }
  202.  
  203. /*
  204.  * Flush data buffers to disk.
  205.  * This is a no-op.
  206.  */
  207. static errcode_t msdos_flush(io_channel channel)
  208. {
  209.     return 0;
  210. }
  211.  
  212.