SMB HOWTO
                                       
作者: David Wood, [1]dwood@plugged.net.au
译者: J.S. Lin, [2]r6921068@ms.cc.ntu.edu.tw

   v1.0, 10 August 1996
     _________________________________________________________________
   
   这是 SMB HOWTO {如何使用 SMB}. 这文件描述在 Linux 上如何使用 Session
   Message Block (SMB) protocol{协定}, 也叫做 NetBIOS 或 LanManager
   protocol.
     _________________________________________________________________
   
1. 介绍

2. 进一步资讯

3. 安装

4. 执行这两个 daemon

5. 一般组态设定 (/etc/smb.conf)

6. 分享 Linux 磁碟给 Windows 机器

7. 分享 Windows 磁碟给 Linux 机器

8. 分享 Linux 印表机给 Windows 机器

9. 分享 Windows 印表机给 Linux 机器

10. 版权

11. 感激
     _________________________________________________________________
   
1. 介绍

   这是 SMB HOWTO {如何使用 SMB} . 这文件描述在 Linux 上如何使用 Session
   Message Block (SMB) protocol, 也叫做 NetBIOS 或 LanManager protocol.
   
   本文件的维护者是 David Wood ( [3]dwood@plugged.net.au). 再者,修改或修正
   可以寄到那,以便下一版包涵进去.
   
   SMB protocol 被使用在 Microsoft Windows 3.11, NT 和 95 用来分享磁碟及印
   机. 使用 Andrew Tridgell 所做的 Samba 工具套件, UNIX (包含 Linux) 机器
   能分享磁碟与印表机给 Windows 主机.
   
   吾人使用 Samba 有四样东西可以做:
   
    1. 分享 linux 磁碟给 Windows 机器.
    2. 分享 Windows 磁碟给 linux 机器.
    3. 分享 linux 印表机给 Windows 机器.
    4. 分享 Windows 印表机给 linux 机器.
       
   这些东西都已包含在本文件中.
   
   Disclaimer: procedures 和 script 要嘛对作者是可以正常运作的,或要嘛由那
   些(procedures和script)的提供者报告可以正常运作. 以在这□的资讯做不同的
   设定可能会不能正常运作.如果你遭遇类似的困境,你可以 e-mail 给作者,提出建
   议来改进本文件, 但作者并不作任何保证.你预期什麽呢? 作者毕竟只是个顾
   问.....
   
2. 进一步资讯

   这个 HOWTO 设法去解释如何设定基本的 SMB档以及列印服务在 linux 机器上.
   Samba 是个非常复杂且完整的包装. 在这个地方没有要设法去复制所有的 Samba
   文件.
   
   进一步资讯,请看以下文件:
     * Samba 文件, 可取得於 Samba 发行套件{distribution}的部分. 此发行套件
       可取得在: [4]ftp://nimbus.anu.edu.au/pub/tridge/samba/
     * The linux Printing HOWTO.
     * The Print2Win Mini-HOWTO.
       
