]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/pkg_install/lib/url.c
This commit was generated by cvs2svn to compensate for changes in r147464,
[FreeBSD/FreeBSD.git] / usr.sbin / pkg_install / lib / url.c
1 /*
2  * FreeBSD install - a package for the installation and maintainance
3  * of non-core utilities.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
14  * Jordan K. Hubbard
15  * 18 July 1993
16  *
17  * URL file access utilities.
18  *
19  */
20
21 #include <sys/cdefs.h>
22 __FBSDID("$FreeBSD$");
23
24 #include "lib.h"
25 #include <err.h>
26 #include <fetch.h>
27 #include <sys/wait.h>
28
29 /*
30  * Try and fetch a file by URL, returning the directory name for where
31  * it's unpacked, if successful.
32  */
33 char *
34 fileGetURL(const char *base, const char *spec)
35 {
36     char *cp, *rp;
37     char fname[FILENAME_MAX];
38     char pen[FILENAME_MAX];
39     char buf[8192];
40     FILE *ftp;
41     pid_t tpid;
42     int pfd[2], pstat, r, w = 0;
43     char *hint;
44     int fd;
45
46     rp = NULL;
47     /* Special tip that sysinstall left for us */
48     hint = getenv("PKG_ADD_BASE");
49     if (!isURL(spec)) {
50         if (!base && !hint)
51             return NULL;
52         /*
53          * We've been given an existing URL (that's known-good) and now we need
54          * to construct a composite one out of that and the basename we were
55          * handed as a dependency.
56          */
57         if (base) {
58             strcpy(fname, base);
59             /*
60              * Advance back two slashes to get to the root of the package
61              * hierarchy
62              */
63             cp = strrchr(fname, '/');
64             if (cp) {
65                 *cp = '\0';     /* chop name */
66                 cp = strrchr(fname, '/');
67             }
68             if (cp) {
69                 *(cp + 1) = '\0';
70                 strcat(cp, "All/");
71                 strcat(cp, spec);
72 #if defined(__FreeBSD_version) && __FreeBSD_version >= 500039
73                 strcat(cp, ".tbz");
74 #else
75                 strcat(cp, ".tgz");
76 #endif
77             }
78             else
79                 return NULL;
80         }
81         else {
82             /*
83              * Otherwise, we've been given an environment variable hinting
84              * at the right location from sysinstall
85              */
86             strcpy(fname, hint);
87             strcat(fname, spec);
88 #if defined(__FreeBSD_version) && __FreeBSD_version >= 500039
89             strcat(fname, ".tbz");
90 #else
91             strcat(fname, ".tgz");
92 #endif
93         }
94     }
95     else
96         strcpy(fname, spec);
97
98     if ((ftp = fetchGetURL(fname, Verbose ? "v" : NULL)) == NULL) {
99         printf("Error: FTP Unable to get %s: %s\n",
100                fname, fetchLastErrString);
101         return NULL;
102     }
103
104     if (isatty(0) || Verbose)
105         printf("Fetching %s...", fname), fflush(stdout);
106     pen[0] = '\0';
107     if ((rp = make_playpen(pen, 0)) == NULL) {
108         printf("Error: Unable to construct a new playpen for FTP!\n");
109         fclose(ftp);
110         return NULL;
111     }
112     if (pipe(pfd) == -1) {
113         warn("pipe()");
114         cleanup(0);
115         exit(2);
116     }
117     if ((tpid = fork()) == -1) {
118         warn("pipe()");
119         cleanup(0);
120         exit(2);
121     }
122     if (!tpid) {
123         dup2(pfd[0], 0);
124         for (fd = getdtablesize() - 1; fd >= 3; --fd)
125             close(fd);
126         execl("/usr/bin/tar", "tar",
127 #if defined(__FreeBSD_version) && __FreeBSD_version >= 500039
128             Verbose ? "-xjvf" : "-xjf",
129 #else
130             Verbose ? "-xzvf" : "-xzf",
131 #endif
132             "-", (char *)0);
133         _exit(2);
134     }
135     close(pfd[0]);
136     for (;;) {
137         if ((r = fread(buf, 1, sizeof buf, ftp)) < 1)
138             break;
139         if ((w = write(pfd[1], buf, r)) != r)
140             break;
141     }
142     if (ferror(ftp))
143         warn("warning: error reading from server");
144     fclose(ftp);
145     close(pfd[1]);
146     if (w == -1)
147         warn("warning: error writing to tar");
148     tpid = waitpid(tpid, &pstat, 0);
149     if (Verbose)
150         printf("tar command returns %d status\n", WEXITSTATUS(pstat));
151     if (rp && (isatty(0) || Verbose))
152         printf(" Done.\n");
153     return rp;
154 }