From 429b651f636b9ca9edae8761242c40d65bd40b25 Mon Sep 17 00:00:00 2001 From: Robert Rati <rrati@redhat.com> Date: Fri, 11 Mar 2011 12:02:57 -0600 Subject: [PATCH 01/13] Correctly parse windows commandline in run_cmd --- module/osutil.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 51 insertions(+), 1 deletions(-) diff --git a/module/osutil.py b/module/osutil.py index ba68214..549394b 100644 --- a/module/osutil.py +++ b/module/osutil.py @@ -59,7 +59,10 @@ def run_cmd(cmd, environ={}, inter=False): std_err = None elif use_popen2 == False: try: - cmd_list = shlex.split(cmd) + if os.name == 'nt' or os.name == 'ce': + cmd_list = _cmdline2list(cmd) + else: + cmd_list = shlex.split(cmd) obj = Popen(cmd_list, stdout=PIPE, stderr=PIPE, env=env) (std_out, std_err) = obj.communicate() retcode = obj.returncode @@ -181,3 +184,50 @@ def tarball_extract(filename): for file in tarball.getnames(): tarball.extract(file) tarball.close() + + +def _cmdline2list(cmdline): + """Build an argv list from a Microsoft shell style cmdline str + following the MS C runtime rules.""" + + whitespace = ' \t' + # count of preceding '\' + bs_count = 0 + in_quotes = False + arg = [] + argv = [] + + for ch in cmdline: + if ch in whitespace and not in_quotes: + if arg: + # finalize arg and reset + argv.append(''.join(arg)) + arg = [] + bs_count = 0 + elif ch == '\\': + arg.append(ch) + bs_count += 1 + elif ch == '"': + if not bs_count % 2: + # Even number of '\' followed by a '"'. Place one + # '\' for every pair and treat '"' as a delimiter + if bs_count: + del arg[-(bs_count / 2):] + in_quotes = not in_quotes + else: + # Odd number of '\' followed by a '"'. Place one '\' + # for every pair and treat '"' as an escape sequence + # by the remaining '\' + del arg[-(bs_count / 2 + 1):] + arg.append(ch) + bs_count = 0 + else: + # regular char + arg.append(ch) + bs_count = 0 + + # A single trailing '"' delimiter yields an empty arg + if arg or in_quotes: + argv.append(''.join(arg)) + + return argv -- 1.7.6.5