]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/deb/dpkgpm.cc
apt-pkg/tagfile.h: add dpointer placeholder, make destructor virtual; apt-pkg/deb...
[apt.git] / apt-pkg / deb / dpkgpm.cc
index aa0b04bd5a9ab0eac5c7a814d0783039e61e8f6b..55525db85a9ca729be99bab2ff504b4359ef156c 100644 (file)
 
 using namespace std;
 
 
 using namespace std;
 
+class pkgDPkgPMPrivate 
+{
+public:
+   pkgDPkgPMPrivate() : dpkgbuf_pos(0), term_out(NULL), history_out(NULL)
+   {
+   }
+   bool stdin_is_dev_null;
+   // the buffer we use for the dpkg status-fd reading
+   char dpkgbuf[1024];
+   int dpkgbuf_pos;
+   FILE *term_out;
+   FILE *history_out;
+   string dpkg_error;
+};
+
 namespace
 {
   // Maps the dpkg "processing" info to human readable names.  Entry 0
 namespace
 {
   // Maps the dpkg "processing" info to human readable names.  Entry 0
@@ -108,9 +123,9 @@ ionice(int PID)
 // ---------------------------------------------------------------------
 /* */
 pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
 // ---------------------------------------------------------------------
 /* */
 pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
-   : pkgPackageManager(Cache), dpkgbuf_pos(0),
-     term_out(NULL), history_out(NULL), PackagesDone(0), PackagesTotal(0)
+   : pkgPackageManager(Cache), PackagesDone(0), PackagesTotal(0)
 {
 {
+   d = new pkgDPkgPMPrivate();
 }
                                                                        /*}}}*/
 // DPkgPM::pkgDPkgPM - Destructor                                      /*{{{*/
 }
                                                                        /*}}}*/
 // DPkgPM::pkgDPkgPM - Destructor                                      /*{{{*/
@@ -118,6 +133,7 @@ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache)
 /* */
 pkgDPkgPM::~pkgDPkgPM()
 {
 /* */
 pkgDPkgPM::~pkgDPkgPM()
 {
+   delete d;
 }
                                                                        /*}}}*/
 // DPkgPM::Install - Install a package                                 /*{{{*/
 }
                                                                        /*}}}*/
 // DPkgPM::Install - Install a package                                 /*{{{*/
@@ -369,7 +385,7 @@ void pkgDPkgPM::DoStdin(int master)
    if (len)
       write(master, input_buf, len);
    else
    if (len)
       write(master, input_buf, len);
    else
-      stdin_is_dev_null = true;
+      d->stdin_is_dev_null = true;
 }
                                                                        /*}}}*/
 // DPkgPM::DoTerminalPty - Read the terminal pty and write log         /*{{{*/
 }
                                                                        /*}}}*/
 // DPkgPM::DoTerminalPty - Read the terminal pty and write log         /*{{{*/
@@ -393,8 +409,8 @@ void pkgDPkgPM::DoTerminalPty(int master)
    if(len <= 0) 
       return;
    write(1, term_buf, len);
    if(len <= 0) 
       return;
    write(1, term_buf, len);
-   if(term_out)
-      fwrite(term_buf, len, sizeof(char), term_out);
+   if(d->term_out)
+      fwrite(term_buf, len, sizeof(char), d->term_out);
 }
                                                                        /*}}}*/
 // DPkgPM::ProcessDpkgStatusBuf                                                /*{{{*/
 }
                                                                        /*}}}*/
 // DPkgPM::ProcessDpkgStatusBuf                                                /*{{{*/
@@ -554,7 +570,7 @@ void pkgDPkgPM::handleDisappearAction(string const &pkgname)
    // the disappeared package was auto-installed - nothing to do
    if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
       return;
    // the disappeared package was auto-installed - nothing to do
    if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
       return;
