casprint lib/cas PKG-INFO version
by Adam Stokes
PKG-INFO | 6 +++---
casprint | 4 ++--
lib/cas/rpmutils.py | 2 ++
lib/cas/utilities.py | 20 +-------------------
version | 2 +-
5 files changed, 9 insertions(+), 25 deletions(-)
New commits:
commit 7707997f97bdf038a733933dacf5cdcca4d5efee
Author: Adam Stokes <ajs(a)redhat.com>
Date: Tue Oct 14 18:51:06 2008 -0400
casprint properly extracts and timestamps any ELF type debug kernel provided.
diff --git a/PKG-INFO b/PKG-INFO
index 061ea88..2e55bb2 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -2,9 +2,9 @@ Metadata-Version: 1.0
Name: cas
Version: 0.13
Summary: CAS - automated core setup
-Home-page: http://megatron.gsslab.rdu.redhat.com:8080
+Home-page: http://fedorahosted.org/cas
Author: Adam Stokes
-Author-email: ajs(a)redhat.com
+Author-email: astokes(a)fedoraproject.org
License: GPLv2
-Description: UNKNOWN
+Description: Core analysis system.
Platform: Linux
diff --git a/casprint b/casprint
index c08f2b8..e8656da 100755
--- a/casprint
+++ b/casprint
@@ -24,7 +24,6 @@ DPRINT = config.get("settings","dprint")
class CasTimeStampHandler(object):
def __init__(self):
- self.dst = dst
self.cmd = ["find", "-L", DEBUGS, "-iname", "vmlinux"]
self.tool = CoreTool()
self.util = Utilities()
@@ -60,8 +59,9 @@ class CasDatabaseHandler(object):
count = 0
for x in rpms:
count = count + 1
+ dst = os.path.join(DEBUGS, str(count))
rpmTool = Tools()
- rpmTool.extract(x, DEBUGS)
+ rpmTool.extract(x, dst)
sprint("(extracted) [%d/%d] %-100s" % (count, totalRpms, os.path.basename(x)))
return
diff --git a/lib/cas/rpmutils.py b/lib/cas/rpmutils.py
index ac8738b..23b024b 100644
--- a/lib/cas/rpmutils.py
+++ b/lib/cas/rpmutils.py
@@ -55,6 +55,8 @@ class Tools(object):
self.cpio_args = "-imud"
# change to destination directory
+ if not os.path.isdir(self.dst):
+ os.makedirs(self.dst)
os.chdir(self.dst)
# pipe to handle extraction, e.g. rpm2cpio kernel.rpm | cpio -imud */vmlinux
diff --git a/lib/cas/utilities.py b/lib/cas/utilities.py
index 2e1e953..9b40d59 100644
--- a/lib/cas/utilities.py
+++ b/lib/cas/utilities.py
@@ -97,24 +97,6 @@ class Utilities(object):
raise UtilitiesException("%s : Unable to locate/load file." % (fname,))
return out
- def moveFiles(self, regex, start, end):
- """ Function to move files into working directory
- """
- reg=re.compile(regex, re.MULTILINE)
- dirList=self.dirList(start)
- for v in dirList:
- for b in reg.findall("%s" % (v)):
- shutil.move(b,end)
- return
-
- def setPerms(self, path):
- """ Set permissions on path
- """
- self.path = path
- self._exec(['/bin/chgrp support -R %s' % (self.path,)])
- self._exec(['setfacl -R -m o:rwx %s' % (self.path,)])
- return
-
def sighandler(a, b):
sys.exit()
@@ -174,7 +156,7 @@ class Utilities(object):
supportArch = {"IBM S/390":"s390",
"Intel 80386":"x86",
"Advanced Micro Devices X86-64" : "x86_64",
- "Intel IA-64": "ia64"}
+ "Intel IA-64": "ia64",
"PowerPC64": "ppc64"}
cmd = ["readelf", "-h", debug]
diff --git a/version b/version
index 54dfa8a..6b6bf85 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-0.13 60
+0.13 61
15 years, 7 months
lib/cas
by Adam Stokes
lib/cas/utilities.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
New commits:
commit 67fc6c710091b8f26cf93265a19df54c1fc091c0
Author: Adam Stokes <ajs(a)redhat.com>
Date: Fri Oct 10 12:46:33 2008 -0400
return definitive machine type for debug kernels.
This should allow us to separate out debugs into architecture specific directories and keep track of the usage of each arch.
diff --git a/lib/cas/utilities.py b/lib/cas/utilities.py
index 9a83d5c..2e1e953 100644
--- a/lib/cas/utilities.py
+++ b/lib/cas/utilities.py
@@ -168,6 +168,25 @@ class Utilities(object):
return(0)
+ def arch(self, debug):
+ """ determine machine type for debug kernel
+ """
+ supportArch = {"IBM S/390":"s390",
+ "Intel 80386":"x86",
+ "Advanced Micro Devices X86-64" : "x86_64",
+ "Intel IA-64": "ia64"}
+ "PowerPC64": "ppc64"}
+
+ cmd = ["readelf", "-h", debug]
+ cmd2 = ["grep", "Machine"]
+ pipe = Popen(cmd, stdout=PIPE, stderr=PIPE)
+ pipe2 = Popen(cmd2, stdin=pipe.stdout, stdout=PIPE, stderr=PIPE).communicate()
+ machine, sts = pipe2
+ for k, v in supportArch.iteritems():
+ if k in machine:
+ return supportArch[k]
+ return False
+
class CoreException(Exception):
pass
15 years, 7 months
cas casprint lib/cas version
by Adam Stokes
cas | 53 +++++++++++++------------------
casprint | 86 +++++++++++++++++++++++++++++----------------------
lib/cas/utilities.py | 36 ++++++++++++++-------
version | 2 -
4 files changed, 99 insertions(+), 78 deletions(-)
New commits:
commit 036899f032bbe838fa08c4d0040dd231e9b732a6
Author: Adam Stokes <ajs(a)redhat.com>
Date: Wed Oct 8 21:17:32 2008 -0400
split workflow on casprint to handle both building new cas db and updating existing debug kernels.
One major problem exists in that the kernel debugs overwrite themselves since the extraction doesn't distinguish between architectures. So that needs to be addressed, I'm thinking we should determine this architecture through the file command and seperate the extraction based on that.
diff --git a/cas b/cas
index d0b8468..099ea6e 100755
--- a/cas
+++ b/cas
@@ -1,16 +1,13 @@
#!/usr/bin/python
-
""" cas - core accessibility system.
"""
-
import sys
import optparse
import os
import ConfigParser
-import logging
import shutil
-from cas.utilities import Utilities, CoreTool, dprint
+from cas.utilities import Utilities, CoreTool, dprint, sprint
if sys.version_info[:2] < (2,4):
raise SystemExit("Python >= 2.4 required")
@@ -22,13 +19,6 @@ RPMS = config.get("settings","rpms")
JOBS = config.get("settings","jobs")
DPRINT = config.get("settings","dprint")
-logging.basicConfig(level=logging.DEBUG,
- format='%(asctime)s %(levelname)-8s %(message)s',
- filename='/var/log/cas.log',
- filemode='a')
-
-class CasException(Exception): pass
-
class CoreHandler(object):
def __init__(self, filename, dst):
self.filename = filename
@@ -37,7 +27,8 @@ class CoreHandler(object):
def run(self):
if not os.path.isfile(self.filename):
- raise CasException("Unable to find file specified by -f FILENAME.")
+ dprint("Unable to find file specified by -f FILENAME.", DPRINT)
+ sys.exit(1)
if self.tool.isCorefile(self.filename):
shutil.move(self.filename,
os.path.join(self.dst,self.filename))
@@ -55,15 +46,17 @@ class TimestampHandler(object):
self.tool = CoreTool()
def run(self):
- if os.path.isfile(self.db):
- rpmsDict = self.util.load(self.db)
- timestamp = self.tool.timestamp(self.corefile)
- if timestamp:
- for k,v in rpmsDict.iteritems():
- if rpmsDict[k].timestamp and timestamp in rpmsDict[k].timestamp:
- return rpmsDict[k]
+ debugList = self.util.load(self.db)
+ coreTimestamp = self.tool.timestamp(self.corefile)
+ if coreTimestamp:
+ dprint(coreTimestamp, DPRINT)
+ for item in debugList:
+ debug, timestamp = item
+ if coreTimestamp and coreTimestamp in timestamp:
+ return debug
else:
- raise CasException("No database found.")
+ dprint("Unable to match fingerprint : %s" % (coreTimestamp,), DPRINT)
+ sys.exit(1)
return False
class CasApplication(object):
@@ -81,9 +74,9 @@ class CasApplication(object):
self.opts, args = parser.parse_args()
if not self.opts.identifier:
- parser.error("Identifier number missing")
+ parser.error("A unique identifier number is missing.")
elif not self.opts.filename:
- parser.error("Corefile missing")
+ parser.error("A file object is missing.")
self.filename = self.opts.filename
self.identifier = self.opts.identifier
@@ -95,18 +88,18 @@ class CasApplication(object):
os.makedirs(self.storagePath)
corefile = CoreHandler(self.filename, self.storagePath).run()
if not corefile:
- raise CasException("Unable to determine a corefile.")
- rpmObj = TimestampHandler(corefile, RPMS).run()
- if not rpmObj:
- raise CasException("Unable to determine fingerprint.")
+ dprint("Unable to determine corefile : %s" % (corefile,), DPRINT)
+ sys.exit(1)
+ debug = TimestampHandler(corefile, RPMS).run()
try:
symlink_dst = os.path.join(self.storagePath,
- os.path.basename(rpmObj.sanitizeFilename))
- os.symlink(rpmObj.sanitizeFilename,symlink_dst)
+ os.path.basename(debug))
+ os.symlink(debug,symlink_dst)
except:
- raise CasException("Unable to perform symlink %s" % (os.path.basename(rpmObj.sanitizeFilename)))
+ dprint("Unable to perform symlink %s" % (os.path.basename(debug)), DPRINT)
+ sys.exit(1)
- crash_cmd = "crash %s %s" % (symlink_dst, corefile)
+ crash_cmd = "/bin/sh\ncrash %s %s" % (symlink_dst, corefile)
crash_exe = os.path.join(self.storagePath,"crash")
fh = open(crash_exe,"w")
fh.write(crash_cmd)
diff --git a/casprint b/casprint
index 02b81d6..c08f2b8 100755
--- a/casprint
+++ b/casprint
@@ -1,22 +1,19 @@
#!/usr/bin/python
-
""" casprint - fingerprinting utility for cas
"""
-
import os
-import re
-import threading
import ConfigParser
-import logging
+import optparse
import sys
-from time import sleep
-from stat import ST_SIZE
from cas.db import Core
from cas.utilities import Utilities, CoreTool, dprint, sprint
from cas.rpmutils import Analyze, Tools
from subprocess import Popen, PIPE
+if sys.version_info[:2] < (2,4):
+ raise SystemExit("Python >= 2.4 required")
+
# Read in configuration
config = ConfigParser.ConfigParser()
config.read("/etc/cas.conf")
@@ -25,27 +22,37 @@ RPMS = config.get("settings","rpms")
DEBUGS = config.get("settings","debugs")
DPRINT = config.get("settings","dprint")
-# setup logging
-logging.basicConfig(level=logging.DEBUG,
- format='%(asctime)s %(levelname)-8s %(message)s',
- filename='/var/log/casprint.log',
- filemode='a')
+class CasTimeStampHandler(object):
+ def __init__(self):
+ self.dst = dst
+ self.cmd = ["find", "-L", DEBUGS, "-iname", "vmlinux"]
+ self.tool = CoreTool()
+ self.util = Utilities()
+ self.debugList = []
+ def run(self):
+ pipe = Popen(self.cmd, stdout=PIPE, stderr=PIPE)
+ for line in pipe.stdout:
+ vmlinux = line.strip()
+ tstamp = CoreTool()
+ timestamp = tstamp.timestamp(vmlinux)
+ self.debugList.append((vmlinux,timestamp))
+ sprint("(timestamp) %-100s" % (os.path.realpath(vmlinux),))
+ self.util.save(self.debugList, RPMS)
+ return
+
class CasDatabaseHandler(object):
def __init__(self):
- util = Utilities()
+ self.util = Utilities()
if os.path.isfile(RPMS):
- self.rpmsList = util.load(RPMS)
+ self.debugList = self.util.load(RPMS)
else:
- self.rpmsList = []
-
- self.util = Utilities()
+ self.debugList = []
def run(self):
rpms = []
- cmd = "find" + " -L %s -iname kernel-debuginfo*rpm" % (KERNELS,)
- dprint("running cmd : %s" % (cmd,), DPRINT)
- pipe = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
+ cmd = ["find", "-L", KERNELS, "-iname", "kernel-debuginfo*rpm"]
+ pipe = Popen(cmd, stdout=PIPE, stderr=PIPE)
for line in pipe.stdout:
rpms.append(line.strip())
sprint("(found) %-100s" % (os.path.basename(line.strip()),))
@@ -56,20 +63,19 @@ class CasDatabaseHandler(object):
rpmTool = Tools()
rpmTool.extract(x, DEBUGS)
sprint("(extracted) [%d/%d] %-100s" % (count, totalRpms, os.path.basename(x)))
- cmd = "find" + " -L %s -iname vmlinux" % (DEBUGS,)
- pipe = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
- for line in pipe.stdout:
- vmlinux = line.strip()
- tstamp = CoreTool()
- timestamp = tstamp.timestamp(vmlinux)
- self.rpmsList.append((vmlinux,timestamp))
- sprint("(timestamp) %s : %s" % (os.path.basename(vmlinux), timestamp))
- util.save(rpmsList, RPMS)
return
class CasprintApplication(object):
- def __init__(self):
- pass
+ def __init__(self, args):
+ self.parse_options(args)
+
+ def parse_options(self, args):
+ parser = optparse.OptionParser(usage="casprint -n -t")
+ parser.add_option("-n","--new", dest="newCasDB",
+ help="Build new CAS database", action="store_true")
+ parser.add_option("-t","--timestamp", dest="timestamp",
+ help="Timestamp existing debug kernels", action="store_true")
+ self.opts, args = parser.parse_args()
def run(self):
""" Make sure necessary directories and configuration is setup
@@ -77,15 +83,23 @@ class CasprintApplication(object):
"""
util = Utilities()
if os.getuid() is not 0:
- raise RuntimeError, "You must be root(0), instead you are id(%d)" \
- % (os.getuid())
+ raise RuntimeError, "You must be root(0), instead you are id(%d)" % (os.getuid())
if not os.path.isdir(os.path.dirname(RPMS)):
util.mkdir(RPMS)
if not os.path.isdir(DEBUGS):
util.mkdir(DEBUGS)
- dbHandler = CasDatabaseHandler().run()
- logging.info("Database index complete.")
+ if self.opts.newCasDB:
+ dprint("Running a new cas database instance.", DPRINT)
+ dbHandler = CasDatabaseHandler().run()
+ elif self.opts.timestamp:
+ dprint("Building an updated cache of timestamps on existing debugs.", DPRINT)
+ timestampHandler = CasTimeStampHandler().run()
+ else:
+ raise RuntimeError("You must define either -n for a new CAS database or \n"
+ "-t to update existing debugs")
if __name__=="__main__":
- sys.exit(CasprintApplication().run())
+ app = CasprintApplication(sys.argv[1:])
+ sys.exit(app.run())
+
diff --git a/lib/cas/utilities.py b/lib/cas/utilities.py
index ef6a051..9a83d5c 100644
--- a/lib/cas/utilities.py
+++ b/lib/cas/utilities.py
@@ -7,12 +7,20 @@ import re
import sys
import shutil
import tarfile
+import logging
from subprocess import Popen, PIPE
+# setup logging
+logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)s %(levelname)-8s %(message)s',
+ filename='/var/log/cas.log',
+ filemode='a')
+
def dprint(msg, debug=True):
if debug:
- print "(debug) %s" % (msg,)
+ sys.stderr.write("(debug) %s" % (msg,))
+ logging.error(msg)
def sprint(msg):
""" function to print status messages
@@ -81,9 +89,12 @@ class Utilities(object):
def load(self, fname):
''' grab data from pickle file
'''
- FILE=open(fname, 'r')
- out=cPickle.load(FILE)
- FILE.close()
+ if os.path.isfile(fname):
+ FILE=open(fname, 'r')
+ out=cPickle.load(FILE)
+ FILE.close()
+ else:
+ raise UtilitiesException("%s : Unable to locate/load file." % (fname,))
return out
def moveFiles(self, regex, start, end):
@@ -157,6 +168,9 @@ class Utilities(object):
return(0)
+class CoreException(Exception):
+ pass
+
class CoreTool(object):
def __init__(self):
self.util = Utilities()
@@ -167,7 +181,7 @@ class CoreTool(object):
self.dst = dst
self.filepath = filepath
if not tarfile.is_tarfile(self.filepath):
- return False
+ raise CoreException("%s : is not a properly compressed tarfile." % (self.filepath,))
else:
tar = tarfile.open(self.filepath, "r")
tar.extractall(self.dst)
@@ -175,11 +189,11 @@ class CoreTool(object):
for file in files:
if self.isCorefile(file):
return os.path.join(root,file)
- return False
+ raise CoreException("Can not determine a corefile from tarball : %s" % (self.filepath,))
def isCorefile(self, corefile):
- cmd = "file -i %s" % (corefile,)
- p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
+ cmd = ["file","-i",corefile]
+ p = Popen(cmd, stdout=PIPE, stderr=PIPE)
txt = p.stdout.read()
items = ['application/x-coredump',
'application/octet-stream',
@@ -195,11 +209,11 @@ class CoreTool(object):
match='Linux\sversion.*\d{1,4}|#1\s.*\d{1,2}'
try:
fd=open('%s' % (path))
- except IOError: return False
+ except IOError:
+ return False
fd.seek(0)
b = os.read(fd.fileno(),54000000)
out = self.util.regexSearch(match, b)
if out:
return out
- return False
-
+ raise CoreException("Unable to retrieve timestamp from: %s" % (path,))
diff --git a/version b/version
index a5a0abb..54dfa8a 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-0.13 58
+0.13 60
15 years, 7 months
casprint lib/cas version
by Adam Stokes
casprint | 32 ++++++++++++++++++--------------
lib/cas/rpmutils.py | 2 +-
lib/cas/utilities.py | 6 ++++++
version | 2 +-
4 files changed, 26 insertions(+), 16 deletions(-)
New commits:
commit 598f6db98c4067b089e05e8b5d72ffdf06a63674
Author: Adam Stokes <ajs(a)redhat.com>
Date: Wed Oct 8 13:26:32 2008 -0400
final stage of casprint
- fd leak completely gone
- status messages complete
- extraction method stable
- timestamp method stable
diff --git a/casprint b/casprint
index e261caa..02b81d6 100755
--- a/casprint
+++ b/casprint
@@ -13,7 +13,7 @@ import sys
from time import sleep
from stat import ST_SIZE
from cas.db import Core
-from cas.utilities import Utilities, CoreTool, dprint
+from cas.utilities import Utilities, CoreTool, dprint, sprint
from cas.rpmutils import Analyze, Tools
from subprocess import Popen, PIPE
@@ -35,32 +35,36 @@ class CasDatabaseHandler(object):
def __init__(self):
util = Utilities()
if os.path.isfile(RPMS):
- self.rpmsDict = util.load(RPMS)
+ self.rpmsList = util.load(RPMS)
else:
- self.rpmsDict = {}
+ self.rpmsList = []
self.util = Utilities()
def run(self):
rpms = []
cmd = "find" + " -L %s -iname kernel-debuginfo*rpm" % (KERNELS,)
+ dprint("running cmd : %s" % (cmd,), DPRINT)
pipe = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
for line in pipe.stdout:
rpms.append(line.strip())
+ sprint("(found) %-100s" % (os.path.basename(line.strip()),))
+ totalRpms = len(rpms)
+ count = 0
for x in rpms:
- rpmObj = Core()
+ count = count + 1
rpmTool = Tools()
- dprint("extracting %s" % (x,), DPRINT)
rpmTool.extract(x, DEBUGS)
- return
- if os.path.isfile(RPMS):
- for k,v in self.rpmsDict.iteritems():
- tstamp = CoreTool()
- timestamp = tstamp.timestamp(rpmsDict[k].sanitizeFilename)
- rpmsDict[k].timestamp = timestamp
- util.save(rpmsDict, RPMS)
- else:
- raise RuntimeError("Unable to process rpms, please re-run fingerprinter.")
+ sprint("(extracted) [%d/%d] %-100s" % (count, totalRpms, os.path.basename(x)))
+ cmd = "find" + " -L %s -iname vmlinux" % (DEBUGS,)
+ pipe = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
+ for line in pipe.stdout:
+ vmlinux = line.strip()
+ tstamp = CoreTool()
+ timestamp = tstamp.timestamp(vmlinux)
+ self.rpmsList.append((vmlinux,timestamp))
+ sprint("(timestamp) %s : %s" % (os.path.basename(vmlinux), timestamp))
+ util.save(rpmsList, RPMS)
return
class CasprintApplication(object):
diff --git a/lib/cas/rpmutils.py b/lib/cas/rpmutils.py
index ba0a616..ac8738b 100644
--- a/lib/cas/rpmutils.py
+++ b/lib/cas/rpmutils.py
@@ -8,7 +8,7 @@ import logging
import md5
import time
-from subprocess import Popen, PIPE, call
+from subprocess import Popen, PIPE
class RPMException(Exception): pass
diff --git a/lib/cas/utilities.py b/lib/cas/utilities.py
index abc4178..ef6a051 100644
--- a/lib/cas/utilities.py
+++ b/lib/cas/utilities.py
@@ -14,6 +14,12 @@ def dprint(msg, debug=True):
if debug:
print "(debug) %s" % (msg,)
+def sprint(msg):
+ """ function to print status messages
+ """
+ sys.stdout.write(msg + "\r")
+ sys.stdout.flush()
+
class UtilitiesException(Exception): pass
class Utilities(object):
diff --git a/version b/version
index 23fbe17..a5a0abb 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-0.13 57
+0.13 58
15 years, 7 months
casprint lib/cas version
by Adam Stokes
casprint | 5 +++--
lib/cas/rpmutils.py | 3 ---
version | 2 +-
3 files changed, 4 insertions(+), 6 deletions(-)
New commits:
commit c30cacedae4dbcc9f982f4b21a509369536e0e09
Author: Adam Stokes <ajs(a)redhat.com>
Date: Wed Oct 8 06:43:07 2008 -0400
all extraction is done which includes all necessary arch's and extensions
suprisingly when using a filter such as */vmlinux with cpio no fd leak exist but when using the filepath directly it can cause the process to hang.
diff --git a/casprint b/casprint
index fca3704..e261caa 100755
--- a/casprint
+++ b/casprint
@@ -33,6 +33,7 @@ logging.basicConfig(level=logging.DEBUG,
class CasDatabaseHandler(object):
def __init__(self):
+ util = Utilities()
if os.path.isfile(RPMS):
self.rpmsDict = util.load(RPMS)
else:
@@ -40,7 +41,7 @@ class CasDatabaseHandler(object):
self.util = Utilities()
- def run():
+ def run(self):
rpms = []
cmd = "find" + " -L %s -iname kernel-debuginfo*rpm" % (KERNELS,)
pipe = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
@@ -49,8 +50,8 @@ class CasDatabaseHandler(object):
for x in rpms:
rpmObj = Core()
rpmTool = Tools()
+ dprint("extracting %s" % (x,), DPRINT)
rpmTool.extract(x, DEBUGS)
- dprint("Completed extracting debug kernels.", DPRINT)
return
if os.path.isfile(RPMS):
for k,v in self.rpmsDict.iteritems():
diff --git a/lib/cas/rpmutils.py b/lib/cas/rpmutils.py
index 476ab68..ba0a616 100644
--- a/lib/cas/rpmutils.py
+++ b/lib/cas/rpmutils.py
@@ -61,8 +61,5 @@ class Tools(object):
p1 = Popen([self.rpm2cpio, self.rpm], stdout=PIPE)
(out, err) = Popen([self.cpio,self.cpio_args,self.filter], stdin=p1.stdout,
stdout=open(os.devnull, "w"),stderr=open(os.devnull,"w")).communicate()
- os.close(p1.stdout.fileno())
- if p1.stderr:
- os.close(p1.stderr.fileno())
return
diff --git a/version b/version
index 7b28dff..23fbe17 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-0.13 56
+0.13 57
15 years, 8 months
Looking for a logo
by Adam Stokes
If anyone with some artistic skills wants to create a CAS logo I would
appreciate it :D
--
( adam stokes ) || ( adam.stokes(a)gmail.com )
15 years, 8 months