对版权的误解—一系列的错误

From:http://www.gnu.org/philosophy/misinterpreting-copyright.zh-cn.html

对版权的误解—一系列的错误

Richard Stallman

在版权领域,正在发生着一些奇怪并且危险的事情。根据美国宪法,版权的存在是为了让那些读书,听音乐,看电影或是用软件的用户受益,而非为了出版商、发行 商或作者。版权法律中的种种约束都是号称“为用户着想”,不过现实中,人们却不断地拒绝、违抗着这些束缚。面对公众的反抗,美国政府反而继续增加限制,用 新的严刑酷法来恐吓大众,以便让他们听话。
版权政策何以发展到如此,以至于与它的初衷背道而驰? 而我们又该如何让其回归正途? 要理解这些,我们必须追本溯源,来看看美国版权法的基础:美国宪法。

美国宪法下的版权思维

起草美国宪法时,“作者独享其作品的版权”这一观点被提出时就遭到了反对。于是美国的立国者采用了一个完全不同的前提 ── 版权并非是作者的自然权利,而是为了社会的发展,人为做出的一种让步。下面的一段话引自美国宪法,表明了美国宪法中,对于版权的态度(见第一条,第八款)。

[国会有权]保障著作家和发明家对各自著作和发明在一定期限内的专有权利,以促进科学和使用艺术之进步。

美国联邦最高法院也曾不止一次地强调,推动社会发展意味着让版权作品的用户受益。例如,在福克斯电影公司诉Doyal案中,法院就曾表示,

美国的唯一利益和主要目的在于使公众从创作者的劳动中获益,因此才让版权具有垄断特征。

这一根本性的决定解释了为什么版权并非是宪法所要求的,而仅仅是宪法允许将其作为一种选择 ── 以及为什么它被认为仅有“一定期限”。假如版权是一种自然权利,那么这种权力就应理所当然地被作者享有,也就没有什么人或组织可以在一定时期后,公正地终止这一权利。倘若这种自然权力能够如此被公正地终止,那么无异于让每个人的房子,在一定时期后变为公共财产。

“以权购版”(Copyright Bargain)

版权体系会保证出版商和创作者的特权,从而使他们受益;但这么做的目的却绝非为了他们自身的利益。之所以这么做,更多地是为了能够影响这些人的行为: 鼓励创作者更多地创造并发布其作品。由此带来的结果是,政府以公众的身份做交易,通过牺牲公众的自然权利,为公众换来更多的出版作品。法律学者将这一概念称为“以权购版”(copyright bargain)。这就好比政府用纳税人的钱,修建高速公路或机场,只不过在以权购版的交易中,政府花费的是我们的自由而非我们的金钱。
然而,这样的交易是否真的有利于公众呢?还有很多可选的交易方案,哪个又是最好的呢?版权政策中的每个议点都是这问题的一部分。如果我们曲解了这问题本身,那么我们将会很可能做出糟糕的决策。
美国宪法将版权授予创作者本人。而在实际当中,创作者通常将版权转让给出版商。因此,通常是拥有这些权利的出版商受益,而非作者本人──尽管作者也可能从 中分得一杯羹。因此,通常是出版商去游说要加强版权所有者的权利。这里为了更好地反应版权方面的实际情况,避免对他们粉饰神化,本文中使用“出版商”来描 述版权的所有者,而非“创作者”。并使用“读者”一词来描述版权作品的用户。这并非总是意味着要“读”什么,仅仅是因为“用户”一词太过抽象,远离生活。

错误一:“寻求一个平衡”

以权购版的思维将公众放在第一位:让读者大众获益是其最终目的;这中间,出版商也许会有利可图,但这绝非是最终目的,仅仅是为了达目的而踏出的一步。读者 的利益和出版商的利益在优先权上存在着本质的差别。对版权本身目的的一种曲解往往产生于此:将出版商提升到了与读者同等重要的级别上。
一种常见的说法是,美国版权法是为了在出版商与读者的利益之间寻求一个平衡。这一说法的支持者们认为,这种解释与美国宪法站在同一立场,仅仅是表述不同;换言之,他们认为这种解释与以权购版等价。
然而,这两种解释方式却相去甚远;不仅概念相异,而且暗含不同。这一“平衡”的观点假定了读者与出版商的利益,在重要性上仅仅是量上的差别。这种观点认 为,这无非就是个孰轻孰重的问题,再对不同权重采取不同措施。“股东”一词常被用来塑造这个观点;它假定在制定政策的过程中,每一方的利益都是同等重要 的。这一观点否认读者与出版商之间的利益存在着质的差别,然而这种质的差别却是政府参与以权购版交易的根本原因。
这种利益平衡的观点贻害颇深,因为它拒绝强调对公众的最大保护。而在以权购版的概念中,这种保护被不断重申:版权所授予的特权仅仅能够以读者的名义进行修 正,而非是以出版商的名义。由于使出版商获益在此也被视为目的之一,那么也就可以以此为名修正版权所涉权利;换言之,“平衡”的观点认为可以以某些人而非 公众的名义,修正版权所有者的权利。
在实际当中,这种”平衡“的观点颠倒了这套公正地修正版权法的流程:以权购版将责任放在出版商那里,需要出版商去劝告读者放弃一定程度的自由;“平衡”的 观点将这一责任倒置了。简单点说,以“平衡”的观点来看,既然出版商拥有特权,那么基于这种特权而获利则是无可厚非的。除非可以证明这种获利途径会对读者 产生伤害,让读者得不偿失,否则,我们很可能得出这样的结论:出版商可以获得任何他们要求的特权。
由于这种所谓的在出版商与读者间“寻求一种平衡”的观点忽视了读者群本身的重要性,我们必须抛弃它。

