Annotation of embedtools/src/dircmp.c, revision 1.1.2.1
1.1.2.1 ! misho 1: #include "global.h"
! 2: #include "dircmp.h"
! 3:
! 4:
! 5: extern char compiled[], compiledby[], compilehost[];
! 6: char l;
! 7:
! 8:
! 9: static void
! 10: Usage()
! 11: {
! 12: printf( "-= DirCmp =- Tool for compare directories and show differences\n"
! 13: "=== %s === %s@%s ===\n\n"
! 14: " Syntax: dircmp [options] <dir> <cmp_dir>\n\n"
! 15: "\t-l\t\tLong directory output ..."
! 16: "\n", compiled, compiledby, compilehost);
! 17: }
! 18:
! 19: int
! 20: calcDir(const char *csDir, u_char **md)
! 21: {
! 22: DIR *dir;
! 23: struct dirent d, *pd;
! 24: MD5_CTX ctx;
! 25:
! 26: *md = malloc(MD5_DIGEST_LENGTH);
! 27: if (!*md) {
! 28: printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
! 29: return -1;
! 30: } else
! 31: memset(*md, 0, MD5_DIGEST_LENGTH);
! 32:
! 33: dir = opendir(csDir);
! 34: if (!dir) {
! 35: printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
! 36: free(*md);
! 37: return -1;
! 38: }
! 39:
! 40: MD5_Init(&ctx);
! 41: while (!readdir_r(dir, &d, &pd) && pd) {
! 42: if (d.d_type == DT_DIR && (!strcmp(d.d_name, ".") || !strcmp(d.d_name, "..")))
! 43: continue;
! 44: MD5_Update(&ctx, d.d_name, d.d_namlen);
! 45: }
! 46: MD5_Final(*md, &ctx);
! 47:
! 48: closedir(dir);
! 49: return 0;
! 50: }
! 51:
! 52: // -------------------------------------------------------------------
! 53:
! 54: static int
! 55: func_comp(struct tagDirName const *d1, struct tagDirName const *d2)
! 56: {
! 57: return d1->tag - d2->tag;
! 58: }
! 59:
! 60: int
! 61: cmpDir(const char *csDir1, const char *csDir2, struct tagDirName **list)
! 62: {
! 63: struct tagDirName *l, *find;
! 64: int n, cx;
! 65: DIR *dir;
! 66: struct dirent d, *pd;
! 67: int tags[USHRT_MAX];
! 68: register int i;
! 69: u_short t;
! 70: u_int hash;
! 71: struct stat sb;
! 72: char szStr[MAX_STR], szType[MAX_STR];
! 73:
! 74: if (!csDir1 || !csDir2 || !list)
! 75: return -1;
! 76: else
! 77: memset(tags, -1, sizeof tags);
! 78:
! 79: l = malloc(sizeof(struct tagDirName));
! 80: if (!l) {
! 81: printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
! 82: return -1;
! 83: } else {
! 84: n = 0;
! 85: memset(l, 0, sizeof(struct tagDirName));
! 86: }
! 87:
! 88: dir = opendir(csDir1);
! 89: if (!dir) {
! 90: printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
! 91: free(l);
! 92: return -1;
! 93: }
! 94: while (!readdir_r(dir, &d, &pd) && pd) {
! 95: if (d.d_type == DT_DIR && (!strcmp(d.d_name, ".") || !strcmp(d.d_name, "..")))
! 96: continue;
! 97:
! 98: l = realloc(l, sizeof(struct tagDirName) * (n + 2));
! 99: if (!l) {
! 100: printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
! 101: closedir(dir);
! 102: return -1;
! 103: } else
! 104: memset(&l[n + 1], 0, sizeof(struct tagDirName));
! 105:
! 106: l[n].ch = '<';
! 107: l[n].tag = crcFletcher16((u_short*) d.d_name, d.d_namlen / 2 + d.d_namlen % 2);
! 108: l[n].hash = crcAdler((u_char*) d.d_name, d.d_namlen);
! 109: strlcpy(l[n].name, d.d_name, MAXPATHLEN);
! 110: if (l) {
! 111: if (lstat(d.d_name, &sb) != -1) {
! 112: memset(szStr, 0, MAX_STR);
! 113: strftime(szStr, MAX_STR, "%y-%m-%d %H:%M:%S", localtime(&sb.st_mtim));
! 114: switch (d.d_type) {
! 115: case DT_FIFO:
! 116: strlcpy(szType, "fifo", MAX_STR);
! 117: break;
! 118: case DT_CHR:
! 119: strlcpy(szType, "char", MAX_STR);
! 120: break;
! 121: case DT_DIR:
! 122: strlcpy(szType, "dir", MAX_STR);
! 123: break;
! 124: case DT_BLK:
! 125: strlcpy(szType, "block", MAX_STR);
! 126: break;
! 127: case DT_REG:
! 128: strlcpy(szType, "file", MAX_STR);
! 129: break;
! 130: case DT_LNK:
! 131: strlcpy(szType, "link", MAX_STR);
! 132: break;
! 133: case DT_SOCK:
! 134: strlcpy(szType, "socket", MAX_STR);
! 135: break;
! 136: case DT_WHT:
! 137: strlcpy(szType, "wht", MAX_STR);
! 138: break;
! 139: case DT_UNKNOWN:
! 140: default:
! 141: strlcpy(szType, "unknown", MAX_STR);
! 142: break;
! 143: }
! 144: snprintf(l[n].extra, MAX_STR, "%s links=%d %d:%d perm=0%o size=%llu %s\n", szType,
! 145: sb.st_nlink, sb.st_uid, sb.st_gid, sb.st_mode, sb.st_size, szStr);
! 146: }
! 147: }
! 148:
! 149: n++;
! 150: }
! 151: closedir(dir);
! 152: qsort(l, n, sizeof(struct tagDirName), (int (*)(const void*, const void*)) func_comp);
! 153: for (i = n - 1; i > -1; i--)
! 154: tags[l[i].tag] = i;
! 155:
! 156: // open dir 2 for diff ...
! 157: dir = opendir(csDir2);
! 158: if (!dir) {
! 159: printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
! 160: free(l);
! 161: return -1;
! 162: }
! 163: while (!readdir_r(dir, &d, &pd) && pd) {
! 164: if (d.d_type == DT_DIR && (!strcmp(d.d_name, ".") || !strcmp(d.d_name, "..")))
! 165: continue;
! 166: else {
! 167: t = crcFletcher16((u_short*) d.d_name, d.d_namlen / 2 + d.d_namlen % 2);
! 168: hash = crcAdler((u_char*) d.d_name, d.d_namlen);
! 169: }
! 170:
! 171: // search in index tags
! 172: find = NULL;
! 173: if (tags[t] != -1 && l[tags[t]].tag == t) {
! 174: // search in sorted hashes
! 175: for (i = 0; l[tags[t] + i].tag == t; i++)
! 176: if (l[tags[t] + i].hash == hash) {
! 177: // finded & marked for delete!
! 178: find = &l[tags[t] + i];
! 179: find->ch = '*';
! 180: break;
! 181: }
! 182: }
! 183: // element not find in dir1, added
! 184: if (!find) {
! 185: l = realloc(l, sizeof(struct tagDirName) * (n + 2));
! 186: if (!l) {
! 187: printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
! 188: closedir(dir);
! 189: return -1;
! 190: } else
! 191: memset(&l[n + 1], 0, sizeof(struct tagDirName));
! 192:
! 193: l[n].ch = '>';
! 194: l[n].tag = t;
! 195: l[n].hash = hash;
! 196: strlcpy(l[n].name, d.d_name, MAXPATHLEN);
! 197:
! 198: n++;
! 199: }
! 200: }
! 201: closedir(dir);
! 202:
! 203: // delete equal elemets !!!
! 204: for (i = cx = 0; i < n; i++)
! 205: if (l[i].ch == '*') {
! 206: memmove(&l[i], &l[i + 1], (n - i + 1) * sizeof(struct tagDirName));
! 207: cx++;
! 208: i--;
! 209: }
! 210: n -= cx;
! 211:
! 212: *list = l;
! 213: return n;
! 214: }
! 215:
! 216: // ----------------------------------------------------
! 217:
! 218: int
! 219: main(int argc, char **argv)
! 220: {
! 221: u_char *md[2];
! 222: char ch;
! 223: struct tagDirName *list;
! 224: register int i;
! 225:
! 226: while ((ch = getopt(argc, argv, "hl")) != -1)
! 227: switch (ch) {
! 228: case 'l':
! 229: l = 1;
! 230: break;
! 231: case 'h':
! 232: default:
! 233: Usage();
! 234: return 127;
! 235: }
! 236: argc -= optind;
! 237: argv += optind;
! 238:
! 239: if (argc < 2) {
! 240: Usage();
! 241: return 127;
! 242: }
! 243: // check for general differences
! 244: if (calcDir(argv[0], &md[0]) == -1)
! 245: return 127;
! 246: if (calcDir(argv[1], &md[1]) == -1) {
! 247: free(md[0]);
! 248: return 127;
! 249: }
! 250: if (!memcmp(md[0], md[1], MD5_DIGEST_LENGTH)) {
! 251: free(md[0]);
! 252: free(md[1]);
! 253: printf("Directory %s == %s\n\n", argv[0], argv[1]);
! 254: return 0;
! 255: } else {
! 256: free(md[0]);
! 257: free(md[1]);
! 258: printf("Directory %s != %s ::\n\n", argv[0], argv[1]);
! 259: }
! 260:
! 261: if (cmpDir(argv[0], argv[1], &list) == -1)
! 262: return 127;
! 263:
! 264: for (i = 0; list[i].ch; i++)
! 265: printf("%c %s %s\n", list[i].ch, list[i].name, list[i].extra);
! 266: printf("\nTotal count of elements = %d\n", i);
! 267:
! 268: free(list);
! 269: return 1;
! 270: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>