3. 安装

   最新 Samba 的原始程式可以取得自:
   
   [5]ftp://nimbus.anu.edu.au/pub/tridge/samba/
   
   然而,如果已安装 linux 的 Redhat 版本,你可以使用软体套件{package} 来安装
   它.有些其他版本也包含 Samba 的binaries{二元档程式}.
   
   以下两个 daemon{管理精灵} 对 Samba 软体套件 是必要的. 它们一般是被安装
   在 /usr/sbin ,而可在开机时,从系统起动的 scripts或inetd来执行. script的
   例子被展示在 [6]执行 Daemons.
     _________________________________________________________________
   
        smbd (The SMB daemon)
        nmbd (提供 NetBIOS nameserver 的支援给 clients)
     _________________________________________________________________
   
   一般而言,以下的 Samba 的 binaries 被安装在 /usr/bin, 虽然说它的位置是可
   选择性.
     _________________________________________________________________
   
        smbclient       (一种供给 UNIX 机器用的 SMB  client{程式})
        smbprint        (一种 script 用在列印於 SMB 主机{host}上的列表机)
        smbprint.sysv   (同上, 但是提供给 SVR4 UNIX 机器用的)
        smbstatus       (列出对当地主机之目前 SMB 连结情况)
        smbrun          (一种 'glue' script 用来简易地执行应用程式於 SMB 主机)
     _________________________________________________________________
   
   再者,一种叫 'print' 的 script 被包函在本 HOWTO 之中, 其用来当作一种有用
   的 front end{前端介面} 给 smbprint script用.
   
   Samba 软体套件是简易安装的.简单地从上述的位址取得原始码, 且阅读在发行套
   件中的 README 档案. 在发行套件中也有一个 docs/INSTALL.txt 档提供一个简
   单的逐步安装指示.
   
   接著安装後, 把 daemons 放到 /usr/sbin 而 binaries 放到 /usr/bin. 而
   man pages{手册页} 摆在 /usr/local/man.
   
   当你在做 Samba 软体套件, 你在 Makefile 中会有记载组态档,smb.conf,的位
   置. 这一般是在 /etc下, 但可以把它摆到你喜欢摆的任意位置. 对於这些使用方
   法{directions}, 我们将假设你记载组载档位置成 /etc/smb.conf, log 档位置
   为 log file = /var/log/samba-log.%m ,而 lock 目录为 lock directory =
   /var/lock/samba.
   
   安装组态{configuration}档, smb.conf. 去 Samba 所在的的目录. 看一下在其
   子目录 example/simple 而且读一下 README 档. 复制在那个目录下的
   smb.conf 档到 /etc 下. 注意! 如果你有一 linux 发行套件已安装好 Samba,
   你也许已有 Samba 组态档在 /etc 下. 或许你应该从那个档开始.
   
   如果你不想把组态档放在 /etc 目录下,可以把它摆在你想要摆的地方,然後在
   /etc 下做一下 symlink{符号连结}:
     _________________________________________________________________
   
        ln -s /path/to/smb.conf /etc/smb.conf
     _________________________________________________________________
   
4. 执行这两个 daemon

   这两个 daemon 是 /usr/sbin/smbd 和 /usr/sbin/nmbd.
   
   你可以执行 Samba daemon 从 inetd 或当成单独的程序. 如果你正设定一个永久
   档案伺服器,你应该从 inetd 来执行,所以如果他们死掉,那将重新开始.如果你只
   是偶尔想要使用 SMB 伺服器,或者用系统管理来辅助,当你需要时,你可以藉由使
   用 /etc/rc.d/init.d script,或甚至直接手动的.
   
   要从 inetd 来执行 daemon , 请放以下几行在 inetd 组态档,
   /etc/inetd.conf:
       ______________________________________________________________
     
    # SAMBA NetBIOS services (for PC file and print sharing)
    netbios-ssn stream tcp nowait root /usr/sbin/smbd smbd
    netbios-ns dgram udp wait root /usr/sbin/nmbd nmbd
       ______________________________________________________________
     
   然後下指令以便重新启动 inetd daemon :
     _________________________________________________________________
   
    kill -HUP 1
     _________________________________________________________________
   
   要从系统启动的 script 来执行 daemon, 请把以下的 script 置於一个叫做
   /etc/rc.d/init.d/smb 档, 而且 symbolically link 到注释{comments}所说明
   的档案:
       ______________________________________________________________
     
    #!/bin/sh

    #
    # /etc/rc.d/init.d/smb - starts and stops SMB services.
    #
    # The following files should be synbolic links to this file:
    # symlinks: /etc/rc.d/rc1.d/K35smb  (Kills SMB services on shutdown)
    #           /etc/rc.d/rc3.d/S91smb  (Starts SMB services in multiuser mode)
    #           /etc/rc.d/rc6.d/K35smb  (Kills SMB services on reboot)
    #

    # Source function library.
    . /etc/rc.d/init.d/functions

    # Source networking configuration.
    . /etc/sysconfig/network

    # Check that networking is up.
    [ ${NETWORKING} = "no" ] && exit 0

    # See how we were called.
    case "$1" in
      start)
        echo -n "Starting SMB services: "
        daemon smbd -D
        daemon nmbd -D
        echo
        touch /var/lock/subsys/smb
        ;;
      stop)
        echo -n "Shutting down SMB services: "
        killproc smbd
        killproc nmbd
        rm -f /var/lock/subsys/smb
        echo ""
        ;;
      *)
        echo "Usage: smb {start|stop}"
        exit 1
    esac
       ______________________________________________________________
     
