static int bootstrap_pkg(void) { FILE *remote; 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; last = 0; ret = -1; remote = NULL; config = NULL; printf("Bootstrapping pkg please wait\n"); if (pkg_get_myabi(abi, MAXPATHLEN) != 0) { warnx("failed to determine the system ABI"); return (-1); } 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") : _PATH_TMP); if ((fd = mkstemp(tmppkg)) == -1) { warn("mkstemp()"); return (-1); } retry = 3; do { remote = fetchXGetURL(url, &st, ""); if (remote == NULL) sleep(1); } while (remote == NULL && retry-- > 0); if (remote == NULL) goto fetchfail; while (done < st.size) { if ((r = fread(buf, 1, sizeof(buf), remote)) < 1) break; if (write(fd, buf, r) != r) { warn("write()"); goto cleanup; } done += r; now = time(NULL); if (now > last || done == st.size) last = now; } 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 (ret); }
static int bootstrap_pkg(void) { struct url *u; FILE *remote; FILE *config; char *site; struct dns_srvinfo *mirrors, *current; /* To store _https._tcp. + hostname + \0 */ char zone[MAXHOSTNAMELEN + 13]; char url[MAXPATHLEN]; char conf[MAXPATHLEN]; char tmppkg[MAXPATHLEN]; const char *packagesite, *mirror_type; char buf[10240]; char pkgstatic[MAXPATHLEN]; int fd, retry, ret, max_retry; struct url_stat st; off_t done, r; time_t now; time_t last; done = 0; last = 0; max_retry = 3; ret = -1; remote = NULL; config = NULL; current = mirrors = NULL; printf("Bootstrapping pkg please wait\n"); if (config_string(PACKAGESITE, &packagesite) != 0) { warnx("No PACKAGESITE defined"); return (-1); } if (config_string(MIRROR_TYPE, &mirror_type) != 0) { warnx("No MIRROR_TYPE defined"); return (-1); } snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz", packagesite); snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX", getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); if ((fd = mkstemp(tmppkg)) == -1) { warn("mkstemp()"); return (-1); } retry = max_retry; u = fetchParseURL(url); while (remote == NULL) { if (retry == max_retry) { if (strcmp(u->scheme, "file") != 0 && strcasecmp(mirror_type, "srv") == 0) { snprintf(zone, sizeof(zone), "_%s._tcp.%s", u->scheme, u->host); mirrors = dns_getsrvinfo(zone); current = mirrors; } } if (mirrors != NULL) strlcpy(u->host, current->host, sizeof(u->host)); remote = fetchXGet(u, &st, ""); if (remote == NULL) { --retry; if (retry <= 0) goto fetchfail; if (mirrors == NULL) { sleep(1); } else { current = current->next; if (current == NULL) current = mirrors; } } } if (remote == NULL) goto fetchfail; while (done < st.size) { if ((r = fread(buf, 1, sizeof(buf), remote)) < 1) break; if (write(fd, buf, r) != r) { warn("write()"); goto cleanup; } done += r; now = time(NULL); if (now > last || done == st.size) last = now; } 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\n", url); fclose(config); } goto cleanup; fetchfail: warnx("Error fetching %s: %s", url, fetchLastErrString); fprintf(stderr, "A pre-built version of pkg could not be found for your system.\n"); fprintf(stderr, "Consider changing PACKAGESITE or installing it from ports: 'ports-mgmt/pkg'.\n"); cleanup: if (remote != NULL) fclose(remote); close(fd); unlink(tmppkg); return (ret); }