Magellan Linux

Contents of /trunk/mkinitrd-magellan/klibc/usr/utils/cat.c

Parent Directory Parent Directory | Revision Log 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)
-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 }