Monthly Archive for July, 2008

讓 pure-ftpd 支援 smbfs

pure-ftpd 要能支援 smbfs 這些比較特殊的 File System,必須在 configure 的時候加入 “–without-sendfile” 這個參數,讓它不使用 sendfile 這個 System Call,在 FreeBSD ports 裡,只需要將預設的 Option “SENDFILE       Support for the sendfile syscall” 取消即可。下面是官方的說明:

--without-sendfile: on Linux, Solaris, HPUX and FreeBSD kernels, Pure-FTPd
tries to reduce the CPU/memory usage by using a special system call (sendfile)
. It works very well with most filesystems. However, this optimization is not
implemented for all filesystems in current kernels. Users reported that
downloading files with Pure-FTPd failed with SMBFS (Samba) on FreeBSD and
TmpFS and NTFS on Linux (the error reported by the server is "broken pipe" or
"Error during write to data connection") . If you are planning to serve files
from these filesystems, you have to use the --without-sendfile switch to
enable a workaround. It was also reported that PA-Risc Linux systems need this
flag.

portconf new feature “.undef” 進 ports 了

之前 po 的那篇幫 portconf 加新功能的,後來聽了 gslin 的建議送了 PR 給作者,剛剛收到 reply mail 通知已經 commit 了。

題外話,最近陸續送了好幾個 PR,也慢慢學習到 ports 的正確包法,對 FreeBSD 的 ports 機制也更了解了,能對 FreeBSD 做出貢獻真的很棒!

Update: 看了一下作者最後的作法,改成了只動到 portconf.sh,主要在下面這行:

echo ${_line#*:} | sed -E 's/([A-Z0-9_]+)(=([^|]+))?/\1=\3/g;s/!([A-Z0-9_]+)=([^|]+)?/.undef \1/g;s/ *\| */|/g;s/ /%/g'

果然高明多了。

portconf 中的 .undef 功能

ports-mgmt/portconf 是個很棒的工具,它的用法就不多說了,google 一下都可以找到很多篇教學,這篇主要是幫 portconf 加入 .undef 的功能。

在 ports 中常常用到一個作法,就是利用 .ifdef 來判斷 WITHOUT_XXX 是否已定義,如果定義了,便加入 XXX 的設定,一個最常見的便是 WITHOUT_X11,對於那些不想裝 XWindow 的機器來說很有用,只需要在 ports.conf 加入:

*: WITHOUT_X11=yes    # WITHOUT_X11 也可

如此一來,所有的 ports 預設便會設定 WITHOUT_X11;但是對於某些套件來說,則必須去掉這個變數才能用到一些 library,最近遇到的例子是,我需要用到 textproc/wv,它 depend on x11-toolkits/gtk20,而 x11-toolkits/gtk20 depend on graphics/cairo,如果 cairo 設定 WITHOUT_X11 來編的話,gtk20 便會編不過出現:

gdkdrawable-x11.c:32:24: cairo-xlib.h: No such file or directory

所以 cairo 必須去掉 WITHOUT_X11 來重編。為了這些特定的套件的需要,我把 /usr/local/libexec/portconf 改成:

_conf=/usr/local/etc/ports.conf
if [ ! -r "${_conf}" ]; then
    exit
fi
_pwd=`pwd`
sed '/^#/d;/^[[:space:]]*$/d' "${_conf}" | while read _line; do
    for _port in ${_line%%:*}; do
        if [ "${_pwd%%${_port}}" != "${_pwd}" ]; then
            echo ${_line#*:} | sed -E 's/(!?)([A-Z0-9_]+)((\?)?=([^|]+))?/\1\2\4=\5/g;s/ *\| */|/g;s/ /%/g'
        fi
    done
done

至於 /etc/make.conf 裡 portconf 的設定改成(我的 /etc/make.conf 已經是改過的了):

# Begin portconf settings
# Do not touch these lines
_PORTSDIR!=/bin/realpath /usr/ports
_MATCHDIR!=echo `echo ${.CURDIR} | /usr/bin/grep ^${_PORTSDIR}`
.if !empty(_MATCHDIR) && exists(/usr/local/libexec/portconf)
_PORTCONF!=/usr/local/libexec/portconf
.for i in ${_PORTCONF:S/|/ /g}
${i:C/!([A-Z0-9_]+)(=([^ ]+)?)?/.undef \1/g}    # 主要是這行
${i:S/%/ /g}
.endfor
.endif
# End portconf settings

如此一來,我可以在 ports.conf 設定:

*: WITHOUT_X11=yes
graphics/cairo: !WITHOUT_X11

任何變數前面加上 ‘!’ 都會自動 .undef,以上面為例:

$ make -V _PORTCONF
WITHOUT_X11=yes !WITHOUT_X11=

最後會變成:

WITHOUT_X11=yes
.undef WITHOUT_X11

如此一來,便可針對某些套件設定相對於 Global 的設定了。
但要注意,不能寫成下面這樣:

graphics/cairo: !WITHOUT_X11
*: WITHOUT_X11=yes

否則會變成:

.undef WITHOUT_X11
WITHOUT_X11=yes