]> git.pld-linux.org Git - packages/apt.git/blame - apt-newmethods.patch
- readline 5.0
[packages/apt.git] / apt-newmethods.patch
CommitLineData
3cc90fba
AM
1diff -urN apt-0.3.19cnc52.org/apt-pkg/acquire-method.cc apt-0.3.19cnc52/apt-pkg/acquire-method.cc
2--- apt-0.3.19cnc52.org/apt-pkg/acquire-method.cc Thu Sep 6 22:20:42 2001
3+++ apt-0.3.19cnc52/apt-pkg/acquire-method.cc Sat Sep 8 13:18:36 2001
4@@ -97,7 +97,8 @@
5 if (Queue != 0)
6 {
7 snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: %s\n"
8- "Message: %s\n",Queue->Uri.c_str(),Err.c_str());
9+ "Message: %s %s\n",Queue->Uri.c_str(),Err.c_str(),
10+ FailExtra.c_str());
11
12 // Dequeue
13 FetchItem *Tmp = Queue;
14@@ -108,7 +109,8 @@
15 }
16 else
17 snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: <UNKNOWN>\n"
18- "Message: %s\n",Err.c_str());
19+ "Message: %s %s\n",Err.c_str(),
20+ FailExtra.c_str());
21
22 // Set the transient flag
23 if (Transient == true)
24diff -urN apt-0.3.19cnc52.org/apt-pkg/acquire-method.h apt-0.3.19cnc52/apt-pkg/acquire-method.h
25--- apt-0.3.19cnc52.org/apt-pkg/acquire-method.h Thu Sep 6 22:20:42 2001
26+++ apt-0.3.19cnc52/apt-pkg/acquire-method.h Sat Sep 8 13:15:34 2001
27@@ -50,6 +50,7 @@
28 vector<string> Messages;
29 FetchItem *Queue;
30 FetchItem *QueueBack;
31+ string FailExtra;
32
33 // Handlers for messages
34 virtual bool Configuration(string Message);
35@@ -75,6 +76,7 @@
36 void Status(const char *Format,...);
37
38 int Run(bool Single = false);
39+ inline void SetFailExtraMsg(string Msg) {FailExtra = Msg;};
40
41 pkgAcqMethod(const char *Ver,unsigned long Flags = 0);
42 virtual ~pkgAcqMethod() {};
43diff -urN apt-0.3.19cnc52.org/apt-pkg/contrib/strutl.cc apt-0.3.19cnc52/apt-pkg/contrib/strutl.cc
44--- apt-0.3.19cnc52.org/apt-pkg/contrib/strutl.cc Thu Sep 6 22:20:42 2001
45+++ apt-0.3.19cnc52/apt-pkg/contrib/strutl.cc Sat Sep 8 12:54:40 2001
46@@ -861,7 +861,29 @@
47 return Hits;
48 }
49 /*}}}*/
50-
51+// CheckDomainList - See if Host is in a , seperate list /*{{{*/
52+// ---------------------------------------------------------------------
53+/* The domain list is a comma seperate list of domains that are suffix
54+ matched against the argument */
55+bool CheckDomainList(string Host,string List)
56+{
57+ string::const_iterator Start = List.begin();
58+ for (string::const_iterator Cur = List.begin(); Cur <= List.end(); Cur++)
59+ {
60+ if (Cur < List.end() && *Cur != ',')
61+ continue;
62+
63+ // Match the end of the string..
64+ if ((Host.size() >= (unsigned)(Cur - Start)) &&
65+ Cur - Start != 0 &&
66+ stringcasecmp(Host.end() - (Cur - Start),Host.end(),Start,Cur) == 0)
67+ return true;
68+
69+ Start = Cur + 1;
70+ }
71+ return false;
72+}
73+ /*}}}*/
74 // URI::CopyFrom - Copy from an object /*{{{*/
75 // ---------------------------------------------------------------------
76 /* This parses the URI into all of its components */
77diff -urN apt-0.3.19cnc52.org/apt-pkg/contrib/strutl.h apt-0.3.19cnc52/apt-pkg/contrib/strutl.h
78--- apt-0.3.19cnc52.org/apt-pkg/contrib/strutl.h Thu Sep 6 22:20:42 2001
79+++ apt-0.3.19cnc52/apt-pkg/contrib/strutl.h Sat Sep 8 12:53:14 2001
80@@ -45,6 +45,7 @@
81 unsigned int Length);
82 bool TokSplitString(char Tok,char *Input,char **List,
83 unsigned long ListMax);
84+bool CheckDomainList(string Host,string List);
85
86 int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
87 inline int stringcmp(const char *A,const char *AEnd,const char *B) {return stringcmp(A,AEnd,B,B+strlen(B));};
88diff -urN apt-0.3.19cnc52.org/methods/connect.cc apt-0.3.19cnc52/methods/connect.cc
89--- apt-0.3.19cnc52.org/methods/connect.cc Thu Sep 6 22:20:43 2001
90+++ apt-0.3.19cnc52/methods/connect.cc Tue Feb 20 08:03:18 2001
91@@ -1,6 +1,6 @@
92 // -*- mode: cpp; mode: fold -*-
93 // Description /*{{{*/
94-// $Id$
95+// $Id$
96 /* ######################################################################
97
98 Connect - Replacement connect call
99@@ -30,6 +30,18 @@
100 static struct addrinfo *LastHostAddr = 0;
101 static struct addrinfo *LastUsed = 0;
102
103+// RotateDNS - Select a new server from a DNS rotation /*{{{*/
104+// ---------------------------------------------------------------------
105+/* This is called during certain errors in order to recover by selecting a
106+ new server */
107+void RotateDNS()
108+{
109+ if (LastUsed != 0 && LastUsed->ai_next != 0)
110+ LastUsed = LastUsed->ai_next;
111+ else
112+ LastUsed = LastHostAddr;
113+}
114+ /*}}}*/
115 // DoConnect - Attempt a connect operation /*{{{*/
116 // ---------------------------------------------------------------------
117 /* This helper function attempts a connection to a single address. */
118@@ -38,28 +50,44 @@
119 {
120 // Show a status indicator
121 char Name[NI_MAXHOST];
122- Name[0] = 0;
123+ char Service[NI_MAXSERV];
124+
125+ Name[0] = 0;
126+ Service[0] = 0;
127 getnameinfo(Addr->ai_addr,Addr->ai_addrlen,
128- Name,sizeof(Name),0,0,NI_NUMERICHOST);
129+ Name,sizeof(Name),Service,sizeof(Service),
130+ NI_NUMERICHOST|NI_NUMERICSERV);
131 Owner->Status("Connecting to %s (%s)",Host.c_str(),Name);
132-
133+
134+ /* If this is an IP rotation store the IP we are using.. If something goes
135+ wrong this will get tacked onto the end of the error message */
136+ if (LastHostAddr->ai_next != 0)
137+ {
138+ char Name2[NI_MAXHOST + NI_MAXSERV + 10];
139+ snprintf(Name2,sizeof(Name2),"[IP: %s %s]",Name,Service);
140+ Owner->SetFailExtraMsg(string(Name2));
141+ }
142+ else
143+ Owner->SetFailExtraMsg("");
144+
145 // Get a socket
146 if ((Fd = socket(Addr->ai_family,Addr->ai_socktype,
147 Addr->ai_protocol)) < 0)
148- return _error->Errno("socket","Could not create a socket");
149+ return _error->Errno("socket","Could not create a socket for %s (f=%u t=%u p=%u)",
150+ Name,Addr->ai_family,Addr->ai_socktype,Addr->ai_protocol);
151
152 SetNonBlock(Fd,true);
153 if (connect(Fd,Addr->ai_addr,Addr->ai_addrlen) < 0 &&
154 errno != EINPROGRESS)
155 return _error->Errno("connect","Cannot initiate the connection "
156- "to %s (%s).",Host.c_str(),Name);
157+ "to %s:%s (%s).",Host.c_str(),Service,Name);
158
159 /* This implements a timeout for connect by opening the connection
160 nonblocking */
161 if (WaitFd(Fd,true,TimeOut) == false)
162- return _error->Error("Could not connect to %s (%s), "
163- "connection timed out",Host.c_str(),Name);
164-
165+ return _error->Error("Could not connect to %s:%s (%s), "
166+ "connection timed out",Host.c_str(),Service,Name);
167+
168 // Check the socket for an error condition
169 unsigned int Err;
170 unsigned int Len = sizeof(Err);
171@@ -67,8 +95,12 @@
172 return _error->Errno("getsockopt","Failed");
173
174 if (Err != 0)
175- return _error->Error("Could not connect to %s (%s).",Host.c_str(),Name);
176-
177+ {
178+ errno = Err;
179+ return _error->Errno("connect","Could not connect to %s:%s (%s).",Host.c_str(),
180+ Service,Name);
181+ }
182+
183 return true;
184 }
185 /*}}}*/
186@@ -80,6 +112,13 @@
187 {
188 if (_error->PendingError() == true)
189 return false;
190+
191+ // Convert the port name/number
192+ char ServStr[300];
193+ if (Port != 0)
194+ snprintf(ServStr,sizeof(ServStr),"%u",Port);
195+ else
196+ snprintf(ServStr,sizeof(ServStr),"%s",Service);
197
198 /* We used a cached address record.. Yes this is against the spec but
199 the way we have setup our rotating dns suggests that this is more
200@@ -88,59 +127,49 @@
201 {
202 Owner->Status("Connecting to %s",Host.c_str());
203
204- // Lookup the host
205- char S[300];
206- if (Port != 0)
207- snprintf(S,sizeof(S),"%u",Port);
208- else
209- snprintf(S,sizeof(S),"%s",Service);
210-
211 // Free the old address structure
212 if (LastHostAddr != 0)
213 {
214 freeaddrinfo(LastHostAddr);
215 LastHostAddr = 0;
216+ LastUsed = 0;
217 }
218
219 // We only understand SOCK_STREAM sockets.
220 struct addrinfo Hints;
221 memset(&Hints,0,sizeof(Hints));
222 Hints.ai_socktype = SOCK_STREAM;
223- Hints.ai_protocol = IPPROTO_TCP; // Right?
224+ Hints.ai_protocol = 0;
225
226 // Resolve both the host and service simultaneously
227 while (1)
228 {
229 int Res;
230- if ((Res = getaddrinfo(Host.c_str(),S,&Hints,&LastHostAddr)) != 0 ||
231+ if ((Res = getaddrinfo(Host.c_str(),ServStr,&Hints,&LastHostAddr)) != 0 ||
232 LastHostAddr == 0)
233 {
234 if (Res == EAI_NONAME || Res == EAI_SERVICE)
235 {
236 if (DefPort != 0)
237 {
238- snprintf(S,sizeof(S),"%u",DefPort);
239+ snprintf(ServStr,sizeof(ServStr),"%u",DefPort);
240 DefPort = 0;
241 continue;
242 }
243 return _error->Error("Could not resolve '%s'",Host.c_str());
244 }
245
246- return _error->Error("Something wicked happend resolving '%s/%s'",
247- Host.c_str(),S);
248+ return _error->Error("Something wicked happened resolving '%s:%s' (%i)",
249+ Host.c_str(),ServStr,Res);
250 }
251 break;
252 }
253
254- if (LastHostAddr->ai_family == AF_UNIX)
255- return _error->Error("getaddrinfo returned a unix domain socket\n");
256-
257 LastHost = Host;
258 LastPort = Port;
259- LastUsed = 0;
260 }
261
262- // Get the printable IP address
263+ // When we have an IP rotation stay with the last IP.
264 struct addrinfo *CurHost = LastHostAddr;
265 if (LastUsed != 0)
266 CurHost = LastUsed;
267@@ -155,14 +184,28 @@
268 close(Fd);
269 Fd = -1;
270
271- CurHost = CurHost->ai_next;
272- LastUsed = 0;
273+ // Ignore UNIX domain sockets
274+ do
275+ {
276+ CurHost = CurHost->ai_next;
277+ }
278+ while (CurHost != 0 && CurHost->ai_family == AF_UNIX);
279+
280+ /* If we reached the end of the search list then wrap around to the
281+ start */
282+ if (CurHost == 0 && LastUsed != 0)
283+ CurHost = LastHostAddr;
284+
285+ // Reached the end of the search cycle
286+ if (CurHost == LastUsed)
287+ break;
288+
289 if (CurHost != 0)
290 _error->Discard();
291- }
292-
293+ }
294+
295 if (_error->PendingError() == true)
296- return false;
297- return _error->Error("Unable to connect to '%s'",Host.c_str());
298+ return false;
299+ return _error->Error("Unable to connect to %s %s:",Host.c_str(),ServStr);
300 }
301 /*}}}*/
302diff -urN apt-0.3.19cnc52.org/methods/connect.h apt-0.3.19cnc52/methods/connect.h
303--- apt-0.3.19cnc52.org/methods/connect.h Thu Sep 6 22:20:43 2001
304+++ apt-0.3.19cnc52/methods/connect.h Tue Feb 20 08:03:18 2001
305@@ -1,6 +1,6 @@
306 // -*- mode: cpp; mode: fold -*-
307 // Description /*{{{*/
308-// $Id$
309+// $Id$
310 /* ######################################################################
311
312 Connect - Replacement connect call
313@@ -15,5 +15,6 @@
314
315 bool Connect(string To,int Port,const char *Service,int DefPort,
316 int &Fd,unsigned long TimeOut,pkgAcqMethod *Owner);
317+void RotateDNS();
318
319 #endif
320diff -urN apt-0.3.19cnc52.org/methods/ftp.cc apt-0.3.19cnc52/methods/ftp.cc
321--- apt-0.3.19cnc52.org/methods/ftp.cc Thu Sep 6 22:20:43 2001
322+++ apt-0.3.19cnc52/methods/ftp.cc Sat Sep 8 12:33:40 2001
323@@ -1,9 +1,9 @@
324 // -*- mode: cpp; mode: fold -*-
325 // Description /*{{{*/
326-// $Id$
327+// $Id$
328 /* ######################################################################
329
330- HTTP Aquire Method - This is the FTP aquire method for APT.
331+ FTP Aquire Method - This is the FTP aquire method for APT.
332
333 This is a very simple implementation that does not try to optimize
334 at all. Commands are sent syncronously with the FTP server (as the
335@@ -28,6 +28,7 @@
336 #include <stdio.h>
337 #include <errno.h>
338 #include <stdarg.h>
339+#include <iostream>
340
341 // Internet stuff
342 #include <netinet/in.h>
343@@ -40,6 +41,22 @@
344 #include "ftp.h"
345 /*}}}*/
346
347+using namespace std;
348+
349+/* This table is for the EPRT and EPSV commands, it maps the OS address
350+ family to the IETF address families */
351+struct AFMap
352+{
353+ unsigned long Family;
354+ unsigned long IETFFamily;
355+};
356+
357+#ifndef AF_INET6
358+struct AFMap AFMap[] = {{AF_INET,1},{}};
359+#else
360+struct AFMap AFMap[] = {{AF_INET,1},{AF_INET6,2},{}};
361+#endif
362+
363 unsigned long TimeOut = 120;
364 URI Proxy;
365 string FtpMethod::FailFile;
366@@ -53,7 +70,7 @@
367 DataListenFd(-1), ServerName(Srv)
368 {
369 Debug = _config->FindB("Debug::Acquire::Ftp",false);
370- memset(&PasvAddr,0,sizeof(PasvAddr));
371+ PasvAddr = 0;
372 }
373 /*}}}*/
374 // FTPConn::~FTPConn - Destructor /*{{{*/
375@@ -75,7 +92,10 @@
376 DataFd = -1;
377 close(DataListenFd);
378 DataListenFd = -1;
379- memset(&PasvAddr,0,sizeof(PasvAddr));
380+
381+ if (PasvAddr != 0)
382+ freeaddrinfo(PasvAddr);
383+ PasvAddr = 0;
384 }
385 /*}}}*/
386 // FTPConn::Open - Open a new connection /*{{{*/
387@@ -89,7 +109,7 @@
388 return true;
389
390 Close();
391-
392+
393 // Determine the proxy setting
394 if (getenv("ftp_proxy") == 0)
395 {
396@@ -108,32 +128,13 @@
397 else
398 Proxy = getenv("ftp_proxy");
399
400- // Parse no_proxy, a , seperated list of domains
401+ // Parse no_proxy, a , separated list of domains
402 if (getenv("no_proxy") != 0)
403 {
404- const char *Start = getenv("no_proxy");
405- const char *ServerEnd = ServerName.Host.end();
406-
407- for (const char *Cur = Start; true ; Cur++)
408- {
409- if (*Cur != ',' && *Cur != 0)
410- continue;
411-
412- // match end of the string
413- if ((ServerName.Host.size() >= (Cur - Start))
414- && stringcasecmp(ServerEnd - (Cur - Start),
415- ServerEnd,Start,Cur) == 0)
416- {
417- Proxy = "";
418- break;
419- }
420-
421- Start = Cur + 1;
422- if (*Cur == 0)
423- break;
424- }
425+ if (CheckDomainList(ServerName.Host,getenv("no_proxy")) == true)
426+ Proxy = "";
427 }
428-
429+
430 // Determine what host and port to use based on the proxy settings
431 int Port = 0;
432 string Host;
433@@ -150,15 +151,27 @@
434 Host = Proxy.Host;
435 }
436
437- // Connect to the remote server
438+ /* Connect to the remote server. Since FTP is connection oriented we
439+ want to make sure we get a new server every time we reconnect */
440+ RotateDNS();
441 if (Connect(Host,Port,"ftp",21,ServerFd,TimeOut,Owner) == false)
442 return false;
443- socklen_t Len = sizeof(Peer);
444- if (getpeername(ServerFd,(sockaddr *)&Peer,&Len) != 0)
445+
446+ // Login must be before getpeername otherwise dante won't work.
447+ Owner->Status("Logging in");
448+ bool Res = Login();
449+
450+ // Get the remote server's address
451+ PeerAddrLen = sizeof(PeerAddr);
452+ if (getpeername(ServerFd,(sockaddr *)&PeerAddr,&PeerAddrLen) != 0)
453 return _error->Errno("getpeername","Unable to determine the peer name");
454
455- Owner->Status("Logging in");
456- return Login();
457+ // Get the local machine's address
458+ ServerAddrLen = sizeof(ServerAddr);
459+ if (getsockname(ServerFd,(sockaddr *)&ServerAddr,&ServerAddrLen) != 0)
460+ return _error->Errno("getsockname","Unable to determine the local name");
461+
462+ return Res;
463 }
464 /*}}}*/
465 // FTPConn::Login - Login to the remote server /*{{{*/
466@@ -172,11 +185,7 @@
467
468 // Setup the variables needed for authentication
469 string User = "anonymous";
470- string Pass;
471- if (0) //akk
472- Pass = "apt_get_ftp_2.0@debian.linux.user";
473- else
474- Pass = "apt_get_ftp_2.0@conectiva.linux.user";
475+ string Pass = "apt_get_ftp_2.0@pld.linux.user";
476
477 // Fill in the user/pass
478 if (ServerName.User.empty() == false)
479@@ -209,7 +218,7 @@
480 if (_config->Exists("Acquire::FTP::Passive::" + ServerName.Host) == true)
481 TryPassive = _config->FindB("Acquire::FTP::Passive::" + ServerName.Host,true);
482 else
483- TryPassive = _config->FindB("Acquire::FTP::Passive",true);
484+ TryPassive = _config->FindB("Acquire::FTP::Passive",true);
485 }
486 else
487 {
488@@ -266,6 +275,12 @@
489 }
490 }
491
492+ // Force the use of extended commands
493+ if (_config->Exists("Acquire::FTP::ForceExtended::" + ServerName.Host) == true)
494+ ForceExtended = _config->FindB("Acquire::FTP::ForceExtended::" + ServerName.Host,true);
495+ else
496+ ForceExtended = _config->FindB("Acquire::FTP::ForceExtended",false);
497+
498 // Binary mode
499 if (WriteMsg(Tag,Msg,"TYPE I") == false)
500 return false;
501@@ -313,6 +328,8 @@
502
503 // Suck it back
504 int Res = read(ServerFd,Buffer + Len,sizeof(Buffer) - Len);
505+ if (Res == 0)
506+ _error->Error("Server closed the connection");
507 if (Res <= 0)
508 {
509 _error->Errno("read","Read error");
510@@ -439,10 +456,19 @@
511 // ---------------------------------------------------------------------
512 /* Try to enter passive mode, the return code does not indicate if passive
513 mode could or could not be established, only if there was a fatal error.
514- Borrowed mostly from lftp. We have to enter passive mode every time
515- we make a data connection :| */
516+ We have to enter passive mode every time we make a data connection :| */
517 bool FTPConn::GoPasv()
518 {
519+ /* The PASV command only works on IPv4 sockets, even though it could
520+ in theory suppory IPv6 via an all zeros reply */
521+ if (((struct sockaddr *)&PeerAddr)->sa_family != AF_INET ||
522+ ForceExtended == true)
523+ return ExtGoPasv();
524+
525+ if (PasvAddr != 0)
526+ freeaddrinfo(PasvAddr);
527+ PasvAddr = 0;
528+
529 // Try to enable pasv mode
530 unsigned int Tag;
531 string Msg;
532@@ -452,41 +478,139 @@
533 // Unsupported function
534 string::size_type Pos = Msg.find('(');
535 if (Tag >= 400 || Pos == string::npos)
536- {
537- memset(&PasvAddr,0,sizeof(PasvAddr));
538 return true;
539- }
540
541 // Scan it
542 unsigned a0,a1,a2,a3,p0,p1;
543 if (sscanf(Msg.c_str() + Pos,"(%u,%u,%u,%u,%u,%u)",&a0,&a1,&a2,&a3,&p0,&p1) != 6)
544+ return true;
545+
546+ /* Some evil servers return 0 to mean their addr. We can actually speak
547+ to these servers natively using IPv6 */
548+ if (a0 == 0 && a1 == 0 && a2 == 0 && a3 == 0)
549 {
550- memset(&PasvAddr,0,sizeof(PasvAddr));
551+ // Get the IP in text form
552+ char Name[NI_MAXHOST];
553+ char Service[NI_MAXSERV];
554+ getnameinfo((struct sockaddr *)&PeerAddr,PeerAddrLen,
555+ Name,sizeof(Name),Service,sizeof(Service),
556+ NI_NUMERICHOST|NI_NUMERICSERV);
557+
558+ struct addrinfo Hints;
559+ memset(&Hints,0,sizeof(Hints));
560+ Hints.ai_socktype = SOCK_STREAM;
561+ Hints.ai_family = ((struct sockaddr *)&PeerAddr)->sa_family;
562+ Hints.ai_flags |= AI_NUMERICHOST;
563+
564+ // Get a new passive address.
565+ char Port[100];
566+ snprintf(Port,sizeof(Port),"%u",(p0 << 8) + p1);
567+ if (getaddrinfo(Name,Port,&Hints,&PasvAddr) != 0)
568+ return true;
569 return true;
570 }
571
572- // lftp used this horrid byte order manipulation.. Ik.
573- PasvAddr.sin_family = AF_INET;
574- unsigned char *a;
575- unsigned char *p;
576- a = (unsigned char *)&PasvAddr.sin_addr;
577- p = (unsigned char *)&PasvAddr.sin_port;
578+ struct addrinfo Hints;
579+ memset(&Hints,0,sizeof(Hints));
580+ Hints.ai_socktype = SOCK_STREAM;
581+ Hints.ai_family = AF_INET;
582+ Hints.ai_flags |= AI_NUMERICHOST;
583+
584+ // Get a new passive address.
585+ char Port[100];
586+ snprintf(Port,sizeof(Port),"%u",(p0 << 8) + p1);
587+ char Name[100];
588+ snprintf(Name,sizeof(Name),"%u.%u.%u.%u",a0,a1,a2,a3);
589+ if (getaddrinfo(Name,Port,&Hints,&PasvAddr) != 0)
590+ return true;
591+ return true;
592+}
593+ /*}}}*/
594+// FTPConn::ExtGoPasv - Enter Extended Passive mode /*{{{*/
595+// ---------------------------------------------------------------------
596+/* Try to enter extended passive mode. See GoPasv above and RFC 2428 */
597+bool FTPConn::ExtGoPasv()
598+{
599+ if (PasvAddr != 0)
600+ freeaddrinfo(PasvAddr);
601+ PasvAddr = 0;
602
603- // Some evil servers return 0 to mean their addr
604- if (a0 == 0 && a1 == 0 && a2 == 0 && a3 == 0)
605+ // Try to enable pasv mode
606+ unsigned int Tag;
607+ string Msg;
608+ if (WriteMsg(Tag,Msg,"EPSV") == false)
609+ return false;
610+
611+ // Unsupported function
612+ string::size_type Pos = Msg.find('(');
613+ if (Tag >= 400 || Pos == string::npos)
614+ return true;
615+
616+ // Scan it
617+ string::const_iterator List[4];
618+ unsigned Count = 0;
619+ Pos++;
620+ for (string::const_iterator I = Msg.begin() + Pos; I < Msg.end(); I++)
621 {
622- PasvAddr.sin_addr = Peer.sin_addr;
623+ if (*I != Msg[Pos])
624+ continue;
625+ if (Count >= 4)
626+ return true;
627+ List[Count++] = I;
628+ }
629+ if (Count != 4)
630+ return true;
631+
632+ // Break it up ..
633+ unsigned long Proto = 0;
634+ unsigned long Port = 0;
635+ string IP;
636+ IP = string(List[1]+1,List[2]);
637+ Port = atoi(string(List[2]+1,List[3]).c_str());
638+ if (IP.empty() == false)
639+ Proto = atoi(string(List[0]+1,List[1]).c_str());
640+
641+ if (Port == 0)
642+ return false;
643+
644+ // String version of the port
645+ char PStr[100];
646+ snprintf(PStr,sizeof(PStr),"%lu",Port);
647+
648+ // Get the IP in text form
649+ struct addrinfo Hints;
650+ memset(&Hints,0,sizeof(Hints));
651+ Hints.ai_socktype = SOCK_STREAM;
652+ Hints.ai_flags |= AI_NUMERICHOST;
653+
654+ /* The RFC defined case, connect to the old IP/protocol using the
655+ new port. */
656+ if (IP.empty() == true)
657+ {
658+ // Get the IP in text form
659+ char Name[NI_MAXHOST];
660+ char Service[NI_MAXSERV];
661+ getnameinfo((struct sockaddr *)&PeerAddr,PeerAddrLen,
662+ Name,sizeof(Name),Service,sizeof(Service),
663+ NI_NUMERICHOST|NI_NUMERICSERV);
664+ IP = Name;
665+ Hints.ai_family = ((struct sockaddr *)&PeerAddr)->sa_family;
666 }
667 else
668 {
669- a[0] = a0;
670- a[1] = a1;
671- a[2] = a2;
672- a[3] = a3;
673+ // Get the family..
674+ Hints.ai_family = 0;
675+ for (unsigned J = 0; AFMap[J].Family != 0; J++)
676+ if (AFMap[J].IETFFamily == Proto)
677+ Hints.ai_family = AFMap[J].Family;
678+ if (Hints.ai_family == 0)
679+ return true;
680 }
681
682- p[0] = p0;
683- p[1] = p1;
684+ // Get a new passive address.
685+ int Res;
686+ if ((Res = getaddrinfo(IP.c_str(),PStr,&Hints,&PasvAddr)) != 0)
687+ return true;
688
689 return true;
690 }
691@@ -547,34 +671,35 @@
692 return false;
693
694 // Oops, didn't work out, don't bother trying again.
695- if (PasvAddr.sin_port == 0)
696+ if (PasvAddr == 0)
697 TryPassive = false;
698 }
699
700 // Passive mode?
701- if (PasvAddr.sin_port != 0)
702+ if (PasvAddr != 0)
703 {
704 // Get a socket
705- if ((DataFd = socket(AF_INET,SOCK_STREAM,0)) < 0)
706+ if ((DataFd = socket(PasvAddr->ai_family,PasvAddr->ai_socktype,
707+ PasvAddr->ai_protocol)) < 0)
708 return _error->Errno("socket","Could not create a socket");
709
710 // Connect to the server
711 SetNonBlock(DataFd,true);
712- if (connect(DataFd,(sockaddr *)&PasvAddr,sizeof(PasvAddr)) < 0 &&
713+ if (connect(DataFd,PasvAddr->ai_addr,PasvAddr->ai_addrlen) < 0 &&
714 errno != EINPROGRESS)
715 return _error->Errno("socket","Could not create a socket");
716
717 /* This implements a timeout for connect by opening the connection
718 nonblocking */
719- if (WaitFd(ServerFd,true,TimeOut) == false)
720+ if (WaitFd(DataFd,true,TimeOut) == false)
721 return _error->Error("Could not connect data socket, connection timed out");
722 unsigned int Err;
723 unsigned int Len = sizeof(Err);
724- if (getsockopt(ServerFd,SOL_SOCKET,SO_ERROR,&Err,&Len) != 0)
725+ if (getsockopt(DataFd,SOL_SOCKET,SO_ERROR,&Err,&Len) != 0)
726 return _error->Errno("getsockopt","Failed");
727 if (Err != 0)
728- return _error->Error("Could not connect.");
729-
730+ return _error->Error("Could not connect passive socket.");
731+
732 return true;
733 }
734
735@@ -582,43 +707,91 @@
736 close(DataListenFd);
737 DataListenFd = -1;
738
739- // Get a socket
740- if ((DataListenFd = socket(AF_INET,SOCK_STREAM,0)) < 0)
741+ // Get the information for a listening socket.
742+ struct addrinfo *BindAddr = 0;
743+ struct addrinfo Hints;
744+ memset(&Hints,0,sizeof(Hints));
745+ Hints.ai_socktype = SOCK_STREAM;
746+ Hints.ai_flags |= AI_PASSIVE;
747+ Hints.ai_family = ((struct sockaddr *)&ServerAddr)->sa_family;
748+ int Res;
749+ if ((Res = getaddrinfo(0,"0",&Hints,&BindAddr)) != 0)
750+ return _error->Error("getaddrinfo was unable to get a listening socket");
751+
752+ // Construct the socket
753+ if ((DataListenFd = socket(BindAddr->ai_family,BindAddr->ai_socktype,
754+ BindAddr->ai_protocol)) < 0)
755+ {
756+ freeaddrinfo(BindAddr);
757 return _error->Errno("socket","Could not create a socket");
758+ }
759
760 // Bind and listen
761- sockaddr_in Addr;
762- memset(&Addr,0,sizeof(Addr));
763- if (bind(DataListenFd,(sockaddr *)&Addr,sizeof(Addr)) < 0)
764+ if (bind(DataListenFd,BindAddr->ai_addr,BindAddr->ai_addrlen) < 0)
765+ {
766+ freeaddrinfo(BindAddr);
767 return _error->Errno("bind","Could not bind a socket");
768+ }
769+ freeaddrinfo(BindAddr);
770 if (listen(DataListenFd,1) < 0)
771 return _error->Errno("listen","Could not listen on the socket");
772 SetNonBlock(DataListenFd,true);
773
774 // Determine the name to send to the remote
775- sockaddr_in Addr2;
776- socklen_t Jnk = sizeof(Addr);
777- if (getsockname(DataListenFd,(sockaddr *)&Addr,&Jnk) < 0)
778- return _error->Errno("getsockname","Could not determine the socket's name");
779- Jnk = sizeof(Addr2);
780- if (getsockname(ServerFd,(sockaddr *)&Addr2,&Jnk) < 0)
781+ struct sockaddr_storage Addr;
782+ socklen_t AddrLen = sizeof(Addr);
783+ if (getsockname(DataListenFd,(sockaddr *)&Addr,&AddrLen) < 0)
784 return _error->Errno("getsockname","Could not determine the socket's name");
785-
786- // This bit ripped from qftp
787- unsigned long badr = ntohl(*(unsigned long *)&Addr2.sin_addr);
788- unsigned long bp = ntohs(Addr.sin_port);
789
790- // Send the port command
791+ // Reverse the address. We need the server address and the data port.
792+ char Name[NI_MAXHOST];
793+ char Service[NI_MAXSERV];
794+ char Service2[NI_MAXSERV];
795+ getnameinfo((struct sockaddr *)&Addr,AddrLen,
796+ Name,sizeof(Name),Service,sizeof(Service),
797+ NI_NUMERICHOST|NI_NUMERICSERV);
798+ getnameinfo((struct sockaddr *)&ServerAddr,ServerAddrLen,
799+ Name,sizeof(Name),Service2,sizeof(Service2),
800+ NI_NUMERICHOST|NI_NUMERICSERV);
801+
802+ // Send off an IPv4 address in the old port format
803+ if (((struct sockaddr *)&Addr)->sa_family == AF_INET &&
804+ ForceExtended == false)
805+ {
806+ // Convert the dots in the quad into commas
807+ for (char *I = Name; *I != 0; I++)
808+ if (*I == '.')
809+ *I = ',';
810+ unsigned long Port = atoi(Service);
811+
812+ // Send the port command
813+ unsigned int Tag;
814+ string Msg;
815+ if (WriteMsg(Tag,Msg,"PORT %s,%d,%d",
816+ Name,
817+ (int)(Port >> 8) & 0xff, (int)(Port & 0xff)) == false)
818+ return false;
819+ if (Tag >= 400)
820+ return _error->Error("Unable to send PORT command");
821+ return true;
822+ }
823+
824+ // Construct an EPRT command
825+ unsigned Proto = 0;
826+ for (unsigned J = 0; AFMap[J].Family != 0; J++)
827+ if (AFMap[J].Family == ((struct sockaddr *)&Addr)->sa_family)
828+ Proto = AFMap[J].IETFFamily;
829+ if (Proto == 0)
830+ return _error->Error("Unkonwn address family %u (AF_*)",
831+ ((struct sockaddr *)&Addr)->sa_family);
832+
833+ // Send the EPRT command
834 unsigned int Tag;
835 string Msg;
836- if (WriteMsg(Tag,Msg,"PORT %d,%d,%d,%d,%d,%d",
837- (int) (badr >> 24) & 0xff, (int) (badr >> 16) & 0xff,
838- (int) (badr >> 8) & 0xff, (int) badr & 0xff,
839- (int) (bp >> 8) & 0xff, (int) bp & 0xff) == false)
840+ if (WriteMsg(Tag,Msg,"EPRT |%u|%s|%s|",Proto,Name,Service) == false)
841 return false;
842 if (Tag >= 400)
843- return _error->Error("Unable to send port command");
844-
845+ return _error->Error("EPRT failed, server said: %s",Msg.c_str());
846 return true;
847 }
848 /*}}}*/
849@@ -629,7 +802,7 @@
850 bool FTPConn::Finalize()
851 {
852 // Passive mode? Do nothing
853- if (PasvAddr.sin_port != 0)
854+ if (PasvAddr != 0)
855 return true;
856
857 // Close any old socket..
858@@ -906,18 +1079,20 @@
859
860 int main(int argc,const char *argv[])
861 {
862- /* See if we should become the http client - we do this for http
863+ /* See if we should be come the http client - we do this for http
864 proxy urls */
865 if (getenv("ftp_proxy") != 0)
866 {
867 URI Proxy = string(getenv("ftp_proxy"));
868
869+ // Run the HTTP method
870 if (Proxy.Access == "http")
871 {
872 // Copy over the environment setting
873 char S[300];
874 snprintf(S,sizeof(S),"http_proxy=%s",getenv("ftp_proxy"));
875 putenv(S);
876+ putenv("no_proxy=");
877
878 // Run the http method
879 string Path = flNotFile(argv[0]) + "/http";
880diff -urN apt-0.3.19cnc52.org/methods/ftp.h apt-0.3.19cnc52/methods/ftp.h
881--- apt-0.3.19cnc52.org/methods/ftp.h Thu Sep 6 22:20:43 2001
882+++ apt-0.3.19cnc52/methods/ftp.h Sat Sep 8 12:35:01 2001
883@@ -1,5 +1,6 @@
884 // -*- mode: cpp; mode: fold -*-
885-// Description /*{{{*/// $Id$
886+// Description /*{{{*/// $Id$
887+// $Id$
888 /* ######################################################################
889
890 FTP Aquire Method - This is the FTP aquire method for APT.
891@@ -17,12 +18,20 @@
892 int DataFd;
893 int DataListenFd;
894 URI ServerName;
895+ bool ForceExtended;
896 bool TryPassive;
897 bool Debug;
898-
899- struct sockaddr_in PasvAddr;
900- struct sockaddr_in Peer;
901
902+ struct addrinfo *PasvAddr;
903+
904+ // Generic Peer Address
905+ struct sockaddr_storage PeerAddr;
906+ socklen_t PeerAddrLen;
907+
908+ // Generic Server Address (us)
909+ struct sockaddr_storage ServerAddr;
910+ socklen_t ServerAddrLen;
911+
912 // Private helper functions
913 bool ReadLine(string &Text);
914 bool Login();
915@@ -41,6 +50,7 @@
916 bool Open(pkgAcqMethod *Owner);
917 void Close();
918 bool GoPasv();
919+ bool ExtGoPasv();
920
921 // Query
922 bool Size(const char *Path,unsigned long &Size);
923diff -urN apt-0.3.19cnc52.org/methods/http.cc apt-0.3.19cnc52/methods/http.cc
924--- apt-0.3.19cnc52.org/methods/http.cc Thu Sep 6 22:20:43 2001
925+++ apt-0.3.19cnc52/methods/http.cc Sat Sep 8 12:41:18 2001
926@@ -1,20 +1,18 @@
927 // -*- mode: cpp; mode: fold -*-
928 // Description /*{{{*/
929-// $Id$
930+// $Id$
931 /* ######################################################################
932
933 HTTP Aquire Method - This is the HTTP aquire method for APT.
934
935 It uses HTTP/1.1 and many of the fancy options there-in, such as
936- pipelining, range, if-range and so on. It accepts on the command line
937- a list of url destination pairs and writes to stdout the status of the
938- operation as defined in the APT method spec.
939-
940- It is based on a doubly buffered select loop. All the requests are
941+ pipelining, range, if-range and so on.
942+
943+ It is based on a doubly buffered select loop. A groupe of requests are
944 fed into a single output buffer that is constantly fed out the
945 socket. This provides ideal pipelining as in many cases all of the
946 requests will fit into a single packet. The input socket is buffered
947- the same way and fed into the fd for the file.
948+ the same way and fed into the fd for the file (may be a pipe in future).
949
950 This double buffering provides fairly substantial transfer rates,
951 compared to wget the http method is about 4% faster. Most importantly,
952@@ -39,6 +37,8 @@
953 #include <signal.h>
954 #include <stdio.h>
955 #include <errno.h>
956+#include <string.h>
957+#include <iostream>
958
959 // Internet stuff
960 #include <netdb.h>
961@@ -48,6 +48,7 @@
962 #include "http.h"
963
964 /*}}}*/
965+using namespace std;
966
967 string HttpMethod::FailFile;
968 int HttpMethod::FailFd = -1;
969@@ -140,7 +141,7 @@
970 unsigned long Sz = LeftRead();
971 if (OutQueue.length() - StrPos < Sz)
972 Sz = OutQueue.length() - StrPos;
973- memcpy(Buf + (InP%Size),OutQueue.begin() + StrPos,Sz);
974+ memcpy(Buf + (InP%Size),OutQueue.c_str() + StrPos,Sz);
975
976 // Advance
977 StrPos += Sz;
978@@ -258,9 +259,6 @@
979 // ServerState::Open - Open a connection to the server /*{{{*/
980 // ---------------------------------------------------------------------
981 /* This opens a connection to the server. */
982-string LastHost;
983-int LastPort = 0;
984-struct addrinfo *LastHostAddr = 0;
985 bool ServerState::Open()
986 {
987 // Use the already open connection if possible.
988@@ -270,7 +268,8 @@
989 Close();
990 In.Reset();
991 Out.Reset();
992-
993+ Persistent = true;
994+
995 // Determine the proxy setting
996 if (getenv("http_proxy") == 0)
997 {
998@@ -289,32 +288,13 @@
999 else
1000 Proxy = getenv("http_proxy");
1001
1002- // Parse no_proxy, a , seperated list of domains
1003+ // Parse no_proxy, a , separated list of domains
1004 if (getenv("no_proxy") != 0)
1005 {
1006- const char *Start = getenv("no_proxy");
1007- const char *ServerEnd = ServerName.Host.end();
1008-
1009- for (const char *Cur = Start; true ; Cur++)
1010- {
1011- if (*Cur != ',' && *Cur != 0)
1012- continue;
1013-
1014- // match end of the string
1015- if ((ServerName.Host.size() >= (Cur - Start))
1016- && stringcasecmp(ServerEnd - (Cur - Start),
1017- ServerEnd,Start,Cur) == 0)
1018- {
1019- Proxy = "";
1020- break;
1021- }
1022-
1023- Start = Cur + 1;
1024- if (*Cur == 0)
1025- break;
1026- }
1027+ if (CheckDomainList(ServerName.Host,getenv("no_proxy")) == true)
1028+ Proxy = "";
1029 }
1030-
1031+
1032 // Determine what host and port to use based on the proxy settings
1033 int Port = 0;
1034 string Host;
1035@@ -380,14 +360,23 @@
1036 {
1037 string::const_iterator J = I;
1038 for (; J != Data.end() && *J != '\n' && *J != '\r';J++);
1039- if (HeaderLine(string(I,J-I)) == false)
1040+ if (HeaderLine(string(I,J)) == false)
1041 return 2;
1042 I = J;
1043 }
1044+
1045+ // 100 Continue is a Nop...
1046+ if (Result == 100)
1047+ continue;
1048+
1049+ // Tidy up the connection persistance state.
1050+ if (Encoding == Closes && HaveContent == true)
1051+ Persistent = false;
1052+
1053 return 0;
1054 }
1055 while (Owner->Go(false,this) == true);
1056-
1057+
1058 return 1;
1059 }
1060 /*}}}*/
1061@@ -513,7 +502,7 @@
1062 string Tag = string(Line,0,Pos);
1063 string Val = string(Line,Pos2);
1064
1065- if (stringcasecmp(Tag.begin(),Tag.begin()+4,"HTTP") == 0)
1066+ if (stringcasecmp(Tag.c_str(),Tag.c_str()+4,"HTTP") == 0)
1067 {
1068 // Evil servers return no version
1069 if (Line[4] == '/')
1070@@ -529,7 +518,19 @@
1071 if (sscanf(Line.c_str(),"HTTP %u %[^\n]",&Result,Code) != 2)
1072 return _error->Error("The http server sent an invalid reply header");
1073 }
1074-
1075+
1076+ /* Check the HTTP response header to get the default persistance
1077+ state. */
1078+ if (Major < 1)
1079+ Persistent = false;
1080+ else
1081+ {
1082+ if (Major == 1 && Minor <= 0)
1083+ Persistent = false;
1084+ else
1085+ Persistent = true;
1086+ }
1087+
1088 return true;
1089 }
1090
1091@@ -569,11 +570,19 @@
1092 {
1093 HaveContent = true;
1094 if (stringcasecmp(Val,"chunked") == 0)
1095- Encoding = Chunked;
1096-
1097+ Encoding = Chunked;
1098 return true;
1099 }
1100
1101+ if (stringcasecmp(Tag,"Connection:") == 0)
1102+ {
1103+ if (stringcasecmp(Val,"close") == 0)
1104+ Persistent = false;
1105+ if (stringcasecmp(Val,"keep-alive") == 0)
1106+ Persistent = true;
1107+ return true;
1108+ }
1109+
1110 if (stringcasecmp(Tag,"Last-Modified:") == 0)
1111 {
1112 if (StrToTime(Val,Date) == false)
1113@@ -660,10 +669,11 @@
1114 Req += string("Proxy-Authorization: Basic ") +
1115 Base64Encode(Proxy.User + ":" + Proxy.Password) + "\r\n";
1116
1117- if (0)//akk
1118- Req += "User-Agent: Debian APT-HTTP/1.2\r\n\r\n";
1119- else
1120- Req += "User-Agent: Conectiva APT-HTTP/1.2\r\n\r\n";
1121+ if (Uri.User.empty() == false || Uri.Password.empty() == false)
1122+ Req += string("Authorization: Basic ") +
1123+ Base64Encode(Uri.User + ":" + Uri.Password) + "\r\n";
1124+
1125+ Req += "User-Agent: PLD APT-HTTP/1.2\r\n\r\n";
1126
1127 if (Debug == true)
1128 cerr << Req << endl;
1129@@ -686,10 +696,12 @@
1130 FD_ZERO(&rfds);
1131 FD_ZERO(&wfds);
1132
1133- // Add the server
1134- if (Srv->Out.WriteSpace() == true && Srv->ServerFd != -1)
1135+ /* Add the server. We only send more requests if the connection will
1136+ be persisting */
1137+ if (Srv->Out.WriteSpace() == true && Srv->ServerFd != -1
1138+ && Srv->Persistent == true)
1139 FD_SET(Srv->ServerFd,&wfds);
1140- if (Srv->In.ReadSpace() == true && Srv->ServerFd != -1)
1141+ if (Srv->In.ReadSpace() == true && Srv->ServerFd != -1)
1142 FD_SET(Srv->ServerFd,&rfds);
1143
1144 // Add the file
1145@@ -714,7 +726,11 @@
1146 tv.tv_usec = 0;
1147 int Res = 0;
1148 if ((Res = select(MaxFd+1,&rfds,&wfds,0,&tv)) < 0)
1149+ {
1150+ if (errno == EINTR)
1151+ return true;
1152 return _error->Errno("select","Select failed");
1153+ }
1154
1155 if (Res == 0)
1156 {
1157@@ -1007,7 +1023,15 @@
1158 delete Server;
1159 Server = new ServerState(Queue->Uri,this);
1160 }
1161-
1162+
1163+ /* If the server has explicitly said this is the last connection
1164+ then we pre-emptively shut down the pipeline and tear down
1165+ the connection. This will speed up HTTP/1.0 servers a tad
1166+ since we don't have to wait for the close sequence to
1167+ complete */
1168+ if (Server->Persistent == false)
1169+ Server->Close();
1170+
1171 // Reset the pipeline
1172 if (Server->ServerFd == -1)
1173 QueueBack = Queue;
1174@@ -1035,6 +1059,7 @@
1175 {
1176 _error->Error("Bad header Data");
1177 Fail(true);
1178+ RotateDNS();
1179 continue;
1180 }
1181
1182@@ -1053,6 +1078,7 @@
1183 FailCounter = 0;
1184 }
1185
1186+ RotateDNS();
1187 continue;
1188 }
1189 };
1190@@ -1070,6 +1096,11 @@
1191 // Run the data
1192 bool Result = Server->RunData();
1193
1194+ /* If the server is sending back sizeless responses then fill in
1195+ the size now */
1196+ if (Res.Size == 0)
1197+ Res.Size = File->Size();
1198+
1199 // Close the file, destroy the FD object and timestamp it
1200 FailFd = -1;
1201 delete File;
1202@@ -1090,7 +1121,7 @@
1203 }
1204 else
1205 Fail(true);
1206-
1207+
1208 break;
1209 }
1210
1211@@ -1112,6 +1143,7 @@
1212 case 5:
1213 {
1214 Fail();
1215+ RotateDNS();
1216 Server->Close();
1217 break;
1218 }
1219diff -urN apt-0.3.19cnc52.org/methods/http.h apt-0.3.19cnc52/methods/http.h
1220--- apt-0.3.19cnc52.org/methods/http.h Thu Sep 6 22:20:43 2001
1221+++ apt-0.3.19cnc52/methods/http.h Sat Sep 8 12:42:54 2001
1222@@ -1,5 +1,6 @@
1223 // -*- mode: cpp; mode: fold -*-
1224-// Description /*{{{*/// $Id$
1225+// Description /*{{{*/// $Id$
1226+// $Id$
1227 /* ######################################################################
1228
1229 HTTP Aquire Method - This is the HTTP aquire method for APT.
1230@@ -12,6 +13,11 @@
1231
1232 #define MAXLEN 360
1233
1234+#include <iostream>
1235+
1236+using std::cout;
1237+using std::endl;
1238+
1239 class HttpMethod;
1240
1241 class CircleBuf
1242@@ -87,6 +93,9 @@
1243 bool HaveContent;
1244 enum {Chunked,Stream,Closes} Encoding;
1245 enum {Header, Data} State;
1246+ bool Persistent;
1247+
1248+ // This is a Persistent attribute of the server itself.
1249 bool Pipeline;
1250
1251 HttpMethod *Owner;
1252@@ -130,7 +139,7 @@
1253 static void SigTerm(int);
1254
1255 public:
1256- friend ServerState;
1257+ friend class ServerState;
1258
1259 FileFd *File;
1260 ServerState *Server;
1261diff -urN apt-0.3.19cnc52.org/methods/rfc2553emu.cc apt-0.3.19cnc52/methods/rfc2553emu.cc
1262--- apt-0.3.19cnc52.org/methods/rfc2553emu.cc Thu Sep 6 22:20:43 2001
1263+++ apt-0.3.19cnc52/methods/rfc2553emu.cc Tue Feb 20 08:03:18 2001
1264@@ -1,6 +1,6 @@
1265 // -*- mode: cpp; mode: fold -*-
1266 // Description /*{{{*/
1267-// $Id$
1268+// $Id$
1269 /* ######################################################################
1270
1271 RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo,
1272@@ -36,20 +36,6 @@
1273 const char *End;
1274 char **CurAddr;
1275
1276- Addr = gethostbyname(nodename);
1277- if (Addr == 0)
1278- {
1279- if (h_errno == TRY_AGAIN)
1280- return EAI_AGAIN;
1281- if (h_errno == NO_RECOVERY)
1282- return EAI_FAIL;
1283- return EAI_NONAME;
1284- }
1285-
1286- // No A records
1287- if (Addr->h_addr_list[0] == 0)
1288- return EAI_NONAME;
1289-
1290 // Try to convert the service as a number
1291 Port = htons(strtol(servname,(char **)&End,0));
1292 Proto = SOCK_STREAM;
1293@@ -86,10 +72,32 @@
1294 hints->ai_socktype != 0)
1295 return EAI_SERVICE;
1296 }
1297+
1298+ // Hostname lookup, only if this is not a listening socket
1299+ if (hints != 0 && (hints->ai_flags & AI_PASSIVE) != AI_PASSIVE)
1300+ {
1301+ Addr = gethostbyname(nodename);
1302+ if (Addr == 0)
1303+ {
1304+ if (h_errno == TRY_AGAIN)
1305+ return EAI_AGAIN;
1306+ if (h_errno == NO_RECOVERY)
1307+ return EAI_FAIL;
1308+ return EAI_NONAME;
1309+ }
1310+
1311+ // No A records
1312+ if (Addr->h_addr_list[0] == 0)
1313+ return EAI_NONAME;
1314+
1315+ CurAddr = Addr->h_addr_list;
1316+ }
1317+ else
1318+ CurAddr = (char **)&End; // Fake!
1319
1320 // Start constructing the linked list
1321 *res = 0;
1322- for (CurAddr = Addr->h_addr_list; *CurAddr != 0; CurAddr++)
1323+ for (; *CurAddr != 0; CurAddr++)
1324 {
1325 // New result structure
1326 *Result = (struct addrinfo *)calloc(sizeof(**Result),1);
1327@@ -124,8 +132,15 @@
1328 // Set the address
1329 ((struct sockaddr_in *)(*Result)->ai_addr)->sin_family = AF_INET;
1330 ((struct sockaddr_in *)(*Result)->ai_addr)->sin_port = Port;
1331- ((struct sockaddr_in *)(*Result)->ai_addr)->sin_addr = *(in_addr *)(*CurAddr);
1332-
1333+
1334+ if (hints != 0 && (hints->ai_flags & AI_PASSIVE) != AI_PASSIVE)
1335+ ((struct sockaddr_in *)(*Result)->ai_addr)->sin_addr = *(in_addr *)(*CurAddr);
1336+ else
1337+ {
1338+ // Already zerod by calloc.
1339+ break;
1340+ }
1341+
1342 Result = &(*Result)->ai_next;
1343 }
1344
1345@@ -202,9 +217,9 @@
1346 {
1347 struct servent *Ent;
1348 if ((flags & NI_DATAGRAM) == NI_DATAGRAM)
1349- Ent = getservbyport(sin->sin_port,"udp");
1350+ Ent = getservbyport(ntohs(sin->sin_port),"udp");
1351 else
1352- Ent = getservbyport(sin->sin_port,"tcp");
1353+ Ent = getservbyport(ntohs(sin->sin_port),"tcp");
1354
1355 if (Ent != 0)
1356 strncpy(serv,Ent->s_name,servlen);
1357@@ -220,7 +235,7 @@
1358 // Resolve as a plain numberic
1359 if ((flags & NI_NUMERICSERV) == NI_NUMERICSERV)
1360 {
1361- snprintf(serv,servlen,"%u",sin->sin_port);
1362+ snprintf(serv,servlen,"%u",ntohs(sin->sin_port));
1363 }
1364 }
1365
1366diff -urN apt-0.3.19cnc52.org/methods/rfc2553emu.h apt-0.3.19cnc52/methods/rfc2553emu.h
1367--- apt-0.3.19cnc52.org/methods/rfc2553emu.h Thu Sep 6 22:20:43 2001
1368+++ apt-0.3.19cnc52/methods/rfc2553emu.h Sun Jun 18 08:04:45 2000
1369@@ -1,6 +1,6 @@
1370 // -*- mode: cpp; mode: fold -*-
1371 // Description /*{{{*/
1372-// $Id$
1373+// $Id$
1374 /* ######################################################################
1375
1376 RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo,
1377@@ -74,6 +74,11 @@
1378 #define EAI_MEMORY -11
1379 #endif
1380
1381+ /* If we don't have getaddrinfo then we probably don't have
1382+ sockaddr_storage either (same RFC) so we definately will not be
1383+ doing any IPv6 stuff. Do not use the members of this structure to
1384+ retain portability, cast to a sockaddr. */
1385+ #define sockaddr_storage sockaddr_in
1386 #endif
1387
1388 // getnameinfo support (glibc2.0 has getaddrinfo only)
1389@@ -97,6 +102,12 @@
1390 #define NI_DATAGRAM (1<<4)
1391 #endif
1392
1393+ #define sockaddr_storage sockaddr_in
1394+#endif
1395+
1396+// Glibc 2.0.7 misses this one
1397+#ifndef AI_NUMERICHOST
1398+#define AI_NUMERICHOST 0
1399 #endif
1400
1401 #endif
This page took 0.364784 seconds and 4 git commands to generate.