Index: /pykota/trunk/conf/pykota.conf.sample
===================================================================
--- /pykota/trunk/conf/pykota.conf.sample (revision 999)
+++ /pykota/trunk/conf/pykota.conf.sample (revision 1000)
@@ -68,4 +68,9 @@
 #
 #                   accounter: external(/bin/grep -c showpage)
+#
+#                 Another one, which should work with all DSC
+#                 compliant Postscript files :
+#
+#                   accounter: external(/bin/grep -c "%%Page:")
 # 
 #    - stupid : counts the occurences of the 'showpage' postscript
@@ -83,5 +88,6 @@
 # untested/postscript directory to another place.
 # accounter: external(/usr/local/bin/pagecount.sh)
-# WARNING : it may produce broken pipes, I don't know why yet. YMMV.
+# WARNING : it may not work when multiple copies are asked.
+#           this breaks ghostscript, I don't know why yet.
 #
 # default value 
Index: /pykota/trunk/pykota/accounters/stupid.py
===================================================================
--- /pykota/trunk/pykota/accounters/stupid.py (revision 977)
+++ /pykota/trunk/pykota/accounters/stupid.py (revision 1000)
@@ -21,4 +21,8 @@
 #
 # $Log$
+# Revision 1.3  2003/05/27 23:00:21  jalet
+# Big rewrite of external accounting methods.
+# Should work well now.
+#
 # Revision 1.2  2003/04/30 13:40:47  jalet
 # Small fix
@@ -44,5 +48,5 @@
         
         # get the job size    
-        jobsize = self.getJobSize()
+        jobsize = self.getJobSize() * self.filter.copies
             
         # get last job information for this printer
@@ -86,6 +90,5 @@
         pagecount = 0
         for line in infile.xreadlines() :
-            if line.startswith("showpage") :
-                pagecount += 1
+            pagecount += line.count("showpage")
             if temporary is not None :    
                 temporary.write(line)    
Index: /pykota/trunk/pykota/accounters/external.py
===================================================================
--- /pykota/trunk/pykota/accounters/external.py (revision 995)
+++ /pykota/trunk/pykota/accounters/external.py (revision 1000)
@@ -21,4 +21,8 @@
 #
 # $Log$
+# Revision 1.3  2003/05/27 23:00:21  jalet
+# Big rewrite of external accounting methods.
+# Should work well now.
+#
 # Revision 1.2  2003/05/13 13:54:20  jalet
 # Better handling of broken pipes
