tor-browser

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

filetools.cpp (4618B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /******************************************************************************
      4 *   Copyright (C) 2009-2013, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *******************************************************************************
      7 */
      8 
      9 #include "unicode/platform.h"
     10 #if U_PLATFORM == U_PF_MINGW
     11 // *cough* - for struct stat
     12 #ifdef __STRICT_ANSI__
     13 #undef __STRICT_ANSI__
     14 #endif
     15 #endif
     16 
     17 #include "filetools.h"
     18 #include "filestrm.h"
     19 #include "charstr.h"
     20 #include "cstring.h"
     21 #include "unicode/putil.h"
     22 #include "putilimp.h"
     23 
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <sys/stat.h>
     27 #include <time.h>
     28 #include <string.h>
     29 
     30 #if U_HAVE_DIRENT_H
     31 #include <dirent.h>
     32 typedef struct dirent DIRENT;
     33 
     34 #define SKIP1 "."
     35 #define SKIP2 ".."
     36 #endif
     37 
     38 static int32_t whichFileModTimeIsLater(const char *file1, const char *file2);
     39 
     40 /*
     41 * Goes through the given directory recursive to compare each file's modification time with that of the file given.
     42 * Also can be given just one file to check against. Default value for isDir is false.
     43 */
     44 U_CAPI UBool U_EXPORT2
     45 isFileModTimeLater(const char *filePath, const char *checkAgainst, UBool isDir) {
     46    UBool isLatest = true;
     47 
     48    if (filePath == nullptr || checkAgainst == nullptr) {
     49        return false;
     50    }
     51 
     52    if (isDir == true) {
     53 #if U_HAVE_DIRENT_H
     54        DIR *pDir = nullptr;
     55        if ((pDir= opendir(checkAgainst)) != nullptr) {
     56            DIR *subDirp = nullptr;
     57            DIRENT *dirEntry = nullptr;
     58 
     59            while ((dirEntry = readdir(pDir)) != nullptr) {
     60                if (uprv_strcmp(dirEntry->d_name, SKIP1) != 0 && uprv_strcmp(dirEntry->d_name, SKIP2) != 0) {
     61                    UErrorCode status = U_ZERO_ERROR;
     62                    icu::CharString newpath(checkAgainst, -1, status);
     63                    newpath.append(U_FILE_SEP_STRING, -1, status);
     64                    newpath.append(dirEntry->d_name, -1, status);
     65                    if (U_FAILURE(status)) {
     66                        fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, u_errorName(status));
     67                        return false;
     68                    }
     69 
     70                    if ((subDirp = opendir(newpath.data())) != nullptr) {
     71                        /* If this new path is a directory, make a recursive call with the newpath. */
     72                        closedir(subDirp);
     73                        isLatest = isFileModTimeLater(filePath, newpath.data(), isDir);
     74                        if (!isLatest) {
     75                            break;
     76                        }
     77                    } else {
     78                        int32_t latest = whichFileModTimeIsLater(filePath, newpath.data());
     79                        if (latest < 0 || latest == 2) {
     80                            isLatest = false;
     81                            break;
     82                        }
     83                    }
     84 
     85                }
     86            }
     87            closedir(pDir);
     88        } else {
     89            fprintf(stderr, "Unable to open directory: %s\n", checkAgainst);
     90            return false;
     91        }
     92 #endif
     93    } else {
     94        if (T_FileStream_file_exists(checkAgainst)) {
     95            int32_t latest = whichFileModTimeIsLater(filePath, checkAgainst);
     96            if (latest < 0 || latest == 2) {
     97                isLatest = false;
     98            }
     99        } else {
    100            isLatest = false;
    101        }
    102    }
    103 
    104    return isLatest;
    105 }
    106 
    107 /* Compares the mod time of both files returning a number indicating which one is later. -1 if error ocurs. */
    108 static int32_t whichFileModTimeIsLater(const char *file1, const char *file2) {
    109    int32_t result = 0;
    110    struct stat stbuf1, stbuf2;
    111 
    112    if (stat(file1, &stbuf1) == 0 && stat(file2, &stbuf2) == 0) {
    113        time_t modtime1, modtime2;
    114        double diff;
    115 
    116        modtime1 = stbuf1.st_mtime;
    117        modtime2 = stbuf2.st_mtime;
    118 
    119        diff = difftime(modtime1, modtime2);
    120        if (diff < 0.0) {
    121            result = 2;
    122        } else if (diff > 0.0) {
    123            result = 1;
    124        }
    125 
    126    } else {
    127        fprintf(stderr, "Unable to get stats from file: %s or %s\n", file1, file2);
    128        result = -1;
    129    }
    130 
    131    return result;
    132 }
    133 
    134 /* Swap the file separater character given with the new one in the file path. */
    135 U_CAPI void U_EXPORT2
    136 swapFileSepChar(char *filePath, const char oldFileSepChar, const char newFileSepChar) {
    137    for (int32_t i = 0, length = static_cast<int32_t>(uprv_strlen(filePath)); i < length; i++) {
    138        filePath[i] = (filePath[i] == oldFileSepChar ) ? newFileSepChar : filePath[i];
    139    }
    140 }