Customizing Windows Separator pages

(adding real names to separator page)

The problem:

So, say for instance you’ve got a hundred people sharing 5 printers, and because you’re not a totally square organization your usernames aren’t always lastnamefirstinitial. You can’t expect everyone to remember the mapping of usernames to real names, especially if the usernames are weird, or of the people keep changing, like in a university or in a quickly growing company.

The ideal thing is for the separator page to have the real name of the user as well as the username.

It turns out that if you’re using an NT print server for all those Windows boxes on the the desktops, it’s not trivial to include the code in the print server to pass the real name to the printer.

However, it’s much simpler to modify the generic cover page to include some new postscript code, and download the dynamic part to the printer from a unix box (or anything, really)

In my organization we have a Windows NT server as a print server, but we’re running lots of unix boxes too, so our windows usernames and our unix usernames match. This is important. Also, all the main printers support postscript. This is also important.

The process is thus:

  1. download a hash table that maps usernames to real names to the printer
  2. modify the stock header page to include some postscript that will do a lookup on the above hash table, and print the real name if it exists.
Once a night I run a perl script on my linux box that gets a list of the usernames and realnames, (I use YPCAT, but any other way would work fine) and generate a postscript file that gets printed to each of the printers. The perl script is here:

That script generates a script that looks like this:

%!PS-Adobe-2.0
%!
%!

serverdict begin 0 exitserver
systemdict

/PUTTHEDICT { <<
(fflint) (Fred Flintstone)        
(dubbya) (George W. Bush)
(jrh4) (man with obscure username)   
(Lflint) (Larry Flint)
(flintl) (Lisa Flint)
(ron) (Ronald Reagan)
(ron2) (Ron Foobar) 
(ora1) (Oracle User 1)     
>> begin } def put
                                                                              
but with a lot more entries, you get the idea.

When printed this will set up a hash table in the printers memory that maps usernames to real names whenever PUTTHEDICT is run.

Just print this file to the Poststscript printer. No pages will come out, as there’s no show, stroke, line, arc, etc, or showpage.

I just cull out the temporary file, and pipe the output of the script directly to lpr -Pprinter, my nightly script looks like this:


#!/usr/bin/perl

@printers= `cat printers.txt`;		#printers.txt is a list of the printer names
chomp @printers;			# get rid of the carraige returns
foreach (@printers) {
        $printername = $_ . "1" ;	# I do this becasue the one-less printer name 
					# goes through an intermediate print server 
					# which tries to add a header page.  printername1 
					# goes direct to the JetDirect port on the printer.

        `./makeheader.pl |lpr -P$printername` ;
}

If you do it this way make sure to remove "FILE" from all the "print" statements, otherwise there won’t be any output to pipe to lpr.

The next thing is to add stuff to the windows seperator page.

The interesting things about the separator page are:

The last one is the most interesting one.

The files have a "@L" (or something equally ugly) as the first two characters of each line except for the first one and the last one. The windows print server strips these out before sending it to the printer. I can’t imagine why you’d do it this way, but they do. The first line only has the "@" with nothing else, and the last line is "@E" (no "L", indicating the end of the file

without the "@L" on each line and that "E" at the end, it’s postscript.

anyway, there’s a bit at the top that defines the things that NT stuffs in:

@L% Pull off the job specific values:
@L%----------------------------------
@L/name (@N@L) def
@L/jobid(@I@L) def
@L/date (@D@L) def
@L/time (@T@L) def 

and then here’s the stuff I put in at the bottom:

@L% add the real name
@L%-----------------
@L(PUTTHEDICT) where
@L{ PUTTHEDICT name where {/Helvetica-Bold findfont .5 inch scalefont setfont
@Lnewpath
@Lxmin ymax 2.5 inch sub moveto 
@LPrintWidth  name load CenterString true charpath
@Lclosepath}if}  if
@Lgsave
@LGray setgray fill
@Lgrestore

Note that that there’s a couple "if" statements in here, they’re to make sure that if the cron job doesn’t run, or the printer has been rebooted since the cron job ran, or if there’s a new user since the cron job, (basically any reason the postscript could barf), it won’t. It will simply ignore the stuff you put in and you’ll get a stock cover page.

I had to reduce the size of the text for the realname because we have some people here with really long names, and it was getting shoved off the sides of the page.

The final thing is to set the print server to use the seperator page, which you do on the NT machine by going to the "advanced" tab and clicking on the separator page button, then chosing the one you’ve modified.

You should be able use this one without trouble. Just make sure to save the original just in case.

In the future I’ll have the printer spit out things like the person’s horoscope, a riddle, or "happy birthday" if it’s the person’s birthday, but not yet.


Some Windows printing references: (perhaps the only two useful ones on the net)
Some postscript references (quite useful)