]>
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>
47 static void doskip(const char *, int);
48 static u_char
*get(void);
50 enum _vflag vflag
= FIRST
;
52 static off_t address
; /* address/offset in stream */
53 static off_t eaddress
; /* end address */
56 print(PR
*pr
, unsigned char *bp
) {
60 (void)printf(pr
->fmt
, (int64_t)address
);
63 (void)printf(pr
->fmt
, "");
69 (void)printf(pr
->fmt
, *bp
);
77 memmove(&fval
, bp
, sizeof(fval
));
78 (void)printf(pr
->fmt
, fval
);
81 memmove(&dval
, bp
, sizeof(dval
));
82 (void)printf(pr
->fmt
, dval
);
89 short sval
; /* int16_t */
90 int ival
; /* int32_t */
91 long long Lval
; /* int64_t, int64_t */
95 (void)printf(pr
->fmt
, (int64_t)*bp
);
98 memmove(&sval
, bp
, sizeof(sval
));
99 (void)printf(pr
->fmt
, (int64_t)sval
);
102 memmove(&ival
, bp
, sizeof(ival
));
103 (void)printf(pr
->fmt
, (int64_t)ival
);
106 memmove(&Lval
, bp
, sizeof(Lval
));
107 (void)printf(pr
->fmt
, (int64_t)Lval
);
113 (void)printf(pr
->fmt
, isprint(*bp
) ? *bp
: '.');
116 (void)printf(pr
->fmt
, (char *)bp
);
119 (void)printf("%s", pr
->fmt
);
126 unsigned short sval
; /* u_int16_t */
127 unsigned int ival
; /* u_int32_t */
128 unsigned long long Lval
;/* u_int64_t, u_int64_t */
132 (void)printf(pr
->fmt
, (uint64_t)*bp
);
135 memmove(&sval
, bp
, sizeof(sval
));
136 (void)printf(pr
->fmt
, (uint64_t)sval
);
139 memmove(&ival
, bp
, sizeof(ival
));
140 (void)printf(pr
->fmt
, (uint64_t)ival
);
143 memmove(&Lval
, bp
, sizeof(Lval
));
144 (void)printf(pr
->fmt
, (uint64_t)Lval
);
152 static void bpad(PR
*pr
)
154 static const char *spec
= " -0+#";
158 * remove all conversion flags; '-' is the only one valid
159 * with %s, and it's not useful here.
164 for (p1
= pr
->fmt
; *p1
!= '%'; ++p1
);
165 for (p2
= ++p1
; *p1
&& strchr(spec
, *p1
); ++p1
);
166 while ((*p2
++ = *p1
++) != 0) ;
175 register unsigned char *bp
;
177 unsigned char savech
= 0, *savebp
;
179 while ((bp
= get()) != NULL
)
180 for (fs
= fshead
, savebp
= bp
, saveaddress
= address
; fs
;
181 fs
= fs
->nextfs
, bp
= savebp
, address
= saveaddress
)
182 for (fu
= fs
->nextfu
; fu
; fu
= fu
->nextfu
) {
183 if (fu
->flags
&F_IGNORE
)
185 for (cnt
= fu
->reps
; cnt
; --cnt
)
186 for (pr
= fu
->nextpr
; pr
; address
+= pr
->bcnt
,
187 bp
+= pr
->bcnt
, pr
= pr
->nextpr
) {
188 if (eaddress
&& address
>= eaddress
&&
189 !(pr
->flags
&(F_TEXT
|F_BPAD
)))
191 if (cnt
== 1 && pr
->nospace
) {
192 savech
= *pr
->nospace
;
196 if (cnt
== 1 && pr
->nospace
)
197 *pr
->nospace
= savech
;
202 * if eaddress not set, error or file size was multiple of
203 * blocksize, and no partial block ever found.
210 for (pr
= endfu
->nextpr
; pr
; pr
= pr
->nextpr
)
213 (void)printf(pr
->fmt
, (int64_t)eaddress
);
216 (void)printf("%s", pr
->fmt
);
227 static int ateof
= 1;
228 static u_char
*curp
, *savp
;
229 ssize_t n
, need
, nread
;
233 curp
= xcalloc(1, blocksize
);
234 savp
= xcalloc(1, blocksize
);
239 address
+= blocksize
;
241 for (need
= blocksize
, nread
= 0;;) {
243 * if read the right number of bytes, or at EOF for one file,
244 * and no other files are available, zero-pad the rest of the
245 * block and set the end flag.
247 if (!length
|| (ateof
&& !next(NULL
))) {
248 if (need
== blocksize
)
250 if (!need
&& vflag
!= ALL
&&
251 !memcmp(curp
, savp
, nread
)) {
257 memset((char *)curp
+ nread
, 0, need
);
258 eaddress
= address
+ nread
;
261 if (fileno(stdin
) == -1) {
262 warnx(_("all input file arguments failed"));
265 n
= fread((char *)curp
+ nread
, sizeof(unsigned char),
266 length
== -1 ? need
: min(length
, need
), stdin
);
269 warn("%s", _argv
[-1]);
277 if (vflag
== ALL
|| vflag
== FIRST
||
278 memcmp(curp
, savp
, blocksize
)) {
279 if (vflag
== DUP
|| vflag
== FIRST
)
286 address
+= blocksize
;
295 int next(char **argv
)
306 if (!(freopen(*_argv
, "r", stdin
))) {
308 exitval
= EXIT_FAILURE
;
319 doskip(statok
? *_argv
: "stdin", statok
);
329 doskip(const char *fname
, int statok
)
334 if (fstat(fileno(stdin
), &sbuf
))
335 err(EXIT_FAILURE
, "%s", fname
);
336 if (S_ISREG(sbuf
.st_mode
) && skip
> sbuf
.st_size
) {
337 /* If size valid and skip >= size */
338 skip
-= sbuf
.st_size
;
339 address
+= sbuf
.st_size
;
343 /* sbuf may be undefined here - do not test it */
344 if (fseek(stdin
, skip
, SEEK_SET
))
345 err(EXIT_FAILURE
, "%s", fname
);