5. 一般组态设定 (/etc/smb.conf)

   在 linux (或其他 UNIX机器)上的 Samba 组态设定是被单一档案,
   /etc/smb.conf ,所控制. 这个档决定你想要哪个系统资源分享给外面世界以及你
   想对他们做什麽限制.
   
   因为以下章节将会处理分享 linux 磁碟与印表机给 Windows 机器, 本小节所展
   示的 smb.conf 档尽量是你所能取得较简单的, 它只是以介绍性为目的.
   
   目前还不要担心细节部分. 後面的章节将会介绍主要的概念.
   
   在档案中的每的段落{section}会有个段落标头开始, 其标头像是 [global],
   [homes], [printers] 等等.
   
   [global] 段落定义一些变数, 而 Samba 将用来定义於所有资源之分享.
   
   [homes] 段落允许远端使用者来存取在当地(linux)机器上之他们的(且只有他们
   的) home directories{家目录}. 也就是, 如果一个 Windows 使用者从他们的
   Windows 机器要设法连接到这个分享, 他们将是连接到他们自己个人的 home
   directiory. 要做这样事情,所要注意的是,他们必须在linux box上有个帐号.
   
   以下的 smb.conf 档案样本允许远端使用者来用当地机器上他们的 home
   directories 而且写到一个暂存的目录. 对一个 Windows 使用者,要想看到这些
   分享, linux box 必须是在区域网路{local network}内. 然後,使用者简单地从
   Windows File Manager 或 Windows Explorer 连接到网路磁碟.
   
   在以下段落要注意的是, 对这个档之额外项目将会用来允许更多资源被分享.
       ______________________________________________________________
     
; /etc/smb.conf
;
; Make sure and restart the server after making changes to this file, ex:
; /etc/rc.d/init.d/smb stop
; /etc/rc.d/init.d/smb start

[global]
; Uncomment this if you want a guest account
; guest account = nobody
   log file = /var/log/samba-log.%m
   lock directory = /var/lock/samba
   share modes = yes

[homes]
   comment = Home Directories
   browseable = no
   read only = no
   create mode = 0750

[tmp]
   comment = Temporary file space
   path = /tmp
   read only = no
   public = yes
       ______________________________________________________________
     
6. 分享 Linux 磁碟给 Windows 机器

   以上所展示的 smb.conf 样本档, 分享 linux 磁碟给 Windows 使用者是很容易
   的. 然而, 像 Samba 其他的东西, 你可以控制到很大的程度. 以下有些例子 :
   
   为了分享目录给大家使用, 就建立个类似上述 [tmp] 段落, 亦即加入像这个的东
   西到 smb.conf:
       ______________________________________________________________
     
[public]
   comment = Public Stuff
   path = /home/public
   public = yes
   writable = yes
   printable = yes
       ______________________________________________________________
     
   为了使以上目录供大众可读取,但只有群组成员{group staff}可写入,请修改其项
   目像这样:
       ______________________________________________________________
     
[public]
   comment = Public Stuff
   path = /home/public
   public = yes
   writable = yes
   printable = no
   write list = @staff
       ______________________________________________________________
     
   其他玩磁碟分享的技巧,请看 Samba 文件或 man pages.
   
7. 分享 Windows 磁碟给 Linux 机器

   一种给 UNIX 机器用的 SMB client 程式被包含在 Samba 发行套件之中.它提供
   一种在命令列下的像ftp的介面.
   
   想要看在给定的主机上有哪些分享可取得, 执行:
     _________________________________________________________________
   
    /usr/sbin/smbclient -L host
     _________________________________________________________________
   
   这□的 'host' 是你想要浏览的机器名子. 这将会回应一串 'service' 的名称
   - 也就是, 它所分享给你的磁碟或印表机的名称. 除非 SMB 伺服器没有安全上的
   设定, 否则它将要求你输入密码. 给它 'guest' 帐号的密码或是你个人在那台机
   器上帐号的密码.
   
   举个例子:
     _________________________________________________________________
   
    smbclient -L zimmerman
     _________________________________________________________________
   
   这个指令的输出应该看起来像是这样:
       ______________________________________________________________
     
Server time is Sat Aug 10 15:58:27 1996
Timezone is UTC+10.0
Password:
Domain=[WORKGROUP] OS=[Windows NT 3.51] Server=[NT LAN Manager 3.51]

