home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd2.bin / dosutils / gtar109 / disktape.c < prev    next >
C/C++ Source or Header  |  1991-01-14  |  4KB  |  217 lines

  1. /* DISKTAPE.C
  2.  *
  3.  * "tape on a disk" emulator for MS-DOS and OS/2.
  4.  * special GNU tar version
  5.  *
  6.  * Autor:    Kai Uwe Rommel
  7.  * Datum:    Thu 28-Dec-1989
  8.  * Stand:    Fri 21-Sep-1990
  9.  *
  10.  * Compiler: MS C ab 5.00
  11.  * System:   OS/2 ab 1.1
  12.  *
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <errno.h>
  18.  
  19. #include "diskacc.h"
  20.  
  21. #define SLOTS 4
  22.  
  23.  
  24. struct slot
  25. {
  26.   int handle;
  27.   unsigned short sides, tracks, sectors;
  28.   unsigned long current, size;
  29. };
  30.  
  31. static struct slot tbl[SLOTS];
  32.  
  33.  
  34. int __rmt_open(char *path, int oflag, int mode)
  35. {
  36.   int drive = *path - '0';
  37.   int cnt, fd;
  38.  
  39.   for ( cnt = 0; cnt < SLOTS; cnt++ )
  40.     if ( tbl[cnt].handle == 0 )
  41.       break;
  42.  
  43.   if ( cnt == SLOTS )
  44.     return -1;
  45.  
  46.   fd = DskOpen(drive, &tbl[cnt].sides, &tbl[cnt].tracks, &tbl[cnt].sectors);
  47.  
  48.   if ( fd < 0 )
  49.     return -1;
  50.  
  51.   tbl[cnt].handle = fd;
  52.   tbl[cnt].current = 0L;
  53.   tbl[cnt].size = 512L * tbl[cnt].sides * tbl[cnt].tracks * tbl[cnt].sectors;
  54.  
  55.   return cnt;
  56. }
  57.  
  58.  
  59. int __rmt_close(int handle)
  60. {
  61.   if ( (handle < 0) || (SLOTS <= handle) )
  62.     return -1;
  63.  
  64.   if ( tbl[handle].handle == 0 )
  65.     return -1;
  66.  
  67.   DskClose(tbl[handle].handle);
  68.   tbl[handle].handle = 0;
  69.  
  70.   return 0;
  71. }
  72.  
  73.  
  74. int __rmt_read(int handle, char *buf, unsigned nbyte)
  75. {
  76.   unsigned side, track, sector, nsects, ok, chunk;
  77.  
  78.   if ( (handle < 0) || (SLOTS <= handle) )
  79.     return -1;
  80.  
  81.   if ( tbl[handle].handle == 0 )
  82.     return -1;
  83.  
  84.   if ( nbyte % 512 != 0 )
  85.     return -1;
  86.  
  87.   sector = (unsigned) (tbl[handle].current / 512L);
  88.  
  89.   track  = sector / tbl[handle].sectors;
  90.   sector -= track * tbl[handle].sectors;
  91.  
  92.   side   = track % tbl[handle].sides;
  93.   track  /= tbl[handle].sides;
  94.  
  95.   nsects = nbyte / 512;
  96.   ok = 0;
  97.  
  98.   while ( nsects != 0 )
  99.   {
  100.     if ( track >= tbl[handle].tracks )
  101.       break;
  102.  
  103.     chunk = min(tbl[handle].sectors - sector, nsects);
  104.  
  105.     if ( DskRead(tbl[handle].handle, side, track, sector + 1, chunk, buf) != 0 )
  106.       break;
  107.  
  108.     ok += chunk;
  109.     nsects -= chunk;
  110.     sector = 0;
  111.  
  112.     if ( ++side >= tbl[handle].sides )
  113.     {
  114.       side = 0;
  115.       track++;
  116.     }
  117.  
  118.     tbl[handle].current += 512L * chunk;
  119.     buf += 512 * chunk;
  120.   }
  121.  
  122.   return ok * 512;
  123. }
  124.  
  125.  
  126. int __rmt_write(int handle, char *buf, unsigned nbyte)
  127. {
  128.   unsigned side, track, sector, nsects, ok, chunk;
  129.  
  130.   if ( (handle < 0) || (SLOTS <= handle) )
  131.     return -1;
  132.  
  133.   if ( tbl[handle].handle == 0 )
  134.     return -1;
  135.  
  136.   if ( nbyte % 512 != 0 )
  137.     return -1;
  138.  
  139.   sector = (unsigned) (tbl[handle].current / 512L);
  140.  
  141.   track  = sector / tbl[handle].sectors;
  142.   sector -= track * tbl[handle].sectors;
  143.  
  144.   side   = track % tbl[handle].sides;
  145.   track  /= tbl[handle].sides;
  146.  
  147.   nsects = nbyte / 512;
  148.   ok = 0;
  149.  
  150.   while ( nsects != 0 )
  151.   {
  152.     if ( track >= tbl[handle].tracks )
  153.       break;
  154.  
  155.     chunk = min(tbl[handle].sectors - sector, nsects);
  156.  
  157.     if ( DskWrite(tbl[handle].handle, side, track, sector + 1, chunk, buf) != 0 )
  158.       break;
  159.  
  160.     ok += chunk;
  161.     nsects -= chunk;
  162.     sector = 0;
  163.  
  164.     if ( ++side >= tbl[handle].sides )
  165.     {
  166.       side = 0;
  167.       track++;
  168.     }
  169.  
  170.     tbl[handle].current += 512L * chunk;
  171.     buf += 512 * chunk;
  172.   }
  173.  
  174.   if ( nsects != 0 )
  175.     errno = ENOSPC;
  176.  
  177.   return ok * 512;
  178. }
  179.  
  180.  
  181. long __rmt_lseek(int handle, long offset, int where)
  182. {
  183.   if ( (handle < 0) || (SLOTS <= handle) )
  184.     return -1;
  185.  
  186.   if ( tbl[handle].handle == 0 )
  187.     return -1;
  188.  
  189.   if ( offset % 512L != 0L )
  190.     return -1;
  191.  
  192.   switch ( where )
  193.   {
  194.   case SEEK_SET:
  195.     tbl[handle].current = offset;
  196.     break;
  197.   case SEEK_CUR:
  198.     tbl[handle].current += offset;
  199.     break;
  200.   case SEEK_END:
  201.     tbl[handle].current = tbl[handle].size + offset;
  202.     break;
  203.   }
  204.  
  205.   if ( tbl[handle].current > tbl[handle].size )
  206.   {
  207.     tbl[handle].current = 0L;
  208.     errno = EINVAL;
  209.     return -1L;
  210.   }
  211.  
  212.   return tbl[handle].current;
  213. }
  214.  
  215.  
  216. /* Ende DISKTAPE.C */
  217.