summaryrefslogtreecommitdiff
path: root/apt-pkg/deb
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r--apt-pkg/deb/deblistparser.cc104
-rw-r--r--apt-pkg/deb/dpkgpm.cc59
2 files changed, 58 insertions, 105 deletions
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 28857176b..87aab6ee2 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -805,94 +805,28 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
map_ptrloc const storage = WriteUniqString(component);
FileI->Component = storage;
- // FIXME: should use FileFd and TagSection
- FILE* release = fdopen(dup(File.Fd()), "r");
- if (release == NULL)
+ pkgTagFile TagFile(&File, File.Size());
+ pkgTagSection Section;
+ if (_error->PendingError() == true || TagFile.Step(Section) == false)
return false;
- char buffer[101];
- while (fgets(buffer, sizeof(buffer), release) != NULL)
- {
- size_t len = 0;
-
- // Skip empty lines
- for (; buffer[len] == '\r' && buffer[len] == '\n'; ++len)
- /* nothing */
- ;
- if (buffer[len] == '\0')
- continue;
-
- // seperate the tag from the data
- const char* dataStart = strchr(buffer + len, ':');
- if (dataStart == NULL)
- continue;
- len = dataStart - buffer;
- for (++dataStart; *dataStart == ' '; ++dataStart)
- /* nothing */
- ;
- const char* dataEnd = (const char*)rawmemchr(dataStart, '\0');
- // The last char should be a newline, but we can never be sure: #633350
- const char* lineEnd = dataEnd;
- for (--lineEnd; *lineEnd == '\r' || *lineEnd == '\n'; --lineEnd)
- /* nothing */
- ;
- ++lineEnd;
-
- // which datastorage need to be updated
- enum { Suite, Component, Version, Origin, Codename, Label, None } writeTo = None;
- if (buffer[0] == ' ')
- ;
- #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
- APT_PARSER_WRITETO(Suite)
- APT_PARSER_WRITETO(Component)
- APT_PARSER_WRITETO(Version)
- APT_PARSER_WRITETO(Origin)
- APT_PARSER_WRITETO(Codename)
- APT_PARSER_WRITETO(Label)
- #undef APT_PARSER_WRITETO
- #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
- pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
- APT_PARSER_FLAGIT(NotAutomatic)
- APT_PARSER_FLAGIT(ButAutomaticUpgrades)
- #undef APT_PARSER_FLAGIT
-
- // load all data from the line and save it
- string data;
- if (writeTo != None)
- data.append(dataStart, dataEnd);
- if (sizeof(buffer) - 1 == (dataEnd - buffer))
- {
- while (fgets(buffer, sizeof(buffer), release) != NULL)
- {
- if (writeTo != None)
- data.append(buffer);
- if (strlen(buffer) != sizeof(buffer) - 1)
- break;
- }
- }
- if (writeTo != None)
- {
- // remove spaces and stuff from the end of the data line
- for (std::string::reverse_iterator s = data.rbegin();
- s != data.rend(); ++s)
- {
- if (*s != '\r' && *s != '\n' && *s != ' ')
- break;
- *s = '\0';
- }
- map_ptrloc const storage = WriteUniqString(data);
- switch (writeTo) {
- case Suite: FileI->Archive = storage; break;
- case Component: FileI->Component = storage; break;
- case Version: FileI->Version = storage; break;
- case Origin: FileI->Origin = storage; break;
- case Codename: FileI->Codename = storage; break;
- case Label: FileI->Label = storage; break;
- case None: break;
- }
- }
+ std::string data;
+ #define APT_INRELEASE(TAG, STORE) \
+ data = Section.FindS(TAG); \
+ if (data.empty() == false) \
+ { \
+ map_ptrloc const storage = WriteUniqString(data); \
+ STORE = storage; \
}
- fclose(release);
+ APT_INRELEASE("Suite", FileI->Archive)
+ APT_INRELEASE("Component", FileI->Component)
+ APT_INRELEASE("Version", FileI->Version)
+ APT_INRELEASE("Origin", FileI->Origin)
+ APT_INRELEASE("Codename", FileI->Codename)
+ APT_INRELEASE("Label", FileI->Label)
+ #undef APT_INRELEASE
+ Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic);
+ Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades);
return !_error->PendingError();
}
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index b0bd6b184..4b5467eff 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -134,7 +134,8 @@ static void dpkgChrootDirectory()
std::cerr << "Chrooting into " << chrootDir << std::endl;
if (chroot(chrootDir.c_str()) != 0)
_exit(100);
- chdir("/");
+ if (chdir("/") != 0)
+ _exit(100);
}
/*}}}*/
@@ -381,24 +382,32 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
OptSec = "DPkg::Tools::Options::" + string(Opts->Value.c_str(),Pos);
unsigned int Version = _config->FindI(OptSec+"::Version",1);
+ unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO);
// Create the pipes
int Pipes[2];
if (pipe(Pipes) != 0)
return _error->Errno("pipe","Failed to create IPC pipe to subprocess");
- SetCloseExec(Pipes[0],true);
+ if (InfoFD != (unsigned)Pipes[0])
+ SetCloseExec(Pipes[0],true);
+ else
+ _config->Set("APT::Keep-Fds::", Pipes[0]);
SetCloseExec(Pipes[1],true);
-
+
// Purified Fork for running the script
- pid_t Process = ExecFork();
+ pid_t Process = ExecFork();
if (Process == 0)
{
// Setup the FDs
- dup2(Pipes[0],STDIN_FILENO);
+ dup2(Pipes[0], InfoFD);
SetCloseExec(STDOUT_FILENO,false);
- SetCloseExec(STDIN_FILENO,false);
+ SetCloseExec(STDIN_FILENO,false);
SetCloseExec(STDERR_FILENO,false);
+ string hookfd;
+ strprintf(hookfd, "%d", InfoFD);
+ setenv("APT_HOOK_INFO_FD", hookfd.c_str(), 1);
+
dpkgChrootDirectory();
const char *Args[4];
Args[0] = "/bin/sh";
@@ -408,6 +417,8 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
execv(Args[0],(char **)Args);
_exit(100);
}
+ if (InfoFD == (unsigned)Pipes[0])
+ _config->Clear("APT::Keep-Fds", Pipes[0]);
close(Pipes[0]);
FILE *F = fdopen(Pipes[1],"w");
if (F == 0)
@@ -750,13 +761,15 @@ bool pkgDPkgPM::OpenLog()
return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
setvbuf(d->term_out, NULL, _IONBF, 0);
SetCloseExec(fileno(d->term_out), true);
- struct passwd *pw;
- struct group *gr;
- pw = getpwnam("root");
- gr = getgrnam("adm");
- if (pw != NULL && gr != NULL)
- chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid);
- chmod(logfile_name.c_str(), 0640);
+ if (getuid() == 0) // if we aren't root, we can't chown a file, so don't try it
+ {
+ struct passwd *pw = getpwnam("root");
+ struct group *gr = getgrnam("adm");
+ if (pw != NULL && gr != NULL && chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid) != 0)
+ _error->WarningE("OpenLog", "chown to root:adm of file %s failed", logfile_name.c_str());
+ }
+ if (chmod(logfile_name.c_str(), 0640) != 0)
+ _error->WarningE("OpenLog", "chmod 0640 of file %s failed", logfile_name.c_str());
fprintf(d->term_out, "\nLog started: %s\n", timestr);
}
@@ -1235,16 +1248,13 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// if tcgetattr does not return zero there was a error
// and we do not do any pty magic
- if (tcgetattr(0, &tt) == 0)
+ _error->PushToStack();
+ if (tcgetattr(STDOUT_FILENO, &tt) == 0)
{
ioctl(0, TIOCGWINSZ, (char *)&win);
- if (openpty(&master, &slave, NULL, &tt, &win) < 0)
+ if (openpty(&master, &slave, NULL, &tt, &win) < 0)
{
- const char *s = _("Can not write log, openpty() "
- "failed (/dev/pts not mounted?)\n");
- fprintf(stderr, "%s",s);
- if(d->term_out)
- fprintf(d->term_out, "%s",s);
+ _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
master = slave = -1;
} else {
struct termios rtt;
@@ -1262,6 +1272,15 @@ bool pkgDPkgPM::Go(int OutStatusFd)
sigprocmask(SIG_SETMASK, &original_sigmask, 0);
}
}
+ // complain only if stdout is either a terminal (but still failed) or is an invalid
+ // descriptor otherwise we would complain about redirection to e.g. /dev/null as well.
+ else if (isatty(STDOUT_FILENO) == 1 || errno == EBADF)
+ _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?"));
+
+ if (_error->PendingError() == true)
+ _error->DumpErrors(std::cerr);
+ _error->RevertToStack();
+
// Fork dpkg
pid_t Child;
_config->Set("APT::Keep-Fds::",fd[1]);