/*
 * $Header: /home/gene/library/website/docsrc/tlf/RCS/tail-f.c,v 395.1 2008/04/20 17:25:48 gene Exp $
 *
 * Copyright (c) 2004--2006 Gene Michael Stover.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL GENE MICHAEL STOVER BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 * Except as contained in this notice, the name of Gene Michael Stover
 * shall not be used in advertising or otherwise to promote the sale, use
 * or other dealings in this Software without prior written authorization
 * from Gene Michael Stover.
 */

/*
 * A simple re-implementation of the "tail" program found on unices.
 * It's for when you are stuck on a computer without a tail.
 */

#define MICROSLOTH_WINDERS 1

/* Standard C */
#include <stdio.h>
#include <stdlib.h>

/* Proprietary bullshit */
#ifdef MICROSLOTH_WINDERS
#include <windows.h>
#endif

typedef int Boolean;

static void
S_Sleep (n)
     int n; /* seconds */
{
#ifdef MICROSLOTH_WINDERS
  /* Dumbshit Microsloth Winders doesn't have a "sleep" function.  God
   * forbid Microsloth include a standard POSIX C function in
   * their library.  Proprietary idiot fuckers like Microsloth are what's
   * wrong with capitalism. */
  Sleep (n * 1000);
#else
  sleep (n);
#endif
}

static Boolean
S_IsReadable (pathname)
     char pathname[];
{
  FILE *fp;

  fp = fopen (pathname, "r");
  if (fp != NULL) {
    fclose (fp);
  }
  return fp != NULL;
}

static long
S_InitOffset (pathname)
     char pathname[];
{
  long offset;
  FILE *fp;

  fp = fopen (pathname, "r");
  if (fp != NULL) {
    if (fseek (fp, 0, SEEK_END) == 0) {
      offset = ftell (fp);
      offset -= 1024;                   /* backup 1 kilobyte */
      if (offset < 0) {
	offset = 0;
      }
    } else {
      /* Couldn't seek to the end. */
      offset = -1;
    }
    fclose (fp);
  } else {
    /* Couldn't open the file to read. */
    offset = -1;
  }
  return offset;
}

static long
S_Tick (pathname, offset)
     char pathname[];
     long offset;
{
  FILE *fp;
  int c;

  fp = fopen (pathname, "r");
  if (fp != NULL) {
    if (fseek (fp, offset, SEEK_SET) == 0) {
      while ((c = fgetc (fp)) != -1) {
	putchar (c);
      }
      offset = ftell (fp);
    } else {
      fprintf (stderr, "\n%s:%d: Can't seek to offset %ld.\n", __FILE__,
	       __LINE__, offset);
      offset = -1;
    }
    fclose (fp);
  } else {
    fprintf (stderr, "\n%s:%d: Can't re-open the file.  Did it move?\n",
	     __FILE__, __LINE__);
    offset = -1;
  }
  return offset;
}

int
main (argc, argv)
     int argc;
     char *argv[];
{
  int rc = 0;
  char *pathname;
  long offset;

  setbuf (stdout, NULL);
  pathname = argv[1];
  if (S_IsReadable (pathname)) {
    offset = S_InitOffset (pathname);
    while (rc == 0 && offset >= 0) {
      offset = S_Tick (pathname, offset);
      if (offset >= 0) {
	S_Sleep (2);
      } else {
	fprintf (stderr, "%s:%d: S_Tick indicates error\n", __FILE__,
		 __LINE__);
	rc = -7;
      }
    }
  } else {
    fprintf (stderr, "%s:%d: It appears that \"%s\" does not exist.\n",
	     __FILE__, __LINE__, pathname);
    rc = -4;
  }
  return rc == 0 ? 0 : 1;
}

/* --- end of file --- */
