head.c revision 27314
1219820Sjeff/*
2219820Sjeff * Copyright (c) 1980, 1987, 1992, 1993
3219820Sjeff *	The Regents of the University of California.  All rights reserved.
4219820Sjeff *
5219820Sjeff * Redistribution and use in source and binary forms, with or without
6219820Sjeff * modification, are permitted provided that the following conditions
7219820Sjeff * are met:
8219820Sjeff * 1. Redistributions of source code must retain the above copyright
9219820Sjeff *    notice, this list of conditions and the following disclaimer.
10219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
11219820Sjeff *    notice, this list of conditions and the following disclaimer in the
12219820Sjeff *    documentation and/or other materials provided with the distribution.
13219820Sjeff * 3. All advertising materials mentioning features or use of this software
14219820Sjeff *    must display the following acknowledgement:
15219820Sjeff *	This product includes software developed by the University of
16219820Sjeff *	California, Berkeley and its contributors.
17219820Sjeff * 4. Neither the name of the University nor the names of its contributors
18219820Sjeff *    may be used to endorse or promote products derived from this software
19219820Sjeff *    without specific prior written permission.
20219820Sjeff *
21219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24219820Sjeff * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31219820Sjeff * SUCH DAMAGE.
32219820Sjeff */
33219820Sjeff
34219820Sjeff#ifndef lint
35219820Sjeffstatic const char copyright[] =
36219820Sjeff"@(#) Copyright (c) 1980, 1987, 1992, 1993\n\
37219820Sjeff	The Regents of the University of California.  All rights reserved.\n";
38219820Sjeff#endif /* not lint */
39219820Sjeff
40219820Sjeff#ifndef lint
41219820Sjeff#if 0
42219820Sjeffstatic char sccsid[] = "@(#)head.c	8.2 (Berkeley) 5/4/95";
43219820Sjeff#endif
44219820Sjeffstatic const char rcsid[] =
45219820Sjeff	"$Id$";
46219820Sjeff#endif /* not lint */
47219820Sjeff
48219820Sjeff#include <sys/types.h>
49219820Sjeff
50219820Sjeff#include <ctype.h>
51219820Sjeff#include <err.h>
52219820Sjeff#include <stdio.h>
53219820Sjeff#include <stdlib.h>
54219820Sjeff#include <string.h>
55219820Sjeff#include <unistd.h>
56219820Sjeff
57219820Sjeff/*
58219820Sjeff * head - give the first few lines of a stream or of each of a set of files
59219820Sjeff *
60219820Sjeff * Bill Joy UCB August 24, 1977
61219820Sjeff */
62219820Sjeff
63219820Sjeffvoid head __P((FILE *, int));
64219820Sjeffvoid head_bytes __P((FILE *, int));
65219820Sjeffvoid obsolete __P((char *[]));
66219820Sjeffvoid usage __P((void));
67219820Sjeff
68219820Sjeffint eval;
69219820Sjeff
70219820Sjeffint
71219820Sjeffmain(argc, argv)
72219820Sjeff	int argc;
73219820Sjeff	char *argv[];
74219820Sjeff{
75219820Sjeff	register int ch;
76219820Sjeff	FILE *fp;
77219820Sjeff	int first, linecnt = -1, bytecnt = -1;
78219820Sjeff	char *ep;
79219820Sjeff
80219820Sjeff	obsolete(argv);
81219820Sjeff	while ((ch = getopt(argc, argv, "n:c:")) != -1)
82219820Sjeff		switch(ch) {
83219820Sjeff		case 'c':
84219820Sjeff			bytecnt = strtol(optarg, &ep, 10);
85219820Sjeff			if (*ep || bytecnt <= 0)
86219820Sjeff				errx(1, "illegal byte count -- %s", optarg);
87219820Sjeff			break;
88219820Sjeff		case 'n':
89219820Sjeff			linecnt = strtol(optarg, &ep, 10);
90219820Sjeff			if (*ep || linecnt <= 0)
91219820Sjeff				errx(1, "illegal line count -- %s", optarg);
92219820Sjeff			break;
93219820Sjeff		case '?':
94219820Sjeff		default:
95219820Sjeff			usage();
96219820Sjeff		}
97219820Sjeff	argc -= optind;
98219820Sjeff	argv += optind;
99219820Sjeff
100219820Sjeff	if (linecnt != -1 && bytecnt != -1)
101219820Sjeff		errx(1, "can't combine line and byte counts");
102219820Sjeff	if (linecnt == -1 )
103219820Sjeff		linecnt = 10;
104219820Sjeff	if (*argv) {
105219820Sjeff		for (first = 1; *argv; ++argv) {
106219820Sjeff			if ((fp = fopen(*argv, "r")) == NULL) {
107219820Sjeff				warn("%s", *argv);
108219820Sjeff				continue;
109219820Sjeff			}
110			if (argc > 1) {
111				(void)printf("%s==> %s <==\n",
112				    first ? "" : "\n", *argv);
113				first = 0;
114			}
115			if (bytecnt == -1)
116				head(fp, linecnt);
117			else
118				head_bytes(fp, bytecnt);
119			(void)fclose(fp);
120		}
121	}
122	else if (bytecnt == -1)
123		head(stdin, linecnt);
124	else
125		head_bytes(stdin, bytecnt);
126
127	exit(eval);
128}
129
130void
131head(fp, cnt)
132	FILE *fp;
133	register int cnt;
134{
135	register int ch;
136
137	while (cnt && (ch = getc(fp)) != EOF) {
138			if (putchar(ch) == EOF)
139				err(1, "stdout");
140			if (ch == '\n')
141				cnt--;
142		}
143}
144
145void
146head_bytes(fp, cnt)
147	 FILE *fp;
148	 register int cnt;
149{
150	char buf[4096];
151	register int readlen;
152
153	while (cnt) {
154		if (cnt < sizeof(buf))
155			readlen = cnt;
156		else
157			readlen = sizeof(buf);
158		readlen = fread(buf, sizeof(char), readlen, fp);
159		if (readlen == EOF)
160			break;
161		if (fwrite(buf, sizeof(char), readlen, stdout) != readlen)
162			err(1, "stdout");
163		cnt -= readlen;
164	}
165}
166
167void
168obsolete(argv)
169	char *argv[];
170{
171	char *ap;
172
173	while ((ap = *++argv)) {
174		/* Return if "--" or not "-[0-9]*". */
175		if (ap[0] != '-' || ap[1] == '-' || !isdigit(ap[1]))
176			return;
177		if ((ap = malloc(strlen(*argv) + 2)) == NULL)
178			err(1, NULL);
179		ap[0] = '-';
180		ap[1] = 'n';
181		(void)strcpy(ap + 2, *argv + 1);
182		*argv = ap;
183	}
184}
185
186void
187usage()
188{
189	(void)fprintf(stderr, "usage: head [-n lines] [-c bytes] [file ...]\n");
190	exit(1);
191}
192