@@ -42,6 +46,6 @@
            The command must print the job size on its standard output and exit successfully.
         """
-        # get the job size    
-        jobsize = self.getJobSize()
+        # get the job size, which is real job size * number of copies.
+        jobsize = self.getJobSize() * self.filter.copies
             
         # get last job information for this printer
@@ -81,32 +85,45 @@
             
         # launches external accounter
+        infilename = tempfile.mktemp()
+        outfilename = tempfile.mktemp()
+        errfilename = tempfile.mktemp()
+        
         try :
-            process = popen2.Popen3("%s" % self.arguments)
-        
             # feed it with our data
+            fakeinput = open(infilename, "wb")
             data = infile.read(256*1024)    
             while data :
-                process.tochild.write(data)
-                temporary.write(data)
+                fakeinput.write(data)
+                if temporary is not None :
+                    temporary.write(data)
                 data = infile.read(256*1024)
-            process.tochild.close()
+            fakeinput.close()
         
-            # wait for child process to exit (or die)
-            retcode = process.wait()
+            # launches child process
+            command = "%s <%s >%s 2>%s" % (self.arguments, infilename, outfilename, errfilename)
+            o = open("/tmp/comm", "w")
+            o.write("%s\n" % command)
+            o.close()
+            retcode = os.system(command)
             
             # check exit status
-            if os.WIFEXITED(retcode) and not os.WEXITSTATUS(retcode) :
+            if (os.WIFEXITED(retcode) and not os.WEXITSTATUS(retcode)) or os.stat(errfilename) :
                 # tries to extract the job size from the external accounter's
                 # standard output
+                childoutput = open(outfilename, "r")
                 try :
-                    pagecount = int(process.fromchild.readline().strip())
+                    pagecount = int(childoutput.readline().strip())
                 except (AttributeError, ValueError) :
                     self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % self.arguments)
                     pagecount = 0
+                childoutput.close()    
             else :
                 self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % self.arguments)
                 pagecount = 0
-            process.fromchild.close()    
+            os.remove(infilename)
+            os.remove(outfilename)
+            os.remove(errfilename)
         except IOError, msg :    
+            # TODO : temporary files may remain on the filesystem...
             msg = "%s : %s" % (self.arguments, msg) 
             self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % msg)
Index: /pykota/trunk/pykota/config.py
===================================================================
--- /pykota/trunk/pykota/config.py (revision 980)
+++ /pykota/trunk/pykota/config.py (revision 1000)
@@ -21,4 +21,8 @@
 #
 # $Log$
+# Revision 1.27  2003/05/27 23:00:21  jalet
+# Big rewrite of external accounting methods.
+# Should work well now.
+#
 # Revision 1.26  2003/04/30 19:53:58  jalet
 # 1.05
@@ -205,8 +209,8 @@
         validaccounters = [ "querying", "stupid", "external" ]     
         try :
-            fullaccounter = self.getPrinterOption(printer, "accounter").strip().lower()
+            fullaccounter = self.getPrinterOption(printer, "accounter").strip()
         except PyKotaConfigError :    
             fullaccounter = "querying"
-        if fullaccounter.startswith("external") :    
+        if fullaccounter.lower().startswith("external") :    
             try :
                 (accounter, args) = [x.strip() for x in fullaccounter.split('(', 1)]
@@ -217,9 +221,9 @@
             if not args :
                 raise PyKotaConfigError, _("Invalid external accounter %s for printer %s") % (fullaccounter, printer)
-            return (accounter, args)    
-        elif fullaccounter not in validaccounters :
+            return (accounter.lower(), args)    
+        elif fullaccounter.lower() not in validaccounters :
             raise PyKotaConfigError, _("Option accounter in section %s only supports values in %s") % (printer, str(validaccounters))
         else :    
-            return (fullaccounter, None)
+            return (fullaccounter.lower(), None)
         
     def getRequesterBackend(self, printer) :    
@@ -242,4 +246,5 @@
                 raise PyKotaConfigError, _("Invalid requester %s for printer %s") % (fullrequester, printer)
             validrequesters = [ "snmp", "external" ] # TODO : add more requesters
+            requester = requester.lower()
             if requester not in validrequesters :
                 raise PyKotaConfigError, _("Option requester for printer %s only supports values in %s") % (printer, str(validrequesters))
Index: /pykota/trunk/pykota/version.py
===================================================================
--- /pykota/trunk/pykota/version.py (revision 998)
+++ /pykota/trunk/pykota/version.py (revision 1000)
@@ -21,5 +21,5 @@
 #
 
-__version__ = "1.08alpha2_unofficial"
+__version__ = "1.08alpha3_unofficial"
 
 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""
Index: /pykota/trunk/bin/pykota
===================================================================
--- /pykota/trunk/bin/pykota (revision 976)
+++ /pykota/trunk/bin/pykota (revision 1000)
@@ -23,4 +23,8 @@
 #
 # $Log$
+# Revision 1.32  2003/05/27 23:00:20  jalet
+# Big rewrite of external accounting methods.
+# Should work well now.
+#
 # Revision 1.31  2003/04/30 13:36:39  jalet
 # Stupid accounting method was added.
@@ -150,5 +154,5 @@
     def __init__(self) :
         PyKotaTool.__init__(self)
-        (self.printingsystem, self.printerhostname, self.printername, self.username, self.jobid, self.inputfile) = self.extractInfoFromCupsOrLprng()
+        (self.printingsystem, self.printerhostname, self.printername, self.username, self.jobid, self.inputfile, self.copies) = self.extractInfoFromCupsOrLprng()
         self.accounter = openAccounter(self)
     
@@ -174,8 +178,8 @@
                 destination = destination[1:]
             printerhostname = destination.split("/")[0].split(":")[0]
-            return ("CUPS", printerhostname, os.environ.get("PRINTER"), sys.argv[2].strip(), sys.argv[1].strip(), inputfile)
+            return ("CUPS", printerhostname, os.environ.get("PRINTER"), sys.argv[2].strip(), sys.argv[1].strip(), inputfile, int(sys.argv[4].strip()))
         else :    
             # Try to detect LPRng
-            jseen = Jseen = Pseen = nseen = rseen = None
+            jseen = Jseen = Pseen = nseen = rseen = Kseen = None
             for arg in sys.argv :
                 if arg.startswith("-j") :
@@ -191,7 +195,11 @@
                 elif arg.startswith("-r") :    
                     rseen = arg[2:].strip()
+                elif arg.startswith("-K") or arg.startswith("-#") :    
+                    Kseen = int(arg[2:].strip())
+            if Kseen is None :        
+                Kseen = 1       # we assume the user wants at least one copy...
             if jseen and Pseen and nseen and rseen :        
-                return ("LPRNG", rseen, Pseen, nseen, jseen, Jseen)
-        return (None, None, None, None, None, None)   # Unknown printing system          
+                return ("LPRNG", rseen, Pseen, nseen, jseen, Jseen, Kseen)
+        return (None, None, None, None, None, None, None)   # Unknown printing system          
         
     def acceptJob(self) :        
Index: /pykota/trunk/NEWS
===================================================================
--- /pykota/trunk/NEWS (revision 998)
+++ /pykota/trunk/NEWS (revision 1000)
@@ -22,9 +22,27 @@
 PyKota NEWS :
 
+    - 1.08alpha3 :
+    
+        - External accounting methods were partly rewritten :
+         
+          - No more "broken pipe" should happen.
+          
+          - They now take care of the number of copies
+            This may be unneeded though, if the postscript
+            file already does this, because this would
+            overcharge users (number of copies counted
+            two times). NEEDS MORE TESTING.
+            
+          - The sample configuration file now contains  
+            an external accounting method example which should
+            work with all DSC compliant Postscript files.
+            
+        - Some small bugs were fixed.    
+        
     - 1.08alpha2 :
     
         - Now works with net-snmp v5.0 and above.
           It already worked, but the sample configuration 
-	  file didn't contain appropriate values...
+          file didn't contain appropriate values...
         
     - 1.07 : Release of the Shame !
