Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}