~racb/ubuntu/quantal/apt/by_hash

« back to all changes in this revision

Viewing changes to methods/bzip2.cc

  • Committer: Package Import Robot
  • Author(s): Steve Langasek, Michael Vogt, Steve Langasek
  • Date: 2012-06-11 22:36:16 UTC
  • mfrom: (1.4.47 sid)
  • Revision ID: package-import@ubuntu.com-20120611223616-1cctfc7qrxrx4vcu
Tags: 0.9.6ubuntu1
[ Michael Vogt ]
* merged from Debian, remaining changes:
  - use ubuntu keyring and ubuntu archive keyring in apt-key
  - run update-apt-xapian-index in apt.cron
  - support apt-key net-update and verify keys against master-keyring
  - run apt-key net-update in cron.daily
  - different example sources.list
  - APT::pkgPackageManager::MaxLoopCount set to 5000
  - apport pkgfailure handling
  - ubuntu changelog download handling
  - patch for apt cross-building, see http://bugs.debian.org/666772

[ Steve Langasek ]
* Drop upgrade handling for obsolete conffile /etc/apt/apt.conf.d/01ubuntu,
  removed in previous LTS.
* prepare-release: declare the packages needed as source build deps.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- mode: cpp; mode: fold -*-
2
 
// Description                                                          /*{{{*/
3
 
/* ######################################################################
4
 
 
5
 
   Bzip2 method - Take a file URI in and decompress it into the target 
6
 
   file.
7
 
 
8
 
   While the method is named "bzip2" it handles also other compression
9
 
   types as it calls binaries based on the name of the method,
10
 
   so it can also be used to handle gzip, lzma and others if named
11
 
   correctly.
12
 
 
13
 
   ##################################################################### */
14
 
                                                                        /*}}}*/
15
 
// Include Files                                                        /*{{{*/
16
 
#include <config.h>
17
 
 
18
 
#include <apt-pkg/fileutl.h>
19
 
#include <apt-pkg/error.h>
20
 
#include <apt-pkg/acquire-method.h>
21
 
#include <apt-pkg/strutl.h>
22
 
#include <apt-pkg/hashes.h>
23
 
#include <apt-pkg/configuration.h>
24
 
 
25
 
#include <sys/stat.h>
26
 
#include <unistd.h>
27
 
#include <utime.h>
28
 
#include <stdio.h>
29
 
#include <errno.h>
30
 
#include <apti18n.h>
31
 
                                                                        /*}}}*/
32
 
 
33
 
const char *Prog;
34
 
 
35
 
class Bzip2Method : public pkgAcqMethod
36
 
{
37
 
   virtual bool Fetch(FetchItem *Itm);
38
 
   
39
 
   public:
40
 
   
41
 
   Bzip2Method() : pkgAcqMethod("1.1",SingleInstance | SendConfig) {};
42
 
};
43
 
 
44
 
 
45
 
// Bzip2Method::Fetch - Decompress the passed URI                       /*{{{*/
46
 
// ---------------------------------------------------------------------
47
 
/* */
48
 
bool Bzip2Method::Fetch(FetchItem *Itm)
49
 
