From a0b43ea704836fb9b3ec0a4620fa0dcfbfca84a6 Mon Sep 17 00:00:00 2001 From: Thierry Vignaud Date: Fri, 21 Dec 2012 17:37:41 +0000 Subject: special case for libreoffice-langpack-br --- mdk-stage1/url.c | 6292 +++++------------------------------------------------- 1 file changed, 560 insertions(+), 5732 deletions(-) (limited to 'mdk-stage1/url.c') diff --git a/mdk-stage1/url.c b/mdk-stage1/url.c index b9af3c689..3d2846649 100644 --- a/mdk-stage1/url.c +++ b/mdk-stage1/url.c @@ -1,5732 +1,560 @@ - - - - - - - - - - - - - - - -[soft] Contents of /drakx/trunk/mdk-stage1/url.c - - - - - - -
- - - -
/[soft]/drakx/trunk/mdk-stage1/url.c
-
-
ViewVC logotype
-

Contents of /drakx/trunk/mdk-stage1/url.c

- -

- -Parent Directory Parent Directory - -| Revision Log Revision Log - - - - -

- -
-
-Revision 2834 - -(show annotations) -(download) -(as text) - -
Fri Jan 27 07:14:12 2012 UTC -(9 months, 2 weeks ago) -by tv - - - - - - -
File MIME type: text/x-c - - -
File size: 12365 byte(s) - - - - - - -
kill dead emails
-
- -
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* -
2 * Guillaume Cottenceau (gc) -
3 * -
4 * Copyright 2000 Mandriva -
5 * -
6 * This software may be freely redistributed under the terms of the GNU -
7 * public license. -
8 * -
9 * You should have received a copy of the GNU General Public License -
10 * along with this program; if not, write to the Free Software -
11 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -
12 * -
13 */ -
14 -
15/* -
16 * Portions from Erik Troan <ewt@redhat.com> and Matt Wilson <msw@redhat.com> -
17 * -
18 * Copyright 1999 Red Hat, Inc. -
19 * -
20 */ -
21 -
22#include <alloca.h> -
23#include <sys/socket.h> -
24#include <sys/types.h> -
25#include <netinet/in_systm.h> -
26 -
27#include <ctype.h> -
28#include <errno.h> -
29#include <fcntl.h> -
30#include <netdb.h> -
31#include <stdarg.h> -
32#include <stdio.h> -
33#include <stdlib.h> -
34#include <string.h> -
35#include <strings.h> -
36#include <sys/socket.h> -
37#include <sys/time.h> -
38#include <sys/types.h> -
39#include <unistd.h> -
40#include <sys/poll.h> -
41 -
42#include <netinet/in.h> -
43#include <netinet/ip.h> -
44#include <arpa/inet.h> -
45 -
46#include "dns.h" -
47#include "log.h" -
48#include "tools.h" -
49#include "utils.h" -
50 -
51#include "url.h" -
52 -
53 -
54#define TIMEOUT_SECS 60 -
55#define BUFFER_SIZE 4096 -
56#define HTTP_MAX_RECURSION 5 -
57 -
58 -
59static int ftp_check_response(int sock, char ** str) -
60{ -
61 static char buf[BUFFER_SIZE + 1]; -
62 int bufLength = 0; -
63 struct pollfd polls; -
64 char * chptr, * start; -
65 int bytesRead, rc = 0; -
66 int doesContinue = 1; -
67 char errorCode[4]; -
68 -
69 errorCode[0] = '\0'; -
70 -
71 do { -
72 polls.fd = sock; -
73 polls.events = POLLIN; -
74 if (poll(&polls, 1, TIMEOUT_SECS*1000) != 1) -
75 return FTPERR_BAD_SERVER_RESPONSE; -
76 -
77 bytesRead = read(sock, buf + bufLength, sizeof(buf) - bufLength - 1); -
78 -
79 bufLength += bytesRead; -
80 -
81 buf[bufLength] = '\0'; -
82 -
83 /* divide the response into lines, checking each one to see if -
84 we are finished or need to continue */ -
85 -
86 start = chptr = buf; -
87 -
88 do { -
89 while (*chptr != '\n' && *chptr) chptr++; -
90 -
91 if (*chptr == '\n') { -
92 *chptr = '\0'; -
93 if (*(chptr - 1) == '\r') *(chptr - 1) = '\0'; -
94 if (str) *str = start; -
95 -
96 if (errorCode[0]) { -
97 if (!strncmp(start, errorCode, 3) && start[3] == ' ') -
98 doesContinue = 0; -
99 } else { -
100 strncpy(errorCode, start, 3); -
101 errorCode[3] = '\0'; -
102 if (start[3] != '-') { -
103 doesContinue = 0; -
104 } -
105 } -
106 -
107 start = chptr + 1; -
108 chptr++; -
109 } else { -
110 chptr++; -
111 } -
112 } while (*chptr); -
113 -
114 if (doesContinue && chptr > start) { -
115 memcpy(buf, start, chptr - start - 1); -
116 bufLength = chptr - start - 1; -
117 } else { -
118 bufLength = 0; -
119 } -
120 } while (doesContinue); -
121 -
122 if (*errorCode == '4' || *errorCode == '5') { -
123 if (!strncmp(errorCode, "550", 3)) { -
124 return FTPERR_FILE_NOT_FOUND; -
125 } -
126 -
127 return FTPERR_BAD_SERVER_RESPONSE; -
128 } -
129 -
130 if (rc) return rc; -
131 -
132 return 0; -
133} -
134 -
135static int ftp_command(int sock, char * command, char * param) -
136{ -
137 char buf[500]; -
138 int rc; -
139 -
140 snprintf(buf, sizeof(buf), "%s%s%s\r\n", command, param ? " " : "", param ? param : ""); -
141 -
142 if (write(sock, buf, strlen(buf)) != (ssize_t)strlen(buf)) { -
143 return FTPERR_SERVER_IO_ERROR; -
144 } -
145 -
146 if ((rc = ftp_check_response(sock, NULL))) -
147 return rc; -
148 -
149 return 0; -
150} -
151 -
152static int get_host_address(char * host, struct in_addr * address) -
153{ -
154 if (isdigit(host[0])) { -
155 if (!inet_aton(host, address)) { -
156 return FTPERR_BAD_HOST_ADDR; -
157 } -
158 } else { -
159 if (mygethostbyname(host, address)) -
160 return FTPERR_BAD_HOSTNAME; -
161 } -
162 -
163 return 0; -
164} -
165 -
166int ftp_open_connection(char * host, char * name, char * password, char * proxy) -
167{ -
168 int sock; -
169 struct in_addr serverAddress; -
170 struct sockaddr_in destPort; -
171 int rc; -
172 int port = 21; -
173 -
174 if (!strcmp(name, "")) { -
175 name = "anonymous"; -
176 password = "-drakx@"; -
177 } -
178 -
179 if (strcmp(proxy, "")) { -
180 name = asprintf_("%s@%s", name, host); -
181 host = proxy; -
182 } -
183 -
184 if ((rc = get_host_address(host, &serverAddress))) return rc; -
185 -
186 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); -
187 if (sock < 0) { -
188 return FTPERR_FAILED_CONNECT; -
189 } -
190 -
191 destPort.sin_family = AF_INET; -
192 destPort.sin_port = htons(port); -
193 destPort.sin_addr = serverAddress; -
194 -
195 if (connect(sock, (struct sockaddr *) &destPort, sizeof(destPort))) { -
196 close(sock); -
197 return FTPERR_FAILED_CONNECT; -
198 } -
199 -
200 /* ftpCheckResponse() assumes the socket is nonblocking */ -
201 if (fcntl(sock, F_SETFL, O_NONBLOCK)) { -
202 close(sock); -
203 return FTPERR_FAILED_CONNECT; -
204 } -
205 -
206 if ((rc = ftp_check_response(sock, NULL))) { -
207 return rc; -
208 } -
209 -
210 if ((rc = ftp_command(sock, "USER", name))) { -
211 close(sock); -
212 return rc; -
213 } -
214 -
215 if ((rc = ftp_command(sock, "PASS", password))) { -
216 close(sock); -
217 return rc; -
218 } -
219 -
220 if ((rc = ftp_command(sock, "TYPE", "I"))) { -
221 close(sock); -
222 return rc; -
223 } -
224 -
225 return sock; -
226} -
227 -
228 -
229int ftp_data_command(int sock, char * command, char * param) -
230{ -
231 int dataSocket; -
232 struct sockaddr_in dataAddress; -
233 int i, j; -
234 char * passReply; -
235 char * chptr; -
236 char retrCommand[500]; -
237 int rc; -
238 -
239 if (write(sock, "PASV\r\n", 6) != 6) { -
240 return FTPERR_SERVER_IO_ERROR; -
241 } -
242 if ((rc = ftp_check_response(sock, &passReply))) -
243 return FTPERR_PASSIVE_ERROR; -
244 -
245 chptr = passReply; -
246 while (*chptr && *chptr != '(') chptr++; -
247 if (*chptr != '(') return FTPERR_PASSIVE_ERROR; -
248 chptr++; -
249 passReply = chptr; -
250 while (*chptr && *chptr != ')') chptr++; -
251 if (*chptr != ')') return FTPERR_PASSIVE_ERROR; -
252 *chptr-- = '\0'; -
253 -
254 while (*chptr && *chptr != ',') chptr--; -
255 if (*chptr != ',') return FTPERR_PASSIVE_ERROR; -
256 chptr--; -
257 while (*chptr && *chptr != ',') chptr--; -
258 if (*chptr != ',') return FTPERR_PASSIVE_ERROR; -
259 *chptr++ = '\0'; -
260 -
261 /* now passReply points to the IP portion, and chptr points to the -
262 port number portion */ -
263 -
264 dataAddress.sin_family = AF_INET; -
265 if (sscanf(chptr, "%d,%d", &i, &j) != 2) { -
266 return FTPERR_PASSIVE_ERROR; -
267 } -
268 dataAddress.sin_port = htons((i << 8) + j); -
269 -
270 chptr = passReply; -
271 while (*chptr++) { -
272 if (*chptr == ',') *chptr = '.'; -
273 } -
274 -
275 if (!inet_aton(passReply, &dataAddress.sin_addr)) -
276 return FTPERR_PASSIVE_ERROR; -
277 -
278 dataSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); -
279 if (dataSocket < 0) { -
280 return FTPERR_FAILED_CONNECT; -
281 } -
282 -
283 if (!param) -
284 sprintf(retrCommand, "%s\r\n", command); -
285 else -
286 sprintf(retrCommand, "%s %s\r\n", command, param); -
287 -
288 i = strlen(retrCommand); -
289 -
290 if (write(sock, retrCommand, i) != i) { -
291 return FTPERR_SERVER_IO_ERROR; -
292 } -
293 -
294 if (connect(dataSocket, (struct sockaddr *) &dataAddress, -
295 sizeof(dataAddress))) { -
296 close(dataSocket); -
297 return FTPERR_FAILED_DATA_CONNECT; -
298 } -
299 -
300 if ((rc = ftp_check_response(sock, NULL))) { -
301 close(dataSocket); -
302 return rc; -
303 } -
304 -
305 return dataSocket; -
306} -
307 -
308 -
309int ftp_get_filesize(int sock, char * remotename) -
310{ -
311 int size = 0; -
312 char buf[2000]; -
313 char file[500]; -
314 char * ptr; -
315 int fd, rc, tot; -
316 int i; -
317 -
318 strcpy(buf, remotename); -
319 ptr = strrchr(buf, '/'); -
320 if (!*ptr) -
321 return -1; -
322 *ptr = '\0'; -
323 -
324 strcpy(file, ptr+1); -
325 -
326 if ((rc = ftp_command(sock, "CWD", buf))) { -
327 return -1; -
328 } -
329 -
330 fd = ftp_data_command(sock, "LIST", file); -
331 if (fd <= 0) { -
332 close(sock); -
333 return -1; -
334 } -
335 -
336 ptr = buf; -
337 while ((tot = read(fd, ptr, sizeof(buf) - (ptr - buf) - 1)) != 0) -
338 ptr += tot; -
339 *ptr = '\0'; -
340 close(fd); -
341 -
342 if (!(ptr = strstr(buf, file))) { -
343 log_message("FTP/get_filesize: Bad mood, directory does not contain searched file (%s)", file); -
344 if (ftp_end_data_command(sock)) -
345 close(sock); -
346 return -1; -
347 } -
348 -
349 for (i=0; i<4; i++) { -
350 while (*ptr && *ptr != ' ') -
351 ptr--; -
352 while (*ptr && *ptr == ' ') -
353 ptr--; -
354 } -
355 while (*ptr && *ptr != ' ') -
356 ptr--; -
357 -
358 if (ptr) -
359 size = charstar_to_int(ptr+1); -
360 else -
361 size = 0; -
362 -
363 if (ftp_end_data_command(sock)) { -
364 close(sock); -
365 return -1; -
366 } -
367 -
368 return size; -
369} -
370 -
371 -
372int ftp_start_download(int sock, char * remotename, int * size) -
373{ -
374 if ((*size = ftp_get_filesize(sock, remotename)) == -1) { -
375 log_message("FTP: could not get filesize (trying to continue)"); -
376 *size = 0; -
377 } -
378 return ftp_data_command(sock, "RETR", remotename); -
379} -
380 -
381 -
382int ftp_end_data_command(int sock) -
383{ -
384 if (ftp_check_response(sock, NULL)) -
385 return FTPERR_BAD_SERVER_RESPONSE; -
386 -
387 return 0; -
388} -
389 -
390 -
391char *str_ftp_error(int error) -
392{ -
393 return error == FTPERR_PASSIVE_ERROR ? "error with passive connection" : -
394 error == FTPERR_FAILED_CONNECT ? "couldn't connect to server" : -
395 error == FTPERR_FILE_NOT_FOUND ? "file not found" : -
396 error == FTPERR_BAD_SERVER_RESPONSE ? "bad server response (server too busy?)" : -
397 NULL; -
398} -
399 -
400 -
401static int _http_download_file(char * hostname, char * remotename, int * size, char * proxyprotocol, char * proxyname, char * proxyport, int recursion) -
402{ -
403 char * buf; -
404 char headers[4096]; -
405 char * nextChar = headers; -
406 int statusCode; -
407 struct in_addr serverAddress; -
408 struct pollfd polls; -
409 int sock; -
410 int rc; -
411 struct sockaddr_in destPort; -
412 const char * header_content_length = "Content-Length: "; -
413 const char * header_location = "Location: http://"; -
414 char * http_server_name; -
415 int http_server_port; -
416 -
417 if (proxyprotocol) { -
418 http_server_name = proxyname; -
419 http_server_port = atoi(proxyport); -
420 } else { -
421 http_server_name = hostname; -
422 http_server_port = 80; -
423 } -
424 -
425 log_message("HTTP: connecting to server %s:%i (%s)", -
426 http_server_name, http_server_port, -
427 proxyprotocol ? "proxy" : "no proxy"); -
428 -
429 if ((rc = get_host_address(http_server_name, &serverAddress))) return rc; -
430 -
431 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); -
432 if (sock < 0) { -
433 return FTPERR_FAILED_CONNECT; -
434 } -
435 -
436 destPort.sin_family = AF_INET; -
437 destPort.sin_port = htons(http_server_port); -
438 destPort.sin_addr = serverAddress; -
439 -
440 if (connect(sock, (struct sockaddr *) &destPort, sizeof(destPort))) { -
441 close(sock); -
442 return FTPERR_FAILED_CONNECT; -
443 } -
444 -
445 buf = proxyprotocol ? asprintf_("GET %s://%s%s HTTP/1.0\r\nHost: %s\r\n\r\n", proxyprotocol, hostname, remotename, hostname) -
446 : asprintf_("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", remotename, hostname); -
447 -
448 write(sock, buf, strlen(buf)); -
449 -
450 /* This is fun; read the response a character at a time until we: -
451 -
452 1) Get our first \r\n; which lets us check the return code -
453 2) Get a \r\n\r\n, which means we're done */ -
454 -
455 *nextChar = '\0'; -
456 statusCode = 0; -
457 while (!strstr(headers, "\r\n\r\n")) { -
458 polls.fd = sock; -
459 polls.events = POLLIN; -
460 rc = poll(&polls, 1, TIMEOUT_SECS*1000); -
461 -
462 if (rc == 0) { -
463 close(sock); -
464 return FTPERR_SERVER_TIMEOUT; -
465 } else if (rc < 0) { -
466 close(sock); -
467 return FTPERR_SERVER_IO_ERROR; -
468 } -
469 -
470 if (read(sock, nextChar, 1) != 1) { -
471 close(sock); -
472 return FTPERR_SERVER_IO_ERROR; -
473 } -
474 -
475 nextChar++; -
476 *nextChar = '\0'; -
477 -
478 if (nextChar - headers == sizeof(headers)) { -
479 close(sock); -
480 return FTPERR_SERVER_IO_ERROR; -
481 } -
482 -
483 if (!statusCode && strstr(headers, "\r\n")) { -
484 char * start, * end; -
485 -
486 start = headers; -
487 while (!isspace(*start) && *start) start++; -
488 if (!*start) { -
489 close(sock); -
490 return FTPERR_SERVER_IO_ERROR; -
491 } -
492 start++; -
493 -
494 end = start; -
495 while (!isspace(*end) && *end) end++; -
496 if (!*end) { -
497 close(sock); -
498 return FTPERR_SERVER_IO_ERROR; -
499 } -
500 -
501 *end = '\0'; -
502 log_message("HTTP: server response '%s'", start); -
503 if (streq(start, "404")) { -
504 close(sock); -
505 return FTPERR_FILE_NOT_FOUND; -
506 } else if (streq(start, "302")) { -
507 log_message("HTTP: found, but document has moved"); -
508 statusCode = 302; -
509 } else if (streq(start, "200")) { -
510 statusCode = 200; -
511 } else { -
512 close(sock); -
513 return FTPERR_BAD_SERVER_RESPONSE; -
514 } -
515 -
516 *end = ' '; -
517 } -
518 } -
519 -
520 if (statusCode == 302) { -
521 if (recursion >= HTTP_MAX_RECURSION) { -
522 log_message("HTTP: too many levels of recursion, aborting"); -
523 close(sock); -
524 return FTPERR_UNKNOWN; -
525 } -
526 if ((buf = strstr(headers, header_location))) { -
527 char * found_host; -
528 char *found_file; -
529 found_host = buf + strlen(header_location); -
530 if ((found_file = index(found_host, '/'))) { -
531 if ((buf = index(found_file, '\r'))) { -
532 buf[0] = '\0'; -
533 remotename = strdup(found_file); -
534 found_file[0] = '\0'; -
535 hostname = strdup(found_host); -
536 log_message("HTTP: redirected to new host \"%s\" and file \"%s\"", hostname, remotename); -
537 } -
538 } -
539 -
540 } -
541 /* -
542 * don't fail if new URL can't be parsed, -
543 * asking the same URL may work if the DNS server are doing round-robin -
544 */ -
545 return _http_download_file(hostname, remotename, size, proxyprotocol, proxyname, proxyport, recursion + 1); -
546 } -
547 -
548 if ((buf = strstr(headers, header_content_length))) -
549 *size = charstar_to_int(buf + strlen(header_content_length)); -
550 else -
551 *size = 0; -
552 -
553 return sock; -
554} -
555 -
556 -
557int http_download_file(char * hostname, char * remotename, int * size, char * proxyprotocol, char * proxyname, char * proxyport) -
558{ -
559 return _http_download_file(hostname, remotename, size, proxyprotocol, proxyname, proxyport, 0); -
560} -
-
- - - -
-
-

Properties

- - - - - - - - - - - - - - - - - -
NameValue
svn:eol-stylenative -
-
- - - -
- - - - - - - - - -
 ViewVC Help
Powered by ViewVC 1.1.15 
- - - +/* + * Guillaume Cottenceau (gc) + * + * Copyright 2000 Mandriva + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * Portions from Erik Troan and Matt Wilson + * + * Copyright 1999 Red Hat, Inc. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "dns.h" +#include "log.h" +#include "tools.h" +#include "utils.h" + +#include "url.h" + + +#define TIMEOUT_SECS 60 +#define BUFFER_SIZE 4096 +#define HTTP_MAX_RECURSION 5 + + +static int ftp_check_response(int sock, char ** str) +{ + static char buf[BUFFER_SIZE + 1]; + int bufLength = 0; + struct pollfd polls; + char * chptr, * start; + int bytesRead, rc = 0; + int doesContinue = 1; + char errorCode[4]; + + errorCode[0] = '\0'; + + do { + polls.fd = sock; + polls.events = POLLIN; + if (poll(&polls, 1, TIMEOUT_SECS*1000) != 1) + return FTPERR_BAD_SERVER_RESPONSE; + + bytesRead = read(sock, buf + bufLength, sizeof(buf) - bufLength - 1); + + bufLength += bytesRead; + + buf[bufLength] = '\0'; + + /* divide the response into lines, checking each one to see if + we are finished or need to continue */ + + start = chptr = buf; + + do { + while (*chptr != '\n' && *chptr) chptr++; + + if (*chptr == '\n') { + *chptr = '\0'; + if (*(chptr - 1) == '\r') *(chptr - 1) = '\0'; + if (str) *str = start; + + if (errorCode[0]) { + if (!strncmp(start, errorCode, 3) && start[3] == ' ') + doesContinue = 0; + } else { + strncpy(errorCode, start, 3); + errorCode[3] = '\0'; + if (start[3] != '-') { + doesContinue = 0; + } + } + + start = chptr + 1; + chptr++; + } else { + chptr++; + } + } while (*chptr); + + if (doesContinue && chptr > start) { + memcpy(buf, start, chptr - start - 1); + bufLength = chptr - start - 1; + } else { + bufLength = 0; + } + } while (doesContinue); + + if (*errorCode == '4' || *errorCode == '5') { + if (!strncmp(errorCode, "550", 3)) { + return FTPERR_FILE_NOT_FOUND; + } + + return FTPERR_BAD_SERVER_RESPONSE; + } + + if (rc) return rc; + + return 0; +} + +static int ftp_command(int sock, char * command, char * param) +{ + char buf[500]; + int rc; + + snprintf(buf, sizeof(buf), "%s%s%s\r\n", command, param ? " " : "", param ? param : ""); + + if (write(sock, buf, strlen(buf)) != (ssize_t)strlen(buf)) { + return FTPERR_SERVER_IO_ERROR; + } + + if ((rc = ftp_check_response(sock, NULL))) + return rc; + + return 0; +} + +static int get_host_address(char * host, struct in_addr * address) +{ + if (isdigit(host[0])) { + if (!inet_aton(host, address)) { + return FTPERR_BAD_HOST_ADDR; + } + } else { + if (mygethostbyname(host, address)) + return FTPERR_BAD_HOSTNAME; + } + + return 0; +} + +int ftp_open_connection(char * host, char * name, char * password, char * proxy) +{ + int sock; + struct in_addr serverAddress; + struct sockaddr_in destPort; + int rc; + int port = 21; + + if (!strcmp(name, "")) { + name = "anonymous"; + password = "-drakx@"; + } + + if (strcmp(proxy, "")) { + name = asprintf_("%s@%s", name, host); + host = proxy; + } + + if ((rc = get_host_address(host, &serverAddress))) return rc; + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + if (sock < 0) { + return FTPERR_FAILED_CONNECT; + } + + destPort.sin_family = AF_INET; + destPort.sin_port = htons(port); + destPort.sin_addr = serverAddress; + + if (connect(sock, (struct sockaddr *) &destPort, sizeof(destPort))) { + close(sock); + return FTPERR_FAILED_CONNECT; + } + + /* ftpCheckResponse() assumes the socket is nonblocking */ + if (fcntl(sock, F_SETFL, O_NONBLOCK)) { + close(sock); + return FTPERR_FAILED_CONNECT; + } + + if ((rc = ftp_check_response(sock, NULL))) { + return rc; + } + + if ((rc = ftp_command(sock, "USER", name))) { + close(sock); + return rc; + } + + if ((rc = ftp_command(sock, "PASS", password))) { + close(sock); + return rc; + } + + if ((rc = ftp_command(sock, "TYPE", "I"))) { + close(sock); + return rc; + } + + return sock; +} + + +int ftp_data_command(int sock, char * command, char * param) +{ + int dataSocket; + struct sockaddr_in dataAddress; + int i, j; + char * passReply; + char * chptr; + char retrCommand[500]; + int rc; + + if (write(sock, "PASV\r\n", 6) != 6) { + return FTPERR_SERVER_IO_ERROR; + } + if ((rc = ftp_check_response(sock, &passReply))) + return FTPERR_PASSIVE_ERROR; + + chptr = passReply; + while (*chptr && *chptr != '(') chptr++; + if (*chptr != '(') return FTPERR_PASSIVE_ERROR; + chptr++; + passReply = chptr; + while (*chptr && *chptr != ')') chptr++; + if (*chptr != ')') return FTPERR_PASSIVE_ERROR; + *chptr-- = '\0'; + + while (*chptr && *chptr != ',') chptr--; + if (*chptr != ',') return FTPERR_PASSIVE_ERROR; + chptr--; + while (*chptr && *chptr != ',') chptr--; + if (*chptr != ',') return FTPERR_PASSIVE_ERROR; + *chptr++ = '\0'; + + /* now passReply points to the IP portion, and chptr points to the + port number portion */ + + dataAddress.sin_family = AF_INET; + if (sscanf(chptr, "%d,%d", &i, &j) != 2) { + return FTPERR_PASSIVE_ERROR; + } + dataAddress.sin_port = htons((i << 8) + j); + + chptr = passReply; + while (*chptr++) { + if (*chptr == ',') *chptr = '.'; + } + + if (!inet_aton(passReply, &dataAddress.sin_addr)) + return FTPERR_PASSIVE_ERROR; + + dataSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + if (dataSocket < 0) { + return FTPERR_FAILED_CONNECT; + } + + if (!param) + sprintf(retrCommand, "%s\r\n", command); + else + sprintf(retrCommand, "%s %s\r\n", command, param); + + i = strlen(retrCommand); + + if (write(sock, retrCommand, i) != i) { + return FTPERR_SERVER_IO_ERROR; + } + + if (connect(dataSocket, (struct sockaddr *) &dataAddress, + sizeof(dataAddress))) { + close(dataSocket); + return FTPERR_FAILED_DATA_CONNECT; + } + + if ((rc = ftp_check_response(sock, NULL))) { + close(dataSocket); + return rc; + } + + return dataSocket; +} + + +int ftp_get_filesize(int sock, char * remotename) +{ + int size = 0; + char buf[2000]; + char file[500]; + char * ptr; + int fd, rc, tot; + int i; + + strcpy(buf, remotename); + ptr = strrchr(buf, '/'); + if (!*ptr) + return -1; + *ptr = '\0'; + + strcpy(file, ptr+1); + + if ((rc = ftp_command(sock, "CWD", buf))) { + return -1; + } + + fd = ftp_data_command(sock, "LIST", file); + if (fd <= 0) { + close(sock); + return -1; + } + + ptr = buf; + while ((tot = read(fd, ptr, sizeof(buf) - (ptr - buf) - 1)) != 0) + ptr += tot; + *ptr = '\0'; + close(fd); + + if (!(ptr = strstr(buf, file))) { + log_message("FTP/get_filesize: Bad mood, directory does not contain searched file (%s)", file); + if (ftp_end_data_command(sock)) + close(sock); + return -1; + } + + for (i=0; i<4; i++) { + while (*ptr && *ptr != ' ') + ptr--; + while (*ptr && *ptr == ' ') + ptr--; + } + while (*ptr && *ptr != ' ') + ptr--; + + if (ptr) + size = charstar_to_int(ptr+1); + else + size = 0; + + if (ftp_end_data_command(sock)) { + close(sock); + return -1; + } + + return size; +} + + +int ftp_start_download(int sock, char * remotename, int * size) +{ + if ((*size = ftp_get_filesize(sock, remotename)) == -1) { + log_message("FTP: could not get filesize (trying to continue)"); + *size = 0; + } + return ftp_data_command(sock, "RETR", remotename); +} + + +int ftp_end_data_command(int sock) +{ + if (ftp_check_response(sock, NULL)) + return FTPERR_BAD_SERVER_RESPONSE; + + return 0; +} + + +char *str_ftp_error(int error) +{ + return error == FTPERR_PASSIVE_ERROR ? "error with passive connection" : + error == FTPERR_FAILED_CONNECT ? "couldn't connect to server" : + error == FTPERR_FILE_NOT_FOUND ? "file not found" : + error == FTPERR_BAD_SERVER_RESPONSE ? "bad server response (server too busy?)" : + NULL; +} + + +static int _http_download_file(char * hostname, char * remotename, int * size, char * proxyprotocol, char * proxyname, char * proxyport, int recursion) +{ + char * buf; + char headers[4096]; + char * nextChar = headers; + int statusCode; + struct in_addr serverAddress; + struct pollfd polls; + int sock; + int rc; + struct sockaddr_in destPort; + const char * header_content_length = "Content-Length: "; + const char * header_location = "Location: http://"; + char * http_server_name; + int http_server_port; + + if (proxyprotocol) { + http_server_name = proxyname; + http_server_port = atoi(proxyport); + } else { + http_server_name = hostname; + http_server_port = 80; + } + + log_message("HTTP: connecting to server %s:%i (%s)", + http_server_name, http_server_port, + proxyprotocol ? "proxy" : "no proxy"); + + if ((rc = get_host_address(http_server_name, &serverAddress))) return rc; + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + if (sock < 0) { + return FTPERR_FAILED_CONNECT; + } + + destPort.sin_family = AF_INET; + destPort.sin_port = htons(http_server_port); + destPort.sin_addr = serverAddress; + + if (connect(sock, (struct sockaddr *) &destPort, sizeof(destPort))) { + close(sock); + return FTPERR_FAILED_CONNECT; + } + + buf = proxyprotocol ? asprintf_("GET %s://%s%s HTTP/1.0\r\nHost: %s\r\n\r\n", proxyprotocol, hostname, remotename, hostname) + : asprintf_("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", remotename, hostname); + + write(sock, buf, strlen(buf)); + + /* This is fun; read the response a character at a time until we: + + 1) Get our first \r\n; which lets us check the return code + 2) Get a \r\n\r\n, which means we're done */ + + *nextChar = '\0'; + statusCode = 0; + while (!strstr(headers, "\r\n\r\n")) { + polls.fd = sock; + polls.events = POLLIN; + rc = poll(&polls, 1, TIMEOUT_SECS*1000); + + if (rc == 0) { + close(sock); + return FTPERR_SERVER_TIMEOUT; + } else if (rc < 0) { + close(sock); + return FTPERR_SERVER_IO_ERROR; + } + + if (read(sock, nextChar, 1) != 1) { + close(sock); + return FTPERR_SERVER_IO_ERROR; + } + + nextChar++; + *nextChar = '\0'; + + if (nextChar - headers == sizeof(headers)) { + close(sock); + return FTPERR_SERVER_IO_ERROR; + } + + if (!statusCode && strstr(headers, "\r\n")) { + char * start, * end; + + start = headers; + while (!isspace(*start) && *start) start++; + if (!*start) { + close(sock); + return FTPERR_SERVER_IO_ERROR; + } + start++; + + end = start; + while (!isspace(*end) && *end) end++; + if (!*end) { + close(sock); + return FTPERR_SERVER_IO_ERROR; + } + + *end = '\0'; + log_message("HTTP: server response '%s'", start); + if (streq(start, "404")) { + close(sock); + return FTPERR_FILE_NOT_FOUND; + } else if (streq(start, "302")) { + log_message("HTTP: found, but document has moved"); + statusCode = 302; + } else if (streq(start, "200")) { + statusCode = 200; + } else { + close(sock); + return FTPERR_BAD_SERVER_RESPONSE; + } + + *end = ' '; + } + } + + if (statusCode == 302) { + if (recursion >= HTTP_MAX_RECURSION) { + log_message("HTTP: too many levels of recursion, aborting"); + close(sock); + return FTPERR_UNKNOWN; + } + if ((buf = strstr(headers, header_location))) { + char * found_host; + char *found_file; + found_host = buf + strlen(header_location); + if ((found_file = index(found_host, '/'))) { + if ((buf = index(found_file, '\r'))) { + buf[0] = '\0'; + remotename = strdup(found_file); + found_file[0] = '\0'; + hostname = strdup(found_host); + log_message("HTTP: redirected to new host \"%s\" and file \"%s\"", hostname, remotename); + } + } + + } + /* + * don't fail if new URL can't be parsed, + * asking the same URL may work if the DNS server are doing round-robin + */ + return _http_download_file(hostname, remotename, size, proxyprotocol, proxyname, proxyport, recursion + 1); + } + + if ((buf = strstr(headers, header_content_length))) + *size = charstar_to_int(buf + strlen(header_content_length)); + else + *size = 0; + + return sock; +} + + +int http_download_file(char * hostname, char * remotename, int * size, char * proxyprotocol, char * proxyname, char * proxyport) +{ + return _http_download_file(hostname, remotename, size, proxyprotocol, proxyname, proxyport, 0); +} -- cgit v1.2.1