/* tail -- output the last part of file(s)
   Copyright (C) 89, 90, 91, 95, 1996 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

   Original version by Paul Rubin <phr@ocf.berkeley.edu>.
   Extensions by David MacKenzie <djm@gnu.ai.mit.edu>.
   tail -f for multiple files by Ian Lance Taylor <ian@airs.com>.  

   Rewrote the option parser, removed locales support,
    and generally busyboxed, Erik Andersen <andersen@lineo.com>
 
 */

#include "internal.h"

#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>



/* Disable assertions.  Some systems have broken assert macros.  */
#define NDEBUG 1


static void error(int i, int errnum, char* fmt, ...)
{
    va_list arguments;

    va_start(arguments, fmt);
    vfprintf(stderr, fmt, arguments);
    fprintf(stderr, "\n%s\n", strerror( errnum));
    va_end(arguments);
    exit(i);
}


#define XWRITE(fd, buffer, n_bytes)					\
  do									\
    {									\
      assert ((fd) == 1);						\
      assert ((n_bytes) >= 0);						\
      if (n_bytes > 0 && fwrite ((buffer), 1, (n_bytes), stdout) == 0)	\
	error (EXIT_FAILURE, errno, "write error");			\
    }									\
  while (0)

/* Number of items to tail.  */
#define DEFAULT_N_LINES 10

/* Size of atomic reads.  */
#ifndef BUFSIZ
#define BUFSIZ (512 * 8)
#endif

/* If nonzero, interpret the numeric argument as the number of lines.
   Otherwise, interpret it as the number of bytes.  */
static int count_lines;

/* If nonzero, read from the end of one file until killed.  */
static int forever;

/* If nonzero, read from the end of multiple files until killed.  */
static int forever_multiple;

/* Array of file descriptors if forever_multiple is 1.  */
static int *file_descs;

/* Array of file sizes if forever_multiple is 1.  */
static off_t *file_sizes;

/* If nonzero, count from start of file instead of end.  */
static int from_start;

/* If nonzero, print filename headers.  */
static int print_headers;

/* When to print the filename banners.  */
enum header_mode
{
  multiple_files, always, never
};

char *xmalloc ();

/* The name this program was run with.  */
char *program_name;

/* Nonzero if we have ever read standard input.  */
static int have_read_stdin;


static const char tail_usage[] = 
"tail [OPTION]... [FILE]...\n\
\n\
Print last 10 lines of each FILE to standard output.\n\
With more than one FILE, precede each with a header giving the file name.\n\
With no FILE, or when FILE is -, read standard input.\n\
\n\
  -c=N[kbm]       output the last N bytes\n\
  -f              output appended data as the file grows\n\
  -n=N            output the last N lines, instead of last 10\n\
  -q              never output headers giving file names\n\
  -v              always output headers giving file names\n\
  --help          display this help and exit\n\
\n\
If the first character of N (bytes or lines) is a `+', output begins with \n\
the Nth item from the start of each file, otherwise, print the last N items\n\
in the file.  N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n\n";

static void
write_header (const char *filename, const char *comment)
{
  static int first_file = 1;

  printf ("%s==> %s%s%s <==\n", (first_file ? "" : "\n"), filename,
	  (comment ? ": " : ""),
	  (comment ? comment : ""));
  first_file = 0;
}

/* Print the last N_LINES lines from the end of file FD.
   Go backward through the file, reading `BUFSIZ' bytes at a time (except
   probably the first), until we hit the start of the file or have
   read NUMBER newlines.
   POS starts out as the length of the file (the offset of the last
   byte of the file + 1).
   Return 0 if successful, 1 if an error occurred.  */

