[darwinbuild-changes] [88] trunk/darwinxref

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 4 01:44:11 PDT 2006


Revision: 88
          http://trac.macosforge.org/projects/darwinbuild/changeset/88
Author:   kevin
Date:     2006-10-04 01:44:11 -0700 (Wed, 04 Oct 2006)

Log Message:
-----------
- create manifest when registering a root

Modified Paths:
--------------
    trunk/darwinxref/Makefile
    trunk/darwinxref/plugins/register.c

Modified: trunk/darwinxref/Makefile
===================================================================
--- trunk/darwinxref/Makefile	2005-07-25 20:32:26 UTC (rev 87)
+++ trunk/darwinxref/Makefile	2006-10-04 08:44:11 UTC (rev 88)
@@ -69,6 +69,9 @@
 		$(SOURCES) \
 		$(SQLITELIB)
 
+plugins/register.so: plugins/register.c DBPlugin.h
+	cc -o $@ $(PLUGIN_CFLAGS) $(PLUGIN_LDFLAGS) -lcrypto $^
+
 plugins/%.so: plugins/%.c DBPlugin.h
 	cc -o $@ $(PLUGIN_CFLAGS) $(PLUGIN_LDFLAGS) $^
 

Modified: trunk/darwinxref/plugins/register.c
===================================================================
--- trunk/darwinxref/plugins/register.c	2005-07-25 20:32:26 UTC (rev 87)
+++ trunk/darwinxref/plugins/register.c	2006-10-04 08:44:11 UTC (rev 88)
@@ -34,8 +34,15 @@
 #include <sys/syslimits.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <fts.h>
-#include <fcntl.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <openssl/evp.h>
 
 int register_files(char* build, char* project, char* path);
 
@@ -67,19 +74,76 @@
 	return 0;
 }
 
-static int buildpath(char* path, size_t bufsiz, FTSENT* ent) {
-	if (ent->fts_parent != NULL && ent->fts_level > 1) {
-		bufsiz = buildpath(path, bufsiz, ent->fts_parent);
+static char* format_digest(const unsigned char* m) {
+        char* result = NULL;
+		// SHA-1
+		asprintf(&result,
+                "%02x%02x%02x%02x"
+                "%02x%02x%02x%02x"
+                "%02x%02x%02x%02x"
+                "%02x%02x%02x%02x"
+                "%02x%02x%02x%02x",
+                m[0], m[1], m[2], m[3],
+                m[4], m[5], m[6], m[7],
+                m[8], m[9], m[10], m[11],
+                m[12], m[13], m[14], m[15],
+				m[16], m[17], m[18], m[19]
+				);
+        return result;
+}
+
+static int compare(const FTSENT **a, const FTSENT **b) {
+	return strcmp((*a)->fts_name, (*b)->fts_name);
+}
+
+static int ent_filename(FTSENT* ent, char* filename, size_t bufsiz) {
+	if (ent == NULL) return 0;
+	if (ent->fts_level > 1) {
+		bufsiz = ent_filename(ent->fts_parent, filename, bufsiz);
 	}
-	strncat(path, "/", bufsiz);
+	strncat(filename, "/", bufsiz);
 	bufsiz -= 1;
 	if (ent->fts_name) {
-		strncat(path, ent->fts_name, bufsiz);
+		strncat(filename, ent->fts_name, bufsiz);
 		bufsiz -= strlen(ent->fts_name);
 	}
 	return bufsiz;
 }
 
+static char* calculate_digest(int fd) {
+	unsigned char digstr[EVP_MAX_MD_SIZE];
+	memset(digstr, 0, sizeof(digstr));
+	
+	EVP_MD_CTX ctx;
+	static const EVP_MD* md;
+	
+	if (md == NULL) {
+		EVP_MD_CTX_init(&ctx);
+		OpenSSL_add_all_digests();
+		md = EVP_get_digestbyname("sha1");
+		if (md == NULL) return NULL;
+	}
+
+	EVP_DigestInit(&ctx, md);
+
+	unsigned int len;
+	const unsigned int blocklen = 8192;
+	static unsigned char* block = NULL;
+	if (block == NULL) {
+		block = malloc(blocklen);
+	}
+	while(1) {
+		len = read(fd, block, blocklen);
+		if (len == 0) { close(fd); break; }
+		if ((len < 0) && (errno == EINTR)) continue;
+		if (len < 0) { close(fd); return NULL; }
+		EVP_DigestUpdate(&ctx, block, len);
+	}
+
+	EVP_DigestFinal(&ctx, digstr, &len);
+	return format_digest(digstr);
+}
+
 // If the path points to a Mach-O file, records all dylib
 // link commands as library dependencies in the database.
 // XXX
@@ -135,7 +199,6 @@
 			res = SQL("INSERT INTO unresolved_dependencies (build,project,type,dependency) VALUES (%Q,%Q,%Q,%Q)",
 			build, project, "lib", str);
 			
-			//fprintf(stdout, "\t%s\n", str);
 			free(str);
 			
 			lseek(fd, save - sizeof(struct dylib_command) + lc.cmdsize, SEEK_SET);
@@ -147,13 +210,8 @@
 	return 0;
 }
 
-int register_libraries(char* project, char* version, char* path) {
+int register_libraries(int fd, char* build, char* project) {
 	int res;
-	int fd = open(path, O_RDONLY);
-	if (fd == -1) {
-		perror(path);
-		return -1;
-	}
 	
 	struct mach_header mh;
 	struct fat_header fh;
@@ -186,15 +244,14 @@
 
 			res = read(fd, &mh, sizeof(mh));
 			if (res < sizeof(mh)) { goto error_out; }
-			register_mach_header(project, version, &mh, fd);
+			register_mach_header(build, project, &mh, fd);
 			
 			lseek(fd, save, SEEK_SET);
 		}
 	} else {
-		register_mach_header(project, version, &mh, fd);
+		register_mach_header(build, project, &mh, fd);
 	}
 error_out:
-	close(fd);
 	return 0;
 }
 
