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> 33*3b05c2a8SBaptiste 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> 41*3b05c2a8SBaptiste Daroussin #include <fetch.h> 423aa4b42aSBaptiste Daroussin #include <gelf.h> 433aa4b42aSBaptiste Daroussin #include <stdlib.h> 443aa4b42aSBaptiste Daroussin #include <stdio.h> 453aa4b42aSBaptiste Daroussin #include <string.h> 463aa4b42aSBaptiste Daroussin #include <time.h> 473aa4b42aSBaptiste Daroussin #include <unistd.h> 483aa4b42aSBaptiste Daroussin 493aa4b42aSBaptiste Daroussin #include "elf_tables.h" 503aa4b42aSBaptiste Daroussin 513aa4b42aSBaptiste Daroussin #define _LOCALBASE "/usr/local" 523aa4b42aSBaptiste Daroussin #define _PKGS_URL "http://pkgbeta.FreeBSD.org" 533aa4b42aSBaptiste Daroussin #define _DEFAULT_TMP "/tmp" 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 GElf_Ehdr elfhdr; 723aa4b42aSBaptiste Daroussin GElf_Shdr shdr; 733aa4b42aSBaptiste Daroussin Elf_Data *data; 743aa4b42aSBaptiste Daroussin Elf_Note note; 753aa4b42aSBaptiste Daroussin Elf_Scn *scn; 763aa4b42aSBaptiste Daroussin char *src, *osname; 773aa4b42aSBaptiste Daroussin const char *abi; 783aa4b42aSBaptiste Daroussin int fd, i, ret; 793aa4b42aSBaptiste Daroussin uint32_t version; 803aa4b42aSBaptiste Daroussin 813aa4b42aSBaptiste Daroussin version = 0; 823aa4b42aSBaptiste Daroussin ret = 0; 833aa4b42aSBaptiste Daroussin scn = NULL; 843aa4b42aSBaptiste Daroussin abi = NULL; 853aa4b42aSBaptiste Daroussin 863aa4b42aSBaptiste Daroussin if (elf_version(EV_CURRENT) == EV_NONE) { 87*3b05c2a8SBaptiste Daroussin warnx("ELF library initialization failed: %s", 88*3b05c2a8SBaptiste Daroussin elf_errmsg(-1)); 89*3b05c2a8SBaptiste Daroussin return (-1); 903aa4b42aSBaptiste Daroussin } 913aa4b42aSBaptiste Daroussin 923aa4b42aSBaptiste Daroussin if ((fd = open("/bin/sh", O_RDONLY)) < 0) { 933aa4b42aSBaptiste Daroussin warn("open()"); 94*3b05c2a8SBaptiste 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; 1223aa4b42aSBaptiste Daroussin warn("fail 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", 146*3b05c2a8SBaptiste 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 1513aa4b42aSBaptiste Daroussin switch (elfhdr.e_machine) { 1523aa4b42aSBaptiste Daroussin case EM_ARM: 1533aa4b42aSBaptiste Daroussin snprintf(dest + strlen(dest), sz - strlen(dest), 154*3b05c2a8SBaptiste Daroussin ":%s:%s:%s", elf_corres_to_string(endian_corres, 1553aa4b42aSBaptiste Daroussin (int)elfhdr.e_ident[EI_DATA]), 1563aa4b42aSBaptiste Daroussin (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ? 1573aa4b42aSBaptiste Daroussin "eabi" : "oabi", 1583aa4b42aSBaptiste Daroussin (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ? 1593aa4b42aSBaptiste Daroussin "softfp" : "vfp"); 1603aa4b42aSBaptiste Daroussin break; 1613aa4b42aSBaptiste Daroussin case EM_MIPS: 1623aa4b42aSBaptiste Daroussin /* 1633aa4b42aSBaptiste Daroussin * this is taken from binutils sources: 1643aa4b42aSBaptiste Daroussin * include/elf/mips.h 1653aa4b42aSBaptiste Daroussin * mapping is figured out from binutils: 1663aa4b42aSBaptiste Daroussin * gas/config/tc-mips.c 1673aa4b42aSBaptiste Daroussin */ 1683aa4b42aSBaptiste Daroussin switch (elfhdr.e_flags & EF_MIPS_ABI) { 1693aa4b42aSBaptiste Daroussin case E_MIPS_ABI_O32: 1703aa4b42aSBaptiste Daroussin abi = "o32"; 1713aa4b42aSBaptiste Daroussin break; 1723aa4b42aSBaptiste Daroussin case E_MIPS_ABI_N32: 1733aa4b42aSBaptiste Daroussin abi = "n32"; 1743aa4b42aSBaptiste Daroussin break; 1753aa4b42aSBaptiste Daroussin default: 1763aa4b42aSBaptiste Daroussin if (elfhdr.e_ident[EI_DATA] == 1773aa4b42aSBaptiste Daroussin ELFCLASS32) 1783aa4b42aSBaptiste Daroussin abi = "o32"; 1793aa4b42aSBaptiste Daroussin else if (elfhdr.e_ident[EI_DATA] == 1803aa4b42aSBaptiste Daroussin ELFCLASS64) 1813aa4b42aSBaptiste Daroussin abi = "n64"; 1823aa4b42aSBaptiste Daroussin break; 1833aa4b42aSBaptiste Daroussin } 1843aa4b42aSBaptiste Daroussin snprintf(dest + strlen(dest), sz - strlen(dest), 185*3b05c2a8SBaptiste Daroussin ":%s:%s", elf_corres_to_string(endian_corres, 186*3b05c2a8SBaptiste Daroussin (int)elfhdr.e_ident[EI_DATA]), abi); 1873aa4b42aSBaptiste Daroussin break; 1883aa4b42aSBaptiste Daroussin } 1893aa4b42aSBaptiste Daroussin 1903aa4b42aSBaptiste Daroussin cleanup: 1913aa4b42aSBaptiste Daroussin if (elf != NULL) 1923aa4b42aSBaptiste Daroussin elf_end(elf); 1933aa4b42aSBaptiste Daroussin 1943aa4b42aSBaptiste Daroussin close(fd); 1953aa4b42aSBaptiste Daroussin return (ret); 1963aa4b42aSBaptiste Daroussin } 1973aa4b42aSBaptiste Daroussin 1983aa4b42aSBaptiste Daroussin static int 1993aa4b42aSBaptiste Daroussin extract_pkg_static(int fd, char *p, int sz) 2003aa4b42aSBaptiste Daroussin { 2013aa4b42aSBaptiste Daroussin struct archive *a; 2023aa4b42aSBaptiste Daroussin struct archive_entry *ae; 2033aa4b42aSBaptiste Daroussin char *end; 2043aa4b42aSBaptiste Daroussin int ret, r; 2053aa4b42aSBaptiste Daroussin 2063aa4b42aSBaptiste Daroussin ret = 0; 2073aa4b42aSBaptiste Daroussin a = archive_read_new(); 2083aa4b42aSBaptiste Daroussin archive_read_support_compression_all(a); 2093aa4b42aSBaptiste Daroussin archive_read_support_format_tar(a); 2103aa4b42aSBaptiste Daroussin 2113aa4b42aSBaptiste Daroussin lseek(fd, 0, 0); 2123aa4b42aSBaptiste Daroussin 2133aa4b42aSBaptiste Daroussin if (archive_read_open_fd(a, fd, 4096) != ARCHIVE_OK) { 2143aa4b42aSBaptiste Daroussin warnx("archive_read_open_fd: %s", 2153aa4b42aSBaptiste Daroussin archive_error_string(a)); 2163aa4b42aSBaptiste Daroussin ret = -1; 2173aa4b42aSBaptiste Daroussin goto cleanup; 2183aa4b42aSBaptiste Daroussin } 2193aa4b42aSBaptiste Daroussin 2203aa4b42aSBaptiste Daroussin ae = NULL; 2213aa4b42aSBaptiste Daroussin while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK) { 2223aa4b42aSBaptiste Daroussin end = strrchr(archive_entry_pathname(ae), '/'); 2233aa4b42aSBaptiste Daroussin if (end == NULL) 2243aa4b42aSBaptiste Daroussin continue; 2253aa4b42aSBaptiste Daroussin 2263aa4b42aSBaptiste Daroussin if (strcmp(end, "/pkg-static") == 0) { 2273aa4b42aSBaptiste Daroussin r = archive_read_extract(a, ae, 2283aa4b42aSBaptiste Daroussin ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | 2293aa4b42aSBaptiste Daroussin ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL | 2303aa4b42aSBaptiste Daroussin ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR); 2313aa4b42aSBaptiste Daroussin snprintf(p, sz, archive_entry_pathname(ae)); 2323aa4b42aSBaptiste Daroussin break; 2333aa4b42aSBaptiste Daroussin } 2343aa4b42aSBaptiste Daroussin } 2353aa4b42aSBaptiste Daroussin 2363aa4b42aSBaptiste Daroussin if (r != ARCHIVE_OK) { 2373aa4b42aSBaptiste Daroussin warnx("fail to extract pkg-static"); 2383aa4b42aSBaptiste Daroussin ret = -1; 2393aa4b42aSBaptiste Daroussin } 2403aa4b42aSBaptiste Daroussin 2413aa4b42aSBaptiste Daroussin cleanup: 2423aa4b42aSBaptiste Daroussin archive_read_finish(a); 243*3b05c2a8SBaptiste Daroussin return (ret); 2443aa4b42aSBaptiste Daroussin 2453aa4b42aSBaptiste Daroussin } 2463aa4b42aSBaptiste Daroussin 2473aa4b42aSBaptiste Daroussin static int 2483aa4b42aSBaptiste Daroussin install_pkg_static(char *path, char *pkgpath) 2493aa4b42aSBaptiste Daroussin { 2503aa4b42aSBaptiste Daroussin int pstat; 2513aa4b42aSBaptiste Daroussin pid_t pid; 2523aa4b42aSBaptiste Daroussin 2533aa4b42aSBaptiste Daroussin switch ((pid = fork())) { 2543aa4b42aSBaptiste Daroussin case -1: 2553aa4b42aSBaptiste Daroussin return (-1); 2563aa4b42aSBaptiste Daroussin case 0: 257*3b05c2a8SBaptiste Daroussin execl(path, "pkg-static", "add", pkgpath, 258*3b05c2a8SBaptiste Daroussin (char *)NULL); 259*3b05c2a8SBaptiste Daroussin _exit(1); 2603aa4b42aSBaptiste Daroussin default: 2613aa4b42aSBaptiste Daroussin break; 2623aa4b42aSBaptiste Daroussin } 2633aa4b42aSBaptiste Daroussin 2643aa4b42aSBaptiste Daroussin while (waitpid(pid, &pstat, 0) == -1) { 2653aa4b42aSBaptiste Daroussin if (errno != EINTR) 2663aa4b42aSBaptiste Daroussin return (-1); 2673aa4b42aSBaptiste Daroussin } 2683aa4b42aSBaptiste Daroussin 2693aa4b42aSBaptiste Daroussin return (WEXITSTATUS(pstat)); 2703aa4b42aSBaptiste Daroussin } 2713aa4b42aSBaptiste Daroussin 2723aa4b42aSBaptiste Daroussin static int 2733aa4b42aSBaptiste Daroussin bootstrap_pkg(void) 2743aa4b42aSBaptiste Daroussin { 2753aa4b42aSBaptiste Daroussin struct url_stat st; 2763aa4b42aSBaptiste Daroussin FILE *remote; 2773aa4b42aSBaptiste Daroussin time_t begin_dl; 2783aa4b42aSBaptiste Daroussin time_t now; 2793aa4b42aSBaptiste Daroussin time_t last = 0; 2803aa4b42aSBaptiste Daroussin char url[MAXPATHLEN]; 2813aa4b42aSBaptiste Daroussin char abi[BUFSIZ]; 2823aa4b42aSBaptiste Daroussin char tmppkg[MAXPATHLEN]; 2833aa4b42aSBaptiste Daroussin char buf[10240]; 2843aa4b42aSBaptiste Daroussin char pkgstatic[MAXPATHLEN]; 2853aa4b42aSBaptiste Daroussin int fd, retry, ret; 2863aa4b42aSBaptiste Daroussin off_t done, r; 2873aa4b42aSBaptiste Daroussin 2883aa4b42aSBaptiste Daroussin done = 0; 2893aa4b42aSBaptiste Daroussin ret = 0; 2903aa4b42aSBaptiste Daroussin retry = 3; 2913aa4b42aSBaptiste Daroussin remote = NULL; 2923aa4b42aSBaptiste Daroussin 2933aa4b42aSBaptiste Daroussin printf("Bootstraping pkg please wait\n"); 2943aa4b42aSBaptiste Daroussin 2953aa4b42aSBaptiste Daroussin if (pkg_get_myabi(abi, MAXPATHLEN) != 0) { 2963aa4b42aSBaptiste Daroussin warnx("fail to determine my abi"); 297*3b05c2a8SBaptiste Daroussin return (-1); 2983aa4b42aSBaptiste Daroussin } 2993aa4b42aSBaptiste Daroussin 3003aa4b42aSBaptiste Daroussin if (getenv("PACKAGESITE") != NULL) { 3013aa4b42aSBaptiste Daroussin snprintf(url, MAXPATHLEN, "%s/pkg.txz", 3023aa4b42aSBaptiste Daroussin getenv("PACKAGESITE")); 3033aa4b42aSBaptiste Daroussin } else { 3043aa4b42aSBaptiste Daroussin snprintf(url, MAXPATHLEN, "%s/%s/latest/Latest/pkg.txz", 3053aa4b42aSBaptiste Daroussin getenv("PACKAGEROOT") ? getenv("PACKAGEROOT") : _PKGS_URL, 3063aa4b42aSBaptiste Daroussin getenv("ABI") ? getenv("ABI") : abi); 3073aa4b42aSBaptiste Daroussin } 3083aa4b42aSBaptiste Daroussin 3093aa4b42aSBaptiste Daroussin snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX", 3103aa4b42aSBaptiste Daroussin getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp"); 3113aa4b42aSBaptiste Daroussin 3123aa4b42aSBaptiste Daroussin if ((fd = mkstemp(tmppkg)) == -1) { 3133aa4b42aSBaptiste Daroussin warn("mkstemp()"); 314*3b05c2a8SBaptiste Daroussin return (-1); 3153aa4b42aSBaptiste Daroussin } 3163aa4b42aSBaptiste Daroussin 3173aa4b42aSBaptiste Daroussin while (remote == NULL) { 3183aa4b42aSBaptiste Daroussin remote = fetchXGetURL(url, &st, ""); 3193aa4b42aSBaptiste Daroussin if (remote == NULL) { 3203aa4b42aSBaptiste Daroussin --retry; 3213aa4b42aSBaptiste Daroussin if (retry == 0) { 3223aa4b42aSBaptiste Daroussin warnx("Error fetching %s: %s", url, 3233aa4b42aSBaptiste Daroussin fetchLastErrString); 3243aa4b42aSBaptiste Daroussin ret = 1; 3253aa4b42aSBaptiste Daroussin goto cleanup; 3263aa4b42aSBaptiste Daroussin } 3273aa4b42aSBaptiste Daroussin sleep(1); 3283aa4b42aSBaptiste Daroussin } 3293aa4b42aSBaptiste Daroussin } 3303aa4b42aSBaptiste Daroussin 3313aa4b42aSBaptiste Daroussin begin_dl = time(NULL); 3323aa4b42aSBaptiste Daroussin while (done < st.size) { 3333aa4b42aSBaptiste Daroussin if ((r = fread(buf, 1, sizeof(buf), remote)) < 1) 3343aa4b42aSBaptiste Daroussin break; 3353aa4b42aSBaptiste Daroussin 3363aa4b42aSBaptiste Daroussin if (write(fd, buf, r) != r) { 3373aa4b42aSBaptiste Daroussin warn("write()"); 3383aa4b42aSBaptiste Daroussin ret = -1; 3393aa4b42aSBaptiste Daroussin goto cleanup; 3403aa4b42aSBaptiste Daroussin } 3413aa4b42aSBaptiste Daroussin 3423aa4b42aSBaptiste Daroussin done += r; 3433aa4b42aSBaptiste Daroussin now = time(NULL); 3443aa4b42aSBaptiste Daroussin if (now > last || done == st.size) { 3453aa4b42aSBaptiste Daroussin last = now; 3463aa4b42aSBaptiste Daroussin } 3473aa4b42aSBaptiste Daroussin } 3483aa4b42aSBaptiste Daroussin 3493aa4b42aSBaptiste Daroussin if (ferror(remote)) { 3503aa4b42aSBaptiste Daroussin warnx("Error fetching %s: %s", url, 3513aa4b42aSBaptiste Daroussin fetchLastErrString); 3523aa4b42aSBaptiste Daroussin ret = 1; 3533aa4b42aSBaptiste Daroussin goto cleanup; 3543aa4b42aSBaptiste Daroussin } 3553aa4b42aSBaptiste Daroussin 3563aa4b42aSBaptiste Daroussin if ((ret = extract_pkg_static(fd, pkgstatic, MAXPATHLEN)) == 0) 3573aa4b42aSBaptiste Daroussin ret = install_pkg_static(pkgstatic, tmppkg); 3583aa4b42aSBaptiste Daroussin 3593aa4b42aSBaptiste Daroussin cleanup: 3603aa4b42aSBaptiste Daroussin close(fd); 3613aa4b42aSBaptiste Daroussin unlink(tmppkg); 3623aa4b42aSBaptiste Daroussin 363*3b05c2a8SBaptiste Daroussin return (0); 3643aa4b42aSBaptiste Daroussin } 3653aa4b42aSBaptiste Daroussin 3663aa4b42aSBaptiste Daroussin int 3673aa4b42aSBaptiste Daroussin main(__unused int argc, char *argv[]) 3683aa4b42aSBaptiste Daroussin { 3693aa4b42aSBaptiste Daroussin char pkgpath[MAXPATHLEN]; 3703aa4b42aSBaptiste Daroussin 3713aa4b42aSBaptiste Daroussin snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", 3723aa4b42aSBaptiste Daroussin getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE); 3733aa4b42aSBaptiste Daroussin 3743aa4b42aSBaptiste Daroussin if (access(pkgpath, X_OK) == -1) 3753aa4b42aSBaptiste Daroussin bootstrap_pkg(); 3763aa4b42aSBaptiste Daroussin 3773aa4b42aSBaptiste Daroussin execv(pkgpath, argv); 3783aa4b42aSBaptiste Daroussin 379*3b05c2a8SBaptiste Daroussin return (EXIT_FAILURE); 3803aa4b42aSBaptiste Daroussin } 381