Server=[ZIMMERMAN] User=[] Workgroup=[WORKGROUP] Domain=[]

        Sharename      Type      Comment
        ---------      ----      -------
        ADMIN$         Disk      Remote Admin
        public         Disk      Public
        C$             Disk      Default share
        IPC$           IPC       Remote IPC
        OReilly        Printer   OReilly
        print$         Disk      Printer Drivers


This machine has a browse list:

        Server               Comment
        ---------            -------
        HOPPER               Samba 1.9.15p8
        KERNIGAN             Samba 1.9.15p8
        LOVELACE             Samba 1.9.15p8
        RITCHIE              Samba 1.9.15p8
        ZIMMERMAN
       ______________________________________________________________
     
   这个 browse list 列出其他有资源分享给网路的 SMB 伺服器.
   
   要使用此 client, 请执行:
     _________________________________________________________________
   
    /usr/sbin/smbclient service <password>
     _________________________________________________________________
   
   这□的 'service' 是一台机器和分享名称. 举例而言,如果你设法连到一台叫做
   zimmerman 的机器上之以 'public' 为分享名称的目录 ,此 service 要叫做
   \\zimmerman\public. 然而,因为 shell 限制, 你会需要脱离 backslashes, 所
   以你要像这样的结束:
     _________________________________________________________________
   
    /usr/sbin/smbclient \\\\zimmerman\\public mypasswd
     _________________________________________________________________
   
   这样的 'mypasswd' 是你的密码之文字串{literal string}.
   
   你将会有 smbclient 的提示符号{prompt}出现:
       ______________________________________________________________
     
Server time is Sat Aug 10 15:58:44 1996
Timezone is UTC+10.0
Domain=[WORKGROUP] OS=[Windows NT 3.51] Server=[NT LAN Manager 3.51]
smb: \>
       ______________________________________________________________
     
   键入 'h' 取得关於使用 smbclient 的 help:
       ______________________________________________________________
     
smb: \> h
ls             dir            lcd            cd             pwd
get            mget           put            mput           rename
more           mask           del            rm             mkdir
md             rmdir          rd             prompt         recurse
translate      lowercase      print          printmode      queue
cancel         stat           quit           q              exit
newer          archive        tar            blocksize      tarmode
setmode        help           ?              !
smb: \>
       ______________________________________________________________
     
   如果你能使用ftp,你应该不需要查询 smbclient 的 man pages.
   
8. 分享 Linux 印表机给 Windows 机器

   为了分享 Linux 印表机给 Windows 机器, 你必须确定你的印表机已经装设好.
   如果你能从 linux 上列印,设定 SMB 的印表机分享将会很直接.
   
   请见 Printing HOWTO 来设定当地的列印.
   
   因为作者使用被连接到 Windows NT 机器的印表机, 这小节不应该被视为很完整
   的,而只是建议.任何有详细资料可分享出来的人, 请将这些资料寄到
   [7]dwood@plugged.net.au 使得这小节能够完成.
   
   加入列印设定到你的 smb.conf:
       ______________________________________________________________
     
[global]
   printing = bsd
   printcap name = /etc/printcap
   load printers = yes
   log file = /var/log/samba-log.%m
   lock directory = /var/lock/samba

[printers]
   comment = All Printers
   security = server
   path = /var/spool/lpd/lp
   browseable = no
   printable = yes
   public = yes
   writable = no
   create mode = 0700

[ljet]
   security = server
   path = /var/spool/lpd/lp
   printer name = lp
   writable = yes
   public = yes
   printable = yes
   print command = lpr -r -h -P %p %s
       ______________________________________________________________
     
   确认印表机的路径(本例子中是在[ljet]下)要与 /etc/printcap中的 spool 目录
   相符合!
   
   注意: 使用 Samba 来分享 UNIX boxes 上的印表机给 Windows NT 机器有一些问
   题. 其中一个问题是使用 NT 适当地看到分享的印表机. 想要修正这个问题, 请
   看 Samba 发行套件上的说明, 即 docs/WinNT.txt 档案.其他是处理密码的问
   题. 对於这扰人问题的了解与不能成功的修正,请看相同文件上的说明.
   