@@ -226,40 +283,69 @@
 	// not seen before.
 	//
 	// Skip the first result, since that is . of the DSTROOT itself.
-	int skip = 1;
 	char* path_argv[] = { path, NULL };
-	FTS* fts = fts_open(path_argv, FTS_PHYSICAL | FTS_COMFOLLOW | FTS_XDEV, NULL);
-	if (fts != NULL) {
-		FTSENT* ent;
-		while (ent = fts_read(fts)) {
-			if (ent->fts_number == 0) {
-				char path[PATH_MAX];
-				path[0] = 0;
-				buildpath(path, PATH_MAX-1, ent);
+	FTS* fts = fts_open(path_argv, FTS_PHYSICAL | FTS_COMFOLLOW | FTS_XDEV, compare);
+	FTSENT* ent = fts_read(fts); // throw away the entry for the DSTROOT itself
+	while ((ent = fts_read(fts)) != NULL) {
+		char filename[MAXPATHLEN+1];
+		char symlink[MAXPATHLEN+1];
+		int len;
+		off_t size;
+		
+		// Filename
+		filename[0] = 0;
+		ent_filename(ent, filename, MAXPATHLEN);
 
-				// don't bother to store $DSTROOT
-				if (!skip) {
-					printf("%s\n", path);
-					++loaded;
-					res = SQL("INSERT INTO files (build, project, path) VALUES (%Q,%Q,%Q)",
-						build, project, path);
-				} else {
-					skip = 0;
-				}
-
-				ent->fts_number = 1;
-
-				if (ent->fts_info == FTS_F) {
-					res = register_libraries(build, project, ent->fts_accpath);
-				}
+		// Symlinks
+		symlink[0] = 0;
+		if (ent->fts_info == FTS_SL || ent->fts_info == FTS_SLNONE) {
+			len = readlink(ent->fts_accpath, symlink, MAXPATHLEN);
+			if (len >= 0) symlink[len] = 0;
+		}
+		
+		// Default to empty SHA-1 checksum
+		char* checksum = strdup("                                        ");
+		
+		// Checksum regular files
+		if (ent->fts_info == FTS_F) {
+			int fd = open(ent->fts_accpath, O_RDONLY);
+			if (fd == -1) {
+				perror(filename);
+				return -1;
 			}
+			res = register_libraries(fd, build, project);
+			lseek(fd, (off_t)0, SEEK_SET);
+			checksum = calculate_digest(fd);
+			close(fd);
 		}
-		fts_close(fts);
+
+		// register regular files and symlinks in the DB
+		if (ent->fts_info == FTS_F || ent->fts_info == FTS_SL || ent->fts_info == FTS_SLNONE) {
+			res = SQL("INSERT INTO files (build, project, path) VALUES (%Q,%Q,%Q)",
+				build, project, filename);
+			++loaded;
+		}
+		
+		// add all regular files, directories, and symlinks to the manifest
+		if (ent->fts_info == FTS_F || ent->fts_info == FTS_D ||
+			ent->fts_info == FTS_SL || ent->fts_info == FTS_SLNONE) {
+			fprintf(stdout, "%s %o %d %d %lld %s%s%s\n",
+				checksum,
+				ent->fts_statp->st_mode,
+				ent->fts_statp->st_uid,
+				ent->fts_statp->st_gid,
+				(ent->fts_info != FTS_D) ? ent->fts_statp->st_size : (off_t)0,
+				filename,
+				symlink[0] ? " -> " : "",
+				symlink[0] ? symlink : "");
+		}
+		free(checksum);
 	}
+	fts_close(fts);
 	
 	if (SQL("COMMIT")) { return -1; }
 
-	fprintf(stdout, "%s - %d files registered.\n", project, loaded);
+	fprintf(stderr, "%s - %d files registered.\n", project, loaded);
 	
 	return res;
 }

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20061004/6f6edb56/attachment.html


More information about the darwinbuild-changes mailing list