by Alexander Panasyuk (
).
Version 6.0.0
(FYI, analogous problem for SunOS 4.x.x can be solved using APSfilter package).
How to disable banner page? How to enable remote print requests under Solaris 2.5? Why is my postscript document still being printed as a text? I am getting error diagnostics from printer daemon which looks like following: "ld.so.1: /opt/bin/gs: fatal: libXext.so.0: can't open file: errno=2". What's up? Can I pass command line options to my filter? Why does not "stcolor" work with my Epson Stylus? Where is this "stcolor" anyway? What about ULTRAstation? Filtering does not work for remote printer, what can I do (Solaris 2.6 to Windows NT Printing) ? There are no error messages, but no printer output either... I am having trouble printing plain text files. Notes on Solaris 8.
This HOW-TO primarily concerns locally connected and networked printers. Stephen Thamel has sent me a workaround to extend this solution on remote printers as well. I have put his information here.
These instructions are still being occasionally updated and corrected (see "Important changes in this document from previous versions" below), you can find latest revision at SetGSprinter4Solaris.html.
I am not taking any responsibility for what may happen to your printer, system, state of mind or wallet if you follow these instructions. They worked for me, though.
1) Write filter description file and put it into /etc/lp/fd directory. Name it whatever you want, e.g. "stylus.fd". Content may be like this:
# Beginning of the file - this is just a commentInstead of "ESC" for "Output types" you can use any word which you believe describes the language your printer understands. Example above was used by me for Epson Stylus which understands Epson ESC-codes language. I guess "PCL" would be proper for HP's. What particular word does not really matter as long as you use it consistently. Don't use types already defined in the system, like "PS","postscript","simple" or "postdown". As a "Command:" you specify whatever is required to convert postscript to this language. For LaserJets it may look like following:
Input types: postscript
Output types: ESC
Printer types: any
Printers: any
Filter type: fast
Command: /opt/bin/gs -q -dSAFER -dNOPAUSE -dMicroweave -sDEVICE=stcolor -r360x360 -sOutputFile=/dev/bpp0 stcolor.ps -
# End of the file
Command: /opt/bin/gs -q -dSAFER -dNOPAUSE -sDEVICE=laserjet -r300 -sOutputFile=/dev/bpp0 -See Ghostscript documentation for options suitable for your printer. You should use real name of the device your printer is connected to instead of "/dev/bpp0" if different.
You should use full path names for executables.
1a) Set file ownership and permissions similar to the "standard" filters in the directory, for my system it was "chown lp:lp stylus.fd; chmod 664 stylus.fd"
2) Register filter with printing system.
/usr/sbin/lpfilter -f stylus -F /etc/lp/fd/stylus.fd
Here "stylus.fd" is the name of the file you have created in 1), "stylus" is the name of the filter which can be whatever you like (just watch for names already defined - "lpfilter -f all -l" should print them).
3) Register printer
/usr/sbin/lpadmin -p your_printer_name -v /dev/null -I ESC
"your_printer_name" here is your choice - you will be using it with "lp" command. Use "Output type" from filter description file (see 1) instead of "ESC" if different. Users of Solaris (x86) may want to add -o stty="-opost" to the list of options to avoid CR/LF to CR translation in the STREAM module.
4) I had to reset my printer port device to be owned by "lp" with permission "666", you may have to as well. Now run
enable your_printer_name
accept your_printer_name
and you are in business ( hopefully ).
Nevertheless you may be more lucky, or modern versions of Solaris
may
make it easier. To use correct approach in the list of instructions
above
change following:
1) In filter "Command:" line change "-sOutputFile=/dev/bpp0"
to "-sOutputFile=-". Change "Filter type:" from
"fast"
to "slow".
3) In lpadmin command line change "-v /dev/null"
to "-v /dev/bpp0" or whatever port your printer is connected
to.
Install Ghostscript and find proper options to run your printer. Install printer with
lpadmin -p <printer name> -i /usr/lib/lp/model/netstandard
-v
/dev/null \
-o dest=<printer network address> -I
postscript
Then edit /etc/lp/interfaces/<printer name> file and replace whole if-statement
if [ -z "${FILTER}" ]
then
#####
#
# If no filter is being
used, we use netpr to push the
# file to the printer.
# (QUOTES ARE IMPORTANT!)
#####
....
fi
with
FILTER="/path_to_gs/gs -q -dSAFER -dNOPAUSE <options to run your printer> -sOutputFile=- -"
Then run
enable your_printer_name
accept your_printer_name
That's it.
a) run "lpadmin -p your_printer_name -o nobanner". This would allow users to suppress banner by running "lp" with "-o nobanner" option, but it will still be printed by default.
b) Edit "/etc/lp/interfaces/your_printer_name" file (it is created by "lpadmin" command in 3). Find line which says
nobanner="no"
and change it to ... guess what ...
nobanner="yes".
(!!!WARNING!!! Following sequence of commands is retyped from Answerbook for Solaris version 2.5. It worked for me with Solaris 2.5.1. There is no guaranty that it would work with any other version of Solaris. Casper Dik has informed me that all this stuff is not necessary for Solaris 2.6 where remote printing is done through inetd.)
sacadm -a -p tcp -t listen -c "/usr/lib/saf/listen tcp" \After magic had worked "pmadm -l" should return something closely resembling following (there may be more lines, but these should be present):
-v `nlsadmin -V` -n 999
pmadm -a -p tcp -s lp -i root -m `nlsadmin -o /var/spool/lp/fifos/listenS5` \
-v `nlsadmin -V`
u_addr=`lpsystem -A`
pmadm -a -p tcp -s lpd -i root \
-m `nlsadmin -o /var/spool/lp/fifos/listenBSD -A "\\x${u_addr}"` \
-v `nlsadmin -V`
new_addr=`lpsystem -A | cut -b1-4`
tail=`lpsystem -A | awk '{pos = index($0, "0203")+4
print substr($0, pos, length($0)-pos+1)}'`
new_addr=`echo ${new_addr}0ACE${tail}`
pmadm -a -p tcp -s 0 -i root \ -m `nlsadmin -c /usr/lib/saf/nlps_server -A \
"\\x${new_addr}"` -v `nlsadmin -V`
PMTAG PMTYPE SVCTAG FLGS ID <PMSPECIFIC>"sacadm -l" should return in particular something like this:
tcp listen lp - root - - p - /var/spool/lp/fifos/listenS5 #
tcp listen lpd - root \x00020203000000000000000000000000 - p - /var/spool/lp/fifos/listenBSD #
tcp listen 0 - root \x00020ACE000000000000000000000000 - c - /usr/lib/saf/nlps_server #
PMTAG PMTYPE FLGS RCNT STATUS COMMANDNow there is a question about permissions for remote requests. If you don't care about restricting access to your printer edit "/etc/lp/Systems" file and uncomment "+:x:-:s5:-:n:10:-:-:Allow all connections" line if it is commented out ; you may want to read relevant information in the same file.
tcp listen - 999 ENABLED /usr/lib/saf/listen tcp #
If your luck has hold you should be all set by now.
1) Locate necessary libraries (libXext.so.0 in the example above). If Ghostscript works fine from your shell prompt then enter command "ldd full-path-to-gs-file" (e.g. "ldd /opt/bin/gs") and it will print out locations of all shared libraries "gs" uses (usually libXext.so.0 is located in /usr/openwin/lib) . Then unset environment variable LD_LIBRARY_PATH (e.g. "unsetenv LD_LIBRARY_PATH" for C-shell) and run "ldd full-path-to-gs-file" again. For all "not found" libraries note the directories where they are located comparing output with previous "ldd" run.
2) What you do next depends on how many directories should be included in the path. If it is only one prepend program call in filter description file "Command:" line with LD_LIBRARY_PATH=directory-not-found-libraries-are-located-in statement. In our case the line in the filter description file may look like this:
Command: LD_LIBRARY_PATH=/usr/openwin/lib /opt/bin/gs -q -dSAFER ...
You can not specify several directories this way because the format of LD_LIBRARY_PATH variable (directories are separated with colons) conflicts with format of some internal printing subsystem database files. You have to write a shell script in this case.
NOTE: if you are compiling Ghostscript yourself you may use -R compiler option to record necessary directory information into executable, so it does not have to rely on LD_LIBRARY_PATH at all.
"Perhaps it's interesting to also supply information on how to pass parameters to the filter script. This can be done using modes in the filter definition:
Options: MODES fast = -f
This example passes the "-f" option to your interface script if you invoke lp like this:
lp -y fast
You can use this to have one queue for several types of output; I use it for fast (360x360 dpi; @st600pl.up), normal (720x720dpi) and photo (1440x720 @st600ih.upp) on my Stylus Color 600."
NOTE: As Dr. David Kirkby found out it was not so straightforward to use this approach without writing a special interface script. Problem here is that option gets attached to the END of command line, so in case of ghostscript command it would appear after input file specification ("-" in case of standard input). Ghostscript does not like this and would not process such an option. One solution is to write interface script which would put option in correct place on command line.
1.Install LPDSVC on Windows NT and apply the "SimlatePassThrough" mod as described in Q168457
2.Install in standard locations GhostScript 5.10 or later for Solaris. Binaries are probably available.
3.On Solaris, create the following filter as (/etc/lp/fd/PStoPCL.fd):
Input types: postscript
Output types: PCL
Printer types: any
Printers: any
Filter type: slow
Command: /usr/local/bin/gs -q -dSAFER -dNOPAUSE -sDEVICE
-sDEVICE=laserjet
-r300 -sOutputFile=\|'lp -d ibm4019remote -' -
4. Assign ownership and permissions to this filters, otherwise the daemon might not be able to access it.
chown lp:lp /etc/lp/fd/PStoPCL.fd; chmod 664 /etc/lp/fd/PStoPCL.fd
5. Register this filter with the printing system.
/usr/sbin/lpfilter -f PStoPCL -F /etc/lp/fd/PStoPCL.fd
6. Verify the full filter has been parsed. It should end up at the bottom of the following output:
/usr/sbin/lpfilter -f all -l
7. Register the remote printer. The -s option is where the
server
ip and
queue name are supplied. Also, the remote printer can process
ascii text
without filtering, so set its content-type to simple.
lpadmin -p ibm4019remote -s 100.100.100.5!IBM4019Unix -I simple
8. Register the local printer and assign the local printer as the system default. Make sure the local printer is assigned a content-type of PCL so the filter will be applied.
lpadmin -p ibm4019local -v /dev/null -I PCL
lpadmin -d ibm4019local
9. Allow the local queue to accept jobs and enable the local queue to output. Solaris may have already performed these actions in the step above.
enable ibm4019local
accept ibm4019local
"
NOTE (by Andy Robertson): "One minor suggestion
for Stephen W. Thamel's solution in your "Solaris 2.6 to Windows NT
Printing"
section. In Step 3 the filter definition hardwires the remote printer
name,
but uses a filter name and "Output type" which reflects the
actual
type e.g. PStoPCL.fd and PCL. This is okay if there's only one remote
printer
of this type, but there could be more than one PCL printer on your
network.
A clearer approach might be to derive each filter name and its output
type
from the unique printer name. Just a thought."
Another NOTE (by Sumit Shah):
Problem: When a user submits a job to the queue
the job will print as expected, but will remain in the
queue.
When I run lpq -P<printer> it will list the jobs with
the following
warning:
Warning: hpofficelocal is down: new printer
The printer itself is connected to an NT box.
Solution:I managed to fix the problem by enabling the printer,
but not with the enable listed in /usr/bin,
but the one in: /usr/lib/lp/local.
Solution by Casper Dik:
"There's an easy trick in Solaris 2.6 to make a remote (BSD) printer appear as a local printer and have local filtering.
Simply define the printer as a local printer, but use the "netstandard" script. The queue will act as a local printer, but the output phase will write to the networked printer instead. But make sure you define the input types correctly.
There are two ways to have a remote printer: one is defining it as a
remote printer in /etc/printers.conf, but the other is defining a local
printer and sending output through netstandard. With the latter
method,
a netstandard printer can be used for local filtering."
/usr/sbin/lpadmin -p different_name -v
device_your_printer_is_connected_to
\
-I simple
It may work or may not, because printing system will filter your file, possibly removing CRs etc. and producing ugly printout. Another approach is to activate "plain text (simple) to postscript" filter provided with Solaris. Just run as a root:
/usr/sbin/lpfilter -f postprint -F /etc/lp/fd/postprint.fd
Conversion to and from postscript will suck up some CPU, but you don't have to specify second printer name this way.