/* DISKTAPE.C * * "tape on a disk" emulator for MS-DOS and OS/2. * special GNU tar version * * Autor: Kai Uwe Rommel * Datum: Thu 28-Dec-1989 * Stand: Fri 21-Sep-1990 * * Compiler: MS C ab 5.00 * System: OS/2 ab 1.1 * */ #include #include #include #include "diskacc.h" #define SLOTS 4 struct slot { int handle; unsigned short sides, tracks, sectors; unsigned long current, size; }; static struct slot tbl[SLOTS]; int __rmt_open(char *path, int oflag, int mode) { int drive = *path - '0'; int cnt, fd; for ( cnt = 0; cnt < SLOTS; cnt++ ) if ( tbl[cnt].handle == 0 ) break; if ( cnt == SLOTS ) return -1; fd = DskOpen(drive, &tbl[cnt].sides, &tbl[cnt].tracks, &tbl[cnt].sectors); if ( fd < 0 ) return -1; tbl[cnt].handle = fd; tbl[cnt].current = 0L; tbl[cnt].size = 512L * tbl[cnt].sides * tbl[cnt].tracks * tbl[cnt].sectors; return cnt; } int __rmt_close(int handle) { if ( (handle < 0) || (SLOTS <= handle) ) return -1; if ( tbl[handle].handle == 0 ) return -1; DskClose(tbl[handle].handle); tbl[handle].handle = 0; return 0; } int __rmt_read(int handle, char *buf, unsigned nbyte) { unsigned side, track, sector, nsects, ok, chunk; if ( (handle < 0) || (SLOTS <= handle) ) return -1; if ( tbl[handle].handle == 0 ) return -1; if ( nbyte % 512 != 0 ) return -1; sector = (unsigned) (tbl[handle].current / 512L); track = sector / tbl[handle].sectors; sector -= track * tbl[handle].sectors; side = track % tbl[handle].sides; track /= tbl[handle].sides; nsects = nbyte / 512; ok = 0; while ( nsects != 0 ) { if ( track >= tbl[handle].tracks ) break; chunk = min(tbl[handle].sectors - sector, nsects); if ( DskRead(tbl[handle].handle, side, track, sector + 1, chunk, buf) != 0 ) break; ok += chunk; nsects -= chunk; sector = 0; if ( ++side >= tbl[handle].sides ) { side = 0; track++; } tbl[handle].current += 512L * chunk; buf += 512 * chunk; } return ok * 512; } int __rmt_write(int handle, char *buf, unsigned nbyte) { unsigned side, track, sector, nsects, ok, chunk; if ( (handle < 0) || (SLOTS <= handle) ) return -1; if ( tbl[handle].handle == 0 ) return -1; if ( nbyte % 512 != 0 ) return -1; sector = (unsigned) (tbl[handle].current / 512L); track = sector / tbl[handle].sectors; sector -= track * tbl[handle].sectors; side = track % tbl[handle].sides; track /= tbl[handle].sides; nsects = nbyte / 512; ok = 0; while ( nsects != 0 ) { if ( track >= tbl[handle].tracks ) break; chunk = min(tbl[handle].sectors - sector, nsects); if ( DskWrite(tbl[handle].handle, side, track, sector + 1, chunk, buf) != 0 ) break; ok += chunk; nsects -= chunk; sector = 0; if ( ++side >= tbl[handle].sides ) { side = 0; track++; } tbl[handle].current += 512L * chunk; buf += 512 * chunk; } if ( nsects != 0 ) errno = ENOSPC; return ok * 512; } long __rmt_lseek(int handle, long offset, int where) { if ( (handle < 0) || (SLOTS <= handle) ) return -1; if ( tbl[handle].handle == 0 ) return -1; if ( offset % 512L != 0L ) return -1; switch ( where ) { case SEEK_SET: tbl[handle].current = offset; break; case SEEK_CUR: tbl[handle].current += offset; break; case SEEK_END: tbl[handle].current = tbl[handle].size + offset; break; } if ( tbl[handle].current > tbl[handle].size ) { tbl[handle].current = 0L; errno = EINVAL; return -1L; } return tbl[handle].current; } /* Ende DISKTAPE.C */