~jr/ubuntu/oneiric/apt/bzr-get-rename

« back to all changes in this revision

Viewing changes to methods/ftp.cc

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2005-03-07 20:08:33 UTC
  • Revision ID: james.westby@ubuntu.com-20050307200833-0lxdgg2cb4oculdv
Tags: 0.6.35
* Merge apt--mvo--0 (incorporates 0.6.34ubuntu1):
  - Implement MaxSize and MaxAge in apt.cron.daily, to prevent the cache
    from growing too large (Ubuntu #6761)
  - some comments about the pkgAcqMetaSig::Custom600Headers() added
  - use gpg --with-colons
  - commented the ftp no_proxy unseting in methods/ftp.cc
  - added support for "Acquire::gpgv::options" in methods/gpgv.cc
* Merge bubulle@debian.org--2005/apt--main--0
  - Make capitalization more consistent
  - Un-fuzzy translations resulting from capitalization changes
  - Italian translation update

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// -*- mode: cpp; mode: fold -*-
2
2
// Description                                                          /*{{{*/
3
 
// $Id: ftp.cc,v 1.28 2001/05/22 04:02:00 jgg Exp $
 
3
// $Id: ftp.cc,v 1.31.2.1 2004/01/16 18:58:50 mdz Exp $
4
4
/* ######################################################################
5
5
 
6
6
   FTP Aquire Method - This is the FTP aquire method for APT.
29
29
#include <errno.h>
30
30
#include <stdarg.h>
31
31
#include <iostream>
 
32
#include <apti18n.h>
32
33
 
33
34
// Internet stuff
34
35
#include <netinet/in.h>
158
159
      return false;
159
160
 
160
161
   // Login must be before getpeername otherwise dante won't work.
161
 
   Owner->Status("Logging in");
 
162
   Owner->Status(_("Logging in"));
162
163
   bool Res = Login();
163
164
   
164
165
   // Get the remote server's address
165
166
   PeerAddrLen = sizeof(PeerAddr);
166
167
   if (getpeername(ServerFd,(sockaddr *)&PeerAddr,&PeerAddrLen) != 0)
167
 
      return _error->Errno("getpeername","Unable to determine the peer name");
 
168
      return _error->Errno("getpeername",_("Unable to determine the peer name"));
168
169
   
169
170
   // Get the local machine's address
170
171
   ServerAddrLen = sizeof(ServerAddr);
171
172
   if (getsockname(ServerFd,(sockaddr *)&ServerAddr,&ServerAddrLen) != 0)
172
 
      return _error->Errno("getsockname","Unable to determine the local name");
 
173
      return _error->Errno("getsockname",_("Unable to determine the local name"));
173
174
   
174
175
   return Res;
175
176
}
200
201
      if (ReadResp(Tag,Msg) == false)
201
202
         return false;
202
203
      if (Tag >= 400)
203
 
         return _error->Error("Server refused our connection and said: %s",Msg.c_str());
 
204
         return _error->Error(_("The server refused the connection and said: %s"),Msg.c_str());
204
205
      
205
206
      // Send the user
206
207
      if (WriteMsg(Tag,Msg,"USER %s",User.c_str()) == false)
207
208
         return false;
208
209
      if (Tag >= 400)
209
 
         return _error->Error("USER failed, server said: %s",Msg.c_str());
 
210
         return _error->Error(_("USER failed, server said: %s"),Msg.c_str());
210
211
      
211
 
      // Send the Password
212
 
      if (WriteMsg(Tag,Msg,"PASS %s",Pass.c_str()) == false)
213
 
         return false;
214
 
      if (Tag >= 400)
215
 
         return _error->Error("PASS failed, server said: %s",Msg.c_str());
 
212
      if (Tag == 331) { // 331 User name okay, need password.
 
213
         // Send the Password
 
214
         if (WriteMsg(Tag,Msg,"PASS %s",Pass.c_str()) == false)
 
215
            return false;
 
216
         if (Tag >= 400)
 
217
            return _error->Error(_("PASS failed, server said: %s"),Msg.c_str());
 
218
      }
216
219
      
217
220
      // Enter passive mode
218
221
      if (_config->Exists("Acquire::FTP::Passive::" + ServerName.Host) == true)
226
229
      if (ReadResp(Tag,Msg) == false)
227
230
         return false;
228
231
      if (Tag >= 400)
229
 
         return _error->Error("Server refused our connection and said: %s",Msg.c_str());
 
232
         return _error->Error(_("The server refused the connection and said: %s"),Msg.c_str());
230
233
      
231
234
      // Perform proxy script execution
232
235
      Configuration::Item const *Opts = _config->Tree("Acquire::ftp::ProxyLogin");
233
236
      if (Opts == 0 || Opts->Child == 0)
234
 
         return _error->Error("A proxy server was specified but no login "
235
 
                              "script, Acquire::ftp::ProxyLogin is empty.");
 
237
         return _error->Error(_("A proxy server was specified but no login "
 
238
                              "script, Acquire::ftp::ProxyLogin is empty."));
236
239
      Opts = Opts->Child;
237
240
 
238
241
      // Iterate over the entire login script
259
262
         if (WriteMsg(Tag,Msg,"%s",Tmp.c_str()) == false)
260
263
            return false;
261
264
         if (Tag >= 400)
262
 
            return _error->Error("Login script command '%s' failed, server said: %s",Tmp.c_str(),Msg.c_str());   
 
265
            return _error->Error(_("Login script command '%s' failed, server said: %s"),Tmp.c_str(),Msg.c_str());        
263
266
      }
264
267
      
265
268
      // Enter passive mode
285
288
   if (WriteMsg(Tag,Msg,"TYPE I") == false)
286
289
      return false;
287
290
   if (Tag >= 400)
288
 
      return _error->Error("TYPE failed, server said: %s",Msg.c_str());
 
291
      return _error->Error(_("TYPE failed, server said: %s"),Msg.c_str());
289
292
   
290
293
   return true;
291
294
}
323
326
      if (WaitFd(ServerFd,false,TimeOut) == false)
324
327
      {
325
328
         Close();
326
 
         return _error->Error("Connection timeout");
 
329
         return _error->Error(_("Connection timeout"));
327
330
      }
328
331
      
329
332
      // Suck it back
330
333
      int Res = read(ServerFd,Buffer + Len,sizeof(Buffer) - Len);
331
334
      if (Res == 0)
332
 
         _error->Error("Server closed the connection");
 
335
         _error->Error(_("Server closed the connection"));
333
336
      if (Res <= 0)
334
337
      {
335
 
         _error->Errno("read","Read error");
 
338
         _error->Errno("read",_("Read error"));
336
339
         Close();
337
340
         return false;
338
341
      }      
339
342
      Len += Res;
340
343
   }
341
344
 
342
 
   return _error->Error("A response overflowed the buffer.");
 
345
   return _error->Error(_("A response overflowed the buffer."));
343
346
}
344
347
                                                                        /*}}}*/
345
348
// FTPConn::ReadResp - Read a full response from the server             /*{{{*/
356
359
   char *End;   
357
360
   Ret = strtol(Msg.c_str(),&End,10);
358
361
   if (End - Msg.c_str() != 3)
359
 
      return _error->Error("Protocol corruption");
 
362
      return _error->Error(_("Protocol corruption"));
360
363
 
361
364
   // All done ?
362
365
   Text = Msg.c_str()+4;
368
371
   }