static int
file_lines (const char *filename, int fd, long int n_lines, off_t pos)
{
  char buffer[BUFSIZ];
  int bytes_read;
  int i;			/* Index into `buffer' for scanning.  */

  if (n_lines == 0)
    return 0;

  /* Set `bytes_read' to the size of the last, probably partial, buffer;
     0 < `bytes_read' <= `BUFSIZ'.  */
  bytes_read = pos % BUFSIZ;
  if (bytes_read == 0)
    bytes_read = BUFSIZ;
  /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all
     reads will be on block boundaries, which might increase efficiency.  */
  pos -= bytes_read;
  lseek (fd, pos, SEEK_SET);
  bytes_read = fullRead (fd, buffer, bytes_read);
  if (bytes_read == -1)
    {
      error (0, errno, "%s", filename);
      return 1;
    }

  /* Count the incomplete line on files that don't end with a newline.  */
  if (bytes_read && buffer[bytes_read - 1] != '\n')
    --n_lines;

  do
    {
      /* Scan backward, counting the newlines in this bufferfull.  */
      for (i = bytes_read - 1; i >= 0; i--)
	{
	  /* Have we counted the requested number of newlines yet?  */
	  if (buffer[i] == '\n' && n_lines-- == 0)
	    {
	      /* If this newline wasn't the last character in the buffer,
	         print the text after it.  */
	      if (i != bytes_read - 1)
		XWRITE (STDOUT_FILENO, &buffer[i + 1], bytes_read - (i + 1));
	      return 0;
	    }
	}
      /* Not enough newlines in that bufferfull.  */
      if (pos == 0)
	{
	  /* Not enough lines in the file; print the entire file.  */
	  lseek (fd, (off_t) 0, SEEK_SET);
	  return 0;
	}
      pos -= BUFSIZ;
      lseek (fd, pos, SEEK_SET);
    }
  while ((bytes_read = fullRead (fd, buffer, BUFSIZ)) > 0);
  if (bytes_read == -1)
    {
      error (0, errno, "%s", filename);
      return 1;
    }
  return 0;
}

/* Print the last N_LINES lines from the end of the standard input,
   open for reading as pipe FD.
   Buffer the text as a linked list of LBUFFERs, adding them as needed.
   Return 0 if successful, 1 if an error occured.  */

static int
pipe_lines (const char *filename, int fd, long int n_lines)
{
  struct linebuffer
  {
    int nbytes, nlines;
    char buffer[BUFSIZ];
    struct linebuffer *next;
  };
  typedef struct linebuffer LBUFFER;
  LBUFFER *first, *last, *tmp;
  int i;			/* Index into buffers.  */
  int total_lines = 0;		/* Total number of newlines in all buffers.  */
  int errors = 0;

  first = last = (LBUFFER *) xmalloc (sizeof (LBUFFER));
  first->nbytes = first->nlines = 0;
  first->next = NULL;
  tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));

  /* Input is always read into a fresh buffer.  */
  while ((tmp->nbytes = fullRead (fd, tmp->buffer, BUFSIZ)) > 0)
    {
      tmp->nlines = 0;
      tmp->next = NULL;

      /* Count the number of newlines just read.  */
      for (i = 0; i < tmp->nbytes; i++)
	if (tmp->buffer[i] == '\n')
	  ++tmp->nlines;
      total_lines += tmp->nlines;

      /* If there is enough room in the last buffer read, just append the new
         one to it.  This is because when reading from a pipe, `nbytes' can
         often be very small.  */
      if (tmp->nbytes + last->nbytes < BUFSIZ)
	{
	  memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
	  last->nbytes += tmp->nbytes;
	  last->nlines += tmp->nlines;
	}
      else
	{
	  /* If there's not enough room, link the new buffer onto the end of
	     the list, then either free up the oldest buffer for the next
	     read if that would leave enough lines, or else malloc a new one.
	     Some compaction mechanism is possible but probably not
	     worthwhile.  */
	  last = last->next = tmp;
	  if (total_lines - first->nlines > n_lines)
	    {
	      tmp = first;
	      total_lines -= first->nlines;
	      first = first->next;
	    }
	  else
	    tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
	}
    }
  if (tmp->nbytes == -1)
    {
      error (0, errno, "%s", filename);
      errors = 1;
      free ((char *) tmp);
      goto free_lbuffers;
    }

  free ((char *) tmp);

  /* This prevents a core dump when the pipe contains no newlines.  */
  if (n_lines == 0)
    goto free_lbuffers;

  /* Count the incomplete line on files that don't end with a newline.  */
  if (last->buffer[last->nbytes - 1] != '\n')
    {
      ++last->nlines;
      ++total_lines;
    }

  /* Run through the list, printing lines.  First, skip over unneeded
     buffers.  */
  for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next)
    total_lines -= tmp->nlines;

  /* Find the correct beginning, then print the rest of the file.  */
  if (total_lines > n_lines)
    {
      char *cp;

      /* Skip `total_lines' - `n_lines' newlines.  We made sure that
         `total_lines' - `n_lines' <= `tmp->nlines'.  */
      cp = tmp->buffer;
      for (i = total_lines - n_lines; i; --i)
	while (*cp++ != '\n')
	  /* Do nothing.  */ ;
      i = cp - tmp->buffer;
    }
  else
    i = 0;
  XWRITE (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);

  for (tmp = tmp->next; tmp; tmp = tmp->next)
    XWRITE (STDOUT_FILENO, tmp->buffer, tmp->nbytes);

