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 )

Reply via email to