Diff for /embedtools/src/dircmp.c between versions 1.1.2.3 and 1.2

version 1.1.2.3, 2010/07/13 11:22:36 version 1.2, 2011/06/08 12:45:41
Line 1 Line 1
   /*************************************************************************
    * (C) 2010 AITNET - Sofia/Bulgaria - <office@aitbg.com>
    *  by Michael Pounov <misho@aitbg.com>
    *
    * $Author$
    * $Id$
    *
    *************************************************************************/
 #include "global.h"  #include "global.h"
 #include "dircmp.h"  
   
   
 extern char compiled[], compiledby[], compilehost[];  extern char compiled[], compiledby[], compilehost[];
 char lm;  
   
   
 static void  static void
Line 11  Usage() Line 17  Usage()
 {  {
         printf( "-= DirCmp =- Tool for compare directories and show differences\n"          printf( "-= DirCmp =- Tool for compare directories and show differences\n"
                 "=== %s === %s@%s ===\n\n"                  "=== %s === %s@%s ===\n\n"
                "  Syntax: dircmp [options] <dir> <cmp_dir>\n\n"                "  Syntax: dircmp [options] <dir> [<cmp_dir>]\n\n"
                "\t-l\t\tLong directory output ..."                "\t-l\t\tLong directory output ...\n"
                 "\t-o <filename>\tOutput diff to filename\n"
                 "\n", compiled, compiledby, compilehost);                  "\n", compiled, compiledby, compilehost);
 }  }
   
 int  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;  
 }  
   
 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 szStr[MAX_STR], szType[MAX_STR];  
   
         if (!csDir1 || !csDir2 || !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) {  
                         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;  
   
         // 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);  
                 }  
   
                 // 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;  
                                 }  
                 }  
                 // 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) {  
                                 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);  
   
         // 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;  
   
         *list = l;  
         return n;  
 }  
   
 // ----------------------------------------------------  
   
 int  
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
        u_char *md[2];        char ch, szFName[MAXPATHLEN];
        char ch;        int lm = 0;
         struct tagDirName *list;          struct tagDirName *list;
         register int i;          register int i;
           FILE *f = stdout;
           struct stat sb;
   
        while ((ch = getopt(argc, argv, "hl")) != -1)        while ((ch = getopt(argc, argv, "hlo:")) != -1)
                 switch (ch) {                  switch (ch) {
                           case 'o':
                                   lm |= 2;
                                   strlcpy(szFName, optarg, MAXPATHLEN);
                                   break;
                         case 'l':                          case 'l':
                                lm = 1;                                lm |= 1;
                                 break;                                  break;
                         case 'h':                          case 'h':
                         default:                          default:
Line 286  main(int argc, char **argv) Line 50  main(int argc, char **argv)
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
   
        if (argc < 2) {        if (!argc || (!(lm & 2) && argc < 2)) {
                 Usage();                  Usage();
                 return 127;                  return 127;
         }          }
         // check for general differences          // check for general differences
        if (calcDir(argv[0], &md[0]) == -1)        if (argc > 1) {
                return 127;                if (lstat(argv[1], &sb) == -1) {
        if (calcDir(argv[1], &md[1]) == -1) {                        printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
                free(md[0]);                        return 127;
                return 127;                }
 
                 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 (!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 (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;                  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++)          for (i = 0; list[i].ch; i++)
                printf("%c  %s %s\n", list[i].ch, list[i].name, list[i].extra);                fprintf(f, "%c  %s %s\n", list[i].ch, list[i].name, list[i].extra);
        printf("\nTotal count of elements = %d\n", i);        if (lm & 2)
                 fclose(f);
   
           printf("\nTotal count of elements = %d\n", i);
         free(list);          free(list);
         return 1;          return 1;
 }  }

Removed from v.1.1.2.3  
changed lines
  Added in v.1.2


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