tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

tail.c (3451B)


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