svn commit: r206043 - in head/usr.sbin/pkg_install: add delete lib version

Florent Thoumie flz at FreeBSD.org
Thu Apr 1 14:27:29 UTC 2010


Author: flz
Date: Thu Apr  1 14:27:29 2010
New Revision: 206043
URL: http://svn.freebsd.org/changeset/base/206043

Log:
  Various fixes.
  
  - Replace hardcoded INDEX version. [1]
  - Fix a buffer overlap. [2]
  - Remove empty package when fetching fails and -K is used. [3]
  - Remove useless chmod2() after mkdtemp(3). [4]
  - Replace mkdir(1) call with mkdir(2). [5]
  - Get rid of some vsystem() calls.
  - Switch from lstat(2) to open(2) in fexists().
  - Try rename(2) in move_file() first.
  - Bump PKG_INSTALL_VERSION to 20100401.
  
  PR:		bin/145101 [1], bin/139492 [2], bin/144919 [3]
  		bin/144920 [4], bin/144921 [5]
  Submitted by:	gcooper [1,2,3,4,5]

Modified:
  head/usr.sbin/pkg_install/add/futil.c
  head/usr.sbin/pkg_install/add/perform.c
  head/usr.sbin/pkg_install/delete/perform.c
  head/usr.sbin/pkg_install/lib/file.c
  head/usr.sbin/pkg_install/lib/lib.h
  head/usr.sbin/pkg_install/lib/match.c
  head/usr.sbin/pkg_install/lib/pen.c
  head/usr.sbin/pkg_install/lib/url.c
  head/usr.sbin/pkg_install/version/perform.c