-   pkgCache::VerIterator PkgVer = Pkg.CurrentVer();
+   pkgCache::VerIterator PkgVer = Cache[Pkg].InstVerIter(Cache);
    if (unlikely(PkgVer.end() == true))
       return;
    /* search in the list of dependencies for (Pre)Depends,
    if (unlikely(PkgVer.end() == true))
       return;
    /* search in the list of dependencies for (Pre)Depends,
@@ -571,7 +587,9 @@ void pkgDPkgPM::handleDisappearAction(string const &pkgname)
       // the package is already marked as manual
       if ((Cache[Tar].Flags & pkgCache::Flag::Auto) != pkgCache::Flag::Auto)
         continue;
       // the package is already marked as manual
       if ((Cache[Tar].Flags & pkgCache::Flag::Auto) != pkgCache::Flag::Auto)
         continue;
-      pkgCache::VerIterator TarVer = Tar.CurrentVer();
+      pkgCache::VerIterator TarVer =  Cache[Tar].InstVerIter(Cache);
+      if (TarVer.end() == true)
+        continue;
       for (pkgCache::DepIterator Rep = TarVer.DependsList(); Rep.end() != true; ++Rep)
       {
         if (Rep->Type != pkgCache::Dep::Replaces)
       for (pkgCache::DepIterator Rep = TarVer.DependsList(); Rep.end() != true; ++Rep)
       {
         if (Rep->Type != pkgCache::Dep::Replaces)
@@ -596,14 +614,14 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
    char *p, *q;
    int len;
 
    char *p, *q;
    int len;
 
-   len=read(statusfd, &dpkgbuf[dpkgbuf_pos], sizeof(dpkgbuf)-dpkgbuf_pos);
-   dpkgbuf_pos += len;
+   len=read(statusfd, &d->dpkgbuf[d->dpkgbuf_pos], sizeof(d->dpkgbuf)-d->dpkgbuf_pos);
+   d->dpkgbuf_pos += len;
    if(len <= 0)
       return;
 
    // process line by line if we have a buffer
    if(len <= 0)
       return;
 
    // process line by line if we have a buffer
-   p = q = dpkgbuf;
-   while((q=(char*)memchr(p, '\n', dpkgbuf+dpkgbuf_pos-p)) != NULL)
+   p = q = d->dpkgbuf;
+   while((q=(char*)memchr(p, '\n', d->dpkgbuf+d->dpkgbuf_pos-p)) != NULL)
    {
       *q = 0;
       ProcessDpkgStatusLine(OutStatusFd, p);
    {
       *q = 0;
       ProcessDpkgStatusLine(OutStatusFd, p);
@@ -611,8 +629,8 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
    }
 
    // now move the unprocessed bits (after the final \n that is now a 0x0) 
    }
 
    // now move the unprocessed bits (after the final \n that is now a 0x0) 
-   // to the start and update dpkgbuf_pos
-   p = (char*)memrchr(dpkgbuf, 0, dpkgbuf_pos);
+   // to the start and update d->dpkgbuf_pos
+   p = (char*)memrchr(d->dpkgbuf, 0, d->dpkgbuf_pos);
    if(p == NULL)
       return;
 
    if(p == NULL)
       return;
 
@@ -620,8 +638,8 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
    p++;
 
    // move the unprocessed tail to the start and update pos
    p++;
 
    // move the unprocessed tail to the start and update pos
-   memmove(dpkgbuf, p, p-dpkgbuf);
-   dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p;
+   memmove(d->dpkgbuf, p, p-d->dpkgbuf);
+   d->dpkgbuf_pos = d->dpkgbuf+d->dpkgbuf_pos-p;
 }
                                                                        /*}}}*/
 // DPkgPM::WriteHistoryTag                                             /*{{{*/
 }
                                                                        /*}}}*/
 // DPkgPM::WriteHistoryTag                                             /*{{{*/
@@ -633,13 +651,14 @@ void pkgDPkgPM::WriteHistoryTag(string const &tag, string value)
    // poor mans rstrip(", ")
    if (value[length-2] == ',' && value[length-1] == ' ')
       value.erase(length - 2, 2);
    // poor mans rstrip(", ")
    if (value[length-2] == ',' && value[length-1] == ' ')
       value.erase(length - 2, 2);
