Classification: medium HACK

With this patch information given on the CLI are staying intact. Else,
they would be merged to a single string which will break e.g. handling
of '--define "foo bar"'.

Some parts of the patch are just quick hacks; mach should be written
so that arguments are always arrays which gets merged to a parameter
of system()/popen() as late as possible. Usage of execv() should be
prefered also.

2003-12-13  Enrico Scholz  <enrico.scholz@informatik.tu-chemnitz.de>
        * rediffed
	* do not shell-escape buildrequirements anymore; this is done
	  by the aptget() method already

2003-12-05  Enrico Scholz  <enrico.scholz@informatik.tu-chemnitz.de>
	* created initially
--- mach/scripts/mach.in~args	2003-12-13 01:39:52.000000000 +0100
+++ mach/scripts/mach.in	2003-12-13 01:39:52.000000000 +0100
@@ -107,7 +107,7 @@
 
 
 # rpm -q format, users may have customized %_query_all_fmt in ~/.rpmmacros...
-qfmt = '"%{name}-%{version}-%{release}\n"'
+qfmt = '%{name}-%{version}-%{release}\\n'
 
 def escapeShell(opt, level=1):
     while level>0:
@@ -429,7 +429,7 @@
         result = []
         other = []
         match = re.compile (matcher, re.I)
-        for arg in argstring.split ():
+        for arg in argstring:
             if match.search (arg):
                 result.append (arg)
             else:
@@ -453,7 +453,8 @@
                 progress = False, interactive = False):
         "run apt-get (arg) from outside the root on the root"
         conf = os.path.join (self.statedir, 'apt.conf')
-        command = "%s -c %s %s" % (self.config['apt-get'], conf, arg)
+        args_esc = map(lambda x: escapeShell(x), arg)
+        command  = "%s -c %s %s" % (self.config['apt-get'], conf, string.join(args_esc))
         if interactive:
             return os.system (command)
         if message: self.stdout (message)
@@ -461,7 +462,7 @@
         (status, output) = do_with_output (command, progress)
         if message and not progress: self.stdout ('\n')
         if status != 0:
-            raise self.Error, "Could not apt-get %s" % arg
+            raise self.Error, "Could not apt-get %s" % (arg,)
 
     def intaptget (self, arg):
         if not self.get_state ('base'):
@@ -473,18 +474,20 @@
     def aptcache (self, arg, progress = False):
         "run apt-cache (arg) from outside the root on the root"
         conf = os.path.join (self.statedir, 'apt.conf')
-        command = "%s -c %s %s" % (self.config['apt-cache'], conf, arg)
+        args_esc = map(lambda x: escapeShell(x), arg)
+        command  = "%s -c %s %s" % (self.config['apt-cache'], conf, string.join(args_esc))
         (status, output) = do_with_output (command, progress)
         if status != 0:
-            raise self.Error, "Could not apt-cache %s" % arg
+            raise self.Error, "Could not apt-cache %s" % (arg,)
         print output
 
     def rpm (self, arg, progress = False):
         "run rpm (arg) from outside the root on the root, returns output"
-        command = "%s --root %s %s" % (self.config['rpm'], self.rootdir, arg)
+        args_esc = map(lambda x: escapeShell(x), arg)
+        command  = "%s --root %s %s" % (self.config['rpm'], self.rootdir, string.join(args_esc))
         (status, output) = do_with_output (command, progress)
         if status != 0:
-            raise self.Error, "Could not rpm %s" % arg
+            raise self.Error, "Could not rpm %s" % (arg,)
         return output
 
     # main command executer:
@@ -543,13 +546,13 @@
             print "Not removing packages from root."
             return
         root = self.rootdir
-        cmd = 'rpm --root %s -qa --qf %s \
+        cmd = 'rpm --root %s -qa --qf "%s" \
                | diff - %s > /dev/null 2>&1' % (root, qfmt, listfile)
         debug ("running " + cmd)
         if os.system (cmd) == 0:
             # no differences
             return True
-        cmd = "rpm --root %s -qa --qf %s \
+        cmd = "rpm --root %s -qa --qf '%s' \
                | grep -v -f %s - \
                | tr '\n' ' '" % (root, qfmt, listfile)
         packages = commands.getoutput (cmd)
@@ -557,7 +560,7 @@
         if not packages:
            return True
         sys.stdout.write ("Removing packages ...")
-        self.rpm ("-ev %s" % packages, self.progress ())
+        self.rpm (("-ev",) + tuple(string.split(packages)), self.progress ())
         return True
     
 
@@ -661,7 +664,7 @@
         # ready to build them all
         print "Rebuilding generated .src.rpm's: \n- %s" % string.join (srpms, "\n- ")
         self.unlock ()
-        self.rebuild (string.join (options) + " " + string.join (srpms))
+        self.rebuild (options + srpms)
              
     def _bruteclean (self):
         "brutishly clean out the root by using mach-helper rm -rfv"
