home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /*
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- #include "prio.h"
- #include "prprf.h"
- #include "prinit.h"
- #include "prthread.h"
- #include "prinrval.h"
-
- #include "plerror.h"
- #include "plgetopt.h"
-
- #include <stdlib.h>
-
- #define BUFFER_SIZE 500
-
- static PRFileDesc *out = NULL, *err = NULL;
-
- static void Help(void)
- {
- PR_fprintf(err, "Usage: tail [-n <n>] [-f] [-h] <filename>\n");
- PR_fprintf(err, "\t-t <n> Dally time in milliseconds\n");
- PR_fprintf(err, "\t-n <n> Number of bytes before <eof>\n");
- PR_fprintf(err, "\t-f Follow the <eof>\n");
- PR_fprintf(err, "\t-h This message and nothing else\n");
- } /* Help */
-
- PRIntn main(PRIntn argc, char **argv)
- {
- PRIntn rv = 0;
- PLOptStatus os;
- PRStatus status;
- PRFileDesc *file;
- PRFileInfo fileInfo;
- PRIntervalTime dally;
- char buffer[BUFFER_SIZE];
- PRBool follow = PR_FALSE;
- const char *filename = NULL;
- PRUint32 position = 0, seek = 0, time = 0;
- PLOptState *opt = PL_CreateOptState(argc, argv, "hfn:");
-
- out = PR_GetSpecialFD(PR_StandardOutput);
- err = PR_GetSpecialFD(PR_StandardError);
-
- while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
- {
- if (PL_OPT_BAD == os) continue;
- switch (opt->option)
- {
- case 0: /* it's the filename */
- filename = opt->value;
- break;
- case 'n': /* bytes before end of file */
- seek = atoi(opt->value);
- break;
- case 't': /* dally time */
- time = atoi(opt->value);
- break;
- case 'f': /* follow the end of file */
- follow = PR_TRUE;
- break;
- case 'h': /* user wants some guidance */
- Help(); /* so give him an earful */
- return 2; /* but not a lot else */
- break;
- default:
- break;
- }
- }
- PL_DestroyOptState(opt);
-
- if (0 == time) time = 1000;
- dally = PR_MillisecondsToInterval(time);
-
- if (NULL == filename)
- {
- (void)PR_fprintf(out, "Input file not specified\n");
- rv = 1; goto done;
- }
- file = PR_Open(filename, PR_RDONLY, 0);
- if (NULL == file)
- {
- PL_FPrintError(err, "File cannot be opened for reading");
- return 1;
- }
-
- status = PR_GetOpenFileInfo(file, &fileInfo);
- if (PR_FAILURE == status)
- {
- PL_FPrintError(err, "Cannot acquire status of file");
- rv = 1; goto done;
- }
- if (seek > 0)
- {
- if (seek > fileInfo.size) seek = 0;
- position = PR_Seek(file, (fileInfo.size - seek), PR_SEEK_SET);
- if (-1 == (PRInt32)position)
- PL_FPrintError(err, "Cannot seek to starting position");
- }
-
- do
- {
- while (position < fileInfo.size)
- {
- PRInt32 read, bytes = fileInfo.size - position;
- if (bytes > sizeof(buffer)) bytes = sizeof(buffer);
- read = PR_Read(file, buffer, bytes);
- if (read != bytes)
- PL_FPrintError(err, "Cannot read to eof");
- position += read;
- PR_Write(out, buffer, read);
- }
-
- if (follow)
- {
- PR_Sleep(dally);
- status = PR_GetOpenFileInfo(file, &fileInfo);
- if (PR_FAILURE == status)
- {
- PL_FPrintError(err, "Cannot acquire status of file");
- rv = 1; goto done;
- }
- }
- } while (follow);
-
- done:
- PR_Close(file);
-
- return rv;
- } /* main */
-
- /* tail.c */
-