free_lbuffers:
  while (first)
    {
      tmp = first->next;
      free ((char *) first);
      first = tmp;
    }
  return errors;
}

/* Print the last N_BYTES characters from the end of pipe FD.
   This is a stripped down version of pipe_lines.
   Return 0 if successful, 1 if an error occurred.  */

static int
pipe_bytes (const char *filename, int fd, off_t n_bytes)
{
  struct charbuffer
  {
    int nbytes;
    char buffer[BUFSIZ];
    struct charbuffer *next;
  };
  typedef struct charbuffer CBUFFER;
  CBUFFER *first, *last, *tmp;
  int i;			/* Index into buffers.  */
  int total_bytes = 0;		/* Total characters in all buffers.  */
  int errors = 0;

  first = last = (CBUFFER *) xmalloc (sizeof (CBUFFER));
  first->nbytes = 0;
  first->next = NULL;
  tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));

  /* Input is always read into a fresh buffer.  */
  while ((tmp->nbytes = fullRead (fd, tmp->buffer, BUFSIZ)) > 0)
    {
      tmp->next = NULL;

      total_bytes += tmp->nbytes;
      /* If there is enough room in the last buffer read, just append the new
         one to it.  This is because when reading from a pipe, `nbytes' can
         often be very small.  */
      if (tmp->nbytes + last->nbytes < BUFSIZ)
	{
	  memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
	  last->nbytes += tmp->nbytes;
	}
      else
	{
	  /* If there's not enough room, link the new buffer onto the end of
	     the list, then either free up the oldest buffer for the next
	     read if that would leave enough characters, or else malloc a new
	     one.  Some compaction mechanism is possible but probably not
	     worthwhile.  */
	  last = last->next = tmp;
	  if (total_bytes - first->nbytes > n_bytes)
	    {
	      tmp = first;
	      total_bytes -= first->nbytes;
	      first = first->next;
	    }
	  else
	    {
	      tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
	    }
	}
    }
  if (tmp->nbytes == -1)
    {
      error (0, errno, "%s", filename);
      errors = 1;
      free ((char *) tmp);
      goto free_cbuffers;
    }

  free ((char *) tmp);

  /* Run through the list, printing characters.  First, skip over unneeded
     buffers.  */
  for (tmp = first; total_bytes - tmp->nbytes > n_bytes; tmp = tmp->next)
    total_bytes -= tmp->nbytes;

  /* Find the correct beginning, then print the rest of the file.
     We made sure that `total_bytes' - `n_bytes' <= `tmp->nbytes'.  */
  if (total_bytes > n_bytes)
    i = total_bytes - n_bytes;
  else
    i = 0;
  XWRITE (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);

  for (tmp = tmp->next; tmp; tmp = tmp->next)
    XWRITE (STDOUT_FILENO, tmp->buffer, tmp->nbytes);

free_cbuffers:
  while (first)
    {
      tmp = first->next;
      free ((char *) first);
      first = tmp;
    }
  return errors;
}

/* Skip N_BYTES characters from the start of pipe FD, and print
   any extra characters that were read beyond that.
   Return 1 on error, 0 if ok.  */

