Hi,

Apologies for the length of this posting.  If you are not having problems
with page counting or end of job detection using pjl_waitend_byjobname
with ifhp-3.5.17 you can skip this message!

I *was* having a problem and the following describes what I was seeing and
how I fixed it.

Up until recently we were using ifhp-3.5.10 with unofficial patches that
added a facility to do end of job detection using "pjl_waitend_byjobname".
This has been working fine for us.

Then a few weeks ago we upgraded to 3.5.17 which includes those patches.
Unfortunately we found page counting broken again, because the end of job
was being detected too early (before the printer had finished printing pages).

I poked around at the source code and ran tests with various levels of
debugging and tracing.  I noticed the following logging from the the code
in Do_waitend.

| ifhp 15:28:03.703 [980] Do_waitend: job 'start', name '', result '<NULL>',
|    echo '[EMAIL PROTECTED]', endname
| ifhp 15:28:03.723 [980] Do_waitend: echo '[EMAIL PROTECTED]',
|    want ''
| ifhp 15:28:03.743 [980] Do_waitend: ECHO END detected
| ifhp 15:28:03.763 [980] Do_waitend: JOB detected pjl ECHO END


Notice how the job name and endname are null.  This results in Do_waitend()
calling safestrstr with a null 2nd parameter which according to the manual
page (for strstr()) always succeeds.  Hence the "ECHO END detected" while
pages were still being printed.

A quick search of the mailing list archives revealed a message from
Hermann Lauer <[EMAIL PROTECTED]> on July 16th 2004
with the subject "LPRng: [ifhp] new displayname fix for 3.5.17".  In
it Hermann says:

> while including my last patch for the displayname separation
> from jobname a mistake occured, so in 3.5.17 the jobname is
> empty (which our lj8150 don't like much). Attached is the
> fix, which makes it working here again.

This sounded like it was related to the problem I was seeing so I applied
the patch enclosed in that email.

That patch definitely changed ifhp's behaviour, but it still didn't work
properly.  Now if would loop endlessly looking for the end of job and never
finding it.

So, back to the source code, logs and debugging traces... :-/

Here is an extract of the log from another test run.

| ifhp 14:31:49.397 [24678] Do_waitend - Devstatus - OBJ_T_HASH len 9
| ifhp 14:31:49.429 [24678]  [0] HASH key 'code'  - OBJ_T_STR '10001'
| ifhp 14:31:49.462 [24678]  [1] HASH key 'display'  - OBJ_T_STR 'ready'
| ifhp 14:31:49.503 [24678]  [2] HASH key 'echo'
|    - OBJ_T_STR '[EMAIL PROTECTED]'
| ifhp 14:31:49.535 [24678]  [3] HASH key 'id'
|    - OBJ_T_STR 'hp_laserjet_4200'
| ifhp 14:31:49.572 [24678]  [4] HASH key 'job'  - OBJ_T_STR 'end'
| ifhp 14:31:49.602 [24678]  [5] HASH key 'name'
|    - OBJ_T_STR 'duncan__press'
| ifhp 14:31:49.633 [24678]  [6] HASH key 'online'  - OBJ_T_STR 'true'
| ifhp 14:31:49.655 [24678]  [7] HASH key 'page'  - OBJ_T_STR '2'
| ifhp 14:31:49.688 [24678]  [8] HASH key 'pages'  - OBJ_T_STR '2'
| ifhp 14:31:49.718 [24678] Do_waitend: job 'end', name 'duncan__press',
|    result '<NULL>', echo '[EMAIL PROTECTED]',
|    endname duncan _press

Note how the job name is "duncan__press" and the endname is "duncan _press".
They don't match, so ifhp doesn't think this is the end of the job and
so it goes around the loop again...

I *think* what was happening was this:

With Hermann's patch applied, the variable Jobname starts as "duncan :press"
(username, null job name, ":", printer name).  The loop at line 3110 in the
routine Pjl_displayname converts this into "duncan _press", and this is then
used as the argument to the "PJL JOB NAME =" command.

But in Check_device_status the status information from the printer is
read back and at line 1086 in that routine any blanks are changed to '_'.
So the job name read back from the printer is "duncan__press" and the
comparision against "duncan _press" to detect the end of the job fails.

It seems to me that the line in Pjl_displayname which reads

              if( !isspace(c) && !isalnum(c) ){

should actually be

              if( isspace(c) || !isalnum(c) ){

That would have the effect of converting both the ':' and space characters
in the jobname to '_' so instead of "duncan _press" we would end up with
"duncan__press" which would compare correctly.

The patch below fixes this problem.  It also includes the above mentioned
patch posted by Hermann Lauers since without his patch mine would be
insufficient.

Duncan

*** ifhp.c.orig	Thu Feb 26 04:56:25 2004
--- ifhp.c	Wed Sep  1 17:17:17 2004
***************
*** 3102,3113 ****
  		Job_ready_msg[Pjl_display_size] = 0;
  	}
  
  	DEBUG2("Pjl_displayname: raw Jobname '%s'", Jobname);
  	{
  		int len = strlen(Jobname), i;
  		for( i = 0; i < len; ++i ){
  			int c = cval(Jobname+i);
! 			if( !isspace(c) && !isalnum(c) ){
  				Jobname[i] = '_';
  			}
  		}
--- 3102,3114 ----
  		Job_ready_msg[Pjl_display_size] = 0;
  	}
  
+ 	SNPRINTF(Jobname,sizeof(Jobname))  "%s", s);
  	DEBUG2("Pjl_displayname: raw Jobname '%s'", Jobname);
  	{
  		int len = strlen(Jobname), i;
  		for( i = 0; i < len; ++i ){
  			int c = cval(Jobname+i);
! 			if( isspace(c) || !isalnum(c) ){
  				Jobname[i] = '_';
  			}
  		}
***************
*** 3154,3160 ****
  	SNPRINTF(buffer+len, sizeof(buffer)-len) Jobstart_str, Jobname );
  	len = safestrlen(buffer);
  	if( Pjl_console ){
! 		SNPRINTF(buffer+len, sizeof(buffer)-len) Job_display, Jobname );
  	}
  
  	if( (s = GET_HASH_STR_OBJ( Zopts, "startpage", MEMINFO))
--- 3155,3161 ----
  	SNPRINTF(buffer+len, sizeof(buffer)-len) Jobstart_str, Jobname );
  	len = safestrlen(buffer);
  	if( Pjl_console ){
! 		SNPRINTF(buffer+len, sizeof(buffer)-len) Job_display, Job_ready_msg );
  	}
  
  	if( (s = GET_HASH_STR_OBJ( Zopts, "startpage", MEMINFO))


Reply via email to