-   fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str());
+   fprintf(d->history_out, "%s: %s\n", tag.c_str(), value.c_str());
 }                                                                      /*}}}*/
 // DPkgPM::OpenLog                                                     /*{{{*/
 bool pkgDPkgPM::OpenLog()
 {
    string const logdir = _config->FindDir("Dir::Log");
 }                                                                      /*}}}*/
 // DPkgPM::OpenLog                                                     /*{{{*/
 bool pkgDPkgPM::OpenLog()
 {
    string const logdir = _config->FindDir("Dir::Log");
-   if(not FileExists(logdir))
+   if(CreateAPTDirectoryIfNeeded(logdir, logdir) == false)
+      // FIXME: use a better string after freeze
       return _error->Error(_("Directory '%s' missing"), logdir.c_str());
 
    // get current time
       return _error->Error(_("Directory '%s' missing"), logdir.c_str());
 
    // get current time
@@ -653,12 +672,13 @@ bool pkgDPkgPM::OpenLog()
                                   _config->Find("Dir::Log::Terminal"));
    if (!logfile_name.empty())
    {
                                   _config->Find("Dir::Log::Terminal"));
    if (!logfile_name.empty())
    {
-      term_out = fopen(logfile_name.c_str(),"a");
-      if (term_out == NULL)
+      d->term_out = fopen(logfile_name.c_str(),"a");
+      if (d->term_out == NULL)
         return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
         return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
-      setvbuf(term_out, NULL, _IONBF, 0);
+      setvbuf(d->term_out, NULL, _IONBF, 0);
+      SetCloseExec(fileno(d->term_out), true);
       chmod(logfile_name.c_str(), 0600);
       chmod(logfile_name.c_str(), 0600);
-      fprintf(term_out, "\nLog started: %s\n", timestr);
+      fprintf(d->term_out, "\nLog started: %s\n", timestr);
    }
 
    // write your history
    }
 
    // write your history
@@ -666,11 +686,11 @@ bool pkgDPkgPM::OpenLog()
                                   _config->Find("Dir::Log::History"));
    if (!history_name.empty())
    {
                                   _config->Find("Dir::Log::History"));
    if (!history_name.empty())
    {
-      history_out = fopen(history_name.c_str(),"a");
-      if (history_out == NULL)
+      d->history_out = fopen(history_name.c_str(),"a");
+      if (d->history_out == NULL)
         return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str());
       chmod(history_name.c_str(), 0644);
         return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str());
       chmod(history_name.c_str(), 0644);
-      fprintf(history_out, "\nStart-Date: %s\n", timestr);
+      fprintf(d->history_out, "\nStart-Date: %s\n", timestr);
       string remove, purge, install, upgrade, downgrade;
       for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
       {
       string remove, purge, install, upgrade, downgrade;
       for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
       {
@@ -700,7 +720,7 @@ bool pkgDPkgPM::OpenLog()
       WriteHistoryTag("Downgrade",downgrade);
       WriteHistoryTag("Remove",remove);
       WriteHistoryTag("Purge",purge);
       WriteHistoryTag("Downgrade",downgrade);
       WriteHistoryTag("Remove",remove);
       WriteHistoryTag("Purge",purge);
-      fflush(history_out);
+      fflush(d->history_out);
    }
    
    return true;
    }
    
    return true;
@@ -714,16 +734,16 @@ bool pkgDPkgPM::CloseLog()
    struct tm *tmp = localtime(&t);
    strftime(timestr, sizeof(timestr), "%F  %T", tmp);
 
    struct tm *tmp = localtime(&t);
    strftime(timestr, sizeof(timestr), "%F  %T", tmp);
 
-   if(term_out)
+   if(d->term_out)
    {
    {
-      fprintf(term_out, "Log ended: ");
-      fprintf(term_out, "%s", timestr);
-      fprintf(term_out, "\n");
-      fclose(term_out);
+      fprintf(d->term_out, "Log ended: ");
+      fprintf(d->term_out, "%s", timestr);
+      fprintf(d->term_out, "\n");
+      fclose(d->term_out);
    }
    }
