APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed

SCO Unix/System V Printing FAQ

Some material is very old and may be incorrect today

© September 2002 Tony Lawrence

This article is from a FAQ concerning SCO operating systems. While some of the information may be applicable to any OS, or any Unix or Linux OS, it may be specific to SCO Xenix, Open There is lots of Linux, Mac OS X and general Unix info elsewhere on this site: Search this site is the best way to find anything.

Where do I get "netcat" for SCO Unix and how do I use it?

September 2002

This is about printing to network printers, specifically HP network printers and other print servers that use a direct "raw" network port.

(I want to thank Jack Wendel for many suggestions that hopefully have made this section easier to understand)

There's a lot of information here. It's all simple, it's all step by step, but you need to READ it. Don't just skim through this and start typing away without any understanding. READ.

Brian White has a more prepackaged version: http://www.aljex.com/bkw/sco/#rlpnc

The netcat we are talking about here is described at /KevinSmith/netcat/. There is another more widely known netcat ("nc") written by Hobbit that is used (among other things) for port scanning.

Netcat "cats" to the network. Most network printers work that way at some port number. For example, HP printers use port 9100. So if you open up port 9100 (a simple "telnet deviceip 9100" is all it takes), anything that is presented there will be printed. With netcat, all you need is a hostname or a raw ip address and the proper port number. Anything you send will be printed- it's that simple. Just like you "cat" a file to the screen, "netcat" sends it to an ipaddress and a port (though unlike "cat", netcat is a filter- you pipe data TO it).

Why use netcat? Because it works. Time after time I've fixed nasty and confusing network printer problems by just using netcat instead of the HP printing method or even lpd. Netcat works. The HP printer stuff and lpd include all sorts of overhead you just do not need.

(Some network print servers do not work in this simple manner. Some will use more complex protocols such as LPD. You may be interested in /Unixart/netcatlpr.html if you have a print server like that.)