谁该跟谁找平衡?

当政府以公众的名义,为人民购买商品的时候,它有责任为其争取一份最好的交易。这种交易应该对公众而言最划算,而绝非对协议中的另一方。
比如,在和某个建筑公司签订一份修建公路的合同时,政府该考虑尽可能少地花费公众的钱财。为此政府部门会利用竞价的手段来降低价格。
实际当中,价格不可能为零,因为承包商不可能把价格降得这么低。虽说没有特殊声明,但是他们同样拥有着一个自由社会公民的权利,这其中就包括拒绝不划算的 合同。所以,哪怕是最低的出价,也会让承包商有得赚。如此说来,这其中的确存在着平衡。但这不是两个利益集团出于各自获利的考虑而蓄意造成的平衡,公众目 标和市场力量才是这种平衡的造就者。也就是说政府尝试为纳税人在自由社会和自由市场的环境中,争取到最好的交易。
在以权购版的交易中,政府花费的是我们的自由,而非金钱。它比金钱更加珍贵,因此政府也有责任更加明智,更加谨慎地花费我们的自由。并且,永远也不能将出版商的利益和公众的自由等同视之。

并非“平衡”,而是“妥协”

版权法的目的在于平衡读者与出版商之间的利益,这种说法是站不住脚的。但其中的确存在着需要权衡的两个利益:读者的两个利益。其一是读者使用出版物的自由程度;其二,根据情况,读者也会利用某些奖惩机制来鼓励创新和出版,从而获得更多的创新作品。
“平衡”一词在讨论版权时,代表了在读者与出版商间“寻求平衡”。因此,继续使用“平衡”来描述读者的两个利益难免会发生误会──咱们得换个词。
概括起来,当一个个体或组织有着两个相互冲突的目标,并且不能同时完全实现他们,我们称这其中需要进行“妥协”。如此的话,我们最好说“在是否消费我们自由的问题上,找个妥协的方案”,而非在组织之间“寻求一个平衡”
(这里有 另一个有关“平衡”的评论。)

错误二:产出最大化

第二个错误是对版权目的的曲解。版权常常被误以为是为了最大化出版作品的数量,而非仅仅是增加它们的数量。“寻求平衡”的观点错在把出版商的重要性提升到了与读者的重要性等同的地位。而这第二个错误,则将出版商凌驾于读者之上。
当我们买东西的时候,我们绝不会把仓库里的商品尽数全包,更不会总买最贵最好的。相反,我们只会买我们需要的,然后留着点钱去买别的东西。我们不求最好, 只求质量够硬。所谓的“收益递减”原则告诫我们,花掉所有的钱来买一样东西是不能充分利用资源的。我们总还会留着一些去买点别的。
和买东西类似,收益递减原则在版权问题上也同样适用。我们第一份花掉的自由,应该是让我们损失最少,而又最能鼓励更多出版的。随着我们继续花费公众的自 由,我们会发现,每一次增加花费都会带来比上一次更大的损失,而收益却没上次多。当收益逐渐趋近与零,我们就会说,多出的那份花销不值得。于是我们确定了 一份交易,它可以增加出版物的数量,但是又不会超出某个界限。
产出最大化的这一说法否认了这些真知灼见,它指挥着大众为了多出一丝创新,而放弃几乎全部的使用出版物和作品的自由。

所谓最大化

实际当中,政客们的花言巧语广为流传,不断地支持着所谓产出最大化的目标,不计公众自由的花销。他们断定公开地复制这些作品是非法的,不公平的,是从根上 大错特错的。比如,那些出版商把复制的行为称为“剽窃”,用这么一个贬义词把你和邻居们共享信息的行为等同于攻击商船。(剽窃这个贬义词曾经被创作者们用 来形容出版商,他们利用合法途径出版未授权的作品版本。如今的出版商则是偷梁换柱,用这个词来诬蔑读者的复制行为。)这种修辞直接地否认了宪法关于版权的 观点,却还装出一幅重申美国法律传统的模样。
“剽窃”一词这里被广泛使用,它蒙蔽了媒体,使得很少人意识到它带来的根本性改变。这法子很有效,因为如果说复制本身就是本质上不合乎道义的,那么我们就 永远也不能反对出版商的要求,哪怕我们会为此而放弃自由。换个说法,当公众需要证明为什么出版商不该获得更大的权利时,其中最重要的一个理由—“我们就是 想要去复制它”—就已然被事先否定了。
这么一来,就遗留了一个重要问题,倘若要反对增强版权所有者的权利,就不得不引用一些次要论点。看看如今关于反对增强版权所有者权利的争论,几乎清一色地都在引用着那些无关痛痒的次要问题。没有哪个敢站出来把自由发行拷贝版本当做是一个公开的观点。
于是现实当中,出版商就可以如此嚣张:“一些行为致使我们的销量减少—或者说我们认为它们可能会导致销量减少—我们推测这会削减一定数量的创新产品—具体 数量还不得而知。因此,这些行为必须被禁止。”于是我们被蒙骗着得出了一个荒唐的怪论:公众利益是由出版商的销量来衡量的。只要是对General Media有利的,就是对美利坚有益的。

错误三:出版商权利最大化

