File:  [ELWIX - Embedded LightWeight unIX -] / embedtools / src / dircmp.c
Revision 1.1.2.1: download - view: text, annotated - select for diffs - revision graph
Tue Jul 13 09:35:01 2010 UTC (13 years, 11 months ago) by misho
Branches: tools1_0
added new prog

    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>