@@ -675,6 +678,8 @@
     def clean (self, args = ""):
         "clean out the root"
         # does the root still exist ?
+        if type(args)!=type(""):
+            args = string.join(args)
         if not os.path.exists (self.rootdir):
             return
         self.umount ()
@@ -698,6 +703,8 @@
     # chroot into root
     def chroot (self, arg):
         self.mount ()
+        if type(arg)!=type(""):
+            arg = string.join(arg)
         # a minimal system might not have su, yikes
         if not os.path.exists (os.path.join (self.rootdir, 'bin', 'su')):
             if arg:
@@ -717,6 +724,8 @@
      
     def setup (self, arg):
         "Set up the root to a given target"
+        if type(arg)!=type(""):
+            arg = string.join(arg)
         target = ''
         if arg:
             target = arg
@@ -822,12 +831,11 @@
             debug ("Building %s with package stuff %s" % (name, pkgs[name].keys ()))
             if 'buildreqs' in pkgs[name].keys ():
                 buildreqs     = string.join (pkgs[name]['buildreqs'])
-                buildreqs_esc = map(lambda x: escapeShell(x), pkgs[name]['buildreqs'])
                 print "Building %s" % srpmname
                 debug ("BuildRequires: %s" % buildreqs)
                 try:
-        	    self.aptget ("update")
-                    self.aptget ('install -my %s' % string.join(buildreqs_esc),
+        	    self.aptget (("update",))
+                    self.aptget (('install', '-my') + tuple(pkgs[name]['buildreqs']),
                                  "Installing BuildRequires", self.progress ())
                     # FIXME: build-dep would be nice but only works on a pkg
                     # in the rpm-src tree apparently
@@ -919,7 +927,7 @@
             (srpm, rpms) = get_rpms_from_log (resultdir + '/rpm.log')
             # FIXME: install these RPMS based on a boolean ?
             # FIXME: error checks
-            output = self.rpm ('-qp --qf "%%{name}=%%{epoch}:%%{version}-%%{release} " %s' % string.join (['', ] + rpms, " " + self.rootdir))
+            output = self.rpm (("-qp", "--qf", "%%{name}=%%{epoch}:%%{version}-%%{release} ", string.join (['', ] + rpms, " " + self.rootdir)))
             #(status, output) = do_chroot_with_output (config, '%s -qp --qf "%%{name}=%%{epoch}:%%{version}-%%{release} " %s' % (chroot_rpm, string.join (rpms, " ")))
             # FIXME: don't install built packages automatically, they can
             # cause conflicts and break sequence builds
@@ -938,7 +946,7 @@
                 # self.do_chroot ('rm ' + file)
 
             # update internal apt repo
-            self.aptget ("update")
+            self.aptget (("update",))
             print "Build of %s succeeded, results in\n%s" % (fullname, resultdir)
             resultdirs.append (resultdir)
 
@@ -988,6 +996,8 @@
         return
 
     def status (self, args):
+        if type(args)!=type(""):
+            arg = string.join(args)
         if not os.path.exists (get_config_dir (self.config, 'state')):
             print "+ %s is cleared" % self.root
             return
@@ -1129,8 +1139,8 @@
         # create sources.list, run apt-get update
         srcs = get_sources_list (config)
         create_sources_list (config, srcs)
-        self.rpm("--initdb");
-        self.aptget ("update", "Updating apt sources",
+        self.rpm(("--initdb",));
+        self.aptget (("update",), "Updating apt sources",
                      self.progress ())
     
         self._call_setup_hook ("prep")
@@ -1196,12 +1206,12 @@
         create_sources_list (self.config, srcs) 
         for dir in ('RPMS', 'SRPMS'):
             self.do_chroot ('ln -sf %s /usr/src/rpm/%s.mach-local' % (dir, dir), fatal = True)
-        self.aptget ("update")
+        self.aptget (("update",))
         self._call_setup_hook ("build")
 
         self.stdout ("Making snapshot ...\n")
         # FIXME: use _with_output for this
-        output = self.rpm ("-qa --qf %s" % qfmt)
+        output = self.rpm (("-qa", "--qf", qfmt))
         self.set_state ('build', output)
         self.umount ()
     
@@ -1220,10 +1230,10 @@
             # do a two change install if necessary and gloss over errors
             # from first try
             try:
-                self.aptget ('install -y %s' % rpms,
+                self.aptget (('install', '-y') + tuple(string.split(rpms)),
                              "Installing package set '%s'" % set, True)
             except self.Error:
-                self.aptget ('install -y %s' % rpms,
+                self.aptget (('install', '-y') + tuple(string.split(rpms)),
                              "Retrying installing package set '%s'" % set, True)
 
         else:
@@ -1707,7 +1717,7 @@
         print help
         sys.exit (1)
     command = args[0]
-    args = string.join (args[1:])
+    del args[0]
     debug ("main: running %s" % command)
     
     root = Root (config)
