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

📄 dd.c

📁 Android 一些工具
💻 C
📖 第 1 页 / 共 3 页
字号:
voidblock_close(void){	/*	 * Copy any remaining data into the output buffer and pad to a record.	 * Don't worry about truncation or translation, the input buffer is	 * always empty when truncating, and no characters have been added for	 * translation.  The bottom line is that anything left in the input	 * buffer is a truncated record.  Anything left in the output buffer	 * just wasn't big enough.	 */	if (in.dbcnt) {		++st.trunc;		(void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);		(void)memset(out.dbp + in.dbcnt,		    ctab ? ctab[' '] : ' ', cbsz - in.dbcnt);		out.dbcnt += cbsz;	}}/* * Convert fixed length (cbsz) records to variable length.  Deletes any * trailing blanks and appends a newline. * * max in buffer:  MAX(ibs, cbsz) + cbsz * max out buffer: obs + cbsz */voidunblock(void){	uint64_t cnt;	u_char *inp;	const u_char *t;	/* Translation and case conversion. */	if ((t = ctab) != NULL)		for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--)			*inp = t[*inp];	/*	 * Copy records (max cbsz size chunks) into the output buffer.  The	 * translation has to already be done or we might not recognize the	 * spaces.	 */	for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {		for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t);		if (t >= inp) {			cnt = t - inp + 1;			(void)memmove(out.dbp, inp, cnt);			out.dbp += cnt;			out.dbcnt += cnt;		}		++out.dbcnt;		*out.dbp++ = '\n';		if (out.dbcnt >= out.dbsz)			dd_out(0);	}	if (in.dbcnt)		(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);	in.dbp = in.db + in.dbcnt;}voidunblock_close(void){	uint64_t cnt;	u_char *t;	if (in.dbcnt) {		warnx("%s: short input record", in.name);		for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t);		if (t >= in.db) {			cnt = t - in.db + 1;			(void)memmove(out.dbp, in.db, cnt);			out.dbp += cnt;			out.dbcnt += cnt;		}		++out.dbcnt;		*out.dbp++ = '\n';	}}#endif	/* NO_CONV */#define	tv2mS(tv) ((tv).tv_sec * 1000LL + ((tv).tv_usec + 500) / 1000)voidsummary(void){	char buf[100];	int64_t mS;	struct timeval tv;	if (progress)		(void)write(STDERR_FILENO, "\n", 1);	(void)gettimeofday(&tv, NULL);	mS = tv2mS(tv) - tv2mS(st.start);	if (mS == 0)		mS = 1;	/* Use snprintf(3) so that we don't reenter stdio(3). */	(void)snprintf(buf, sizeof(buf),	    "%llu+%llu records in\n%llu+%llu records out\n",	    (unsigned long long)st.in_full,  (unsigned long long)st.in_part,	    (unsigned long long)st.out_full, (unsigned long long)st.out_part);	(void)write(STDERR_FILENO, buf, strlen(buf));	if (st.swab) {		(void)snprintf(buf, sizeof(buf), "%llu odd length swab %s\n",		    (unsigned long long)st.swab,		    (st.swab == 1) ? "block" : "blocks");		(void)write(STDERR_FILENO, buf, strlen(buf));	}	if (st.trunc) {		(void)snprintf(buf, sizeof(buf), "%llu truncated %s\n",		    (unsigned long long)st.trunc,		    (st.trunc == 1) ? "block" : "blocks");		(void)write(STDERR_FILENO, buf, strlen(buf));	}	if (st.sparse) {		(void)snprintf(buf, sizeof(buf), "%llu sparse output %s\n",		    (unsigned long long)st.sparse,		    (st.sparse == 1) ? "block" : "blocks");		(void)write(STDERR_FILENO, buf, strlen(buf));	}	(void)snprintf(buf, sizeof(buf),	    "%llu bytes transferred in %lu.%03d secs (%llu bytes/sec)\n",	    (unsigned long long) st.bytes,	    (long) (mS / 1000),	    (int) (mS % 1000),	    (unsigned long long) (st.bytes * 1000LL / mS));	(void)write(STDERR_FILENO, buf, strlen(buf));}voidterminate(int notused){	exit(0);	/* NOTREACHED */}static int	c_arg(const void *, const void *);#ifndef	NO_CONVstatic int	c_conv(const void *, const void *);#endifstatic void	f_bs(char *);static void	f_cbs(char *);static void	f_conv(char *);static void	f_count(char *);static void	f_files(char *);static void	f_ibs(char *);static void	f_if(char *);static void	f_obs(char *);static void	f_of(char *);static void	f_seek(char *);static void	f_skip(char *);static void	f_progress(char *);static const struct arg {	const char *name;	void (*f)(char *);	u_int set, noset;} args[] = {     /* the array needs to be sorted by the first column so	bsearch() can be used to find commands quickly */	{ "bs",		f_bs,		C_BS,	 C_BS|C_IBS|C_OBS|C_OSYNC },	{ "cbs",	f_cbs,		C_CBS,	 C_CBS },	{ "conv",	f_conv,		0,	 0 },	{ "count",	f_count,	C_COUNT, C_COUNT },	{ "files",	f_files,	C_FILES, C_FILES },	{ "ibs",	f_ibs,		C_IBS,	 C_BS|C_IBS },	{ "if",		f_if,		C_IF,	 C_IF },	{ "obs",	f_obs,		C_OBS,	 C_BS|C_OBS },	{ "of",		f_of,		C_OF,	 C_OF },	{ "progress",	f_progress,	0,	 0 },	{ "seek",	f_seek,		C_SEEK,	 C_SEEK },	{ "skip",	f_skip,		C_SKIP,	 C_SKIP },};/* * args -- parse JCL syntax of dd. */voidjcl(char **argv){	struct arg *ap, tmp;	char *oper, *arg;	in.dbsz = out.dbsz = 512;	while ((oper = *++argv) != NULL) {		if ((arg = strchr(oper, '=')) == NULL) {			fprintf(stderr, "unknown operand %s\n", oper);			exit(1);			/* NOTREACHED */		}		*arg++ = '\0';		if (!*arg) {			fprintf(stderr, "no value specified for %s\n", oper);			exit(1);			/* NOTREACHED */		}		tmp.name = oper;		if (!(ap = (struct arg *)bsearch(&tmp, args,		    sizeof(args)/sizeof(struct arg), sizeof(struct arg),		    c_arg))) {			fprintf(stderr, "unknown operand %s\n", tmp.name);			exit(1);			/* NOTREACHED */		}		if (ddflags & ap->noset) {			fprintf(stderr,			    "%s: illegal argument combination or already set\n",			    tmp.name);			exit(1);			/* NOTREACHED */		}		ddflags |= ap->set;		ap->f(arg);	}	/* Final sanity checks. */	if (ddflags & C_BS) {		/*		 * Bs is turned off by any conversion -- we assume the user		 * just wanted to set both the input and output block sizes		 * and didn't want the bs semantics, so we don't warn.		 */		if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |		    C_UNBLOCK | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) {			ddflags &= ~C_BS;			ddflags |= C_IBS|C_OBS;		}		/* Bs supersedes ibs and obs. */		if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))			fprintf(stderr, "bs supersedes ibs and obs\n");	}	/*	 * Ascii/ebcdic and cbs implies block/unblock.	 * Block/unblock requires cbs and vice-versa.	 */	if (ddflags & (C_BLOCK|C_UNBLOCK)) {		if (!(ddflags & C_CBS)) {			fprintf(stderr, "record operations require cbs\n");			exit(1);			/* NOTREACHED */		}		cfunc = ddflags & C_BLOCK ? block : unblock;	} else if (ddflags & C_CBS) {		if (ddflags & (C_ASCII|C_EBCDIC)) {			if (ddflags & C_ASCII) {				ddflags |= C_UNBLOCK;				cfunc = unblock;			} else {				ddflags |= C_BLOCK;				cfunc = block;			}		} else {			fprintf(stderr,			    "cbs meaningless if not doing record operations\n");			exit(1);			/* NOTREACHED */		}	} else		cfunc = def;	/* Read, write and seek calls take off_t as arguments.	 *	 * The following check is not done because an off_t is a quad	 *  for current NetBSD implementations.	 *	 * if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)	 *	errx(1, "seek offsets cannot be larger than %d", INT_MAX);	 */}static intc_arg(const void *a, const void *b){	return (strcmp(((const struct arg *)a)->name,	    ((const struct arg *)b)->name));}static long long strsuftoll(const char* name, const char* arg, int def, unsigned int max){	long long result;		if (sscanf(arg, "%lld", &result) == 0)		result = def;	return result;}static voidf_bs(char *arg){	in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX);}static voidf_cbs(char *arg){	cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX);}static voidf_count(char *arg){	cpy_cnt = strsuftoll("block count", arg, 0, LLONG_MAX);	if (!cpy_cnt)		terminate(0);}static voidf_files(char *arg){	files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX);	if (!files_cnt)		terminate(0);}static voidf_ibs(char *arg){	if (!(ddflags & C_BS))		in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX);}static voidf_if(char *arg){	in.name = arg;}static voidf_obs(char *arg){	if (!(ddflags & C_BS))		out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX);}static voidf_of(char *arg){	out.name = arg;}static voidf_seek(char *arg){	out.offset = strsuftoll("seek blocks", arg, 0, LLONG_MAX);}static voidf_skip(char *arg){	in.offset = strsuftoll("skip blocks", arg, 0, LLONG_MAX);}static voidf_progress(char *arg){	if (*arg != '0')		progress = 1;}#ifdef	NO_CONV/* Build a small version (i.e. for a ramdisk root) */static voidf_conv(char *arg){	fprintf(stderr, "conv option disabled\n");	exit(1);	/* NOTREACHED */}#else	/* NO_CONV */static const struct conv {	const char *name;	u_int set, noset;	const u_char *ctab;} clist[] = {	{ "ascii",	C_ASCII,	C_EBCDIC,	e2a_POSIX },	{ "block",	C_BLOCK,	C_UNBLOCK,	NULL },	{ "ebcdic",	C_EBCDIC,	C_ASCII,	a2e_POSIX },	{ "ibm",	C_EBCDIC,	C_ASCII,	a2ibm_POSIX },	{ "lcase",	C_LCASE,	C_UCASE,	NULL },	{ "noerror",	C_NOERROR,	0,		NULL },	{ "notrunc",	C_NOTRUNC,	0,		NULL },	{ "oldascii",	C_ASCII,	C_EBCDIC,	e2a_32V },	{ "oldebcdic",	C_EBCDIC,	C_ASCII,	a2e_32V },	{ "oldibm",	C_EBCDIC,	C_ASCII,	a2ibm_32V },	{ "osync",	C_OSYNC,	C_BS,		NULL },	{ "sparse",	C_SPARSE,	0,		NULL },	{ "swab",	C_SWAB,		0,		NULL },	{ "sync",	C_SYNC,		0,		NULL },	{ "ucase",	C_UCASE,	C_LCASE,	NULL },	{ "unblock",	C_UNBLOCK,	C_BLOCK,	NULL },	/* If you add items to this table, be sure to add the	 * conversions to the C_BS check in the jcl routine above.	 */};static voidf_conv(char *arg){	struct conv *cp, tmp;	while (arg != NULL) {		tmp.name = strsep(&arg, ",");		if (!(cp = (struct conv *)bsearch(&tmp, clist,		    sizeof(clist)/sizeof(struct conv), sizeof(struct conv),		    c_conv))) {			errx(EXIT_FAILURE, "unknown conversion %s", tmp.name);			/* NOTREACHED */		}		if (ddflags & cp->noset) {			errx(EXIT_FAILURE, "%s: illegal conversion combination", tmp.name);			/* NOTREACHED */		}		ddflags |= cp->set;		if (cp->ctab)			ctab = cp->ctab;	}}static intc_conv(const void *a, const void *b){	return (strcmp(((const struct conv *)a)->name,	    ((const struct conv *)b)->name));}#endif	/* NO_CONV */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -