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>