第 152 期 內含 GPL 授權元件產品的標示義務─自由軟體鑄造場電子報─智邦公益電子報
enews.url.com.tw · February 07,2012[法律專欄] 內含 GPL 授權元件產品的標示義務
林誠夏/文 2010/06/20
以自由軟體授權元件來加速產品開發已漸成時代趨勢,但許多著名的自由軟體授權條款皆帶有 Copyleft(註一)性質的授權拘束性,其拘束散布這些自由軟體授權元件目的碼(Binary code)及其衍生作品(Derivative Works)者,亦有義務一併提供該元件的原始碼(Source code)予收受程式的後手,所以連帶的要求散布者亦需盡相當程度的「標示義務」。
所謂的「標示義務」是說,散布者在散布該自由軟體授權元件的當下,須得開宗明義的將該元件的授權狀態提示予後手知悉,並應進一步說明該元件原始碼的取得途徑給後手知道。以使用率非常高的 GPL 授權條款為說明範例的話,其要求內含 GPL 授權元件的產品釋出時,皆需要有個顯著清楚的標示,說明該產品中哪些部份是內含 GPL 授權程式碼的元件,並進一步告知使用者有取得該元件原始碼的權利,以及後續取得這些原始碼的方式。這樣的理論說來簡單,但實際上國內外精準完成此項義務的廠商並不多見,所以以下即以 gpl-violations.org 所撰寫的「商用常見問答集(註二)」為說明基礎。
在 gpl-violations.org 的「商用常見問答集」裡,其就內含 GPL 授權元件的商業產品提出了三項建議:
1、GPL 授權條款要求散布程式目的碼者,需一併善盡後續散布程式原始碼的義務,您可以將這些原始碼檔案附隨產品一併提供給購買產品的顧客,或是提供一紙正式說明的文書,讓顧客未來能夠向您提示這份文書來取得程式原始碼。一般來說、直接把這些程式原始碼檔案一併燒錄於產品的文件光碟裡與該產品併行散布,會是滿足這個義務性要求的的好方法。2、在散布 GPL 授權元件時(無論此一元件為目的碼格式或是原始碼格式),都需要隨附一份 GPL 授權條款的全文與產品合併釋出,並且清楚的告知消費者,此一產品內含有 GPL 授權元件。
3、如果該產品的軟體或韌體更新檔能透過網路更新,並且這些更新檔也內含 GPL 授權的元件,那麼您必須一併提供這些更新檔案每一個版本的原始碼,給那些能夠取得這些更新檔案執行檔的人。
總結以上的說明內容,可以得到以下的步驟化操作指南:
第一步、將 GPL 授權元件嵌入於產品裡合併散布者,須以清楚的說明文字告知消費者該產品內含 GPL 授權的程式碼。第二步、除了清楚的說明文字外,亦須夾附一份 GPL 授權條款全文與該產品併行散布(列印出來的書面格式或是數位化格式的電子檔皆可)。
第三步、同時提供該元件的程式原始碼給購買該產品的消費者,或是提供一紙書面文書,讓消費者嗣後可以依此文書所提示的方法,以工本費用取得該元件的程式原始碼檔案。
而上述的這些說明資訊,實務上多數公司是先簡易標示在產品的包裝盒上,其他必要資訊再另起一紙文書標示於產品盒內的書面說明文件,或是以數位化格式的電子檔,載於產品盒內的文件光碟片裡,一般常見的範例說明資訊約略如下:
產品包裝盒上的簡易資訊
This product's software/firmware includes open source component from the open source community. For further details, please refer to the User manual in the chapter 2.或是,
This product's software/firmware includes open source component from the open source community. For further details, please refer to the Offer_Source Code.txt file in the "Includes Software and User Guide CD".
必要資訊的書面說明文件
This product from xxx, Inc. contains software/firmware originating from xxx and its suppliers and also contains component from the open source community. Any software originating from xxx and its suppliers is licensed under the applicable xxx Software License Agreement. Any component from the open source community is licensed under the specific license terms applicable to that software. By using that component, you acknowledge that you have reviewed such license terms and that you agree to be bound by the terms of such licenses. Where such specific license terms entitle you to the source code of such component, that source code is available upon request via yyy@xxx.com at cost from xxx for at least three years from the purchase date of this product. If you would like to have a copy of the GPL or certain other open source code in this component on a CD, xxx will mail to you a CD with such code for $?.?? USD plus the cost of shipping, upon request(註三).This product's software/firmware includes the following open source components(完成 GPL 授權標示義務的第一步):
...…
...…
...…
To review the full text of xxx Software License Agreement and GNU General public license and other open source software licenses applying in this product, please refer to the COPYING.txt file(完成 GPL 授權標示義務的第二步).
To initiate a GPL or other open source licensing component request, please mail to yyy@xxx.com, or visit our website in: http://xxx.com/offe_source_Code.html(完成 GPL 授權標示義務的第三步).
如同 gpl-violations.org 在「商用常見問答集」裡第一個建議所描述的,直接將該元件的程式原始碼一併燒錄於產品的文件光碟裡與該產品併行散布,會是一個滿足上述條件最簡便的方法。然而 GPL 授權條款確實也容許散布者將目的碼與原始碼分開來散布,所以若是散布者最後決定採取的是,嗣後經消費者要求後再提供該產品中自由軟體元件原始碼的策略,則須清楚的標示以上所例舉的相關資訊,否則日後產生自由軟體侵權爭訟的風險便會升高。
而關於散布者嗣後提供元件原始碼的方式在實務上也常有若干爭議,這是因為 GPL2 版授權條款成文於 1991 年,於其時透過網路傳輸的方式來提供程式檔案並未風行,所以 GPL2 在嚴謹的文意解釋下,僅能容許以寄送資料儲存媒體(Medium customarily used for software interchange,例如CD、DVD)的方式來完成嗣後原始碼的提供義務,然而 2007 年改版後的 GPL3 版授權條款,已經增設了網路提供程式原始碼下載的選項,所以當前散布 GPL2 授權元件的彈性作法是,增設一個網路頁面供產品的消費者在登入產品序號後直接下載該元件的原始碼,但請注意、此方式僅為便利消費者及產品販售者的額外選項,若是消費者堅持要以寄送資料儲存媒體的方式來得到元件原始碼,那散布者還是需要尊重其意願,回歸 GPL2 版授權條款明文律定的傳統方式來提供,但此時亦可依 GPL2 版授權條款的同款規定,向此元件原始碼的索取者要求燒錄媒體及郵遞支出等必要的工本費用(for a charge no more than your cost of physically performing source distribution)。
註一:Copyleft 的簡單定義是:一種轄於現行著作權法體制之下,卻又不同於傳統的公眾分享方式。此用語由 Richard Stallman 首先提出,其主張自由軟體的著作人仍可主張著作權法所賦予的權利,然後再以著作財產權人的身份規範他人使用其作品的方式,原作者可在授權條款中明示允許他人對原著作進行修改,但同時要求衍生著作的著作人也必須採取同樣的授權模式,允許該衍生著作的散布、流通與修改,並規定衍生著作的授權仍須遵循這樣的規範,以確保這些作品能持續地提供社會大眾自由使用;常見被認定具有嚴格 Copyleft 拘束性的自由軟體授權條款有:GPL2/3, LGPL2/3, AGPL3,部份 Copyleft 拘束性的自由軟體授權條款有:MPL/CDDL/CPL/EPL。
註二:http://www.gpl-violations.org/faq/vendor-faq.html。
註三:範例文字資訊參考自 BusyBox 的專案說明頁面;以及 Cisco Systems, Inc.的 GPL 元件原始碼下載頁面。
[技術專欄] Vim - 編輯緩衝區以及編輯視窗 (Buffers and Windows)
林佑安 (Cornelius)/文 2010/06/18
Vim 內建視窗分割功能,可於編輯器內分割多重視窗及分頁來並行編輯檔案。
各編輯視窗 (Window) 可載入不同編輯緩衝區 (Buffer) 來進行編輯,不限於當前的編輯緩衝區。 編輯視窗也可載入共同的編輯緩衝區來編輯。 事實上編輯視窗基本上就是一個編輯緩衝區的觀察窗口 (viewport)。
由於可開啟多重編輯視窗來並行編輯,因此若能善用編輯視窗及編輯緩衝區等功能,便可提高編輯效率。
編輯緩衝區 (Buffers)
在討論編輯視窗之前,需要先來討論編輯緩衝區。
編輯緩衝區有三種狀態,分別為: 啟用(active), 隱藏(hidden), 非啟用(inactive)。
編輯視窗在關閉時,只是將觀察窗口關閉,所以並不會影響到編輯緩衝區,實際上編輯緩衝區還是會在 執行中的 Vim 內,需要時,仍可使用編輯緩衝區命令將該緩衝區載回。
以下簡單示範緩衝區應用之作法:
於命令列可同時開啟多檔案載入緩衝區:
$ vim file1 file2 file3
此時 file1 會出現在第一個編輯視窗,而 file2 file3 會在背景,可透過 :buffers
命令來查看緩衝區清單:
:buffers
1 %a "file1" line 1
2 "file2" line 0
3 "file3" line 0
而 :buffers
有其他兩個別名,分別為: :ls
, :files
。
欲切換至 file2 及 file3 的 編輯緩衝區需要 :bnext
(載入下一緩衝區) , :bprev
(載入前一緩衝區) 或 :[N]buffer [N]
(載入第 [N] 個緩衝區)。
不過每次翻閱緩衝區需鍵入指令 :bnext , :bprev 仍是麻煩,所以筆者建議可加入以下快捷鍵對應,請於 ~/.vimrc 內加入:
nmap <C-b>n :bnext<CR>
nmap <C-b>p :bprev<CR>
如此可以 Ctrl-b n 以及 Ctrl-b p 來翻閱編輯緩衝區,若不習慣 Ctrl-b 也沒關係 可自行代換成其他快捷鍵組合。
要跳至特定編輯緩衝區可使用 :[N]buffer 命令,如:
:2buffer
或
:buffer 2
如此便可跳至 file2 之編輯緩衝區。
而:
:2buffer!
則可強制跳至 file2 之編輯緩衝區。
若直接輸入緩衝區名稱也行,如:
:buffer file3
若要新增其他檔案進編輯緩衝區,可使用 :badd
命令:
:badd path/to/file4
若要於目前編輯緩衝區編輯檔案:
:edit path/to/file5
離開編輯視窗或是關閉編輯緩衝區時,該編輯緩衝區其實還留在記憶體中, 使用命令 :ls!
可以將隱藏的編輯緩衝區列舉出來。
若要將編輯緩衝區完全卸載,則可使用 bwipeout 命令:
:[N]bw[ipeout][!]
:bw[ipeout][!] {bufname}
:N,Mbw[ipeout][!]
:bw[ipeout][!] N1 N2 ...
舉例來說:
:1bw
:bw path/to/file
:1,5bw!
:bw 1 2 3 4
該參數可以是編輯緩衝區的編號或是完整路徑。
相關選項
buftype bufhidden buflisted swapfile modifiable
編輯視窗
編輯視窗內可以切換不同的編輯緩衝區,常用編輯視窗命令如下:
:split - 將目前編輯視窗水平分割為二,新的視窗為原有的編輯緩衝區
:vsplit - 將目前編輯視窗垂直分割為二,新的視窗為原有的編輯緩衝區
:split path/to/file - 開啟新的水平分割視窗來編輯檔案
:vsplit path/to/file - 開啟新的垂直分割視窗來編輯檔案
:new - 開啟新的水平分割視窗,並且開啟新的編輯緩衝區
:vnew - 開啟新的垂直分割視窗,並且開啟新的編輯緩衝區
有時在分割視窗時,可以利用 topleft 以及 botright 命令來指定分割視窗位置,例如:
從上方左側開啟分割視窗:
:topleft split
從下方右側開啟分割視窗:
:botright split
常用的編輯視窗快捷鍵如下:
垂直分割:
Ctrl-w v
水平分割:
Ctrl-w s
切換視窗 Focus:
Ctrl-w [hjkl]
交換視窗內的編輯緩衝區:
Ctrl-w x
移動目前視窗至 (H: 最左側, L: 最右側, J: 最下方, K: 最上方):
Ctrl-w [HJKL]
將目前的編輯視窗移動至新的分頁:
Ctrl-w T
將目前的水平分割編輯視窗最大化:
Ctrl-w _
將目前的垂直分割編輯視窗最大化:
Ctrl-w |
將目前分割的視窗重新平均分配大小:
Ctrl-w =
在瀏覽程式碼時,可使用之視窗相關命令如下:
Ctrl-w f
於目前游標底下的檔案名稱或檔案路徑,開啟新的視窗來讀取該檔案。 要設定 Ctrl-w f 所搜尋檔案的路徑,可以設定 'path' 選項,如: set path+=/usr/include/
Ctrl-w F
於目前游標底下的檔案名稱或檔案路徑,開啟新的視窗來讀取該檔案, 並且跳至檔名或檔案路徑之後所跟隨的行號。例如:
~/.vimrc:300
於按下 ~/.vimrc 上按下 Ctrl-w F 之後,便會以水平分割視窗開啟 ~/.vimrc 檔案,並且跳至第 300 行。
Ctrl-w gf
同
Ctrl-w f
。不過開啟的檔案會在新的分頁開啟。同樣的功能可透過tab split
以及gf
來達到。
Ctrl-w gF
同
Ctrl-w F
。 不過開啟的檔案會在新的分頁開啟。同樣的功能可透過tab split
以及gF
來達到。
相關腳本片段
設定 gVim 一開始的視窗大小
將以下設定放入 .vimrc 內:
set lines=50 columns=100
或是:
if has("gui_running")
" GUI is running or is about to start.
" Maximize gvim window.
set lines=999 columns=999
else
" This is console Vim.
if exists("+lines")
set lines=50
endif
if exists("+columns")
set columns=100
endif
endif
簡易調整編輯視窗大小
要調整水平分割視窗大小,通常使用 Ctrl-w + , Ctrl-w - ,若要方便調整,可使用下列設定:
nmap + <C-W>+
nmap - <C-W>-
直接使用 + 或 - 來調整視窗大小。
垂直分割視窗大小,則可嘗試下列設定:
nmap <Right> <C-w>>
nmap <Left> <C-w><
快速切換垂直分割視窗 focus
map <C-j> <C-w>j<C-w>_
map <C-k> <C-w>k<C-w>_
如此會切換至下方或上方視窗,並且調整至最大化。
設置最小、預設視窗大小
set winminheight=0
set winheight=999
以循環方式切換編輯緩衝區
:nnoremap <C-n> :bnext<CR>
:nnoremap <C-p> :bprevious<CR>
以正規表示式搜尋編輯緩衝區
要快速搜尋編輯緩衝區,可以使用下方的 Vim Script Function:
" buffer sel by pattern {{{
fu! BufSel(pattern)
let buf_count = bufnr("$")
let cur_bufnr = 1
let nummatches = 0
let firstmatchingbufnr = 0
while cur_bufnr <= buf_count
if(bufexists(cur_bufnr))
let currbufname = bufname(cur_bufnr)
if(match(currbufname, a:pattern) > -1)
echo cur_bufnr . ": ". bufname(cur_bufnr)
let nummatches += 1
let firstmatchingbufnr = cur_bufnr
endif
endif
let cur_bufnr = cur_bufnr + 1
endwhile
if(nummatches == 1)
execute ":buffer ". firstmatchingbufnr
elseif(nummatches > 1)
let desiredbufnr = input("Enter buffer number: ")
if(strlen(desiredbufnr) != 0)
execute ":buffer ". desiredbufnr
endif
else
echo "No matching buffers"
endif
endf
fu! BufSelInput()
let pattern = input( "pattern: " )
call BufSel( pattern )
endf
"Bind the BufSel() function to a user-command
com! -nargs=1 Bs :call BufSel("<args>")
nmap <leader>bf :call BufSelInput()<CR>
將以上程式碼加入至 ~/.vimrc
後,即可使用 :Bs
命令以及 \\bf
快捷鍵來呼叫該函式來使用正規表示式來搜尋符合的編輯緩衝區,如:
:Bs vim.*
或是按下 \\bf
,則會出現要求輸入 Pattern 的提示符。
顯示編輯緩衝區資訊
.vimrc 加入此一片段:
fun! BufInfo()
echo "[bufnr ] ".bufnr("%")
echo "[bufname ] ". expand("%:p")
echo "[cwd ] " . getcwd()
if filereadable(expand("%"))
echo "[mtime ] " . strftime("%Y-%m-%d %H:%M %a",getftime(expand("%")))
endif
echo "[size ] " . Bufsize() . " bytes"
echo "[comment ] " . (exists('b:commentSymbol') ? b:commentSymbol : "undefined")
echo "[filetype ] " . &ft
echo "[tab ] " . &ts . " (" . (&et ? "" : "no") . "expandtab)"
echo "[keywordprg] " . &keywordprg
echo "[makeprg ] " . &makeprg
echo "[Buffer local mappings]"
nmap <buffer>
endf
com! BufInfo :cal BufInfo()<CR>
最後呼叫 :BufInfo
命令即可顯示編輯緩衝區資訊。
相關 Plugin
FuzzyFinder
若有使用 FuzzyFinder Plugin ,則可加上此段設定來搜尋編輯緩衝區 (Buffer)。
:nmap <silent> <leader>fb :FufBuffer<CR>
FuzzyFinder: http://www.vim.org/scripts/script.php?script_id=1984
Bufexplorer
使用 Bufexplorer 可顯示出緩衝區清單,並且以選單的方式切換編輯緩衝區。
Bufexplorer: http://www.vim.org/scripts/script.php?script_id=42
filefind
filefind.vim 是一依據 find 命令的結果的 Vim 延伸插件。
平常需求為:
$ find path/to -type f -iname "*pattern*"
使用 find 命令加上 -type f 參數搜尋檔案,但是要對該檔案清單另外處理就麻煩了,這時候最直接想到的是:
$ find path/to -type f -iname "*pattern*" | vim -
將該結果導向給 vim ,對 vim 命令而言,加上 "-" 則為從 stdout 讀取結果導至 Buffer (編輯緩衝區)。
此時若要開啟、重新命名、編輯檔案,便可利用 filefind.vim 插件來執行這些操作。
安裝:
可使用 git 將 repository 抓取下來:
$ git clone git@github.com:c9s/filefind.vim.git
$ cd filefind.vim
$ make install
只需要呼叫 make 命令即可安裝。 :-) 用法可參考 github 上的 README file.
filefind.vim: http://github.com/c9s/filefind.vim
tselectbuffer
類似 bufexplorer。
tselectbuffer: http://vim.sourceforge.net/scripts/script.php?script_id=1866
作者
熟 Vim Script、 Perl 程式設計及網頁相關等技術。開發及維護多項 Vim Plugin 及 Perl 相關模組。多數 Vim Plugin 可於 Github.com 上找到。