Question for lpd Guru

I have another post ‘TCPIP Printer spooling question…’ where I have
been trying to figure out how to write postscript files from an C
application directly to the lpd spooling system w/o using a
system(“lpr…”) call. I am using Qnx 4.25.

There have been some suggestions that I write into the lpd spool
directory or open a pipe to a spawned lpr process.

I don’t know how lpd manages its queues. Do you have any suggestions
on how I might do this or do you have any references to docs.

Thanks for your Guruish time,
Greg Laird

Previously, Greg Laird wrote in qdn.public.qnx4:

I have another post ‘TCPIP Printer spooling question…’ where I have
been trying to figure out how to write postscript files from an C
application directly to the lpd spooling system w/o using a
system(“lpr…”) call. I am using Qnx 4.25.

There have been some suggestions that I write into the lpd spool
directory or open a pipe to a spawned lpr process.

I don’t know how lpd manages its queues. Do you have any suggestions
on how I might do this or do you have any references to docs.

Thanks for your Guruish time,
Greg Laird

/usr/help/product/tcpip_4.25_en/user_guide/printing.html

Example 4.

Previously, Greg Laird wrote in qdn.public.qnx4:

Hello Andrew,
I have looked at the example that you suggested. The solution of
using both lpsrvr and lpd seems complex to me. I have also not found
anything in the docs about writing to a /dev/spool device to
automatically spool a file (that doesn’t mean it’s not there).

I agree this seems complex, but it also makes a strange kind of
sense. lpd doesn’t offer a local /dev/ because it assumes you
will be printing using lpr. lpsrvr doesn’t offer TCP networked access
because it assumes you will be using QNX networking. If you hook the
/dev/ capability of lpsrvr to the TCP printing capability of
lpd, then you get the exact behaviour you are looking for. This is
consistent with the “UNIX Way” of concatenating simple specialized
applications in various ways to achieve complex behaviour. In this
case I don’t think that using two print spoolers will have any more
impact on stability than any other solution you are considering, and
it means you don’t have to write a line of code.

I was hoping to find an elegant method of letting lpd know that there
is a file to be printed (e.g. storing it in a directory and sending a
message to lpd, or some such thing).

Well, I would actually call anything but invoking lpr to be klugy.
You can safely kill lpd, copy a file into the appropriate spool
directory, create a “cf” file for it, and then restart lpd. I don’t
think that’s very efficient, though.

The system call to invoke lpr
seems sort of klugy to me (firing up both the shell & lpr),

The shell is almost definitely already in memory, so the startup is
pretty cheap, and uses very little extra memory. You have no real
choice but to call lpr, so that startup and memory are a foregone
conclusion. If you really don’t want to run the shell, use spawn() or
qnx_spawn(). At least you don’t have to fiddle with pipes.
Personally, I would write it to spawn() or system() a shell script,
and have the script call lpd. That way I could modify the printing
behaviour without recompiling my program. The difference in time and
memory is pretty minimal unless you are running pretty close to the
limit.

Maybe a file is stored in a directory and a signal gets sent to
lpd???

Not that I’m aware of. lpr creates a control file as well as a spool
file, and it’s reasonable to assume that you aren’t going to reproduce
the behaviour of lpr more reliably than lpr does. If you think you
can get away with a small subset of the lpr behaviour, the source is
available from RedHat, so you can see what you minimally need.

Good luck,
Andrew

Hello Andrew,
I have looked at the example that you suggested. The solution of
using both lpsrvr and lpd seems complex to me. I have also not found
anything in the docs about writing to a /dev/spool device to
automatically spool a file (that doesn’t mean it’s not there).

I was hoping to find an elegant method of letting lpd know that there
is a file to be printed (e.g. storing it in a directory and sending a
message to lpd, or some such thing). The system call to invoke lpr
seems sort of klugy to me (firing up both the shell & lpr), but the
spawn of lpr with a pipe set up seems not too bad. I was hoping for
something simpler still–which I bet could be found if one knew how
lpd worked. Maybe a file is stored in a directory and a signal gets
sent to lpd???

So, this is what I have been thinking about.

Thanks for your pointer.

Best to you,
Greg

On Thu, 15 Mar 2001 16:26:51 +0000, Andrew Thomas <Andrew@cogent.ca>
wrote:

Previously, Greg Laird wrote in qdn.public.qnx4:
I have another post ‘TCPIP Printer spooling question…’ where I have
been trying to figure out how to write postscript files from an C
application directly to the lpd spooling system w/o using a
system(“lpr…”) call. I am using Qnx 4.25.

There have been some suggestions that I write into the lpd spool
directory or open a pipe to a spawned lpr process.

I don’t know how lpd manages its queues. Do you have any suggestions
on how I might do this or do you have any references to docs.

Thanks for your Guruish time,
Greg Laird

/usr/help/product/tcpip_4.25_en/user_guide/printing.html

Example 4.

We have been using the lpsrvr/lpd method for many years. It’s
not flawless and if it weren’t for inertia, I’d get rid of lpsrvr.

Problem #1: If lpsrvr dies, any files in its queues will never
print without a fair bit of twiddling. This is not true of lpd.

#2. If there are more than a few printers, making changes to
/etc/config/lpsrvr and /etc/printcap in such a way as to keep
them in harmony can require a bit of care.

