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