The two attached patches enable another option letter (d) for the
force_lpq_status variable so you can tell LPRng to send a old BSD format
compatible with Solaris' dtprintinfo to specified network addresses (those
machines running Solaris). This is to make it possible for dtprintinfo to
continue working with a LPRng print server. The format looks as follows:
henrik: 1st [job 296fie.example.com]
bar.ps 15806 bytes
henrik: 2nd [job 297fie.example.com]
foo.ps 24512 bytes
henrik: 3rd [job 298fie.example.com]
fie.ps 1233 bytes
henrik: 4th [job 299fie.example.com]
fum.ps 7463 bytes
The patch to lpd_status.c add this feature and also fixes a bug (which I
posted about earlier). The patch to plp_snprintf.c fixes a bug where that
library does not support the snprintf standard to the fully, the patch is
needed for my extension to lpd_status.c to work.
I tried to make the patch to lpd_status.c very little intrusive, so the
code is not as beautiful as it would be if I would have rewritten most of
lpd_status.c. This choice was made as I saw little hope of getting this
accepted into mainstream LPRng, so I needed a little patch as possible
that would also apply to new LPRng releases in the future.
Example:
force_lpq_status=d=10.0.0.0/255.255.255.0,192.168.0.0/255.255.0.0
Patches releases under the GPL. Share and enjoy. Report any bugs to me
please. I use these in a production system where I needed drop in
replacement of the print server, hence no software changes whatsoever on
the workstations. Solaris' lpstat, lp, cancel, dtprintinfo just had to
keep working.
Regards, Henrik--- LPRng-3.8.21/src/common/plp_snprintf.c.orig Wed Apr 16 01:37:42 2003
+++ LPRng-3.8.21/src/common/plp_snprintf.c Sat Jun 14 16:27:42 2003
@@ -683,7 +683,13 @@
return;
case '-': ljust = 1; goto nextch;
case '.': set_precision = 1; precision = 0; goto nextch;
- case '*': len = va_arg( args, int ); goto nextch;
+ case '*':
+ if( set_precision ){
+ precision = va_arg( args, int );
+ } else {
+ len = va_arg( args, int );
+ }
+ goto nextch;
case '0': /* set zero padding if len not set */
if(len==0 && set_precision == 0 ) zpad = '0';
case '1': case '2': case '3':
--- LPRng-3.8.21/src/common/lpd_status.c.orig Wed Apr 16 01:37:42 2003
+++ LPRng-3.8.21/src/common/lpd_status.c Thu Jun 19 12:53:26 2003
@@ -76,6 +76,7 @@
#define SIZEW 6
#define TIMEW 8
+static int status_dtprintinfo = 0;
int Job_status( int *sock, char *input )
{
@@ -119,7 +120,7 @@
/*
* we have a list of hosts with format of the form:
* Key=list; Key=list;...
- * key is s for short, l for long
+ * key is s for short, l for long, d for dtprintinfo compatible
*/
DEBUGF(DLPQ1)("Job_status: Force_lpq_status_DYN '%s'", Force_lpq_status_DYN);
if( Force_lpq_status_DYN ){
@@ -129,7 +130,7 @@
s = listv.list[i];
if( (t = safestrpbrk(s,Value_sep)) ) *t++ = 0;
Free_line_list(&l);
- Split(&l,t,Value_sep,0,0,0,0,0,0);
+ Split(&l,t,File_sep,0,0,0,0,0,0);
DEBUGF(DLPQ1)("Job_status: Force_lpq_status '%s'='%s'", s,t);
if( Match_ipaddr_value( &l, &RemoteHost_IP ) == 0 ){
DEBUGF(DLPQ1)("Job_status: forcing status '%s'", s);
@@ -137,6 +138,8 @@
displayformat = REQ_DSHORT;
} else if( safestrcasecmp(s,"l") == 0 ){
displayformat = REQ_DLONG;
+ } else if( safestrcasecmp(s,"d") == 0 ){
+ status_dtprintinfo = 1;
}
status_lines = Short_status_length_DYN;
break;
@@ -278,6 +281,8 @@
time_t modified = 0;
time_t timestamp = 0;
time_t now = time( (void *)0 );
+ char *suffix, *logname, *fromhost, *jobfield;
+ int len_padded, len_number;
cache_index = -1;
@@ -522,7 +527,7 @@
/* set up the short format for folks */
- if( displayformat == REQ_DLONG && Sort_order.count > 0 ){
+ if( displayformat == REQ_DLONG && Sort_order.count > 0 && status_dtprintinfo
== 0 ){
/*
Rank Owner/ID Class Job Files Size Time
*/
@@ -555,7 +560,22 @@
msg[0] = 0;
nodest = 0;
s = Find_str_value(&job.info,PRSTATUS,Value_sep);
- if( s == 0 ){
+ if( status_dtprintinfo == 1 ){
+ count++;
+ if (count%100 > 10 && count%100 < 14) {
+ suffix = "th";
+ } else if (count%10 == 1) {
+ suffix = "st";
+ } else if (count%10 == 2) {
+ suffix = "nd";
+ } else if (count%10 == 3) {
+ suffix = "rd";
+ } else {
+ suffix = "th";
+ }
+ SNPRINTF(number,sizeof(number))"%d%s",count,suffix);
+ count--;
+ } else if( s == 0 ){
SNPRINTF(number,sizeof(number))"%d",count+1);
} else {
SNPRINTF(number,sizeof(number))"%s",s);
@@ -576,6 +596,8 @@
jobsize = Find_double_value(&job.info,SIZE,Value_sep);
job_time = Find_str_value(&job.info,JOB_TIME,Value_sep );
destinations = Find_flag_value(&job.info,DESTINATIONS,Value_sep);
+ logname = Find_str_value(&job.info,LOGNAME,Value_sep);
+ fromhost = Find_str_value(&job.info,FROMHOST,Value_sep);
openname = Find_str_value(&job.info,OPENNAME,Value_sep);
if( !openname ){
@@ -601,7 +623,37 @@
priority = class;
}
- if( displayformat == REQ_DLONG ){
+ if( displayformat == REQ_DLONG && status_dtprintinfo == 1 ){
+ len_padded = 38-safestrlen(logname);
+ len_number = safestrlen(number);
+ if( len_padded < len_number ){
+ len_padded = len_number;
+ }
+ SNPRINTF( buffer, sizeof(buffer))
+ "%d", jobnumber );
+ SNPRINTF( msg, sizeof(msg))
+ "%.*s: %-*s [job %s%.*s]",
+ 38-len_number, logname, len_padded, number,
+ buffer, 32-safestrlen(buffer), fromhost );
+ DEBUGF(DLPQ3)("Get_queue_status: adding '%s'", msg );
+ Add_line_list(&outbuf,msg,0,0,0);
+ if( joberror ){
+ SNPRINTF( buffer, sizeof(buffer))
+ "<%s>", joberror );
+ jobfield = buffer;
+ } else if( jobname ){
+ jobfield = jobname;
+ } else if( filenames ){
+ jobfield = filenames;
+ } else {
+ jobfield = "<Job name not available>";
+ }
+ SNPRINTF( msg, sizeof(msg))
+ " %-32.32s %0.0f bytes",
+ jobfield, jobsize );
+ DEBUGF(DLPQ3)("Get_queue_status: adding '%s'", msg );
+ Add_line_list(&outbuf,msg,0,0,0);
+ } else if( displayformat == REQ_DLONG ){
SNPRINTF( msg, sizeof(msg))
"%-*s %-*s ", RANKW-1, number, OWNERW-1, identifier );
while( (len = safestrlen(msg)) > (RANKW+OWNERW)
@@ -995,8 +1047,10 @@
SNPRINTF( msg, sizeof(msg)) _(" Queue: %d printable job%s\n"),
printable, printable > 1 ? "s" : "" );
}
- if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0);
- if( held ){
+ if( displayformat != REQ_DLONG || status_dtprintinfo == 0 ){
+ if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0);
+ }
+ if( held && ( displayformat != REQ_DLONG || status_dtprintinfo == 0 ) ){
SNPRINTF( msg, sizeof(msg))
_(" Holding: %d held jobs in queue\n"), held );
if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0);
@@ -1021,7 +1075,7 @@
if( msg[0] ){
safestrncat( msg, "\n" );
}
- if( msg[0] ){
+ if( msg[0] && ( displayformat != REQ_DLONG || status_dtprintinfo == 0 ) ){
if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0);
}
msg[0] = 0;
@@ -1037,15 +1091,17 @@
}
}
- /*
- * get the last status of the spooler
- */
- Print_status_info( sock, Queue_status_file_DYN,
- _(" Status: "), status_lines, max_size );
-
- if( Status_file_DYN ){
- Print_status_info( sock, Status_file_DYN,
- _(" Filter_status: "), status_lines, max_size );
+ if( displayformat != REQ_DLONG || status_dtprintinfo == 0 ){
+ /*
+ * get the last status of the spooler
+ */
+ Print_status_info( sock, Queue_status_file_DYN,
+ _(" Status: "), status_lines, max_size );
+
+ if( Status_file_DYN ){
+ Print_status_info( sock, Status_file_DYN,
+ _(" Filter_status: "), status_lines, max_size );
+ }
}
s = Join_line_list(&outbuf,"\n");
@@ -1178,7 +1234,7 @@
Free_line_list(&cache);
close( lockfd ); lockfd = -1;
}
- if( Server_names_DYN ){
+ if( Server_names_DYN && ( displayformat != REQ_DLONG || status_dtprintinfo ==
0 ) ){
Free_line_list(&info);
Split(&info, Server_names_DYN, File_sep, 0,0,0,0,0,0);
for( ix = 0; ix < info.count; ++ix ){
@@ -1190,7 +1246,7 @@
DEBUGF(DLPQ3)("Get_queue_status: finished subserver status
'%s'",
info.list[ix] );
}
- } else if( Destinations_DYN ){
+} else if( Destinations_DYN && ( displayformat != REQ_DLONG || status_dtprintinfo ==
0 ) ){
Free_line_list(&info);
Split(&info, Destinations_DYN, File_sep, 0,0,0,0,0,0);
for( ix = 0; ix < info.count; ++ix ){
@@ -1202,7 +1258,7 @@
DEBUGF(DLPQ3)("Get_queue_status: finished destination status
'%s'",
info.list[ix] );
}
- } else if( RemoteHost_DYN ){
+ } else if( RemoteHost_DYN && ( displayformat != REQ_DLONG ||
status_dtprintinfo == 0 ) ){
/* now we look at the remote host */
if( Find_fqdn( &LookupHost_IP, RemoteHost_DYN )
&& ( !Same_host(&LookupHost_IP,&Host_IP )