da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1992-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Bell Laboratories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * output the beginning portion of one or more files
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char usage[] =
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin"[-n?\n@(#)$Id: head (AT&T Research) 2006-09-27 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUSAGE_LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?head - output beginning portion of one or more files ]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+DESCRIPTION?\bhead\b copies one or more input files to standard "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "output stopping at a designated point for each file or to the end of "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the file whichever comes first. Copying ends at the point indicated by "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the options. By default a header of the form \b==> \b\afilename\a\b "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "<==\b is output before all but the first file but this can be changed "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "with the \b-q\b and \b-v\b options.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?If no \afile\a is given, or if the \afile\a is \b-\b, \bhead\b "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "copies from standard input starting at the current location.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?The option argument for \b-c\b, and \b-s\b can optionally be "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "followed by one of the following characters to specify a different unit "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "other than a single byte:]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+b?512 bytes.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+k?1-killobyte.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+m?1-megabyte.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?For backwards compatibility, \b-\b\anumber\a is equivalent to \b-n\b "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\anumber\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[n:lines?Copy \alines\a lines from each file.]#[lines:=10]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[c:bytes?Copy \achars\a bytes from each file.]#[chars]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[q:quiet|silent?Never ouput filename headers.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[s:skip?Skip \askip\a characters or lines from each file before "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "copying.]#[skip]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[v:verbose?Always ouput filename headers.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\n\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[ file ... ]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\n\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+EXIT STATUS?]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+0?All files copied successfully.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+>0?One or more files did not copy.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bcat\b(1), \btail\b(1)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <cmd.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinb_head(int argc, register char** argv, void* context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static const char header_fmt[] = "\n==> %s <==\n";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t* fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register off_t keep = 10;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register off_t skip = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int delim = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int header = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* format = (char*)header_fmt+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (optget(argv, usage))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin delim = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (opt_info.offset && argv[opt_info.index][opt_info.offset] == 'c')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin delim = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.offset++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((keep = opt_info.number) <=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %I*d: positive numeric option argument expected", opt_info.name, sizeof(keep), keep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin header = argc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin header = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip = opt_info.number;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc -= opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_info.errors)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", optusage(NiL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp = *argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cp || streq(cp, "-"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "/dev/stdin";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = sfstdin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(fp, SF_SHARE, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(fp = sfopen(NiL, cp, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: cannot open", cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (argc > header)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout, format, cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = (char*)header_fmt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (skip > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfmove(fp, NiL, skip, delim);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfmove(fp, sfstdout, keep, delim) < 0 && errno != EPIPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: read error", cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp != sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (cp = *argv++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfsync(sfstdout))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "write error");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return error_info.errors != 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}