Download netcat from the link above or, if you don't want the C program source and don't need a COFF binary, use one of the ELF binaries (if you don't understand any of that, you probably want the ELF). Get netcat.sco5.newer if you have Openserver 5.0.4 or better or Unixware, netcat.sco5.older if you have 5.0.0 or 5.0.2, and netcat.v42 if you have 3.2v4.2. Put it somwhere in your PATH and rename it "netcat".

Quickest instructions:

Choose an interface script from /usr/spool/lp/model. That's often HPLaserJet or "dumb". Copy that script somewhere that lp can read it: /usr/spool/lp/admins/lp/interfaces/model.orig is a good choice. If you already had used the HP Printer Manager to create a printer, your script is already there. Do a chmod 755 on it just in case. Then create this in /usr/spool/lp/model, calling it whatever you will ultimately call your printer: I'll assume MYPRINTER here:

# /usr/spool/lp/model/MYPRINTER
/usr/spool/lp/admins/lp/interfaces/model.orig/MYPRINTER   "[email protected]" | netcat -h ipaddress -p 9100


/usr/lib/lpadmin -p MYPRINTER -m MYPRINTER -v /dev/null
# That creates /usr/spool/lp/admins/lp/interfaces/MYPRINTER
/usr/lib/accept MYPRINTER

That's it. Read the rest only if you need to understand better.

You can bundle this all up like this:

# cat /usr/spool/lp/model/netcat
# this script assumes that the name you will use for the printer
# is listed in /etc/hosts or dns
# and that you have copied /usr/spool/lp/model/HPLaserJet
# (or whatever interface you want to use) to 
# /usr/spool/lp/admins/lp/interfaces/model.orig/
#  You can change the "9100" to any port needed
P=`basename $0`
/usr/spool/lp/admins/lp/interfaces/model.orig/$P  "[email protected]" | netcat -h $P -p 9100
# cat /usr/bin/addnetcat
test "$MYPRINTER" || { echo "must provide printer name"; exit 1; }
echo "adding or modifying $MYPRINTER"
echo "$MYPRINTER must ne in /etc/hosts or dns"
/usr/lib/lpadmin -p $MYPRINTER -m netcat  -v /dev/null
# That creates /usr/spool/lp/admins/lp/interfaces/MYPRINTER
/usr/lib/accept $MYPRINTER
enable $MYPRINTER 
cp /usr/spool/lp/model/HPLaserJet /usr/spool/lp/admins/lp/interfaces/model.orig/$MYPRINTER

Here's another way to create an HP printer named MYPRINTER that works on port 9100. This assumes OSR5. You should substitute MYPRINTER with whatever you want to call your printer in all steps below. DON'T USE THIS IF YOUR PRINTER ISN'T AN HP LASER OR COMPATIBLE. If you have a dotmatrix or thermal printer or anything NOT HP, skip this and use the other netcat scripts.

Download http://aplawrence.com/pub/netcat/netcat.hp.model

Download the netcat binary. We'll assume it was netcat.sco5.newer above and that you are sitting in the directory you downloaded these too..

You need to edit the interface script. If you don't know how to use vi, see Vi Basics.

# create model for lpadmin to use
cp  ./netcat.hp.model /usr/spool/lp/model/MYPRINTER
# put netcat in /usr/bin
cp ./netcat.sco5.newer /usr/bin/netcat
# make it executable
chmod 755 /usr/bin/netcat
# make sure model.orig is there (it may already exist)
mkdir /usr/spool/lp/admins/lp/interfaces/model.orig
# put MYPRINTER in model.orig.  
cp /usr/spool/lp/model/HPLaserJet /usr/spool/lp/admins/lp/interfaces/model.orig/MYPRINTER
chmod 755 usr/spool/lp/admins/lp/interfaces/model.orig/MYPRINTER
# vi /usr/spool/lp/model/MYPRINTER and point
# MYPRINTER where it needs to go.  Change this line: YOUR_PRINTER_OR_IP=""
vi /usr/spool/lp/model/MYPRINTER 
# now create the printer
/usr/lib/lpadmin -p MYPRINTER -m MYPRINTER -v /dev/null
# That creates /usr/spool/lp/admins/lp/interfaces/MYPRINTER
# now finish up
/usr/lib/accept MYPRINTER

You can get that script here: http://aplawrence.com/pub/netcatscript. Be sure to READ IT and edit it as necessary!

You can test netcat from the command line:

date | netcat -h ip_address -p 9100
echo ^L | netcat -h ip_address -p 9100
# or
echo "`date`\f\c | netcat -h ip_address -p 9100

Many of you don't need to read any more. Nothing else is necessary if you are printing as that assumes. If not, read on:

A simple netcat interface script is:

PORT=9100 # for hp, netgear, some others
shift; shift; shift; shift; shift
# The lpsched program sends 5 arguments that we are going to ignore.
# arguments 6 and on are the file names to be printed
# We just throw away everything but the file names by using shift 5 times
# arguments 6 through whatever are now $*
cat $* | netcat -h printserver -p $PORT
# If you need lfcr translation, do:
# cat $* | /usr/lib/lponlcr | netcat -h printserver -p $PORT
# If you need a pagefeed, do:
# cat $* /usr/lib/Control_L | /usr/lib/lponlcr | netcat -h printserver -p $PORT
# sleep 15
# if you have truble with multiple jobs, try uncommenting sleep
# note that's a printer problem, not a netcat issue

To create /usr/lib/Control_L, do:

echo -n ^L  > /usr/lib/Control_L
# type Ctrl-L 

You really need to TYPE Cntrl-L (hold CTRL and press L). When you do that your screen will blank. Just keep going with the ">" etc.

You'd save that as "netcat" in /usr/spool/lp/model. When you create your printer, use that as the interface script (it will appear in your list of choices). What I do is copy it to the name I will use for the printer, modify the copy to use the correct host name or ip address and port number, and then my printers use the same name for their scripts: printer "officehp" uses the interface script "officehp" etc.

You don't have to use the printer configuration manager to add a simple printer. For example, to add a printer called "printer" after modifying the script as above:

/usr/lib/lpadmin -p printer -m netcat -v /dev/null
# MUST have /usr/spool/lp/model/netcat script !!
# If script were called "hpprinter" you'd do:
# /usr/lib/lpadmin -p printer -m hpprinter -v /dev/null
# then:
/usr/lib/accept printer
enable printer

Here's another example that uses an ip address on an Intel Netport port 2:

shift; shift; shift; shift; shift
cat $* | netcat -h -p $PORT

And here's a Netgear PS110 on port one:

shift; shift; shift; shift; shift
cat $* | netcat -h netgear.wherever.com -p 4010

Remember, these are interface scripts you will use when you define a printer.

If your application lets you specify a printer command (RealWorld, Mas90/Mas200 and many more), you can use netcat directly. For example, you might have previously put something like this in a configuration file:

LP1=">lp -dmyprinter %s";export LP1

(This is the way Realworld configures printers; it's not necessary for you to understand this)

You'd replace this with:

LP1=">netcat -h printerip -p 9100";export LP1

If the "printerip" is the address you can "ping" and 9100 is the port number used for printing.

There are other examples here. These are more complex examples that may require some experience to use and understand.

Printing through pipe device

Printing through interface script

You'll also want to see /Jeffl/printports.html to find out what port numbers to use with your network printer or printserver. IF YOU USE THE WRONG PORT NUMBER IT WON'T WORK.

The netcat program can also help diagnose problems. The folowing was taken from a newsgroup posting by Kevin Smith (the author of this netcat):

(You don't need to read or understand any of this to use netcat)

 $ netcat -d 999 -h hp3 -p 9102
 debugl = 999
 hostname = hp3
 port = 9102
 Connect to port 9102 on hp3: Connection refused
 debugl = 999
     Your debug level.  Anything >= 1 triggers debug messages.
     There are no "levels", just on and off.
 hostname = hp3
     Value from -h arg
 port = 9102
     Value from -p arg
     Return value of gethostbyname() which is the address of the
     hostent struct which is useless unless it's 0 which means there
     was an error.
     This translates the host name (hp3) into an ip address.
     Return value of the socket() call.  It's really a file descriptor
     for the network connection.  Not too many reasons for this to fail.
     Useless unless it's -1.  Should always be 3 (stdin = 0, stdout = 1,
     stderr = 2, 3 is next).
     This is the first half of opening a network connection.
     The ip address in hex, as found by gethostbyname(), not adjusted
     for network byte order.
     0x2882b8d0 -> 0x28.0x82.0xb8.0xd0 -> ->
     I should be using inet_ntoa() to show the ip.
     The return from the connect() call.  Who knows why this was
     failing for the coff and not the elf versions.  I run a coff
     version on OSR 5.0.0 (compiled on OSR 5.x though).
     This is the second half of opening a network connection, where the
     target host is actually contacted and the connection is established.
 Connect to port 9102 on hp3: Connection refused
     Output of
         perror("Connect to port <port> on <host>")

If you have Perl, netcat is very simple:

use IO::Socket;
$host=shift @ARGV;
$port=shift @ARGV;
$socket=IO::Socket::INET->new(PeerAddr=> $host, PeerPort=> $port, Proto=> 'tcp',
Type=> SOCK_STREAM) or die "Can't talk to $host at $port";

while (<>) {
print $socket $_;
close $socket;

If you use this, don't use -h and -p, just give the host first.

Copy that to /usr/bin/netcat or anywhere else you like (somewhere in your PATH is a good idea).

Another netcat how-to: http://www.tkrh.demon.co.uk/netcat.html

If you found something useful today, please consider a small donation.

Got something to add? Send me email.

(OLDER)    <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> (SCO Unix) Where do I get 'netcat' and how do I use it?


Inexpensive and informative Apple related e-books:

Photos: A Take Control Crash Course

iOS 10: A Take Control Crash Course

Take Control of OS X Server

Take Control of iCloud

Are Your Bits Flipped?

More Articles by © Tony Lawrence

Wed Apr 15 19:22:38 2009: 6181   anonymous

I am looking for the netcat.v42 file and the link in this article doesn't work. Is it still available?

Wed Apr 15 19:24:37 2009: 6182   TonyLawrence

Yes, it is. Send me an email (FAQ->Contact above) and I'll pop it to you.

Wed Apr 15 21:06:30 2009: 6183   TonyLawrence

Or just try the link again - it should work now.

Thu Apr 16 10:18:58 2009: 6187   anonymous

Thanks! That was perfect!

Sat Apr 18 22:40:07 2009: 6222   anonymous

Hello, I'm sending a file of commands to a networked printer with netcat"cat file_print | netcat -w1 <IP_PRINTER> <PORT> > /tmp/exit.out " and command nc. It's work fine but with netcat stays with the running process finishes execution and with nc not capture the value returned by the printer. I have reviewed the parametres the two commands and I have been doing tests but there is no way to get it to work. It happens you something. Thanks.

Sat Apr 18 22:53:42 2009: 6223   TonyLawrence

Netcat doesn't read anything from the printer.

Sat Apr 18 23:43:39 2009: 6224   anonymous

Ok, but how can I end the execution of the command "cat file_print | netcat -w1 <IP_PRINTER> <PORT> > /tmp/exit.out". I capture stdout(the code send for the printer) in the file exit.out. Thanks for answer

Sun Apr 19 01:16:00 2009: 6225   TonyLawrence

If netcat can't send the file, it will have a non-zero exit status. Look at the source: (link)

If you want to capture any errors, you need stderr: 2> /tmp/eerrorexit.out

I do not understand what you mean by "end the execution of the command" ???

Sun Apr 19 01:19:30 2009: 6226   TonyLawrence

Wait a sec - what the heck are you doing?

Netcat doesn't use -w1.

You are confused. You think we're talking about "nc" here.

Read more carefully, please: this is NOT about "nc".

Sun Apr 19 01:28:50 2009: 6227   TonyLawrence

Though you could use "nc" to do it that way..

But I have no idea what you are asking.

The command you gave would work with "nc". That's about all I can tell you.

Sun Apr 19 15:27:17 2009: 6232   anonymous

The problem is:
athos# cat files/P_per.txt | netcat 7500
4020000 //printer execute ok the command in the file "P_per.txt",return "4020000"and wait.
^C // for finish the command execute its necesary "^C". Why?
How can close the port for finish execute the command netcat? Any ideas ?

Sun Apr 19 15:32:38 2009: 6233   TonyLawrence

Oh, you are hanging?

You shouldn't be.

Here it is with "nc" on my Mac:

$ date;cat t | nc 9100;date
Sun Apr 19 11:30:47 EDT 2009
Sun Apr 19 11:30:54 EDT 2009

(The delay is while the printer warms up and prints)

I suggest trying the Perl script I show above to try to figure out why you are hanging.

Sun Apr 19 15:51:42 2009: 6234   anonymous

ok, I'm going to test with the script in perl. But, if I send the same file with command "nc" the printer recive the file ok but i haven't the answer 4020000 and the command "nc"finish.

athos# cat files/P_per.txt | nc 7500


Sun Apr 19 16:14:44 2009: 6235   TonyLawrence

What "answer"?

What "4020000" ??

I have no idea what you mean..

Sun Apr 19 16:21:54 2009: 6236   anonymous

4020000 is the code returned by the printer once it has executed the file sent.

Sun Apr 19 18:05:47 2009: 6237   TonyLawrence

Well, as I explained before, we aren't reading anything from the printer.

Look at the netcat.c code - if you want to read, that's easy enough.


Printer Friendly Version

Have you tried Searching this site?

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.

Contact us

Printer Friendly Version

The worst crime against working people is a company which fails to operate at a profit. (Samuel Gompers)

Linux posts

Troubleshooting posts

This post tagged:





Unix/Linux Consultants

Skills Tests

Unix/Linux Book Reviews

My Unix/Linux Troubleshooting Book

This site runs on Linode