13aa4b42aSBaptiste Daroussin /*- 23aa4b42aSBaptiste Daroussin * Copyright (c) 2012 Baptiste Daroussin <bapt@FreeBSD.org> 33aa4b42aSBaptiste Daroussin * All rights reserved. 43aa4b42aSBaptiste Daroussin * 53aa4b42aSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 63aa4b42aSBaptiste Daroussin * modification, are permitted provided that the following conditions 73aa4b42aSBaptiste Daroussin * are met: 83aa4b42aSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 93aa4b42aSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 103aa4b42aSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 113aa4b42aSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 123aa4b42aSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 133aa4b42aSBaptiste Daroussin * 143aa4b42aSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 153aa4b42aSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 163aa4b42aSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 173aa4b42aSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 183aa4b42aSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 193aa4b42aSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 203aa4b42aSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 213aa4b42aSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 223aa4b42aSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 233aa4b42aSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 243aa4b42aSBaptiste Daroussin * SUCH DAMAGE. 253aa4b42aSBaptiste Daroussin */ 263aa4b42aSBaptiste Daroussin 273aa4b42aSBaptiste Daroussin #include <sys/cdefs.h> 283aa4b42aSBaptiste Daroussin __FBSDID("$FreeBSD$"); 293aa4b42aSBaptiste Daroussin 303aa4b42aSBaptiste Daroussin #include <sys/param.h> 313aa4b42aSBaptiste Daroussin #include <sys/elf_common.h> 323aa4b42aSBaptiste Daroussin #include <sys/endian.h> 333b05c2a8SBaptiste Daroussin #include <sys/wait.h> 343aa4b42aSBaptiste Daroussin 353aa4b42aSBaptiste Daroussin #include <archive.h> 363aa4b42aSBaptiste Daroussin #include <archive_entry.h> 373aa4b42aSBaptiste Daroussin #include <ctype.h> 383aa4b42aSBaptiste Daroussin #include <err.h> 393aa4b42aSBaptiste Daroussin #include <errno.h> 403aa4b42aSBaptiste Daroussin #include <fcntl.h> 413b05c2a8SBaptiste Daroussin #include <fetch.h> 423aa4b42aSBaptiste Daroussin #include <gelf.h> 43*a6454741SBaptiste Daroussin #include <paths.h> 443aa4b42aSBaptiste Daroussin #include <stdlib.h> 453aa4b42aSBaptiste Daroussin #include <stdio.h> 463aa4b42aSBaptiste Daroussin #include <string.h> 473aa4b42aSBaptiste Daroussin #include <time.h> 483aa4b42aSBaptiste Daroussin #include <unistd.h> 493aa4b42aSBaptiste Daroussin 503aa4b42aSBaptiste Daroussin #include "elf_tables.h" 513aa4b42aSBaptiste Daroussin 523aa4b42aSBaptiste Daroussin #define _LOCALBASE "/usr/local" 533aa4b42aSBaptiste Daroussin #define _PKGS_URL "http://pkgbeta.FreeBSD.org" 543aa4b42aSBaptiste Daroussin 553aa4b42aSBaptiste Daroussin static const char * 563aa4b42aSBaptiste Daroussin elf_corres_to_string(struct _elf_corres *m, int e) 573aa4b42aSBaptiste Daroussin { 58ce36f45dSBaptiste Daroussin int i; 593aa4b42aSBaptiste Daroussin 603aa4b42aSBaptiste Daroussin for (i = 0; m[i].string != NULL; i++) 613aa4b42aSBaptiste Daroussin if (m[i].elf_nb == e) 623aa4b42aSBaptiste Daroussin return (m[i].string); 633aa4b42aSBaptiste Daroussin 643aa4b42aSBaptiste Daroussin return ("unknown"); 653aa4b42aSBaptiste Daroussin } 663aa4b42aSBaptiste Daroussin 673aa4b42aSBaptiste Daroussin static int 683aa4b42aSBaptiste Daroussin pkg_get_myabi(char *dest, size_t sz) 693aa4b42aSBaptiste Daroussin { 703aa4b42aSBaptiste Daroussin Elf *elf; 713aa4b42aSBaptiste Daroussin Elf_Data *data; 723aa4b42aSBaptiste Daroussin Elf_Note note; 733aa4b42aSBaptiste Daroussin Elf_Scn *scn; 743aa4b42aSBaptiste Daroussin char *src, *osname; 753aa4b42aSBaptiste Daroussin const char *abi; 76*a6454741SBaptiste Daroussin GElf_Ehdr elfhdr; 77*a6454741SBaptiste Daroussin GElf_Shdr shdr; 783aa4b42aSBaptiste Daroussin int fd, i, ret; 793aa4b42aSBaptiste Daroussin uint32_t version; 803aa4b42aSBaptiste Daroussin 813aa4b42aSBaptiste Daroussin version = 0; 82*a6454741SBaptiste Daroussin ret = -1; 833aa4b42aSBaptiste Daroussin scn = NULL; 843aa4b42aSBaptiste Daroussin abi = NULL; 853aa4b42aSBaptiste Daroussin 863aa4b42aSBaptiste Daroussin if (elf_version(EV_CURRENT) == EV_NONE) { 873b05c2a8SBaptiste Daroussin warnx("ELF library initialization failed: %s", 883b05c2a8SBaptiste Daroussin elf_errmsg(-1)); 893b05c2a8SBaptiste Daroussin return (-1); 903aa4b42aSBaptiste Daroussin } 913aa4b42aSBaptiste Daroussin 923aa4b42aSBaptiste Daroussin if ((fd = open("/bin/sh", O_RDONLY)) < 0) { 933aa4b42aSBaptiste Daroussin warn("open()"); 943b05c2a8SBaptiste Daroussin return (-1); 953aa4b42aSBaptiste Daroussin } 963aa4b42aSBaptiste Daroussin 973aa4b42aSBaptiste Daroussin if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { 983aa4b42aSBaptiste Daroussin ret = -1; 993aa4b42aSBaptiste Daroussin warnx("elf_begin() failed: %s.", elf_errmsg(-1)); 1003aa4b42aSBaptiste Daroussin goto cleanup; 1013aa4b42aSBaptiste Daroussin } 1023aa4b42aSBaptiste Daroussin 1033aa4b42aSBaptiste Daroussin if (gelf_getehdr(elf, &elfhdr) == NULL) { 1043aa4b42aSBaptiste Daroussin ret = -1; 1053aa4b42aSBaptiste Daroussin warn("getehdr() failed: %s.", elf_errmsg(-1)); 1063aa4b42aSBaptiste Daroussin goto cleanup; 1073aa4b42aSBaptiste Daroussin } 1083aa4b42aSBaptiste Daroussin 1093aa4b42aSBaptiste Daroussin while ((scn = elf_nextscn(elf, scn)) != NULL) { 1103aa4b42aSBaptiste Daroussin if (gelf_getshdr(scn, &shdr) != &shdr) { 1113aa4b42aSBaptiste Daroussin ret = -1; 1123aa4b42aSBaptiste Daroussin warn("getshdr() failed: %s.", elf_errmsg(-1)); 1133aa4b42aSBaptiste Daroussin goto cleanup; 1143aa4b42aSBaptiste Daroussin } 1153aa4b42aSBaptiste Daroussin 1163aa4b42aSBaptiste Daroussin if (shdr.sh_type == SHT_NOTE) 1173aa4b42aSBaptiste Daroussin break; 1183aa4b42aSBaptiste Daroussin } 1193aa4b42aSBaptiste Daroussin 1203aa4b42aSBaptiste Daroussin if (scn == NULL) { 1213aa4b42aSBaptiste Daroussin ret = -1; 122*a6454741SBaptiste Daroussin warn("failed to get the note section"); 1233aa4b42aSBaptiste Daroussin goto cleanup; 1243aa4b42aSBaptiste Daroussin } 1253aa4b42aSBaptiste Daroussin 1263aa4b42aSBaptiste Daroussin data = elf_getdata(scn, NULL); 1273aa4b42aSBaptiste Daroussin src = data->d_buf; 128ce36f45dSBaptiste Daroussin for (;;) { 1293aa4b42aSBaptiste Daroussin memcpy(¬e, src, sizeof(Elf_Note)); 1303aa4b42aSBaptiste Daroussin src += sizeof(Elf_Note); 1313aa4b42aSBaptiste Daroussin if (note.n_type == NT_VERSION) 1323aa4b42aSBaptiste Daroussin break; 1333aa4b42aSBaptiste Daroussin src += note.n_namesz + note.n_descsz; 1343aa4b42aSBaptiste Daroussin } 1353aa4b42aSBaptiste Daroussin osname = src; 1363aa4b42aSBaptiste Daroussin src += note.n_namesz; 1373aa4b42aSBaptiste Daroussin if (elfhdr.e_ident[EI_DATA] == ELFDATA2MSB) 1383aa4b42aSBaptiste Daroussin version = be32dec(src); 1393aa4b42aSBaptiste Daroussin else 1403aa4b42aSBaptiste Daroussin version = le32dec(src); 1413aa4b42aSBaptiste Daroussin 1423aa4b42aSBaptiste Daroussin for (i = 0; osname[i] != '\0'; i++) 1433aa4b42aSBaptiste Daroussin osname[i] = (char)tolower(osname[i]); 1443aa4b42aSBaptiste Daroussin 1453aa4b42aSBaptiste Daroussin snprintf(dest, sz, "%s:%d:%s:%s", 1463b05c2a8SBaptiste Daroussin osname, version / 100000, 1473aa4b42aSBaptiste Daroussin elf_corres_to_string(mach_corres, (int)elfhdr.e_machine), 1483aa4b42aSBaptiste Daroussin elf_corres_to_string(wordsize_corres, 1493aa4b42aSBaptiste Daroussin (int)elfhdr.e_ident[EI_CLASS])); 1503aa4b42aSBaptiste Daroussin 151*a6454741SBaptiste Daroussin ret = 0; 152*a6454741SBaptiste Daroussin 1533aa4b42aSBaptiste Daroussin switch (elfhdr.e_machine) { 1543aa4b42aSBaptiste Daroussin case EM_ARM: 1553aa4b42aSBaptiste Daroussin snprintf(dest + strlen(dest), sz - strlen(dest), 1563b05c2a8SBaptiste Daroussin ":%s:%s:%s", elf_corres_to_string(endian_corres, 1573aa4b42aSBaptiste Daroussin (int)elfhdr.e_ident[EI_DATA]), 1583aa4b42aSBaptiste Daroussin (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ? 1593aa4b42aSBaptiste Daroussin "eabi" : "oabi", 1603aa4b42aSBaptiste Daroussin (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ? 1613aa4b42aSBaptiste Daroussin "softfp" : "vfp"); 1623aa4b42aSBaptiste Daroussin break; 1633aa4b42aSBaptiste Daroussin case EM_MIPS: 1643aa4b42aSBaptiste Daroussin /* 1653aa4b42aSBaptiste Daroussin * this is taken from binutils sources: 1663aa4b42aSBaptiste Daroussin * include/elf/mips.h 1673aa4b42aSBaptiste Daroussin * mapping is figured out from binutils: 1683aa4b42aSBaptiste Daroussin * gas/config/tc-mips.c 1693aa4b42aSBaptiste Daroussin */ 1703aa4b42aSBaptiste Daroussin switch (elfhdr.e_flags & EF_MIPS_ABI) { 1713aa4b42aSBaptiste Daroussin case E_MIPS_ABI_O32: 1723aa4b42aSBaptiste Daroussin abi = "o32"; 1733aa4b42aSBaptiste Daroussin break; 1743aa4b42aSBaptiste Daroussin case E_MIPS_ABI_N32: 1753aa4b42aSBaptiste Daroussin abi = "n32"; 1763aa4b42aSBaptiste Daroussin break; 1773aa4b42aSBaptiste Daroussin default: 1783aa4b42aSBaptiste Daroussin if (elfhdr.e_ident[EI_DATA] == 1793aa4b42aSBaptiste Daroussin ELFCLASS32) 1803aa4b42aSBaptiste Daroussin abi = "o32"; 1813aa4b42aSBaptiste Daroussin else if (elfhdr.e_ident[EI_DATA] == 1823aa4b42aSBaptiste Daroussin ELFCLASS64) 1833aa4b42aSBaptiste Daroussin abi = "n64"; 1843aa4b42aSBaptiste Daroussin break; 1853aa4b42aSBaptiste Daroussin } 1863aa4b42aSBaptiste Daroussin snprintf(dest + strlen(dest), sz - strlen(dest), 1873b05c2a8SBaptiste Daroussin ":%s:%s", elf_corres_to_string(endian_corres, 1883b05c2a8SBaptiste Daroussin (int)elfhdr.e_ident[EI_DATA]), abi); 1893aa4b42aSBaptiste Daroussin break; 1903aa4b42aSBaptiste Daroussin } 1913aa4b42aSBaptiste Daroussin 1923aa4b42aSBaptiste Daroussin cleanup: 1933aa4b42aSBaptiste Daroussin if (elf != NULL) 1943aa4b42aSBaptiste Daroussin elf_end(elf); 1953aa4b42aSBaptiste Daroussin 1963aa4b42aSBaptiste Daroussin close(fd); 1973aa4b42aSBaptiste Daroussin return (ret); 1983aa4b42aSBaptiste Daroussin } 1993aa4b42aSBaptiste Daroussin 2003aa4b42aSBaptiste Daroussin static int 2013aa4b42aSBaptiste Daroussin extract_pkg_static(int fd, char *p, int sz) 2023aa4b42aSBaptiste Daroussin { 2033aa4b42aSBaptiste Daroussin struct archive *a; 2043aa4b42aSBaptiste Daroussin struct archive_entry *ae; 2053aa4b42aSBaptiste Daroussin char *end; 2063aa4b42aSBaptiste Daroussin int ret, r; 2073aa4b42aSBaptiste Daroussin 208*a6454741SBaptiste Daroussin ret = -1; 2093aa4b42aSBaptiste Daroussin a = archive_read_new(); 210*a6454741SBaptiste Daroussin if (a == NULL) { 211*a6454741SBaptiste Daroussin warn("archive_read_new"); 212*a6454741SBaptiste Daroussin return (ret); 213*a6454741SBaptiste Daroussin } 2143aa4b42aSBaptiste Daroussin archive_read_support_compression_all(a); 2153aa4b42aSBaptiste Daroussin archive_read_support_format_tar(a); 2163aa4b42aSBaptiste Daroussin 217*a6454741SBaptiste Daroussin if (lseek(fd, 0, 0) == -1) { 218*a6454741SBaptiste Daroussin warn("lseek"); 219*a6454741SBaptiste Daroussin goto cleanup; 220*a6454741SBaptiste Daroussin } 2213aa4b42aSBaptiste Daroussin 2223aa4b42aSBaptiste Daroussin if (archive_read_open_fd(a, fd, 4096) != ARCHIVE_OK) { 223*a6454741SBaptiste Daroussin warnx("archive_read_open_fd: %s", archive_error_string(a)); 2243aa4b42aSBaptiste Daroussin goto cleanup; 2253aa4b42aSBaptiste Daroussin } 2263aa4b42aSBaptiste Daroussin 2273aa4b42aSBaptiste Daroussin ae = NULL; 2283aa4b42aSBaptiste Daroussin while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK) { 2293aa4b42aSBaptiste Daroussin end = strrchr(archive_entry_pathname(ae), '/'); 2303aa4b42aSBaptiste Daroussin if (end == NULL) 2313aa4b42aSBaptiste Daroussin continue; 2323aa4b42aSBaptiste Daroussin 2333aa4b42aSBaptiste Daroussin if (strcmp(end, "/pkg-static") == 0) { 2343aa4b42aSBaptiste Daroussin r = archive_read_extract(a, ae, 2353aa4b42aSBaptiste Daroussin ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | 2363aa4b42aSBaptiste Daroussin ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL | 2373aa4b42aSBaptiste Daroussin ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR); 238*a6454741SBaptiste Daroussin strlcpy(p, archive_entry_pathname(ae), sz); 2393aa4b42aSBaptiste Daroussin break; 2403aa4b42aSBaptiste Daroussin } 2413aa4b42aSBaptiste Daroussin } 2423aa4b42aSBaptiste Daroussin 243*a6454741SBaptiste Daroussin if (r == ARCHIVE_OK) 244*a6454741SBaptiste Daroussin ret = 0; 245*a6454741SBaptiste Daroussin else 2463aa4b42aSBaptiste Daroussin warnx("fail to extract pkg-static"); 2473aa4b42aSBaptiste Daroussin 2483aa4b42aSBaptiste Daroussin cleanup: 2493aa4b42aSBaptiste Daroussin archive_read_finish(a); 2503b05c2a8SBaptiste Daroussin return (ret); 2513aa4b42aSBaptiste Daroussin 2523aa4b42aSBaptiste Daroussin } 2533aa4b42aSBaptiste Daroussin 2543aa4b42aSBaptiste Daroussin static int 2553aa4b42aSBaptiste Daroussin install_pkg_static(char *path, char *pkgpath) 2563aa4b42aSBaptiste Daroussin { 2573aa4b42aSBaptiste Daroussin int pstat; 2583aa4b42aSBaptiste Daroussin pid_t pid; 2593aa4b42aSBaptiste Daroussin 2603aa4b42aSBaptiste Daroussin switch ((pid = fork())) { 2613aa4b42aSBaptiste Daroussin case -1: 2623aa4b42aSBaptiste Daroussin return (-1); 2633aa4b42aSBaptiste Daroussin case 0: 264*a6454741SBaptiste Daroussin execl(path, "pkg-static", "add", pkgpath, (char *)NULL); 2653b05c2a8SBaptiste Daroussin _exit(1); 2663aa4b42aSBaptiste Daroussin default: 2673aa4b42aSBaptiste Daroussin break; 2683aa4b42aSBaptiste Daroussin } 2693aa4b42aSBaptiste Daroussin 270*a6454741SBaptiste Daroussin while (waitpid(pid, &pstat, 0) == -1) 2713aa4b42aSBaptiste Daroussin if (errno != EINTR) 2723aa4b42aSBaptiste Daroussin return (-1); 2733aa4b42aSBaptiste Daroussin 274*a6454741SBaptiste Daroussin if (WEXITSTATUS(pstat)) 2753aa4b42aSBaptiste Daroussin return (WEXITSTATUS(pstat)); 276*a6454741SBaptiste Daroussin else if (WIFSIGNALED(pstat)) 277*a6454741SBaptiste Daroussin return (128 & (WTERMSIG(pstat))); 278*a6454741SBaptiste Daroussin return (pstat); 2793aa4b42aSBaptiste Daroussin } 2803aa4b42aSBaptiste Daroussin 2813aa4b42aSBaptiste Daroussin static int 2823aa4b42aSBaptiste Daroussin bootstrap_pkg(void) 2833aa4b42aSBaptiste Daroussin { 2843aa4b42aSBaptiste Daroussin FILE *remote; 2853aa4b42aSBaptiste Daroussin char url[MAXPATHLEN]; 2863aa4b42aSBaptiste Daroussin char abi[BUFSIZ]; 2873aa4b42aSBaptiste Daroussin char tmppkg[MAXPATHLEN]; 2883aa4b42aSBaptiste Daroussin char buf[10240]; 2893aa4b42aSBaptiste Daroussin char pkgstatic[MAXPATHLEN]; 2903aa4b42aSBaptiste Daroussin int fd, retry, ret; 291*a6454741SBaptiste Daroussin struct url_stat st; 2923aa4b42aSBaptiste Daroussin off_t done, r; 293*a6454741SBaptiste Daroussin time_t begin_dl; 294*a6454741SBaptiste Daroussin time_t now; 295*a6454741SBaptiste Daroussin time_t last; 2963aa4b42aSBaptiste Daroussin 2973aa4b42aSBaptiste Daroussin done = 0; 298*a6454741SBaptiste Daroussin last = 0; 299*a6454741SBaptiste Daroussin ret = -1; 3003aa4b42aSBaptiste Daroussin remote = NULL; 3013aa4b42aSBaptiste Daroussin 302*a6454741SBaptiste Daroussin printf("Bootstrapping pkg please wait\n"); 3033aa4b42aSBaptiste Daroussin 3043aa4b42aSBaptiste Daroussin if (pkg_get_myabi(abi, MAXPATHLEN) != 0) { 305*a6454741SBaptiste Daroussin warnx("failed to determine the system ABI"); 3063b05c2a8SBaptiste Daroussin return (-1); 3073aa4b42aSBaptiste Daroussin } 3083aa4b42aSBaptiste Daroussin 309*a6454741SBaptiste Daroussin if (getenv("PACKAGESITE") != NULL) 310*a6454741SBaptiste Daroussin snprintf(url, MAXPATHLEN, "%s/pkg.txz", getenv("PACKAGESITE")); 311*a6454741SBaptiste Daroussin else 3123aa4b42aSBaptiste Daroussin snprintf(url, MAXPATHLEN, "%s/%s/latest/Latest/pkg.txz", 3133aa4b42aSBaptiste Daroussin getenv("PACKAGEROOT") ? getenv("PACKAGEROOT") : _PKGS_URL, 3143aa4b42aSBaptiste Daroussin getenv("ABI") ? getenv("ABI") : abi); 3153aa4b42aSBaptiste Daroussin 3163aa4b42aSBaptiste Daroussin snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX", 317*a6454741SBaptiste Daroussin getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); 3183aa4b42aSBaptiste Daroussin 3193aa4b42aSBaptiste Daroussin if ((fd = mkstemp(tmppkg)) == -1) { 3203aa4b42aSBaptiste Daroussin warn("mkstemp()"); 3213b05c2a8SBaptiste Daroussin return (-1); 3223aa4b42aSBaptiste Daroussin } 3233aa4b42aSBaptiste Daroussin 324*a6454741SBaptiste Daroussin retry = 3; 325*a6454741SBaptiste Daroussin do { 3263aa4b42aSBaptiste Daroussin remote = fetchXGetURL(url, &st, ""); 327*a6454741SBaptiste Daroussin if (remote == NULL) 3283aa4b42aSBaptiste Daroussin sleep(1); 329*a6454741SBaptiste Daroussin } while (remote == NULL && retry-- > 0); 330*a6454741SBaptiste Daroussin 331*a6454741SBaptiste Daroussin if (remote == NULL) 332*a6454741SBaptiste Daroussin goto fetchfail; 3333aa4b42aSBaptiste Daroussin 3343aa4b42aSBaptiste Daroussin begin_dl = time(NULL); 3353aa4b42aSBaptiste Daroussin while (done < st.size) { 3363aa4b42aSBaptiste Daroussin if ((r = fread(buf, 1, sizeof(buf), remote)) < 1) 3373aa4b42aSBaptiste Daroussin break; 3383aa4b42aSBaptiste Daroussin 3393aa4b42aSBaptiste Daroussin if (write(fd, buf, r) != r) { 3403aa4b42aSBaptiste Daroussin warn("write()"); 3413aa4b42aSBaptiste Daroussin goto cleanup; 3423aa4b42aSBaptiste Daroussin } 3433aa4b42aSBaptiste Daroussin 3443aa4b42aSBaptiste Daroussin done += r; 3453aa4b42aSBaptiste Daroussin now = time(NULL); 346*a6454741SBaptiste Daroussin if (now > last || done == st.size) 3473aa4b42aSBaptiste Daroussin last = now; 3483aa4b42aSBaptiste Daroussin } 3493aa4b42aSBaptiste Daroussin 350*a6454741SBaptiste Daroussin if (ferror(remote)) 351*a6454741SBaptiste Daroussin goto fetchfail; 3523aa4b42aSBaptiste Daroussin 3533aa4b42aSBaptiste Daroussin if ((ret = extract_pkg_static(fd, pkgstatic, MAXPATHLEN)) == 0) 3543aa4b42aSBaptiste Daroussin ret = install_pkg_static(pkgstatic, tmppkg); 3553aa4b42aSBaptiste Daroussin 356*a6454741SBaptiste Daroussin goto cleanup; 357*a6454741SBaptiste Daroussin 358*a6454741SBaptiste Daroussin fetchfail: 359*a6454741SBaptiste Daroussin warnx("Error fetching %s: %s", url, fetchLastErrString); 360*a6454741SBaptiste Daroussin 3613aa4b42aSBaptiste Daroussin cleanup: 3623aa4b42aSBaptiste Daroussin close(fd); 3633aa4b42aSBaptiste Daroussin unlink(tmppkg); 3643aa4b42aSBaptiste Daroussin 365*a6454741SBaptiste Daroussin return (ret); 3663aa4b42aSBaptiste Daroussin } 3673aa4b42aSBaptiste Daroussin 3683aa4b42aSBaptiste Daroussin int 3693aa4b42aSBaptiste Daroussin main(__unused int argc, char *argv[]) 3703aa4b42aSBaptiste Daroussin { 3713aa4b42aSBaptiste Daroussin char pkgpath[MAXPATHLEN]; 3723aa4b42aSBaptiste Daroussin 3733aa4b42aSBaptiste Daroussin snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", 3743aa4b42aSBaptiste Daroussin getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE); 3753aa4b42aSBaptiste Daroussin 3763aa4b42aSBaptiste Daroussin if (access(pkgpath, X_OK) == -1) 377*a6454741SBaptiste Daroussin if (bootstrap_pkg() != 0) 378*a6454741SBaptiste Daroussin exit(EXIT_FAILURE); 3793aa4b42aSBaptiste Daroussin 3803aa4b42aSBaptiste Daroussin execv(pkgpath, argv); 3813aa4b42aSBaptiste Daroussin 382*a6454741SBaptiste Daroussin /* NOT REACHED */ 3833b05c2a8SBaptiste Daroussin return (EXIT_FAILURE); 3843aa4b42aSBaptiste Daroussin } 385