Modified: head/usr.sbin/pkg_install/add/futil.c
==============================================================================
--- head/usr.sbin/pkg_install/add/futil.c	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/add/futil.c	Thu Apr  1 14:27:29 2010	(r206043)
@@ -50,7 +50,7 @@ make_hierarchy(char *dir)
 	    }
 	}
 	else {
-	    if (vsystem("/bin/mkdir %s", dir)) {
+	    if (mkdir(dir, 0777) < 0) {
 		if (cp2)
 		    *cp2 = '/';
 		return FAIL;

Modified: head/usr.sbin/pkg_install/add/perform.c
==============================================================================
--- head/usr.sbin/pkg_install/add/perform.c	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/add/perform.c	Thu Apr  1 14:27:29 2010	(r206043)
@@ -78,6 +78,7 @@ pkg_do(char *pkg)
     char pre_arg[FILENAME_MAX], post_arg[FILENAME_MAX];
     char *conflict[2];
     char **matched;
+    int fd;
 
     conflictsfound = 0;
     code = 0;
@@ -408,8 +409,10 @@ pkg_do(char *pkg)
 	goto bomb;
 
     /* Look for the requirements file */
-    if (fexists(REQUIRE_FNAME)) {
-	vsystem("/bin/chmod +x %s", REQUIRE_FNAME);	/* be sure */
+    if ((fd = open(REQUIRE_FNAME, O_RDWR)) != -1) {
+	fstat(fd, &sb);
+	fchmod(fd, sb.st_mode | S_IXALL);	/* be sure, chmod a+x */
+	close(fd);
 	if (Verbose)
 	    printf("Running requirements file first for %s..\n", Plist.name);
 	if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, Plist.name)) {
@@ -441,8 +444,10 @@ pkg_do(char *pkg)
     }
 
     /* If we're really installing, and have an installation file, run it */
-    if (!NoInstall && fexists(pre_script)) {
-	vsystem("/bin/chmod +x %s", pre_script);	/* make sure */
+    if (!NoInstall && (fd = open(pre_script, O_RDWR)) != -1) {
+	fstat(fd, &sb);
+	fchmod(fd, sb.st_mode | S_IXALL);	/* be sure, chmod a+x */
+	close(fd);
 	if (Verbose)
 	    printf("Running pre-install for %s..\n", Plist.name);
 	if (!Fake && vsystem("./%s %s %s", pre_script, Plist.name, pre_arg)) {
@@ -470,8 +475,10 @@ pkg_do(char *pkg)
     }
 
     /* Run the installation script one last time? */
-    if (!NoInstall && fexists(post_script)) {
-	vsystem("/bin/chmod +x %s", post_script);	/* make sure */
+    if (!NoInstall && (fd = open(post_script, O_RDWR)) != -1) {
+	fstat(fd, &sb);
+	fchmod(fd, sb.st_mode | S_IXALL);	/* be sure, chmod a+x */
+	close(fd);
 	if (Verbose)
 	    printf("Running post-install for %s..\n", Plist.name);
 	if (!Fake && vsystem("./%s %s %s", post_script, Plist.name, post_arg)) {
@@ -503,7 +510,10 @@ pkg_do(char *pkg)
 	    goto success;	/* close enough for government work */
 	}
 	/* Make sure pkg_info can read the entry */
-	vsystem("/bin/chmod a+rx %s", LogDir);
+	fd = open(LogDir, O_RDWR);
+	fstat(fd, &sb);
+	fchmod(fd, sb.st_mode | S_IRALL | S_IXALL);	/* be sure, chmod a+rx */
+	close(fd);
 	move_file(".", DESC_FNAME, LogDir);
 	move_file(".", COMMENT_FNAME, LogDir);
 	if (fexists(INSTALL_FNAME))

Modified: head/usr.sbin/pkg_install/delete/perform.c
==============================================================================
--- head/usr.sbin/pkg_install/delete/perform.c	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/delete/perform.c	Thu Apr  1 14:27:29 2010	(r206043)
@@ -132,6 +132,8 @@ pkg_do(char *pkg)
     const char *post_script, *pre_arg, *post_arg;
     struct reqr_by_entry *rb_entry;
     struct reqr_by_head *rb_list;
+    int fd;
+    struct stat sb;
 
     if (!pkg || !(len = strlen(pkg)))
 	return 1;
@@ -221,10 +223,12 @@ pkg_do(char *pkg)
 
     setenv(PKG_PREFIX_VNAME, p->name, 1);
 
-    if (fexists(REQUIRE_FNAME)) {
+    if ((fd = open(REQUIRE_FNAME, O_RDWR)) != -1) {
+	fstat(fd, &sb);
+	fchmod(fd, sb.st_mode | S_IXALL);       /* be sure, chmod a+x */
+	close(fd);
 	if (Verbose)
 	    printf("Executing 'require' script.\n");
-	vsystem("/bin/chmod +x %s", REQUIRE_FNAME);	/* be sure */
 	if (vsystem("./%s %s DEINSTALL", REQUIRE_FNAME, pkg)) {
 	    warnx("package %s fails requirements %s", pkg,
 		   Force ? "" : "- not deleted");
@@ -250,11 +254,13 @@ pkg_do(char *pkg)
 	post_script = pre_arg = post_arg = NULL;
     }
 
-    if (!NoDeInstall && pre_script != NULL && fexists(pre_script)) {
+    if (!NoDeInstall && pre_script != NULL && (fd = open(pre_script, O_RDWR)) != -1) {
 	if (Fake)
 	    printf("Would execute de-install script at this point.\n");
 	else {
-	    vsystem("/bin/chmod +x %s", pre_script);	/* make sure */
+	    fstat(fd, &sb);
+	    fchmod(fd, sb.st_mode | S_IXALL);       /* be sure, chmod a+x */
+	    close(fd);
 	    if (vsystem("./%s %s %s", pre_script, pkg, pre_arg)) {
 		warnx("deinstall script returned error status");
 		if (!Force)
@@ -326,11 +332,13 @@ pkg_do(char *pkg)
  	return 1;
     }
 
-    if (!NoDeInstall && post_script != NULL && fexists(post_script)) {
+    if (!NoDeInstall && post_script != NULL && (fd = open(post_script, O_RDWR)) != -1) {
  	if (Fake)
  	    printf("Would execute post-deinstall script at this point.\n");
  	else {
- 	    vsystem("/bin/chmod +x %s", post_script);	/* make sure */
+	    fstat(fd, &sb);
+	    fchmod(fd, sb.st_mode | S_IXALL);       /* be sure, chmod a+x */
+	    close(fd);
  	    if (vsystem("./%s %s %s", post_script, pkg, post_arg)) {
  		warnx("post-deinstall script returned error status");
  		if (!Force)

Modified: head/usr.sbin/pkg_install/lib/file.c
==============================================================================
--- head/usr.sbin/pkg_install/lib/file.c	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/lib/file.c	Thu Apr  1 14:27:29 2010	(r206043)
@@ -31,10 +31,13 @@ __FBSDID("$FreeBSD$");
 Boolean
 fexists(const char *fname)
 {
-    struct stat dummy;
-    if (!lstat(fname, &dummy))
-	return TRUE;
-    return FALSE;
+    int fd;
+
+    if ((fd = open(fname, O_RDONLY)) == -1)
+	return FALSE;
+
+    close(fd);
+    return TRUE;
 }
 
 /* Quick check to see if something is a directory or symlink to a directory */
@@ -279,17 +282,23 @@ copy_file(const char *dir, const char *f
 }
 
 void
-move_file(const char *dir, const char *fname, const char *to)
+move_file(const char *dir, const char *fname, const char *tdir)
 {
-    char cmd[FILENAME_MAX];
+    char from[FILENAME_MAX];
+    char to[FILENAME_MAX];
 
     if (fname[0] == '/')
-	snprintf(cmd, FILENAME_MAX, "/bin/mv %s %s", fname, to);
+	strncpy(from, fname, FILENAME_MAX);
     else
-	snprintf(cmd, FILENAME_MAX, "/bin/mv %s/%s %s", dir, fname, to);
-    if (vsystem(cmd)) {
-	cleanup(0);
-	errx(2, "%s: could not perform '%s'", __func__, cmd);
+	snprintf(from, FILENAME_MAX, "%s/%s", dir, fname);
+
+    snprintf(to, FILENAME_MAX, "%s/%s", tdir, fname);
+
+    if (rename(from, to) == -1) {
+        if (vsystem("/bin/mv %s %s", from, to)) {
+	    cleanup(0);
+	    errx(2, "%s: could not move '%s' to '%s'", __func__, from, to);
+	}
     }
 }
 

Modified: head/usr.sbin/pkg_install/lib/lib.h
==============================================================================
--- head/usr.sbin/pkg_install/lib/lib.h	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/lib/lib.h	Thu Apr  1 14:27:29 2010	(r206043)
@@ -28,6 +28,7 @@
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/queue.h>
+#include <sys/utsname.h>
 #include <ctype.h>
 #include <dirent.h>
 #include <stdarg.h>
@@ -51,6 +52,11 @@
 #define YES		2
 #define NO		1
 
+/* Some more stat macros. */
+#define S_IRALL		0000444
+#define S_IWALL		0000222
+#define S_IXALL		0000111
+
 /* Usually "rm", but often "echo" during debugging! */
 #define REMOVE_CMD	"/bin/rm"
 
@@ -84,18 +90,6 @@
 #define DISPLAY_FNAME		"+DISPLAY"
 #define MTREE_FNAME		"+MTREE_DIRS"
 
-#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000
-#define INDEX_FNAME		"INDEX-9"
-#elif defined(__FreeBSD_version) && __FreeBSD_version >= 800000
-#define INDEX_FNAME		"INDEX-8"
-#elif defined(__FreeBSD_version) && __FreeBSD_version >= 700000
-#define INDEX_FNAME		"INDEX-7"
-#elif defined(__FreeBSD_version) && __FreeBSD_version >= 600000
-#define INDEX_FNAME		"INDEX-6"
-#else
-#define INDEX_FNAME		"INDEX"
-#endif
-
 #define CMD_CHAR		'@'	/* prefix for extended PLIST cmd */
 
 /* The name of the "prefix" environment variable given to scripts */
@@ -105,7 +99,7 @@
  * Version of the package tools - increase whenever you make a change
  * in the code that is not cosmetic only.
  */
-#define PKG_INSTALL_VERSION	20100122
+#define PKG_INSTALL_VERSION	20100401
 
 #define PKG_WRAPCONF_FNAME	"/var/db/pkg_install.conf"
 #define main(argc, argv)	real_main(argc, argv)

Modified: head/usr.sbin/pkg_install/lib/match.c
==============================================================================
--- head/usr.sbin/pkg_install/lib/match.c	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/lib/match.c	Thu Apr  1 14:27:29 2010	(r206043)
@@ -267,7 +267,7 @@ matchallbyorigin(const char **origins, i
 	 */
 	if (isemptydir(tmp))
 	    continue;
-	snprintf(tmp, PATH_MAX, "%s/%s", tmp, CONTENTS_FNAME);
+	strncat(tmp, "/" CONTENTS_FNAME, PATH_MAX);
 	fp = fopen(tmp, "r");
 	if (fp == NULL) {
 	    warnx("the package info for package '%s' is corrupt", installed[i]);

Modified: head/usr.sbin/pkg_install/lib/pen.c
==============================================================================
--- head/usr.sbin/pkg_install/lib/pen.c	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/lib/pen.c	Thu Apr  1 14:27:29 2010	(r206043)
@@ -113,10 +113,6 @@ make_playpen(char *pen, off_t sz)
 	cleanup(0);
 	errx(2, "%s: can't mktemp '%s'", __func__, pen);
     }
-    if (chmod(pen, 0700) == FAIL) {
-	cleanup(0);
-	errx(2, "%s: can't mkdir '%s'", __func__, pen);
-    }
 
     if (Verbose) {
 	if (sz) {

Modified: head/usr.sbin/pkg_install/lib/url.c
==============================================================================
--- head/usr.sbin/pkg_install/lib/url.c	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/lib/url.c	Thu Apr  1 14:27:29 2010	(r206043)
@@ -108,6 +108,10 @@ fileGetURL(const char *base, const char 
     if ((ftp = fetchGetURL(fname, Verbose ? "v" : NULL)) == NULL) {
 	printf("Error: Unable to get %s: %s\n",
 	       fname, fetchLastErrString);
+	/* If the fetch fails, yank the package. */
+	if (keep_package && unlink(pkg) < 0 && Verbose) {
+	    warnx("failed to remove partially fetched package: %s", pkg);
+	}
 	return NULL;
     }
 

Modified: head/usr.sbin/pkg_install/version/perform.c
==============================================================================
--- head/usr.sbin/pkg_install/version/perform.c	Thu Apr  1 13:27:27 2010	(r206042)
+++ head/usr.sbin/pkg_install/version/perform.c	Thu Apr  1 14:27:29 2010	(r206043)
@@ -35,28 +35,41 @@ static int pkg_do(char *);
 static void show_version(Package, const char *, const char *);
 
 /*
- * This is the traditional pkg_perform, except that the argument is _not_
- * a list of packages. It is the index file from the command line.
+ * This is the traditional pkg_perform, except that the argument is _not_ a
+ * list of packages. It is the index file from the command line.
  *
- * We loop over the installed packages, matching them with the -s flag
- * if needed and calling pkg_do(). Before hand we set up a few things,
- * and after we tear them down...
+ * We loop over the installed packages, matching them with the -s flag if
+ * needed and calling pkg_do(). Beforehand we set up a few things, and after
+ * we tear them down...
+ *
+ * Returns 0 on success, non-zero on failure, corresponding to the number of
+ * failed attempts to access the INDEX.
  */
 int
 pkg_perform(char **indexarg)
 {
     char **pkgs, *pat[2], **patterns;
     struct index_entry *ie;
-    int i, err_cnt = 0;
+    int i, err_cnt = 0, rel_major_ver;
     int MatchType;
 
+    struct utsname u;
+
+    if (uname(&u) == -1) {
+	warn("%s(): failed to determine uname information", __func__);
+	return 1;
+    } else if ((rel_major_ver = (int) strtol(u.release, NULL, 10)) <= 0) {
+
+    }
+
     /*
      * Try to find and open the INDEX. We only check IndexFile != NULL
      * later, if we actually need the INDEX.
      */
-    if (*indexarg == NULL)
-	snprintf(IndexPath, sizeof(IndexPath), "%s/%s", PORTS_DIR, INDEX_FNAME);
-    else
+    if (*indexarg == NULL) {
+	snprintf(IndexPath, sizeof(IndexPath), "%s/INDEX-%d", PORTS_DIR,
+	    rel_major_ver);
+    } else
 	strlcpy(IndexPath, *indexarg, sizeof(IndexPath));
     if (isURL(IndexPath))
 	IndexFile = fetchGetURL(IndexPath, "");


More information about the svn-src-head mailing list