Subject: bin/8880: Output from pac not always formatted correctly.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <bstark@uswest.net>
List: netbsd-bugs
Date: 11/26/1999 00:18:48
>Number: 8880
>Category: bin
>Synopsis: Output from pac not always formatted correctly.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Nov 26 00:18:00 1999
>Last-Modified:
>Originator: Brian Stark
>Organization:
Brian Stark
bstark@uswest.net
>Release: NetBSD 1.4.1
>Environment:
System: NetBSD callisto.niangua.net 1.4.1 NetBSD 1.4.1 (CALLISTO) #5: Sat Nov 6 00:20:51 CST 1999 bstark@callisto.niangua.net:/usr/src/sys/arch/i386/compile/CALLISTO i386
>Description:
Output from pac not always formatted correctly.
>How-To-Repeat:
While processing the printer accounting file pac attempts to limit the
size of the hostname and user name field to 24 characters. However,
printf() on NetBSD does not limit the size of the field to the size
specified if the string exceeds this value (see man page for printf
on a NetBSD 1.4.1 system).
(NOTE: My copy of 'POSIX Programmer's Guide' from O'Reilly & Associates
in the section for printf() states that the meaning of the width
string for the "s" format character will be the maximum number of
characters to be written. Why doesn't NetBSD's implementation of
printf follow this??)
This presents a formatting problem on systems where the length of the
hostname and user name fields exceed the 24 character limit that pac
tries to impose. In file pac.c, functon dumpit(), the following code
segment exists:
printf(" Login pages/feet runs price\n");
feet = 0.0;
runs = 0;
for (ap = base, c = hcount; c--; ap++) {
hp = *ap;
runs += hp->h_count;
feet += hp->h_feetpages;
printf("%-24s %7.2f %4d $%6.2f\n", hp->h_name,
hp->h_feetpages, hp->h_count, hp->h_feetpages * price);
}
if (allflag) {
printf("\n");
printf("%-24s %7.2f %4d $%6.2f\n", "total", feet,
runs, feet * price);
}
Here is an example using hostname 'callisto.niangua.net' and user
names 'bstark' and 'root'. This example will show summary information
for all entries in the accounting file:
# pac -Pljet4
Login pages/feet runs price
callisto.niangua.net:bstark 70.00 26 $ 1.40
callisto.niangua.net:root 21.00 12 $ 0.42
total 91.00 38 $ 1.82
#
Here is another example using the same hostname and a specific user,
'bstark':
# pac -Pljet4 callisto.niangua.net:bstark
Login pages/feet runs price
callisto.niangua.net:bstark 70.00 26 $ 1.40
#
>Fix:
I see several possible solutions for this problem. First, the functionality
of printf could be modified so that if a width is specified for a string
that will be the maximum number of characters to be printed. A second
solution would be to change the formatting of the output to avoid this
problem.
IMHO, both of these solutions should be implemented. It would be really
nice if printf worked according to how a POSIX system should work, and
even if printf did correctly limit the characters printed, it would
be nice to see full information for the hostname and user (as opposed
to truncated information). To solve the second solution, the code in
dumpit could be changed to the following:
printf("pages/feet runs price host name and/or login\n");
printf("---------- ---- ------- ----------------------\n");
feet = 0.0;
runs = 0;
for (ap = base, c = hcount; c--; ap++) {
hp = *ap;
runs += hp->h_count;
feet += hp->h_feetpages;
printf(" %7.2f %4d $%6.2f %-s\n",
hp->h_feetpages, hp->h_count, hp->h_feetpages * price,
hp->h_name);
}
if (allflag) {
printf("\n");
printf(" %7.2f %4d $%6.2f total\n",feet,runs,feet * price);
}
Using the above section of code, the output would now look like this:
callisto:{root}# ./pac -Pljet4
pages/feet runs price host name and/or login
---------- ---- ------- ----------------------
71.00 27 $ 1.42 callisto.niangua.net:bstark
1.00 1 $ 0.02 callisto.niangua.net:root
72.00 28 $ 1.44 total
callisto:{root}# ./pac -Pljet4 callisto.niangua.net:bstark
pages/feet runs price host name and/or login
---------- ---- ------- ----------------------
71.00 27 $ 1.42 callisto.niangua.net:bstark
callisto:{root}#
NOTE #1: The pac command takes a "-s" parameter that causes it to write
information to a summary file. The format of the data written to this
file looks ok because the data fields are separated by a tab character
and the hostname/login name field is written as a complete string.
NOTE #2: There still could be formatting problems if the number of
pages is large and the price per page is large. The maximum dollar
amount that can be shown without formatting problems is $999.99.
However, this is something that can be addressed later...
Diff for my changes:
callisto:{root}# ident pac.c.netbsd141
pac.c.netbsd141:
$NetBSD: pac.c,v 1.10 1997/10/05 15:12:25 mrg Exp $
$NetBSD: pac.c,v 1.10 1997/10/05 15:12:25 mrg Exp $
callisto:{root}# diff pac.c pac.c.netbsd141
269,270c269
< printf("pages/feet runs price host name and/or login\n");
< printf("---------- ---- ------- ----------------------\n");
---
> printf(" Login pages/feet runs price\n");
277,279c276,277
< printf(" %7.2f %4d $%6.2f %-s\n",
< hp->h_feetpages, hp->h_count, hp->h_feetpages * price,
< hp->h_name);
---
> printf("%-24s %7.2f %4d $%6.2f\n", hp->h_name,
> hp->h_feetpages, hp->h_count, hp->h_feetpages * price);
283c281,282
< printf(" %7.2f %4d $%6.2f total\n",feet,runs,feet * price);
---
> printf("%-24s %7.2f %4d $%6.2f\n", "total", feet,
> runs, feet * price);
>Audit-Trail:
>Unformatted: