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