1 /* vi: set sw=4 ts=4: */
2 /* tail -- output the last part of file(s)
3 Copyright (C) 89, 90, 91, 95, 1996 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 Original version by Paul Rubin <phr@ocf.berkeley.edu>.
20 Extensions by David MacKenzie <djm@gnu.ai.mit.edu>.
21 tail -f for multiple files by Ian Lance Taylor <ian@airs.com>.
23 Rewrote the option parser, removed locales support,
24 and generally busyboxed, Erik Andersen <andersen@lineo.com>
26 Removed superfluous options and associated code ("-c", "-n", "-q").
27 Removed "tail -f" support for multiple files.
28 Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>.
30 Compleate Rewrite to correctly support "-NUM", "+NUM", and "-s" by
31 E.Allen Soard (esp@espsw.net).
34 #include <sys/types.h>
44 #define STDIN "standard input"
48 static int n_files = 0;
49 static char **files = NULL;
51 static ssize_t bytes_read=0;
53 static ssize_t filelocation=0;
56 #ifdef BB_FEATURE_SIMPLE_TAIL
57 static const char unit_type=LINES;
59 static char unit_type=LINES;
60 static char verbose = 0;
65 int tail_stream(int fd)
76 filesize=lseek(fd, -1, SEEK_END)+1;
93 bytes_read=read(fd,line,bs);
96 buffer=realloc(buffer,f_size+bytes_read);
97 memcpy(&buffer[f_size],line,bytes_read);
98 filelocation=f_size+=bytes_read;
106 filelocation = lseek(fd, 0, SEEK_CUR);
110 filelocation = lseek(fd, -bs, SEEK_CUR);
112 bytes_read = read(fd, buffer, bs);
122 for(;startpoint!=endpoint;startpoint+=direction) {
123 #ifndef BB_FEATURE_SIMPLE_TAIL
128 if(buffer[startpoint-1]=='\n')
131 filelocation=lseek(fd,0,SEEK_CUR);
132 if(count==units*direction)
135 if((count==units*direction) | pip)
138 filelocation = lseek(fd, -bytes_read, SEEK_CUR);
143 if(pip && (direction<0))
145 bytes_read=bs-startpoint;
146 memcpy(&buffer[0],&buffer[startpoint],bytes_read);
151 void add_file(char *name)
154 files = realloc(files, n_files);
155 files[n_files - 1] = (char *) malloc(strlen(name) + 1);
156 strcpy(files[n_files - 1], name);
159 void checknumbers(const char* name)
167 fatalError("Unrecognised number '%s'\n", name);
171 int tail_main(int argc, char **argv)
173 int show_headers = 1;
182 while ((opt=getopt(argc,argv,"c:fhn:s:q:v123456789+")) >0) {
185 case '1':case '2':case '3':case '4':case '5':
186 case '6':case '7':case '8':case '9':case '0':
187 checknumbers(argv[optind-1]);
190 #ifndef BB_FEATURE_SIMPLE_TAIL
196 if(optarg[strlen(optarg)-1]>'9') {
197 switch (optarg[strlen(optarg)-1]) {
205 test *= (1024 * 1024);
208 fprintf(stderr,"Size must be b,k, or m.");
221 sleep_int = atoi(optarg);
238 if (optarg[0] == '+')
246 errorMsg("\nUnknown arg: %c.\n\n",optopt);
250 while (optind <= argc) {
257 if (*argv[optind] == '+') {
258 checknumbers(argv[optind]);
260 else if (!strcmp(argv[optind], "-")) {
263 add_file(argv[optind]);
272 fd=malloc(sizeof(int)*n_files);
274 #ifndef BB_FEATURE_SIMPLE_TAIL
278 buffer=malloc(BUFSIZ);
279 for (test = 0; test < n_files; test++) {
281 printf("==> %s <==\n", files[test]);
282 if (!strcmp(files[test], STDIN))
285 fd[test] = open(files[test], O_RDONLY);
287 fatalError("Unable to open file %s.\n", files[test]);
288 tail_stream(fd[test]);
292 if((filelocation>0 || pip)){
293 write(1,buffer,bytes_read);
295 bytes_read = read(fd[test], buffer, bs);
296 filelocation+=bytes_read;
297 if (bytes_read <= 0) {
300 usleep(sleep_int * 1000);
306 for (test = 0; test < n_files; test++) {
312 bytes_read = read(fd[test], buffer, bs);
315 printf("==> %s <==\n", files[test]);
316 write(1,buffer,bytes_read);
336 c-file-style: "linux"