Annotation of embedtools/src/dircmp.c, revision 1.1.2.3

1.1.2.1   misho       1: #include "global.h"
                      2: #include "dircmp.h"
                      3: 
                      4: 
                      5: extern char compiled[], compiledby[], compilehost[];
1.1.2.2   misho       6: char lm;
1.1.2.1   misho       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: 
1.1.2.3 ! misho      88:        if (chdir(csDir1) == -1) {
        !            89:                printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
        !            90:                free(l);
        !            91:                return -1;
        !            92:        }
        !            93:        dir = opendir(".");
1.1.2.1   misho      94:        if (!dir) {
                     95:                printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
                     96:                free(l);
                     97:                return -1;
                     98:        }
                     99:        while (!readdir_r(dir, &d, &pd) && pd) {
                    100:                if (d.d_type == DT_DIR && (!strcmp(d.d_name, ".") || !strcmp(d.d_name, "..")))
                    101:                        continue;
                    102: 
                    103:                l = realloc(l, sizeof(struct tagDirName) * (n + 2));
                    104:                if (!l) {
                    105:                        printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
                    106:                        closedir(dir);
                    107:                        return -1;
                    108:                } else
                    109:                        memset(&l[n + 1], 0, sizeof(struct tagDirName));
                    110: 
                    111:                l[n].ch = '<';
                    112:                l[n].tag = crcFletcher16((u_short*) d.d_name, d.d_namlen / 2 + d.d_namlen % 2);
                    113:                l[n].hash = crcAdler((u_char*) d.d_name, d.d_namlen);
                    114:                strlcpy(l[n].name, d.d_name, MAXPATHLEN);
1.1.2.2   misho     115:                if (lm) {
1.1.2.1   misho     116:                        if (lstat(d.d_name, &sb) != -1) {
                    117:                                memset(szStr, 0, MAX_STR);
1.1.2.3 ! misho     118:                                strftime(szStr, MAX_STR, "%Y-%m-%d %H:%M:%S", localtime((time_t*) &sb.st_mtim));
1.1.2.1   misho     119:                                switch (d.d_type) {
                    120:                                        case DT_FIFO:
                    121:                                                strlcpy(szType, "fifo", MAX_STR);
                    122:                                                break;
                    123:                                        case DT_CHR:
                    124:                                                strlcpy(szType, "char", MAX_STR);
                    125:                                                break;
                    126:                                        case DT_DIR:
                    127:                                                strlcpy(szType, "dir", MAX_STR);
                    128:                                                break;
                    129:                                        case DT_BLK:
                    130:                                                strlcpy(szType, "block", MAX_STR);
                    131:                                                break;
                    132:                                        case DT_REG:
                    133:                                                strlcpy(szType, "file", MAX_STR);
                    134:                                                break;
                    135:                                        case DT_LNK:
                    136:                                                strlcpy(szType, "link", MAX_STR);
                    137:                                                break;
                    138:                                        case DT_SOCK:
                    139:                                                strlcpy(szType, "socket", MAX_STR);
                    140:                                                break;
                    141:                                        case DT_WHT:
                    142:                                                strlcpy(szType, "wht", MAX_STR);
                    143:                                                break;
                    144:                                        case DT_UNKNOWN:
                    145:                                        default:
                    146:                                                strlcpy(szType, "unknown", MAX_STR);
                    147:                                                break;
                    148:                                }
1.1.2.3 ! misho     149:                                snprintf(l[n].extra, MAX_STR, "%s links=%d inode=%u %d:%d perm=0%o size=%llu %s", 
        !           150:                                                szType, sb.st_nlink, sb.st_ino, sb.st_uid, sb.st_gid, 
        !           151:                                                sb.st_mode & 0x1fff, sb.st_size, szStr);
1.1.2.1   misho     152:                        }
                    153:                }
                    154: 
                    155:                n++;
                    156:        }
                    157:        closedir(dir);
                    158:        qsort(l, n, sizeof(struct tagDirName), (int (*)(const void*, const void*)) func_comp);
                    159:        for (i = n - 1; i > -1; i--)
                    160:                tags[l[i].tag] = i;
                    161: 
                    162:        // open dir 2 for diff ...
1.1.2.3 ! misho     163:        if (chdir(csDir2) == -1) {
        !           164:                printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
        !           165:                free(l);
        !           166:                return -1;
        !           167:        }
        !           168:        dir = opendir(".");
