Diff for /embedtools/src/dircmp.c between versions 1.1.2.5 and 1.1.2.8

version 1.1.2.5, 2010/07/13 12:38:23 version 1.1.2.8, 2010/09/20 23:07:11
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 13  Usage() Line 19  Usage()
                 "=== %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 ...\n"                  "\t-l\t\tLong directory output ...\n"
                 "\t-s\t\tCompare dir from stdin list\n"  
                 "\t-o <filename>\tOutput diff to filename\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;  
 }  
   
 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)  
 {  
         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 szLine[MAX_STR], szStr[MAX_STR], szType[MAX_STR], *str, *pbrk;  
         FILE *f = stdin;  
   
         if (!csDir1 || !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 & 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));  
                                 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;  
   
         // 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));  
                 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);  
                 }  
   
                 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, d.d_name, MAXPATHLEN);  
                         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));  
                                         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);  
 delel:  
         // 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;  
 end:  
         *list = l;  
         return n;  
 }  
   
 // ----------------------------------------------------  
   
 int  
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
         u_char *md[2] = { NULL, NULL };  
         char ch, szFName[MAXPATHLEN];          char ch, szFName[MAXPATHLEN];
           int lm = 0;
         struct tagDirName *list;          struct tagDirName *list;
         register int i;          register int i;
         FILE *f = stdout;          FILE *f = stdout;
           struct stat sb;
   
        while ((ch = getopt(argc, argv, "hlo:s")) != -1)        while ((ch = getopt(argc, argv, "hlo:")) != -1)
                 switch (ch) {                  switch (ch) {
                         case 'o':                          case 'o':
                                 lm |= 2;                                  lm |= 2;
                                 strlcpy(szFName, optarg, MAXPATHLEN);                                  strlcpy(szFName, optarg, MAXPATHLEN);
                                 break;                                  break;
                         case 's':  
                                 lm |= 4;  
                                 break;  
                         case 'l':                          case 'l':
                                 lm |= 1;                                  lm |= 1;
                                 break;                                  break;
Line 369  main(int argc, char **argv) Line 55  main(int argc, char **argv)
                 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 (argc > 1 && lm < 4) {                        printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
                if (calcDir(argv[1], &md[1]) == -1) { 
                        free(md[0]); 
                         return 127;                          return 127;
                 }                  }
                if (!memcmp(md[0], md[1], MD5_DIGEST_LENGTH)) {
                        free(md[0]);                if (S_ISDIR(sb.st_mode))
                        if (md[1])                        switch (sync_dircmp(argv[0], argv[1])) {
                                free(md[1]);                                case -1:
                        printf("Directory %s == %s\n\n", argv[0], argv[1]);                                        printf("Error:: %s(%d) #%d - %s\n", __func__, __LINE__, errno, strerror(errno));
                        return 0;                                        return 127;
                } else {                                case 0:
                        free(md[0]);                                        printf("Directory %s == %s\n\n", argv[0], argv[1]);
                        if (md[1])                                        return 0;
                                free(md[1]);                                case 1:
                        printf("Directory %s != %s ::\n\n", argv[0], argv[1]);                                        printf("Directory %s != %s ::\n\n", argv[0], argv[1]);
                }                        }
         }          }
   
        if (cmpDir(argv[0], argc > 1 ? argv[1] : NULL, &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, "-")) {          if (lm & 2 && strcmp(szFName, "-")) {
                 f = fopen(szFName, "w");                  f = fopen(szFName, "w");

Removed from v.1.1.2.5  
changed lines
  Added in v.1.1.2.8


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