1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <unistd.h> 46 #include <locale.h> 47 #include <string.h> 48 #include <ctype.h> 49 50 #define DEF_LINE_COUNT 10 51 52 static void copyout(off_t); 53 static void Usage(); 54 55 56 /* 57 * head - give the first few lines of a stream or of each of a set of files 58 * 59 */ 60 int 61 main(int argc, char **argv) 62 { 63 int fileCount; 64 int around = 0; 65 int i; 66 int opt; 67 off_t linecnt = DEF_LINE_COUNT; 68 int error = 0; 69 70 (void) setlocale(LC_ALL, ""); 71 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 72 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 73 #endif 74 (void) textdomain(TEXT_DOMAIN); 75 76 /* check for non-standard "-line-count" option */ 77 for (i = 1; i < argc; i++) { 78 if (strcmp(argv[i], "--") == 0) 79 break; 80 81 if ((argv[i][0] == '-') && isdigit(argv[i][1])) { 82 if (strlen(&argv[i][1]) != 83 strspn(&argv[i][1], "0123456789")) { 84 (void) fprintf(stderr, gettext( 85 "%s: Badly formed number\n"), argv[0]); 86 Usage(); 87 } 88 89 linecnt = (off_t) strtoll(&argv[i][1], (char **)NULL, 90 10); 91 while (i < argc) { 92 argv[i] = argv[i + 1]; 93 i++; 94 } 95 argc--; 96 } 97 } 98 99 /* get options */ 100 while ((opt = getopt(argc, argv, "n:")) != EOF) { 101 switch (opt) { 102 case 'n': 103 if ((strcmp(optarg, "--") == 0) || (optind > argc)) { 104 (void) fprintf(stderr, gettext( 105 "%s: Missing -n argument\n"), argv[0]), 106 Usage(); 107 } 108 linecnt = (off_t) strtoll(optarg, (char **)NULL, 10); 109 if (linecnt <= 0) { 110 (void) fprintf(stderr, gettext( 111 "%s: Invalid \"-n %s\" option\n"), 112 argv[0], optarg); 113 Usage(); 114 } 115 break; 116 117 default: 118 Usage(); 119 } 120 } 121 122 fileCount = argc - optind; 123 124 do { 125 if ((argv[optind] == NULL) && around) 126 break; 127 128 if (argv[optind] != NULL) { 129 (void) close(0); 130 if (freopen(argv[optind], "r", stdin) == NULL) { 131 perror(argv[optind]); 132 error = 1; 133 optind++; 134 continue; 135 } 136 } 137 138 if (around) 139 (void) putchar('\n'); 140 141 if (fileCount > 1) 142 (void) printf("==> %s <==\n", argv[optind]); 143 144 if (argv[optind] != NULL) 145 optind++; 146 147 copyout(linecnt); 148 (void) fflush(stdout); 149 around++; 150 151 } while (argv[optind] != NULL); 152 153 return (error); 154 } 155 156 static void 157 copyout(cnt) 158 register off_t cnt; 159 { 160 char lbuf[BUFSIZ]; 161 size_t len; 162 163 while (cnt > 0 && fgets(lbuf, sizeof (lbuf), stdin) != 0) { 164 (void) printf("%s", lbuf); 165 /* only count as a line if buffer read ends with newline */ 166 if ((len = strlen(lbuf)) > 0) { 167 if (lbuf[len - 1] == '\n') { 168 (void) fflush(stdout); 169 cnt--; 170 } 171 } 172 } 173 } 174 175 static void 176 Usage() 177 { 178 (void) printf(gettext("usage: head [-n #] [-#] [filename...]\n")); 179 exit(1); 180 } 181