head.c revision 93441
159191Skris/* 259191Skris * Copyright (c) 1980, 1987, 1992, 1993 359191Skris * The Regents of the University of California. All rights reserved. 459191Skris * 559191Skris * Redistribution and use in source and binary forms, with or without 659191Skris * modification, are permitted provided that the following conditions 759191Skris * are met: 859191Skris * 1. Redistributions of source code must retain the above copyright 959191Skris * notice, this list of conditions and the following disclaimer. 1059191Skris * 2. Redistributions in binary form must reproduce the above copyright 1159191Skris * notice, this list of conditions and the following disclaimer in the 1259191Skris * documentation and/or other materials provided with the distribution. 1359191Skris * 3. All advertising materials mentioning features or use of this software 1459191Skris * must display the following acknowledgement: 1559191Skris * This product includes software developed by the University of 1659191Skris * California, Berkeley and its contributors. 1759191Skris * 4. Neither the name of the University nor the names of its contributors 1859191Skris * may be used to endorse or promote products derived from this software 1959191Skris * without specific prior written permission. 2059191Skris * 2159191Skris * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259191Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359191Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459191Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559191Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659191Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759191Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859191Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959191Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059191Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159191Skris * SUCH DAMAGE. 3259191Skris */ 3359191Skris 3459191Skris#ifndef lint 3559191Skrisstatic const char copyright[] = 3659191Skris"@(#) Copyright (c) 1980, 1987, 1992, 1993\n\ 3759191Skris The Regents of the University of California. All rights reserved.\n"; 3859191Skris#endif /* not lint */ 3959191Skris 4059191Skris#ifndef lint 4159191Skris#if 0 4259191Skrisstatic char sccsid[] = "@(#)head.c 8.2 (Berkeley) 5/4/95"; 4359191Skris#endif 4459191Skrisstatic const char rcsid[] = 4559191Skris "$FreeBSD: head/usr.bin/head/head.c 93441 2002-03-30 17:17:26Z dwmalone $"; 4659191Skris#endif /* not lint */ 4759191Skris 4859191Skris#include <sys/types.h> 4959191Skris 5059191Skris#include <ctype.h> 5159191Skris#include <err.h> 5259191Skris#include <stdio.h> 5359191Skris#include <stdlib.h> 5459191Skris#include <string.h> 5559191Skris#include <unistd.h> 5659191Skris 5759191Skris/* 5859191Skris * head - give the first few lines of a stream or of each of a set of files 5959191Skris * 6059191Skris * Bill Joy UCB August 24, 1977 6159191Skris */ 6259191Skris 6359191Skrisstatic void head(FILE *, int); 6459191Skrisstatic void head_bytes(FILE *, size_t); 6559191Skrisstatic void obsolete(char *[]); 6659191Skrisstatic void usage(void); 67100936Snectar 68109998Smarkmint 6959191Skrismain(argc, argv) 70142425Snectar int argc; 71142425Snectar char *argv[]; 7259191Skris{ 7359191Skris int ch; 74205128Ssimon FILE *fp; 75205128Ssimon int first, linecnt = -1, bytecnt = -1, eval = 0; 7659191Skris char *ep; 7759191Skris 7859191Skris obsolete(argv); 7959191Skris while ((ch = getopt(argc, argv, "n:c:")) != -1) 8059191Skris switch(ch) { 8159191Skris case 'c': 8259191Skris bytecnt = strtol(optarg, &ep, 10); 8359191Skris if (*ep || bytecnt <= 0) 8459191Skris errx(1, "illegal byte count -- %s", optarg); 8559191Skris break; 8659191Skris case 'n': 8759191Skris linecnt = strtol(optarg, &ep, 10); 8859191Skris if (*ep || linecnt <= 0) 8959191Skris errx(1, "illegal line count -- %s", optarg); 9059191Skris break; 9159191Skris case '?': 9259191Skris default: 9359191Skris usage(); 9459191Skris } 9559191Skris argc -= optind; 9659191Skris argv += optind; 9759191Skris 98109998Smarkm if (linecnt != -1 && bytecnt != -1) 9959191Skris errx(1, "can't combine line and byte counts"); 10059191Skris if (linecnt == -1 ) 101238405Sjkim linecnt = 10; 102238405Sjkim if (*argv) { 10359191Skris for (first = 1; *argv; ++argv) { 104238405Sjkim if ((fp = fopen(*argv, "r")) == NULL) { 10559191Skris warn("%s", *argv); 106109998Smarkm eval = 1; 10759191Skris continue; 10859191Skris } 10959191Skris if (argc > 1) { 11059191Skris (void)printf("%s==> %s <==\n", 11159191Skris first ? "" : "\n", *argv); 11259191Skris first = 0; 11359191Skris } 11459191Skris if (bytecnt == -1) 115194206Ssimon head(fp, linecnt); 116194206Ssimon else 117194206Ssimon head_bytes(fp, bytecnt); 118194206Ssimon (void)fclose(fp); 119194206Ssimon } 120194206Ssimon } else if (bytecnt == -1) 121194206Ssimon head(stdin, linecnt); 122194206Ssimon else 123194206Ssimon head_bytes(stdin, bytecnt); 124109998Smarkm 12559191Skris exit(eval); 12659191Skris} 12759191Skris 12859191Skrisstatic void 12959191Skrishead(fp, cnt) 13059191Skris FILE *fp; 13159191Skris int cnt; 13259191Skris{ 13359191Skris char *cp; 13459191Skris size_t error, readlen; 135109998Smarkm 13659191Skris while (cnt && (cp = fgetln(fp, &readlen)) != NULL) { 13759191Skris error = fwrite(cp, sizeof(char), readlen, stdout); 13859191Skris if (error != readlen) 13959191Skris err(1, "stdout"); 14059191Skris cnt--; 14159191Skris } 14259191Skris} 14359191Skris 14459191Skrisstatic void 145109998Smarkmhead_bytes(fp, cnt) 14659191Skris FILE *fp; 14759191Skris size_t cnt; 14859191Skris{ 14959191Skris char buf[4096]; 15059191Skris size_t readlen; 15159191Skris 15259191Skris while (cnt) { 15359191Skris if (cnt < sizeof(buf)) 15459191Skris readlen = cnt; 15559191Skris else 156109998Smarkm readlen = sizeof(buf); 15759191Skris readlen = fread(buf, sizeof(char), readlen, fp); 15859191Skris if (readlen == 0) 15959191Skris break; 16059191Skris if (fwrite(buf, sizeof(char), readlen, stdout) != readlen) 16159191Skris err(1, "stdout"); 16259191Skris cnt -= readlen; 16359191Skris } 164109998Smarkm} 165109998Smarkm 166109998Smarkmstatic void 167109998Smarkmobsolete(argv) 168109998Smarkm char *argv[]; 169142425Snectar{ 170142425Snectar char *ap; 171109998Smarkm 172109998Smarkm while ((ap = *++argv)) { 173238405Sjkim /* Return if "--" or not "-[0-9]*". */ 174238405Sjkim if (ap[0] != '-' || ap[1] == '-' || !isdigit(ap[1])) 175109998Smarkm return; 176109998Smarkm if ((ap = malloc(strlen(*argv) + 2)) == NULL) 177109998Smarkm err(1, NULL); 178109998Smarkm ap[0] = '-'; 179109998Smarkm ap[1] = 'n'; 180142425Snectar (void)strcpy(ap + 2, *argv + 1); 181142425Snectar *argv = ap; 182109998Smarkm } 183109998Smarkm} 184238405Sjkim 185109998Smarkmstatic void 186109998Smarkmusage() 187109998Smarkm{ 188109998Smarkm 189109998Smarkm (void)fprintf(stderr, "usage: head [-n lines | -c bytes] [file ...]\n"); 190142425Snectar exit(1); 191142425Snectar} 192109998Smarkm