static int
start_bytes (const char *filename, int fd, off_t n_bytes)
{
  char buffer[BUFSIZ];
  int bytes_read = 0;

  while (n_bytes > 0 && (bytes_read = fullRead (fd, buffer, BUFSIZ)) > 0)
    n_bytes -= bytes_read;
  if (bytes_read == -1)
    {
      error (0, errno, "%s", filename);
      return 1;
    }
  else if (n_bytes < 0)
    XWRITE (STDOUT_FILENO, &buffer[bytes_read + n_bytes], -n_bytes);
  return 0;
}

/* Skip N_LINES lines at the start of file or pipe FD, and print
   any extra characters that were read beyond that.
   Return 1 on error, 0 if ok.  */

static int
start_lines (const char *filename, int fd, long int n_lines)
{
  char buffer[BUFSIZ];
  int bytes_read = 0;
  int bytes_to_skip = 0;

  while (n_lines && (bytes_read = fullRead (fd, buffer, BUFSIZ)) > 0)
    {
      bytes_to_skip = 0;
      while (bytes_to_skip < bytes_read)
	if (buffer[bytes_to_skip++] == '\n' && --n_lines == 0)
	  break;
    }
  if (bytes_read == -1)
    {
      error (0, errno, "%s", filename);
      return 1;
    }
  else if (bytes_to_skip < bytes_read)
    {
      XWRITE (STDOUT_FILENO, &buffer[bytes_to_skip],
	      bytes_read - bytes_to_skip);
    }
  return 0;
}

/* Display file FILENAME from the current position in FD to the end.
   If `forever' is nonzero, keep reading from the end of the file
   until killed.  Return the number of bytes read from the file.  */

static long
dump_remainder (const char *filename, int fd)
{
  char buffer[BUFSIZ];
  int bytes_read;
  long total;

  total = 0;
output:
  while ((bytes_read = fullRead (fd, buffer, BUFSIZ)) > 0)
    {
      XWRITE (STDOUT_FILENO, buffer, bytes_read);
      total += bytes_read;
    }
  if (bytes_read == -1)
    error (EXIT_FAILURE, errno, "%s", filename);
  if (forever)
    {
      fflush (stdout);
      sleep (1);
      goto output;
    }
  else
    {
      if (forever_multiple)
	fflush (stdout);
    }

  return total;
}

/* Tail NFILES (>1) files forever until killed.  The file names are in
   NAMES.  The open file descriptors are in `file_descs', and the size
   at which we stopped tailing them is in `file_sizes'.  We loop over
   each of them, doing an fstat to see if they have changed size.  If
   none of them have changed size in one iteration, we sleep for a
   second and try again.  We do this until the user interrupts us.  */

static void
tail_forever (char **names, int nfiles)
{
  int last;

  last = -1;

  while (1)
    {
      int i;
      int changed;

      changed = 0;
      for (i = 0; i < nfiles; i++)
	{
	  struct stat stats;

	  if (file_descs[i] < 0)
	    continue;
	  if (fstat (file_descs[i], &stats) < 0)
	    {
	      error (0, errno, "%s", names[i]);
	      file_descs[i] = -1;
	      continue;
	    }
	  if (stats.st_size == file_sizes[i])
	    continue;

	  /* This file has changed size.  Print out what we can, and
	     then keep looping.  */

	  changed = 1;

	  if (stats.st_size < file_sizes[i])
	    {
	      write_header (names[i], "file truncated");
	      last = i;
	      lseek (file_descs[i], stats.st_size, SEEK_SET);
	      file_sizes[i] = stats.st_size;
	      continue;
	    }

	  if (i != last)
	    {
	      if (print_headers)
		write_header (names[i], NULL);
	      last = i;
	    }
	  file_sizes[i] += dump_remainder (names[i], file_descs[i]);
	}

      /* If none of the files changed size, sleep.  */
      if (! changed)
	sleep (1);
    }
}

/* Output the last N_BYTES bytes of file FILENAME open for reading in FD.
   Return 0 if successful, 1 if an error occurred.  */

