]> git.pld-linux.org Git - packages/apt.git/blob - apt-newmethods.patch
- merged DEVEL
[packages/apt.git] / apt-newmethods.patch
1 diff -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)
24 diff -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() {};
43 diff -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 */
77 diff -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));};
88 diff -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                                                                         /*}}}*/
302 diff -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
320 diff -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";
880 diff -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);
923 diff -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          }
1219 diff -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;
1261 diff -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     
1366 diff -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.274504 seconds and 3 git commands to generate.