svn commit: r235112 - in stable/9/usr.sbin: . pkg

Baptiste Daroussin bapt at FreeBSD.org
Sun May 6 22:50:07 UTC 2012


Author: bapt
Date: Sun May  6 22:50:07 2012
New Revision: 235112
URL: http://svn.freebsd.org/changeset/base/235112

Log:
  MFC r234313 r234315 r234322 r234351 r234870
  
  bootstrap tool for pkgng.
  it respects PACKAGESITE, PACKAGEROOT, and a new environment variable ABI (if a
  user want to use a different API from the base one for its packages)
  it has no man page on purpose to avoid hidding the pkg(8) man page from the
  pkgng package.
  for now uses pkgbeta.FreeBSD.org as default mirror to find its package
  it respects MK_PKGTOOLS
  
  Approved by:	des (mentor)

Added:
  stable/9/usr.sbin/pkg/
     - copied from r234313, head/usr.sbin/pkg/
Modified:
  stable/9/usr.sbin/Makefile
  stable/9/usr.sbin/pkg/Makefile
  stable/9/usr.sbin/pkg/pkg.c
Directory Properties:
  stable/9/   (props changed)
  stable/9/usr.sbin/   (props changed)

Modified: stable/9/usr.sbin/Makefile
==============================================================================
--- stable/9/usr.sbin/Makefile	Sun May  6 22:36:10 2012	(r235111)
+++ stable/9/usr.sbin/Makefile	Sun May  6 22:50:07 2012	(r235112)
@@ -256,6 +256,7 @@ SUBDIR+=	ftp-proxy
 
 .if ${MK_PKGTOOLS} != "no"
 SUBDIR+=	pkg_install
+SUBDIR+=	pkg
 .endif
 
 # XXX MK_TOOLCHAIN?

Modified: stable/9/usr.sbin/pkg/Makefile
==============================================================================
--- head/usr.sbin/pkg/Makefile	Sun Apr 15 15:13:36 2012	(r234313)
+++ stable/9/usr.sbin/pkg/Makefile	Sun May  6 22:50:07 2012	(r235112)
@@ -4,6 +4,7 @@ PROG=	pkg
 SRC=	pkg.c
 
 NO_MAN=	yes
+DPADD=	${LIBARCHIVE} ${LIBELF} ${LIBFETCH}
 LDADD=	-larchive -lelf -lfetch
 
 .include <bsd.prog.mk>

Modified: stable/9/usr.sbin/pkg/pkg.c
==============================================================================
--- head/usr.sbin/pkg/pkg.c	Sun Apr 15 15:13:36 2012	(r234313)
+++ stable/9/usr.sbin/pkg/pkg.c	Sun May  6 22:50:07 2012	(r235112)
@@ -27,11 +27,10 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <sys/param.h>
 #include <sys/elf_common.h>
 #include <sys/endian.h>
+#include <sys/wait.h>
 
 #include <archive.h>
 #include <archive_entry.h>
@@ -39,24 +38,24 @@ __FBSDID("$FreeBSD$");
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <fetch.h>
 #include <gelf.h>
+#include <paths.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-#include <fetch.h>
 
 #include "elf_tables.h"
 
 #define _LOCALBASE "/usr/local"
 #define _PKGS_URL "http://pkgbeta.FreeBSD.org"
-#define _DEFAULT_TMP "/tmp"
 
 static const char *