出版商宣扬的观点,是不计代价地使出版作品最大化。一旦这一观点被接受,他们紧接着会论证,要完成这一目标,需要将他们的权利最大化—让版权覆盖所有能想到的工作,或者利用法律工具,比如使用所谓的“拆封许可”译注1,来达到相同的效果。这个所谓的目标,完全无视“合理使用”(Fair use)和“权利穷竭原则”(Right of first sale)译注2。并且渗透到每个政府部门,从美国各州,到全世界。
出版商权力的最大化是荒谬的,因为严苛的版权规则反而会阻碍创新。莎士比亚也曾在他的作品中借用了别人在十几年前创作的戏剧中的桥段。设想如果遵照今天的版权法,莎翁的戏剧将会被视为非法。
退一步说,就算我们想要不计代价地获得最快的作品创作速度,那么最大化出版商的权利也不是通往此处的正确途径。作为一种提升出版速度的手段,它本身就是自相矛盾的。

三个错误的后果

当前版权的立法趋势,是授予出版商尽量多的权利,和更久的版权有效期。版权的根本理念,从它诞生之日起,就被各种各样的错误曲解着。油嘴滑舌的立法者们打着“版权为公众”的幌子,实际上却对出版商有求必应。
举个例子吧,参议员Hatch提出了S. 483法案。该法案要求版权有效期延长二十年。对此该议员辩称:

我确信我们正在面临着两个问题:其一,当前的版权法是否足够保护作者的利益;其二,这种保护是否足以鼓励更多的创新。

这一法案将会延长1920年以后发布的作品的版权有效期。对出版商来说这好像天上掉馅饼,而对公众来说,这有害无益。因为没有法子让时光倒流,增加那个年 代之前的出版量,从而让公众获得更多自由使用的作品。不过无论如何,对于今天的人们来说,这法案却切实地消耗了公众的自由—无法自由地再版那个年代作品。
这一法案同时也延长了即将出版作品的版权有效期。对于即将出版的作品,版权有效期由原来的75年延长到了95年。理论上讲,这也许确实能够激励更多的创新,但是任何声称需要这些额外鼓励的出版商,最好都拿出一个像样的2075年的预计资产负债表来说话。
到头来,议会也没有对出版商的提议有什么问题:一个延长版权有效期的法律条文在1998年生效了。这就是“松尼-波诺版权期延长法案”(Sony Bono Copyright Term Extension Act)。此法案以其中一位支持者命名,这位松尼先生在法案生效前去世了。我们其实常常把它叫做“米老鼠版权法案”,因为我们都认为,真正推动这项法案,是为了让米老鼠这一角色的版权继续生效。波诺的遗孀继续了他的工作,并表示:

实际上,松尼希望版权可以永久持有。但是有人告诉我,这么做是违背宪法的。我诚挚地邀请各位能够与我并肩,为全方位地加强版权法而努力。各位也许还知道杰克.华伦蒂(Jack Valenti)也提交了类似的议案。他表示,版权的期限应该延续到世界末日(forever less one day)。也许委员会应该在下届国会考虑看看那份提案。译注3

