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(¬e, 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