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);
160 int tail_main(int argc, char **argv)
162 int show_headers = 1;
173 for(opt=0;opt<argc;opt++){
174 test=atoi(argv[opt]);
181 optv = realloc(optv, optc);
182 optv[optc - 1] = (char *) malloc(strlen(argv[opt]) + 1);
183 strcpy(optv[optc - 1], argv[opt]);
186 while ((opt=getopt(optc,optv,"c:fhn:s:q:v")) >0) {
190 #ifndef BB_FEATURE_SIMPLE_TAIL
197 if(optarg[strlen(optarg)-1]>'9') {
198 switch (optarg[strlen(optarg)-1]) {
206 test *= (1024 * 1024);
209 fprintf(stderr,"Size must be b,k, or m.");
222 sleep_int = atoi(optarg);
239 if (optarg[0] == '+')
247 errorMsg("\nUnknown arg: %c.\n\n",optopt);
251 while (optind <= optc) {
258 if (!strcmp(optv[optind], "-"))
261 add_file(optv[optind]);
269 fd=malloc(sizeof(int)*n_files);
271 #ifndef BB_FEATURE_SIMPLE_TAIL
275 buffer=malloc(BUFSIZ);
276 for (test = 0; test < n_files; test++) {
278 printf("==> %s <==\n", files[test]);
279 if (!strcmp(files[test], STDIN))
282 fd[test] = open(files[test], O_RDONLY);
284 fatalError("Unable to open file %s.\n", files[test]);
285 tail_stream(fd[test]);
289 if((filelocation>0 || pip)){
290 write(1,buffer,bytes_read);
292 bytes_read = read(fd[test], buffer, bs);
293 filelocation+=bytes_read;
294 if (bytes_read <= 0) {
297 usleep(sleep_int * 1000);
303 for (test = 0; test < n_files; test++) {
309 bytes_read = read(fd[test], buffer, bs);
312 printf("==> %s <==\n", files[test]);
313 write(1,buffer,bytes_read);
335 c-file-style: "linux"