1da2e3ebdSchin /*********************************************************************** 2da2e3ebdSchin * * 3da2e3ebdSchin * This software is part of the ast package * 4*7c2fbfb3SApril Chin * Copyright (c) 1992-2008 AT&T Intellectual Property * 5da2e3ebdSchin * and is licensed under the * 6da2e3ebdSchin * Common Public License, Version 1.0 * 7*7c2fbfb3SApril Chin * by AT&T Intellectual Property * 8da2e3ebdSchin * * 9da2e3ebdSchin * A copy of the License is available at * 10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12da2e3ebdSchin * * 13da2e3ebdSchin * Information and Software Systems Research * 14da2e3ebdSchin * AT&T Research * 15da2e3ebdSchin * Florham Park NJ * 16da2e3ebdSchin * * 17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18da2e3ebdSchin * David Korn <dgk@research.att.com> * 19da2e3ebdSchin * * 20da2e3ebdSchin ***********************************************************************/ 21da2e3ebdSchin #pragma prototyped 22da2e3ebdSchin /* 23da2e3ebdSchin * David Korn 24da2e3ebdSchin * AT&T Bell Laboratories 25da2e3ebdSchin * 26da2e3ebdSchin * output the beginning portion of one or more files 27da2e3ebdSchin */ 28da2e3ebdSchin 29da2e3ebdSchin static const char usage[] = 30*7c2fbfb3SApril Chin "[-n?\n@(#)$Id: head (AT&T Research) 2006-09-27 $\n]" 31da2e3ebdSchin USAGE_LICENSE 32da2e3ebdSchin "[+NAME?head - output beginning portion of one or more files ]" 33da2e3ebdSchin "[+DESCRIPTION?\bhead\b copies one or more input files to standard " 34da2e3ebdSchin "output stopping at a designated point for each file or to the end of " 35da2e3ebdSchin "the file whichever comes first. Copying ends at the point indicated by " 36da2e3ebdSchin "the options. By default a header of the form \b==> \b\afilename\a\b " 37da2e3ebdSchin "<==\b is output before all but the first file but this can be changed " 38da2e3ebdSchin "with the \b-q\b and \b-v\b options.]" 39da2e3ebdSchin "[+?If no \afile\a is given, or if the \afile\a is \b-\b, \bhead\b " 40da2e3ebdSchin "copies from standard input starting at the current location.]" 41da2e3ebdSchin "[+?The option argument for \b-c\b, and \b-s\b can optionally be " 42da2e3ebdSchin "followed by one of the following characters to specify a different unit " 43da2e3ebdSchin "other than a single byte:]" 44da2e3ebdSchin "{" 45da2e3ebdSchin "[+b?512 bytes.]" 46da2e3ebdSchin "[+k?1-killobyte.]" 47da2e3ebdSchin "[+m?1-megabyte.]" 48da2e3ebdSchin "}" 49da2e3ebdSchin "[+?For backwards compatibility, \b-\b\anumber\a is equivalent to \b-n\b " 50da2e3ebdSchin "\anumber\a.]" 51da2e3ebdSchin "[n:lines?Copy \alines\a lines from each file.]#[lines:=10]" 52da2e3ebdSchin "[c:bytes?Copy \achars\a bytes from each file.]#[chars]" 53da2e3ebdSchin "[q:quiet|silent?Never ouput filename headers.]" 54da2e3ebdSchin "[s:skip?Skip \askip\a characters or lines from each file before " 55da2e3ebdSchin "copying.]#[skip]" 56da2e3ebdSchin "[v:verbose?Always ouput filename headers.]" 57da2e3ebdSchin "\n\n" 58da2e3ebdSchin "[ file ... ]" 59da2e3ebdSchin "\n\n" 60da2e3ebdSchin "[+EXIT STATUS?]" 61da2e3ebdSchin "{" 62da2e3ebdSchin "[+0?All files copied successfully.]" 63da2e3ebdSchin "[+>0?One or more files did not copy.]" 64da2e3ebdSchin "}" 65da2e3ebdSchin "[+SEE ALSO?\bcat\b(1), \btail\b(1)]" 66da2e3ebdSchin ; 67da2e3ebdSchin 68da2e3ebdSchin #include <cmd.h> 69da2e3ebdSchin 70da2e3ebdSchin int 71da2e3ebdSchin b_head(int argc, register char** argv, void* context) 72da2e3ebdSchin { 73da2e3ebdSchin static const char header_fmt[] = "\n==> %s <==\n"; 74da2e3ebdSchin 75da2e3ebdSchin register Sfio_t* fp; 76da2e3ebdSchin register char* cp; 77da2e3ebdSchin register off_t keep = 10; 78da2e3ebdSchin register off_t skip = 0; 79da2e3ebdSchin register int delim = '\n'; 80da2e3ebdSchin int header = 1; 81da2e3ebdSchin char* format = (char*)header_fmt+1; 82da2e3ebdSchin 83da2e3ebdSchin cmdinit(argc, argv, context, ERROR_CATALOG, 0); 84da2e3ebdSchin for (;;) 85da2e3ebdSchin { 86da2e3ebdSchin switch (optget(argv, usage)) 87da2e3ebdSchin { 88da2e3ebdSchin case 'c': 89da2e3ebdSchin delim = -1; 90da2e3ebdSchin /*FALLTHROUGH*/ 91da2e3ebdSchin case 'n': 92da2e3ebdSchin if (opt_info.offset && argv[opt_info.index][opt_info.offset] == 'c') 93da2e3ebdSchin { 94da2e3ebdSchin delim = -1; 95da2e3ebdSchin opt_info.offset++; 96da2e3ebdSchin } 97da2e3ebdSchin if ((keep = opt_info.number) <=0) 98da2e3ebdSchin error(2, "%s: %I*d: positive numeric option argument expected", opt_info.name, sizeof(keep), keep); 99da2e3ebdSchin continue; 100da2e3ebdSchin case 'q': 101da2e3ebdSchin header = argc; 102da2e3ebdSchin continue; 103da2e3ebdSchin case 'v': 104da2e3ebdSchin header = 0; 105da2e3ebdSchin continue; 106da2e3ebdSchin case 's': 107da2e3ebdSchin skip = opt_info.number; 108da2e3ebdSchin continue; 109da2e3ebdSchin case '?': 110da2e3ebdSchin error(ERROR_usage(2), "%s", opt_info.arg); 111da2e3ebdSchin continue; 112da2e3ebdSchin case ':': 113da2e3ebdSchin error(2, "%s", opt_info.arg); 114da2e3ebdSchin continue; 115da2e3ebdSchin } 116da2e3ebdSchin break; 117da2e3ebdSchin } 118da2e3ebdSchin argv += opt_info.index; 119da2e3ebdSchin argc -= opt_info.index; 120da2e3ebdSchin if (error_info.errors) 121da2e3ebdSchin error(ERROR_usage(2), "%s", optusage(NiL)); 122da2e3ebdSchin if (cp = *argv) 123da2e3ebdSchin argv++; 124da2e3ebdSchin do 125da2e3ebdSchin { 126da2e3ebdSchin if (!cp || streq(cp, "-")) 127da2e3ebdSchin { 128da2e3ebdSchin cp = "/dev/stdin"; 129da2e3ebdSchin fp = sfstdin; 130da2e3ebdSchin sfset(fp, SF_SHARE, 1); 131da2e3ebdSchin } 132da2e3ebdSchin else if (!(fp = sfopen(NiL, cp, "r"))) 133da2e3ebdSchin { 134da2e3ebdSchin error(ERROR_system(0), "%s: cannot open", cp); 135da2e3ebdSchin continue; 136da2e3ebdSchin } 137da2e3ebdSchin if (argc > header) 138da2e3ebdSchin sfprintf(sfstdout, format, cp); 139da2e3ebdSchin format = (char*)header_fmt; 140da2e3ebdSchin if (skip > 0) 141da2e3ebdSchin sfmove(fp, NiL, skip, delim); 142da2e3ebdSchin if (sfmove(fp, sfstdout, keep, delim) < 0 && errno != EPIPE) 143da2e3ebdSchin error(ERROR_system(0), "%s: read error", cp); 144da2e3ebdSchin if (fp != sfstdin) 145da2e3ebdSchin sfclose(fp); 146da2e3ebdSchin } while (cp = *argv++); 147da2e3ebdSchin if (sfsync(sfstdout)) 148da2e3ebdSchin error(ERROR_system(0), "write error"); 149da2e3ebdSchin return error_info.errors != 0; 150da2e3ebdSchin } 151