{ yeah : 必须哒 } No place to place should record our youth?

31Jul/101

HTTP Authentication When PHP Runs As CGI/PHPSuExec

Posted by alacner

呵呵,原来以前给一个linux服务器的页面做最简单的验证,习惯用WWW-Authenticate的方式,一般也没问题,今天用的时候发现godaddy的是fcgi模式的,无法获取到$_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']两个变量,所以google了下,发现了一篇解决方案,不错,分享下:

PHP is a feature-rich programming language that includes simple HTTP authentication. Unfortunately, if PHP is running under CGI then PHP scripts cannot use HTTP authentication. The workaround for this problem is to use mod_rewrite to pass HTTP authentication info to scripts as a GET parameter.

The following are step-by-step instructions on how to get HTTP authentication working when PHP is running as a CGI/PHPSuExec.

Step 1:
Create a plain text file using a text editor such as Windows Notepad.

Step 2:
Add the following text...
[cc lang='bash']

RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

[/cc]

Step 3:
Save the file as a plain text file. Name the file ".htaccess"

Step 4:
Upload the .htaccess file in ASCII mode to your web space using an FTP application.

Step 5:
Add the following in your PHP script right before your user/pass check routine.

[cc lang='php']
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
[/cc]

Example:
[cc lang='php']
// split user/pass parts
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));

// open user/pass prompt
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Your Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if Cancel button is used';
exit;
} else {
echo "

Greetings:

".$_SERVER['PHP_AUTH_USER'];
echo "

Password you entered:

".$_SERVER['PHP_AUTH_PW'];
}
?>
[/cc]

转自:http://www.sslcatacombnetworking.com/articles/http-authentication-php-cgi.html

31Jul/101

欢迎james和aida加入【必须哒】

Posted by alacner

在这太阳火辣辣的周末,当我听到james和aida也加入了【必须哒】创作共用博文平台,并且很快james就奉上一篇《MES》,让我觉得耳目一新,引领我了解了另外一块天地。当初,我和ofeng商定开创【必须哒】的目的也是为了记录平时我们遇到的一些点点滴滴,最后可以沉淀出一些知识,一些经验,和一些人生哲理,也许历经3年,5年,甚至10年20年之后,再来看这些“曾经”,也许别有风韵和无法用金钱能够衡量的价值。
所以在这预祝两位也能通过这个平台,找到一些乐趣。

31Jul/100

欢迎新博友:james,aida

Posted by 必须哒

热烈欢迎james和aida加入【必须哒】创作共用博文平台。

31Jul/101

MES

Posted by james

MES

最小有效规模(minimum efficient scale,MES)
最小有效规模(MES)指在长期中平均成本处于或接近其最小值的最小的规模。
一般表现为“长期平均成本下降”,即长期平均成本曲线呈下降趋势,下降的最低点。

市场结构决定于MES的大小与整个市场需求量的大小

  市场所能容纳的厂商数为市场的总需求除以MES。

  不难发现,最小有效规模是单位成本达到最小值时所要求的最小产出,一旦现有企业的规模达到该点,它就迫使新进入者做出选择,要么以更大的生产规模进入,并且现有企业强烈反击的风险;要么以小的生产规模进入,但要忍受产品成本高的劣势。

  由此可见,在其他条件一定的情况下,一个行业的最小有效规模越大,最小有效规模相对整体市场的比例越大,潜在进入者进入前后产品的价格差异越大,因而,潜在进入者进入的可能性越小。因此企业在现有条件下,尽可能提高最小有效规模,可以有效增加新进入者的进入难度。

  至于企业在什么条件下以低于最小有效规模进入新行业,取决于规模经济曲线的形状。如果规模经济曲线很陡,那么小规模进入所带来的成本劣势就越大。换言之,规模经济曲线越陡,小规模进入的可能性就越小。

  企业可以利用最小有效规模,并努力利用学习曲线增加规模经济曲线的斜率,构建行业进入障碍,从而有效地阻击潜在进入者。

