* Copyright (c) 1991 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Keith Muller of the University of California, San Diego and Lance
* Visser of Convex Computer Corporation.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)args.c 5.5 (Berkeley) 7/29/91";
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 *));
"bs", f_bs
, C_BS
, C_BS
|C_IBS
|C_OBS
,
"cbs", f_cbs
, C_CBS
, C_CBS
,
"count", f_count
, C_COUNT
, C_COUNT
,
"files", f_files
, C_FILES
, C_FILES
,
"ibs", f_ibs
, C_IBS
, C_BS
|C_IBS
,
"obs", f_obs
, C_OBS
, C_BS
|C_OBS
,
"seek", f_seek
, C_SEEK
, C_SEEK
,
"skip", f_skip
, C_SKIP
, C_SKIP
,
* args -- parse JCL syntax of dd.
static int c_arg
__P((const void *, const void *));
in
.dbsz
= out
.dbsz
= 512;
if ((arg
= index(oper
, '=')) == NULL
)
err("unknown operand %s", oper
);
err("no value specified for %s", oper
);
if (!(ap
= (struct arg
*)bsearch(&tmp
, args
,
sizeof(args
)/sizeof(struct arg
), sizeof(struct arg
),
err("unknown operand %s", tmp
.name
);
err("%s: illegal argument combination or already set",
/* Final sanity checks. */
* 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
))
/* Bs supersedes ibs and obs. */
if (ddflags
& C_BS
&& ddflags
& (C_IBS
|C_OBS
))
warn("bs supersedes ibs and obs");
* Ascii/ebcdic and cbs implies block/unblock.
* Block/unblock requires cbs and vice-versa.
if (ddflags
& (C_BLOCK
|C_UNBLOCK
)) {
err("record operations require cbs");
err("cbs cannot be zero");
cfunc
= ddflags
& C_BLOCK
? block
: unblock
;
} else if (ddflags
& C_CBS
) {
if (ddflags
& (C_ASCII
|C_EBCDIC
)) {
err("cbs meaningless if not doing record operations");
err("cbs cannot be zero");
if (in
.dbsz
== 0 || out
.dbsz
== 0)
err("buffer sizes cannot be zero");
* Read, write and seek calls take ints as arguments. Seek sizes
* could be larger if we wanted to do it in stages or check only
* 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
);
if (in
.offset
> INT_MAX
/ in
.dbsz
|| out
.offset
> INT_MAX
/ out
.dbsz
)
err("seek offsets cannot be larger than %d", INT_MAX
);
return (strcmp(((struct arg
*)a
)->name
, ((struct arg
*)b
)->name
));
in
.dbsz
= out
.dbsz
= (int)get_bsz(arg
);
cbsz
= (int)get_bsz(arg
);
cpy_cnt
= (u_int
)get_bsz(arg
);
files_cnt
= (int)get_bsz(arg
);
in
.dbsz
= (int)get_bsz(arg
);
out
.dbsz
= (int)get_bsz(arg
);
out
.offset
= (u_int
)get_bsz(arg
);
in
.offset
= (u_int
)get_bsz(arg
);
"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
,
"ucase", C_UCASE
, C_LCASE
, NULL
,
"unblock", C_UNBLOCK
, C_BLOCK
, NULL
,
register struct conv
*cp
;
static int c_conv
__P((const void *, const void *));
tmp
.name
= strsep(&arg
, ",");
if (!(cp
= (struct conv
*)bsearch(&tmp
, clist
,
sizeof(clist
)/sizeof(struct conv
), sizeof(struct conv
),
err("unknown conversion %s", tmp
.name
);
err("%s: illegal conversion combination", tmp
.name
);
return (strcmp(((struct conv
*)a
)->name
, ((struct conv
*)b
)->name
));
* Convert an expression of the following forms to an unsigned long.
* 1) A positive decimal number.
* 2) A positive decimal number followed by a b (mult by 512).
* 3) A positive decimal number followed by a k (mult by 1024).
* 4) A positive decimal number followed by a m (mult by 512).
* 5) A positive decimal number followed by a w (mult by sizeof int)
* 6) Two or more positive decimal numbers (with/without k,b or w).
* seperated by x (also * for backwards compatibility), specifying
* the product of the indicated values.
num
= strtoul(val
, &expr
, 0);
if (num
== ULONG_MAX
) /* Overflow. */
err("%s: %s", oper
, strerror(errno
));
if (expr
== val
) /* No digits. */
err("%s: illegal numeric value", oper
);
case '*': /* Backward compatible. */
num
*= get_bsz(expr
+ 1);
erange
: err("%s: %s", oper
, strerror(ERANGE
));
err("%s: illegal numeric value", oper
);