summaryrefslogtreecommitdiff
path: root/methods
diff options
context:
space:
mode:
Diffstat (limited to 'methods')
-rw-r--r--methods/bzip2.cc175
-rw-r--r--methods/ftp.cc8
-rw-r--r--methods/gzip.cc18
-rw-r--r--methods/http.cc29
-rw-r--r--methods/http.h4
-rw-r--r--methods/https.cc2
-rw-r--r--methods/https.h6
-rw-r--r--methods/makefile40
-rw-r--r--methods/mirror.cc9
-rw-r--r--methods/rred.cc26
10 files changed, 80 insertions, 237 deletions
diff --git a/methods/bzip2.cc b/methods/bzip2.cc
deleted file mode 100644
index 8e7e46557..000000000
--- a/methods/bzip2.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description /*{{{*/
-/* ######################################################################
-
- Bzip2 method - Take a file URI in and decompress it into the target
- file.
-
- While the method is named "bzip2" it handles also other compression
- types as it calls binaries based on the name of the method,
- so it can also be used to handle gzip, lzma and others if named
- correctly.
-
- ##################################################################### */
- /*}}}*/
-// Include Files /*{{{*/
-#include <config.h>
-
-#include <apt-pkg/fileutl.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/acquire-method.h>
-#include <apt-pkg/strutl.h>
-#include <apt-pkg/hashes.h>
-#include <apt-pkg/configuration.h>
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <utime.h>
-#include <stdio.h>
-#include <errno.h>
-#include <apti18n.h>
- /*}}}*/
-
-const char *Prog;
-
-class Bzip2Method : public pkgAcqMethod
-{
- virtual bool Fetch(FetchItem *Itm);
-
- public:
-
- Bzip2Method() : pkgAcqMethod("1.1",SingleInstance | SendConfig) {};
-};
-
-
-// Bzip2Method::Fetch - Decompress the passed URI /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool Bzip2Method::Fetch(FetchItem *Itm)
-{
- URI Get = Itm->Uri;
- std::string Path = Get.Host + Get.Path; // To account for relative paths
-
- std::string GzPathOption = "Dir::bin::" + std::string(Prog);
-
- FetchResult Res;
- Res.Filename = Itm->DestFile;
- URIStart(Res);
-
- // Open the source and destination files
- FileFd From(Path,FileFd::ReadOnly);
-
- if(From.FileSize() == 0)
- return _error->Error(_("Empty files can't be valid archives"));
-
- int GzOut[2];
- if (pipe(GzOut) < 0)
- return _error->Errno("pipe",_("Couldn't open pipe for %s"),Prog);
-
- // Fork bzip2
- pid_t Process = ExecFork();
- if (Process == 0)
- {
- close(GzOut[0]);
- dup2(From.Fd(),STDIN_FILENO);
- dup2(GzOut[1],STDOUT_FILENO);
- From.Close();
- close(GzOut[1]);
- SetCloseExec(STDIN_FILENO,false);
- SetCloseExec(STDOUT_FILENO,false);
-
- const char *Args[3];
- std::string Tmp = _config->Find(GzPathOption,Prog);
- Args[0] = Tmp.c_str();
- Args[1] = "-d";
- Args[2] = 0;
- execvp(Args[0],(char **)Args);
- _exit(100);
- }
- From.Close();
- close(GzOut[1]);
-
- FileFd FromGz(GzOut[0]); // For autoclose
- FileFd To(Itm->DestFile,FileFd::WriteAtomic);
- To.EraseOnFailure();
- if (_error->PendingError() == true)
- return false;
-
- // Read data from bzip2, generate checksums and write
- Hashes Hash;
- bool Failed = false;
- while (1)
- {
- unsigned char Buffer[4*1024];
-
- ssize_t Count = read(GzOut[0],Buffer,sizeof(Buffer));
- if (Count < 0 && errno == EINTR)
- continue;
-
- if (Count < 0)
- {
- _error->Errno("read", _("Read error from %s process"),Prog);
- Failed = true;
- break;
- }
-
- if (Count == 0)
- break;
-
- Hash.Add(Buffer,Count);
- if (To.Write(Buffer,Count) == false)
- {
- Failed = true;
- FromGz.Close();
- break;
- }
- }
-
- // Wait for bzip2 to finish
- if (ExecWait(Process,_config->Find(GzPathOption,Prog).c_str(),false) == false)
- {
- To.OpFail();
- return false;
- }
-
- To.Close();
-
- if (Failed == true)
- return false;
-
- // Transfer the modification times
- struct stat Buf;
- if (stat(Path.c_str(),&Buf) != 0)
- return _error->Errno("stat",_("Failed to stat"));
-
- struct utimbuf TimeBuf;
- TimeBuf.actime = Buf.st_atime;
- TimeBuf.modtime = Buf.st_mtime;
- if (utime(Itm->DestFile.c_str(),&TimeBuf) != 0)
- return _error->Errno("utime",_("Failed to set modification time"));
-
- if (stat(Itm->DestFile.c_str(),&Buf) != 0)
- return _error->Errno("stat",_("Failed to stat"));
-
- // Return a Done response
- Res.LastModified = Buf.st_mtime;
- Res.Size = Buf.st_size;
- Res.TakeHashes(Hash);
-
- URIDone(Res);
-
- return true;
-}
- /*}}}*/
-
-int main(int argc, char *argv[])
-{
- setlocale(LC_ALL, "");
-
- Bzip2Method Mth;
-
- Prog = strrchr(argv[0],'/');
- Prog++;
-
- return Mth.Run();
-}
diff --git a/methods/ftp.cc b/methods/ftp.cc
index b1e8d2b0a..d55ac1224 100644
--- a/methods/ftp.cc
+++ b/methods/ftp.cc
@@ -622,8 +622,7 @@ bool FTPConn::ExtGoPasv()
}
// Get a new passive address.
- int Res;
- if ((Res = getaddrinfo(IP.c_str(),PStr,&Hints,&PasvAddr)) != 0)
+ if (getaddrinfo(IP.c_str(),PStr,&Hints,&PasvAddr) != 0)
return true;
return true;
@@ -721,14 +720,13 @@ bool FTPConn::CreateDataFd()
DataListenFd = -1;
// Get the information for a listening socket.
- struct addrinfo *BindAddr = 0;
+ struct addrinfo *BindAddr = NULL;
struct addrinfo Hints;
memset(&Hints,0,sizeof(Hints));
Hints.ai_socktype = SOCK_STREAM;
Hints.ai_flags |= AI_PASSIVE;
Hints.ai_family = ((struct sockaddr *)&ServerAddr)->sa_family;
- int Res;
- if ((Res = getaddrinfo(0,"0",&Hints,&BindAddr)) != 0)
+ if (getaddrinfo(0,"0",&Hints,&BindAddr) != 0 || BindAddr == NULL)
return _error->Error(_("getaddrinfo was unable to get a listening socket"));
// Construct the socket
diff --git a/methods/gzip.cc b/methods/gzip.cc
index 6ab6548ef..48c8e9892 100644
--- a/methods/gzip.cc
+++ b/methods/gzip.cc
@@ -25,6 +25,8 @@
#include <apti18n.h>
/*}}}*/
+const char *Prog;
+
class GzipMethod : public pkgAcqMethod
{
virtual bool Fetch(FetchItem *Itm);
@@ -46,9 +48,18 @@ bool GzipMethod::Fetch(FetchItem *Itm)
FetchResult Res;
Res.Filename = Itm->DestFile;
URIStart(Res);
-
+
+ std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
+ std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
+ for (; compressor != compressors.end(); ++compressor)
+ if (compressor->Name == Prog)
+ break;
+ if (compressor == compressors.end())
+ return _error->Error("Extraction of file %s requires unknown compressor %s", Path.c_str(), Prog);
+
// Open the source and destination files
- FileFd From(Path,FileFd::ReadOnly, FileFd::Gzip);
+ FileFd From;
+ From.Open(Path, FileFd::ReadOnly, *compressor);
if(From.FileSize() == 0)
return _error->Error(_("Empty files can't be valid archives"));
@@ -117,6 +128,9 @@ int main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
+ Prog = strrchr(argv[0],'/');
+ ++Prog;
+
GzipMethod Mth;
return Mth.Run();
}
diff --git a/methods/http.cc b/methods/http.cc
index 2721b1224..acf25a42a 100644
--- a/methods/http.cc
+++ b/methods/http.cc
@@ -42,6 +42,7 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <climits>
#include <iostream>
#include <map>
@@ -60,7 +61,7 @@ using namespace std;
string HttpMethod::FailFile;
int HttpMethod::FailFd = -1;
time_t HttpMethod::FailTime = 0;
-unsigned long PipelineDepth = 10;
+unsigned long PipelineDepth = 0;
unsigned long TimeOut = 120;
bool AllowRedirect = false;
bool Debug = false;
@@ -534,10 +535,6 @@ bool ServerState::HeaderLine(string Line)
if (Line.empty() == true)
return true;
- // The http server might be trying to do something evil.
- if (Line.length() >= MAXLEN)
- return _error->Error(_("Got a single header line over %u chars"),MAXLEN);
-
string::size_type Pos = Line.find(' ');
if (Pos == string::npos || Pos+1 > Line.length())
{
@@ -561,7 +558,7 @@ bool ServerState::HeaderLine(string Line)
// Evil servers return no version
if (Line[4] == '/')
{
- int const elements = sscanf(Line.c_str(),"HTTP/%u.%u %u%[^\n]",&Major,&Minor,&Result,Code);
+ int const elements = sscanf(Line.c_str(),"HTTP/%3u.%3u %3u%359[^\n]",&Major,&Minor,&Result,Code);
if (elements == 3)
{
Code[0] = '\0';
@@ -575,7 +572,7 @@ bool ServerState::HeaderLine(string Line)
{
Major = 0;
Minor = 9;
- if (sscanf(Line.c_str(),"HTTP %u%[^\n]",&Result,Code) != 2)
+ if (sscanf(Line.c_str(),"HTTP %3u%359[^\n]",&Result,Code) != 2)
return _error->Error(_("The HTTP server sent an invalid reply header"));
}
@@ -585,7 +582,7 @@ bool ServerState::HeaderLine(string Line)
Persistent = false;
else
{
- if (Major == 1 && Minor <= 0)
+ if (Major == 1 && Minor == 0)
Persistent = false;
else
Persistent = true;
@@ -603,9 +600,10 @@ bool ServerState::HeaderLine(string Line)
// The length is already set from the Content-Range header
if (StartPos != 0)
return true;
-
- if (sscanf(Val.c_str(),"%llu",&Size) != 1)
- return _error->Error(_("The HTTP server sent an invalid Content-Length header"));
+
+ Size = strtoull(Val.c_str(), NULL, 10);
+ if (Size >= std::numeric_limits<unsigned long long>::max())
+ return _error->Errno("HeaderLine", _("The HTTP server sent an invalid Content-Length header"));
return true;
}
@@ -760,7 +758,7 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
Base64Encode(Uri.User + ":" + Uri.Password) + "\r\n";
}
Req += "User-Agent: " + _config->Find("Acquire::http::User-Agent",
- "Debian APT-HTTP/1.3 ("VERSION")") + "\r\n\r\n";
+ "Debian APT-HTTP/1.3 (" PACKAGE_VERSION ")") + "\r\n\r\n";
if (Debug == true)
cerr << Req << endl;
@@ -987,7 +985,10 @@ HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv)
else
{
NextURI = DeQuoteString(Srv->Location);
- return TRY_AGAIN_OR_REDIRECT;
+ URI tmpURI = NextURI;
+ // Do not allow a redirection to switch protocol
+ if (tmpURI.Access == "http")
+ return TRY_AGAIN_OR_REDIRECT;
}
/* else pass through for error message */
}
@@ -1329,7 +1330,7 @@ int HttpMethod::Loop()
after the same URI is seen twice in a queue item. */
StringVector &R = Redirected[Queue->DestFile];
bool StopRedirects = false;
- if (R.size() == 0)
+ if (R.empty() == true)
R.push_back(Queue->Uri);
else if (R[0] == "STOP" || R.size() > 10)
StopRedirects = true;
diff --git a/methods/http.h b/methods/http.h
index 5c195de64..7a3ccda54 100644
--- a/methods/http.h
+++ b/methods/http.h
@@ -11,8 +11,6 @@
#ifndef APT_HTTP_H
#define APT_HTTP_H
-#define MAXLEN 360
-
#include <apt-pkg/strutl.h>
#include <string>
@@ -92,7 +90,7 @@ struct ServerState
unsigned int Major;
unsigned int Minor;
unsigned int Result;
- char Code[MAXLEN];
+ char Code[360];
// These are some statistics from the last parsed header lines
unsigned long long Size;
diff --git a/methods/https.cc b/methods/https.cc
index 4f2d581d2..c1a49ba60 100644
--- a/methods/https.cc
+++ b/methods/https.cc
@@ -219,7 +219,7 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
curl_easy_setopt(curl, CURLOPT_USERAGENT,
_config->Find("Acquire::https::User-Agent",
_config->Find("Acquire::http::User-Agent",
- "Debian APT-CURL/1.0 ("VERSION")").c_str()).c_str());
+ "Debian APT-CURL/1.0 (" PACKAGE_VERSION ")").c_str()).c_str());
// set timeout
int const timeout = _config->FindI("Acquire::https::Timeout",
diff --git a/methods/https.h b/methods/https.h
index b7adeb880..b1961a870 100644
--- a/methods/https.h
+++ b/methods/https.h
@@ -8,10 +8,8 @@
##################################################################### */
/*}}}*/
-#ifndef APT_HTTP_H
-#define APT_HTTP_H
-
-#define MAXLEN 360
+#ifndef APT_HTTPS_H
+#define APT_HTTPS_H
#include <iostream>
#include <curl/curl.h>
diff --git a/methods/makefile b/methods/makefile
index 6ba51058e..a271aff5e 100644
--- a/methods/makefile
+++ b/methods/makefile
@@ -7,7 +7,7 @@ include ../buildlib/defaults.mak
BIN := $(BIN)/methods
include ../buildlib/libversion.mak
-APT_DOMAIN := libapt-pkg$(LIBAPTPKG_MAJOR)
+APT_DOMAIN := apt
# The file method
PROGRAM=file
@@ -67,7 +67,7 @@ include $(PROGRAM_H)
# The rred method
PROGRAM=rred
-SLIBS = -lapt-pkg -lz $(SOCKETLIBS) $(INTLLIBS)
+SLIBS = -lapt-pkg $(SOCKETLIBS) $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = rred.cc
include $(PROGRAM_H)
@@ -86,16 +86,9 @@ LIB_MAKES = apt-pkg/makefile
SOURCE = mirror.cc http.cc rfc2553emu.cc connect.cc
include $(PROGRAM_H)
-# The gzip method
-PROGRAM=bzip2
-SLIBS = -lapt-pkg $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
-SOURCE = bzip2.cc
-include $(PROGRAM_H)
-
-# SSH and lzma method symlink
-binary: $(BIN)/ssh $(BIN)/lzma $(BIN)/xz
-veryclean: clean-$(BIN)/ssh clean-$(BIN)/lzma clean-$(BIN)/xz
+# SSH method symlink
+binary: $(BIN)/ssh
+veryclean: clean-$(BIN)/ssh
$(BIN)/ssh:
echo "Installing ssh method link"
@@ -103,14 +96,15 @@ $(BIN)/ssh:
clean-$(BIN)/ssh:
-rm $(BIN)/ssh
-$(BIN)/lzma:
- echo "Installing lzma method link"
- ln -fs bzip2 $(BIN)/lzma
-clean-$(BIN)/lzma:
- -rm $(BIN)/lzma
-
-$(BIN)/xz:
- echo "Installing xz method link"
- ln -fs bzip2 $(BIN)/xz
-clean-$(BIN)/xz:
- -rm $(BIN)/xz
+# create links for all other compressors
+COMPRESSORS=bzip2 lzma xz
+
+binary: $(addprefix $(BIN)/,$(COMPRESSORS))
+veryclean: $(addprefix clean-$(BIN)/,$(COMPRESSORS))
+
+$(addprefix $(BIN)/,$(COMPRESSORS)): $(BIN)/gzip
+ echo "Installing $(notdir $@) method link"
+ ln -fs gzip $@
+
+$(addprefix clean-$(BIN)/,$(COMPRESSORS)):
+ -rm $(BIN)/$(notdir $@)
diff --git a/methods/mirror.cc b/methods/mirror.cc
index 3d5983efa..d6c5ba955 100644
--- a/methods/mirror.cc
+++ b/methods/mirror.cc
@@ -124,9 +124,10 @@ bool MirrorMethod::Clean(string Dir)
if (I == list.end())
unlink(Dir->d_name);
};
-
- chdir(StartDir.c_str());
+
closedir(D);
+ if (chdir(StartDir.c_str()) != 0)
+ return _error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str());
return true;
}
@@ -147,9 +148,9 @@ bool MirrorMethod::DownloadMirrorFile(string mirror_uri_str)
// append all architectures
std::vector<std::string> vec = APT::Configuration::getArchitectures();
for (std::vector<std::string>::const_iterator I = vec.begin();
- I != vec.end(); I++)
+ I != vec.end(); ++I)
if (I == vec.begin())
- fetch += "?arch" + (*I);
+ fetch += "?arch=" + (*I);
else
fetch += "&arch=" + (*I);
diff --git a/methods/rred.cc b/methods/rred.cc
index 1e352d0e7..7c65f8f92 100644
--- a/methods/rred.cc
+++ b/methods/rred.cc
@@ -15,7 +15,6 @@
#include <utime.h>
#include <stdio.h>
#include <errno.h>
-#include <zlib.h>
#include <apti18n.h>
/*}}}*/
/** \brief RredMethod - ed-style incremential patch method {{{
@@ -227,6 +226,21 @@ struct EdCommand {
char type;
};
#define IOV_COUNT 1024 /* Don't really want IOV_MAX since it can be arbitrarily large */
+static ssize_t retry_writev(int fd, const struct iovec *iov, int iovcnt) {
+ ssize_t Res;
+ errno = 0;
+ ssize_t i = 0;
+ do {
+ Res = writev(fd, iov + i, iovcnt);
+ if (Res < 0 && errno == EINTR)
+ continue;
+ if (Res < 0)
+ return _error->Errno("writev",_("Write error"));
+ iovcnt -= Res;
+ i += Res;
+ } while (Res > 0 && iovcnt > 0);
+ return i;
+}
#endif
/*}}}*/
RredMethod::State RredMethod::patchMMap(FileFd &Patch, FileFd &From, /*{{{*/
@@ -377,7 +391,7 @@ RredMethod::State RredMethod::patchMMap(FileFd &Patch, FileFd &From, /*{{{*/
hash->Add((const unsigned char*) begin, input - begin);
if(++iov_size == IOV_COUNT) {
- writev(out_file.Fd(), iov, IOV_COUNT);
+ retry_writev(out_file.Fd(), iov, IOV_COUNT);
iov_size = 0;
}
}
@@ -402,7 +416,7 @@ RredMethod::State RredMethod::patchMMap(FileFd &Patch, FileFd &From, /*{{{*/
iov[iov_size].iov_len);
if(++iov_size == IOV_COUNT) {
- writev(out_file.Fd(), iov, IOV_COUNT);
+ retry_writev(out_file.Fd(), iov, IOV_COUNT);
iov_size = 0;
}
}
@@ -417,15 +431,15 @@ RredMethod::State RredMethod::patchMMap(FileFd &Patch, FileFd &From, /*{{{*/
}
if(iov_size) {
- writev(out_file.Fd(), iov, iov_size);
+ retry_writev(out_file.Fd(), iov, iov_size);
iov_size = 0;
}
for(i = 0; i < iov_size; i += IOV_COUNT) {
if(iov_size - i < IOV_COUNT)
- writev(out_file.Fd(), iov + i, iov_size - i);
+ retry_writev(out_file.Fd(), iov + i, iov_size - i);
else
- writev(out_file.Fd(), iov + i, IOV_COUNT);
+ retry_writev(out_file.Fd(), iov + i, IOV_COUNT);
}
delete [] iov;