从上图可以看出,关键的概念就是“长期平均成本(LAC,Long-run Average Cost)”和“生产规模”,而长期平均成本的计算方式是“长期总成本(LTC,Long-run Total Cost)”除以“生产规模”(在通信运营商中对应的是“用户数量”)。由此可见,“生产规模”(也即是“用户数量”)是决定因素。

Filed under: 游戏人生 1 Comment
31Jul/100

undefined reference to `libiconv_open‘ 导致无法编译PHP

Posted by alacner

[cc lang='bash']

./configure --with-mysql=/backup/mysql --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-curl --with-gd --enable-gd-native-ttf --with-apxs2=/usr/local/apache/bin/apxs --enable-sockets --with-iconv

[/cc]
make时提示:

[cc lang='bash']
.....................................................
ext/iconv/.libs/iconv.o(.text+0x1738): In function `zif_iconv_mime_encode':
/home/work/php-5.2.0/ext/iconv/iconv.c:1017: undefined reference to `libiconv_open'
ext/iconv/.libs/iconv.o(.text+0x1756):/home/work/php-5.2.0/ext/iconv/iconv.c:1031: undefined reference to `libiconv_open'
ext/iconv/.libs/iconv.o(.text+0x1993):/home/work/php-5.2.0/ext/iconv/iconv.c:1290: undefined reference to `libiconv_close'
ext/iconv/.libs/iconv.o(.text+0x19ad):/home/work/php-5.2.0/ext/iconv/iconv.c:1293: undefined reference to `libiconv_close'
ext/iconv/.libs/iconv.o(.text+0x1b01):/home/work/php-5.2.0/ext/iconv/iconv.c:1102: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o(.text+0x1b33):/home/work/php-5.2.0/ext/iconv/iconv.c:1134: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o(.text+0x1b5e):/home/work/php-5.2.0/ext/iconv/iconv.c:1150: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o(.text+0x1e10):/home/work/php-5.2.0/ext/iconv/iconv.c:1202: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o(.text+0x1e3c):/home/work/php-5.2.0/ext/iconv/iconv.c:1233: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o(.text+0x207f):/home/work/php-5.2.0/ext/iconv/iconv.c:1277: more undefined references to `libiconv' follow
ext/iconv/.libs/iconv.o(.text+0x2c08): In function `php_iconv_stream_filter_dtor':
/home/work/php-5.2.0/ext/iconv/iconv.c:2393: undefined reference to `libiconv_close'
ext/iconv/.libs/iconv.o(.text+0x2cf2): In function `php_iconv_stream_filter_append_bucket':
/home/work/php-5.2.0/ext/iconv/iconv.c:2543: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o(.text+0x2d34):/home/work/php-5.2.0/ext/iconv/iconv.c:2543: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o(.text+0x2de7):/home/work/php-5.2.0/ext/iconv/iconv.c:2465: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o(.text+0x30e2): In function `php_iconv_stream_filter_factory_create':
/home/work/php-5.2.0/ext/iconv/iconv.c:2419: undefined reference to `libiconv_open'
collect2: ld returned 1 exit status
make: *** [sapi/cli/php] Error 1

[/cc]

解决方法:

[cc lang='bash']
#wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.1.tar.gz
#tar -zxvf libiconv-1.13.1.tar.gz
#cd libiconv-1.13.1
# ./configure --prefix=/usr/local/libiconv
# make
# make install

[/cc]

再检查php

[cc lang='bash']
#./configure --with-mysql=/backup/mysql --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-curl --with-gd --enable-gd-native-ttf --with-apxs2=/usr/local/apache/bin/apxs --enable-sockets --with-iconv=/usr/local/libiconv
#make
#make install

[/cc]

另一种解决方法为去除iconv模块也能正常编译php,如下:
編輯 Makefile 大約 77 行左右的地方:
[cc lang='bash']