9. 分享 Windows 印表机给 Linux 机器

   为了分享 Windows 机器上的印表机, 你必须做以下步骤:
   
   a) 你必须在 /etc/printcap 内有适当的记录,而且他们必须与当地目录结构 (像
   spool 目录等) 相符合.
   
   b) 你必须有 script 档 /usr/bin/smbprint. 这会随附在 Samba source, 但不
   是随附於所有 Samba binary 发行套件. 一个稍微修改版本在以下讨论.
   
   c) 如果你想要转换 ASCII 档到 Postscript,你必须有netscript,或与其等效
   的. netscipt 是一种 Postscript 转换器而且一般是安装在 /usr/bin.
   
   d) 你可以希望藉由有易於使用的 frond end 来使 Samba 列印更容易. 一种用於
   处理 ASCII, Postscript 或建立 Postscript 的简单 perl script 在下面给
   定.
   
   以下 /etc/printcap 项目用在 Windows NT 主机上 HP 5MP 印表机. 这些项目如
   下:
     _________________________________________________________________
   
        cm - comment
             {说明}
        lp - device name to open for output
             {为了输出,而要开启的设备名称}
        sd - the printer's spool directory (on the local machine)
             {印表机的 spool 目录 (在当地的机器上)}
        af - the accounting file
             {帐号档案}
        mx - the maximum file size (zero is unlimited)
             {最大档案大小 (零表示没限制)}
        if - name of the input filter (script)
             {输入过滤之名称 (script)}
     _________________________________________________________________
   
   要取得更多资讯,请看 Printing HOWTO 或者关於 printcap 的 man page.
       ______________________________________________________________
     
# /etc/printcap
#
# //zimmerman/oreilly via smbprint
#
lp:\
        :cm=HP 5MP Postscript OReilly on zimmerman:\
        :lp=/dev/lp1:\
        :sd=/var/spool/lpd/lp:\
        :af=/var/spool/lpd/lp/acct:\
        :mx#0:\
        :if=/usr/bin/smbprint:
       ______________________________________________________________
     
   请确定 spool 和 accounting{帐号} 的目录存在且可写入. 请确信某行有适当的
   路径指到 smbprint script (在下面会给) 而且确定适当的设备被指到 ( /dev
   下某个档).
   
   下个是 smbprint script 本身. 它通常被摆在 /usr/bin 而且是因为 Andrew
   Tridgell 的缘故,而据我所知是他创造了 Samba. 它随附在 Samba source 发行
   套件, 但在某些 binary 发行套件并没有, 所以在这我再造一个.
   
   你可以希望仔细地看这个. 有某些较小的修改已经证明它们是很有用的.
       ______________________________________________________________
     
#!/bin/sh -x

# This script is an input filter for printcap printing on a unix machine. It
# uses the smbclient program to print the file to the specified smb-based
# server and service.
# For example you could have a printcap entry like this
#
# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
#
# which would create a unix printer called "smb" that will print via this
# script. You will need to create the spool directory /usr/spool/smb with
# appropriate permissions and ownerships for your system.

# Set these to the server and service you wish to print to
# In this example I have a WfWg PC called "lapland" that has a printer
# exported called "printer" with no password.

#
# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
# so that the server, service, and password can be read from
# a /usr/var/spool/lpd/PRINTNAME/.config file.
#
# In order for this to work the /etc/printcap entry must include an
# accounting file (af=...):
#
#   cdcolour:\
#       :cm=CD IBM Colorjet on 6th:\
#       :sd=/var/spool/lpd/cdcolour:\
#       :af=/var/spool/lpd/cdcolour/acct:\
#       :if=/usr/local/etc/smbprint:\
#       :mx=0:\
#       :lp=/dev/null:
#
# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
#   server=PC_SERVER
#   service=PR_SHARENAME
#   password="password"
#
# E.g.
#   server=PAULS_PC
#   service=CJET_371
#   password=""

#
# Debugging log file, change to /dev/null if you like.
#
logfile=/tmp/smb-print.log
# logfile=/dev/null


#
# The last parameter to the filter is the accounting file name.
#
spool_dir=/var/spool/lpd/lp
config_file=$spool_dir/.config

# Should read the following variables set in the config file:
#   server
#   service
#   password
#   user
eval `cat $config_file`