369
372
   
370
373
   if (*End != '-')
371
 
      return _error->Error("Protocol corruption");
 
374
      return _error->Error(_("Protocol corruption"));
372
375
   
373
376
   /* Okay, here we do the continued message trick. This is foolish, but
374
377
      proftpd follows the protocol as specified and wu-ftpd doesn't, so 
434
437
      if (WaitFd(ServerFd,true,TimeOut) == false)
435
438
      {
436
439
         Close();
437
 
         return _error->Error("Connection timeout");
 
440
         return _error->Error(_("Connection timeout"));
438
441
      }
439
442
      
440
443
      int Res = write(ServerFd,S + Start,Len);
441
444
      if (Res <= 0)
442
445
      {
443
 
         _error->Errno("write","Write Error");
 
446
         _error->Errno("write",_("Write error"));
444
447
         Close();
445
448
         return false;
446
449
      }
681
684
      // Get a socket
682
685
      if ((DataFd = socket(PasvAddr->ai_family,PasvAddr->ai_socktype,
683
686
                           PasvAddr->ai_protocol)) < 0)
684
 
         return _error->Errno("socket","Could not create a socket");
 
687
         return _error->Errno("socket",_("Could not create a socket"));
685
688
      
686
689
      // Connect to the server
687
690
      SetNonBlock(DataFd,true);
688
691
      if (connect(DataFd,PasvAddr->ai_addr,PasvAddr->ai_addrlen) < 0 &&
689
692
          errno != EINPROGRESS)
690
 
         return _error->Errno("socket","Could not create a socket");
 
693
         return _error->Errno("socket",_("Could not create a socket"));
691
694
   
692
695
      /* This implements a timeout for connect by opening the connection
693
696
         nonblocking */
