* apt-pkg/deb/dpkgpm.cc:
authorDavid Kalnischkies <kalnischkies@gmail.com>
Fri, 12 Mar 2010 18:41:30 +0000 (19:41 +0100)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Fri, 12 Mar 2010 18:41:30 +0000 (19:41 +0100)
  - if available store the Commandline in the history
* apt-pkg/contrib/cmndline.cc:
  - save Commandline in Commandline::AsString for logging

apt-pkg/contrib/cmndline.cc
apt-pkg/contrib/cmndline.h
apt-pkg/deb/dpkgpm.cc
debian/changelog
test/libapt/commandlineasstring_test.cc [new file with mode: 0644]
test/libapt/makefile

index bfd5369..0b16bf5 100644 (file)
@@ -135,7 +135,9 @@ bool CommandLine::Parse(int argc,const char **argv)
    for (; I != argc; I++)
       *Files++ = argv[I];
    *Files = 0;
-   
+
+   SaveInConfig(argc, argv);
+
    return true;
 }
                                                                        /*}}}*/
@@ -351,3 +353,41 @@ bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch)
    return false;
 }
                                                                        /*}}}*/
+// CommandLine::SaveInConfig - for output later in a logfile or so     /*{{{*/
+// ---------------------------------------------------------------------
+/* We save the commandline here to have it around later for e.g. logging.
+   It feels a bit like a hack here and isn't bulletproof, but it is better
+   than nothing after all. */
+void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * const argv)
+{
+   char cmdline[300];
+   unsigned int length = 0;
+   bool lastWasOption = false;
+   bool closeQuote = false;
+   for (unsigned int i = 0; i < argc; ++i, ++length)
+   {
+      for (unsigned int j = 0; argv[i][j] != '\0' && length < sizeof(cmdline)-1; ++j, ++length)
+      {
+        cmdline[length] = argv[i][j];
+        if (lastWasOption == true && argv[i][j] == '=')
+        {
+           // That is possibly an option: Quote it if it includes spaces,
+           // the benefit is that this will eliminate also most false positives
+           const char* c = &argv[i][j+1];
+           for (; *c != '\0' && *c != ' '; ++c);
+           if (*c == '\0') continue;
+           cmdline[++length] = '"';
+           closeQuote = true;
+        }
+      }
+      if (closeQuote == true)
+        cmdline[length++] = '"';
+      // Problem: detects also --hello
+      if (cmdline[length-1] == 'o')
+        lastWasOption = true;
+      cmdline[length] = ' ';
+   }
+   cmdline[--length] = '\0';
+   _config->Set("CommandLine::AsString", cmdline);
+}
+                                                                       /*}}}*/
index e28071e..7c0c71a 100644 (file)
@@ -60,6 +60,7 @@ class CommandLine
    Configuration *Conf;
    bool HandleOpt(int &I,int argc,const char *argv[],
                  const char *&Opt,Args *A,bool PreceedeMatch = false);
+   void static SaveInConfig(unsigned int const &argc, char const * const * const argv);
 
    public:
    
index ad1ea77..9ba6006 100644 (file)
@@ -614,6 +614,8 @@ bool pkgDPkgPM::OpenLog()
               remove += I.Name() + string(" (") + Cache[I].CurVersion + string("), ");     
         }
       }
+      if (_config->Exists("Commandline::AsString") == true)
+        WriteHistoryTag("Commandline", _config->Find("Commandline::AsString"));
       WriteHistoryTag("Install", install);
       WriteHistoryTag("Upgrade", upgrade);
       WriteHistoryTag("Downgrade",downgrade);
index b05498f..506e70a 100644 (file)
@@ -14,9 +14,12 @@ apt (0.7.26) UNRELEASED; urgency=low
       Thanks to Osamu Aoki for pointing it out! (Closes: #567669)
   * apt-pkg/deb/dpkgpm.cc:
     - fix error message construction in OpenLog()
+    - if available store the Commandline in the history
   * cmdline/apt-get.cc:
     - add a --only-upgrade flag to install command (Closes: #572259)
     - fix memory leaks in error conditions in DoSource()
+  * apt-pkg/contrib/cmndline.cc:
+    - save Commandline in Commandline::AsString for logging
 
  -- David Kalnischkies <kalnischkies@gmail.com>  Fri, 19 Feb 2010 21:21:43 +0100
 
diff --git a/test/libapt/commandlineasstring_test.cc b/test/libapt/commandlineasstring_test.cc
new file mode 100644 (file)
index 0000000..a38957d
--- /dev/null
@@ -0,0 +1,39 @@
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/configuration.h>
+
+#include <string>
+
+#include "assert.h"
+
+class CLT: public CommandLine {
+
+       public:
+       std::string static AsString(const char * const * const argv,
+                                   unsigned int const argc) {
+               std::string const static conf = "Commandline::AsString";
+               _config->Clear(conf);
+               SaveInConfig(argc, argv);
+               return _config->Find(conf);
+       }
+};
+
+#define CMD(y,z) equals(CLT::AsString(argv, y), z);
+
+int main() {
+       {
+               const char* const argv[] = {"apt-get", "install", "-sf"};
+               CMD(3, "apt-get install -sf");
+       }
+       {
+               const char* const argv[] = {"apt-cache", "-s", "apt", "-so", "Debug::test=Test"};
+               CMD(5, "apt-cache -s apt -so Debug::test=Test");
+       }
+       {
+               const char* const argv[] = {"apt-cache", "-s", "apt", "-so", "Debug::test=Das ist ein Test"};
+               CMD(5, "apt-cache -s apt -so Debug::test=\"Das ist ein Test\"");
+       }
+       {
+               const char* const argv[] = {"apt-cache", "-s", "apt", "--hallo", "test=1.0"};
+               CMD(5, "apt-cache -s apt --hallo test=1.0");
+       }
+}
index 08f581e..cb76d5e 100644 (file)
@@ -23,3 +23,9 @@ PROGRAM = GetListOfFilesInDir${BASENAME}
 SLIBS = -lapt-pkg
 SOURCE = getlistoffilesindir_test.cc
 include $(PROGRAM_H)
+
+# Program for testing CommandLine reconstruction
+PROGRAM = commandlineasstring${BASENAME}
+SLIBS = -lapt-pkg
+SOURCE = commandlineasstring_test.cc
+include $(PROGRAM_H)