⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dd.c

📁 一个类linux的dos下开发的操作系统.
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -