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