static int
tail_bytes (const char *filename, int fd, off_t n_bytes)
{
  struct stat stats;

  /* FIXME: resolve this like in dd.c.  */
  /* Use fstat instead of checking for errno == ESPIPE because
     lseek doesn't work on some special files but doesn't return an
     error, either.  */
  if (fstat (fd, &stats))
    {
      error (0, errno, "%s", filename);
      return 1;
    }

  if (from_start)
    {
      if (S_ISREG (stats.st_mode))
	lseek (fd, n_bytes, SEEK_CUR);
      else if (start_bytes (filename, fd, n_bytes))
	return 1;
      dump_remainder (filename, fd);
    }
  else
    {
      if (S_ISREG (stats.st_mode))
	{
	  off_t current_pos, end_pos;
	  size_t bytes_remaining;

	  if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1
	      && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1)
	    {
	      off_t diff;
	      /* Be careful here.  The current position may actually be
		 beyond the end of the file.  */
	      bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff;
	    }
	  else
	    {
	      error (0, errno, "%s", filename);
	      return 1;
	    }

	  if (bytes_remaining <= n_bytes)
	    {
	      /* From the current position to end of file, there are no
		 more bytes than have been requested.  So reposition the
		 file pointer to the incoming current position and print
		 everything after that.  */
	      lseek (fd, current_pos, SEEK_SET);
	    }
	  else
	    {
	      /* There are more bytes remaining than were requested.
		 Back up.  */
	      lseek (fd, -n_bytes, SEEK_END);
	    }
	  dump_remainder (filename, fd);
	}
      else
	return pipe_bytes (filename, fd, n_bytes);
    }
  return 0;
}

/* Output the last N_LINES lines of file FILENAME open for reading in FD.
   Return 0 if successful, 1 if an error occurred.  */

static int
tail_lines (const char *filename, int fd, long int n_lines)
{
  struct stat stats;
  off_t length;

  if (fstat (fd, &stats))
    {
      error (0, errno, "%s", filename);
      return 1;
    }

  if (from_start)
    {
      if (start_lines (filename, fd, n_lines))
	return 1;
      dump_remainder (filename, fd);
    }
  else
    {
      /* Use file_lines only if FD refers to a regular file with
         its file pointer positioned at beginning of file.  */
      /* FIXME: adding the lseek conjunct is a kludge.
	 Once there's a reasonable test suite, fix the true culprit:
	 file_lines.  file_lines shouldn't presume that the input
	 file pointer is initially positioned to beginning of file.  */
      if (S_ISREG (stats.st_mode)
	  && lseek (fd, (off_t) 0, SEEK_CUR) == (off_t) 0)
	{
	  length = lseek (fd, (off_t) 0, SEEK_END);
	  if (length != 0 && file_lines (filename, fd, n_lines, length))
	    return 1;
	  dump_remainder (filename, fd);
	}
      else
	return pipe_lines (filename, fd, n_lines);
    }
  return 0;
}

/* Display the last N_UNITS units of file FILENAME, open for reading
   in FD.
   Return 0 if successful, 1 if an error occurred.  */

static int
tail (const char *filename, int fd, off_t n_units)
{
  if (count_lines)
    return tail_lines (filename, fd, (long) n_units);
  else
    return tail_bytes (filename, fd, n_units);
}

/* Display the last N_UNITS units of file FILENAME.
   "-" for FILENAME means the standard input.
   FILENUM is this file's index in the list of files the user gave.
   Return 0 if successful, 1 if an error occurred.  */