虽然版权期延长法案对宪法当中推进社会发展的目的毫无益处,最高法院最终还是同意了这个颠覆了整个法律系统的提议。
在1996年通过的另一项法案,使得复制任何出版物到达一定数量后,便被视为重刑罪。哪怕你仅仅为了表示友好而把它们送给你的朋友。在这之前,这种赠送行为在美国并非被视为犯罪。
另一项更糟糕的法律就是千禧数字版权法案(Digital Millennium Copyright Act,DMCA)。“反拷贝”机制,或美其名曰“反盗版”机制,再次兴起,因为这一法案将任何破解“反拷贝”机制(一直以来计算机用户都对这种机制深恶痛绝)的行为变为非法,哪怕仅仅是发布破解方法。这法案我看最好叫做“千家传媒合谋法案”(Domination by Media Corporations Act),因为它根本就是让出版商有权制定适合自己的版权法。该法案声称,出版商有权对其作品的使用做出任何限制。这些限制,可以借助该法案赋予的特权,利用加密或许可证管理器等方式来强制执行。
有人曾辩解道,这个法案是实现了最近出台的一项关于加强版权的条约。该条约由世界知识产权组织(World Intellectual Property Organization)颁布。而该组织则被一群版权和专利持有者掌控着,只会为了他们的利益说话。这项条约只是加强版权持有人的权利,而至于它是否会推动社会发展就另当别论了。不管怎样,这项法案也大大超出了条约所要求的范围。
图书馆是反对这项法案的中坚力量,因为在图书馆中的复制行为应属合理使用范畴,而这种行为也可能会根据此法案而被禁止。出版商对此又作何反应呢?Pat Schroeder,以前是出版商的代表,现为美国出版商协会(Association of American Publishers, AAP)的院外活动集团成员。他表示,出版商“倘若按照[图书馆的]要求做就根本不能活“。可是图书馆所要求的和几十年前没什么两样,它不过是在维持现状。说来就奇怪了,出版商又是靠什么来存活至今的呢?
国会议员巴尼-福兰克(Barney Frank)在一次会议上和我还有其它几个反对该项法案的人碰面,他向我们展示了美国宪法中关于版权的观点是怎样被忽视的。他说,由于“电影业”,“唱片 业”和其它“产业”都“对现状表示担忧”,急需通过加大处罚力度来扩大权利。我于是问道:“但是这有没有考虑到公众的利益呢?”他接着换用出版商的口气答 道:“这年头你还考虑公众利益?这些创新型人才可不会为了什么公众利益而放弃自己的权利!”这些五花八门的“产业”雇佣着大量所谓“创新型人才”,并以此 为幌子,将版权作为自己理应获得的特权。宪法由此被彻底颠覆。
千禧数字版权法案在1998年生效。生效之日起,法案规定合理使用依然在名义上是合法的,但是允许出版商以某种形式禁止用户使用软件或硬件。事实的结果是,合理使用由此被禁止了。
基于这项法案,电影业可以监视那些用来播放DVD光盘的自由软件,甚至有权监视DVD数据是如何被读取的。在2001年四月,普林斯顿大学(Princeton University)的爱德华-费尔顿教授(Professor Edward Felten)仅仅由于发表了一篇科研论文,便被美国唱片工业协会(Recording Industry Association of America,RIAA)一纸诉状告上法庭。因为该论文涉及了他最新的密码学研究成果,而他所研究的加密体系正是用来加密音乐唱片的。
我们还可以发现,与传统纸制书相比,电子书剥夺了读者大量的自由—比如,自由地把书借给朋友,卖到二手书店,或是自由地从图书馆借阅,不署名地购买,甚至 是自由地读上第二遍。加密的电子书基本上都会对上述行为进行限制—想读这些电子书?你得用个专用的软件,任凭它对你做出任何限制,你却对此无能为力,因为 这些软件的内部运行细节是保秘的。
我可不会买这些加了密,还处处受限的电子书。我希望你也能够主动抵制它们。要是哪个电子书不能像传统书那样,让读者获得应有的自由,那就别搭理它!
任何个人,倘若独立发布可以阅读那些受限电子书的软件,都有被起诉的风险。一个名叫Dmitry Sklyarov的俄罗斯程序员在2001年来美国参加一个会议的时候被逮捕。因为他在俄罗斯写了一个类似的软件,而这种软件在当地是合法的。不过现在俄罗斯正在筹备制定类似的法律来禁止此类软件,欧盟在最近已经采用了类似的法律。
大众市场上,电子书已经是一个失败的商业尝试。但这并非是由于读者为了维护自己的自由而使其失败的。电子书本来就不太讨人喜欢。比如说,盯着电脑屏幕读书 会让人很不舒服。但是我们可不能指望这么一个幸运的缺陷能够保护我们多久。下一步改进电子书的方案将是采用“电子纸张”—一个张得像书的玩意,可以在里面 放上受限的加密电子书。假如这种类似纸张的显示效果收到欢迎,我们则更需要维护我们的自由。与此同时,电子书也正在步步侵蚀着我们的生活:纽约大学 (New York University,NYU)和其它一些牙科学校要求它们的学生购买的教材,全是受限的电子书。
那些传媒公司可还没满足。在2001年,在迪斯尼的资助下,参议员霍灵思(Senator Hollings)提交了“安全系统标准与认证法案”(Security Systems Standards and Certification Act,SSSCA)[1]。 该法案规定,所有计算机设备(以及全部数字录制和/或播放设备)必须装有政府授权的拷贝限制系统。这是他们的最终目标,在提案中的第一项,就是禁止一切可 以播放HDTV的数字设备,除非它们可以让用户无法”篡改“作品(也就是说,用户无法按照自己的意愿做任何修改)。由于自由软件本身就允许用户对软件进行 修改,我们在这里第一次遇到了一个法案,明显地阻止了自由软件做某些工作。这么看来,禁止其它操作也就不远了。假如联邦通信委员会(Federal Communications Commission,FCC)采纳了该法案,那么现有的自由软件,比如GNU Radio,将会被审查。
阻止这些法案和规章需要我们的行动。[2]

找个划算的交易

