]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - text-utils/display.c
2 * Copyright (c) 1989 The Regents of the University of California.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <sys/param.h>
44 static void doskip(char *, int);
45 static u_char
*get(void);
48 #define MIN(a,b) ((a)<(b)?(a):(b))
51 enum _vflag vflag
= FIRST
;
53 static off_t address
; /* address/offset in stream */
54 static off_t eaddress
; /* end address */
55 static off_t savaddress
; /* saved address/offset in stream */
60 (void)printf(pr->fmt, address); \
63 (void)printf(pr->fmt, ""); \
69 (void)printf(pr->fmt, *bp); \
76 bcopy((char *)bp, (char *)&fval, sizeof(fval)); \
77 (void)printf(pr->fmt, fval); \
80 bcopy((char *)bp, (char *)&dval, sizeof(dval)); \
81 (void)printf(pr->fmt, dval); \
91 (void)printf(pr->fmt, (int)*bp); \
94 bcopy((char *)bp, (char *)&sval, sizeof(sval)); \
95 (void)printf(pr->fmt, (int)sval); \
98 bcopy((char *)bp, (char *)&ival, sizeof(ival)); \
99 (void)printf(pr->fmt, ival); \
105 (void)printf(pr->fmt, isprint(*bp) ? *bp : '.'); \
108 (void)printf(pr->fmt, (char *)bp); \
111 (void)printf(pr->fmt); \
121 (void)printf(pr->fmt, (u_int)*bp); \
124 bcopy((char *)bp, (char *)&sval, sizeof(sval)); \
125 (void)printf(pr->fmt, (u_int)sval); \
128 bcopy((char *)bp, (char *)&ival, sizeof(ival)); \
129 (void)printf(pr->fmt, ival); \
137 static void bpad(PR
*pr
)
139 static char *spec
= " -0+#";
140 register char *p1
, *p2
;
143 * remove all conversion flags; '-' is the only one valid
144 * with %s, and it's not useful here.
148 for (p1
= pr
->fmt
; *p1
!= '%'; ++p1
);
149 for (p2
= ++p1
; *p1
&& index(spec
, *p1
); ++p1
);
150 while ((*p2
++ = *p1
++) != 0) ;
162 u_char savech
= 0, *savebp
;
164 while ((bp
= get()) != NULL
)
165 for (fs
= fshead
, savebp
= bp
, saveaddress
= address
; fs
;
166 fs
= fs
->nextfs
, bp
= savebp
, address
= saveaddress
)
167 for (fu
= fs
->nextfu
; fu
; fu
= fu
->nextfu
) {
168 if (fu
->flags
&F_IGNORE
)
170 for (cnt
= fu
->reps
; cnt
; --cnt
)
171 for (pr
= fu
->nextpr
; pr
; address
+= pr
->bcnt
,
172 bp
+= pr
->bcnt
, pr
= pr
->nextpr
) {
173 if (eaddress
&& address
>= eaddress
&&
174 !(pr
->flags
&(F_TEXT
|F_BPAD
)))
176 if (cnt
== 1 && pr
->nospace
) {
177 savech
= *pr
->nospace
;
181 if (cnt
== 1 && pr
->nospace
)
182 *pr
->nospace
= savech
;
187 * if eaddress not set, error or file size was multiple of
188 * blocksize, and no partial block ever found.
195 for (pr
= endfu
->nextpr
; pr
; pr
= pr
->nextpr
)
198 (void)printf(pr
->fmt
, eaddress
);
201 (void)printf(pr
->fmt
);
213 static int ateof
= 1;
214 static u_char
*curp
, *savp
;
220 curp
= (u_char
*)emalloc(blocksize
);
221 savp
= (u_char
*)emalloc(blocksize
);
226 address
= savaddress
+= blocksize
;
228 for (need
= blocksize
, nread
= 0;;) {
230 * if read the right number of bytes, or at EOF for one file,
231 * and no other files are available, zero-pad the rest of the
232 * block and set the end flag.
234 if (!length
|| (ateof
&& !next((char **)NULL
))) {
235 if (need
== blocksize
)
236 return((u_char
*)NULL
);
237 if (vflag
!= ALL
&& !bcmp(curp
, savp
, nread
)) {
240 return((u_char
*)NULL
);
242 bzero((char *)curp
+ nread
, need
);
243 eaddress
= address
+ nread
;
246 n
= fread((char *)curp
+ nread
, sizeof(u_char
),
247 length
== -1 ? need
: MIN(length
, need
), stdin
);
250 (void)fprintf(stderr
, "hexdump: %s: %s\n",
251 _argv
[-1], strerror(errno
));
259 if (vflag
== ALL
|| vflag
== FIRST
||
260 bcmp(curp
, savp
, blocksize
)) {
261 if (vflag
== DUP
|| vflag
== FIRST
)
268 address
= savaddress
+= blocksize
;
277 int next(char **argv
)
289 if (!(freopen(*_argv
, "r", stdin
))) {
290 (void)fprintf(stderr
, "hexdump: %s: %s\n",
291 *_argv
, strerror(errno
));
303 doskip(statok
? *_argv
: "stdin", statok
);
313 doskip(char *fname
, int statok
)
318 if (fstat(fileno(stdin
), &sbuf
)) {
319 (void)fprintf(stderr
, "hexdump: %s: %s.\n",
320 fname
, strerror(errno
));
323 if ( ( ! (S_ISCHR(sbuf
.st_mode
) ||
324 S_ISBLK(sbuf
.st_mode
) ||
325 S_ISFIFO(sbuf
.st_mode
)) ) &&
326 skip
>= sbuf
.st_size
) {
327 /* If size valid and skip >= size */
328 skip
-= sbuf
.st_size
;
329 address
+= sbuf
.st_size
;
333 if (fseek(stdin
, skip
, SEEK_SET
)) {
334 (void)fprintf(stderr
, "hexdump: %s: %s.\n",
335 fname
, strerror(errno
));
338 savaddress
= address
+= skip
;
346 if (!(p
= malloc((u_int
)sz
)))
353 (void)fprintf(stderr
, "hexdump: %s.\n", strerror(errno
));