static int
tail_file (const char *filename, off_t n_units, int filenum)
{
  int fd, errors;
  struct stat stats;

  if (!strcmp (filename, "-"))
    {
      have_read_stdin = 1;
      filename = "standard input";
      if (print_headers)
	write_header (filename, NULL);
      errors = tail (filename, 0, n_units);
      if (forever_multiple)
	{
	  if (fstat (0, &stats) < 0)
	    {
	      error (0, errno, "standard input");
	      errors = 1;
	    }
	  else if (!S_ISREG (stats.st_mode))
	    {
	      error (0, 0,
		     "standard input: cannot follow end of non-regular file");
	      errors = 1;
	    }
	  if (errors)
	    file_descs[filenum] = -1;
	  else
	    {
	      file_descs[filenum] = 0;
	      file_sizes[filenum] = stats.st_size;
	    }
	}
    }
  else
    {
      /* Not standard input.  */
      fd = open (filename, O_RDONLY);
      if (fd == -1)
	{
	  if (forever_multiple)
	    file_descs[filenum] = -1;
	  error (0, errno, "%s", filename);
	  errors = 1;
	}
      else
	{
	  if (print_headers)
	    write_header (filename, NULL);
	  errors = tail (filename, fd, n_units);
	  if (forever_multiple)
	    {
	      if (fstat (fd, &stats) < 0)
		{
		  error (0, errno, "%s", filename);
		  errors = 1;
		}
	      else if (!S_ISREG (stats.st_mode))
		{
		  error (0, 0, "%s: cannot follow end of non-regular file",
			 filename);
		  errors = 1;
		}
	      if (errors)
		{
		  close (fd);
		  file_descs[filenum] = -1;
		}
	      else
		{
		  file_descs[filenum] = fd;
		  file_sizes[filenum] = stats.st_size;
		}
	    }
	  else
	    {
	      if (close (fd))
		{
		  error (0, errno, "%s", filename);
		  errors = 1;
		}
	    }
	}
    }

  return errors;
}

extern int
tail_main (int argc, char **argv)
{
  int stopit = 0;
  enum header_mode header_mode = multiple_files;
  int exit_status = 0;
  /* If from_start, the number of items to skip before printing; otherwise,
     the number of items at the end of the file to print.  Initially, -1
     means the value has not been set.  */
  off_t n_units = -1;
  int n_files;
  char **file;

  program_name = argv[0];
  have_read_stdin = 0;
  count_lines = 1;
  forever = forever_multiple = from_start = print_headers = 0;
      
  /* Parse any options */
  //fprintf(stderr, "argc=%d, argv=%s\n", argc, *argv);
    while (--argc > 0 && ( **(++argv) == '-' || **argv == '+' )) {
	if (**argv == '+') {
	    from_start = 1;
	}
	stopit = 0;
	while (stopit == 0 && *(++(*argv))) {
	    switch (**argv) {
		case 'c':
		  count_lines = 0;

		  if (--argc < 1) {
		      usage(tail_usage);
		  }
		  n_units = getNum(*(++argv));
		  stopit = 1;
		  break;

		case 'f':
		  forever = 1;
		  break;

		case 'n':
		  count_lines = 1;

		  if (--argc < 1) {
		      usage(tail_usage);
		  }
		  n_units = atol(*(++argv));
		  stopit = 1;
		  break;

		case 'q':
		  header_mode = never;
		  break;

		case 'v':
		  header_mode = always;
		  break;

		default:
		  usage (tail_usage);
	    }
	}
    }


  if (n_units == -1)
    n_units = DEFAULT_N_LINES;

  /* To start printing with item N_UNITS from the start of the file, skip
     N_UNITS - 1 items.  `tail +0' is actually meaningless, but for Unix
     compatibility it's treated the same as `tail +1'.  */
  if (from_start)
    {
      if (n_units)
	--n_units;
    }

  n_files = argc;
  file = argv;

  if (n_files > 1 && forever)
    {
      forever_multiple = 1;
      forever = 0;
      file_descs = (int *) xmalloc (n_files * sizeof (int));
      file_sizes = (off_t *) xmalloc (n_files * sizeof (off_t));
    }

  if (header_mode == always
      || (header_mode == multiple_files && n_files > 1))
    print_headers = 1;

  if (n_files == 0)
    {
      exit_status |= tail_file ("-", n_units, 0);
    }
  else
    {
      int i;
      for (i = 0; i < n_files; i++)
	exit_status |= tail_file (file[i], n_units, i);

      if (forever_multiple)
	tail_forever (file, n_files);
    }

  if (have_read_stdin && close (0) < 0)
    error (EXIT_FAILURE, errno, "-");
  if (fclose (stdout) == EOF)
    error (EXIT_FAILURE, errno, "write error");
  exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