#
# Some debugging help, change the >> to > if you want to same space.
#
echo "server $server, service $service" >> $logfile

(
# NOTE You may wish to add the line `echo translate' if you want automatic
# CR/LF translation when printing.
        echo translate
        echo "print -"
        cat
) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $user -N -P >> $log
file
       ______________________________________________________________
     
   大部分 linux 发行套件随附 nenscript 其用来转换 ASCII 文件成
   Postscript. 以下 perl script 经由 smbprint 使更容易提供一种简单介面给
   linux 的列印.
     _________________________________________________________________
   
Usage: print [-a|c|p] <filename>
       -a prints <filename> as ASCII
       -c prints <filename> formatted as source code
       -p prints <filename> as Postscript
        If no switch is given, print attempts to
        guess the file type and print appropriately.
     _________________________________________________________________
   
   使用 smbprint 来列印 ASCII 档案便於截断过长的行. 如果可能的话,这个
   script 截断长行於空白键处(取代在字的中间).
   
   格式化过的原始码是被 nenscript 处理过. 它处理 ASCII 档而且用个特选的标
   头(像 date,filename等)格式化成两栏. 它也可计算行数. 使用这当作例子, 其
   他格式型态可以达成的.
   
   Postscript 文件已经适当地格式化了,所以它们直接通过.
       ______________________________________________________________
     
#!/usr/bin/perl

# Script:   print
# Authors:  Brad Marshall, David Wood
#           Plugged In Communications
# Date:     960808
#
# Script to print to oreilly which is currently on zimmerman
# Purpose:  Takes files of various types as arguments and
# processes them appropriately for piping to a Samba print script.
#
# Currently supported file types:
#
# ASCII      - ensures that lines longer than $line_length characters wrap on
#              whitespace.
# Postscript - Takes no action.
# Code       - Formats in Postscript (using nenscript) to display
#              properly (landscape, font, etc).
#

# Set the maximum allowable length for each line of ASCII text.
$line_length = 76;

# Set the path and name of the Samba print script
$print_prog = "/usr/bin/smbprint";

# Set the path and name to nenscript (the ASCII-->Postscript converter)
$nenscript = "/usr/bin/nenscript";

unless ( -f $print_prog ) {
        die "Can't find $print_prog!";
}
unless ( -f $nenscript ) {
        die "Can't find $nenscript!";
}

&ParseCmdLine(@ARGV);

# DBG
print "filetype is $filetype\n";

if ($filetype eq "ASCII") {
        &wrap($line_length);
} elsif ($filetype eq "code") {
        &codeformat;
} elsif ($filetype eq "ps") {
        &createarray;
} else {
        print "Sorry..no known file type.\n";
        exit 0;
}
# Pipe the array to smbprint
open(PRINTER, "|$print_prog") || die "Can't open $print_prog: $!\n";
foreach $line (@newlines) {
        print PRINTER $line;
}
# Send an extra linefeed in case a file has an incomplete last line.
print PRINTER "\n";
close(PRINTER);
print "Completed\n";
exit 0;

# --------------------------------------------------- #
#        Everything below here is a subroutine        #
# --------------------------------------------------- #

sub ParseCmdLine {
        # Parses the command line, finding out what file type the file is

        # Gets $arg and $file to be the arguments (if the exists)
        # and the filename
        if ($#_ < 0) {
                &usage;
        }
        # DBG
#       foreach $element (@_) {
#               print "*$element* \n";
#       }

        $arg = shift(@_);
        if ($arg =~ /\-./) {
                $cmd = $arg;
        # DBG
#       print "\$cmd found.\n";

                $file = shift(@_);
        } else {
                $file = $arg;
        }

        # Defining the file type
        unless ($cmd) {
                # We have no arguments

                if ($file =~ /\.ps$/) {
                        $filetype = "ps";
                } elsif ($file =~ /\.java$|\.c$|\.h$|\.pl$|\.sh$|\.csh$|\.m4$|\
.inc$|\.html$|\.htm$/) {
                        $filetype = "code";
                } else {
                        $filetype = "ASCII";
                }

                # Process $file for what type is it and return $filetype
        } else {
                # We have what type it is in $arg
                if ($cmd =~ /^-p$/) {
                        $filetype = "ps";
                } elsif ($cmd =~ /^-c$/) {
                        $filetype = "code";
                } elsif ($cmd =~ /^-a$/) {
                        $filetype = "ASCII"
                }
        }
}