如何合理地制定版权政策呢?假如把版权视为公众购买的商品,那么它必须服务于公众的利益。政府在出售公众自由的时候,必须把它用在刀刃上,不到万不得已不能出手,而且要小心谨慎。至少,我们必须把版权涉及的领域约束在一定范围内,只要能够保证一定数量的出版物和创新作品。
但我们无法用竞价的方式来找出一个最低的价格消费我们的自由,这可不是什么城建工程。那我们该如何找到这最合理的“价位”呢?
一个方案就是将版权的权利逐渐削减,然后随时观察结果如何。通过观察到的结果,计算何时出版物和创新作品的数量出现多大程度的减少,继而我们就可以知道赋 予版权所有者多大的权利是足够满足公众需求的。我们必须通过精确的测量观察来进行判断,而不能听信出版商的结论。因为出版商的权利受到哪怕一丁点的损害, 他们都会夸大其词,叫嚷着世界末日即将到来。
版权政策包含着几个相互独立的方面,它们可以分开来调整。当我们找到了一个方面的最小开销,我们依然可以减小其它方面的权利而将出版发行量维持在一定水平。
版权的其中一个方面就是它的有效期。现在的有效期通常是一个世纪上下。把有效期减少至十年,从作品发布之日起开始计时,这不妨是一个好的开始。另一个方面,涉及到创作后续作品,可以暂时不做修改。
为什么要从作品发布之日起开始计时呢?因为那些尚未发布的版权作品并不会直接限制读者的自由。我们在还没有获得这些作品之前,我们是否有拷贝它的自由还不 确定。所以,给作者久一些的时间来酝酿发布作品是没什么坏处的。作者(他们通常在发布之前拥有对其作品的版权)很少选择为了延长版权持有期,而延期发布作 品。
为什么是十年?因为这个提议可以让人放心。我们可以非常自信地说,这一削减方案不会对现有出版业产生多大影响。在大多数传媒和艺术作品上,成功的作品往往 只能在头几年带来效益。而且,哪怕是那些成功的作品,在十年内也就停止出版了。甚至是一些参考性的作品,通常的也就在十几年内有用。十年的版权有效期足够 了:更新的版本会定期发布,大多数读者都会选择在版权保护期内的作品,而不会去复制一个十年前发布的版本。
十年的时间也许还能有富裕。当运转得比较稳定的时候,我们可以试着再减少些时间。在一次关于文学作品版权的大会上,我提交了关于十年版权有效期的建议。一位坐在我身边的著名科幻小说作者对此表示了强烈的反对。他说,有效期超过五年就已经让人无法忍受了。
不过我们不能把这个有效期适用在任何形式的作品上。创作一个高度一致的版权政策,对于公众利益来说没太大好处。而且现有的版权法中已经有很多针对特定用途 或媒介的条款。要是我们在雇人修建公路的时候,总是假设工人们要跨越千山万水,排除万难,那么我们可就总得花大价钱。这可不是个聪明的法子。同样,假设所 有的创作都是万古常青,永世不朽的,那我们就要付出高额的代价,牺牲很大的自由。这显然也是愚蠢的。
因此,也许小说,字典,计算机程序,歌曲,交响乐还有电影需要区分对待,赋予它们不同的版权有效期。然后,我们可以分别减少每种作品的有效期,直到达到一 个合适的程度。比如,也许一个长度超过一小时的电影可以获得二十年的有效期,因为创作它们可能有更多的开销。在我所从事的计算机程序设计领域,三年也就足 够了。因为产品的周期要远远小于此。
版权政策中,还有一个方面,那就是关于合理使用的范围:对于版权作品,一些部分或全部的复制行为是合法的。要削减版权权利,在这个方面最自然的一步就是允 许个人非商业的,在人与人之间小范围内拷贝和/或传播。这一改变将会削弱版权对私人生活的入侵。而不会对出版物的销量产生太大影响。(也许还有必要在法律 上阻止类似拆封许可合同的条文来替代版权法的限制。)通过Napster的经验来看译注4,我们也应该允许人们在未对作品进行任何修改的前提下,在公共场合出于非商业目的的传播—当很大一部分公众发现作品非常有用,要求拷贝和共享,并且只能通过酷刑对这部分公众的行为进行阻止的时候,那么公众就有权得到他们想要的。
对于小说,或者更普遍地说,对于那些用于娱乐的作品,在不修改的前提下进行非商业目的的拷贝对于读者来说已经说足够自由了。但是对于计算机程序,使用它是 出于功能性的目的(为了完成某项工作),那么需要更多的自由。包括发布修改后版本的自由。关于软件用户应有的自由,可以参见拙作《自由软件定义》一文。不 过有一个可以接受的妥协方案,那就是在程序在发布两三年后,再赋予用户这些自由。
这些改变符合公众对于使用数字技术的需求。显然,出版商会反对这些建议,认为它们是“片面的”。他们也许会威胁说,这么下去就带着他们的不朽作品回家。但他们最多也就是动动口舌,不会真的放弃发布作品。因为即便这么做,出版商依然有利可图;他们也别想玩出花样。译注5
当我们讨论削减版权权力的时候,我们必须考虑到那些大公司会在和用户达成的最终许可协议中修改它。必须有种措施,能够阻止利用协议来增加版权法中没有涉及 的限制。美国的法律体系规定,可以对这些格式条款(即,经营者为了重复使用而预先拟定,并在订立合同时未与消费者协商的条款)做出何种程度的限制。

后记

我是一个软件设计师,并非法律专业的学者。我之所以关注版权,是因为在计算机网络领域中,尤其是因特网上,版权问题是不可避免的。伴随着计算机和网络,我 已走过了三十余个寒暑。作为一个普通用户,我珍视我们失去的每一份自由,也关注那些即将被剥夺的自由。而作为一个作者,我更有资格反对任何对创造者的粉饰神化。出版商对作者的鼓吹夸大,不过是为了能够扩张自己的权力。目的达成,兔死狗烹,作者将不得不把作品版权转让给出版商。
文中所涉及的事实,你都可以去查证;其中的推理论证,也可仔细推敲。你更可以提出自己的观点意见。但请你至少听进我这句话:我,作为一个作者,没有任何资 格可以凌驾于你们之上。倘若你愿为我的付出奖赏我些什么,我会诚挚感谢并欣然接受—然而,请时刻牢记,切勿因为作者的这些付出,而轻易将你们自己的自由拱 手相让。

脚注

  1. 该法案后来重命名为CBDTPA。这最好解释为“买吧,不过别想修改什么”(“Consume, But Don’t Try Programming Anything”)。当然,官方的称呼是“消费者宽带及数字电视促进法”
  2. 如果需要什么帮助,可以访问: DefectiveByDesignpublicknowledge.orgwww.eff.org

本文发表于自由软件,自由社会:Richard Stallman文集

译注

  1. 拆封许可合同,即Shrink Wrap License。多见于软件领域,一旦用户拆开软件最外层包装的热塑封包(Shrink Wrap),就表示用户接受了软件的许可证。引申为某种合同,协议或其它条文,只有在用户拆开产品包装后才能看到,并且一旦拆开包装,就意味着接受其中的条款。
  2. 合理使用,是指在某些情况下,法律允许自由使用版权作品而不必征得版权所有人的同意,也不必向版权所有者支付报 酬的情形。权利穷竭原则,是指版权所有人或其授权人创造或制造的作品,在第一次投放市场后,权利人即丧失了对它的控制权。也就是说权利穷竭了。比如,用户 购买了某品牌的手机,当用户将该手机再次出售给他人的时候,则不必向版权所有者交纳费用。
  3. 杰克.华伦蒂,前美国电影协会(MPAA)主席。他曾说过,倘若要给版权加个期限,那么就该是forever less one day。这句话源自一个英语的俗语:forever and a day。直译为“比永远多一天”。由于美国宪法要求版权应该有期限,因此杰克在这里将原句改为“比永远少一天”。
  4. Naspter,早期的P2P音乐共享程序。使得用户可以免费地与网络上其它人共享音乐文件。因触犯了唱片公司的利益,而被告上法庭。并被迫做出调整。
  5. 原句为“it will be the only game in town”。直译为“这也将是全城唯一的游戏”。表示出版商没有别的选择。“The only game in town”是一本畅销的儿童小说,在美国出版于1988年。