-   term_out = NULL;
+   d->term_out = NULL;
 
 
-   if(history_out)
+   if(d->history_out)
    {
       if (disappearedPkgs.empty() == false)
       {
    {
       if (disappearedPkgs.empty() == false)
       {
@@ -740,12 +760,12 @@ bool pkgDPkgPM::CloseLog()
         }
         WriteHistoryTag("Disappeared", disappear);
       }
         }
         WriteHistoryTag("Disappeared", disappear);
       }
-      if (dpkg_error.empty() == false)
-        fprintf(history_out, "Error: %s\n", dpkg_error.c_str());
-      fprintf(history_out, "End-Date: %s\n", timestr);
-      fclose(history_out);
+      if (d->dpkg_error.empty() == false)
+        fprintf(d->history_out, "Error: %s\n", d->dpkg_error.c_str());
+      fprintf(d->history_out, "End-Date: %s\n", timestr);
+      fclose(d->history_out);
    }
    }
-   history_out = NULL;
+   d->history_out = NULL;
 
    return true;
 }
 
    return true;
 }
@@ -853,7 +873,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       }
    }
 
       }
    }
 
-   stdin_is_dev_null = false;
+   d->stdin_is_dev_null = false;
 
    // create log
    OpenLog();
 
    // create log
    OpenLog();
@@ -1039,8 +1059,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
            const char *s = _("Can not write log, openpty() "
                              "failed (/dev/pts not mounted?)\n");
            fprintf(stderr, "%s",s);
            const char *s = _("Can not write log, openpty() "
                              "failed (/dev/pts not mounted?)\n");
            fprintf(stderr, "%s",s);
-            if(term_out)
-              fprintf(term_out, "%s",s);
+            if(d->term_out)
+              fprintf(d->term_out, "%s",s);
            master = slave = -1;
         }  else {
            struct termios rtt;
            master = slave = -1;
         }  else {
            struct termios rtt;
@@ -1165,7 +1185,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 
         // wait for input or output here
         FD_ZERO(&rfds);
 
         // wait for input or output here
         FD_ZERO(&rfds);
-        if (master >= 0 && !stdin_is_dev_null)
+        if (master >= 0 && !d->stdin_is_dev_null)
            FD_SET(0, &rfds); 
         FD_SET(_dpkgin, &rfds);
         if(master >= 0)
            FD_SET(0, &rfds); 
         FD_SET(_dpkgin, &rfds);
         if(master >= 0)
@@ -1219,14 +1239,14 @@ bool pkgDPkgPM::Go(int OutStatusFd)
            RunScripts("DPkg::Post-Invoke");
 
         if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) 
            RunScripts("DPkg::Post-Invoke");
 
         if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) 
-           strprintf(dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]);
+           strprintf(d->dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]);
         else if (WIFEXITED(Status) != 0)
         else if (WIFEXITED(Status) != 0)
-           strprintf(dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
+           strprintf(d->dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
         else 
         else 
-           strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
+           strprintf(d->dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
 
 
-        if(dpkg_error.size() > 0)
-           _error->Error(dpkg_error.c_str());
+        if(d->dpkg_error.size() > 0)
+           _error->Error(d->dpkg_error.c_str());
 
         if(stopOnError) 
         {
 
         if(stopOnError) 
         {
@@ -1373,8 +1393,8 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
    fprintf(report, "ErrorMessage:\n %s\n", errormsg);
 
    // ensure that the log is flushed
    fprintf(report, "ErrorMessage:\n %s\n", errormsg);
 
    // ensure that the log is flushed
-   if(term_out)
-      fflush(term_out);
+   if(d->term_out)
+      fflush(d->term_out);
 
    // attach terminal log it if we have it
    string logfile_name = _config->FindFile("Dir::Log::Terminal");
 
    // attach terminal log it if we have it
    string logfile_name = _config->FindFile("Dir::Log::Terminal");