1.1.2.1   misho     169:        if (!dir) {
                    170:                printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
                    171:                free(l);
                    172:                return -1;
                    173:        }
                    174:        while (!readdir_r(dir, &d, &pd) && pd) {
                    175:                if (d.d_type == DT_DIR && (!strcmp(d.d_name, ".") || !strcmp(d.d_name, "..")))
                    176:                        continue;
                    177:                else {
                    178:                        t = crcFletcher16((u_short*) d.d_name, d.d_namlen / 2 + d.d_namlen % 2);
                    179:                        hash = crcAdler((u_char*) d.d_name, d.d_namlen);
                    180:                }
                    181: 
                    182:                // search in index tags
                    183:                find = NULL;
                    184:                if (tags[t] != -1 && l[tags[t]].tag == t) {
                    185:                        // search in sorted hashes
                    186:                        for (i = 0; l[tags[t] + i].tag == t; i++)
                    187:                                if (l[tags[t] + i].hash == hash) {
                    188:                                        // finded & marked for delete!
                    189:                                        find = &l[tags[t] + i];
                    190:                                        find->ch = '*';
                    191:                                        break;
                    192:                                }
                    193:                }
                    194:                // element not find in dir1, added
                    195:                if (!find) {
                    196:                        l = realloc(l, sizeof(struct tagDirName) * (n + 2));
                    197:                        if (!l) {
                    198:                                printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
                    199:                                closedir(dir);
                    200:                                return -1;
                    201:                        } else
                    202:                                memset(&l[n + 1], 0, sizeof(struct tagDirName));
                    203: 
                    204:                        l[n].ch = '>';
                    205:                        l[n].tag = t;
                    206:                        l[n].hash = hash;
                    207:                        strlcpy(l[n].name, d.d_name, MAXPATHLEN);
1.1.2.2   misho     208:                        if (lm) {
                    209:                                if (lstat(d.d_name, &sb) != -1) {
                    210:                                        memset(szStr, 0, MAX_STR);
1.1.2.3 ! misho     211:                                        strftime(szStr, MAX_STR, "%Y-%m-%d %H:%M:%S", localtime((time_t*) &sb.st_mtim));
1.1.2.2   misho     212:                                        switch (d.d_type) {
                    213:                                                case DT_FIFO:
                    214:                                                        strlcpy(szType, "fifo", MAX_STR);
                    215:                                                        break;
                    216:                                                case DT_CHR:
                    217:                                                        strlcpy(szType, "char", MAX_STR);
                    218:                                                        break;
                    219:                                                case DT_DIR:
                    220:                                                        strlcpy(szType, "dir", MAX_STR);
                    221:                                                        break;
                    222:                                                case DT_BLK:
                    223:                                                        strlcpy(szType, "block", MAX_STR);
                    224:                                                        break;
                    225:                                                case DT_REG:
                    226:                                                        strlcpy(szType, "file", MAX_STR);
                    227:                                                        break;
                    228:                                                case DT_LNK:
                    229:                                                        strlcpy(szType, "link", MAX_STR);
                    230:                                                        break;
                    231:                                                case DT_SOCK:
                    232:                                                        strlcpy(szType, "socket", MAX_STR);
                    233:                                                        break;
                    234:                                                case DT_WHT:
                    235:                                                        strlcpy(szType, "wht", MAX_STR);
                    236:                                                        break;
                    237:                                                case DT_UNKNOWN:
                    238:                                                default:
                    239:                                                        strlcpy(szType, "unknown", MAX_STR);
                    240:                                                        break;
                    241:                                        }
1.1.2.3 ! misho     242:                                        snprintf(l[n].extra, MAX_STR, "%s links=%d inode=%u %d:%d perm=0%o size=%llu %s", 
        !           243:                                                        szType, sb.st_nlink, sb.st_ino, sb.st_uid, sb.st_gid, 
        !           244:                                                        sb.st_mode & 0x1fff, sb.st_size, szStr);
1.1.2.2   misho     245:                                }
                    246:                        }
1.1.2.1   misho     247: 
                    248:                        n++;
                    249:                }
                    250:        }
                    251:        closedir(dir);
                    252: 
                    253:        // delete equal elemets !!!
                    254:        for (i = cx = 0; i < n; i++)
                    255:                if (l[i].ch == '*') {
                    256:                        memmove(&l[i], &l[i + 1], (n - i + 1) * sizeof(struct tagDirName));
                    257:                        cx++;
                    258:                        i--;
                    259:                }
                    260:        n -= cx;
                    261: 
                    262:        *list = l;
                    263:        return n;
                    264: }
                    265: 
                    266: // ----------------------------------------------------
                    267: 
                    268: int
                    269: main(int argc, char **argv)
                    270: {
                    271:        u_char *md[2];
                    272:        char ch;
                    273:        struct tagDirName *list;
                    274:        register int i;
                    275: 
                    276:        while ((ch = getopt(argc, argv, "hl")) != -1)
                    277:                switch (ch) {
                    278:                        case 'l':
1.1.2.2   misho     279:                                lm = 1;
1.1.2.1   misho     280:                                break;
                    281:                        case 'h':
                    282:                        default:
                    283:                                Usage();
                    284:                                return 127;
                    285:                }
                    286:        argc -= optind;
                    287:        argv += optind;
                    288: 
                    289:        if (argc < 2) {
                    290:                Usage();
                    291:                return 127;
                    292:        }
                    293:        // check for general differences
                    294:        if (calcDir(argv[0], &md[0]) == -1)
                    295:                return 127;
                    296:        if (calcDir(argv[1], &md[1]) == -1) {
                    297:                free(md[0]);
                    298:                return 127;
                    299:        }
                    300:        if (!memcmp(md[0], md[1], MD5_DIGEST_LENGTH)) {
                    301:                free(md[0]);
                    302:                free(md[1]);
                    303:                printf("Directory %s == %s\n\n", argv[0], argv[1]);
                    304:                return 0;
                    305:        } else {
                    306:                free(md[0]);
                    307:                free(md[1]);
                    308:                printf("Directory %s != %s ::\n\n", argv[0], argv[1]);
                    309:        }
                    310: 
                    311:        if (cmpDir(argv[0], argv[1], &list) == -1)
                    312:                return 127;
                    313: 
                    314:        for (i = 0; list[i].ch; i++)
                    315:                printf("%c  %s %s\n", list[i].ch, list[i].name, list[i].extra);
                    316:        printf("\nTotal count of elements = %d\n", i);
                    317: 
                    318:        free(list);
                    319:        return 1;
                    320: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>