3 * Philipp Mergenthaler <philipp.mergenthaler@stud.uni-karlsruhe.de>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include "sysinstall.h"
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <sys/param.h>
37 extern const char *ftp_dirs[]; /* defined in ftp.c */
40 checkAccess(Boolean connectCheckOnly, Boolean isProxy)
43 bool el, found=FALSE; /* end of header line */
44 char *cp, buf[PATH_MAX], req[BUFSIZ];
45 struct addrinfo hints, *res, *res0;
47 af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC;
48 memset(&hints, 0, sizeof(hints));
50 hints.ai_socktype = SOCK_STREAM;
51 hints.ai_protocol = 0;
52 if ((rv = getaddrinfo(variable_get(VAR_HTTP_HOST),
53 variable_get(VAR_HTTP_PORT), &hints, &res0)) != 0) {
54 msgConfirm("%s", gai_strerror(rv));
55 variable_unset(VAR_HTTP_HOST);
59 for (res = res0; res; res = res->ai_next) {
60 if ((s = socket(res->ai_family, res->ai_socktype,
61 res->ai_protocol)) < 0)
63 if (connect(s, res->ai_addr, res->ai_addrlen) >= 0)
71 msgConfirm("Couldn't connect to proxy %s:%s",
72 variable_get(VAR_HTTP_HOST),variable_get(VAR_HTTP_PORT));
74 msgConfirm("Couldn't connect to server http://%s:%s/",
75 variable_get(VAR_HTTP_HOST),variable_get(VAR_HTTP_PORT));
77 variable_unset(VAR_HTTP_HOST);
80 if (connectCheckOnly) {
85 msgNotify("Checking access to\n %s", variable_get(VAR_HTTP_PATH));
87 sprintf(req,"GET %s/ HTTP/1.0\r\n\r\n", variable_get(VAR_HTTP_PATH));
89 sprintf(req,"GET /%s/ HTTP/1.0\r\n\r\n", variable_get(VAR_HTTP_PATH));
90 write(s,req,strlen(req));
92 * scan the headers of the response
93 * this is extremely quick'n dirty
100 variable_set2(VAR_HTTP_FTP_MODE,"",0);
102 if ((*cp == '\012') && el) {
103 /* reached end of a header line */
104 if (!strncmp(buf,"HTTP",4)) {
105 if (strtol((char *)(buf+9),0,0) == 200) {
111 * Some proxies fetch files with certain extensions in "ascii mode"
112 * instead of "binary mode" for FTP. The FTP server then translates
115 * You can force Squid to use binary mode by appending ";type=i" to
116 * the URL, which is what I do here. For other proxies, the
117 * LF->CRLF substitution is reverted in distExtract().
119 if (isProxy && !strncmp(buf,"Server: ",8)) {
120 if (!strncmp(buf,"Server: Squid",13)) {
121 variable_set2(VAR_HTTP_FTP_MODE,";type=i",0);
123 variable_set2(VAR_HTTP_FTP_MODE,"",0);
126 /* ignore other headers */
127 /* check for "\015\012" at beginning of line, i.e. end of headers */
145 mediaInitHTTP(Device *dev)
147 bool found=FALSE; /* end of header line */
148 char *rel, req[BUFSIZ];
152 * First verify the proxy access
154 checkAccess(TRUE, TRUE);
155 while (variable_get(VAR_HTTP_HOST) == NULL) {
156 if (DITEM_STATUS(mediaSetHTTP(NULL)) == DITEM_FAILURE)
158 checkAccess(TRUE, TRUE);
161 /* If the release is specified as "__RELEASE" or "any", then just
162 * assume that the path the user gave is ok.
164 rel = variable_get(VAR_RELNAME);
166 msgConfirm("rel: -%s-", rel);
169 if (strcmp(rel, "__RELEASE") && strcmp(rel, "any")) {
170 for (fdir = 0; ftp_dirs[fdir]; fdir++) {
171 sprintf(req, "%s/%s/%s", variable_get(VAR_FTP_PATH),
172 ftp_dirs[fdir], rel);
173 variable_set2(VAR_HTTP_PATH, req, 0);
174 if (checkAccess(FALSE, TRUE)) {
180 variable_set2(VAR_HTTP_PATH, variable_get(VAR_FTP_PATH), 0);
181 found = checkAccess(FALSE, TRUE);
184 msgConfirm("No such directory: %s\n"
185 "please check the URL and try again.", variable_get(VAR_HTTP_PATH));
186 variable_unset(VAR_HTTP_PATH);
187 dialog_clear_norefresh();
189 if (DITEM_STATUS(mediaSetHTTP(NULL)) != DITEM_FAILURE) goto again;
195 mediaGetHTTP(Device *dev, char *file, Boolean probe)
199 bool el; /* end of header line */
200 char *cp, buf[PATH_MAX], req[BUFSIZ];
201 struct addrinfo hints, *res, *res0;
203 af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC;
204 memset(&hints, 0, sizeof(hints));
205 hints.ai_family = af;
206 hints.ai_socktype = SOCK_STREAM;
207 hints.ai_protocol = 0;
208 if ((rv = getaddrinfo(variable_get(VAR_HTTP_HOST),
209 variable_get(VAR_HTTP_PORT), &hints, &res0)) != 0) {
210 msgConfirm("%s", gai_strerror(rv));
214 for (res = res0; res; res = res->ai_next) {
215 if ((s = socket(res->ai_family, res->ai_socktype,
216 res->ai_protocol)) < 0)
218 if (connect(s, res->ai_addr, res->ai_addrlen) >= 0)
225 msgConfirm("Couldn't connect to proxy %s:%s",
226 variable_get(VAR_HTTP_HOST),variable_get(VAR_HTTP_PORT));
230 sprintf(req,"GET %s/%s%s HTTP/1.0\r\n\r\n",
231 variable_get(VAR_HTTP_PATH), file, variable_get(VAR_HTTP_FTP_MODE));
234 msgDebug("sending http request: %s\n",req);
236 write(s,req,strlen(req));
239 * scan the headers of the response
240 * this is extremely quick'n dirty
247 if ((*cp == '\012') && el) {
248 /* reached end of a header line */
249 if (!strncmp(buf,"HTTP",4)) {
250 rv=strtol((char *)(buf+9),0,0);
251 *(cp-1)='\0'; /* chop the CRLF off */
252 if (probe && (rv != 200)) {
254 } else if (rv >= 500) {
255 msgConfirm("Server error %s when sending %s, you could try an other server",buf, req);
257 } else if (rv == 404) {
258 msgConfirm("%s was not found, maybe directory or release-version are wrong?",req);
260 } else if (rv >= 400) {
261 msgConfirm("Client error %s, you could try an other server",buf);
263 } else if (rv >= 300) {
264 msgConfirm("Error %s",buf);
266 } else if (rv != 200) {
267 msgConfirm("Error %s when sending %s, you could try an other server",buf, req);
271 /* ignore other headers */
272 /* check for "\015\012" at beginning of line, i.e. end of headers */