Subject: pkg_info: patch to create summary file
To: None <tech-pkg@NetBSD.org>
From: Dieter Baron <dillo@danbala.tuwien.ac.at>
List: tech-pkg
Date: 04/11/2006 16:01:31
--fUYQa+Pmc3FrFX/N
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

hi,

attached is a patch that adds an option to pkg_info to output summary
information about packages, as discussed a while back on this list.
Please test and review.

  For lack of a better choice, I used the option -X.

  The patch uses the BUILD_INFO variables suggested by Jeremy.  (If
they are missing, they simply aren't included.)


  What is still missing is DIGEST (sha1 and rmd160) of the binary
package file.  Should I call out to digest(1) or use the C API?

  If I use digest(1), is there a function in lib/ to call a program
and collect its output (popen(3) uses system(3), which we try to
avoid, so is not an option)?

  If I use the C API, where do I get replacement functions from for
platforms missing them from their native libc?


  Another portability question: how do I portably and correctly print
an off_t?  (That's needed to include the file size of binary
packages.)

					yours,
					dillo


--fUYQa+Pmc3FrFX/N
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pkg-summary.diff"

Index: info/info.h
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/info/info.h,v
retrieving revision 1.21
diff -u -r1.21 info.h
--- info/info.h	3 Nov 2005 21:16:41 -0000	1.21
+++ info/info.h	11 Apr 2006 13:44:32 -0000
@@ -52,6 +52,7 @@
 #define SHOW_ALL_SIZE		0x10000
 #define SHOW_BLD_DEPENDS	0x20000
 #define SHOW_BI_VAR		0x40000
+#define SHOW_SUMMARY		0x80000
 
 enum which {
     WHICH_ALL,
@@ -78,5 +79,6 @@
 extern void show_depends(char *, package_t *);
 extern void show_bld_depends(char *, package_t *);
 extern void show_index(char *, char *, char *);
+extern void show_summary(package_t *, const char *);
 
 #endif				/* _INST_INFO_H_INCLUDE */
Index: info/main.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/info/main.c,v
retrieving revision 1.47
diff -u -r1.47 main.c
--- info/main.c	5 Nov 2005 13:11:02 -0000	1.47
+++ info/main.c	11 Apr 2006 13:44:32 -0000
@@ -50,7 +50,7 @@
 #include "lib.h"
 #include "info.h"
 
-static const char Options[] = ".aBbcDde:fFhIiK:kLl:mNnpQ:qRrsSuvV";
+static const char Options[] = ".aBbcDde:fFhIiK:kLl:mNnpQ:qRrsSuvVX";
 
 int     Flags = 0;
 enum which Which = WHICH_LIST;
@@ -68,7 +68,7 @@
 usage(void)
 {
 	fprintf(stderr, "%s\n%s\n%s\n%s\n",
-	    "usage: pkg_info [-BbcDdFfhIikLmNnpqRrSsVv] [-e package] [-K pkg_dbdir] [-l prefix]",
+	    "usage: pkg_info [-BbcDdFfhIikLmNnpqRrSsVvX] [-e package] [-K pkg_dbdir] [-l prefix]",
 	    "                pkg-name [...]",
 	    "       pkg_info [-a | -u] [flags]",
 	    "       pkg_info -Q variable pkg-name [pkg-name ...]");
@@ -205,6 +205,10 @@
 			show_version();
 			/* NOTREACHED */
 
+		case 'X':
+			Flags |= SHOW_SUMMARY;
+			break;
+
 		case 'h':
 		case '?':
 		default:
Index: info/perform.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/info/perform.c,v
retrieving revision 1.68
diff -u -r1.68 perform.c
--- info/perform.c	17 Mar 2006 02:31:44 -0000	1.68
+++ info/perform.c	11 Apr 2006 13:44:33 -0000
@@ -77,6 +77,8 @@
 	lfile_t	*lfp;
 	int	result;
 
+	fname[0] = '\0';
+
 	if (IS_URL(pkg)) {
 		if ((cp = fileGetURL(pkg)) != NULL) {
 			strlcpy(fname, cp, sizeof(fname));
@@ -131,9 +133,9 @@
 					LFILE_ADD(&files, lfp, MTREE_FNAME);
 				if (Flags & SHOW_BUILD_VERSION)
 					LFILE_ADD(&files, lfp, BUILD_VERSION_FNAME);
-				if (Flags & SHOW_BUILD_INFO)
+				if (Flags & (SHOW_BUILD_INFO|SHOW_SUMMARY))
 					LFILE_ADD(&files, lfp, BUILD_INFO_FNAME);
-				if (Flags & SHOW_PKG_SIZE)
+				if (Flags & (SHOW_PKG_SIZE|SHOW_SUMMARY))
 					LFILE_ADD(&files, lfp, SIZE_PKG_FNAME);
 				if (Flags & SHOW_ALL_SIZE)
 					LFILE_ADD(&files, lfp, SIZE_ALL_FNAME);
@@ -232,12 +234,15 @@
 		fclose(fp);
 
 		/* Start showing the package contents */
-		if (!Quiet) {
+		if (!Quiet && !(Flags & SHOW_SUMMARY)) {
 			printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
 			if (fexists(PRESERVE_FNAME)) {
 				printf("*** PACKAGE MAY NOT BE DELETED ***\n");
 			}
 		}
+		if (Flags & SHOW_SUMMARY) {
+			show_summary(&plist, fname);
+		}
 		if (Flags & SHOW_COMMENT) {
 			show_file(pkg, "Comment:\n", COMMENT_FNAME, TRUE);
 		}
@@ -305,7 +310,7 @@
 			show_file(pkg, "Size in bytes including required pkgs: ",
 				  SIZE_ALL_FNAME, TRUE);
 		}
-		if (!Quiet) {
+		if (!Quiet && !(Flags & SHOW_SUMMARY)) {
 			if (fexists(PRESERVE_FNAME)) {
 				printf("*** PACKAGE MAY NOT BE DELETED ***\n\n");
 			}
Index: info/show.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/info/show.c,v
retrieving revision 1.33
diff -u -r1.33 show.c
--- info/show.c	5 Nov 2005 13:11:02 -0000	1.33
+++ info/show.c	11 Apr 2006 13:44:33 -0000
@@ -106,6 +106,8 @@
 	{-1, NULL, NULL}
 };
 
+static int print_file_as_var(const char *, const char *);
+
 void
 show_file(char *pkg, char *title, char *fname, Boolean separator)
 {
@@ -341,3 +343,85 @@
 
 	printf("\n");
 }
+
+
+/*
+ * Show entry for pkg_summary.txt file.
+ */
+void
+show_summary(package_t *plist, const char *fname)
+{
+	static const char *bi_vars[] = {
+		"PKGPATH",
+		"CATEGORIES",
+		"PROVIDES",
+		"REQUIRES",
+		"PKG_OPTIONS",
+		"OPSYS",
+		"OS_VERSION",
+		"MACHINE_ARCH",
+		"LICENSE",
+		"HOMEPAGE",
+		"PKGTOOLS_VERSION",
+		"DATE",
+		NULL
+	};
+	
+	plist_t *p;
+	struct stat st;
+
+	for (p = plist->head; p; p = p->next) {
+		switch (p->type) {
+		case PLIST_NAME:
+			printf("PKGNAME=%s\n", p->name);
+			break;
+		case PLIST_PKGDEP:
+			printf("DEPENDS=%s\n", p->name);
+			break;
+		case PLIST_PKGCFL:
+			printf("CONFLICTS=%s\n", p->name);
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	print_file_as_var("COMMENT", COMMENT_FNAME);
+	print_file_as_var("SIZE_PKG", SIZE_PKG_FNAME);
+
+	var_copy_list(BUILD_INFO_FNAME, bi_vars);
+
+	if (fname[0] != '\0' && stat(fname, &st) == 0) {
+	    /* XXX: how to properly and portably print off_t? */
+	    printf("FILE_SIZE=%ld\n", (long)st.st_size);
+	    /* XXX: DIGETS */
+	}
+
+	print_file_as_var("DESCRIPTION", DESC_FNAME);
+	putc('\n', stdout);
+}
+
+static int
+print_file_as_var(const char *var, const char *fname)
+{
+	FILE *fp;
+	char *line;
+	size_t len;
+
+	fp = fopen(fname, "r");
+	if (!fp) {
+		warn("unable to open %s file", fname);
+		return -1;
+	}
+
+	while ((line = fgetln(fp, &len)) != (char *) NULL) {
+		if (line[len - 1] == '\n')
+			--len;
+		printf("%s=%.*s\n", var, (int)len, line);
+	}
+	
+	fclose(fp);
+
+	return 0;
+}
Index: lib/lib.h
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/lib/lib.h,v
retrieving revision 1.82
diff -u -r1.82 lib.h
--- lib/lib.h	6 Apr 2006 06:45:08 -0000	1.82
+++ lib/lib.h	11 Apr 2006 13:44:34 -0000
@@ -322,6 +322,7 @@
 
 char   *var_get(const char *, const char *);
 int	var_set(const char *, const char *, const char *);
+int     var_copy_list(const char *, const char **);
 
 /* automatically installed as dependency */
 
Index: lib/var.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/lib/var.c,v
retrieving revision 1.4
diff -u -r1.4 var.c
--- lib/var.c	17 Mar 2006 01:10:53 -0000	1.4
+++ lib/var.c	11 Apr 2006 13:44:34 -0000
@@ -61,6 +61,38 @@
 static const char *var_cmp(const char *, size_t, const char *, size_t);
 static void var_print(FILE *, const char *, const char *);
 
+int
+var_copy_list(const char *fname, const char **variables)
+{
+	FILE   *fp;
+	char   *line;
+	size_t  len;
+	const char *p;
+	int i;
+
+	fp = fopen(fname, "r");
+	if (!fp) {
+		if (errno != ENOENT)
+			warn("var_copy_list: can't open '%s' for reading",
+			     fname);
+		return -1;
+	}
+
+	while ((line = fgetln(fp, &len)) != (char *) NULL) {
+		if (line[len - 1] == '\n')
+			--len;
+		for (i=0; variables[i]; i++) {
+			if ((p=var_cmp(line, len, variables[i],
+				       strlen(variables[i]))) != NULL) {
+				printf("%.*s\n", (int)len, line);
+				break;
+			}
+		}
+	}
+	(void) fclose(fp);
+	return 0;
+}
+
 char *
 var_get(const char *fname, const char *variable)
 {

--fUYQa+Pmc3FrFX/N--