Index: /pykota/trunk/pykota/tool.py
===================================================================
--- /pykota/trunk/pykota/tool.py (revision 1483)
+++ /pykota/trunk/pykota/tool.py (revision 1492)
@@ -22,4 +22,7 @@
 #
 # $Log$
+# Revision 1.89  2004/05/21 22:02:52  jalet
+# Preliminary work on pre-accounting
+#
 # Revision 1.88  2004/05/18 14:49:20  jalet
 # Big code changes to completely remove the need for "requester" directives,
@@ -341,8 +344,9 @@
 import signal
 import socket
+import tempfile
 
 from mx import DateTime
 
-from pykota import version, config, storage, logger, accounter
+from pykota import version, config, storage, logger, accounter, pdlanalyzer
 
 class PyKotaToolError(Exception):
@@ -757,4 +761,10 @@
     def __init__(self) :
         """Initialize local datas from current environment."""
+        # We begin with ignoring signals, we may de-ignore them later on.
+        self.gotSigTerm = 0
+        signal.signal(signal.SIGTERM, signal.SIG_IGN)
+        signal.signal(signal.SIGCHLD, signal.SIG_IGN)
+        signal.signal(signal.SIGPIPE, signal.SIG_IGN)
+        
         PyKotaTool.__init__(self)
         (self.printingsystem, \
@@ -774,15 +784,51 @@
         self.accounter = accounter.openAccounter(self)
         self.exportJobInfo()
-        
-        # then deal with signals
-        # CUPS backends always ignore SIGPIPE and ignore SIGTERM
-        # when printing from their stdin
-        # Here we have to catch them correctly, and pass
-        # SIGTERM to any child if needed.
-        self.gotSigTerm = self.gotSigChld = self.gotSigPipe = 0
-        signal.signal(signal.SIGTERM, self.sigterm_handler)
-        signal.signal(signal.SIGCHLD, self.sigchld_handler)
-        signal.signal(signal.SIGPIPE, self.sigpipe_handler)
-        
+        self.jobdatastream = self.openJobDataStream()
+        self.softwareJobSize = self.precomputeJobSize()
+        self.logdebug("Precomputed job's size is : %s pages" % self.softwareJobSize)
+        
+    def openJobDataStream(self) :    
+        """Opens the file which contains the job's datas."""
+        if self.preserveinputfile is None :
+            # Job comes from sys.stdin, but this is not
+            # seekable and complexifies our task, so create
+            # a temporary file and use it instead
+            self.logdebug("Duplicating data stream from stdin to temporary file")
+            MEGABYTE = 1024*1024
+            infile = tempfile.TemporaryFile()
+            while 1 :
+                data = sys.stdin.read(MEGABYTE) 
+                if not data :
+                    break
+                infile.write(data)
+            infile.flush()    
+            infile.seek(0)
+            return infile
+        else :    
+            # real file, just open it
+            self.logdebug("Opening data stream %s" % self.preserveinputfile)
+            return open(self.preserveinputfile, "rb")
+        
+    def closeJobDataStream(self) :    
+        """Closes the file which contains the job's datas."""
+        self.logdebug("Closing data stream.")
+        try :
+            self.jobdatastream.close()
+        except :    
+            pass
+        
+    def precomputeJobSize(self) :    
+        """Computes the job size with a software method."""
+        try :
+            parser = pdlanalyzer.PDLAnalyzer(self.jobdatastream)
+            return parser.getJobSize()
+        except pdlanalyzer.PDLAnalyzerError, msg :    
+            # Here we just log the failure, but
+            # we finally ignore it and return 0 since this
+            # computation is just an indication of what the
+            # job's size MAY be.
+            self.logger.log_message(_("Unable to precompute the job's size with the generic PDL analyzer."), "warn")
+            return 0
+            
     def sigterm_handler(self, signum, frame) :
         """Sets an attribute whenever SIGTERM is received."""
@@ -790,14 +836,4 @@
         os.putenv("PYKOTASTATUS", "CANCELLED")
         self.logger.log_message(_("SIGTERM received, job %s cancelled.") % self.jobid, "info")
-        
-    def sigchld_handler(self, signum, frame) :
-        """Sets an attribute whenever SIGCHLD is received."""
-        self.gotSigChld = 1
-        self.logdebug("SIGCHLD received")
-        
-    def sigpipe_handler(self, signum, frame) :
-        """Sets an attribute whenever SIGPIPE is received."""
-        self.gotSigPipe = 1
-        self.logdebug("SIGPIPE received")
         
     def exportJobInfo(self) :    
Index: /pykota/trunk/pykota/version.py
===================================================================
--- /pykota/trunk/pykota/version.py (revision 1490)
+++ /pykota/trunk/pykota/version.py (revision 1492)
@@ -22,5 +22,5 @@
 #
 
-__version__ = "1.19alpha11_unofficial"
+__version__ = "1.19alpha12_unofficial"
 
 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""
Index: /pykota/trunk/bin/cupspykota
===================================================================
--- /pykota/trunk/bin/cupspykota (revision 1484)
+++ /pykota/trunk/bin/cupspykota (revision 1492)
@@ -24,4 +24,7 @@
 #
 # $Log$
+# Revision 1.46  2004/05/21 22:02:51  jalet
+# Preliminary work on pre-accounting
+#
 # Revision 1.45  2004/05/19 07:15:32  jalet
 # Could the 'misterious' bug in my loop be finally fixed ???
@@ -381,4 +384,6 @@
         killed = 0
         status = -1
+        self.logdebug("Catching SIGTERM.")
+        signal.signal(signal.SIGTERM, self.sigterm_handler)
         self.logdebug("Entering streams polling loop...")
         while status == -1 :
@@ -459,4 +464,8 @@
                 
         self.logdebug("Exiting streams polling loop...")
+        
+        self.logdebug("Ignoring SIGTERM again.")
+        signal.signal(signal.SIGTERM, signal.SIG_IGN)
+        
         status = subprocess.wait()      # just in case
         if os.WIFEXITED(status) :
@@ -528,4 +537,6 @@
         except (TypeError, NameError, AttributeError) :    
             pass
+            
+        kotabackend.closeJobDataStream()    
         
     sys.exit(retcode)    
Index: /pykota/trunk/NEWS
===================================================================
--- /pykota/trunk/NEWS (revision 1490)
+++ /pykota/trunk/NEWS (revision 1492)
@@ -22,4 +22,11 @@
 PyKota NEWS :
 
+    - 1.19alpha12 :
+    
+        - Job's size is now precomputed unconditionnally using 
+          the generic PDL analyzer.
+          NB : This value is not yet used to pre-allow/deny the
+          job.
+        
     - 1.19alpha11 :
     