694
697
      if (WaitFd(DataFd,true,TimeOut) == false)
695
 
         return _error->Error("Could not connect data socket, connection timed out");
 
698
         return _error->Error(_("Could not connect data socket, connection timed out"));
696
699
      unsigned int Err;
697
700
      unsigned int Len = sizeof(Err);
698
701
      if (getsockopt(DataFd,SOL_SOCKET,SO_ERROR,&Err,&Len) != 0)
699
 
         return _error->Errno("getsockopt","Failed");
 
702
         return _error->Errno("getsockopt",_("Failed"));
700
703
      if (Err != 0)
701
 
         return _error->Error("Could not connect passive socket.");
 
704
         return _error->Error(_("Could not connect passive socket."));
702
705
 
703
706
      return true;
704
707
   }
716
719
   Hints.ai_family = ((struct sockaddr *)&ServerAddr)->sa_family;
717
720
   int Res;
718
721
   if ((Res = getaddrinfo(0,"0",&Hints,&BindAddr)) != 0)
719
 
      return _error->Error("getaddrinfo was unable to get a listening socket");
 
722
      return _error->Error(_("getaddrinfo was unable to get a listening socket"));
720
723
   
721
724
   // Construct the socket
722
725
   if ((DataListenFd = socket(BindAddr->ai_family,BindAddr->ai_socktype,
723
726
                              BindAddr->ai_protocol)) < 0)
724
727
   {
725
728
      freeaddrinfo(BindAddr);
726
 
      return _error->Errno("socket","Could not create a socket");
 
729
      return _error->Errno("socket",_("Could not create a socket"));
727
730
   }
728
731
   
729
732
   // Bind and listen
730
733
   if (bind(DataListenFd,BindAddr->ai_addr,BindAddr->ai_addrlen) < 0)
731
734
   {
732
735
      freeaddrinfo(BindAddr);
733
 
      return _error->Errno("bind","Could not bind a socket");
 
736
      return _error->Errno("bind",_("Could not bind a socket"));
734
737
   }
735
738
   freeaddrinfo(BindAddr);   
736
739
   if (listen(DataListenFd,1) < 0)
737
 
      return _error->Errno("listen","Could not listen on the socket");
 
740
      return _error->Errno("listen",_("Could not listen on the socket"));
738
741
   SetNonBlock(DataListenFd,true);
739
742
   
740
743
   // Determine the name to send to the remote
741
744
   struct sockaddr_storage Addr;
742
745
   socklen_t AddrLen = sizeof(Addr);
743
746
   if (getsockname(DataListenFd,(sockaddr *)&Addr,&AddrLen) < 0)
744
 
      return _error->Errno("getsockname","Could not determine the socket's name");
 
747
      return _error->Errno("getsockname",_("Could not determine the socket's name"));
 
748
 
745
749
 
746
750
   // Reverse the address. We need the server address and the data port.
747
751
   char Name[NI_MAXHOST];
772
776
                   (int)(Port >> 8) & 0xff, (int)(Port & 0xff)) == false)
773
777
         return false;
774
778
      if (Tag >= 400)
775
 
         return _error->Error("Unable to send PORT command");
 
779
         return _error->Error(_("Unable to send PORT command"));
776
780
      return true;
777
781
   }
778
782
 
