home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / DOC / HOWTO / OTHER_FO / SGML / SMB_HOWT.GZ / SMB-HOWTO.sgml
Encoding:
SGML Document  |  1996-08-18  |  26.1 KB  |  771 lines

  1. <!doctype linuxdoc system>
  2.  
  3. <!-- This is the SMB HowTo for Linux and other UNIXs
  4. -->
  5.  
  6. <article>
  7.  
  8. <!-- Title information -->
  9.  
  10. <title>SMB HOWTO
  11. <author>David Wood, <htmlurl url="mailto:dwood@plugged.net.au"
  12.                   name="dwood@plugged.net.au">
  13. <date>v1.0, 10 August 1996
  14. <abstract>
  15. This is the SMB HOWTO.  This document describes how to use the Session Message Block (SMB) protocol, also called the NetBIOS or LanManager protocol, with Linux.
  16. </abstract>
  17.  
  18. <!-- Table of contents -->
  19. <toc>
  20.  
  21. <!-- Begin the document -->
  22.  
  23. <sect>Introduction
  24. <p>
  25. This is the SMB HOWTO.  This document describes how to use the Session Message Block (SMB) protocol, also called the NetBIOS or LanManager protocol, with Linux.
  26.  
  27. This document is maintained by David Wood (<htmlurl url="mailto:dwood@plugged.net.au" name="dwood@plugged.net.au">).  Additions, modifications or corrections may be mailed there for inclusion in the next release.
  28.  
  29. The SMB protocol is used by Microsoft Windows 3.11, NT and 95 to share disks and printers.  Using the Samba suite of tools by Andrew Tridgell, UNIX (including Linux) machines can share disk and printers with Windows hosts.
  30.  
  31. There are four things that one can do with Samba:
  32.  
  33. <enum>
  34. <item>Share a linux drive with Windows machines.
  35. <item>Share a Windows drive with linux machines.
  36. <item>Share a linux printer with Windows machines.
  37. <item>Share a Windows printer with linux machines.
  38. </enum>
  39.  
  40. All of these are covered in this document.
  41.  
  42. Disclaimer: The procedures and scripts either work for the author or have been reported to work by the people that provided them.  Different configurations may not work with the information given here.  If you encounter such a situation, you may e-mail the author with suggestions for improvement in this document, but the author guarantees nothing.  What did you expect?  The author is, after all, a consultant...
  43.  
  44.  
  45. <sect>Further Information
  46. <P>
  47. This HOWTO attempts to explain how to configure basic SMB file and print services on a linux machine.  Samba is a very complex and complete package.  There would be no point in attempting to duplicate all of the documentation for Samba here.  
  48.  
  49. For further information, please see the following documents:
  50. <itemize>
  51. <item>The Samba documentation, available as part of the Samba distribution.  The distribution is available at:
  52.     <url url="ftp://nimbus.anu.edu.au/pub/tridge/samba/"
  53.             name="ftp://nimbus.anu.edu.au/pub/tridge/samba/">
  54. <item>The linux Printing HOWTO.
  55. <item>The Print2Win Mini-HOWTO.
  56. </itemize>
  57.  
  58.  
  59. <sect>Installation
  60. <P>
  61. The latest source version of Samba is available from:
  62.  
  63.         <url url="ftp://nimbus.anu.edu.au/pub/tridge/samba/"
  64.             name="ftp://nimbus.anu.edu.au/pub/tridge/samba/">
  65.  
  66. However, if you have installed the Redhat distribution of linux, you have the option of installing it as a package.  Some other distributions also include the Samba binaries.
  67.  
  68. The following two daemons are required for the Samba package.  They are typically installed in /usr/sbin and run either on boot from the systems startup scripts or from inetd.  Example scripts are shown in <ref id="sec-daemons" name="Running the Daemons">.
  69.  
  70. <code>
  71.     smbd (The SMB daemon)
  72.     nmbd (Provides NetBIOS nameserver support to clients)
  73. </code>
  74.  
  75. Typically, the following Samba binaries are installed in /usr/bin, although the location is optional.
  76.  
  77. <code>
  78.     smbclient    (An SMB client for UNIX machines)
  79.     smbprint    (A script to print to a printer on an SMB host)
  80.     smbprint.sysv    (As above, but for SVR4 UNIX machines)
  81.     smbstatus    (Lists the cuurent SMB connections for the local host)
  82.     smbrun        (A 'glue' script to facilitate runnning applciations
  83.              on SMB hosts)
  84. </code>
  85.  
  86. Additionally, a script called 'print' is included with this HOWTO, which serves as a usefull front end to the smbprint script.
  87.  
  88. The Samba package is simple to install.  Simply retrieve the source from the location mentioned above, and read the file README in the distribution.  There is also a file called docs/INSTALL.txt in the distribution that provides a simple step-by-step set of instructions.
  89.  
  90. Following installation, place the daemons in /usr/sbin and the binaries in /usr/bin.  Install the man pages in /usr/local/man.  
  91.  
  92. When you made the Samba package, you would have specified in the Makefile the location for the configuration file, smb.conf.  This is generally in /etc, but you can put it anywhere you like.  For these directions, we will presume that you specified the location of the configuration file as /etc/smb.conf, the log file location as log file = /var/log/samba-log.%m and the lock directory as lock directory = /var/lock/samba.
  93.  
  94. Install the configuration file, smb.conf.  Go to the directory where Samba was built.  Look in the subdirectory examples/simple and read the file README.  Copy the file smb.conf found in that directory to /etc.  BE CAREFUL!  If you have a linux distribution that already has Samba installed, you may already have a Samba configuration file in /etc.  You should probably start with that one.
  95.  
  96. If you don't want to have your configuration file in /etc, put it wherever you want to, then put a symlink in /etc:
  97.  
  98. <code>
  99.     ln -s /path/to/smb.conf /etc/smb.conf
  100. </code>
  101.  
  102. <sect>Running The Daemons<label id="sec-daemons">
  103. <P>
  104. The two SMB daemons are /usr/sbin/smbd and /usr/sbin/nmbd.
  105.  
  106. You can run the Samba daemons from inetd or as stand-alone processes.  If you are configuring a permanent file server, they should be run from inetd so that they will be restarted if they die.  If you just want to use SMB services occasionally or to assist with systems administration, you can start them with an /etc/rc.d/init.d script or even by hand when you need them.
  107.  
  108. To run the daemons from inetd, place the following lines in the inetd configuration file, /etc/inetd.conf:
  109.  
  110. <tscreen><code>
  111.     # SAMBA NetBIOS services (for PC file and print sharing)
  112.     netbios-ssn stream tcp nowait root /usr/sbin/smbd smbd
  113.     netbios-ns dgram udp wait root /usr/sbin/nmbd nmbd
  114. </code></tscreen>
  115.  
  116. Then restart the inetd daemon by running the command:
  117.  
  118. <code>
  119.     kill -HUP 1
  120. </code>
  121.  
  122. To run the daemons from the system startup scripts, put the following script in file called /etc/rc.d/init.d/smb and symbolically link it to the files specified in the comments:
  123.  
  124. <tscreen><code>
  125.     #!/bin/sh
  126.  
  127.     #
  128.     # /etc/rc.d/init.d/smb - starts and stops SMB services.
  129.     #
  130.     # The following files should be synbolic links to this file:
  131.     # symlinks: /etc/rc.d/rc1.d/K35smb  (Kills SMB services on shutdown)
  132.     #           /etc/rc.d/rc3.d/S91smb  (Starts SMB services in multiuser mode)
  133.     #           /etc/rc.d/rc6.d/K35smb  (Kills SMB services on reboot)
  134.     #
  135.  
  136.     # Source function library.
  137.     . /etc/rc.d/init.d/functions
  138.  
  139.     # Source networking configuration.
  140.     . /etc/sysconfig/network
  141.  
  142.     # Check that networking is up.
  143.     [ ${NETWORKING} = "no" ] &ero;&ero; exit 0
  144.  
  145.     # See how we were called.
  146.     case "$1" in
  147.       start)
  148.         echo -n "Starting SMB services: "
  149.     daemon smbd -D     
  150.     daemon nmbd -D 
  151.     echo
  152.     touch /var/lock/subsys/smb
  153.     ;;
  154.       stop)
  155.     echo -n "Shutting down SMB services: "
  156.     killproc smbd
  157.     killproc nmbd
  158.     rm -f /var/lock/subsys/smb
  159.     echo ""
  160.     ;;
  161.       *)
  162.     echo "Usage: smb {start|stop}"
  163.     exit 1
  164.     esac
  165. </code></tscreen>
  166.  
  167.  
  168. <sect>General Configuration (/etc/smb.conf)
  169. <P>
  170. Samba configuration on a linux (or other UNIX machine) is controlled by a single file, /etc/smb.conf.  This file determines which system resources you want to share with the outside world and what restrictions you wish to place on them.  
  171.  
  172. Since the following sections will address sharing linux drives and printers with Windows machines, the smb.conf file shown in this section is as simple as you can get, just for introductory purposes.
  173.  
  174. Don't worry about the details, yet.  Later sections will introduce the major concepts.
  175.  
  176. Each section of the file starts with a section header such as [global], [homes], [printers], etc.  
  177.  
  178. The [global] section defines a few variables that Samba will use to define sharing for all resources.  
  179.  
  180. The [homes] section allows a remote users to access their (and only their) home directory on the local (linux) machine).  That is, if a Windows user trys to connect to this share from their Windows machines, they will be connected to their personal home directory.  Note that to do this, they must have an account on the linux box.
  181.  
  182. The sample smb.conf file below allows remote users to get to their home directories on the local machine and to write to a temporary directory.  For a Windows user to see these shares, the linux box has to be on the local network.  Then the user simply connects a network drive from the Windows File Manager or Windows Explorer.
  183.  
  184. Note that in the following sections, additional entries for this file will be given to allow more resources to be shared.
  185.  
  186. <tscreen><code>
  187. ; /etc/smb.conf
  188. ;
  189. ; Make sure and restart the server after making changes to this file, ex:
  190. ; /etc/rc.d/init.d/smb stop
  191. ; /etc/rc.d/init.d/smb start
  192.  
  193. [global]
  194. ; Uncomment this if you want a guest account
  195. ; guest account = nobody
  196.    log file = /var/log/samba-log.%m
  197.    lock directory = /var/lock/samba
  198.    share modes = yes
  199.  
  200. [homes]
  201.    comment = Home Directories
  202.    browseable = no
  203.    read only = no
  204.    create mode = 0750
  205.  
  206. [tmp]
  207.    comment = Temporary file space
  208.    path = /tmp
  209.    read only = no
  210.    public = yes
  211. </code></tscreen>
  212.  
  213.  
  214. <sect>Sharing A Linux Drive With Windows Machines
  215. <P>
  216. As shown in the simple smb.conf above, sharing linux drives with Windows users is easy.  However, like everything else with Samba, you can control things to a large degree.  Here are some examples:
  217.  
  218. To share a directory with the public, create a clone of the [tmp] section above by adding something like this to smb.conf:
  219.  
  220. <tscreen><code>
  221. [public]
  222.    comment = Public Stuff
  223.    path = /home/public
  224.    public = yes
  225.    writable = yes
  226.    printable = yes
  227. </code></tscreen>
  228.  
  229. To make the above directory readable by the public, but only writable by people in group staff, modify the entry like this:
  230.  
  231. <tscreen><code>
  232. [public]
  233.    comment = Public Stuff
  234.    path = /home/public
  235.    public = yes
  236.    writable = yes
  237.    printable = no
  238.    write list = @staff
  239. </code></tscreen>
  240.  
  241. For other tricks to play with drive shares, see the Samba documentation or man pages.
  242.  
  243.  
  244. <sect>Sharing A Windows Drive With Linux Machines
  245. <P>
  246. An SMB client program for UNIX machines is included with the Samba distribution.  It provides an ftp-like interface on the command line.  You can uyse this utility to transfer files between a Windows 'server' and a linux client.  
  247.  
  248. To see which shares are available on a given host, run:
  249.  
  250. <code>
  251.     /usr/sbin/smbclient -L host
  252. </code>
  253.  
  254. where 'host' is the name of the machine that you wish to view.  this will return a list of 'service' names - that is, names of drives or printers that it can share with you.  Unless the SMB server has no security configured, it will ask you for a password.  Get it the password for the 'guest' account or for your personal account on that machine.
  255.  
  256. For example:
  257.  
  258. <code>
  259.     smbclient -L zimmerman
  260. </code>
  261.  
  262. The output of this command should look something like this:
  263.  
  264. <tscreen><code>
  265. Server time is Sat Aug 10 15:58:27 1996
  266. Timezone is UTC+10.0
  267. Password: 
  268. Domain=[WORKGROUP] OS=[Windows NT 3.51] Server=[NT LAN Manager 3.51]
  269.  
  270. Server=[ZIMMERMAN] User=[] Workgroup=[WORKGROUP] Domain=[]
  271.  
  272.         Sharename      Type      Comment
  273.         ---------      ----      -------
  274.         ADMIN$         Disk      Remote Admin
  275.         public         Disk      Public 
  276.         C$             Disk      Default share
  277.         IPC$           IPC       Remote IPC
  278.         OReilly        Printer   OReilly
  279.         print$         Disk      Printer Drivers
  280.  
  281.  
  282. This machine has a browse list:
  283.  
  284.         Server               Comment
  285.         ---------            -------
  286.         HOPPER               Samba 1.9.15p8
  287.         KERNIGAN             Samba 1.9.15p8
  288.         LOVELACE             Samba 1.9.15p8
  289.         RITCHIE              Samba 1.9.15p8
  290.         ZIMMERMAN            
  291. </code></tscreen>
  292.  
  293. The browse list shows other SMB servers with resources to share on the network.
  294.  
  295. To use the client, run:
  296.  
  297. <code>
  298.     /usr/sbin/smbclient service <password>
  299. </code>
  300.  
  301. where 'service' is a machine and share name.  For example, if you are trying to reach a directory that has been shared as 'public' on a machine called zimmerman, the service would be called \\zimmerman\public.  However, due to shell restrictions, you will need to escape the backslashes, so you end up with something like this:
  302.  
  303. <code>
  304.     /usr/sbin/smbclient \\\\zimmerman\\public mypasswd
  305. </code>
  306.  
  307. where 'mypasswd' is the literal string of your password.
  308.  
  309. You will get the smbclient prompt:
  310.  
  311. <tscreen><code>
  312. Server time is Sat Aug 10 15:58:44 1996
  313. Timezone is UTC+10.0
  314. Domain=[WORKGROUP] OS=[Windows NT 3.51] Server=[NT LAN Manager 3.51]
  315. smb: \> 
  316. </code></tscreen>
  317.  
  318. Type 'h' to get help using smbclient:
  319.  
  320. <tscreen><code>
  321. smb: \> h
  322. ls             dir            lcd            cd             pwd            
  323. get            mget           put            mput           rename         
  324. more           mask           del            rm             mkdir          
  325. md             rmdir          rd             prompt         recurse        
  326. translate      lowercase      print          printmode      queue          
  327. cancel         stat           quit           q              exit           
  328. newer          archive        tar            blocksize      tarmode        
  329. setmode        help           ?              !              
  330. smb: \> 
  331. </code></tscreen>
  332.  
  333. If you can use ftp, you shouldn't need the man pages for smbclient.
  334.  
  335.  
  336. <sect>Sharing A Linux Printer With Windows Machines
  337. <P>
  338. To share a linux printer with Windows machines, you need to make certain that your printer is set up to work under linux.  If you can print from linux, setting up an SMB share of the printer is stright forward.
  339.  
  340. See the Printing HOWTO to set up local printing.
  341.  
  342. Since the author uses a printer connected to a Windows NT machine, this section should not be taken as definitive, but merely a suggestion.  Anyone with details to share, please send them to 
  343.        <htmlurl url="mailto:dwood@plugged.net.au"
  344.                   name="dwood@plugged.net.au">
  345. so this section can be completed.
  346.  
  347. Add printing configuration to your smb.conf:
  348.  
  349. <tscreen><code>
  350. [global]
  351.    printing = bsd
  352.    printcap name = /etc/printcap
  353.    load printers = yes
  354.    log file = /var/log/samba-log.%m
  355.    lock directory = /var/lock/samba
  356.  
  357. [printers]
  358.    comment = All Printers
  359.    security = server
  360.    path = /var/spool/lpd/lp
  361.    browseable = no
  362.    printable = yes
  363.    public = yes
  364.    writable = no
  365.    create mode = 0700
  366.  
  367. [ljet]
  368.    security = server
  369.    path = /var/spool/lpd/lp
  370.    printer name = lp
  371.    writable = yes
  372.    public = yes
  373.    printable = yes
  374.    print command = lpr -r -h -P %p %s
  375. </code></tscreen>
  376.  
  377. Make certain that the printer path (in this case under [ljet]) matches the spool directory in /etc/printcap!
  378.  
  379. NOTE:  There are some problems sharing printers on UNIX boxes with Windows NT machines using Samba.  One problem is with NT seeing the shared printer properly.  To fix this, see the notes in the Samba distribution in the file docs/WinNT.txt.  The other deals with password problems.  See the comments in the same file for an annoying gain of understanding and failure to fix the problem.
  380.  
  381.  
  382. <sect>Sharing A Windows Printer With Linux Machines
  383. <P>
  384. To share a printer on a Windows machine, you must do the following:
  385.  
  386. a) You must have the proper entries in /etc/printcap and they must correspond to the local directory structure (for the spool directory, etc)
  387.  
  388. b) You must have the script /usr/bin/smbprint.  This comes with the Samba source, but not with all Samba binary distributions.  A slightly modifed copy is discussed below.
  389.  
  390. c) If you want to convert ASCII files to Postscript, you must have nenscript, or its equivalent.  nenscript is a Postscript converter and is generally installed in /usr/bin.
  391.  
  392. d)  you may wish to make Samba printing easier by having an easy-to-use front end.  A simple perl script to handle ASCII, Postscript or created Postscript is given below.
  393.  
  394. The /etc/printcap entry below is for an HP 5MP printer on a Windows NT host.  The entries are as follows:
  395.  
  396. <code>
  397.     cm - comment
  398.     lp - device name to open for output
  399.     sd - the printer's spool directory (on the local machine)
  400.     af - the accounting file
  401.     mx - the maximum file size (zero is unlimited)
  402.     if - name of the input filter (script)
  403. </code>
  404.  
  405. For more information, see the Printing HOWTO or the man page for printcap.
  406.  
  407. <tscreen><code>
  408. # /etc/printcap
  409. #
  410. # //zimmerman/oreilly via smbprint
  411. #
  412. lp:\
  413.         :cm=HP 5MP Postscript OReilly on zimmerman:\
  414.         :lp=/dev/lp1:\
  415.         :sd=/var/spool/lpd/lp:\
  416.         :af=/var/spool/lpd/lp/acct:\
  417.         :mx#0:\
  418.         :if=/usr/bin/smbprint:
  419. </code></tscreen>
  420.  
  421. Make certain that the spool and accounting directories exist and are writable.  Ensure that the 'if' line holds the proper path to the smbprint script (given below) and make sure that the proper device is pointed to (the /dev speical file).
  422.  
  423. Next is the smbprint script itself.  It is usually placed in /usr/bin and is attributable to Andrew Tridgell, the person who created Samba as far as I know.  It comes with the Samba source distribution, but is absent from some binary distributions, so I have recreated it here.  
  424.  
  425. You may wish to look at this carefully.  There are some minor alterations that have shown themselves to be useful.
  426.  
  427. <tscreen><code>
  428. #!/bin/sh -x
  429.  
  430. # This script is an input filter for printcap printing on a unix machine. It
  431. # uses the smbclient program to print the file to the specified smb-based 
  432. # server and service.
  433. # For example you could have a printcap entry like this
  434. #
  435. # smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
  436. #
  437. # which would create a unix printer called "smb" that will print via this 
  438. # script. You will need to create the spool directory /usr/spool/smb with
  439. # appropriate permissions and ownerships for your system.
  440.  
  441. # Set these to the server and service you wish to print to 
  442. # In this example I have a WfWg PC called "lapland" that has a printer 
  443. # exported called "printer" with no password.
  444.  
  445. #
  446. # Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
  447. # so that the server, service, and password can be read from 
  448. # a /usr/var/spool/lpd/PRINTNAME/.config file.
  449. #
  450. # In order for this to work the /etc/printcap entry must include an 
  451. # accounting file (af=...):
  452. #
  453. #   cdcolour:\
  454. #    :cm=CD IBM Colorjet on 6th:\
  455. #    :sd=/var/spool/lpd/cdcolour:\
  456. #    :af=/var/spool/lpd/cdcolour/acct:\
  457. #    :if=/usr/local/etc/smbprint:\
  458. #    :mx=0:\
  459. #    :lp=/dev/null:
  460. #
  461. # The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
  462. #   server=PC_SERVER
  463. #   service=PR_SHARENAME
  464. #   password="password"
  465. #
  466. # E.g.
  467. #   server=PAULS_PC
  468. #   service=CJET_371
  469. #   password=""
  470.  
  471. #
  472. # Debugging log file, change to /dev/null if you like.
  473. #
  474. logfile=/tmp/smb-print.log
  475. # logfile=/dev/null
  476.  
  477.  
  478. #
  479. # The last parameter to the filter is the accounting file name.
  480. #
  481. spool_dir=/var/spool/lpd/lp
  482. config_file=$spool_dir/.config
  483.  
  484. # Should read the following variables set in the config file:
  485. #   server
  486. #   service
  487. #   password
  488. #   user
  489. eval `cat $config_file`
  490.  
  491. #
  492. # Some debugging help, change the >> to > if you want to same space.
  493. #
  494. echo "server $server, service $service" >> $logfile
  495.  
  496. (
  497. # NOTE You may wish to add the line `echo translate' if you want automatic
  498. # CR/LF translation when printing.
  499.         echo translate
  500.     echo "print -"
  501.     cat
  502. ) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $user -N -P >> $logfile
  503. </code></tscreen>
  504.  
  505. Most linux distributions come with nenscript for converting ASCII documents to Postscript.  The following perl script makes life easier be providing a simple interface to linux printing via smbprint.
  506.  
  507. <code>
  508. Usage: print [-a|c|p] <filename>
  509.        -a prints <filename> as ASCII
  510.        -c prints <filename> formatted as source code
  511.        -p prints <filename> as Postscript
  512.         If no switch is given, print attempts to
  513.         guess the file type and print appropriately.
  514. </code>
  515.  
  516. Using smbprint to print ASCII files tends to truncate long lines.  This script breaks long lines on whitespace (instead of in the middle of a word), if possible.
  517.  
  518. The source code formatting is done with nenscript.  It takes an ASCII file and foramts it in 2 columns with a fancy header (date, filename, etc).  It also numbers the lines.  Using this as an example, other types of formatting can be accomplished.
  519.  
  520. Postscript documents are already properly formatted, so they pass through directly.
  521.  
  522. <tscreen><code>
  523. #!/usr/bin/perl
  524.  
  525. # Script:   print
  526. # Authors:  Brad Marshall, David Wood
  527. #        Plugged In Communications
  528. # Date:     960808
  529. #
  530. # Script to print to oreilly which is currently on zimmerman
  531. # Purpose:  Takes files of various types as arguments and 
  532. # processes them appropriately for piping to a Samba print script.
  533. #
  534. # Currently supported file types:
  535. # ASCII      - ensures that lines longer than $line_length characters wrap on
  536. #              whitespace.
  537. # Postscript - Takes no action.
  538. # Code       - Formats in Postscript (using nenscript) to display
  539. #              properly (landscape, font, etc).
  540. #
  541.  
  542. # Set the maximum allowable length for each line of ASCII text.
  543. $line_length = 76;
  544.  
  545. # Set the path and name of the Samba print script
  546. $print_prog = "/usr/bin/smbprint";
  547.  
  548. # Set the path and name to nenscript (the ASCII-->Postscript converter)
  549. $nenscript = "/usr/bin/nenscript";
  550.  
  551. unless ( -f $print_prog ) {
  552.     die "Can't find $print_prog!";
  553. }
  554. unless ( -f $nenscript ) {
  555.     die "Can't find $nenscript!";
  556. }
  557.  
  558. &ero;ParseCmdLine(@ARGV);
  559.  
  560. # DBG
  561. print "filetype is $filetype\n";
  562.  
  563. if ($filetype eq "ASCII") {
  564.     &ero;wrap($line_length);
  565. } elsif ($filetype eq "code") {
  566.     &ero;codeformat;
  567. } elsif ($filetype eq "ps") {
  568.     &ero;createarray;
  569. } else {
  570.     print "Sorry..no known file type.\n";
  571.     exit 0;
  572. }
  573. # Pipe the array to smbprint
  574. open(PRINTER, "|$print_prog") || die "Can't open $print_prog: $!\n";
  575. foreach $line (@newlines) {
  576.     print PRINTER $line;
  577. }
  578. # Send an extra linefeed in case a file has an incomplete last line.
  579. print PRINTER "\n";
  580. close(PRINTER);
  581. print "Completed\n";
  582. exit 0;
  583.  
  584. # --------------------------------------------------- #
  585. #        Everything below here is a subroutine        #
  586. # --------------------------------------------------- #
  587.  
  588. sub ParseCmdLine {
  589.     # Parses the command line, finding out what file type the file is
  590.  
  591.     # Gets $arg and $file to be the arguments (if the exists)
  592.     # and the filename
  593.     if ($#_ < 0) {
  594.         &ero;usage;
  595.     }
  596.     # DBG
  597. #    foreach $element (@_) {
  598. #        print "*$element* \n";
  599. #    }
  600.  
  601.     $arg = shift(@_);
  602.     if ($arg =~ /\-./) {
  603.         $cmd = $arg;
  604.     # DBG
  605. #    print "\$cmd found.\n";
  606.  
  607.         $file = shift(@_);
  608.     } else {
  609.         $file = $arg;
  610.     }
  611.     
  612.     # Defining the file type
  613.     unless ($cmd) {
  614.         # We have no arguments
  615.  
  616.         if ($file =~ /\.ps$/) {
  617.             $filetype = "ps";
  618.         } elsif ($file =~ /\.java$|\.c$|\.h$|\.pl$|\.sh$|\.csh$|\.m4$|\.inc$|\.html$|\.htm$/) {
  619.             $filetype = "code";
  620.         } else {
  621.             $filetype = "ASCII";
  622.         }
  623.  
  624.         # Process $file for what type is it and return $filetype 
  625.     } else {
  626.         # We have what type it is in $arg
  627.         if ($cmd =~ /^-p$/) {
  628.             $filetype = "ps";
  629.         } elsif ($cmd =~ /^-c$/) {
  630.             $filetype = "code";
  631.         } elsif ($cmd =~ /^-a$/) {
  632.             $filetype = "ASCII"
  633.         }
  634.     }
  635. }
  636.  
  637. sub usage {
  638.     print "
  639. Usage: print [-a|c|p] <filename>
  640.        -a prints <filename> as ASCII
  641.        -c prints <filename> formatted as source code
  642.        -p prints <filename> as Postscript
  643.         If no switch is given, print attempts to
  644.         guess the file type and print appropriately.\n
  645. ";
  646.     exit(0);
  647. }
  648.  
  649. sub wrap {
  650.     # Create an array of file lines, where each line is < the 
  651.     # number of characters specified, and wrapped only on whitespace
  652.  
  653.     # Get the number of characters to limit the line to.
  654.     $limit = pop(@_);
  655.  
  656.     # DBG
  657.     #print "Entering subroutine wrap\n";
  658.     #print "The line length limit is $limit\n";
  659.  
  660.     # Read in the file, parse and put into an array.
  661.     open(FILE, "<$file") || die "Can't open $file: $!\n";
  662.     while(<FILE>) {
  663.         $line = $_;
  664.         
  665.         # DBG
  666.         #print "The line is:\n$line\n";
  667.  
  668.         # Wrap the line if it is over the limit.
  669.         while ( length($line) > $limit ) {
  670.             
  671.             # DBG
  672.             #print "Wrapping...";
  673.  
  674.             # Get the first $limit +1 characters.
  675.             $part = substr($line,0,$limit +1);
  676.  
  677.             # DBG
  678.             #print "The partial line is:\n$part\n";
  679.  
  680.             # Check to see if the last character is a space.
  681.             $last_char = substr($part,-1, 1);
  682.             if ( " " eq $last_char ) {
  683.                 # If it is, print the rest.
  684.  
  685.                 # DBG
  686.                 #print "The last character was a space\n";
  687.  
  688.                 substr($line,0,$limit + 1) = "";
  689.                 substr($part,-1,1) = "";
  690.                 push(@newlines,"$part\n");
  691.             } else {
  692.                  # If it is not, find the last space in the 
  693.                  # sub-line and print up to there.
  694.  
  695.                 # DBG
  696.                 #print "The last character was not a space\n";
  697.  
  698.                  # Remove the character past $limit
  699.                  substr($part,-1,1) = "";
  700.                  # Reverse the line to make it easy to find
  701.                  # the last space.
  702.                  $revpart = reverse($part);
  703.                  $index = index($revpart," ");
  704.                  if ( $index > 0 ) {
  705.                    substr($line,0,$limit-$index) = "";
  706.                    push(@newlines,substr($part,0,$limit-$index) 
  707.                        . "\n");
  708.                  } else {
  709.                    # There was no space in the line, so
  710.                    # print it up to $limit.
  711.                    substr($line,0,$limit) = "";
  712.                    push(@newlines,substr($part,0,$limit) 
  713.                        . "\n");
  714.                  }
  715.             }
  716.         }
  717.         push(@newlines,$line);
  718.     }
  719.     close(FILE);
  720. }
  721.  
  722. sub codeformat {
  723.     # Call subroutine wrap then filter through nenscript
  724.     &ero;wrap($line_length);
  725.     
  726.     # Pipe the results through nenscript to create a Postscript
  727.     # file that adheres to some decent format for printing
  728.     # source code (landscape, Courier font, line numbers).
  729.     # Print this to a temporary file first.
  730.     $tmpfile = "/tmp/nenscript$$";
  731.     open(FILE, "|$nenscript -2G -i$file -N -p$tmpfile -r") || 
  732.         die "Can't open nenscript: $!\n";
  733.     foreach $line (@newlines) {
  734.         print FILE $line;
  735.     }
  736.     close(FILE);
  737.     
  738.     # Read the temporary file back into an array so it can be
  739.     # passed to the Samba print script.
  740.     @newlines = ("");
  741.     open(FILE, "<$tmpfile") || die "Can't open $file: $!\n";
  742.     while(<FILE>) {
  743.         push(@newlines,$_);
  744.     }
  745.     close(FILE);
  746.     system("rm $tmpfile");
  747. }
  748.  
  749. sub createarray {
  750.     # Create the array for postscript
  751.     open(FILE, "<$file") || die "Can't open $file: $!\n";
  752.     while(<FILE>) {
  753.         push(@newlines,$_);
  754.     }
  755.     close(FILE);
  756. }
  757. </code></tscreen>
  758.  
  759.  
  760. <sect>Copyright
  761. <P>
  762. This HOWTO is copyright 1996 by David Wood.  It may be reproduced in any form and freely distributed as long as the file stays intact, including this statement.
  763.  
  764.  
  765. <sect>Acknowledgements
  766. <P>
  767. As soon as you mail me with suggestions, I'll acknowledge you here in the next release.
  768.  
  769. </article>
  770.