2 * FreeBSD install - a package for the installation and maintenance
3 * of non-core utilities.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
17 * URL file access utilities.
21 #include <sys/cdefs.h>
22 __FBSDID("$FreeBSD$");
32 * Try and fetch a file by URL, returning the directory name for where
33 * it's unpacked, if successful.
36 fileGetURL(const char *base, const char *spec, int keep_package)
40 char fname[FILENAME_MAX];
41 char pen[FILENAME_MAX];
42 char pkg[FILENAME_MAX];
46 int pfd[2], pstat, r, w = 0;
51 /* Special tip that sysinstall left for us */
52 hint = getenv("PKG_ADD_BASE");
57 * We've been given an existing URL (that's known-good) and now we need
58 * to construct a composite one out of that and the basename we were
59 * handed as a dependency.
64 * Advance back two slashes to get to the root of the package
67 cp = strrchr(fname, '/');
69 *cp = '\0'; /* chop name */
70 cp = strrchr(fname, '/');
76 if (getenv("PACKAGESUFFIX"))
77 strcat(cp, getenv("PACKAGESUFFIX"));
86 * Otherwise, we've been given an environment variable hinting
87 * at the right location from sysinstall
91 if (getenv("PACKAGESUFFIX"))
92 strcat(fname, getenv("PACKAGESUFFIX"));
94 strcat(fname, ".tbz");
101 tmp = getenv("PKGDIR");
102 strlcpy(pkg, tmp ? tmp : ".", sizeof(pkg));
103 tmp = basename(fname);
104 strlcat(pkg, "/", sizeof(pkg));
105 strlcat(pkg, tmp, sizeof(pkg));
106 if ((pkgfd = open(pkg, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) {
107 printf("Error: Unable to open %s\n", pkg);
113 fetchDebug = (Verbose > 0);
114 if ((ftp = fetchGetURL(fname, Verbose ? "v" : NULL)) == NULL) {
115 printf("Error: Unable to get %s: %s\n",
116 fname, fetchLastErrString);
117 /* If the fetch fails, yank the package. */
118 if (keep_package && unlink(pkg) < 0 && Verbose) {
119 warnx("failed to remove partially fetched package: %s", pkg);
124 if (isatty(0) || Verbose)
125 printf("Fetching %s...", fname), fflush(stdout);
127 if ((rp = make_playpen(pen, 0)) == NULL) {
128 printf("Error: Unable to construct a new playpen for FTP!\n");
132 if (pipe(pfd) == -1) {
137 if ((tpid = fork()) == -1) {
144 for (fd = getdtablesize() - 1; fd >= 3; --fd)
146 execl("/usr/bin/tar", "tar",
147 Verbose ? "-xpjvf" : "-xpjf",
153 if ((r = fread(buf, 1, sizeof buf, ftp)) < 1)
155 if ((w = write(pfd[1], buf, r)) != r)
158 if ((w = write(pkgfd, buf, r)) != r)
163 warn("warning: error reading from server");
170 warn("warning: error writing to tar");
171 tpid = waitpid(tpid, &pstat, 0);
173 printf("tar command returns %d status\n", WEXITSTATUS(pstat));
174 if (rp && (isatty(0) || Verbose))