#3. If a large job is to be printed (>500KB ? ), there can be a
noticeable delay before the start of printing, and noticeably
more disk activity since lpd doesn’t do anything until lpsrvr
gets an EOF and the file is copied to lpd’s queue.

Richard

Andrew Thomas wrote:

Previously, Greg Laird wrote in qdn.public.qnx4:
Hello Andrew,
I have looked at the example that you suggested. The solution of
using both lpsrvr and lpd seems complex to me. I have also not found
anything in the docs about writing to a /dev/spool device to
automatically spool a file (that doesn’t mean it’s not there).

I agree this seems complex, but it also makes a strange kind of
sense. lpd doesn’t offer a local /dev/ because it assumes you
will be printing using lpr. lpsrvr doesn’t offer TCP networked access
because it assumes you will be using QNX networking. If you hook the
/dev/ capability of lpsrvr to the TCP printing capability of
lpd, then you get the exact behaviour you are looking for. This is
consistent with the “UNIX Way” of concatenating simple specialized
applications in various ways to achieve complex behaviour. In this
case I don’t think that using two print spoolers will have any more
impact on stability than any other solution you are considering, and
it means you don’t have to write a line of code.

I was hoping to find an elegant method of letting lpd know that there
is a file to be printed (e.g. storing it in a directory and sending a
message to lpd, or some such thing).

Well, I would actually call anything but invoking lpr to be klugy.
You can safely kill lpd, copy a file into the appropriate spool
directory, create a “cf” file for it, and then restart lpd. I don’t
think that’s very efficient, though.

The system call to invoke lpr
seems sort of klugy to me (firing up both the shell & lpr),

The shell is almost definitely already in memory, so the startup is
pretty cheap, and uses very little extra memory. You have no real
choice but to call lpr, so that startup and memory are a foregone
conclusion. If you really don’t want to run the shell, use spawn() or
qnx_spawn(). At least you don’t have to fiddle with pipes.
Personally, I would write it to spawn() or system() a shell script,
and have the script call lpd. That way I could modify the printing
behaviour without recompiling my program. The difference in time and
memory is pretty minimal unless you are running pretty close to the
limit.

Maybe a file is stored in a directory and a signal gets sent to
lpd???

Not that I’m aware of. lpr creates a control file as well as a spool
file, and it’s reasonable to assume that you aren’t going to reproduce
the behaviour of lpr more reliably than lpr does. If you think you
can get away with a small subset of the lpr behaviour, the source is
available from RedHat, so you can see what you minimally need.

Good luck,
Andrew

And one more thing I forgot to mention. Assuming you can
get the files properly constructed, you can probably do the
following to control lpd; we do this with lpsrvr and it works
well; I should think it would also work with lpd.

Write a daemon that you can talk to via Send/Receive. This
daemon should spawn lprc with no additional args, connected
with one or two pipes. If you need to kick lpd, send a message
to your daemon to start , which pipes "start "
to lprc. You can use a “reverse” pipe to get status messages
if needed.

Richard

Andrew Thomas wrote:

Previously, Greg Laird wrote in qdn.public.qnx4:
Hello Andrew,
I have looked at the example that you suggested. The solution of
using both lpsrvr and lpd seems complex to me. I have also not found
anything in the docs about writing to a /dev/spool device to
automatically spool a file (that doesn’t mean it’s not there).

I agree this seems complex, but it also makes a strange kind of
sense. lpd doesn’t offer a local /dev/ because it assumes you
will be printing using lpr. lpsrvr doesn’t offer TCP networked access
because it assumes you will be using QNX networking. If you hook the
/dev/ capability of lpsrvr to the TCP printing capability of
lpd, then you get the exact behaviour you are looking for. This is
consistent with the “UNIX Way” of concatenating simple specialized
applications in various ways to achieve complex behaviour. In this
case I don’t think that using two print spoolers will have any more
impact on stability than any other solution you are considering, and
it means you don’t have to write a line of code.

I was hoping to find an elegant method of letting lpd know that there
is a file to be printed (e.g. storing it in a directory and sending a
message to lpd, or some such thing).

Well, I would actually call anything but invoking lpr to be klugy.
You can safely kill lpd, copy a file into the appropriate spool
directory, create a “cf” file for it, and then restart lpd. I don’t
think that’s very efficient, though.

The system call to invoke lpr
seems sort of klugy to me (firing up both the shell & lpr),

The shell is almost definitely already in memory, so the startup is
pretty cheap, and uses very little extra memory. You have no real
choice but to call lpr, so that startup and memory are a foregone
conclusion. If you really don’t want to run the shell, use spawn() or
qnx_spawn(). At least you don’t have to fiddle with pipes.
Personally, I would write it to spawn() or system() a shell script,
and have the script call lpd. That way I could modify the printing
behaviour without recompiling my program. The difference in time and
memory is pretty minimal unless you are running pretty close to the
limit.

Maybe a file is stored in a directory and a signal gets sent to
lpd???

Not that I’m aware of. lpr creates a control file as well as a spool
file, and it’s reasonable to assume that you aren’t going to reproduce
the behaviour of lpr more reliably than lpr does. If you think you
can get away with a small subset of the lpr behaviour, the source is
available from RedHat, so you can see what you minimally need.

Good luck,
Andrew