EXTRA_LIBS = ..... -lcrypt
[/cc]

在最後加上 -liconv,例如:
[cc lang='bash']

EXTRA_LIBS = ..... -lcrypt -liconv
[/cc]

再运行make就可以了。

最后一种方法:由tonyty163提供:

[cc lang='bash']

#make ZEND_EXTRA_LIBS='-liconv'
#make install

[/cc]

Tagged as: , No Comments
31Jul/100

删除旧网卡信息

Posted by alacner

网卡换了个插槽,进入系统时,设备管理器中就多出了个网卡Realtek RTL8139 Family PCI Fast Ethernet NIC #2 。我在局域网上网,给网卡设置IP地址时,提示冲突信息,不允许设置。请问怎么才能删除旧网卡Realtek RTL8139 Family PCI Fast Ethernet NIC ?
在windows2000中,利用”控制面板”中的添加/删除硬件”选项删除原有的网卡。启动”添加/删除硬件向导”,依次选择”卸载/拔插硬 件-卸载设备”,钩选”显示隐藏设备”,可以找到原来的网卡,卸载即可。

在windows xp中,没有”卸载/拔插设备管理器”,而且”设备管理器”中的”查看”选项中虽有”显示隐藏设备”选项,但并不会显示己经拔除的旧网卡。

方法一:”命令提示符下”显示隐藏设备 打开在windows xp的命令提示符,输入”set devmgr_show_nonpresent_devices=1”后回车,接着输入”start devmgmt.msc”,打开设备管理器,选择”查看”菜单中的”显示隐藏设备”,展开”网络适配器”,我们就会看到原有的网卡,卸载即可,从而释放原 来与它捆绑在一起的IP地址。

方法二:修改”环境变量” 打开系统属性窗口,选择”高级”选项,点击下方的”环境变量”。在当前用户变量或“系统变量”中,点击“新建”按钮,在“变量名”一栏中输入 “Devmgr_show_Nonpresent_Devices”,“变量值”一栏中输入“1”。最后,点击“确 定”按钮,关闭桌面窗口,重新打开“系统属性”中的“设备管理器”,选中“显示隐藏设备”,就可以随时查看真正隐藏的设备了。 这种方法也可以通过修改注册表来实现。

打开注册表编辑窗口,依次展开“HKEY-LOCAL-MACHINE\\System\\ ControlSet001\\coontrol\\session manage”,在Environment键下新建”字符串值”,命名为”Devmgr_Show_Nonpresent_Devices”,双击此键, 将”数据数值”高定为”1”。关闭注册表,重新启动windows xp或重新登录,就能看到真正隐藏的设备了。
============ save this with .reg =============
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment]
"Devmgr_Show_Nonpresent_Devices"="1"
===============================================

29Jul/102

如何在Eclipse中显示空格(space)和制表符(tab)

Posted by alacner

无废话版:Window->Preferences->General->Editors->Text Editors->Show whitespace characters

29Jul/102

[原创]邪恶的vpn+gamesearcher在windows7下玩dota(魔兽)

Posted by alacner

同学们,乡亲们,玩dota吗?没有一个流畅的对战平台可以耍大刀?玩dota非要去网吧吗?在家里几个人不能连起来玩吗?一定要路由器上吗?不,不,不,与ofeng一起,通过一晚的实验,无数次的重启机器,终于找到了破处结界的方法,那就是利用vpn将非局域网的同学们,逗她友们组成内网,这个实现方式很多,就不一一介绍了,大家可以google下(严禁百度,对搜百度引起的一系列问题概不解答),哥的路由机器型号Broadcom 9/0x456/45/0x25/0x2758  CPU型号 Broadcom BCM947XX  CPU频率  199.47 MHz Flash容量 8MB 内存 61.54(160多淘宝买的)已经刷成Tomato DualWan的双wan,这里要感谢某些同志免费提供给我网通线路,所以组成了双wan网络,并且路由器提供vpn的PPTP 服务器功能,只要简单的在路由器里面开启,然后将IP告诉各位dota玩友,大家就同时处于一个虚拟的局域网了,这里要特别注意,系统的防火墙要设置好,比如要开放Warcraft程序,开发vpn端口等等,也可以google下,就不在这次邪恶的讨论范围了。

