home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 May
/
Chip_2000-05_cd2.bin
/
dosutils
/
gtar109
/
disktape.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-14
|
4KB
|
217 lines
/* 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 <stdio.h>
#include <stdlib.h>
#include <errno.h>
#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 */