--- embedtools/src/dircmp.c 2010/07/13 11:22:36 1.1.2.3 +++ embedtools/src/dircmp.c 2010/07/13 12:38:23 1.1.2.5 @@ -11,8 +11,10 @@ Usage() { printf( "-= DirCmp =- Tool for compare directories and show differences\n" "=== %s === %s@%s ===\n\n" - " Syntax: dircmp [options] \n\n" - "\t-l\t\tLong directory output ..." + " 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); } @@ -57,6 +59,27 @@ func_comp(struct tagDirName const *d1, struct tagDirNa 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) { @@ -69,9 +92,10 @@ cmpDir(const char *csDir1, const char *csDir2, struct u_short t; u_int hash; struct stat sb; - char szStr[MAX_STR], szType[MAX_STR]; + char szLine[MAX_STR], szStr[MAX_STR], szType[MAX_STR], *str, *pbrk; + FILE *f = stdin; - if (!csDir1 || !csDir2 || !list) + if (!csDir1 || !list) return -1; else memset(tags, -1, sizeof tags); @@ -112,7 +136,7 @@ cmpDir(const char *csDir1, const char *csDir2, struct 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) { + 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)); @@ -159,6 +183,63 @@ cmpDir(const char *csDir1, const char *csDir2, struct 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)); @@ -179,18 +260,7 @@ cmpDir(const char *csDir1, const char *csDir2, struct hash = crcAdler((u_char*) d.d_name, d.d_namlen); } - // search in index tags - find = NULL; - 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 = &l[tags[t] + i]; - find->ch = '*'; - break; - } - } + find = find_tag(tags, l, t, hash); // element not find in dir1, added if (!find) { l = realloc(l, sizeof(struct tagDirName) * (n + 2)); @@ -205,7 +275,7 @@ cmpDir(const char *csDir1, const char *csDir2, struct l[n].tag = t; l[n].hash = hash; strlcpy(l[n].name, d.d_name, MAXPATHLEN); - if (lm) { + 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)); @@ -249,7 +319,7 @@ cmpDir(const char *csDir1, const char *csDir2, struct } } closedir(dir); - +delel: // delete equal elemets !!! for (i = cx = 0; i < n; i++) if (l[i].ch == '*') { @@ -258,7 +328,7 @@ cmpDir(const char *csDir1, const char *csDir2, struct i--; } n -= cx; - +end: *list = l; return n; } @@ -268,15 +338,23 @@ cmpDir(const char *csDir1, const char *csDir2, struct int main(int argc, char **argv) { - u_char *md[2]; - char ch; + u_char *md[2] = { NULL, NULL }; + char ch, szFName[MAXPATHLEN]; struct tagDirName *list; register int i; + FILE *f = stdout; - while ((ch = getopt(argc, argv, "hl")) != -1) + while ((ch = getopt(argc, argv, "hlo:s")) != -1) switch (ch) { + case 'o': + lm |= 2; + strlcpy(szFName, optarg, MAXPATHLEN); + break; + case 's': + lm |= 4; + break; case 'l': - lm = 1; + lm |= 1; break; case 'h': default: @@ -286,35 +364,50 @@ main(int argc, char **argv) argc -= optind; argv += optind; - if (argc < 2) { + if (!argc || (!(lm & 2) && argc < 2)) { Usage(); return 127; } // check for general differences if (calcDir(argv[0], &md[0]) == -1) return 127; - if (calcDir(argv[1], &md[1]) == -1) { - free(md[0]); - return 127; + if (argc > 1 && lm < 4) { + if (calcDir(argv[1], &md[1]) == -1) { + free(md[0]); + 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 (!memcmp(md[0], md[1], MD5_DIGEST_LENGTH)) { - free(md[0]); - free(md[1]); - printf("Directory %s == %s\n\n", argv[0], argv[1]); - return 0; - } else { - free(md[0]); - free(md[1]); - printf("Directory %s != %s ::\n\n", argv[0], argv[1]); - } - if (cmpDir(argv[0], argv[1], &list) == -1) + if (cmpDir(argv[0], argc > 1 ? argv[1] : NULL, &list) == -1) return 127; + if (lm & 2 && strcmp(szFName, "-")) { + f = fopen(szFName, "w"); + if (!f) { + printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno)); + if (list) + free(list); + return 0; + } + } for (i = 0; list[i].ch; i++) - printf("%c %s %s\n", list[i].ch, list[i].name, list[i].extra); - printf("\nTotal count of elements = %d\n", i); + fprintf(f, "%c %s %s\n", list[i].ch, list[i].name, list[i].extra); + if (lm & 2) + fclose(f); + printf("\nTotal count of elements = %d\n", i); free(list); return 1; }