WP-Syntax代码高亮

www.wpdaxue.com/wp-syntax.html

WP-Syntax 代码书写格式

1
2
3
<pre lang="html" line="1" escaped="true">
//这里添加代码……
</pre>

其中,lang=”html”表示代码语言为html,请根据自己需要修改;
line=”1” 表示显示行号,如果不需要,去掉即可;
escaped=”true” 是为了防止代码转义,如果不需要,去掉即可。
注意:在wordpress后台使用 WP-Syntax 等代码高亮插件,需要在html模式下添加代码,不要随意切换到可视化模式,否则代码就容易转义!!

WP-Syntax 插件支持的高亮语言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
'actionscript' => array('as'),
'ada' => array('a', 'ada', 'adb', 'ads'),
'apache' => array('conf'),
'asm' => array('ash', 'asm', 'inc'),
'asp' => array('asp'),
'bash' => array('sh'),
'bf' => array('bf'),
'c' => array('c', 'h'),
'c_mac' => array('c', 'h'),
'caddcl' => array(),
'cadlisp' => array(),
'cdfg' => array('cdfg'),
'cobol' => array('cbl'),
'cpp' => array('cpp', 'hpp', 'C', 'H', 'CPP', 'HPP'),
'csharp' => array('cs'),
'css' => array('css'),
'd' => array('d'),
'delphi' => array('dpk', 'dpr', 'pp', 'pas'),
'diff' => array('diff', 'patch'),
'dos' => array('bat', 'cmd'),
'gettext' => array('po', 'pot'),
'gml' => array('gml'),
'gnuplot' => array('plt'),
'groovy' => array('groovy'),
'haskell' => array('hs'),
'html4strict' => array('html', 'htm'),
'ini' => array('ini', 'desktop'),
'java' => array('java'),
'javascript' => array('js'),
'klonec' => array('kl1'),
'klonecpp' => array('klx'),
'latex' => array('tex'),
'lisp' => array('lisp'),
'lua' => array('lua'),
'matlab' => array('m'),
'mpasm' => array(),
'mysql' => array('sql'),
'nsis' => array(),
'objc' => array(),
'oobas' => array(),
'oracle8' => array(),
'oracle10' => array(),
'pascal' => array('pas'),
'perl' => array('pl', 'pm'),
'php' => array('php', 'php5', 'phtml', 'phps'),
'povray' => array('pov'),
'providex' => array('pvc', 'pvx'),
'prolog' => array('pl'),
'python' => array('py'),
'qbasic' => array('bi'),
'reg' => array('reg'),
'ruby' => array('rb'),
'sas' => array('sas'),
'scala' => array('scala'),
'scheme' => array('scm'),
'scilab' => array('sci'),
'smalltalk' => array('st'),
'smarty' => array(),
'tcl' => array('tcl'),
'vb' => array('bas'),
'vbnet' => array(),
'visualfoxpro' => array(),
'whitespace' => array('ws'),
'xml' => array('xml', 'svg'),
'z80' => array('z80', 'asm', 'inc')

包装cout等ostream对象的方法

http://stackoverflow.com/questions/1134388/stdendl-is-of-unknown-type-when-overloading-operator

技术关键在于std::endl是一个函数  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>

struct MyStream
{
template <typename T>
MyStream& operator<<(const T& x)
{
std::cout << x;

return *this;
}


// function that takes a custom stream, and returns it
typedef MyStream& (*MyStreamManipulator)(MyStream&);

// take in a function with the custom signature
MyStream& operator<<(MyStreamManipulator manip)
{
// call the function, and return it's value
return manip(*this);
}

// define the custom endl for this stream.
// note how it matches the `MyStreamManipulator`
// function signature
static MyStream& endl(MyStream& stream)
{
// print a new line
std::cout << std::endl;

// do other stuff with the stream
// std::cout, for example, will flush the stream
stream << "Called MyStream::endl!" << std::endl;

return stream;
}

// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;

// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);

// define an operator<< to take in std::endl
MyStream& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return it's value
manip(std::cout);

return *this;
}
};

int main(void)
{
MyStream stream;

stream << 10 << " faces.";
stream << MyStream::endl;
stream << std::endl;

return 0;
}

文件夹遍历

http://www.cppblog.com/shongbee2/archive/2009/03/30/78366.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364428%28v=vs.85%29.aspx

用windows的API实现文件夹的遍历扫描的程序
使用到的API:

1
2
3
FindFirstFile
FindNextFile
FindClose

主要用到的结构:

1
WIN32_FIND_DATA

在msdn都有详细的说明。这里也简要说明一下:

1
2
3
4
HANDLE WINAPI FindFirstFile(
__in LPCTSTR lpFileName, //要查找的文件路径
__out LPWIN32_FIND_DATA lpFindFileData //保存文件结构的指针
);

查找对应的路径,如果查找返回查找的句柄,然后我们可以通过该句柄去查找下一个和关闭这个句柄。
如果查找失败,则返回(INVALED_HANDLE_VALUE)(-1),可以通过GetLastError();来得到他的错误类型。
注意:查找第一个的时候,他不仅返回了查找的句柄,他也把第一个的文件信息保存在lpFindFileData里面了。所以这个也是要处理的。