782
786
      if (AFMap[J].Family == ((struct sockaddr *)&Addr)->sa_family)
783
787
         Proto = AFMap[J].IETFFamily;
784
788
   if (Proto == 0)
785
 
      return _error->Error("Unkonwn address family %u (AF_*)",
 
789
      return _error->Error(_("Unknown address family %u (AF_*)"),
786
790
                           ((struct sockaddr *)&Addr)->sa_family);
787
791
   
788
792
   // Send the EPRT command
791
795
   if (WriteMsg(Tag,Msg,"EPRT |%u|%s|%s|",Proto,Name,Service) == false)
792
796
      return false;
793
797
   if (Tag >= 400)
794
 
      return _error->Error("EPRT failed, server said: %s",Msg.c_str());
 
798
      return _error->Error(_("EPRT failed, server said: %s"),Msg.c_str());
795
799
   return true;
796
800
}
797
801
                                                                        /*}}}*/
811
815
   
812
816
   // Wait for someone to connect..
813
817
   if (WaitFd(DataListenFd,false,TimeOut) == false)
814
 
      return _error->Error("Data socket connect timed out");
 
818
      return _error->Error(_("Data socket connect timed out"));
815
819
      
816
820
   // Accept the connection
817
821
   struct sockaddr_in Addr;
818
822
   socklen_t Len = sizeof(Addr);
819
823
   DataFd = accept(DataListenFd,(struct sockaddr *)&Addr,&Len);
820
824
   if (DataFd < 0)
821
 
      return _error->Errno("accept","Unable to accept connection");
 
825
      return _error->Errno("accept",_("Unable to accept connection"));
822
826
 
823
827
   close(DataListenFd);
824
828
   DataListenFd = -1;
857
861
   {
858
862
      if (Hash.AddFD(To.Fd(),Resume) == false)
859
863
      {
860
 
         _error->Errno("read","Problem hashing file");
 
864
         _error->Errno("read",_("Problem hashing file"));
861
865
         return false;
862
866
      }
863
867
   }
870
874
   {
871
875
      if (Tag == 550)
872
876
         Missing = true;
873
 
      return _error->Error("Unable to fetch file, server said '%s'",Msg.c_str());
 
877
      return _error->Error(_("Unable to fetch file, server said '%s'"),Msg.c_str());
874
878
   }
875
879
   
876
880
   // Finish off the data connection
885
889
      if (WaitFd(DataFd,false,TimeOut) == false)
886
890
      {
887
891
         Close();
888
 
         return _error->Error("Data socket timed out");
 
892
         return _error->Error(_("Data socket timed out"));
889
893
      }
890
894
      
891
895
      // Read the data..
915
919
   if (ReadResp(Tag,Msg) == false)
916
920
      return false;
917
921
   if (Tag >= 400)
918
 
      return _error->Error("Data transfer failed, server said '%s'",Msg.c_str());
 
922
      return _error->Error(_("Data transfer failed, server said '%s'"),Msg.c_str());
919
923
   return true;
920
924
}
921
925
                                                                        /*}}}*/
990
994
   }
991
995
   
992
996
   // Get the files information
993
 
   Status("Query");
 
997
   Status(_("Query"));
994
998
   unsigned long Size;
995
999
   if (Server->Size(File,Size) == false ||
996
1000
       Server->ModTime(File,FailTime) == false)
1079
1083
 
1080
1084
int main(int argc,const char *argv[])
1081
1085
 
1086
   setlocale(LC_ALL, "");
 
1087
 
1082
1088
   /* See if we should be come the http client - we do this for http
1083
1089
      proxy urls */
1084
1090
   if (getenv("ftp_proxy") != 0)
1095
1101
         putenv("no_proxy=");
1096
1102
         
1097
1103
         // Run the http method
1098
 
         string Path = flNotFile(argv[0]) + "/http";
 
1104
         string Path = flNotFile(argv[0]) + "http";
1099
1105
         execl(Path.c_str(),Path.c_str(),0);
1100
 
         cerr << "Unable to invoke " << Path << endl;
 
1106
         cerr << _("Unable to invoke ") << Path << endl;
1101
1107
         exit(100);
1102
1108
      }      
1103
1109
   }