sub usage {
        print "
Usage: print [-a|c|p] <filename>
       -a prints <filename> as ASCII
       -c prints <filename> formatted as source code
       -p prints <filename> as Postscript
        If no switch is given, print attempts to
        guess the file type and print appropriately.\n
";
        exit(0);
}

sub wrap {
        # Create an array of file lines, where each line is < the
        # number of characters specified, and wrapped only on whitespace

        # Get the number of characters to limit the line to.
        $limit = pop(@_);

        # DBG
        #print "Entering subroutine wrap\n";
        #print "The line length limit is $limit\n";

        # Read in the file, parse and put into an array.
        open(FILE, "<$file") || die "Can't open $file: $!\n";
        while(<FILE>) {
                $line = $_;

                # DBG
                #print "The line is:\n$line\n";

                # Wrap the line if it is over the limit.
                while ( length($line) > $limit ) {

                        # DBG
                        #print "Wrapping...";

                        # Get the first $limit +1 characters.
                        $part = substr($line,0,$limit +1);

                        # DBG
                        #print "The partial line is:\n$part\n";

                        # Check to see if the last character is a space.
                        $last_char = substr($part,-1, 1);
                        if ( " " eq $last_char ) {
                            # If it is, print the rest.

                            # DBG
                            #print "The last character was a space\n";

                            substr($line,0,$limit + 1) = "";
                            substr($part,-1,1) = "";
                            push(@newlines,"$part\n");
                        } else {
                             # If it is not, find the last space in the
                             # sub-line and print up to there.

                            # DBG
                            #print "The last character was not a space\n";

                             # Remove the character past $limit
                             substr($part,-1,1) = "";
                             # Reverse the line to make it easy to find
                             # the last space.
                             $revpart = reverse($part);
                             $index = index($revpart," ");
                             if ( $index > 0 ) {
                               substr($line,0,$limit-$index) = "";
                               push(@newlines,substr($part,0,$limit-$index)
                                   . "\n");
                             } else {
                               # There was no space in the line, so
                               # print it up to $limit.
                               substr($line,0,$limit) = "";
                               push(@newlines,substr($part,0,$limit)
                                   . "\n");
                             }
                        }
                }
                push(@newlines,$line);
        }
        close(FILE);
}

sub codeformat {
        # Call subroutine wrap then filter through nenscript
        &wrap($line_length);

        # Pipe the results through nenscript to create a Postscript
        # file that adheres to some decent format for printing
        # source code (landscape, Courier font, line numbers).
        # Print this to a temporary file first.
        $tmpfile = "/tmp/nenscript$$";
        open(FILE, "|$nenscript -2G -i$file -N -p$tmpfile -r") ||
                die "Can't open nenscript: $!\n";
        foreach $line (@newlines) {
                print FILE $line;
        }
        close(FILE);

        # Read the temporary file back into an array so it can be
        # passed to the Samba print script.
        @newlines = ("");
        open(FILE, "<$tmpfile") || die "Can't open $file: $!\n";
        while(<FILE>) {
                push(@newlines,$_);
        }
        close(FILE);
        system("rm $tmpfile");
}

sub createarray {
        # Create the array for postscript
        open(FILE, "<$file") || die "Can't open $file: $!\n";
        while(<FILE>) {
                push(@newlines,$_);
        }
        close(FILE);
}
       ______________________________________________________________
     
10. 版权

   1996 年的 HOWTO 版权是属於 David Wood. 它可以用任何型式的再重覆产生以及
   自由的散播,只要这个档原封不动,包含这段叙述.
   
11. 感激

   只要你写信给我提供意见, 我将会在这(文件)的下一版感激你.

References

   1. mailto:dwood@plugged.net.au
   2. mailto:r6921068@ms.cc.ntu.edu.tw
   3. mailto:dwood@plugged.net.au
   4. ftp://nimbus.anu.edu.au/pub/tridge/samba/
   5. ftp://nimbus.anu.edu.au/pub/tridge/samba/
   6. file://localhost/tmp/zh-sgmltools.16199/SMB-HOWTO.txt.html#sec-daemons
   7. mailto:dwood@plugged.net.au