插曲:互相ping通后,发现不管怎么设置,都不能在魔兽局域网创建中找到对方,这个相当纠结,我们尝试了非常多的方法,甚至,连呼:曾哥,曾哥,我信你,春哥,春哥,我信你,如此重的口味居然都不能让我们创建的游戏被对方发现,我等凡人彻底蒙了,想起了98时代,需要装ipx协议,windows7下没有,怎么办,到处找,居然也有人提供了,越过N多黄图的干扰,在一堆无法理解的页面,在几乎不可见的地方点击了download,下载、安装,嗝屁,没用……

我等正准备剖腹自我了断的时候(旋外音:为什么?)为什么?我们怎么也混成IT淫才,10几年的接触电脑史,我们重装系统的次数,比你吃过的米还多,这都不会,以后还怎么在江湖上混?还如何去见电脑市场的奸商朋友们?所以我们毅然决定自我了断。正当举刀将落的刹那,ofeng资深提到了“我去下载个war3 搜索器”那就是黑暗中的一缕阳光,屎堆里的一朵鲜花~同时进行google,终于分别找到了一个,哈哈,ofeng估计只信了春哥,没信曾哥,所以下载的不能运行,哈哈,我比他多信了曾哥,所以下下来就能用了,那邪恶的软件,将创建了游戏的IP填入查找,然后几秒后就勾搭上了,此时点开始,就进入了纠结了无数次的游戏界面……,终于连上了……

接下里就是玩了,水平那啥,dota剧情就不能多说了,你懂的!~

gamesearcher软件我就不放了,也不详细介绍了,功能非常少,不懂或者软件找不到的可以回我, 我会解答~

28Jul/101

(转)C++中extern “C”含义深层探索

Posted by ofeng

1.引言

C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同。作为一种欲与C兼容的语言,C++保留了一部分过程式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数。但是,C++毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同。

2.从标准头文件说起

某企业曾经给出如下的一道面试题:

面试题
为什么标准头文件都有类似以下的结构?
[cc lang='c' ]
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
#endif /* __INCvxWorksh */
[/cc]

显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用是防止该头文件被重复引用。
那么
[cc lang="c"]
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
[/cc]
的作用又是什么呢?我们将在下文一一道来。

3.深层揭密extern "C"

extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。让我们来详细解读这两重含义。

被extern "C"限定的函数或变量是extern类型的;

extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。记住,下列语句:

extern int a;

仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。

通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数。

与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。

被extern "C"修饰的变量和函数是按照C语言方式编译和连接的;

未加extern “C”声明时的编译方式

首先看看C++中对类似C的函数是怎样编译的。

作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:

void foo( int x, int y );

该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。

_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数void foo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。
同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。

未加extern "C"声明时的连接方式

假设在C++中,模块A的头文件如下:
[cc lang="c"]
// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
int foo( int x, int y );
#endif
[/cc]

在模块B中引用该函数:
[cc lang="c"]
// 模块B实现文件 moduleB.cpp
#include "moduleA.h"
foo(2,3);
[/cc]

实际上,在连接阶段,连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号!

  加extern "C"声明后的编译和连接方式

  加extern "C"声明后,模块A的头文件变为:
[cc lang="c"]
// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
extern "C" int foo( int x, int y );
#endif
[/cc]
在模块B的实现文件中仍然调用foo( 2,3 ),其结果是:

  (1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,采用了C语言的方式;

  (2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。

  如果在模块A中函数声明了foo为extern "C"类型,而模块B中包含的是extern int foo( int x, int y ) ,则模块B找不到模块A中的函数;反之亦然。

  所以,可以用一句话概括extern “C”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语言是怎么做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更深入地理解许多问题):
  实现C++与C及其它语言的混合编程。
  明白了C++中extern "C"的设立动机,我们下面来具体分析extern "C"通常的使用技巧。

4.extern "C"的惯用法
  (1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:
[cc lang="c"]
extern "C"
{
#include "cExample.h"
}
[/cc]

而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。

  笔者编写的C++引用C函数例子工程中包含的三个文件的源代码如下:
[cc lang="c"]
/* c语言头文件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);
#endif
/* c语言实现文件:cExample.c */
#include "cExample.h"
int add( int x, int y )
{
return x + y;
}
// c++实现文件,调用add:cppFile.cpp
extern "C"
{
#include "cExample.h"
}
int main(int argc, char* argv[])
{
add(2,3);
return 0;
}
[/cc]

  如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern "C" { }。

  (2)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern "C",但是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型。
  笔者编写的C引用C++函数例子工程中包含的三个文件的源代码如下:
[cc lang="c++"]
//C++头文件 cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H
extern "C" int add( int x, int y );
#endif
//C++实现文件 cppExample.cpp
#include "cppExample.h"
int add( int x, int y )
{
return x + y;
}
/* C实现文件 cFile.c
/* 这样会编译出错:#include "cExample.h" */
extern int add( int x, int y );
int main( int argc, char* argv[] )
{
add( 2, 3 );
return 0;
}
[/cc]

Tagged as: , 1 Comment
27Jul/101

五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT) – 整理

Posted by alacner

当Adobe、Microsoft、Sun等一系列巨头开始表现出对”开源”的青睐时,”开源”的时代即将到来!

最初来自:sinoprise.com/read.php?tid-662-page-e-fpage-1.html(遗憾的是这个链接已经打不开了),我基本未改动,只是进行了一些排版和整理。
参考文献:http://www.fsf.org/licensing/licenses/

现今存在的开源协议很多,而经过Open Source Initiative组织通过批准的开源协议目前有58种(http://www.opensource.org/licenses/alphabetical)。我们在常见的开源协议如BSD, GPL, LGPL,MIT等都是OSI批准的协议。如果要开源自己的代码,最好也是选择这些被批准的开源协议。

这里我们来看四种最常用的开源协议及它们的适用范围,供那些准备开源或者使用开源产品的开发人员/厂家参考。

BSD开源协议(original BSD licenseFreeBSD licenseOriginal BSD license

BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。

但”为所欲为”的前提当你发布使用了BSD协议的代码,或则以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件:

  1. 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
  2. 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
  3. 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。

BSD 代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议,因为可以完全控制这些第三方的代码,在必要的时候可以修改或者二次开发。

Apache Licence 2.0(Apache License, Version 2.0Apache License, Version 1.1Apache License, Version 1.0

Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,同样鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)。需要满足的条件也和BSD类似:

  1. 需要给代码的用户一份Apache Licence
  2. 如果你修改了代码,需要再被修改的文件中说明。
  3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
  4. 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。

Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。

GPL(GNU General Public License

我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux,包括商业公司的linux和linux上各种各样的由个人,组织,以及商业软件公司开发的免费软件了。

GPL协议的主要内容是只要在一个软件中使用(“使用”指类库引用,修改后的代码或者衍生代码)GPL 协议的产品,则该软件产品必须也采用GPL协议,既必须也是开源和免费。这就是所谓的”传染性”。GPL协议的产品作为一个单独的产品使用没有任何问题,还可以享受免费的优势。

由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议,对于使用GPL协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。

其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。

LGPL(GNU Lesser General Public License

LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL 允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并发布和销售。

但是如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。

GPL/LGPL都保障原作者的知识产权,避免有人利用开源代码复制并开发类似的产品

MIT(MIT

MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制.也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的.

本文来自:http://www.awflasher.com/blog/archives/939