/*-
- * Copyright (c) 1991, 1993
+ * Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
*/
#ifndef lint
-static char sccsid[] = "@(#)args.c 8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)args.c 8.3 (Berkeley) %G%";
#endif /* not lint */
#include <sys/types.h>
-#include <limits.h>
+
+#include <err.h>
#include <errno.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
#include "dd.h"
#include "extern.h"
-static u_long get_bsz __P((char *));
-
-static void f_bs __P((char *));
-static void f_cbs __P((char *));
-static void f_conv __P((char *));
-static void f_count __P((char *));
-static void f_files __P((char *));
-static void f_ibs __P((char *));
-static void f_if __P((char *));
-static void f_obs __P((char *));
-static void f_of __P((char *));
-static void f_seek __P((char *));
-static void f_skip __P((char *));
+static int c_arg __P((const void *, const void *));
+static int c_conv __P((const void *, const void *));
+static void f_bs __P((char *));
+static void f_cbs __P((char *));
+static void f_conv __P((char *));
+static void f_count __P((char *));
+static void f_files __P((char *));
+static void f_ibs __P((char *));
+static void f_if __P((char *));
+static void f_obs __P((char *));
+static void f_of __P((char *));
+static void f_seek __P((char *));
+static void f_skip __P((char *));
+static u_long get_bsz __P((char *));
static struct arg {
char *name;
void (*f) __P((char *));
u_int set, noset;
} args[] = {
- "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,
- "seek", f_seek, C_SEEK, C_SEEK,
- "skip", f_skip, C_SKIP, C_SKIP,
+ { "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 },
+ { "seek", f_seek, C_SEEK, C_SEEK },
+ { "skip", f_skip, C_SKIP, C_SKIP },
};
static char *oper;
*/
void
jcl(argv)
- register char **argv;
+ char **argv;
{
- register struct arg *ap;
- struct arg tmp;
+ struct arg *ap, tmp;
char *arg;
- static int c_arg __P((const void *, const void *));
in.dbsz = out.dbsz = 512;
while (oper = *++argv) {
- if ((arg = index(oper, '=')) == NULL)
- err("unknown operand %s", oper);
+ if ((arg = strchr(oper, '=')) == NULL)
+ errx(1, "unknown operand %s", oper);
*arg++ = '\0';
if (!*arg)
- err("no value specified for %s", oper);
+ errx(1, "no value specified for %s", oper);
tmp.name = oper;
if (!(ap = (struct arg *)bsearch(&tmp, args,
sizeof(args)/sizeof(struct arg), sizeof(struct arg),
c_arg)))
- err("unknown operand %s", tmp.name);
+ errx(1, "unknown operand %s", tmp.name);
if (ddflags & ap->noset)
- err("%s: illegal argument combination or already set",
+ errx(1, "%s: illegal argument combination or already set",
tmp.name);
ddflags |= ap->set;
ap->f(arg);
/* Bs supersedes ibs and obs. */
if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
- warn("bs supersedes ibs and obs");
+ warnx("bs supersedes ibs and obs");
}
/*
*/
if (ddflags & (C_BLOCK|C_UNBLOCK)) {
if (!(ddflags & C_CBS))
- err("record operations require cbs");
+ errx(1, "record operations require cbs");
if (cbsz == 0)
- err("cbs cannot be zero");
+ errx(1, "cbs cannot be zero");
cfunc = ddflags & C_BLOCK ? block : unblock;
} else if (ddflags & C_CBS) {
if (ddflags & (C_ASCII|C_EBCDIC)) {
cfunc = block;
}
} else
- err("cbs meaningless if not doing record operations");
+ errx(1, "cbs meaningless if not doing record operations");
if (cbsz == 0)
- err("cbs cannot be zero");
+ errx(1, "cbs cannot be zero");
} else
cfunc = def;
if (in.dbsz == 0 || out.dbsz == 0)
- err("buffer sizes cannot be zero");
+ errx(1, "buffer sizes cannot be zero");
/*
* Read, write and seek calls take ints as arguments. Seek sizes
* regular files, but it's probably not worth it.
*/
if (in.dbsz > INT_MAX || out.dbsz > INT_MAX)
- err("buffer sizes cannot be greater than %d", INT_MAX);
+ errx(1, "buffer sizes cannot be greater than %d", INT_MAX);
if (in.offset > INT_MAX / in.dbsz || out.offset > INT_MAX / out.dbsz)
- err("seek offsets cannot be larger than %d", INT_MAX);
+ errx(1, "seek offsets cannot be larger than %d", INT_MAX);
}
static int
c_arg(a, b)
const void *a, *b;
{
+
return (strcmp(((struct arg *)a)->name, ((struct arg *)b)->name));
}
f_bs(arg)
char *arg;
{
+
in.dbsz = out.dbsz = (int)get_bsz(arg);
}
f_cbs(arg)
char *arg;
{
+
cbsz = (int)get_bsz(arg);
}
f_count(arg)
char *arg;
{
+
cpy_cnt = (u_int)get_bsz(arg);
if (!cpy_cnt)
terminate(0);
f_files(arg)
char *arg;
{
+
files_cnt = (int)get_bsz(arg);
}
f_ibs(arg)
char *arg;
{
+
if (!(ddflags & C_BS))
in.dbsz = (int)get_bsz(arg);
}
f_if(arg)
char *arg;
{
+
in.name = arg;
}
f_obs(arg)
char *arg;
{
+
if (!(ddflags & C_BS))
out.dbsz = (int)get_bsz(arg);
}
f_of(arg)
char *arg;
{
+
out.name = arg;
}
f_seek(arg)
char *arg;
{
+
out.offset = (u_int)get_bsz(arg);
}
f_skip(arg)
char *arg;
{
+
in.offset = (u_int)get_bsz(arg);
}
u_int set, noset;
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,
- "swab", C_SWAB, 0, NULL,
- "sync", C_SYNC, 0, NULL,
- "ucase", C_UCASE, C_LCASE, NULL,
- "unblock", C_UNBLOCK, C_BLOCK, NULL,
+ { "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 },
+ { "swab", C_SWAB, 0, NULL },
+ { "sync", C_SYNC, 0, NULL },
+ { "ucase", C_UCASE, C_LCASE, NULL },
+ { "unblock", C_UNBLOCK, C_BLOCK, NULL },
};
static void
f_conv(arg)
char *arg;
{
- register struct conv *cp;
- struct conv tmp;
- static int c_conv __P((const void *, const void *));
+ 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)))
- err("unknown conversion %s", tmp.name);
+ errx(1, "unknown conversion %s", tmp.name);
if (ddflags & cp->noset)
- err("%s: illegal conversion combination", tmp.name);
+ errx(1, "%s: illegal conversion combination", tmp.name);
ddflags |= cp->set;
if (cp->ctab)
ctab = cp->ctab;
c_conv(a, b)
const void *a, *b;
{
+
return (strcmp(((struct conv *)a)->name, ((struct conv *)b)->name));
}
get_bsz(val)
char *val;
{
- char *expr;
u_long num, t;
+ char *expr;
num = strtoul(val, &expr, 0);
if (num == ULONG_MAX) /* Overflow. */
- err("%s: %s", oper, strerror(errno));
+ err(1, "%s", oper);
if (expr == val) /* No digits. */
- err("%s: illegal numeric value", oper);
+ errx(1, "%s: illegal numeric value", oper);
switch(*expr) {
case 'b':
t = num;
num *= get_bsz(expr + 1);
if (t > num)
-erange: err("%s: %s", oper, strerror(ERANGE));
+erange: errx(1, "%s: %s", oper, strerror(ERANGE));
break;
default:
- err("%s: illegal numeric value", oper);
+ errx(1, "%s: illegal numeric value", oper);
}
- return(num);
+ return (num);
}
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)dd.c 8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)dd.c 8.3 (Berkeley) %G%";
#endif /* not lint */
#include <sys/param.h>
#include <sys/mtio.h>
#include <ctype.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
u_int ddflags; /* conversion options */
u_int cbsz; /* conversion block size */
u_int files_cnt = 1; /* # of files to copy */
-int errstats; /* show statistics on error */
u_char *ctab; /* conversion table */
int
jcl(argv);
setup();
- (void)signal(SIGINFO, summary);
+ (void)signal(SIGINFO, summaryx);
(void)signal(SIGINT, terminate);
- for (errstats = 1; files_cnt--;)
+ atexit(summary);
+
+ while (files_cnt--)
dd_in();
dd_close();
- summary(0);
exit(0);
}
static void
-setup()
+getfdtype(io)
+ IO *io;
{
- register u_int cnt;
- struct stat sb;
struct mtget mt;
+ struct stat sb;
+
+ if (fstat(io->fd, &sb))
+ err(1, "%s", io->name);
+ if (S_ISCHR(sb.st_mode))
+ io->flags |= ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE;
+ else if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
+ io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */
+}
+
+static void
+setup()
+{
+ u_int cnt;
if (in.name == NULL) {
in.name = "stdin";
} else {
in.fd = open(in.name, O_RDONLY, 0);
if (in.fd < 0)
- err("%s: %s", in.name, strerror(errno));
+ err(1, "%s", in.name);
}
- if (fstat(in.fd, &sb))
- err("%s: %s", in.name, strerror(errno));
- if (S_ISCHR(sb.st_mode))
- in.flags |= ioctl(in.fd, MTIOCGET, &mt) ? ISCHR : ISTAPE;
- else if (lseek(in.fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
- in.flags |= ISPIPE; /* XXX fixed in 4.4BSD */
+ getfdtype(&in);
if (files_cnt > 1 && !(in.flags & ISTAPE))
- err("files is not supported for non-tape devices");
+ errx(1, "files is not supported for non-tape devices");
if (out.name == NULL) {
/* No way to check for read access here. */
out.flags |= NOREAD;
}
if (out.fd < 0)
- err("%s: %s", out.name, strerror(errno));
+ err(1, "%s", out.name);
}
- if (fstat(out.fd, &sb))
- err("%s: %s", out.name, strerror(errno));
- if (S_ISCHR(sb.st_mode))
- out.flags |= ioctl(out.fd, MTIOCGET, &mt) ? ISCHR : ISTAPE;
- else if (lseek(out.fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
- out.flags |= ISPIPE; /* XXX fixed in 4.4BSD */
+ getfdtype(&out);
/*
* Allocate space for the input and output buffers. If not doing
*/
if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL)
- err("%s", strerror(errno));
+ err(1, NULL);
out.db = in.db;
} else if ((in.db =
malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL ||
(out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL)
- err("%s", strerror(errno));
+ err(1, NULL);
in.dbp = in.db;
out.dbp = out.db;
static void
dd_in()
{
- register int flags, n;
+ int flags, n;
for (flags = ddflags;;) {
if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
* the warning message be followed by an I/O display.
*/
if (!(flags & C_NOERROR))
- err("%s: %s", in.name, strerror(errno));
- warn("%s: %s", in.name, strerror(errno));
- summary(0);
+ err(1, "%s", in.name);
+ warn("%s", in.name);
+ summary();
/*
* If it's not a tape drive or a pipe, seek past the
*/
if (!(in.flags & (ISPIPE|ISTAPE)) &&
lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
- warn("%s: %s", in.name, strerror(errno));
+ warn("%s", in.name);
/* If sync not specified, omit block and continue. */
if (!(ddflags & C_SYNC))
else if (cfunc == unblock)
unblock_close();
if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) {
- bzero(out.dbp, out.dbsz - out.dbcnt);
+ memset(out.dbp, 0, out.dbsz - out.dbcnt);
out.dbcnt = out.dbsz;
}
if (out.dbcnt)
int force;
{
static int warned;
- register int cnt, n, nw;
- register u_char *outp;
+ int cnt, n, nw;
+ u_char *outp;
/*
* Write one or more blocks out. The common case is writing a full
nw = write(out.fd, outp, cnt);
if (nw <= 0) {
if (nw == 0)
- err("%s: end of device", out.name);
+ errx(1, "%s: end of device", out.name);
if (errno != EINTR)
- err("%s: %s",
- out.name, strerror(errno));
+ err(1, "%s", out.name);
nw = 0;
}
outp += nw;
break;
if (out.flags & ISCHR && !warned) {
warned = 1;
- warn("%s: short write on character device",
+ warnx("%s: short write on character device",
out.name);
}
if (out.flags & ISTAPE)
- err("%s: short write on tape device", out.name);
+ errx(1, "%s: short write on tape device", out.name);
}
if ((out.dbcnt -= n) < out.dbsz)
break;