-elf_corres_to_string(struct _elf_corres* m, int e)
+elf_corres_to_string(struct _elf_corres *m, int e)
 {
-	int i = 0;
+	int i;
 
 	for (i = 0; m[i].string != NULL; i++)
 		if (m[i].elf_nb == e)
@@ -69,29 +68,30 @@ static int
 pkg_get_myabi(char *dest, size_t sz)
 {
 	Elf *elf;
-	GElf_Ehdr elfhdr;
-	GElf_Shdr shdr;
 	Elf_Data *data;
 	Elf_Note note;
 	Elf_Scn *scn;
 	char *src, *osname;
 	const char *abi;
+	GElf_Ehdr elfhdr;
+	GElf_Shdr shdr;
 	int fd, i, ret;
 	uint32_t version;
 
 	version = 0;
-	ret = 0;
+	ret = -1;
 	scn = NULL;
 	abi = NULL;
 
 	if (elf_version(EV_CURRENT) == EV_NONE) {
-		warnx("ELF library initialization failed: %s", elf_errmsg(-1));
-		return -1;
+		warnx("ELF library initialization failed: %s",
+		    elf_errmsg(-1));
+		return (-1);
 	}
 
 	if ((fd = open("/bin/sh", O_RDONLY)) < 0) {
 		warn("open()");
-		return -1;
+		return (-1);
 	}
 
 	if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
@@ -119,13 +119,13 @@ pkg_get_myabi(char *dest, size_t sz)
 
 	if (scn == NULL) {
 		ret = -1;
-		warn("fail to get the note section");
+		warn("failed to get the note section");
 		goto cleanup;
 	}
 
 	data = elf_getdata(scn, NULL);
 	src = data->d_buf;
-	while (1) {
+	for (;;) {
 		memcpy(&note, src, sizeof(Elf_Note));
 		src += sizeof(Elf_Note);
 		if (note.n_type == NT_VERSION)
@@ -143,52 +143,50 @@ pkg_get_myabi(char *dest, size_t sz)
 		osname[i] = (char)tolower(osname[i]);
 
 	snprintf(dest, sz, "%s:%d:%s:%s",
-	    osname,
-	    version / 100000,
-	    elf_corres_to_string(mach_corres, (int) elfhdr.e_machine),
+	    osname, version / 100000,
+	    elf_corres_to_string(mach_corres, (int)elfhdr.e_machine),
 	    elf_corres_to_string(wordsize_corres,
-	        (int)elfhdr.e_ident[EI_CLASS]));
+	    (int)elfhdr.e_ident[EI_CLASS]));
+
+	ret = 0;
 
 	switch (elfhdr.e_machine) {
-		case EM_ARM:
-			snprintf(dest + strlen(dest), sz - strlen(dest),
-			    ":%s:%s:%s",
-			    elf_corres_to_string(endian_corres,
-			        (int) elfhdr.e_ident[EI_DATA]),
-			    (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ?
-			        "eabi" : "oabi",
-			    (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ?
-			        "softfp" : "vfp");
+	case EM_ARM:
+		snprintf(dest + strlen(dest), sz - strlen(dest),
+		    ":%s:%s:%s", elf_corres_to_string(endian_corres,
+		    (int)elfhdr.e_ident[EI_DATA]),
+		    (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ?
+		    "eabi" : "oabi",
+		    (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ?
+		    "softfp" : "vfp");
+		break;
+	case EM_MIPS:
+		/*
+		 * this is taken from binutils sources:
+		 * include/elf/mips.h
+		 * mapping is figured out from binutils:
+		 * gas/config/tc-mips.c
+		 */
+		switch (elfhdr.e_flags & EF_MIPS_ABI) {
+		case E_MIPS_ABI_O32:
+			abi = "o32";
 			break;
-		case EM_MIPS:
-			/*
-			 * this is taken from binutils sources:
-			 * include/elf/mips.h
-			 * mapping is figured out from binutils:
-			 * gas/config/tc-mips.c
-			 */
-			switch (elfhdr.e_flags & EF_MIPS_ABI) {
-				case E_MIPS_ABI_O32:
-					abi = "o32";
-					break;
-				case E_MIPS_ABI_N32:
-					abi = "n32";
-					break;
-				default:
-					if (elfhdr.e_ident[EI_DATA] ==
-					    ELFCLASS32)
-						abi = "o32";
-					else if (elfhdr.e_ident[EI_DATA] ==
-					    ELFCLASS64)
-						abi = "n64";
-					break;
-			}
-			snprintf(dest + strlen(dest), sz - strlen(dest),
-			    ":%s:%s",
-			    elf_corres_to_string(endian_corres,
-			        (int) elfhdr.e_ident[EI_DATA]),
-			    abi);
+		case E_MIPS_ABI_N32:
+			abi = "n32";
 			break;
+		default:
+			if (elfhdr.e_ident[EI_DATA] ==
+			    ELFCLASS32)
+				abi = "o32";
+			else if (elfhdr.e_ident[EI_DATA] ==
+			    ELFCLASS64)
+				abi = "n64";
+			break;
+		}
+		snprintf(dest + strlen(dest), sz - strlen(dest),
+		    ":%s:%s", elf_corres_to_string(endian_corres,
+		    (int)elfhdr.e_ident[EI_DATA]), abi);
+		break;
 	}
 
 cleanup:
@@ -207,17 +205,22 @@ extract_pkg_static(int fd, char *p, int 
 	char *end;
 	int ret, r;
 
-	ret = 0;
+	ret = -1;
 	a = archive_read_new();
+	if (a == NULL) {
+		warn("archive_read_new");
+		return (ret);
+	}
 	archive_read_support_compression_all(a);
 	archive_read_support_format_tar(a);
 
-	lseek(fd, 0, 0);
+	if (lseek(fd, 0, 0) == -1) {
+		warn("lseek");
+		goto cleanup;
+	}
 
 	if (archive_read_open_fd(a, fd, 4096) != ARCHIVE_OK) {
-		warnx("archive_read_open_fd: %s",
-		    archive_error_string(a));
-		ret = -1;
+		warnx("archive_read_open_fd: %s", archive_error_string(a));
 		goto cleanup;
 	}
 
@@ -229,22 +232,22 @@ extract_pkg_static(int fd, char *p, int 
 
 		if (strcmp(end, "/pkg-static") == 0) {
 			r = archive_read_extract(a, ae,
-			    ARCHIVE_EXTRACT_OWNER |ARCHIVE_EXTRACT_PERM|
-			    ARCHIVE_EXTRACT_TIME  |ARCHIVE_EXTRACT_ACL |
-			    ARCHIVE_EXTRACT_FFLAGS|ARCHIVE_EXTRACT_XATTR);
-			snprintf(p, sz, archive_entry_pathname(ae));
+			    ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM |
+			    ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL |
+			    ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR);
+			strlcpy(p, archive_entry_pathname(ae), sz);
 			break;
 		}
 	}
 
-	if (r != ARCHIVE_OK) {
+	if (r == ARCHIVE_OK)
+		ret = 0;
+	else
 		warnx("fail to extract pkg-static");
-		ret = -1;
-	}
 
 cleanup:
 	archive_read_finish(a);
-	return ret;
+	return (ret);
 
 }
 
@@ -255,129 +258,151 @@ install_pkg_static(char *path, char *pkg
 	pid_t pid;
 
 	switch ((pid = fork())) {
-		case -1:
-			return (-1);
-		case 0:
-			execl(path, "pkg-static", "add", pkgpath, (char *)NULL);
-			_exit(1); /* NOT REACHED */
-		default:
-			break;
+	case -1:
+		return (-1);
+	case 0:
+		execl(path, "pkg-static", "add", pkgpath, (char *)NULL);
+		_exit(1);
+	default:
+		break;
 	}
 
-	while (waitpid(pid, &pstat, 0) == -1) {
+	while (waitpid(pid, &pstat, 0) == -1)
 		if (errno != EINTR)
 			return (-1);
-	}
 
-	return (WEXITSTATUS(pstat));
+	if (WEXITSTATUS(pstat))
+		return (WEXITSTATUS(pstat));
+	else if (WIFSIGNALED(pstat))
+		return (128 & (WTERMSIG(pstat)));
+	return (pstat);
 }
 
 static int
 bootstrap_pkg(void)
 {
-	struct url_stat st;
 	FILE *remote;
-	time_t begin_dl;
-	time_t now;
-	time_t last = 0;
+	FILE *config;
+	char *site;
 	char url[MAXPATHLEN];
+	char conf[MAXPATHLEN];
 	char abi[BUFSIZ];
 	char tmppkg[MAXPATHLEN];
 	char buf[10240];
 	char pkgstatic[MAXPATHLEN];
 	int fd, retry, ret;
+	struct url_stat st;
 	off_t done, r;
+	time_t now;
+	time_t last;
 
 	done = 0;
-	ret = 0;
-	retry = 3;
+	last = 0;
+	ret = -1;
 	remote = NULL;
+	config = NULL;
 
-	printf("Bootstraping pkg please wait\n");
+	printf("Bootstrapping pkg please wait\n");
 
 	if (pkg_get_myabi(abi, MAXPATHLEN) != 0) {
-		warnx("fail to determine my abi");
-		return -1;
+		warnx("failed to determine the system ABI");
+		return (-1);
 	}
 
-	if (getenv("PACKAGESITE") != NULL) {
-		snprintf(url, MAXPATHLEN, "%s/pkg.txz",
-		    getenv("PACKAGESITE"));
-	} else {
+	if (getenv("PACKAGESITE") != NULL)
+		snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz", getenv("PACKAGESITE"));
+	else
 		snprintf(url, MAXPATHLEN, "%s/%s/latest/Latest/pkg.txz",
 		    getenv("PACKAGEROOT") ? getenv("PACKAGEROOT") : _PKGS_URL,
 		    getenv("ABI") ? getenv("ABI") : abi);
-	}
 
 	snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX",
-	    getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
+	    getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP);
 
 	if ((fd = mkstemp(tmppkg)) == -1) {
 		warn("mkstemp()");
-		return -1;
+		return (-1);
 	}
 
-	while (remote == NULL) {
+	retry = 3;
+	do {
 		remote = fetchXGetURL(url, &st, "");
-		if (remote == NULL) {
-			--retry;
-			if (retry == 0) {
-				warnx("Error fetching %s: %s", url,
-				    fetchLastErrString);
-				ret = 1;
-				goto cleanup;
-			}
+		if (remote == NULL)
 			sleep(1);
-		}
-	}
+	} while (remote == NULL && retry-- > 0);
+
+	if (remote == NULL)
+		goto fetchfail;
 
-	begin_dl = time(NULL);
 	while (done < st.size) {
 		if ((r = fread(buf, 1, sizeof(buf), remote)) < 1)
 			break;
 
 		if (write(fd, buf, r) != r) {
 			warn("write()");
-			ret = -1;
 			goto cleanup;
 		}
 
 		done += r;
 		now = time(NULL);
-		if (now > last || done == st.size) {
+		if (now > last || done == st.size)
 			last = now;
-		}
 	}
 
-	if (ferror(remote)) {
-		warnx("Error fetching %s: %s", url,
-		    fetchLastErrString);
-		ret = 1;
-		goto cleanup;
-	}
+	if (ferror(remote))
+		goto fetchfail;
 
 	if ((ret = extract_pkg_static(fd, pkgstatic, MAXPATHLEN)) == 0)
 		ret = install_pkg_static(pkgstatic, tmppkg);
 
+	snprintf(conf, MAXPATHLEN, "%s/etc/pkg.conf",
+	    getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);
+
+	if (access(conf, R_OK) == -1) {
+		site = strrchr(url, '/');
+		if (site == NULL)
+			goto cleanup;
+		site[0] = '\0';
+		site = strrchr(url, '/');
+		if (site == NULL)
+			goto cleanup;
+		site[0] = '\0';
+
+		config = fopen(conf, "w+");
+		if (config == NULL)
+			goto cleanup;
+		fprintf(config, "packagesite: %s", url);
+		fclose(config);
+	}
+
+	goto cleanup;
+
+fetchfail:
+	warnx("Error fetching %s: %s", url, fetchLastErrString);
+
 cleanup:
+	if (remote != NULL)
+		fclose(remote);
 	close(fd);
 	unlink(tmppkg);
 
-	return 0;
+	return (ret);
 }
 
 int
-main(__unused int argc, char * argv[])
+main(__unused int argc, char *argv[])
 {
 	char pkgpath[MAXPATHLEN];
 
 	snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg",
-	    getenv("LOCALBASE") ? getenv("LOCALBASE"): _LOCALBASE);
+	    getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);
 
 	if (access(pkgpath, X_OK) == -1)
-		bootstrap_pkg();
+		if (bootstrap_pkg() != 0)
+			exit(EXIT_FAILURE);
 
 	execv(pkgpath, argv);
 
-	return (EXIT_SUCCESS);
+	/* NOT REACHED */
+	return (EXIT_FAILURE);
 }


More information about the svn-src-stable-9 mailing list