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>
43 #define STDIN "standard input"
47 static int n_files = 0;
48 static char **files = NULL;
50 static ssize_t bytes_read=0;
52 static ssize_t filelocation=0;
55 #ifdef BB_FEATURE_SIMPLE_TAIL
56 static const char unit_type=LINES;
58 static char unit_type=LINES;
59 static char verbose = 0;
64 int tail_stream(int fd)
75 filesize=lseek(fd, -1, SEEK_END)+1;
92 bytes_read=read(fd,line,bs);
95 buffer=realloc(buffer,f_size+bytes_read);
96 memcpy(&buffer[f_size],line,bytes_read);
97 filelocation=f_size+=bytes_read;
105 filelocation = lseek(fd, 0, SEEK_CUR);
109 filelocation = lseek(fd, -bs, SEEK_CUR);
111 bytes_read = read(fd, buffer, bs);
121 for(;startpoint!=endpoint;startpoint+=direction) {
122 #ifndef BB_FEATURE_SIMPLE_TAIL
127 if(buffer[startpoint-1]=='\n')
130 filelocation=lseek(fd,0,SEEK_CUR);
131 if(count==units*direction)
134 if((count==units*direction) | pip)
137 filelocation = lseek(fd, -bytes_read, SEEK_CUR);
142 if(pip && (direction<0))
144 bytes_read=bs-startpoint;
145 memcpy(&buffer[0],&buffer[startpoint],bytes_read);
150 void add_file(char *name)
153 files = realloc(files, n_files);
154 files[n_files - 1] = (char *) malloc(strlen(name) + 1);
155 strcpy(files[n_files - 1], name);
158 void checknumbers(const char* name)
166 fatalError("Unrecognised number '%s'\n", name);
170 int tail_main(int argc, char **argv)
172 int show_headers = 1;
181 while ((opt=getopt(argc,argv,"c:fhn:s:q:v123456789+")) >0) {
184 case '1':case '2':case '3':case '4':case '5':
185 case '6':case '7':case '8':case '9':case '0':
186 checknumbers(argv[optind-1]);
189 #ifndef BB_FEATURE_SIMPLE_TAIL
195 if(optarg[strlen(optarg)-1]>'9') {
196 switch (optarg[strlen(optarg)-1]) {
204 test *= (1024 * 1024);
207 fprintf(stderr,"Size must be b,k, or m.");
220 sleep_int = atoi(optarg);
237 if (optarg[0] == '+')
245 errorMsg("\nUnknown arg: %c.\n\n",optopt);
249 while (optind <= argc) {
256 if (*argv[optind] == '+') {
257 checknumbers(argv[optind]);
259 else if (!strcmp(argv[optind], "-")) {
262 add_file(argv[optind]);
271 fd=malloc(sizeof(int)*n_files);
273 #ifndef BB_FEATURE_SIMPLE_TAIL
277 buffer=malloc(BUFSIZ);
278 for (test = 0; test < n_files; test++) {
280 printf("==> %s <==\n", files[test]);
281 if (!strcmp(files[test], STDIN))
284 fd[test] = open(files[test], O_RDONLY);
286 fatalError("Unable to open file %s.\n", files[test]);
287 tail_stream(fd[test]);
291 if((filelocation>0 || pip)){
292 write(1,buffer,bytes_read);
294 bytes_read = read(fd[test], buffer, bs);
295 filelocation+=bytes_read;
296 if (bytes_read <= 0) {
299 usleep(sleep_int * 1000);
305 for (test = 0; test < n_files; test++) {
311 bytes_read = read(fd[test], buffer, bs);
314 printf("==> %s <==\n", files[test]);
315 write(1,buffer,bytes_read);
335 c-file-style: "linux"