Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/tail/tail.c
Show All 40 Lines | |||||
"@(#) Copyright (c) 1991, 1993\n\ | "@(#) Copyright (c) 1991, 1993\n\ | ||||
The Regents of the University of California. All rights reserved.\n"; | The Regents of the University of California. All rights reserved.\n"; | ||||
#endif | #endif | ||||
#ifndef lint | #ifndef lint | ||||
static const char sccsid[] = "@(#)tail.c 8.1 (Berkeley) 6/6/93"; | static const char sccsid[] = "@(#)tail.c 8.1 (Berkeley) 6/6/93"; | ||||
#endif | #endif | ||||
#include <sys/capsicum.h> | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <capsicum_helpers.h> | |||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <getopt.h> | #include <getopt.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <libcasper.h> | |||||
#include <casper/cap_fileargs.h> | |||||
#include "extern.h" | #include "extern.h" | ||||
int Fflag, fflag, qflag, rflag, rval, no_files; | int Fflag, fflag, qflag, rflag, rval, no_files; | ||||
static file_info_t *files; | static file_info_t *files; | ||||
static void obsolete(char **); | static void obsolete(char **); | ||||
static void usage(void); | static void usage(void); | ||||
Show All 12 Lines | main(int argc, char *argv[]) | ||||
struct stat sb; | struct stat sb; | ||||
const char *fn; | const char *fn; | ||||
FILE *fp; | FILE *fp; | ||||
off_t off; | off_t off; | ||||
enum STYLE style; | enum STYLE style; | ||||
int i, ch, first; | int i, ch, first; | ||||
file_info_t *file; | file_info_t *file; | ||||
char *p; | char *p; | ||||
fileargs_t *fa; | |||||
cap_rights_t rights; | |||||
cap_rights_init(&rights, CAP_FSTAT, CAP_FCNTL, CAP_MMAP_RW); | |||||
if (caph_rights_limit(STDIN_FILENO, &rights) < 0 || | |||||
caph_limit_stderr() < 0 || caph_limit_stdout() < 0) | |||||
err(1, "can't limit stdio rights"); | |||||
/* | /* | ||||
* Tail's options are weird. First, -n10 is the same as -n-10, not | * Tail's options are weird. First, -n10 is the same as -n-10, not | ||||
* -n+10. Second, the number options are 1 based and not offsets, | * -n+10. Second, the number options are 1 based and not offsets, | ||||
* so -n+1 is the first line, and -c-1 is the last byte. Third, the | * so -n+1 is the first line, and -c-1 is the last byte. Third, the | ||||
* number options for the -r option specify the number of things that | * number options for the -r option specify the number of things that | ||||
* get displayed, not the starting point in the file. The one major | * get displayed, not the starting point in the file. The one major | ||||
* incompatibility in this version as compared to historical versions | * incompatibility in this version as compared to historical versions | ||||
* is that the 'r' option couldn't be modified by the -lbc options, | * is that the 'r' option couldn't be modified by the -lbc options, | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | while ((ch = getopt_long(argc, argv, "+Fb:c:fn:qr", long_opts, NULL)) != | ||||
default: | default: | ||||
usage(); | usage(); | ||||
} | } | ||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
no_files = argc ? argc : 1; | no_files = argc ? argc : 1; | ||||
fa = fileargs_init(argc, argv, O_RDONLY, 0, &rights, FA_OPEN); | |||||
if (fa == NULL) | |||||
errx(1, "unable to init casper"); | |||||
caph_cache_catpages(); | |||||
if (caph_enter_casper() < 0) | |||||
err(1, "unable to enter capability mode"); | |||||
/* | /* | ||||
* If displaying in reverse, don't permit follow option, and convert | * If displaying in reverse, don't permit follow option, and convert | ||||
* style values. | * style values. | ||||
*/ | */ | ||||
if (rflag) { | if (rflag) { | ||||
if (fflag) | if (fflag) | ||||
usage(); | usage(); | ||||
if (style == FBYTES) | if (style == FBYTES) | ||||
Show All 21 Lines | files = (struct file_info *) malloc(no_files * | ||||
sizeof(struct file_info)); | sizeof(struct file_info)); | ||||
if (!files) | if (!files) | ||||
err(1, "Couldn't malloc space for file descriptors."); | err(1, "Couldn't malloc space for file descriptors."); | ||||
for (file = files; (fn = *argv++); file++) { | for (file = files; (fn = *argv++); file++) { | ||||
file->file_name = strdup(fn); | file->file_name = strdup(fn); | ||||
if (! file->file_name) | if (! file->file_name) | ||||
errx(1, "Couldn't malloc space for file name."); | errx(1, "Couldn't malloc space for file name."); | ||||
if ((file->fp = fopen(file->file_name, "r")) == NULL || | if ((file->fp = fileargs_fopen(fa, file->file_name, "r")) == NULL || | ||||
fstat(fileno(file->fp), &file->st)) { | fstat(fileno(file->fp), &file->st)) { | ||||
if (file->fp != NULL) { | if (file->fp != NULL) { | ||||
fclose(file->fp); | fclose(file->fp); | ||||
file->fp = NULL; | file->fp = NULL; | ||||
} | } | ||||
if (!Fflag || errno != ENOENT) | if (!Fflag || errno != ENOENT) | ||||
ierr(file->file_name); | ierr(file->file_name); | ||||
} | } | ||||
} | } | ||||
follow(files, style, off); | follow(files, style, off); | ||||
for (i = 0, file = files; i < no_files; i++, file++) { | for (i = 0, file = files; i < no_files; i++, file++) { | ||||
free(file->file_name); | free(file->file_name); | ||||
} | } | ||||
free(files); | free(files); | ||||
} else if (*argv) { | } else if (*argv) { | ||||
for (first = 1; (fn = *argv++);) { | for (first = 1; (fn = *argv++);) { | ||||
if ((fp = fopen(fn, "r")) == NULL || | if ((fp = fileargs_fopen(fa, fn, "r")) == NULL || | ||||
fstat(fileno(fp), &sb)) { | fstat(fileno(fp), &sb)) { | ||||
ierr(fn); | ierr(fn); | ||||
continue; | continue; | ||||
} | } | ||||
if (argc > 1 && !qflag) { | if (argc > 1 && !qflag) { | ||||
printfn(fn, !first); | printfn(fn, !first); | ||||
first = 0; | first = 0; | ||||
} | } | ||||
Show All 21 Lines | if (lseek(fileno(stdin), (off_t)0, SEEK_CUR) == -1 && | ||||
fflag = 0; /* POSIX.2 requires this. */ | fflag = 0; /* POSIX.2 requires this. */ | ||||
} | } | ||||
if (rflag) | if (rflag) | ||||
reverse(stdin, fn, style, off, &sb); | reverse(stdin, fn, style, off, &sb); | ||||
else | else | ||||
forward(stdin, fn, style, off, &sb); | forward(stdin, fn, style, off, &sb); | ||||
} | } | ||||
fileargs_free(fa); | |||||
exit(rval); | exit(rval); | ||||
} | } | ||||
/* | /* | ||||
* Convert the obsolete argument form into something that getopt can handle. | * Convert the obsolete argument form into something that getopt can handle. | ||||
* This means that anything of the form [+-][0-9][0-9]*[lbc][Ffr] that isn't | * This means that anything of the form [+-][0-9][0-9]*[lbc][Ffr] that isn't | ||||
* the option argument for a -b, -c or -n option gets converted. | * the option argument for a -b, -c or -n option gets converted. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 91 Lines • Show Last 20 Lines |