2005年03月31日

在使用Apache AJP方式整合Tomcat集群之后,

如果启用sticky session,就可以关闭session replication功能,提高集群效率。

通过使用sticky session来减少session replication的开销,

并且不受session replication所要求的几个必要条件限制

(session replication最最麻烦的一点,

所有存放在Session中的Attribute必须序列化,

根据Sessiont同步机制,Attribute还得尽可能是不可变类的实例),

大大降低开发难度。

下面是效果图(两台tomcat上的test.jsp经过修改以显示出不同内容):

2005年03月30日
1.使用DNS轮询.
2.使用Apache R-proxy方式。
3.使用Apache mod_jk方式.
 
DNS轮询的缺点是,当集群中某台服务器停止之后,用户由于dns缓存的缘故,便无法访问服务,
必须等到dns解析更新,或者这台服务器重新启动。
还有就是必须把集群中的所有服务端口暴露给外界,没有用apache做前置代理的方式安全,
并且占用大量公网IP地址,而且tomcat还要负责处理静态网页资源,影响效率。
优点是集群配置最简单,dns设置也非常简单。
 
R-proxy的缺点是,当其中一台tomcat停止运行的时候,apache仍然会转发请求过去,导致502网关错误。
但是只要服务器再启动就不存在这个问题。
 
mod_jk方式的优点是,Apache 会自动检测到停止掉的tomcat,然后不再发请求过去。
缺点就是,当停止掉的tomcat服务器再次启动的时候,Apache检测不到,仍然不会转发请求过去。
 
R-proxy和mod_jk的共同优点是.可以只将Apache置于公网,节省公网IP地址资源。
可以通过设置来实现Apache专门负责处理静态网页,让Tomcat专门负责处理jsp和servlet等动态请求。
共同缺点是:如果前置Apache代理服务器停止运行,所有集群服务将无法对外提供。
R-proxy和mod_jk对静态页面请求的处理,都可以通设置来选取一个尽可能优化的效果。
这三种方式对实现最佳负载均衡都有一定不足,mod_jk相对好些,可以通过设置lbfactor参数来分配请求任务。
 
所有这些在实际使用中都应该根据具体情况来选择。
 
简略配置如下:
 
前期准备:
1。下载Apache和Tomcat:
Apache2.0.53:
http://www.eu.apache.org/dist/httpd/binaries/win32/apache_2.0.53-win32-x86-no_ssl.msi
 
Tomcat5.5.9:
http://www.eu.apache.org/dist/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9.zip
http://www.eu.apache.org/dist/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9-fulldocs.tar.gz
http://www.eu.apache.org/dist/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9-compat.zip
http://www.eu.apache.org/dist/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9-admin.zip
 
mod_jk.so
http://www.eu.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/win32/jk-1.2.8/mod_jk-1.2.8-apache-2.0.52.so
(可选,因为Apache2.0.53已经自带).
 
 
2.配置Tomcat集群。
同时发布有clusterapp这个web应用,,修改test.jsp,
使得打开:
http://192.168.9.235:12080/clusterapp/test.jsp
http://192.168.9.226:12080/clusterapp/test.jsp
看到的是不同的页面效果。
 
3.安装Apache2.0.53。
 
此时Tomcat集群的服务器为:
192.168.9.226:12080和192.168.9.235:12080
 
编辑c:/windows/system32/drivers/etc/host文件,
最后一行加上
127.0.0.1   lizongbo.com
 
先来R-proxy方式。
 
接下来是mod_jk方式。
 
重新启动apache,同样打开
不停的刷新这个页面,也将会看到页面显示出不同的内容。
 

参考资料:
Tomcat cluster:
http://www.onjava.com/onjava/2004/04/14/examples/tomcatclustering.zip
http://www.onjava.com/pub/a/onjava/2004/11/24/replication1.html
http://www.onjava.com/pub/a/onjava/2004/11/24/replication1.html?page=2
http://www.onjava.com/pub/a/onjava/2004/04/14/clustering.html
http://www.onjava.com/pub/a/onjava/2004/04/14/clustering.html?page=2
 
R-proxy:
 
mod_jk:
 
 
 
相对已经过时的资料(因为mod_jk2方式已经不被推荐,mod_jk2已经不再被更新了):
 
 
可能有用的资料:(因为我还没有仔细看过)
 
 
 
 

 
2005年03月20日
Tomcat5.5.x 的集群配置非常简单,几乎只需要取消server.xml的对cluster的注释即可。
并且每个服务器都必须部署了相同的webapp。
 
但是这样的情况,需要用如果要用到Session复制,而Session是基于Cookie的话,就必须与dns轮询配合才能够维持好会话状态。
使用URL重写的不存在这个问题。
 
或者使用前置一个负载均衡代理服务器进行url转发,这样的一般用于大量的访问而不涉及会话交互的场合,减少或者不使用session复制以减少集群压力。
 
