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