home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / tools / tail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  3.9 KB  |  148 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "prio.h"
  20. #include "prprf.h"
  21. #include "prinit.h"
  22. #include "prthread.h"
  23. #include "prinrval.h"
  24.  
  25. #include "plerror.h"
  26. #include "plgetopt.h"
  27.  
  28. #include <stdlib.h>
  29.  
  30. #define BUFFER_SIZE 500
  31.  
  32. static PRFileDesc *out = NULL, *err = NULL;
  33.  
  34. static void Help(void)
  35. {
  36.     PR_fprintf(err, "Usage: tail [-n <n>] [-f] [-h] <filename>\n");
  37.     PR_fprintf(err, "\t-t <n>    Dally time in milliseconds\n");
  38.     PR_fprintf(err, "\t-n <n>    Number of bytes before <eof>\n");
  39.     PR_fprintf(err, "\t-f       Follow the <eof>\n");
  40.     PR_fprintf(err, "\t-h       This message and nothing else\n");
  41. }  /* Help */
  42.  
  43. PRIntn main(PRIntn argc, char **argv)
  44. {
  45.     PRIntn rv = 0;
  46.     PLOptStatus os;
  47.     PRStatus status;
  48.     PRFileDesc *file;
  49.     PRFileInfo fileInfo;
  50.     PRIntervalTime dally;
  51.     char buffer[BUFFER_SIZE];
  52.     PRBool follow = PR_FALSE;
  53.     const char *filename = NULL;
  54.     PRUint32 position = 0, seek = 0, time = 0;
  55.     PLOptState *opt = PL_CreateOptState(argc, argv, "hfn:");
  56.  
  57.     out = PR_GetSpecialFD(PR_StandardOutput);
  58.     err = PR_GetSpecialFD(PR_StandardError);
  59.  
  60.     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  61.     {
  62.         if (PL_OPT_BAD == os) continue;
  63.         switch (opt->option)
  64.         {
  65.         case 0:  /* it's the filename */
  66.             filename = opt->value;
  67.             break;
  68.         case 'n':  /* bytes before end of file */
  69.             seek = atoi(opt->value);
  70.             break;
  71.         case 't':  /* dally time */
  72.             time = atoi(opt->value);
  73.             break;
  74.         case 'f':  /* follow the end of file */
  75.             follow = PR_TRUE;
  76.             break;
  77.         case 'h':  /* user wants some guidance */
  78.             Help();  /* so give him an earful */
  79.             return 2;  /* but not a lot else */
  80.             break;
  81.          default:
  82.             break;
  83.         }
  84.     }
  85.     PL_DestroyOptState(opt);
  86.  
  87.     if (0 == time) time = 1000;
  88.     dally = PR_MillisecondsToInterval(time);
  89.  
  90.     if (NULL == filename)
  91.     {
  92.         (void)PR_fprintf(out, "Input file not specified\n");
  93.         rv = 1; goto done;
  94.     }
  95.     file = PR_Open(filename, PR_RDONLY, 0);
  96.     if (NULL == file)
  97.     {
  98.         PL_FPrintError(err, "File cannot be opened for reading");
  99.         return 1;
  100.     }
  101.  
  102.     status = PR_GetOpenFileInfo(file, &fileInfo);
  103.     if (PR_FAILURE == status)
  104.     {
  105.         PL_FPrintError(err, "Cannot acquire status of file");
  106.         rv = 1; goto done;
  107.     }
  108.     if (seek > 0)
  109.     {
  110.         if (seek > fileInfo.size) seek = 0;
  111.         position = PR_Seek(file, (fileInfo.size - seek), PR_SEEK_SET);
  112.         if (-1 == (PRInt32)position)
  113.             PL_FPrintError(err, "Cannot seek to starting position");
  114.     }
  115.  
  116.     do
  117.     {
  118.         while (position < fileInfo.size)
  119.         {
  120.             PRInt32 read, bytes = fileInfo.size - position;
  121.             if (bytes > sizeof(buffer)) bytes = sizeof(buffer);
  122.             read = PR_Read(file, buffer, bytes);
  123.             if (read != bytes)
  124.                 PL_FPrintError(err, "Cannot read to eof");
  125.             position += read;
  126.             PR_Write(out, buffer, read);
  127.         }
  128.  
  129.         if (follow)
  130.         {
  131.             PR_Sleep(dally);
  132.             status = PR_GetOpenFileInfo(file, &fileInfo);
  133.             if (PR_FAILURE == status)
  134.             {
  135.                 PL_FPrintError(err, "Cannot acquire status of file");
  136.                 rv = 1; goto done;
  137.             }
  138.         }
  139.     } while (follow);
  140.  
  141. done:
  142.     PR_Close(file);
  143.  
  144.     return rv;
  145. }  /* main */
  146.  
  147. /* tail.c */
  148.