例程:
头文件包含:

1
2
#include <windows.h>
#include <winbase.h> // 在这里定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

#include <windows.h>
#include <winbase.h> // 在这里



int main()
{

// HANDLE WINAPI FindFirstFile(
// _In_ LPCTSTR lpFileName, // C风格字符串 名
// _Out_ LPWIN32_FIND_DATA lpFindFileData // 指向接收信息的结构体的指针
// );

// 关于返回值
// 成功, 则返回用来继续查找或者关闭用的句柄
//
// 失败,则返回 INVALID_HANDLE_VALUE 并且结构体内容是不确定的
// 获取更多信息在 GetLastError 函数
//
// 如果没有找到文件 GetLastError 函数会返回 ERROR_FILE_NOT_FOUND

// 关于第一个参数
// The directory or path, and the file name, which can include wildcard characters,
// for example, an asterisk (*) or a question mark (?).
//
// This parameter should not be NULL, an invalid string
// (for example, an empty string or a string that is missing the terminating null character),
// or end in a trailing backslash ().
//
// If the string ends with a wildcard, period (.),
// or directory name,
// the user must have access permissions to the root and all subdirectories on the path.
//
// In the ANSI version of this function, the name is limited to MAX_PATH characters.
// To extend this limit to 32,767 wide characters,
// call the Unicode version of the function and prepend "\?" to the path.


// BOOL WINAPI FindNextFile(
// _In_ HANDLE hFindFile, // 上一个函数的返回句柄
// _Out_ LPWIN32_FIND_DATA lpFindFileData
// );
// 失败返回false【没有下一个??】 并且结构体返回内容不确定
// 具体失败信息查看 GetLastError

// BOOL WINAPI FindClose(
// _Inout_ HANDLE hFindFile // 关闭句柄
// );

// 结构体内容
// typedef struct _WIN32_FIND_DATA {
// DWORD dwFileAttributes;
// FILETIME ftCreationTime;
// FILETIME ftLastAccessTime;
// FILETIME ftLastWriteTime;
// DWORD nFileSizeHigh;
// DWORD nFileSizeLow;
// DWORD dwReserved0;
// DWORD dwReserved1;
// CHAR cFileName[MAX_PATH];
// CHAR cAlternateFileName[14];
// } WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;

// DWORD WINAPI GetLastError(void);
// 返回上一个错误代码

WIN32_FIND_DATA FindFileData;
LPWIN32_FIND_DATA lpFindFileData = &FindFileData;

string path = ".\png\*.png";

HANDLE handle = FindFirstFile( path.c_str(), lpFindFileData );

if ( INVALID_HANDLE_VALUE == handle )
{
cout << "INVALID_HANDLE_VALUE" << endl;
cin.get();
return -1;
}

do{
if ( !( lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
cout << lpFindFileData->cFileName < < endl;
}
int t = GetLastError();
// cout << "GetLastError " << t << endl;
if ( ERROR_FILE_NOT_FOUND == t )
{
cout << "ERROR_FILE_NOT_FOUND" << endl;
}
}while ( FindNextFile( handle, lpFindFileData ) );

if ( !FindClose(handle) )
{
cout << "CloseFail" << endl;
return -1;
}

cin.get();

return 0;
}

win虚拟按键编码

http://msdn.microsoft.com/en-us/library/ms927178.aspx

Virtual key codes

Symbolic constant Hexadecimal value Mouse or keyboard equivalent
VK_LBUTTON 01 Left mouse button
VK_RBUTTON 02 Right mouse button
VK_CANCEL 03 Control-break processing
VK_MBUTTON 04 Middle mouse button on a three-button mouse
0507 Undefined
VK_BACK 08 BACKSPACE key
VK_TAB 09 TAB key
0A0B Undefined
VK_CLEAR 0C CLEAR key
VK_RETURN 0D ENTER key
0E0F Undefined
VK_SHIFT 10 SHIFT key
VK_CONTROL 11 CTRL key
VK_MENU 12 ALT key
VK_PAUSE 13 PAUSE key
VK_CAPITAL 14 CAPS LOCK key
1519 Reserved for Kanji systems
1A Undefined
VK_ESCAPE 1B ESC key
1C1F Reserved for Kanji systems
VK_SPACE 20 SPACEBAR
VK_PRIOR 21 PAGE UP key
VK_NEXT 22 PAGE DOWN key
VK_END 23 END key
VK_HOME 24 HOME key
VK_LEFT 25 LEFT ARROW key
VK_UP 26 UP ARROW key
VK_RIGHT 27 RIGHT ARROW key
VK_DOWN 28 DOWN ARROW key
VK_SELECT 29 SELECT key
2A Specific to original equipment manufacturer
VK_EXECUTE 2B EXECUTE key
VK_SNAPSHOT 2C PRINT SCREEN key
VK_INSERT 2D INS key
VK_DELETE 2E DEL key
VK_HELP 2F HELP key
3A40 Undefined
VK_LWIN 5B Left Windows key on a Microsoft Natural Keyboard
VK_RWIN 5C Right Windows key on a Microsoft Natural Keyboard
VK_APPS 5D Applications key on a Microsoft Natural Keyboard
5E5F Undefined
VK_NUMPAD0 60 Numeric keypad 0 key
VK_NUMPAD1 61 Numeric keypad 1 key
VK_NUMPAD2 62 Numeric keypad 2 key
VK_NUMPAD3 63 Numeric keypad 3 key
VK_NUMPAD4 64 Numeric keypad 4 key
VK_NUMPAD5 65 Numeric keypad 5 key
VK_NUMPAD6 66 Numeric keypad 6 key
VK_NUMPAD7 67 Numeric keypad 7 key
VK_NUMPAD8 68 Numeric keypad 8 key
VK_NUMPAD9 69 Numeric keypad 9 key
VK_MULTIPLY 6A Multiply key
VK_ADD 6B Add key
VK_SEPARATOR 6C Separator key
VK_SUBTRACT 6D Subtract key
VK_DECIMAL 6E Decimal key
VK_DIVIDE 6F Divide key
VK_F1 70 F1 key
VK_F2 71 F2 key
VK_F3 72 F3 key
VK_F4 73 F4 key
VK_F5 74 F5 key
VK_F6 75 F6 key
VK_F7 76 F7 key
VK_F8 77 F8 key
VK_F9 78 F9 key
VK_F10 79 F10 key
VK_F11 7A F11 key
VK_F12 7B F12 key
VK_F13 7C F13 key
VK_F14 7D F14 key
VK_F15 7E F15 key
VK_F16 7F F16 key
VK_F17 80H F17 key
VK_F18 81H F18 key
VK_F19 82H F19 key
VK_F20 83H F20 key
VK_F21 84H F21 key
VK_F22 85H F22 key(PPC only) Key used to lock device.
VK_F23 86H F23 key
VK_F24 87H F24 key
888F Unassigned
VK_NUMLOCK 90 NUM LOCK key
VK_SCROLL 91 SCROLL LOCK key
VK_LSHIFT 0xA0 Left SHIFT
VK_RSHIFT 0xA1 Right SHIFT
VK_LCONTROL 0xA2 Left CTRL
VK_RCONTROL 0xA3 Right CTRL
VK_LMENU 0xA4 Left ALT
VK_RMENU 0xA5 Right ALT
BA-C0 Specific to original equipment manufacturer; reserved. See following tables.
C1-DA Unassigned
DB-E2 Specific to original equipment manufacturer; reserved. See following tables.
E3 – E4 Specific to original equipment manufacturer
E5 Unassigned
E6 Specific to original equipment manufacturer
VK_PACKET E7 Used to pass Unicode characters as if they were keystrokes. If VK_PACKET is used with SendInput, then the Unicode character to be delivered should be placed into the lower 16 bits of the scan code. If a keyboard message is removed from the message queue and the virtual key is VK_PACKET, then the Unicode character will be the upper 16 bits of the lparam.
E8 Unassigned
E9-F5 Specific to original equipment manufacturer
VK_ATTN F6 ATTN key
VK_CRSEL F7 CRSEL key
VK_EXSEL F8 EXSEL key
VK_EREOF F9 Erase EOF key
VK_PLAY FA PLAY key
VK_ZOOM FB ZOOM key
VK_NONAME FC Reserved for future use
VK_PA1 FD PA1 key
VK_OEM_CLEAR FE CLEAR key
VK_KEYLOCK F22 Key used to lock device

Original equipment manufacturers should make special note of the VK key ranges reserved for specific original equipment manufacturer use: 2A, DBE4, E6, and E9F5.

In addition to the VK key assignments in the previous table, Microsoft has assigned the following specific original equipment manufacturer VK keys.

Symbolic constant Hexadecimal value Mouse or keyboard equivalent
VK_OEM_SCROLL 0x91 None
VK_OEM_1 0xBA “;:” for US
VK_OEM_PLUS 0xBB “+” any country/region
VK_OEM_COMMA 0xBC “,” any country/region
VK_OEM_MINUS 0xBD “-” any country/region
VK_OEM_PERIOD 0xBE “.” any country/region
VK_OEM_2 0xBF “/?” for US
VK_OEM_3 0xC0 “`~” for US
VK_OEM_4 0xDB “[{” for US
VK_OEM_5 0xDC “|” for US
VK_OEM_6 0xDD “]}” for US
VK_OEM_7 0xDE “‘”” for US
VK_OEM_8 0xDF None
VK_OEM_AX 0xE1 AX key on Japanese AX keyboard
VK_OEM_102 0xE2 “<>” or “|” on RT 102-key keyboard

For East Asian Input Method Editors (IMEs) the following additional virtual keyboard definitions must be observed.

Symbolic constant Hexadecimal value Description
VK_DBE_ALPHANUMERIC 0x0f0 Changes the mode to alphanumeric.
VK_DBE_KATAKANA 0x0f1 Changes the mode to Katakana.
VK_DBE_HIRAGANA 0x0f2 Changes the mode to Hiragana.
VK_DBE_SBCSCHAR 0x0f3 Changes the mode to single-byte characters.
VK_DBE_DBCSCHAR 0x0f4 Changes the mode to double-byte characters.
VK_DBE_ROMAN 0x0f5 Changes the mode to Roman characters.
VK_DBE_NOROMAN 0x0f6 Changes the mode to non-Roman characters.
VK_DBE_ENTERWORDREGISTERMODE 0x0f7 Activates the word registration dialog box.
VK_DBE_ENTERIMECONFIGMODE 0x0f8 Activates a dialog box for setting up an IME environment.
VK_DBE_FLUSHSTRING 0x0f9 Deletes the undetermined string without determining it.
VK_DBE_CODEINPUT 0x0fa Changes the mode to code input.
VK_DBE_NOCODEINPUT 0x0fb Changes the mode to no-code input.

Original equipment manufacturers should not use the unassigned portions of the VK mapping tables. Microsoft will assign these values in the future. If manufacturers require additional VK mappings, they should reuse some of the current manufacturer-specific and vendor-specific assignments.