--- embedtools/src/dircmp.c 2010/07/13 12:38:23 1.1.2.5 +++ embedtools/src/dircmp.c 2011/06/08 12:45:41 1.2 @@ -1,9 +1,15 @@ +/************************************************************************* + * (C) 2010 AITNET - Sofia/Bulgaria - + * by Michael Pounov + * + * $Author: misho $ + * $Id: dircmp.c,v 1.2 2011/06/08 12:45:41 misho Exp $ + * + *************************************************************************/ #include "global.h" -#include "dircmp.h" extern char compiled[], compiledby[], compilehost[]; -char lm; static void @@ -13,346 +19,26 @@ Usage() "=== %s === %s@%s ===\n\n" " Syntax: dircmp [options] []\n\n" "\t-l\t\tLong directory output ...\n" - "\t-s\t\tCompare dir from stdin list\n" "\t-o \tOutput diff to filename\n" "\n", compiled, compiledby, compilehost); } int -calcDir(const char *csDir, u_char **md) -{ - DIR *dir; - struct dirent d, *pd; - MD5_CTX ctx; - - *md = malloc(MD5_DIGEST_LENGTH); - if (!*md) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - return -1; - } else - memset(*md, 0, MD5_DIGEST_LENGTH); - - dir = opendir(csDir); - if (!dir) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - free(*md); - return -1; - } - - MD5_Init(&ctx); - while (!readdir_r(dir, &d, &pd) && pd) { - if (d.d_type == DT_DIR && (!strcmp(d.d_name, ".") || !strcmp(d.d_name, ".."))) - continue; - MD5_Update(&ctx, d.d_name, d.d_namlen); - } - MD5_Final(*md, &ctx); - - closedir(dir); - return 0; -} - -// ------------------------------------------------------------------- - -static int -func_comp(struct tagDirName const *d1, struct tagDirName const *d2) -{ - return d1->tag - d2->tag; -} - -static struct tagDirName * -find_tag(int const * __restrict tags, struct tagDirName const * __restrict l, u_short t, u_int hash) -{ - struct tagDirName *find = NULL; - register int i; - - // search in index tags - if (tags[t] != -1 && l[tags[t]].tag == t) { - // search in sorted hashes - for (i = 0; l[tags[t] + i].tag == t; i++) - if (l[tags[t] + i].hash == hash) { - // finded & marked for delete! - find = (struct tagDirName*) &l[tags[t] + i]; - find->ch = '*'; - break; - } - } - - return find; -} - -int -cmpDir(const char *csDir1, const char *csDir2, struct tagDirName **list) -{ - struct tagDirName *l, *find; - int n, cx; - DIR *dir; - struct dirent d, *pd; - int tags[USHRT_MAX]; - register int i; - u_short t; - u_int hash; - struct stat sb; - char szLine[MAX_STR], szStr[MAX_STR], szType[MAX_STR], *str, *pbrk; - FILE *f = stdin; - - if (!csDir1 || !list) - return -1; - else - memset(tags, -1, sizeof tags); - - l = malloc(sizeof(struct tagDirName)); - if (!l) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - return -1; - } else { - n = 0; - memset(l, 0, sizeof(struct tagDirName)); - } - - if (chdir(csDir1) == -1) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - free(l); - return -1; - } - dir = opendir("."); - if (!dir) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - free(l); - return -1; - } - while (!readdir_r(dir, &d, &pd) && pd) { - if (d.d_type == DT_DIR && (!strcmp(d.d_name, ".") || !strcmp(d.d_name, ".."))) - continue; - - l = realloc(l, sizeof(struct tagDirName) * (n + 2)); - if (!l) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - closedir(dir); - return -1; - } else - memset(&l[n + 1], 0, sizeof(struct tagDirName)); - - l[n].ch = '<'; - l[n].tag = crcFletcher16((u_short*) d.d_name, d.d_namlen / 2 + d.d_namlen % 2); - l[n].hash = crcAdler((u_char*) d.d_name, d.d_namlen); - strlcpy(l[n].name, d.d_name, MAXPATHLEN); - if (lm & 1) { - if (lstat(d.d_name, &sb) != -1) { - memset(szStr, 0, MAX_STR); - strftime(szStr, MAX_STR, "%Y-%m-%d %H:%M:%S", localtime((time_t*) &sb.st_mtim)); - switch (d.d_type) { - case DT_FIFO: - strlcpy(szType, "fifo", MAX_STR); - break; - case DT_CHR: - strlcpy(szType, "char", MAX_STR); - break; - case DT_DIR: - strlcpy(szType, "dir", MAX_STR); - break; - case DT_BLK: - strlcpy(szType, "block", MAX_STR); - break; - case DT_REG: - strlcpy(szType, "file", MAX_STR); - break; - case DT_LNK: - strlcpy(szType, "link", MAX_STR); - break; - case DT_SOCK: - strlcpy(szType, "socket", MAX_STR); - break; - case DT_WHT: - strlcpy(szType, "wht", MAX_STR); - break; - case DT_UNKNOWN: - default: - strlcpy(szType, "unknown", MAX_STR); - break; - } - snprintf(l[n].extra, MAX_STR, "%s links=%d inode=%u %d:%d perm=0%o size=%llu %s", - szType, sb.st_nlink, sb.st_ino, sb.st_uid, sb.st_gid, - sb.st_mode & 0x1fff, sb.st_size, szStr); - } - } - - n++; - } - closedir(dir); - qsort(l, n, sizeof(struct tagDirName), (int (*)(const void*, const void*)) func_comp); - for (i = n - 1; i > -1; i--) - tags[l[i].tag] = i; - - // if only 1 dir supplied and output filename is set, goto end - if (lm & 2 && !csDir2) - goto end; - // - if (lm & 4) { - if (strcmp(csDir2, "-")) { - f = fopen(csDir2, "r"); - if (!f) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - free(l); - return -1; - } - } - while (fgets(szLine, MAX_STR, f)) { - if (!*szLine || *szLine == '#') - continue; - - str = strtok_r(szLine, " \t", &pbrk); - if (!str) - continue; - str = strtok_r(NULL, " \t", &pbrk); - if (!str) - continue; - else { - i = strlen(str); - t = crcFletcher16((u_short*) str, i / 2 + i % 2); - hash = crcAdler((u_char*) str, i); - } - - find = find_tag(tags, l, t, hash); - // element not find in dir1, added - if (!find) { - l = realloc(l, sizeof(struct tagDirName) * (n + 2)); - if (!l) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - closedir(dir); - return -1; - } else - memset(&l[n + 1], 0, sizeof(struct tagDirName)); - - l[n].ch = '>'; - l[n].tag = t; - l[n].hash = hash; - strlcpy(l[n].name, str, MAXPATHLEN); - if (lm & 1 && (str = strtok_r(NULL, "\r\n", &pbrk))) - strlcpy(l[n].extra, str, MAX_STR); - - n++; - } - } - if (strcmp(csDir2, "-")) - fclose(f); - - goto delel; - } - //// - - // open dir 2 for diff ... - if (chdir(csDir2) == -1) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - free(l); - return -1; - } - dir = opendir("."); - if (!dir) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - free(l); - return -1; - } - while (!readdir_r(dir, &d, &pd) && pd) { - if (d.d_type == DT_DIR && (!strcmp(d.d_name, ".") || !strcmp(d.d_name, ".."))) - continue; - else { - t = crcFletcher16((u_short*) d.d_name, d.d_namlen / 2 + d.d_namlen % 2); - hash = crcAdler((u_char*) d.d_name, d.d_namlen); - } - - find = find_tag(tags, l, t, hash); - // element not find in dir1, added - if (!find) { - l = realloc(l, sizeof(struct tagDirName) * (n + 2)); - if (!l) { - printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); - closedir(dir); - return -1; - } else - memset(&l[n + 1], 0, sizeof(struct tagDirName)); - - l[n].ch = '>'; - l[n].tag = t; - l[n].hash = hash; - strlcpy(l[n].name, d.d_name, MAXPATHLEN); - if (lm & 1) { - if (lstat(d.d_name, &sb) != -1) { - memset(szStr, 0, MAX_STR); - strftime(szStr, MAX_STR, "%Y-%m-%d %H:%M:%S", localtime((time_t*) &sb.st_mtim)); - switch (d.d_type) { - case DT_FIFO: - strlcpy(szType, "fifo", MAX_STR); - break; - case DT_CHR: - strlcpy(szType, "char", MAX_STR); - break; - case DT_DIR: - strlcpy(szType, "dir", MAX_STR); - break; - case DT_BLK: - strlcpy(szType, "block", MAX_STR); - break; - case DT_REG: - strlcpy(szType, "file", MAX_STR); - break; - case DT_LNK: - strlcpy(szType, "link", MAX_STR); - break; - case DT_SOCK: - strlcpy(szType, "socket", MAX_STR); - break; - case DT_WHT: - strlcpy(szType, "wht", MAX_STR); - break; - case DT_UNKNOWN: - default: - strlcpy(szType, "unknown", MAX_STR); - break; - } - snprintf(l[n].extra, MAX_STR, "%s links=%d inode=%u %d:%d perm=0%o size=%llu %s", - szType, sb.st_nlink, sb.st_ino, sb.st_uid, sb.st_gid, - sb.st_mode & 0x1fff, sb.st_size, szStr); - } - } - - n++; - } - } - closedir(dir); -delel: - // delete equal elemets !!! - for (i = cx = 0; i < n; i++) - if (l[i].ch == '*') { - memmove(&l[i], &l[i + 1], (n - i + 1) * sizeof(struct tagDirName)); - cx++; - i--; - } - n -= cx; -end: - *list = l; - return n; -} - -// ---------------------------------------------------- - -int main(int argc, char **argv) { - u_char *md[2] = { NULL, NULL }; char ch, szFName[MAXPATHLEN]; + int lm = 0; struct tagDirName *list; register int i; FILE *f = stdout; + struct stat sb; - while ((ch = getopt(argc, argv, "hlo:s")) != -1) + while ((ch = getopt(argc, argv, "hlo:")) != -1) switch (ch) { case 'o': lm |= 2; strlcpy(szFName, optarg, MAXPATHLEN); break; - case 's': - lm |= 4; - break; case 'l': lm |= 1; break; @@ -369,29 +55,29 @@ main(int argc, char **argv) return 127; } // check for general differences - if (calcDir(argv[0], &md[0]) == -1) - return 127; - if (argc > 1 && lm < 4) { - if (calcDir(argv[1], &md[1]) == -1) { - free(md[0]); + if (argc > 1) { + if (lstat(argv[1], &sb) == -1) { + printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); return 127; } - if (!memcmp(md[0], md[1], MD5_DIGEST_LENGTH)) { - free(md[0]); - if (md[1]) - free(md[1]); - printf("Directory %s == %s\n\n", argv[0], argv[1]); - return 0; - } else { - free(md[0]); - if (md[1]) - free(md[1]); - printf("Directory %s != %s ::\n\n", argv[0], argv[1]); - } + + if (S_ISDIR(sb.st_mode)) + switch (sync_dircmp(argv[0], argv[1])) { + case -1: + printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); + return 127; + case 0: + printf("Directory %s == %s\n\n", argv[0], argv[1]); + return 0; + case 1: + printf("Directory %s != %s ::\n\n", argv[0], argv[1]); + } } - if (cmpDir(argv[0], argc > 1 ? argv[1] : NULL, &list) == -1) + if (sync_dircmpList(argv[0], argc > 1 ? argv[1] : NULL, lm, &list) == -1) { + printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, sync_GetErrno(), sync_GetError()); return 127; + } if (lm & 2 && strcmp(szFName, "-")) { f = fopen(szFName, "w");