📄 dd.c
字号:
return 0;
DEBUG(printf("dd_fill: block %u\n", file->curr_blk);)
/* read block from regular file */
if(!file->is_device)
{
lseek(file->handle, (unsigned long)file->curr_blk *
file->buf_size, SEEK_SET);
temp = read(file->handle, file->buf, file->buf_size);
if(temp < 0)
{
printf("error reading file in dd_fill\n");
return -1;
}
/* zero-fill if short read */
else if(temp < file->buf_size)
memset(file->buf + temp, 0, file->buf_size - temp);
}
/* read block from disk
xxx - do zero-fill if full or partial read beyond end of disk */
else
{
temp = dd_rwdisk(file, _DISK_READ, file->curr_blk *
file->sects, file->buf_size / file->bps, file->buf);
if(temp != 0)
return -1;
}
DEBUG(printf("dd_fill: read %lu bytes so far\n",
(unsigned long)file->curr_blk * file->buf_size);)
file->needs_fill = false;
file->curr_blk++;
return 0;
}
/*****************************************************************************
*****************************************************************************/
static int dd_read(file_t *file, unsigned char *byte)
{
int err;
/* fill the buffer if it's empty */
if(file->needs_fill)
{
err = dd_fill(file);
if(err != 0)
return -1;
file->curr_off = 0;
}
/* read char from buffer */
*byte = file->buf[file->curr_off];
file->curr_off++;
if(file->curr_off >= file->buf_size)
file->needs_fill = true;
return 0;
}
/*////////////////////////////////////////////////////////////////////////////
OUTPUT
////////////////////////////////////////////////////////////////////////////*/
/*****************************************************************************
*****************************************************************************/
static int dd_flush(file_t *file)
{
int temp;
if(!file->needs_flush)
return 0;
DEBUG(printf("dd_flush: block %u\n", file->curr_blk);)
/* write block to regular file */
if(!file->is_device)
{
lseek(file->handle, (unsigned long)file->curr_blk *
file->buf_size, SEEK_SET);
temp = write(file->handle, file->buf, file->curr_off);
if(temp < 0)
{
printf("error writing file in dd_flush\n");
return -1;
}
}
/* write block to disk */
else
{
temp = dd_rwdisk(file, _DISK_WRITE, file->curr_blk *
file->sects, file->buf_size / file->bps, file->buf);
if(temp != 0)
return -1;
}
DEBUG(printf("dd_flush: wrote %lu bytes so far\n",
(unsigned long)file->curr_blk * file->buf_size);)
file->needs_flush = 0;
file->curr_blk++;
return 0;
}
/*****************************************************************************
*****************************************************************************/
static int dd_write(file_t *file, unsigned char byte)
{
int err;
file->buf[file->curr_off] = byte;
file->curr_off++;
file->needs_flush = true;
if(file->curr_off < file->buf_size)
return 0;
err = dd_flush(file);
file->curr_off = 0;
return err;
}
/*////////////////////////////////////////////////////////////////////////////
MAIN
////////////////////////////////////////////////////////////////////////////*/
/*****************************************************************************
*****************************************************************************/
static int dd_open(file_t *file, char *name, bool output)
{
unsigned long pos;
int temp;
memset(file, 0, sizeof(file_t));
/* opening a disk drive? */
if(isalpha(name[0]) && (name[1] == ':') && (name[2] == '\0'))
{
/* compute INT 13h-style drive number */
temp = toupper(name[0]);
if(temp >= 'C')
file->int13_dev = 0x80 + temp - 'C';
else
file->int13_dev = temp - 'A';
/* check if drive exists, and get disk geometry */
if(dd_get_geom(file) != 0)
return -1;
/* set buf_size equal to one track, for faster floppy access */
file->buf_size = file->bps * file->sects;
file->is_device = true;
}
/* else it's a regular file */
else
{
if(output)
temp = open(name, O_BINARY | O_RDWR | O_CREAT);
else
temp = open(name, O_BINARY | O_RDONLY);
if(temp < 0)
{
printf("error: could not open file '%s' "
"in dd_open\n", name);
return -1;
}
file->handle = temp;
file->buf_size = BUFLEN;
}
/* allocate block buffer
xxx - do this only for devices? */
file->buf = malloc(file->buf_size);
if(file->buf == NULL)
{
printf("error: could not allocate %u "
"bytes memory in dd_open\n", file->buf_size);
return -1;
}
/* compute size of file/device */
if(file->is_device)
file->size = (unsigned long)file->cyls * file->sects *
file->heads * file->bps;
else
{
pos = tell(file->handle);
lseek(file->handle, 0, SEEK_END);
file->size = tell(file->handle);
lseek(file->handle, pos, SEEK_SET);
}
if(!output)
file->needs_fill = true;
return 0;
}
/*****************************************************************************
*****************************************************************************/
static void dd_close(file_t *file)
{
if(!file->is_device)
close(file->handle);
if(file->buf != NULL)
free(file->buf);
memset(file, 0, sizeof(file_t));
}
/*****************************************************************************
*****************************************************************************/
int main(int arg_c, char *arg_v[])
{
unsigned long skip = 0, seek = 0, count = 0;
char *iname = NULL, *oname = NULL;
unsigned char one_byte;
file_t in, out;
int temp;
bool k;
/* usage */
if(arg_c < 2)
{
printf(_usage);
return 1;
}
/* get command line options */
for(temp = 1; temp < arg_c; temp++)
{
if(tolower(arg_v[temp][strlen(arg_v[temp]) - 1]) == 'k')
k = true;
else
k = false;
if(!memicmp(arg_v[temp], "if=", 3))
iname = arg_v[temp] + 3;
else if(!memicmp(arg_v[temp], "of=", 3))
oname = arg_v[temp] + 3;
else if(!memicmp(arg_v[temp], "skip=", 5))
{
skip = atol(arg_v[temp] + 5);
if(k)
skip *= 1024;
}
else if(!memicmp(arg_v[temp], "seek=", 5))
{
seek = atol(arg_v[temp] + 5);
if(k)
seek *= 1024;
}
else if(!memicmp(arg_v[temp], "count=", 6))
{
count = atol(arg_v[temp] + 6);
if(k)
count *= 1024;
}
else if(!memicmp(arg_v[temp], "probe", 5))
{
#if defined(__DJGPP__)
/* see file SRC/LIBC/BIOS/BIOSDISK.C of DJLSR203.ZIP */
printf("WARNING: DJGPP biosdisk() can't handle "
">18 sectors/track,\nso 'probe' "
"may not work\n");
#endif
_probe_floppy = true;
}
}
/* open files */
if(iname == NULL)
{
printf("error: no input file/device specified\n");
return 1;
}
if(oname == NULL)
{
printf("error: no output file/device specified\n");
return 1;
}
temp = dd_open(&in, iname, false);
if(temp < 0)
return 2;
temp = dd_open(&out, oname, true);
if(temp < 0)
return 2;
in.curr_off = skip % in.buf_size;
in.curr_blk = skip / in.buf_size;
out.curr_off = seek % out.buf_size;
/* write starts in the middle of a block? */
if(out.curr_off != 0)
{
out.needs_fill = true;
if(dd_fill(&out) != 0)
goto ERR;
}
out.curr_blk = seek / out.buf_size;
out.curr_off = seek % out.buf_size;
/* if count not given, use size of input */
if(count == 0)
count = in.size;
/* copy! */
for(; count != 0; count--)
{
if(dd_read(&in, &one_byte) != 0)
break;
if(dd_write(&out, one_byte) != 0)
break;
}
dd_flush(&out);
ERR:
dd_close(&out);
dd_close(&in);
old_fpt();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -