home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit v2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Unix / HOWTOs / SMB-HOWT < prev    next >
Text File  |  1999-11-04  |  32KB  |  866 lines

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