/* * Goes through the given directory recursive to compare each file's modification time with that of the file given. * Also can be given just one file to check against. Default value for isDir is FALSE. */ U_CAPI UBool U_EXPORT2 isFileModTimeLater(const char *filePath, const char *checkAgainst, UBool isDir) { UBool isLatest = TRUE; if (filePath == NULL || checkAgainst == NULL) { return FALSE; } if (isDir == TRUE) { #if U_HAVE_DIRENT_H DIR *pDir = NULL; if ((pDir= opendir(checkAgainst)) != NULL) { DIR *subDirp = NULL; DIRENT *dirEntry = NULL; while ((dirEntry = readdir(pDir)) != NULL) { if (uprv_strcmp(dirEntry->d_name, SKIP1) != 0 && uprv_strcmp(dirEntry->d_name, SKIP2) != 0) { UErrorCode status = U_ZERO_ERROR; icu::CharString newpath(checkAgainst, -1, status); newpath.append(U_FILE_SEP_STRING, -1, status); newpath.append(dirEntry->d_name, -1, status); if (U_FAILURE(status)) { fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, u_errorName(status)); return FALSE; }; if ((subDirp = opendir(newpath.data())) != NULL) { /* If this new path is a directory, make a recursive call with the newpath. */ closedir(subDirp); isLatest = isFileModTimeLater(filePath, newpath.data(), isDir); if (!isLatest) { break; } } else { int32_t latest = whichFileModTimeIsLater(filePath, newpath.data()); if (latest < 0 || latest == 2) { isLatest = FALSE; break; } } } } closedir(pDir); } else { fprintf(stderr, "Unable to open directory: %s\n", checkAgainst); return FALSE; } #endif } else { if (T_FileStream_file_exists(checkAgainst)) { int32_t latest = whichFileModTimeIsLater(filePath, checkAgainst); if (latest < 0 || latest == 2) { isLatest = FALSE; } } else { isLatest = FALSE; } } return isLatest; }
static int32_t pkg_executeOptions(UPKGOptions *o) { UErrorCode status = U_ZERO_ERROR; int32_t result = 0; // char cmd[SMALL_BUFFER_MAX_SIZE] = ""; const char mode = o->mode[0]; char targetDir[SMALL_BUFFER_MAX_SIZE] = ""; char tmpDir[SMALL_BUFFER_MAX_SIZE] = ""; char datFileName[SMALL_BUFFER_MAX_SIZE] = ""; char datFileNamePath[LARGE_BUFFER_MAX_SIZE] = ""; char checkLibFile[LARGE_BUFFER_MAX_SIZE] = ""; /* Initialize pkgdataFlags */ pkgDataFlags = (char**)uprv_malloc(sizeof(char*) * PKGDATA_FLAGS_SIZE); if (pkgDataFlags != NULL) { for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) { pkgDataFlags[i] = (char*)uprv_malloc(sizeof(char) * SMALL_BUFFER_MAX_SIZE); if (pkgDataFlags[i] != NULL) { pkgDataFlags[i][0] = 0; } else { fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"); return -1; } } } else { fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"); return -1; } #ifndef WINDOWS_WITH_MSVC /* Read in options file. */ parseFlagsFile(o->options, pkgDataFlags, SMALL_BUFFER_MAX_SIZE, (int32_t)PKGDATA_FLAGS_SIZE, &status); if (U_FAILURE(status)) { fprintf(stderr,"Unable to open or read \"%s\" option file.\n", o->options); return -1; } #endif if (mode == MODE_FILES) { /* Copy the raw data to the installation directory. */ if (o->install != NULL) { uprv_strcpy(targetDir, o->install); if (o->shortName != NULL) { uprv_strcat(targetDir, PKGDATA_FILE_SEP_STRING); uprv_strcat(targetDir, o->shortName); } result = pkg_installFileMode(targetDir, o->srcDir, o->fileListFiles->str); } return result; } else /* if (mode == MODE_COMMON || mode == MODE_STATIC || mode == MODE_DLL) */ { uprv_strcpy(targetDir, o->targetDir); uprv_strcat(targetDir, PKGDATA_FILE_SEP_STRING); uprv_strcpy(tmpDir, o->tmpDir); uprv_strcat(tmpDir, PKGDATA_FILE_SEP_STRING); uprv_strcpy(datFileNamePath, tmpDir); uprv_strcpy(datFileName, o->shortName); uprv_strcat(datFileName, UDATA_CMN_SUFFIX); uprv_strcat(datFileNamePath, datFileName); result = writePackageDatFile(datFileNamePath, o->comment, o->srcDir, o->fileListFiles->str, NULL, U_IS_BIG_ENDIAN ? 'b' : 'l'); if (result != 0) { fprintf(stderr,"Error writing package dat file.\n"); return result; } if (mode == MODE_COMMON) { char targetFileNamePath[LARGE_BUFFER_MAX_SIZE] = ""; uprv_strcpy(targetFileNamePath, targetDir); uprv_strcat(targetFileNamePath, datFileName); if (T_FileStream_file_exists(targetFileNamePath)) { if ((result = remove(targetFileNamePath)) != 0) { fprintf(stderr, "Unable to remove old dat file: %s\n", targetFileNamePath); return result; } } /* Move the dat file created to the target directory. */ result = rename(datFileNamePath, targetFileNamePath); if (result != 0) { fprintf(stderr, "Unable to move dat file (%s) to target location (%s).\n", datFileNamePath, targetFileNamePath); } return result; } else /* if (mode[0] == MODE_STATIC || mode[0] == MODE_DLL) */ { char gencFilePath[SMALL_BUFFER_MAX_SIZE] = ""; char version_major[10] = ""; UBool reverseExt = FALSE; #ifndef WINDOWS_WITH_MSVC /* Get the version major number. */ if (o->version != NULL) { for (uint32_t i = 0;i < sizeof(version_major);i++) { if (o->version[i] == '.') { version_major[i] = 0; break; } version_major[i] = o->version[i]; } } #ifndef OS400 /* Certain platforms have different library extension ordering. (e.g. libicudata.##.so vs libicudata.so.##) * reverseExt is FALSE if the suffix should be the version number. */ if (pkgDataFlags[LIB_EXT_ORDER][uprv_strlen(pkgDataFlags[LIB_EXT_ORDER])-1] == pkgDataFlags[SO_EXT][uprv_strlen(pkgDataFlags[SO_EXT])-1]) { reverseExt = TRUE; } #endif /* Using the base libName and version number, generate the library file names. */ createFileNames(version_major, o->version, o->libName, reverseExt); if (o->version != 0 && o->rebuild == FALSE) { /* Check to see if a previous built data library file exists and check if it is the latest. */ sprintf(checkLibFile, "%s%s", targetDir, libFileNames[LIB_FILE_VERSION_TMP]); if (T_FileStream_file_exists(checkLibFile)) { if (isFileModTimeLater(checkLibFile, o->srcDir, TRUE) && isFileModTimeLater(checkLibFile, o->options)) { if (o->install != NULL) { uprv_strcpy(libFileNames[LIB_FILE_VERSION], libFileNames[LIB_FILE_VERSION_TMP]); result = pkg_installLibrary(o->install, targetDir); } return result; } } } pkg_checkFlag(o); #endif if (pkgDataFlags[GENCCODE_ASSEMBLY_TYPE][0] != 0) { const char* genccodeAssembly = pkgDataFlags[GENCCODE_ASSEMBLY_TYPE]; /* Offset genccodeAssembly by 3 because "-a " */ if (checkAssemblyHeaderName(genccodeAssembly+3)) { writeAssemblyCode(datFileNamePath, o->tmpDir, o->entryName, NULL, gencFilePath); result = pkg_createWithAssemblyCode(targetDir, mode, gencFilePath); if (result != 0) { fprintf(stderr, "Error generating assembly code for data.\n"); return result; } else if (mode == MODE_STATIC) { return result; } } else { fprintf(stderr,"Assembly type \"%s\" is unknown.\n", genccodeAssembly); return -1; } } else { #ifdef CAN_WRITE_OBJ_CODE writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, NULL, NULL, gencFilePath); #ifdef U_LINUX result = pkg_generateLibraryFile(targetDir, mode, gencFilePath); #elif defined(WINDOWS_WITH_MSVC) return pkg_createWindowsDLL(mode, gencFilePath, o); #endif #elif defined(BUILD_DATA_WITHOUT_ASSEMBLY) result = pkg_createWithoutAssemblyCode(o, targetDir, mode); #endif if (result != 0) { fprintf(stderr, "Error generating package data.\n"); return result; } } #ifndef U_WINDOWS /* Certain platforms uses archive library. (e.g. AIX) */ result = pkg_archiveLibrary(targetDir, o->version, reverseExt); if (result != 0) { fprintf(stderr, "Error creating data archive library file.\n"); return result; } #ifndef OS400 /* Create symbolic links for the final library file. */ result = pkg_createSymLinks(targetDir); if (result != 0) { fprintf(stderr, "Error creating symbolic links of the data library file.\n"); return result; } #endif /* Install the libraries if option was set. */ if (o->install != NULL) { result = pkg_installLibrary(o->install, targetDir); if (result != 0) { fprintf(stderr, "Error installing the data library.\n"); return result; } } #endif } } return result; }