{
50
 
   URI Get = Itm->Uri;
51
 
   std::string Path = Get.Host + Get.Path; // To account for relative paths
52
 
   
53
 
   std::string GzPathOption = "Dir::bin::" + std::string(Prog);
54
 
 
55
 
   FetchResult Res;
56
 
   Res.Filename = Itm->DestFile;
57
 
   URIStart(Res);
58
 
   
59
 
   // Open the source and destination files
60
 
   FileFd From(Path,FileFd::ReadOnly);
61
 
 
62
 
   if(From.FileSize() == 0)
63
 
      return _error->Error(_("Empty files can't be valid archives"));
64
 
 
65
 
   int GzOut[2];   
66
 
   if (pipe(GzOut) < 0)
67
 
      return _error->Errno("pipe",_("Couldn't open pipe for %s"),Prog);
68
 
 
69
 
   // Fork bzip2
70
 
   pid_t Process = ExecFork();
71
 
   if (Process == 0)
72
 
   {
73
 
      close(GzOut[0]);
74
 
      dup2(From.Fd(),STDIN_FILENO);
75
 
      dup2(GzOut[1],STDOUT_FILENO);
76
 
      From.Close();
77
 
      close(GzOut[1]);
78
 
      SetCloseExec(STDIN_FILENO,false);
79
 
      SetCloseExec(STDOUT_FILENO,false);
80
 
      
81
 
      const char *Args[3];
82
 
      std::string Tmp = _config->Find(GzPathOption,Prog);
83
 
      Args[0] = Tmp.c_str();
84
 
      Args[1] = "-d";
85
 
      Args[2] = 0;
86
 
      execvp(Args[0],(char **)Args);
87
 
      _exit(100);
88
 
   }
89
 
   From.Close();
90
 
   close(GzOut[1]);
91
 
   
92
 
   FileFd FromGz(GzOut[0]);  // For autoclose   
93
 
   FileFd To(Itm->DestFile,FileFd::WriteAtomic);   
94
 
   To.EraseOnFailure();
95
 
   if (_error->PendingError() == true)
96
 
      return false;
97
 
   
98
 
   // Read data from bzip2, generate checksums and write
99
 
   Hashes Hash;
100
 
   bool Failed = false;
101
 
   while (1) 
102
 
   {
103
 
      unsigned char Buffer[4*1024];
104
 
      
105
 
      ssize_t Count = read(GzOut[0],Buffer,sizeof(Buffer));
106
 
      if (Count < 0 && errno == EINTR)
107
 
         continue;
108
 
      
109
 
      if (Count < 0)
110
 
      {
111
 
         _error->Errno("read", _("Read error from %s process"),Prog);
112
 
         Failed = true;
113
 
         break;
114
 
      }
115
 
      
116
 
      if (Count == 0)
117
 
         break;
118
 
      
119
 
      Hash.Add(Buffer,Count);
120
 
      if (To.Write(Buffer,Count) == false)
121
 
      {
122
 
         Failed = true;
123
 
         FromGz.Close();
124
 
         break;
125
 
      }      
126
 
   }
127
 
   
128
 
   // Wait for bzip2 to finish
129
 
   if (ExecWait(Process,_config->Find(GzPathOption,Prog).c_str(),false) == false)
130
 
   {
131
 
      To.OpFail();
132
 
      return false;
133
 
   }  
134
 
       
135
 
   To.Close();
136
 
   
137
 
   if (Failed == true)
138
 
      return false;
139
 
   
140
 
   // Transfer the modification times
141
 
   struct stat Buf;
142
 
   if (stat(Path.c_str(),&Buf) != 0)
143
 
      return _error->Errno("stat",_("Failed to stat"));
144
 
 
145
 
   struct utimbuf TimeBuf;
146
 
   TimeBuf.actime = Buf.st_atime;
147
 
   TimeBuf.modtime = Buf.st_mtime;
148
 
   if (utime(Itm->DestFile.c_str(),&TimeBuf) != 0)
149
 
      return _error->Errno("utime",_("Failed to set modification time"));
150
 
 
151
 
   if (stat(Itm->DestFile.c_str(),&Buf) != 0)
152
 
      return _error->Errno("stat",_("Failed to stat"));
153
 
   
154
 
   // Return a Done response
155
 
   Res.LastModified = Buf.st_mtime;
156
 
   Res.Size = Buf.st_size;
157
 
   Res.TakeHashes(Hash);
158
 
 
159
 
   URIDone(Res);
160
 
   
161
 
   return true;
162
 
}
163
 
                                                                        /*}}}*/
164
 
 
165
 
int main(int argc, char *argv[])
166
 
{
167
 
   setlocale(LC_ALL, "");
168
 
 
169
 
   Bzip2Method Mth;
170
 
 
171
 
   Prog = strrchr(argv[0],'/');
172
 
   Prog++;
173
 
   
174
 
   return Mth.Run();
175
 
}