Contents of /trunk/mkinitrd-magellan/klibc/usr/utils/cat.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 7041 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 7041 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | /* $NetBSD: cat.c,v 1.43 2004/01/04 03:31:28 jschauma Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 1989, 1993 |
5 | * The Regents of the University of California. All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to Berkeley by |
8 | * Kevin Fall. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * 3. Neither the name of the University nor the names of its contributors |
19 | * may be used to endorse or promote products derived from this software |
20 | * without specific prior written permission. |
21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 | * SUCH DAMAGE. |
33 | */ |
34 | |
35 | #ifndef __COPYRIGHT |
36 | #define __COPYRIGHT(arg) |
37 | #endif |
38 | #ifndef __RCSID |
39 | #define __RCSID(arg) |
40 | #endif |
41 | |
42 | #if HAVE_NBTOOL_CONFIG_H |
43 | #include "nbtool_config.h" |
44 | #endif |
45 | |
46 | #ifndef __KLIBC__ |
47 | #include <sys/cdefs.h> |
48 | #endif |
49 | #if !defined(lint) |
50 | __COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\ |
51 | The Regents of the University of California. All rights reserved.\n"); |
52 | #if 0 |
53 | static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95"; |
54 | #else |
55 | __RCSID("$NetBSD: cat.c,v 1.43 2004/01/04 03:31:28 jschauma Exp $"); |
56 | #endif |
57 | #endif /* not lint */ |
58 | |
59 | #include <sys/param.h> |
60 | #include <sys/stat.h> |
61 | |
62 | #include <ctype.h> |
63 | #ifndef __KLIBC__ |
64 | #include <err.h> |
65 | #endif |
66 | #include <errno.h> |
67 | #include <fcntl.h> |
68 | #ifndef __KLIBC__ |
69 | #include <locale.h> |
70 | #endif |
71 | #include <stdio.h> |
72 | #include <stdlib.h> |
73 | #include <string.h> |
74 | #include <unistd.h> |
75 | |
76 | int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag; |
77 | int rval; |
78 | const char *filename; |
79 | |
80 | int main(int, char *[]); |
81 | void cook_args(char *argv[]); |
82 | void cook_buf(FILE *); |
83 | void raw_args(char *argv[]); |
84 | void raw_cat(int); |
85 | |
86 | int main(int argc, char *argv[]) |
87 | { |
88 | int ch; |
89 | struct flock stdout_lock; |
90 | |
91 | #ifndef __KLIBC__ |
92 | setprogname(argv[0]); |
93 | (void)setlocale(LC_ALL, ""); |
94 | #endif |
95 | |
96 | while ((ch = getopt(argc, argv, "beflnstuv")) != -1) |
97 | switch (ch) { |
98 | case 'b': |
99 | bflag = nflag = 1; /* -b implies -n */ |
100 | break; |
101 | case 'e': |
102 | eflag = vflag = 1; /* -e implies -v */ |
103 | break; |
104 | case 'f': |
105 | fflag = 1; |
106 | break; |
107 | case 'l': |
108 | lflag = 1; |
109 | break; |
110 | case 'n': |
111 | nflag = 1; |
112 | break; |
113 | case 's': |
114 | sflag = 1; |
115 | break; |
116 | case 't': |
117 | tflag = vflag = 1; /* -t implies -v */ |
118 | break; |
119 | case 'u': |
120 | #ifndef __KLIBC__ |
121 | setbuf(stdout, NULL); |
122 | #endif |
123 | break; |
124 | case 'v': |
125 | vflag = 1; |
126 | break; |
127 | default: |
128 | case '?': |
129 | (void)fprintf(stderr, |
130 | "usage: cat [-beflnstuv] [-] [file ...]\n"); |
131 | exit(1); |
132 | /* NOTREACHED */ |
133 | } |
134 | argv += optind; |
135 | |
136 | if (lflag) { |
137 | stdout_lock.l_len = 0; |
138 | stdout_lock.l_start = 0; |
139 | stdout_lock.l_type = F_WRLCK; |
140 | stdout_lock.l_whence = SEEK_SET; |
141 | if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1) { |
142 | perror("fcntl"); |
143 | exit(1); |
144 | } |
145 | } |
146 | |
147 | if (bflag || eflag || nflag || sflag || tflag || vflag) |
148 | cook_args(argv); |
149 | else |
150 | raw_args(argv); |
151 | if (fclose(stdout)) { |
152 | perror("fclose"); |
153 | exit(1); |
154 | } |
155 | exit(rval); |
156 | /* NOTREACHED */ |
157 | } |
158 | |
159 | void cook_args(char **argv) |
160 | { |
161 | FILE *fp; |
162 | |
163 | fp = stdin; |
164 | filename = "stdin"; |
165 | do { |
166 | if (*argv) { |
167 | if (!strcmp(*argv, "-")) |
168 | fp = stdin; |
169 | else if ((fp = fopen(*argv, |
170 | fflag ? "rf" : "r")) == NULL) { |
171 | perror("fopen"); |
172 | rval = 1; |
173 | ++argv; |
174 | continue; |
175 | } |
176 | filename = *argv++; |
177 | } |
178 | cook_buf(fp); |
179 | if (fp != stdin) |
180 | (void)fclose(fp); |
181 | } while (*argv); |
182 | } |
183 | |
184 | void cook_buf(FILE * fp) |
185 | { |
186 | int ch, gobble, line, prev; |
187 | int stdout_err = 0; |
188 | |
189 | line = gobble = 0; |
190 | for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { |
191 | if (prev == '\n') { |
192 | if (ch == '\n') { |
193 | if (sflag) { |
194 | if (!gobble && putchar(ch) == EOF) |
195 | break; |
196 | gobble = 1; |
197 | continue; |
198 | } |
199 | if (nflag) { |
200 | if (!bflag) { |
201 | if (fprintf(stdout, |
202 | "%6d\t", |
203 | ++line) < 0) { |
204 | stdout_err++; |
205 | break; |
206 | } |
207 | } else if (eflag) { |
208 | if (fprintf(stdout, |
209 | "%6s\t", "") < 0) { |
210 | stdout_err++; |
211 | break; |
212 | } |
213 | } |
214 | } |
215 | } else if (nflag) { |
216 | if (fprintf(stdout, "%6d\t", ++line) < 0) { |
217 | stdout_err++; |
218 | break; |
219 | } |
220 | } |
221 | } |
222 | gobble = 0; |
223 | if (ch == '\n') { |
224 | if (eflag) |
225 | if (putchar('$') == EOF) |
226 | break; |
227 | } else if (ch == '\t') { |
228 | if (tflag) { |
229 | if (putchar('^') == EOF || putchar('I') == EOF) |
230 | break; |
231 | continue; |
232 | } |
233 | } else if (vflag) { |
234 | if (!isascii(ch)) { |
235 | if (putchar('M') == EOF || putchar('-') == EOF) |
236 | break; |
237 | ch = (ch) & 0x7f; |
238 | } |
239 | if (iscntrl(ch)) { |
240 | if (putchar('^') == EOF || |
241 | putchar(ch == '\177' ? '?' : |
242 | ch | 0100) == EOF) |
243 | break; |
244 | continue; |
245 | } |
246 | } |
247 | if (putchar(ch) == EOF) |
248 | break; |
249 | } |
250 | if (stdout_err) { |
251 | perror(filename); |
252 | rval = 1; |
253 | } |
254 | } |
255 | |
256 | void raw_args(char **argv) |
257 | { |
258 | int fd; |
259 | |
260 | fd = fileno(stdin); |
261 | filename = "stdin"; |
262 | do { |
263 | if (*argv) { |
264 | if (!strcmp(*argv, "-")) |
265 | fd = fileno(stdin); |
266 | else if (fflag) { |
267 | struct stat st; |
268 | fd = open(*argv, O_RDONLY | O_NONBLOCK, 0); |
269 | if (fd < 0) |
270 | goto skip; |
271 | |
272 | if (fstat(fd, &st) == -1) { |
273 | close(fd); |
274 | goto skip; |
275 | } |
276 | if (!S_ISREG(st.st_mode)) { |
277 | close(fd); |
278 | errno = EINVAL; |
279 | goto skipnomsg; |
280 | } |
281 | } else if ((fd = open(*argv, O_RDONLY, 0)) < 0) { |
282 | skip: |
283 | perror(*argv); |
284 | skipnomsg: |
285 | rval = 1; |
286 | ++argv; |
287 | continue; |
288 | } |
289 | filename = *argv++; |
290 | } |
291 | raw_cat(fd); |
292 | if (fd != fileno(stdin)) |
293 | (void)close(fd); |
294 | } while (*argv); |
295 | } |
296 | |
297 | void raw_cat(int rfd) |
298 | { |
299 | static char *buf; |
300 | static char fb_buf[BUFSIZ]; |
301 | static size_t bsize; |
302 | |
303 | struct stat sbuf; |
304 | ssize_t nr, nw, off; |
305 | int wfd; |
306 | |
307 | wfd = fileno(stdout); |
308 | if (buf == NULL) { |
309 | if (fstat(wfd, &sbuf) == 0) { |
310 | bsize = sbuf.st_blksize > BUFSIZ ? |
311 | sbuf.st_blksize : BUFSIZ; |
312 | buf = malloc(bsize); |
313 | } |
314 | if (buf == NULL) { |
315 | buf = fb_buf; |
316 | bsize = BUFSIZ; |
317 | } |
318 | } |
319 | while ((nr = read(rfd, buf, bsize)) > 0) |
320 | for (off = 0; nr; nr -= nw, off += nw) |
321 | if ((nw = write(wfd, buf + off, (size_t) nr)) < 0) { |
322 | perror("write"); |
323 | exit(1); |
324 | } |
325 | if (nr < 0) { |
326 | fprintf(stderr, "%s: invalid length\n", filename); |
327 | rval = 1; |
328 | } |
329 | } |