weblogic的集群配置就太复杂了 :(
 
 
参考:
 
http://www.onjava.com/pub/a/onjava/2004/04/14/clustering.html?page=2
 
2005年03月15日
 
 
12.如果你的webapp需要只能够进行https方式访问,那么在webapp的web.xml里加上:
 <security-constraint>
  <web-resource-collection>
   <web-resource-name>must https</web-resource-name>
   <url-pattern>/lizongbo/*</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
   <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
 </security-constraint>
 
13.修改远程关闭服务器的命令。
server.xml默认有下面一行:
<Server port=”8005″ shutdown=”SHUTDOWN”>
这样允许任何人只要telnet到服务器的8005端口,输入”SHUTDOWN”,然后回车,服务器立即就被关掉了。
从安全的角度上考虑,我们需要把这个shutdown指令改成一个别人不容易猜测的字符串。
例如修改如下:
<Server port=”8006″ shutdown=”lizongbo”>,这样就只有在telnet到8006,并且输入”lizongbo”才能够关闭Tomcat.
注意:这个修改不影响shutdown.bat的执行。运行shutdown.bat一样可以关闭服务器。
 
 
 
 
14.配置http访问日志。Tomcat自带的能够记录的http访问日志已经很详细了
取消下面这段的注释:
 
        <Valve className=”org.apache.catalina.valves.AccessLogValve”
                 directory=”logs”  prefix=”localhost_access_log.” suffix=”.txt”
                 pattern=”common” resolveHosts=”false”/>
 
然后修改为:
        <Valve className=”org.apache.catalina.valves.FastCommonAccessLogValve”
                 directory=”logs”  prefix=”localhost_access_log.” suffix=”.txt”
                 pattern=”combined” resolveHosts=”false” fileDateFormat=”yyyy-MM-dd.HH”/>
 
pattern=”combined” 记录的日志内容更详细,fileDateFormat=”yyyy-MM-dd.HH”,会让日志文件按小时进行滚卷,
比默认的按天滚卷要好些,尤其是访问量大的网站,可以考虑写成fileDateFormat=”yyyy-MM-dd.HH.mm”,就会是每分钟一个日志文件了。
而且可以分别按Engine, Host, or Context,来记录自己的日志
详情参考:
而且还可以配合awstats来进行日志统计分析: http://www.chedong.com/tech/awstats.html
 
15.限制ip,限制主机访问等。
如果想禁止指定的ip或者主机名来拒绝某些机器访问,或者指定某些机器来访问。
也支持分别按Engine, Host, or Context,进行以下配置:
<Context path=”/examples” …>  …
  <Valve className=”org.apache.catalina.valves.RemoteHostValve”
         allow=”*.mycompany.com,www.yourcompany.com”/>
  <Valve className=”org.apache.catalina.valves.RemoteAddrValve”
         deny=”192.168.1.*”/>
</Context>
参考:
 
16.发布webapp到网站根目录
1。直接复制到ROOT目录下。
2.因为无法创建无名字的xml文件,并且在xml文件里指定path也是无效的(tomcat靠文件名字来判断的),
因此必须在server.xml里写下面一段:
<Context docBase=”${catalina.home}/vhost/www.lizongbo.com” path=”/”
         privileged=”true” antiResourceLocking=”false” antiJARLocking=”false”>
<Manager className=”org.apache.catalina.session.StandardManager” algorithm=”SHA-512″
entropy=”suijisifuchuansuijisifuchuansuijisifuchuansuijisifuchuan”
maxActiveSessions=”800″ />
        <Valve className=”org.apache.catalina.valves.FastCommonAccessLogValve”
                 directory=”logs”  prefix=”localhost_mytest_access_log.” suffix=”.txt”
                 pattern=”combined” resolveHosts=”true” fileDateFormat=”yyyy-MM-dd.HH”/>       
 
</Context>
而且必须把ROOT目录删除掉,否则Tomcat还是优先部署ROOT目录为”/”。
 
17.在重新启动Tomcat的webapp的时候,禁止把session写入文件。
修改conf/web.xml
取消注释:
 <!—->
    <Manager pathname=”" />
 
18.增强SessiionID的生成算法和长度。
 

         <Manager className=”org.apache.catalina.session.StandardManager” algorithm=”SHA-512″ sessionIdLength=”40″>
         </Manager>
 
(默认的是MD5,长度是16位。)
 
 

在D:\jakarta-tomcat-5.5.8\common\classes\新建log4j.properties

 
内容:
log4j.rootLogger=debug, R
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/tomcat5.5.log
log4j.appender.R.MaxFileSize=10MB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c – %m%n
log4j.logger.org.apache.catalina=DEBUG, R
log4j.logger.org.apache.catalina.core.ContainerBase.Catalina.localhost=DEBUG, R
log4j.logger.org.apache.catalina.core=DEBUG, R
log4j.logger.org.apache.catalina.session=DEBUG, R
复制log4j-1.2.9.jar和commons-logging.jar到
D:\jakarta-tomcat-5.5.8\common\lib
 
20.使用windows域用户验证
 
 
 
 
使用hsqldb将常用数据库整合到应用程序中
 
提到过一些常用数据库,可以视作固定编码的数据库。对于这些书库,通常只进行查询使用。
 
因此针对一些比如用户希望只传入ip地址就要查询到用户信息,或者只传入行政区划编号,
就可以得到行政区划名字等等需求。而且用户不希望去配置数据库信息等等,
Access文件虽然比较方便,却不具有跨平台的效果,因此可以借助开源免费的hsql来进行在应用小型数据库的嵌入。
尤其是在1.7.2版本加入了新的特性,可以支持在jar里直接以只读方式访问数据库。
因此,把封装好的class和数据文件一并打包,可以非常方便的给别人使用。
 
以下是操作过程,
首先下载hsql,最新的稳定版本是1.7.3.3:
 
下载ip数据库:
 
然后利用自带工具将其数据解压导出为文本文件
,用Editplus打开,替换掉  CZ88.NET,以减少文件占用空间,(使用正则表达式进行替换,将数据规整。
用xmlspy进行转换成xml再导入access,(这一步完全可以省略掉)),然后直接用access导入这195074条记录。
 
然后是从Access里导入数据
比如我的常用数据有ip地址信息表,行政区划和省份信表:
 //创建表
    connto.createStatement().execute(“CREATE TABLE PROVINCE(PDOMAIN VARCHAR(3),PLABEL VARCHAR(50),PNAME VARCHAR(6),PNO VARCHAR(3),PSHORTNAME VARCHAR(2))”);
    connto.createStatement().execute(
        “CREATE TABLE XZQH(NAME VARCHAR(30),CODE VARCHAR(6),O_CODE VARCHAR(8))”);
    connto.createStatement().execute(
        “CREATE TABLE IPINFO(IPS BIGINT,IPE BIGINT,AREA VARCHAR(60))”);
    ResultSet rs = stmtin.executeQuery(“SELECT * FROM province”);
 
 
PreparedStatement pstmt = connto.prepareStatement(
        “insert into province (pdomain,plabel,pname,pno,pshortname) values(?,?,?,?,?)”);
 
导入完成之后,将数据文件添加到jar文件中,再封装好常用方法。
就可以了,以后的数据维护也非常简单,只要不修改表结果,只需要把数据文件更新即可,不需要修改任何代码。
 
调用方法示例 :
先引入这个jar文件,然后使用下面的方法调用,
String area=com.lizongbo.database.SearchUtil.findAreabyIp(“192.168.9.1″);
 
使用者不需要关心任何其它的东西,一行代码就得到想要的结果了。
 
 
不过需要注意的是,使用了ip数据库之后,因为ip数据库记录量很大,生成的scrpit文件比较大,我的文件有22M,
打包压缩后的jar,也有 3M大小,初始化数据库的时候会非常缓慢。
综合考虑, 牺牲空间和一部分内存来换取应用程序的可复用和跨平台以及数据记录可维护性,还是比较值得的。
 
抓图:  
2005年03月12日
利用xml+xsl快速生成大量JSP的常用代码的方法.
 
参考Jbuilder的Servlet向导来使用xml+xsl产生JSP的常用代码。
xml样本:
 
<?xml version=”1.0″ encoding=”GB2312″?>
<?xml-stylesheet type=”text/xsl” href=”jspram.xsl”?>
<jsp xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”jspsrcgen.xsd”>
 <param>
  <variable>rloginusername</variable>
  <name>loginusername</name>
  <type>String</type>
  <src>request</src>
  <default>lizongbo</default>
  <desc>用户的登录名</desc>
 </param>
 <param>
  <variable>clastlogintime</variable>
  <name>lastlogintime</name>
  <type>long</type>
  <src>cookie</src>
  <default>0</default>
  <desc>用户最近一次的登录时间</desc>
 </param>
 <param>
  <variable>suserpass</variable>
  <name>userpass</name>
  <type>String</type>
  <src>session</src>
  <default>password</default>
  <desc>存放在session里的密码</desc>
 </param>
</jsp>
 
xsl文件略。
 
 
转换后的效果图和相关代码:
 

testjsp.jsp

变量名字 参数名字 变量类型 变量来源 默认值 备注
rloginusername loginusername String request lizongbo 用户的登录名
rloginusername loginusername String request lizongbo 用户的登录名
rloginusername loginusername String request lizongbo 用户的登录名
suserpass userpass String session password 存放在session里的密码
suserpass userpass String session password 存放在session里的密码
suserpass userpass String session password 存放在session里的密码
clastlogintime lastlogintime long cookie 0 用户最近一次的登录时间
clastlogintime lastlogintime long cookie 0 用户最近一次的登录时间
clastlogintime lastlogintime long cookie 0 用户最近一次的登录时间
生成好的java代码:
<%@page import=”com.lizongbo.util.JSPUtil”%>
//用户的登录名
String rloginusername = JSPUtil. getParameter(request,”loginusername”,lizongbo);
//用户的登录名
String rloginusername = JSPUtil. getParameter(request,”loginusername”,lizongbo);
//用户的登录名
String rloginusername = JSPUtil. getParameter(request,”loginusername”,lizongbo);
//存放在session里的密码
String suserpass = JSPUtil.getAttribute(session,”userpass”,password);
//存放在session里的密码
String suserpass = JSPUtil.getAttribute(session,”userpass”,password);
//存放在session里的密码
String suserpass = JSPUtil.getAttribute(session,”userpass”,password);
//用户最近一次的登录时间
long clastlogintime = JSPUtil. getValue(request.getCookies(),”lastlogintime”,0);
//用户最近一次的登录时间
long clastlogintime = JSPUtil. getValue(request.getCookies(),”lastlogintime”,0);
//用户最近一次的登录时间
long clastlogintime = JSPUtil. getValue(request.getCookies(),”lastlogintime”,0);
 
 
 
我封装的JSPUtil代码片断:
 
  public static string getparameter(httpservletrequest request, string name,
                                    string defval) {
    string param = request.getparameter(name);
    return (param != null ? param : defval);
  }
 
  public static boolean getparameter(httpservletrequest request, string name,
                                     boolean defval) {
    string bv = request.getparameter(name);
    return bv == null ? defval : parseboolean(bv);
 
  }
 
  public static double getparameter(httpservletrequest request, string name,
                                    double defval) {
    return parsedouble(request.getparameter(name), defval);
  }
 
  public static float getparameter(httpservletrequest request, string name,
                                   float defval) {
    return parsefloat(request.getparameter(name), defval);
  }
 
  public static int getparameter(httpservletrequest request, string name,
                                 int defval) {
    return parseint(request.getparameter(name), defval);
  }
 
  public static long getparameter(httpservletrequest request, string name,
                                  long defval) {
    return parselong(request.getparameter(name), defval);
  }
 
  public static short getparameter(httpservletrequest request, string name,
                                   short defval) {
    return parseshort(request.getparameter(name), defval);
  }

一般的javamil发送附件的代码如下:
                bodypart = new mimebodypart();
                datasource datasource = new filedatasource(“c:\测试附件.doc”);
                bodypart.setdatahandler(new datahandler(datasource));
                bodypart.setfilename(mimeutility.encodeword(“测试附件.doc”,”gb2312″, null));
                multipart.addbodypart(bodypart);
由于javamail 的包里默认的对javax.activation.datasource只有两个实现:
分别是:filedatasource和urldatasource。
因此在webapp里为了不把上传的文件再保存为本地文件,然后再使用filedatasource,
我结合apache的commons fileupload组件,写了一个实现了datasource的uploadfiledatasource。

其实代码非常简单,具体代码如下:

 

package com.lizongbo.util;

import java.io.*;

import javax.activation.*;
import org.apache.commons.fileupload.fileitem;

/**
 * <p>title: uploadfile datasource for javamail</p>
 * <p>description: </p>
 * <p>copyright: copyright (c) 2005</p>
 * <p>company: zongboli</p>
 * @author lizongbo
 * @version 1.0
 */
public class uploadfiledatasource implements datasource {
    private fileitem uploadfileitem = null;
    public uploadfiledatasource() {
    }

    public uploadfiledatasource(fileitem uploadfile) {
        this.uploadfileitem = uploadfile;
    }
    public string getcontenttype() {
        return uploadfileitem.getcontenttype();
    }

    public inputstream getinputstream() throws ioexception {
        return uploadfileitem.getinputstream();
    }

    public string getname() {
        return uploadfileitem.getname();
    }

    public outputstream getoutputstream() throws ioexception {
        return null;
    }

    public static void main(string[] args) {
    }
}

附在struts里的使用例子:

if (diskfileupload.ismultipartcontent(servletrequest)) {
            diskfileupload fileupload = new diskfileupload();
            fileupload.setsizemax(1024 * 1024);
            try {
                list filelist = fileupload.parserequest(servletrequest);
                iterator itr = filelist.iterator();
                fileitem item;
                while (itr.hasnext()) {
                    item = (fileitem) itr.next();
                    if (item.isformfield()) {
                        logger.debug(item.getfieldname() + “=” +
                                     item.getstring() + “”);
                    } else {
                     mimebodypart   bodypart = new mimebodypart();
                     datasource datasource = new com.webmail.util.uploadfiledatasource(item);
                     bodypart.setdatahandler(new datahandler(datasource));
                     multipart.addbodypart(bodypart);                    }
                }
            } catch (org.apache.commons.fileupload.fileuploadbase.
                     sizelimitexceededexception sle) {
                logger.debug(“size is too large”, sle);
            } catch (org.apache.commons.fileupload.fileuploadbase.
                     unknownsizeexception use) {
                logger.debug(“unknown size “, use);
            } catch (org.apache.commons.fileupload.fileuploadexception fue) {
                logger.debug(fue.getmessage() + “  “);
            } catch (exception e) {
                logger.debug(“chucuo”, e);
            }

        } else {
            logger.debug(“没有附件!!!”);
        }


由于《用javamail免认证方式发送邮件给163.com的用户的完整代码实例。》 代码被人copy直接运行, 给我带来了很大的麻烦(发了很多垃圾邮件到我邮箱 :( ),
从现在开始发布的代码,一律转为小写之后再进行发布,以仅供阅读参考。

 

2005年03月09日
 
 
SpamAssassin 在windows下的安装
 
SpamAssassin http://spamassassin.apache.org/ 是一个非常优秀的开源的反垃圾邮件过滤器。
支持很多邮件服务器。包括apache james,经过简单的配置,也可以使用SpamAssassin 来进行垃圾邮件过滤。
下面是在windows下安装SpamAssassin 的过程。
1.下载:
a.perl 5.8.6.811
 
b.SpamAssassin 3.0.2
 
c.nmake
 
 
2.安装,
a.先安装perl,运行按默认安装即可,我的安装在D:\Perl
b.运行Nmake15.exe,然后按提示在Nmake15.exe所在的目录下生成NMAKE.EXE和NMAKE.ERR,把这两个文件复制到D:\Perl\bin
c.在联网的状态下,进入到命令行,
运行。
 
c1.
D:\Perl\bin>ppm install DB_File
====================
Install ‘DB_File’ version 1.810 in ActivePerl 5.8.6.811.
====================
Installing D:\Perl\site\lib\auto\DB_File\DB_File.bs
Installing D:\Perl\site\lib\auto\DB_File\DB_File.dll
Installing D:\Perl\site\lib\auto\DB_File\DB_File.exp
Installing D:\Perl\site\lib\auto\DB_File\DB_File.lib
Installing D:\Perl\html\site\lib\DB_File.html
Files found in blib\arch: installing files in blib\lib into architecture depende
nt library tree
Installing D:\Perl\site\lib\DB_File.pm
Installing D:\Perl\site\lib\auto\DB_File\autosplit.ix
Successfully installed DB_File version 1.810 in ActivePerl 5.8.6.811.
 
 
c2.
 

D:\Perl\bin>ppm install HTML-Parser
Note: Package ‘HTML-Parser’ is already installed.

 
c3.
 

D:\Perl\bin>ppm install Digest-SHA1
Note: Package ‘Digest-SHA1′ is already installed.

 
c4.
 
D:\Perl\bin>ppm install Time-HiRes
====================
Install ‘Time-HiRes’ version 1.49 in ActivePerl 5.8.6.811.
====================
Installing D:\Perl\site\lib\auto\Time\HiRes\HiRes.bs
Installing D:\Perl\site\lib\auto\Time\HiRes\HiRes.dll
Installing D:\Perl\site\lib\auto\Time\HiRes\HiRes.exp
Installing D:\Perl\site\lib\auto\Time\HiRes\HiRes.lib
Installing D:\Perl\html\site\lib\Time\HiRes.html
Files found in blib\arch: installing files in blib\lib into architecture depende
nt library tree
Installing D:\Perl\site\lib\Time\HiRes.pm
Successfully installed Time-HiRes version 1.49 in ActivePerl 5.8.6.811.
 
c5.
 

D:\Perl\bin>ppm install IP-Country
====================
Install ‘Geography-Countries’ version 1.4 in ActivePerl 5.8.6.811.
====================
Installing D:\Perl\html\site\lib\Geography\Countries.html
Installing D:\Perl\site\lib\Geography\Countries.pm
Successfully installed Geography-Countries version 1.4 in ActivePerl 5.8.6.811.
====================
Install ‘IP-Country’ version 2.18 in ActivePerl 5.8.6.811.
====================
Installing D:\Perl\html\site\lib\IP\Authority.html
Installing D:\Perl\html\site\lib\IP\Country.html
Installing D:\Perl\html\site\lib\IP\Country\Fast.html
Installing D:\Perl\html\site\lib\IP\Country\MaxMind.html
Installing D:\Perl\html\site\lib\IP\Country\Medium.html
Installing D:\Perl\html\site\lib\IP\Country\Slow.html
Installing D:\Perl\html\bin\ip2cc.html
Installing D:\Perl\site\lib\IP\Authority.pm
Installing D:\Perl\site\lib\IP\Country.pm
Installing D:\Perl\site\lib\IP\Country\Fast.pm
Installing D:\Perl\site\lib\IP\Country\MaxMind.pm
Installing D:\Perl\site\lib\IP\Country\Medium.pm
Installing D:\Perl\site\lib\IP\Country\Slow.pm
Installing D:\Perl\site\lib\IP\Country\Fast\cc.gif
Installing D:\Perl\site\lib\IP\Country\Fast\ip.gif
Installing D:\Perl\site\lib\IP\Authority\auth.gif
Installing D:\Perl\site\lib\IP\Authority\ipauth.gif
Installing D:\Perl\bin\ip2cc
Installing D:\Perl\bin\ip2cc.bat
Successfully installed IP-Country version 2.18 in ActivePerl 5.8.6.811.
 
c6.
 

D:\Perl\bin>ppm install Mail-SPF-Query
====================
Install ‘Net-DNS’ version 0.48 in ActivePerl 5.8.6.811.
====================
Installing D:\Perl\html\site\lib\Net\DNS.html
Installing D:\Perl\html\site\lib\Net\DNS\FAQ.html
Installing D:\Perl\html\site\lib\Net\DNS\Header.html
Installing D:\Perl\html\site\lib\Net\DNS\Nameserver.html
Installing D:\Perl\html\site\lib\Net\DNS\Packet.html
Installing D:\Perl\html\site\lib\Net\DNS\Question.html
Installing D:\Perl\html\site\lib\Net\DNS\Resolver.html
Installing D:\Perl\html\site\lib\Net\DNS\RR.html
Installing D:\Perl\html\site\lib\Net\DNS\Update.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\A.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\AAAA.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\AFSDB.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\CERT.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\CNAME.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\DNAME.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\EID.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\HINFO.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\ISDN.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\LOC.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\MB.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\MG.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\MINFO.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\MR.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\MX.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\NAPTR.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\NIMLOC.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\NS.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\NSAP.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\NULL.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\OPT.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\PTR.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\PX.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\RP.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\RT.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\SOA.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\SRV.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\SSHFP.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\TKEY.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\TSIG.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\TXT.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\Unknown.html
Installing D:\Perl\html\site\lib\Net\DNS\RR\X25.html
Installing D:\Perl\html\site\lib\Net\DNS\Resolver\Base.html
Installing D:\Perl\html\site\lib\Net\DNS\Resolver\Cygwin.html
Installing D:\Perl\html\site\lib\Net\DNS\Resolver\Recurse.html
Installing D:\Perl\html\site\lib\Net\DNS\Resolver\UNIX.html
Installing D:\Perl\html\site\lib\Net\DNS\Resolver\Win32.html
Installing D:\Perl\site\lib\Net\DNS.pm
Installing D:\Perl\site\lib\Net\DNS\FAQ.pod
Installing D:\Perl\site\lib\Net\DNS\Header.pm
Installing D:\Perl\site\lib\Net\DNS\Nameserver.pm
Installing D:\Perl\site\lib\Net\DNS\Packet.pm
Installing D:\Perl\site\lib\Net\DNS\Question.pm
Installing D:\Perl\site\lib\Net\DNS\Resolver.pm
Installing D:\Perl\site\lib\Net\DNS\RR.pm
Installing D:\Perl\site\lib\Net\DNS\Update.pm
Installing D:\Perl\site\lib\Net\DNS\RR\A.pm
Installing D:\Perl\site\lib\Net\DNS\RR\AAAA.pm
Installing D:\Perl\site\lib\Net\DNS\RR\AFSDB.pm
Installing D:\Perl\site\lib\Net\DNS\RR\CERT.pm
Installing D:\Perl\site\lib\Net\DNS\RR\CNAME.pm
Installing D:\Perl\site\lib\Net\DNS\RR\DNAME.pm
Installing D:\Perl\site\lib\Net\DNS\RR\EID.pm
Installing D:\Perl\site\lib\Net\DNS\RR\HINFO.pm
Installing D:\Perl\site\lib\Net\DNS\RR\ISDN.pm
Installing D:\Perl\site\lib\Net\DNS\RR\LOC.pm
Installing D:\Perl\site\lib\Net\DNS\RR\MB.pm
Installing D:\Perl\site\lib\Net\DNS\RR\MG.pm
Installing D:\Perl\site\lib\Net\DNS\RR\MINFO.pm
Installing D:\Perl\site\lib\Net\DNS\RR\MR.pm
Installing D:\Perl\site\lib\Net\DNS\RR\MX.pm
Installing D:\Perl\site\lib\Net\DNS\RR\NAPTR.pm
Installing D:\Perl\site\lib\Net\DNS\RR\NIMLOC.pm
Installing D:\Perl\site\lib\Net\DNS\RR\NS.pm
Installing D:\Perl\site\lib\Net\DNS\RR\NSAP.pm
Installing D:\Perl\site\lib\Net\DNS\RR\NULL.pm
Installing D:\Perl\site\lib\Net\DNS\RR\OPT.pm
Installing D:\Perl\site\lib\Net\DNS\RR\PTR.pm
Installing D:\Perl\site\lib\Net\DNS\RR\PX.pm
Installing D:\Perl\site\lib\Net\DNS\RR\RP.pm
Installing D:\Perl\site\lib\Net\DNS\RR\RT.pm
Installing D:\Perl\site\lib\Net\DNS\RR\SOA.pm
Installing D:\Perl\site\lib\Net\DNS\RR\SRV.pm
Installing D:\Perl\site\lib\Net\DNS\RR\SSHFP.pm
Installing D:\Perl\site\lib\Net\DNS\RR\TKEY.pm
Installing D:\Perl\site\lib\Net\DNS\RR\TSIG.pm
Installing D:\Perl\site\lib\Net\DNS\RR\TXT.pm
Installing D:\Perl\site\lib\Net\DNS\RR\Unknown.pm
Installing D:\Perl\site\lib\Net\DNS\RR\X25.pm
Installing D:\Perl\site\lib\Net\DNS\Resolver\Base.pm
Installing D:\Perl\site\lib\Net\DNS\Resolver\Cygwin.pm
Installing D:\Perl\site\lib\Net\DNS\Resolver\Recurse.pm
Installing D:\Perl\site\lib\Net\DNS\Resolver\UNIX.pm
Installing D:\Perl\site\lib\Net\DNS\Resolver\Win32.pm
Successfully installed Net-DNS version 0.48 in ActivePerl 5.8.6.811.
Can’t remove directory C:\TEMP/Net-DNS-0-2784-1110293328/blib/html/site/lib/Net/
DNS: Directory not empty at D:/Perl/site/lib/PPM/Repository.pm line 247
Can’t remove directory C:\TEMP/Net-DNS-0-2784-1110293328/blib/html/site/lib/Net:
 Directory not empty at D:/Perl/site/lib/PPM/Repository.pm line 247
Can’t remove directory C:\TEMP/Net-DNS-0-2784-1110293328/blib/html/site/lib: Dir
ectory not empty at D:/Perl/site/lib/PPM/Repository.pm line 247
Can’t remove directory C:\TEMP/Net-DNS-0-2784-1110293328/blib/html/site: Directo
ry not empty at D:/Perl/site/lib/PPM/Repository.pm line 247
Can’t remove directory C:\TEMP/Net-DNS-0-2784-1110293328/blib/html: Directory no
t empty at D:/Perl/site/lib/PPM/Repository.pm line 247
Can’t remove directory C:\TEMP/Net-DNS-0-2784-1110293328/blib: Directory not emp
ty at D:/Perl/site/lib/PPM/Repository.pm line 247
Can’t remove directory C:\TEMP/Net-DNS-0-2784-1110293328: Directory not empty at
 D:/Perl/site/lib/PPM/Repository.pm line 247
====================
Install ‘Net-CIDR-Lite’ version 0.15 in ActivePerl 5.8.6.811.
====================
Installing D:\Perl\html\site\lib\Net\CIDR\Lite.html
Installing D:\Perl\site\lib\Net\CIDR\Lite.pm
Successfully installed Net-CIDR-Lite version 0.15 in ActivePerl 5.8.6.811.
====================
Install ‘Sys-Hostname-Long’ version 1.2 in ActivePerl 5.8.6.811.
====================
Installing D:\Perl\html\site\lib\Sys\Hostname\Long.html
Installing D:\Perl\site\lib\Sys\Hostname\Long.pm
Installing D:\Perl\site\lib\Sys\Hostname\testall.pl
Successfully installed Sys-Hostname-Long version 1.2 in ActivePerl 5.8.6.811.
====================
Install ‘Mail-SPF-Query’ version 1.997 in ActivePerl 5.8.6.811.
====================
Installing D:\Perl\html\site\lib\Mail\SPF\Query.html
Installing D:\Perl\site\lib\Mail\SPF\Query.pm
Installing D:\Perl\bin\spfd
Installing D:\Perl\bin\spfd.bat
Installing D:\Perl\bin\spfquery
Installing D:\Perl\bin\spfquery.bat
Successfully installed Mail-SPF-Query version 1.997 in ActivePerl 5.8.6.811.
 
 
c7.
 

D:\Perl\bin>ppm install Net-DNS
Note: Package ‘Net-DNS’ is already installed.
 
(在安装Mail-SPF-Query时被自动安装好了。)
 
 
 
d.解压Mail-SpamAssassin-3.0.2.zip,到D:\Mail-SpamAssassin-3.0.2
 
e.编译
 

D:\Perl\bin>cd D:\Mail-SpamAssassin-3.0.2
 
D:\Mail-SpamAssassin-3.0.2>PERL makefile.pl
Build spamc.exe (environment must be set up for C compiler)? (y/n) [y] n
What email address or URL should be used in the suspected-spam report
text for users who want more information on your filter installation?
(In particular, ISPs should change this to a local Postmaster contact)
default text: [the administrator of that system] lizongbo@gmail.com
 
Check network rules during ‘make test’ (test scripts may fail due to
network problems)? (y/n) [n] y
 
Checking if your kit is complete…
Looks good
Writing Makefile for Mail::SpamAssassin
Makefile written by ExtUtils::MakeMaker 6.17
 
 
 
f.nmake
 

D:\Mail-SpamAssassin-3.0.2>nmake
 
Microsoft (R) Program Maintenance Utility   Version 1.50
Copyright (c) Microsoft Corp 1988-94. All rights reserved.
 
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/AutoWhitelist.pm >blib\lib\Mail\Sp
mAssassin\AutoWhitelist.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Dns.pm >blib\lib\Mail\SpamAssassin
Dns.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Message/Metadata/Received.pm >blib
lib\Mail\SpamAssassin\Message\Metadata\Received.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Message/Metadata.pm >blib\lib\Mail
SpamAssassin\Message\Metadata.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/BayesStore.pm >blib\lib\Mail\SpamA
sassin\BayesStore.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Message/Node.pm >blib\lib\Mail\Spa
Assassin\Message\Node.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Locker.pm >blib\lib\Mail\SpamAssas
in\Locker.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/PluginHandler.pm >blib\lib\Mail\Sp
mAssassin\PluginHandler.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Conf.pm >blib\lib\Mail\SpamAssassi
\Conf.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Util.pm >blib\lib\Mail\SpamAssassi
\Util.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Message.pm >blib\lib\Mail\SpamAssa
sin\Message.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/ArchiveIterator.pm >blib\lib\Mail\
pamAssassin\ArchiveIterator.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/MailingList.pm >blib\lib\Mail\Spam
ssassin\MailingList.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Conf/Parser.pm >blib\lib\Mail\Spam
ssassin\Conf\Parser.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Reporter.pm >blib\lib\Mail\SpamAss
ssin\Reporter.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Locales.pm >blib\lib\Mail\SpamAssa
sin\Locales.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Conf/LDAP.pm >blib\lib\Mail\SpamAs
assin\Conf\LDAP.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/HTML.pm >blib\lib\Mail\SpamAssassi
\HTML.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/DBBasedAddrList.pm >blib\lib\Mail\
pamAssassin\DBBasedAddrList.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/SQLBasedAddrList.pm >blib\lib\Mail
SpamAssassin\SQLBasedAddrList.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Plugin/Hashcash.pm >blib\lib\Mail\
pamAssassin\Plugin\Hashcash.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Plugin.pm >blib\lib\Mail\SpamAssas
in\Plugin.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm >blib\lib\Mail\
pamAssassin\Plugin\URIDNSBL.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/PersistentAddrList.pm >blib\lib\Ma
l\SpamAssassin\PersistentAddrList.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin.pm >blib\lib\Mail\SpamAssassin.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Locker/Flock.pm >blib\lib\Mail\Spa
Assassin\Locker\Flock.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/BayesStore/SQL.pm >blib\lib\Mail\S
amAssassin\BayesStore\SQL.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Plugin/SPF.pm >blib\lib\Mail\SpamA
sassin\Plugin\SPF.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Bayes.pm >blib\lib\Mail\SpamAssass
n\Bayes.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Conf/SQL.pm >blib\lib\Mail\SpamAss
ssin\Conf\SQL.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/TextCat.pm >blib\lib\Mail\SpamAssa
sin\TextCat.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/NetSet.pm >blib\lib\Mail\SpamAssas
in\NetSet.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/PerMsgStatus.pm >blib\lib\Mail\Spa
Assassin\PerMsgStatus.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/BayesStore/DBM.pm >blib\lib\Mail\S
amAssassin\BayesStore\DBM.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Constants.pm >blib\lib\Mail\SpamAs
assin\Constants.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/PerMsgLearner.pm >blib\lib\Mail\Sp
mAssassin\PerMsgLearner.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/EvalTests.pm >blib\lib\Mail\SpamAs
assin\EvalTests.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Locker/Win32.pm >blib\lib\Mail\Spa
Assassin\Locker\Win32.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Plugin/RelayCountry.pm >blib\lib\M
il\SpamAssassin\Plugin\RelayCountry.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Locker/UnixNFSSafe.pm >blib\lib\Ma
l\SpamAssassin\Locker\UnixNFSSafe.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Plugin/Test.pm >blib\lib\Mail\Spam
ssassin\Plugin\Test.pm
D:\Perl\bin\perl.exe build/preprocessor -Mconditional -Mvars -DVERSION=3.000002
-DPREFIX=D:\Perl\site <lib/Mail/SpamAssassin/Util/RegistrarBoundaries.pm >blib\
ib\Mail\SpamAssassin\Util\RegistrarBoundaries.pm
        D:\Perl\bin\perl.exe build/preprocessor  -Mvars  -DVERSION=”3.000002″
DPREFIX=”D:\Perl\site”  -DDEF_RULES_DIR=”D:\Perl\site/share/spamassassin”  -DLO
AL_RULES_DIR=”D:\Perl\site/etc/mail/spamassassin”  -DINSTALLSITELIB=”D:\Perl\si
e\lib”  -DCONTACT_ADDRESS=”lizongbo@gmail.com” -Msharpbang  -DPERL_BIN=”D:\Perl
bin\perl.exe”  -DPERL_WARN=”"  -DPERL_TAINT=”" -m755 -isa-learn.raw -osa-learn
        D:\Perl\bin\perl.exe -MExtUtils::Command -e cp sa-learn blib\script\sa-
earn
        pl2bat.bat blib\script\sa-learn
        D:\Perl\bin\perl.exe build/preprocessor  -Mvars  -DVERSION=”3.000002″
DPREFIX=”D:\Perl\site”  -DDEF_RULES_DIR=”D:\Perl\site/share/spamassassin”  -DLO
AL_RULES_DIR=”D:\Perl\site/etc/mail/spamassassin”  -DINSTALLSITELIB=”D:\Perl\si
e\lib”  -DCONTACT_ADDRESS=”lizongbo@gmail.com” -Msharpbang  -DPERL_BIN=”D:\Perl
bin\perl.exe”  -DPERL_WARN=”"  -DPERL_TAINT=”" -m755 -ispamassassin.raw -ospama
sassin
        D:\Perl\bin\perl.exe -MExtUtils::Command -e cp spamassassin blib\script
spamassassin
        pl2bat.bat blib\script\spamassassin
 
D:\Mail-SpamAssassin-3.0.2>
 
g.安装
 

D:\Mail-SpamAssassin-3.0.2>nmake INSTALL
 
Microsoft (R) Program Maintenance Utility   Version 1.50
Copyright (c) Microsoft Corp 1988-94. All rights reserved.
 
Installing D:\Perl\site\lib\Mail\SpamAssassin.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\AutoWhitelist.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Dns.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\BayesStore.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Locker.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\PluginHandler.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Conf.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Util.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Message.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\ArchiveIterator.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\MailingList.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Reporter.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Locales.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\HTML.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\DBBasedAddrList.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\SQLBasedAddrList.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Plugin.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\PersistentAddrList.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Bayes.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\TextCat.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\NetSet.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\PerMsgStatus.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Constants.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\PerMsgLearner.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\EvalTests.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Message\Metadata.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Message\Node.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Message\Metadata\Received.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Conf\Parser.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Conf\LDAP.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Conf\SQL.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Plugin\Hashcash.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Plugin\URIDNSBL.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Plugin\SPF.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Plugin\RelayCountry.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Plugin\Test.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Locker\Flock.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Locker\Win32.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Locker\UnixNFSSafe.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\BayesStore\SQL.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\BayesStore\DBM.pm
Installing D:\Perl\site\lib\Mail\SpamAssassin\Util\RegistrarBoundaries.pm
Installing D:\Perl\bin\sa-learn
Installing D:\Perl\bin\sa-learn.bat
Installing D:\Perl\bin\spamassassin
Installing D:\Perl\bin\spamassassin.bat
Appending installation info to D:\Perl\lib/perllocal.pod
        D:\Perl\bin\perl.exe “-MExtUtils::Command” -e mkpath D:\Perl\site/etc/ma
il/spamassassin
        D:\Perl\bin\perl.exe -MFile::Spec -MFile::Copy  -e “copy(q{rules/local.c
f}, q{D:\Perl\site/etc/mail/spamassassin/local.cf}) unless -f q{D:\Perl\site/etc
/mail/spamassassin/local.cf};”
        D:\Perl\bin\perl.exe -MFile::Spec -MFile::Copy  -e “copy(q{rules/init.pr
e}, q{D:\Perl\site/etc/mail/spamassassin/init.pre}) unless -f q{D:\Perl\site/etc
/mail/spamassassin/init.pre};”
        D:\Perl\bin\perl.exe “-MExtUtils::Command” -e mkpath D:\Perl\site/share/
spamassassin
        D:\Perl\bin\perl.exe -e “map unlink, <D:\Perl\site/share/spamassassin/*>

        D:\Perl\bin\perl.exe build/preprocessor -Mvars  -DVERSION=”3.000002″  -D
PREFIX=”D:\Perl\site”  -DDEF_RULES_DIR=”D:\Perl\site/share/spamassassin”  -DLOCA
L_RULES_DIR=”D:\Perl\site/etc/mail/spamassassin”  -DINSTALLSITELIB=”D:\Perl\site
\lib”  -DCONTACT_ADDRESS=”lizongbo@gmail.com” -m644 -Irules -OD:\Perl\site/share
/spamassassin 10_misc.cf 20_anti_ratware.cf 20_body_tests.cf 20_compensate.cf 20
_dnsbl_tests.cf 20_drugs.cf 20_fake_helo_tests.cf 20_head_tests.cf 20_html_tests
.cf 20_meta_tests.cf 20_phrases.cf 20_porn.cf 20_ratware.cf 20_uri_tests.cf 23_b
ayes.cf 25_body_tests_es.cf 25_hashcash.cf 25_spf.cf 25_uribl.cf 30_text_de.cf 3
0_text_fr.cf 30_text_nl.cf 30_text_pl.cf 50_scores.cf 60_whitelist.cf user_prefs
.template triplets.txt languages
        D:\Perl\bin\perl.exe -MExtUtils::Command -e chmod 755 D:\Perl\site/share
/spamassassin
 
h.设置
记事本打开d:\perl\bin\spamasasssin.bat
在第二行(@echo off)后面加上下面两行:
SET RES_NAMESERVERS=192.168.9.1
SET LANG=zh_CN
 
 
 
 
 
 
下载垃圾邮件过滤规则文件:http://www.ccert.edu.cn/spam/sa/Chinese_rules.cf
然后覆盖:D:\Perl\site\etc\mail\spamassassin\local.cf
 
 
打开local.cf,在最后加上
 

use_razor2 0
use_dcc 0
use_pyzor 0

 
 

D:\Perl\site\etc\mail\spamassassin

新建pod.bat。
内容如下:
 
REM Run from the top of the SpamAssassin install directory
mkdir \spamdocs
mkdir \spamdocs\geek
mkdir \spamdocs\plugins
del \spamdocs\*.*
del \spamdocs\geek\*.*
del \spamdocs\plugins\*.*
call pod2html spamassassin.raw --outfile \spamdocs\spamassassin.html
call pod2html sa-learn. --outfile \spamdocs\sa-learn.html
call pod2html lib\mail\spamassassin\AutoWhiteList.pm --outfile \spamdocs\geek\AutoWhiteList.html
call pod2html lib\mail\spamassassin\Bayes.pm --outfile \spamdocs\Bayes.html
call pod2html lib\mail\spamassassin\Message\Metadata.pm --outfile \spamdocs\geek\MessageMetaData.html
call pod2html lib\mail\spamassassin\Message\Node.pm --outfile \spamdocs\geek\MessageNode.html
call pod2html lib\mail\spamassassin\BayesStore\SQL.pm --outfile \spamdocs\geek\BayesStoreSQL.html
call pod2html lib\mail\spamassassin\BayesStore.pm --outfile \spamdocs\geek\BayesStore.html
call pod2html lib\mail\spamassassin\conf.pm --outfile \spamdocs\conf.html
call pod2html lib\mail\spamassassin\Conf\SQL.pm --outfile \spamdocs\geek\confSQL.html
call pod2html lib\mail\spamassassin\Conf\LDAP.pm --outfile \spamdocs\geek\confLDAP.html
call pod2html lib\mail\spamassassin\Conf\Parser.pm --outfile \spamdocs\geek\confParser.html
call pod2html lib\mail\spamassassin\permsgstatus.pm --outfile \spamdocs\geek\permsgstatus.html
call pod2html lib\mail\spamassassin\message.pm --outfile \spamdocs\geek\message.html --quiet
call pod2html lib\mail\spamassassin\permsglearner.pm --outfile \spamdocs\geek\permsglearner.html
call pod2html lib\mail\spamassassin\plugin.pm --outfile \spamdocs\geek\PluginsArchitecture.html
call pod2html lib\mail\spamassassin\persistentaddrlist.pm --outfile \spamdocs\geek\Persistentaddrlist.html
call pod2html lib\mail\spamassassin\SQLBasedAddrList.pm --outfile \spamdocs\geek\SQLBasedAddrList.html
call pod2html lib\mail\spamassassin.pm --outfile \spamdocs\geek\spamassassinclass.html
cd lib\mail\spamassassin\plugin
for %%f in (*.*) do call pod2html %%f --outfile \spamdocs\plugins\%%f.html --quiet
cd ..\..\..\..
 
 测试:
 

D:\MAIL-S~1.2>spamassassin -D < sample-spam.txt
复制 D:\Mail-SpamAssassin-3.0.2\spamd\spamd.raw到D:\Perl\bin
 
参考 http://wiki.apache.org/spamassassin/SpamdOnWindows 制作SpamD.bat
运行SpamD.bat就可以启动spamassassin了。
 
 
 
参考:
 
 
2005年03月06日
1.把邮件保存为一个文件,这个文件可以直接用Outlook,Foxmail等邮件客户端工具打开。
 
 
    private void savemail(MimeMessage msg, String path) {
        try {
            File f = new File(path);
            f.getParentFile().mkdirs();
            FileOutputStream fo = new FileOutputStream(f);
//CRLFOutputStream 可以把一些换行符不满足MIME规范的邮件进行修正。
            CRLFOutputStream CRLFO = new CRLFOutputStream(fo);
            msg.writeTo(CRLFO);
            CRLFO.close();
            fo.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
 
调用:
 
savemail(msg,”c:/lizongbo/testmail.eml”);
 
2.对邮件体使用base64编码。
 
默认情况下使用的是quoted-printable编码:
示例如下:
 
    MimeMessage msg = new MimeMessage((Session)null);
    msg.setFrom(new InternetAddress(“lizongbo@gmail.com“));
    msg.setRecipient(Message.RecipientType.TO,
                     new InternetAddress(“lizongbo@msn.com“));
    msg.setText(“测试一下,邮件来自 http://www.donews.net/lizongbo !!!”);
    msg.setSubject(“测试标题!!!”, “GB2312″);
    MimeMultipart multipart = new MimeMultipart();
    MimeBodyPart txtbodyPart = new MimeBodyPart();
    txtbodyPart.setText(“这是一封html邮件,请用html方式察看!!!”);
    multipart.addBodyPart(txtbodyPart);
    MimeBodyPart htmlodyPart = new MimeBodyPart();
    String content=”html邮件内容!来自 http://www.donews.net/lizongbo “;
    content = “<html><body>” + content + “</body><html>”;
    htmlodyPart.setContent(content, “text/html;charset=GBK”);
    multipart.addBodyPart(htmlodyPart);
    msg.setContent(multipart);
    msg.saveChanges();
得到的邮件内容为:
————————————————————–
 
 
 
Subject: =?GB2312?B?suLK1LHqzOKjoaOho6E=?=
 
Mime-Version: 1.0
 
Content-Type: multipart/mixed; boundary=”—-=_Part_0_8568863.1110043294484″
 
 
 
——=_Part_0_8568863.1110043294484
 
Content-Type: text/plain; charset=GBK
 
Content-Transfer-Encoding: base64
 
 
 
1eLKx9K7t+JodG1s08q8/qOsx+vTw2h0bWy3vcq9suy/tKOho6GjoQ==
 
——=_Part_0_8568863.1110043294484
 
Content-Type: text/html;charset=GBK
 
Content-Transfer-Encoding: quoted-printable
 
 
 
<html><body>html=D3=CA=BC=FE=A3=A1 http://www.donews.net/lizongbo </body><h=
 
tml>
 
——=_Part_0_8568863.1110043294484–
 
 
 
 
 
————————————————————–
 
使用base64编码的代码:
————————————————————–
    MimeMessage msg = new MimeMessage( (Session)null);
    msg.setFrom(new InternetAddress(“lizongbo@gmail.com“));
    msg.setRecipient(Message.RecipientType.TO,
                     new InternetAddress(“lizongbo@msn.com“));
    msg.setText(“测试一下,邮件来自 http://www.donews.net/lizongbo !!!”);
    msg.setSubject(“测试标题!!!”, “GB2312″);
    MimeMultipart multipart = new MimeMultipart();
    MimeBodyPart txtbodyPart = new MimeBodyPart();
    txtbodyPart.setText(“这是一封html邮件,请用html方式察看!!!”);
    multipart.addBodyPart(txtbodyPart);
    MimeBodyPart htmlodyPart = new MimeBodyPart();
    String content = “html邮件! http://www.donews.net/lizongbo “;
    content = “<html><body>” + content + “</body><html>”;
    htmlodyPart.setContent(content, “text/html;charset=GBK”);
    //最最关键的就这么一行
    htmlodyPart.setHeader(“Content-Transfer-Encoding”, “base64″);
    multipart.addBodyPart(htmlodyPart);
    msg.setContent(multipart);
    msg.saveChanges();
 
得到邮件内容如下:
 
————————————————————–
 
 
 
Subject: =?GB2312?B?suLK1LHqzOKjoaOho6E=?=
 
Mime-Version: 1.0
 
Content-Type: multipart/mixed; boundary=”—-=_Part_0_8568863.1110043370687″
 
 
 
——=_Part_0_8568863.1110043370687
 
Content-Type: text/plain; charset=GBK
 
Content-Transfer-Encoding: base64
 
 
 
1eLKx9K7t+JodG1s08q8/qOsx+vTw2h0bWy3vcq9suy/tKOho6GjoQ==
 
——=_Part_0_8568863.1110043370687
 
Content-Type: text/html;charset=GBK
 
Content-Transfer-Encoding: base64
 
 
 
PGh0bWw+PGJvZHk+aHRtbNPKvP6joSBodHRwOi8vd3d3LmRvbmV3cy5uZXQvbGl6b25nYm8gPC9i
 
b2R5PjxodG1sPg==
 
——=_Part_0_8568863.1110043370687–
 
3.启动javamail的调试模式,可以在发送和接收邮件的时候方便查看详细的调试信息,只需要:
 
    //Session session = Session.getInstance(System.getProperties());
    session.getProperties().setProperty(“mail.debug”,”true”);
    session.setDebug(true);
//默认的是输出调试信息到控制台
 
4.显式连接到需要验证的smtp服务器进行邮件发送。
一般的资料都说是自己继承javax.mail.Authenticator.
代码如下:
 
package com.lizongbo.javamail;
 
 
import javax.mail.*;
 
public class MailAuthenticator extends Authenticator {
    public MailAuthenticator() {
    }
 
    private String mUser;
    private String mPass;
 
    public MailAuthenticator(String userName, String passWord) {
        super();
        mUser = userName;
        mPass = passWord;
    }
 
    public PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(mUser, mPass);
    }
 
}

调用的示例:
 Session session = Session.getInstance(System.getProperties(),new MailAuthenticator (“lizongbo”,”password”) );
    MimeMessage msg = new MimeMessage(session);
Transport.send(msg);
 
    其实也可以不继承这个class,而是直接使用用户名和密码连接到邮件服务器进行邮件发送操作。
    MimeMessage msg = new MimeMessage( (Session)null);
    msg.setFrom(new InternetAddress(“lizongbo@gmail.com“));
    msg.setRecipient(Message.RecipientType.TO,
                     new InternetAddress(“lizongbo@msn.com“));
    //中间代码略去
    msg.saveChanges();
    Transport smtpTransport = session.getTransport(“smtp”);
    smtpTransport.connect(“smtp.163.com”, 25, “lizongbo”, “password”);
    //切忌不可以使用 smtpTransport.send(msg)和smtpTransport.send(msg,msg.getAllRecipients());
    //因为这两个是静态方法,无法获取与smtpTransport这个实例有关的参数.
    smtpTransport.sendMessage(msg, msg.getAllRecipients());
 
具体可以通过阅读javamail1.3.2的源代码来发现一些细节差异。
 
2005年03月05日

java代码:

—————————————————————————————

package com.lizongbo;

import java.util.*;
import javax.mail.internet.*;
import javax.mail.*;

/**
 * <p>Title: javamail to 163 </p>
 *
 * <p>Description: 用javamail免认证方式发送邮件给163.com的用户,
 * 具体原理不在此作详细解说,有兴趣者请自行查阅相关资料。
 * /p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: lizongbo </p>
 *
 * @author lizongbo http://www.donews.net/lizongbo
 * @version 1.0
 */
public class javamail163 {

  public static void main(string[] args) throws addressexception,
      messagingexception {
    properties mailpro = new properties();
    mailpro.setproperty(“mail.smtp.host”, “202.108.44.210″);
    session session = session.getdefaultinstance(mailpro);
    session.setdebug(true);
    mimemessage msg = new mimemessage(session);
    msg.setfrom(new internetaddress(“lizongbo@gmail.com“));
    msg.setrecipient(message.recipienttype.to,
                     new internetaddress(“li_zongbo@163.com“));
    msg.setsubject(“测试免认证方式发送邮件!!!”);
    msg.settext(“测试一下,邮件来自 http://www.donews.net/lizongbo “);
    transport.send(msg);
  }
}


—————————————————————————————

执行结果:

—————————————————————————————

DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]

DEBUG SMTP: useEhlo true, useAuth false


DEBUG: SMTPTransport trying to connect to host “202.108.44.210″, port 25


DEBUG SMTP RCVD: 220 Coremail SMTP(Anti Spam) System (163com[20050206])


DEBUG: SMTPTransport connected to host “202.108.44.210″, port: 25


DEBUG SMTP SENT: EHLO lizongbo

DEBUG SMTP RCVD: 250-mx7
250-PIPELINING
250-AUTH LOGIN PLAIN NTLM
250-AUTH=LOGIN PLAIN NTLM
250 8BITMIME


DEBUG SMTP Found extension “PIPELINING”, arg “”

DEBUG SMTP Found extension “AUTH”, arg “LOGIN PLAIN NTLM”

DEBUG SMTP Found extension “AUTH=LOGIN”, arg “PLAIN NTLM”

DEBUG SMTP Found extension “8BITMIME”, arg “”

DEBUG SMTP: use8bit false

DEBUG SMTP SENT: MAIL FROM:<lizongbo@gmail.com>

DEBUG SMTP RCVD: 250 Ok


DEBUG SMTP SENT: RCPT TO:<li_zongbo@163.com>

DEBUG SMTP RCVD: 250 Ok


Verified Addresses

  li_zongbo@163.com

DEBUG SMTP SENT: DATA

DEBUG SMTP RCVD: 354 End data with <CR><LF>.<CR><LF>


DEBUG SMTP SENT:

.

DEBUG SMTP RCVD: 250 Ok: queued as NkBMWIV9KUKqYBoE.1


DEBUG SMTP SENT: QUIT