home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / utils / djtar / oread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-16  |  3.7 KB  |  169 lines

  1. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  2. #include <malloc.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5. #include <bios.h>
  6. #include <fcntl.h>
  7. #include <io.h>
  8. #include <unistd.h>
  9. #include <pc.h>
  10.  
  11. #include "oread.h"
  12. #include "zread.h"
  13.  
  14. #define D_READ    2
  15. #define    D_WRITE    3
  16.  
  17. #define CACHE_SECTORS 18
  18.  
  19. typedef struct {
  20.   int fd; /* or drive, if cm set */
  21.   int cm, hm, sm;
  22.   long file_ptr;
  23.   void *cache;
  24.   long cache_fptr;
  25.   long cache_fptre;
  26.   int volume_in_drive;
  27. } oread;
  28.  
  29. void *oread_open(char *fn)
  30. {
  31.   oread *or;
  32.   if ((strlen(fn) == 2) && (fn[1] == ':'))
  33.   {
  34.     char buf[512];
  35.     int status;
  36.  
  37.     switch (fn[0])
  38.     {
  39.       case 'a':
  40.       case 'A':
  41.         or = (oread *)xmalloc(sizeof(oread));
  42.         or->fd = 0;
  43.         break;
  44.       case 'b':
  45.       case 'B':
  46.         or = (oread *)xmalloc(sizeof(oread));
  47.         or->fd = 1;
  48.         break;
  49.       default:
  50.         fprintf(log_out, "Invalid drive specified: %s\n", fn);
  51.         errno = ENODEV;
  52.         return 0;
  53.     }
  54.     while ((status = biosdisk(D_READ, or->fd, 0, 0, 1, 1, buf)) == 6)
  55.       /* wait for valid read */ ;
  56.     if (status)
  57.     {
  58.       if (errno == 0)
  59.         errno = EIO;
  60.       return 0;
  61.     }
  62.  
  63.     biosdisk(8, or->fd, 0, 0, 0, 0, buf);
  64.     or->cm = (((buf[0] & 0x00c0) << 2) | (buf[1] & 0xff))+1;
  65.     or->hm = buf[3] + 1;
  66.     or->sm = buf[0] & 0x3f;
  67.     or->file_ptr = 0L;
  68.     or->cache = (void *)xmalloc(512*CACHE_SECTORS);
  69.     or->cache_fptr = -512*CACHE_SECTORS;
  70.     or->cache_fptre = -512*CACHE_SECTORS;
  71.     or->volume_in_drive = 0;
  72.     return or;
  73.   }
  74.   else
  75.   {
  76.     int fd;
  77.     if (*fn == '-' && fn[1] == '\0')
  78.       {
  79.         fd = fileno(stdin);
  80.         setmode(fd, O_BINARY);
  81.         fd = dup(fd);
  82.         close(fileno(stdin));
  83.         open("CON", O_RDONLY | O_TEXT); /* should reopen fileno(stdin) */
  84.       }
  85.     else
  86.       fd = _open(fn, O_RDONLY);
  87.     if (fd < 0)
  88.       return 0;
  89.     or = (oread *)xmalloc(sizeof(oread));
  90.     or->fd = fd;
  91.     or->cm = 0;
  92.     return or;
  93.   }
  94. }
  95.  
  96. int oread_read(void *rv, void *buffer)
  97. {
  98.   oread *r = (oread *)rv;
  99.   if (r->cm)
  100.   {
  101.     int c, h, s, v, sc;
  102.     if ((r->file_ptr >= r->cache_fptr) && (r->file_ptr < r->cache_fptre))
  103.     {
  104.       memcpy(buffer, (char *)(r->cache) + r->file_ptr - r->cache_fptr, 512);
  105.       r->file_ptr += 512;
  106.       return 512;
  107.     }
  108.     s = (unsigned long)(r->file_ptr) / 512;
  109.     h = s / r->sm;
  110.     c = h / r->hm;
  111.     v = c / r->cm;
  112.     s = s % r->sm;
  113.     h = h % r->hm;
  114.     c = c % r->cm;
  115.     if (v != r->volume_in_drive)
  116.     {
  117.       fprintf(log_out, "Please insert volume %03d . . .", v);
  118.       fflush(log_out);
  119.       if (getkey() == 3)
  120.       {
  121.         fprintf(log_out, "^C\n");
  122.         exit(3);
  123.       }
  124.       fprintf(log_out, "\n");
  125.       r->volume_in_drive = v;
  126.       r->cache_fptr = -512*CACHE_SECTORS;
  127.     }
  128.     sc = r->sm - s;
  129.     if (sc > CACHE_SECTORS)
  130.       sc = CACHE_SECTORS;
  131.     fprintf(log_out, "v=%02d c=%02d h=%02d s=%02d n=%02d\r", v, c, h, s, sc);
  132.     fflush(log_out);
  133.     if (biosdisk(D_READ, r->fd, h, c, s+1, sc, r->cache))
  134.       biosdisk(D_READ, r->fd, h, c, s+1, sc, r->cache);
  135.     memcpy(buffer, r->cache, 512);
  136.     r->cache_fptr = r->file_ptr;
  137.     r->cache_fptre = r->cache_fptr + 512*sc;
  138.     r->file_ptr += 512;
  139.     return 512;
  140.   }
  141.   else
  142.     return _read(r->fd, buffer, 512);
  143. }
  144.  
  145. #if 0
  146. void oread_skip(void *rv, long skip_bytes)
  147. {
  148.   oread *r = (oread *)rv;
  149.   if (r->cm)
  150.   {
  151.     r->file_ptr += skip_bytes;
  152.   }
  153.   else
  154.   {
  155.     lseek(r->fd, skip_bytes, 1);
  156.   }
  157. }
  158. #endif
  159.  
  160. void oread_close(void *rv)
  161. {
  162.   oread *r = (oread *)rv;
  163.   if (r->cm == 0)
  164.     _close(r->fd);
  165.   else
  166.     free(r->cache);
  167.   free(r);
  168. }
  169.