From: Michael Vogt Date: Fri, 3 Aug 2007 17:24:22 +0000 (+0200) Subject: * merged from apt--mvo X-Git-Tag: 0.7.24ubuntu1~160 X-Git-Url: https://git.saurik.com/apt.git/commitdiff_plain/04b38410e88705c26f191ca654cb89ab91c866ad?hp=-c * merged from apt--mvo --- 04b38410e88705c26f191ca654cb89ab91c866ad diff --combined apt-pkg/deb/dpkgpm.cc index 6cb444ef1,168c31483..de84ba96a --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@@ -12,7 -12,6 +12,7 @@@ #include #include #include +#include #include #include @@@ -44,8 -43,7 +44,8 @@@ using namespace std // --------------------------------------------------------------------- /* */ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) - : pkgPackageManager(Cache), dpkgbuf_pos(0), PackagesTotal(0), - PackagesDone(0), term_out(NULL) - : pkgPackageManager(Cache), dpkgbuf_pos(0), PackagesDone(0), PackagesTotal(0) ++ : pkgPackageManager(Cache), dpkgbuf_pos(0), ++ PackagesTotal(0), PackagesDone(0), term_out(NULL) { } /*}}}*/ @@@ -352,7 -350,7 +352,7 @@@ void pkgDPkgPM::DoStdin(int master /* * read the terminal pty and write log */ -void pkgDPkgPM::DoTerminalPty(int master, FILE *term_out) +void pkgDPkgPM::DoTerminalPty(int master) { char term_buf[1024] = {0,}; @@@ -411,8 -409,6 +411,8 @@@ void pkgDPkgPM::ProcessDpkgStatusLine(i write(OutStatusFd, status.str().c_str(), status.str().size()); if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) std::clog << "send: '" << status.str() << "'" << endl; + pkgFailures++; + WriteApportReport(list[1], list[3]); return; } if(strncmp(action,"conffile",strlen("conffile")) == 0) @@@ -570,6 -566,7 +570,6 @@@ bool pkgDPkgPM::Go(int OutStatusFd return _error->Error(_("Directory '%s' missing"), logdir.c_str()); string logfile_name = flCombine(logdir, _config->Find("Dir::Log::Terminal")); - FILE *term_out = NULL; if (!logfile_name.empty()) { term_out = fopen(logfile_name.c_str(),"a"); @@@ -773,9 -770,6 +773,6 @@@ int _dpkgin = fd[0]; close(fd[1]); // close the write end of the pipe - // the read buffers for the communication with dpkg - char buf[2] = {0,0}; - // the result of the waitpid call int res; close(slave); @@@ -812,7 -806,7 +809,7 @@@ continue; if(FD_ISSET(master, &rfds)) - DoTerminalPty(master, term_out); + DoTerminalPty(master); if(FD_ISSET(0, &rfds)) DoStdin(master); if(FD_ISSET(_dpkgin, &rfds)) @@@ -868,115 -862,3 +865,115 @@@ void pkgDPkgPM::Reset( List.erase(List.begin(),List.end()); } /*}}}*/ +// pkgDpkgPM::WriteApportReport - write out error report pkg failure /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) +{ + string pkgname, reportfile, srcpkgname, pkgver, arch; + string::size_type pos; + FILE *report; + + if (_config->FindB("Dpkg::ApportFailureReport",true) == false) + return; + + // only report the first error if we are in StopOnError=false mode + // to prevent bogus reports + if((_config->FindB("Dpkg::StopOnError",true) == false) && pkgFailures > 1) + return; + + // get the pkgname and reportfile + pkgname = flNotDir(pkgpath); + pos = pkgname.rfind('_'); + if(pos != string::npos) + pkgname = string(pkgname, 0, pos); + + // find the package versin and source package name + pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname); + if (Pkg.end() == true) + return; + pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); + pkgver = Ver.VerStr(); + if (Ver.end() == true) + return; + pkgRecords Recs(Cache); + pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); + srcpkgname = Parse.SourcePkg(); + if(srcpkgname.empty()) + srcpkgname = pkgname; + + // if the file exists already, we check: + // - if it was reported already (touched by apport). + // If not, we do nothing, otherwise + // we overwrite it. This is the same behaviour as apport + // - if we have a report with the same pkgversion already + // then we skip it + reportfile = flCombine("/var/crash",pkgname+".0.crash"); + if(FileExists(reportfile)) + { + struct stat buf; + char strbuf[255]; + + // check atime/mtime + stat(reportfile.c_str(), &buf); + if(buf.st_mtime > buf.st_atime) + return; + + // check if the existing report is the same version + report = fopen(reportfile.c_str(),"r"); + while(fgets(strbuf, sizeof(strbuf), report) != NULL) + { + if(strstr(strbuf,"Package:") == strbuf) + { + char pkgname[255], version[255]; + if(sscanf(strbuf, "Package: %s %s", pkgname, version) == 2) + if(strcmp(pkgver.c_str(), version) == 0) + { + fclose(report); + return; + } + } + } + fclose(report); + } + + // now write the report + arch = _config->Find("APT::Architecture"); + report = fopen(reportfile.c_str(),"w"); + if(report == NULL) + return; + if(_config->FindB("DPkgPM::InitialReportOnly",false) == true) + chmod(reportfile.c_str(), 0); + else + chmod(reportfile.c_str(), 0600); + fprintf(report, "ProblemType: Package\n"); + fprintf(report, "Architecture: %s\n", arch.c_str()); + time_t now = time(NULL); + fprintf(report, "Date: %s" , ctime(&now)); + fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str()); + fprintf(report, "SourcePackage: %s\n", srcpkgname.c_str()); + fprintf(report, "ErrorMessage:\n %s\n", errormsg); + + // ensure that the log is flushed + if(term_out) + fflush(term_out); + + // attach terminal log it if we have it + string logfile_name = _config->FindFile("Dir::Log::Terminal"); + if (!logfile_name.empty()) + { + FILE *log = NULL; + char buf[1024]; + + fprintf(report, "DpkgTerminalLog:\n"); + log = fopen(logfile_name.c_str(),"r"); + if(log != NULL) + { + while( fgets(buf, sizeof(buf), log) != NULL) + fprintf(report, " %s", buf); + fclose(log); + } + } + fclose(report); +} + /*}}}*/ diff --combined apt-pkg/deb/dpkgpm.h index 222add98f,065c6c917..debde36a3 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@@ -26,10 -26,8 +26,10 @@@ class pkgDPkgPM : public pkgPackageMana // the buffer we use for the dpkg status-fd reading char dpkgbuf[1024]; int dpkgbuf_pos; - + FILE *term_out; + protected: + int pkgFailures; // progress reporting struct DpkgState @@@ -45,10 -43,10 +45,10 @@@ // the dpkg states that are already done; the string is the package // the int is the state that is already done (e.g. a package that is // going to be install is already in state "half-installed") - map PackageOpsDone; + map PackageOpsDone; // progress reporting - int PackagesDone; - int PackagesTotal; + unsigned int PackagesDone; + unsigned int PackagesTotal; struct Item { @@@ -67,12 -65,9 +67,12 @@@ bool RunScriptsWithPkgs(const char *Cnf); bool SendV2Pkgs(FILE *F); + // apport integration + void WriteApportReport(const char *pkgpath, const char *errormsg); + // input processing void DoStdin(int master); - void DoTerminalPty(int master, FILE *out); + void DoTerminalPty(int master); void DoDpkgStatusFd(int statusfd, int OutStatusFd); void ProcessDpkgStatusLine(int OutStatusFd, char *line); diff --combined debian/control index ac14c5e0b,742e8ca5c..6c1453857 --- a/debian/control +++ b/debian/control @@@ -1,22 -1,20 +1,22 @@@ Source: apt Section: admin Priority: important -Maintainer: APT Development Team +Maintainer: Ubuntu Core Developers +XSBC-Original-Maintainer: APT Development Team Uploaders: Jason Gunthorpe , Adam Heath , Matt Zimmerman , Michael Vogt , Otavio Salvador Standards-Version: 3.7.2.2 Build-Depends: debhelper (>= 5.0), libdb4.4-dev, gettext (>= 0.12), libcurl4-gnutls-dev | libcurl3-gnutls-dev (>= 7.15.5) Build-Depends-Indep: debiandoc-sgml, docbook-utils (>= 0.6.12-1) -XS-Vcs-Bzr: http://bzr.debian.org/apt/debian-sid/ +XS-Vcs-Bzr: http://code.launchpad.net/~ubuntu-core-dev/apt/ubuntu Package: apt Architecture: any -Depends: ${shlibs:Depends}, debian-archive-keyring +Depends: ${shlibs:Depends} Priority: important Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7) Provides: ${libapt-pkg:provides} -Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2, lzma +Recommends: ubuntu-keyring - Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2, gnupg, lzma ++Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2, lzma, gnupg Section: admin Description: Advanced front-end for dpkg This is Debian's next generation front-end for the dpkg package manager.