当前位置:Linux教程 - Linux - SMB HOWTO

SMB HOWTO



         作者: David Wood, [email protected]
    译者: J.S. Lin, [email protected]
    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 (
    [email protected]). 再者,修改或修正可以寄到那,以便下一版包涵进去.

    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 文件.

    进一步资讯,请看以下文件:


    3. 安装



    最新 Samba 的原始程式可以取得自:


    ftp://nimbus.anu.edu.au/pub/tridge/samba/

    然而,如果已安装 linux 的 Redhat 版本,你可以使用软体套件{package} 来安装它.有些其他版本也包含 Samba 的binaries{二元档程式}.

    以下两个 daemon{管理精灵} 对 Samba 软体套件 是必要的. 它们一般是被安装在 /usr/sbin ,而可在开机时,从系统起动的 scripts或inetd来执行. script的例子被展示在
    执行 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 机器的印表机, 这小节不应该被视为很完整的,而只是建议.任何有详细资料可分享出来的人, 请将这些资料寄到
    [email protected]
    使得这小节能够完成.

    加入列印设定到你的 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 [email protected] (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 >> $logfile




    大部分 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. 感激
    只要你写信给我提供意见, 我将会在这(文件)的下一版感激你.


    发布人:netbull 来自:Linux HOWTO