2005年08月26日

使用Apache 2和MySQL 4.1.3安装PHP 5.0
 

经过几个月期待,PHP 5.0终于问世。在最新版本中,推出了具有非常重要性的编程语言特性,这些改变将博得新手和有经验的程序员的满意。这些更新包括:一个内部SQLite数据库,通过libxml2提高XML API运行的可靠性,一个可以重新设计的对象模型以及一个新推出的Zend Engine。
你肯定渴望采用PHP 5.0来开始你的开发工作。但是,既然你一定编译和安装PHP 5.0,为什么不将其升级成一个完全的LAMP(Linux,Apache,MySQL,PHP)开发环境呢?毕竟,过去的几个月中,已经发布了一系列新的版本:MySQL 4.1.3,其支持字符设置,自动校正,子查询和处理记录; Apache 2.0具有很好的稳定性。
我准备告诉你使用PHP 5.0,Apache 2.0和MySQL 4.1.3.来安装一个高效率PHP开发环境的过程,让我们开始吧!

 

基本条件

假定你已经安装了Linux版本,而且它能够正确运行。请确信系统中已经安装一个可以运行的C语言编译器,否则我们的操作就不能进行。
而且,还需要确定已经下载了所有相关软件:
最新MySQL版本(即现在的MySQL 4.1.3测试版),可以从MySQL.com(http://www.mysql.com/)下载。
最新的PHP版本(即现在的PHP 5.0.0),可从Php.net (http://www.php.net/downloads.php)下载。
最新的Apache 2版本(即现在的Apache 2.0.50),从Apache.org(http://httpd.apache.org/)下载。
最重要的一点是:在这些版本中,Apache 2.0和PHP 5.0的结合并不是天衣无缝,所以不应该同时用于同一系统中。但是,这种结合应该对开发系统是有好处的。
你可能还需要以下的支持库:
最新版本的libxml2库(现在的libxml2 2.6.11),从XmlSoft.org(http://www.xmlsoft.org/)下载。
最新版本的zlib库(现在的zlib 1.2.1)从Gzip.org (http://www.gzip.org/zlib/)下载。

把所有的东西都复制到你的/tmp子目录,并进行解压,如下所示:

$ cd /tmp
$ tar -xzvf mysql-standard-4.1.3-beta-pc-linux-i686.tar.gz
$ tar -xzvf php-5.0.0.tar.gz
$ tar -xzvf httpd-2.0.50.tar.gz
$ tar -xzvf libxml2-2.6.11.tar.gz
$ tar -xzvf zlib-1.2.1.tar.gz

安装支持库

第一步,检查你是否安装了libxml2或者zlib。PHP 5.0要求libxml2 2.6.0(或者是比libxml2 2.6.0更好的版本)和zlib 1.0.9(或者是比zlib 1.0.9更好的版本)。如果这两个支持库都没有,保持只读形式,否则进入下一部分。

 

 

开始时,编译和安装libxml2 XML解析器,这一解析器提供PHP 5.0新的XML APL:

$ cd /tmp/libxml2-2.6.11
$ ./configure
$ make && make install

这一步结束时,libxml2被安装在/usr/local/下。如果你想把它安装在其它地方,你应该在先前步骤中明确指定prefix选项到configure设置中。

第二步:对zlib做类似的操作:

$ cd /tmp/zlib-1.2.1
$ ./configure
$ make && make install

这一步结束时,zlib也被安装在/usr/local/下。你可以不使用默认值,而使用指定prefix选项将其安装到其它地方。

 


安装Apache

以Apache使用PHP有两种方式:作为动态模块,其在运行状态时可载入到Web服务器,或者作为静态模块,其可直接编译到Web服务器代码中。对于本文,我们着重于第一种方式。

为了能以Apache2.0模块使PHP动态载入,Apache服务器必须以动态共享对象(DSO, Dynamic Shared Object)编译。可以通过传递–enable-so参数到Apache 2.0 configure使这一特性生效:

$ cd /tmp/httpd-2.0.50
$ ./configure –prefix=/usr/local/apache2 –enable-so $ make
&& make install

这一过程将会设置,编译,以及将服务器安装到/usr/local/apache2。

 

完成MySQL和Apache的安装之后,最后的一步即为编译和安装PHP。这一步骤中,最为关键的一步是使用一系列的激发扩展功能提供PHP configure,以及外部类库正确的文件路径。表A为其中的例子:


表 A

$ cd /tmp/php-5.0.0
$ ./configure –prefix=/usr/local/php5
–with-apxs2=/usr/local/apache2/bin/apxs
–with-libxml-dir=/usr/local/lib
–with-zlib –with-zlib-dir=/usr/local/lib
–with-mysql=/usr/local/mysql
–with-mysqli=/usr/local/mysql/bin/mysql_config
–with-gd –enable-soap –enable-sockets

以上例子看起来相当复杂,然而事实并非如此:

–prefix设置PHP5 的安装路径。

–with-apxs2告诉PHP查找Apache 2.0的地方。

–with-libxml-dir和 –with-zlib-dir告诉PHP放置libxml2和zlib库的地方。

–with-mysql变量激活regularMySQL扩展功能。

–with-mysqli变量激活新增加的MySQL功能。

–with-gd变量激活 GD 扩展功能。

–with-zlib变量激活ZLIB 压缩库。

–enable-sockets变量激活socket通讯特性。

–enable-soap变量激活SOAP和Web services支持。

 

当然,也可以尝试其它选项和扩展功能:

$ ./configure –help

一旦configure已经完成,你即可编译和安装PHP。

$ make
$ make install

可以注意到,这些安装过程能够自动将PHP模块安装在正确目录下,以便Apache 2.0的查找。

 

使用PHP配置和测试Apache

已经完成?还没有呢!最后一步包括,配置Apache以识别PHP代码,然后发送到PHP解释器。为了实现这一过程,编辑Apache配置文件,即/usr/local/apache2/conf/httpd.conf,并添加以下一行:

AddType application/x-httpd-php .php

保存文件并启动服务器:

$ /usr/local/apache2/bin/apachectl start [/output]

现在,你可以测试一切是否可以正常运行,你可以在服务器文档目录/usr/local/apache2/htdocs/建立一个简单的测试程序。

将这一程序命名为test.php,并增加以下几行:

<?php
phpinfo();
?>

保存文件,并将浏览器地址指向http://localhost/test.php

2005年08月24日

Introduction

    The exception mechanism is an esstential feature of most modern programming lanaugages. Providing a uniform scheme for the reporting and handling of all sorts of "failure" situations, exceptions have replaced many informal practices which were used by programmers whenever a piece of code (usually a function) could fail.
    However, a subtle issue arises when considering the combination of exceptions and constructors: It is not obvious how is it possible for a constructor to catch an exception thrown by a constructor of a data members. This document discusses this problem and its solution, in the context of the C++ programming language. Although the problem is relevant to other object-oriented languages, C++ is unique in its value-semantics approach, which makes the solution a little more complicated than in reference-semantics languages (namely: Java, C#).


Problem overview (or: "Where is the catch?")

    Let us look at this simple program which defines a String class that represents a fixed-size sequence of characters. A String instance is initialized – at construction time – with a sequence of blank (space) characters. The clients of class String can either observe or change the contents of the sequence by String’s subscript operator, operator[].

struct BufError { };

struct Buf {
   char* array_;
  
   Buf(int sz)
   {
      array_ = (char*) malloc(sz);
      if(array_ == 0)
         throw BufError();
   }
  
   ~Buf() { free(array_); }
  
   char& at(int offset) { return array_[offset]; }
};

struct StringError { };

struct String {
   Buf buf_;
   int limit_;

   String(int limit) : limit_(limit), buf_(limit)
   {
      for(int i = 0; i < limit; ++i)
         (*this)[i] = ‘ ‘;
   }
  
   char& operator[](int offset)
   {
      if(offset < 0 || offset >= limit_)
         throw StringError();
      else
         return buf_.at(index);
   }  
};

int main(int argc, char* argv)
{
   try
   {
      String s(200);
      s[0] = ‘A’;
      cout << s[0] << endl; // Output: ‘A’
   }
   catch(BufError& be)
   {
      cerr << "Some String failure" << endl;
   }
   catch(StringError& se)
   {
       cerr << "Some String failure" << endl;
   }
   return 0;
}


    Looking at the source code of String we see that it uses a data member of type Buf to maintain the memory area where the characters are actually stored. Note that the compiler makes sure that every non primitive data member is initialized by the constructor. Specifically, class Buf does not have a default constructor, therefore, it is explictly initialized by String’s constructor.

    In order to examine the subtle problem of exceptions and constructors, let us consider the possiblity of a memory exhaustation. If no memory is available, the constructor of Buf will throw a BufError exception, which will propegate through the call stack up to the catch(BufError& be) clause in main(). However, when insepcting the body of main() we see that there is no difference between a BufError exception and a StringError exception: From main()’s point of view these two exceptions reflect an arbitrary problem with its local variable s.

    It is obvious that the code of main() will be more natural and simple if it had to cope with only a single type of exception, namely: StringError, instead of two distinct types. Given that it is not always possible to modify the source code of library classes (specifically, to change the type of thrown exceptions), a general solution requires that class String will convert BufError exceptions into a StringError exception.


The Solution

    At first it seems that there is no syntactically legal way to encolse the initializers of data members within a try block. Nonetheless, it turns out that the C++ language does provide the appropriate means for solving this difficulty, using a special kind of a try statement which is formally called "function-try-block". This rarely used feature allows the corresponding catch part to handle ALL exception that were thrown during the execution of the constructor, including those the were emitted by constructors of data members.

    The following source code uses an function-try-block to convert a BufError exception into a StringError exception. Pay attention to the try keyword added to String’s constructor.

struct BufError { };

struct Buf {
   char* array_;
  
   Buf(int sz)
   {
      array_ = (char*) malloc(sz);
      if(array_ == 0)
         throw BufError();
   }
  
   ~Buf() { free(array_); }
  
   char& operator[](int offset) { return array_[offset]; }
};

struct StringError { };

struct String {
   Buf buf_;
   int limit_;

   String(int limit)
   try
      : limit_(limit), buf_(limit)
   {
      for(int i = 0; i < limit; ++i)
         (*this)[i] = ‘ ‘;         
   }
   catch(BufError& )
   {
      throw StringError();
   }
  
   char& operator[](int offset)
   {
      if(offset < 0 || offset >= limit_)
         throw StringError();
      else
         return buf_[index];
   }  
};

int main(int argc, char* argv)
{
   try
   {
      String s(200);
      s[0] = ‘A’;
      cout << s[0] << endl; // Output: ‘A’
   }
   catch(StringError& se)
   {
       cerr << "Some String failure" << endl;
   }
   return 0;
}


Additional Comments

    Compatibility. Not all compilers support exception-try-blocks. For instance, only the most recent version of Microsoft’s Visual C++ compiler support exception-try-blocks. On the other hand, the GCC provides this feature for quite a long time now.

    Function-try-blocks are not limited to constructors. Any member function or file-scope function can use them. For instance, the divide() function below, returns 0 if an exception occurs during its execution, ensuring that calls such as divide(5,0) yield a 0 result. Nonetheless, A function-try-blocks is not really needed in member functions since it is equivalent to a "normal" try block that starts before the very first statement within the function and ends immediately after the last statement.

static int divide(int x, int y)
try
{
   return x / y;
}
catch(…)
{
   return 0;
}


    Initialization exceptions cannot be hidden. In constructors, a function-try-blocks must throw an exception, or rethrow the same exception it caught. It cannot just absorb an exception and then let the execution continue as if nothing went wrong. Even if you provide and ”do nothing” catch clause to a function-try-block, the compiler will make sure that the exception is rethrown when the catch clause is exited. Consequently, the two version of class A, below, are equivalent.


// Version 1
struct A {
    Buf b_;
    A(int n) try : b_(n) {
        cout << "A initialized" << endl;
    } catch(BufError& ) {
        cout << "BufError caught" << endl;
    }
};

// Version 2
struct A {
    Buf b_;
    A(int n) try : b_(n) {
        cout << "A initialized" << endl;
    } catch(BufError& be) {
        cout << "BufError caught" << endl;
        throw;
    }
};

2005年08月16日

搭建自己的Blog平台 — WordPress 新手指南


示例Blog网站 http://wordpress.hugmor.com/

1、什么是WordPress?
  WordPress是一款基于PHP和MySQL的Blog软件,通过它可以快速而简便的搭建属于你自己的Blog平台,目前的最新版本是1.5.1.2版,版本代号是“Strayhorn”。
 
2、安装WordPress的准备工作
  A、首先需要有一个支持PHP和MYSQL的空间,而且根据WordPress的说明文档(readme.html),要求PHP 的版本在4.1以上, MySQL的版本在3.23.23 以上。至于空间的大小,可以根据个人需要来定,WordPress的安装文件是1M左右。
  B、下载WordPress的最新安装包,可以去这里下载:WordPress下载页面(英文版)</a>。可以在网上搜索“WordPress 中文版 ”或直接去中文WordPress 下载。
  C、解压缩,然后将wp-config-sample.php更名为wp-config.php,并使用你所喜欢的文本编辑器(操作系统自带的写字板、记事本等)来进行设置,修改它的前几句,按照你的数据库配置来定义。
  define(’DB_NAME’, ‘数据库名’); // The name of the database
  define(’DB_USER’, ‘MYSQL用户名’); // Your MySQL username
  define(’DB_PASSWORD’, ‘密码’); // …and password
  define(’DB_HOST’, ‘localhost’); // 99% chance you won’t need to change this value
  (这些参数可以从你的主机提供商那里取得)。里面的table_prefix选项是设置MYSQL 数据库里面的数据表的前缀,define (’WPLANG’, ‘’)则是用来设置语言支持,英文版不变,中文版为(’WPLANG’,‘zh_CN‘)。
  D、设置修改完成之后,保存文件,这样前期的准备工具就OK了。
  
3、WordPress的安装进程
  A、使用你所喜爱的FTP客户端软件把WordPress的安装文件上传到你的主机www服务的根目录下(如/var/www/html)。
  B、在浏览器输入:http://网址/wordpress/,程序会自动检测并安装。
  C、安装完成后,系统会给你一个随机生成的管理员密码,记住这个密码,并使用admin和那个密码登录管理界面,在管理界面的Profile选项里修改密码、并修改设置详细的个性信息。如果你能够到这一步,那么恭喜你,你的WordPress就安装完成了。
  D、更多的安装帮助请参考WordPress安装包里面的Readme.html,以及访问官方网站

4、修改界面(主题theme)
  A、下载主题:可以在WordPress ThemesWordPress Reference CentreAlexkingBlogging Pro下载到一些漂亮的主题。
  B、安装主题:将下载来的主题解压,并保留目录结构,将整个文件夹上传到/wordpress/wp-content/themes/目录下,然后进入管理界面,在Presentation里(如果你安装了中文版,就是“表现”项)选择上传好的主题。
  C、修改主题:要修改主题需要先将主题文件夹及里面的文件属性改为“777”,在FTP中右键点击,使用chmod选项修改。然后在Presentation里(如果你安装了中文版,就是“表现”项)里的Theme Editor(主题编辑)项就可以直接修改了。

5、安装插件
  A、常用的 桑椹做的WordPress 评论插件,可以显示最近评论。其他可到WordPress PluginsWordPress Plugin RepositoryWordpress Plugin Database下载。
  B、安装插件:将下载来的插件解压,并保留目录结构,将整个文件夹上传到/wordpress/wp-content/plugins/目录下,然后进入管理界面,在Plugins里(如果你安装了中文版,就是“插件”项)激活上传好的插件。
  C、在需要显示的地方加入调用的语言,如桑椹做的WordPress 评论插件需要在sidebar.php或index.php里加入一行类示< ?php get_recent_comments(); ?>的文字。

  基于WordPress的免费Blog网站Blog Irelandblogthing

  hsuyo blog上有许多参考文章。
  lemonhall:建立你自己的WordPress站点 一文的word文件下载
  台湾的 中文WordPress 專案
  大陆的 中文WordPressWordPress临时论坛
  桑椹的 中文WordPress Planet
  WordPressCN

带认证的Sendmail安装手册


安装环境:

RedHat Linux 9.0 完全安装或者确保以下安装包已经安装完毕:

  imap-2001a-18.i286.rpm
  sendmail-8.12.8-4.i386.rpm
  m4-1.4.1-13.i386.rpm
  cyrus-sasl-2.1.10-4.i386.rpm
  cyrus-sasl-md5-2.1.10-4.i386.rpm
  cyrus-sasl-plain-2.1.10-4.i386.rpm
  cyrus-sasl-gssapi-2.1.10-4.i386.rpm

实现目的:

  实现带认证功能的邮件服务器的配置安装

一、DNS(域名服务器配置)

  假设安装Linux的机器主机名为server,IP地址为192.168.0.1,设置为DNS,别名为ns, 域名为test.com, 同时将其设置为SendMail服务器,别名为mail
  运行redhat-config-bind, 启动域名服务配置程序
        1. 新建正向区块
             1.1 新建 "正向区块" test.com
             1.2 设置 "正向区块" test.com
 选从列表中test.com,选属性打开"名称到IP的翻译"对话框
 1.2.1 修改主名称服务器
      修改SOA(主名称服务器)为ns.test.com.
                  1.2.1 修改联系人Email地址:root@test.com
                  1.2.2 添加记录(主机或别名)
      1.2.2.1 添加server, 地址192.168.0.1, 邮件交换器为mail
                       1.2.2.1 添加ns, 地址192.168.0.1, 邮件交换器为mail
                       1.2.2.2 添加mail, 地址192.168.0.1
       1.2.2.3 添加localhost,地址192.168.0.1
       1.2.2.4 添加局域网中其他主机
                   1.2.3 设置记录
     选记录列表框中的 test.com,选编辑(按钮),添加名称服务器 ns.test.com. ,设置邮件交换器mail,IP地址192.168.0.1

        2. 新建逆向区块
             2.1 新建 "逆向区块" 192.168.0
             2.2 设置 "逆向区块" 192.168.0
 选从列表中0.168.192.in-addr.arpa,选属性打开"IP到名称的翻译"对话框
 2.2.1 修改主名称服务器
      修改SOA(主名称服务器)为ns.
                  2.2.2 修改联系人Email地址
      修改联系为: root@test.com
 2.2.3 确保名称服务器中有 ns.
                  2.2.4 添加记录(主机或别名)
                       2.2.4.1 地址192.168.0.1, 主机或域为 server.test.com
       2.2.4.2 添加局域网中其他主机

        3. 修改/etc/resolv.conf
             在文件前面添加两行:
                  search  test.com
                  nameserver 192.168.0.1
                  # 后面是ISP的域名服务器地址
 nameserver  202.106.0.20
                  nameserver 202.106.46.151

        4. 重启DNS Server

二、Sendmail服务配置

  1. 修改/etc/mail/sendmail.mc,修改后文件如下:

  divert(-1)dnl
  dnl #
  dnl # This is the sendmail macro config file for m4. If you make changes to
  dnl # /etc/mail/sendmail.mc, you will need to regenerate the
  dnl # /etc/mail/sendmail.cf file by confirming that the sendmail-cf package is
  dnl # installed and then performing a
  dnl #
  dnl #     make -C /etc/mail
  dnl #
  include(`/usr/share/sendmail-cf/m4/cf.m4′)dnl
  VERSIONID(`setup for Red Hat Linux’)dnl
  OSTYPE(`linux’)dnl
  dnl #
  dnl # Uncomment and edit the following line if your outgoing mail needs to
  dnl # be sent out through an external mail server:
  dnl #
  dnl define(`SMART_HOST’,`smtp.your.provider’)
  dnl #
  define(`confDEF_USER_ID’,“8:12”)dnl
  define(`confTRUSTED_USER’, `smmsp’)dnl
  dnl define(`confAUTO_REBUILD’)dnl
  define(`confTO_CONNECT’, `1m’)dnl
  define(`confTRY_NULL_MX_LIST’,true)dnl
  define(`confDONT_PROBE_INTERFACES’,true)dnl
  define(`PROCMAIL_MAILER_PATH’,`/usr/bin/procmail’)dnl
  define(`ALIAS_FILE’, `/etc/aliases’)dnl
  dnl define(`STATUS_FILE’, `/etc/mail/statistics’)dnl
  define(`UUCP_MAILER_MAX’, `2000000′)dnl
  define(`confUSERDB_SPEC’, `/etc/mail/userdb.db’)dnl
  define(`confPRIVACY_FLAGS’, `authwarnings,novrfy,noexpn,restrictqrun’)dnl
  define(`confAUTH_OPTIONS’, `A’)dnl
  dnl #
  dnl # The following allows relaying if the user authenticates, and disallows
  dnl # plaintext authentication (PLAIN/LOGIN) on non-TLS links
  dnl #
  dnl define(`confAUTH_OPTIONS’, `A p’)dnl
  dnl # 
  dnl # PLAIN is the preferred plaintext authentication method and used by
  dnl # Mozilla Mail and Evolution, though Outlook Express and other MUAs do
  dnl # use LOGIN. Other mechanisms should be used if the connection is not
  dnl # guaranteed secure.
  dnl #
  [color=red]TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN’)dnl[/color]
  [color=red]define(`confAUTH_MECHANISMS’, `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN’)dnl[/color]
  dnl #
  dnl # Rudimentary information on creating certificates for sendmail TLS:
  dnl #     make -C /usr/share/ssl/certs usage
  dnl #
  dnl define(`confCACERT_PATH’,`/usr/share/ssl/certs’)
  dnl define(`confCACERT’,`/usr/share/ssl/certs/ca-bundle.crt’)
  dnl define(`confSERVER_CERT’,`/usr/share/ssl/certs/sendmail.pem’)
  dnl define(`confSERVER_KEY’,`/usr/share/ssl/certs/sendmail.pem’)
  dnl #
  dnl # This allows sendmail to use a keyfile that is shared with OpenLDAP’s
  dnl # slapd, which requires the file to be readble by group ldap
  dnl #
  dnl define(`confDONT_BLAME_SENDMAIL’,`groupreadablekeyfile’)dnl
  dnl #
  dnl define(`confTO_QUEUEWARN’, `4h’)dnl
  dnl define(`confTO_QUEUERETURN’, `5d’)dnl
  dnl define(`confQUEUE_LA’, `12′)dnl
  dnl define(`confREFUSE_LA’, `18′)dnl
  define(`confTO_IDENT’, `0′)dnl
  dnl FEATURE(delay_checks)dnl
  FEATURE(`no_default_msa’,`dnl’)dnl
  FEATURE(`smrsh’,`/usr/sbin/smrsh’)dnl
  FEATURE(`mailertable’,`hash -o /etc/mail/mailertable.db’)dnl
  FEATURE(`virtusertable’,`hash -o /etc/mail/virtusertable.db’)dnl
  FEATURE(redirect)dnl
  FEATURE(always_add_domain)dnl
  FEATURE(use_cw_file)dnl
  FEATURE(use_ct_file)dnl
  dnl #
  dnl # The -t option will retry delivery if e.g. the user runs over his quota.
  dnl #
  FEATURE(local_procmail,`’,`procmail -t -Y -a $h -d $u’)dnl
  FEATURE(`access_db’,`hash -T<TMPF> -o /etc/mail/access.db’)dnl
  FEATURE(`blacklist_recipients’)dnl
  EXPOSED_USER(`root’)dnl
  dnl #
  dnl # The following causes sendmail to only listen on the IPv4 loopback address
  dnl # 127.0.0.1 and not on any other network devices. Remove the loopback
  dnl # address restriction to accept email from the internet or intranet.
  dnl #
  [color=red]dnl DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA’)dnl[/color]
  dnl #
  dnl # The following causes sendmail to additionally listen to port 587 for
  dnl # mail from MUAs that authenticate. Roaming users who can’t reach their
  dnl # preferred sendmail daemon due to port 25 being blocked or redirected find
  dnl # this useful.
  dnl #
  [color=red]DAEMON_OPTIONS(`Port=25, Name=MSA’)dnl[/color]
  dnl #
  dnl # The following causes sendmail to additionally listen to port 465, but
  dnl # starting immediately in TLS mode upon connecting. Port 25 or 587 followed
  dnl # by STARTTLS is preferred, but roaming clients using Outlook Express can’t
  dnl # do STARTTLS on ports other than 25. Mozilla Mail can ONLY use STARTTLS
  dnl # and doesn’t support the deprecated smtps; Evolution <1.1.1 uses smtps
  dnl # when SSL is enabled– STARTTLS support is available in version 1.1.1.
  dnl #
  dnl # For this to work your OpenSSL certificates must be configured.
  dnl #
  dnl DAEMON_OPTIONS(`Port=smtps, Name=TLSMTA, M=s’)dnl
  dnl #
  dnl # The following causes sendmail to additionally listen on the IPv6 loopback
  dnl # device. Remove the loopback address restriction listen to the network.
  dnl #
  dnl # NOTE: binding both IPv4 and IPv6 daemon to the same port requires
  dnl #       a kernel patch
  dnl #
  dnl DAEMON_OPTIONS(`port=smtp,Addr=::1, Name=MTA-v6, Family=inet6′)dnl
  dnl #
  dnl # We strongly recommend not accepting unresolvable domains if you want to
  dnl # protect yourself from spam. However, the laptop and users on computers
  dnl # that do not have 24×7 DNS do need this.
  dnl #
  FEATURE(`accept_unresolvable_domains’)dnl
  dnl #
  dnl FEATURE(`relay_based_on_MX’)dnl
  dnl # 
  dnl # Also accept email sent to "localhost.localdomain" as local email.
  dnl # 
  LOCAL_DOMAIN(`localhost.localdomain’)dnl
  dnl #
  dnl # The following example makes mail from this host and any additional
  dnl # specified domains appear to be sent from mydomain.com
  dnl #
  dnl MASQUERADE_AS(`mydomain.com’)dnl
  dnl #
  dnl # masquerade not just the headers, but the envelope as well
  dnl #
  dnl FEATURE(masquerade_envelope)dnl
  dnl #
  dnl # masquerade not just @mydomainalias.com, but @*.mydomainalias.com as well
  dnl #
  dnl FEATURE(masquerade_entire_domain)dnl
  dnl #
  dnl MASQUERADE_DOMAIN(localhost)dnl
  dnl MASQUERADE_DOMAIN(localhost.localdomain)dnl
  dnl MASQUERADE_DOMAIN(mydomainalias.com)dnl
  dnl MASQUERADE_DOMAIN(mydomain.lan)dnl
  MAILER(smtp)dnl
  MAILER(procmail)dnl 


  文件中,红色字体[color=red]的行为需要修改的地方,共有五行需要修改。

  第一行和第二行是去掉行首的注释。”TRUST_AUTH_MECH”的作用是使sendmail不管access文件中如何设置,都能 relay 那些通过EXTERNAL, LOGIN, PLAIN, CRAM-MD5或DIGEST-MD5等方式验证的邮件,”confAUTH_MECHANISMS" 的作用是确定系统的认证方式。Outlook Express支持的认证方式是LOGIN。

  第三行是加上注释,以便让sendmail可以侦听所有网络设备,为整个网络提供服务,而不仅仅只对本机提供服务。

  第四行是修改的,原来内容是:

  dnl DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea’)dnl

  去掉行首的注释符,并且将内容修改成Port=25:

  DAEMON_OPTIONS(`Port=25, Name=MSA’)dnl

  在smtp的默认端口(25)上进行认证,而不是587端口。这样就强制所有使用该邮件服务器进行邮件转发的用户在认证后才能发邮件了。

  2. 重新生成sendmail.cf:

  # make -C /etc/mail

  3. 修改/etc/mail/local-host-names,将希望该邮件服务器使用的邮箱名加进去,比如邮箱为:xxx@abc.com.cn则将abc.com.cn加入到该文件中。

  4. 重新启动sendmail服务,运行:

  # service sendmail restart

  5. 测试sendmail服务是否已经启动
            可以通过telnet 本机IP 25来验证sendmail服务是否已经正常启动,若登陆成功,则说明sendmail服务已经成功启动。
  # telnet localhost 25
  Trying 127.0.0.1…
  Connected to localhost.
  Escape character is ‘^]’
  220 localhost.localdomain ESMTP Sendmail 8.12.8/8.12.8; Wed, 12 May 2004 15:57:01 +0800
  ehlo localhost
  250-ENHANCEDSTATUSCODES
  250-PIPELINING
  250-8BITMIME
  250-SIZE
  250-DSN
  250-AUTH GSSAPI LOGIN PLAIN
  250-DELIVERBY
  250-HELP
  quit
  # 

  在AUTH后面有LOGIN就基本上可以在OutlookExpress上认证了。

三、Pop3服务配置:

  1. 启动ipop3服务,运行:

  # setup

  在系统服务列表中选中ipop3,选’OK’保存推出

  2. 重启xinetd服务,运行:

  # service xinetd restart

  3. 查看smtp和pop服务是否启动,运行

  # netstat –l
 
 四、使用
  1. 创建新邮箱
 任何Linux新用户都自动有一个邮箱,比如创建用户newuser,则其邮箱为 newuser@test.com
 
  2. 使用outlook
 新建帐户 newuser,SMTP和POP3服务器为 server, 用户名 newuser,口令为Linux改用户口令,选中"我的服务器要求身份认证"

  3. 使用newuser@test.com
 现在可以使用newuser@test.com收发信

2005年08月10日

windows直接telnet到linux,然后打开xwindows

XWindows系统:Redhat 9.0 (IP: 192.168.0.1)
客户端:Windows (IP: 192.168.0.4)
客户端XServer:Exceed 3D


配置Xwindows,使它能够允许远程访问Xwindows。 
Step1: 
编辑/etc/X11/xdm/Xaccess,将下面的行: 
#* # any host can get a login window 
改为: 
* # any host can get a login window 

Step2: 
修改/etc/X11/gdm/gdm.conf,找到下面的信息: 
[xdmcp] 
Enable=0 或Enable=false 
修改为: 
[xdmcp] 
Enable=1 或Enable=true 
并确保以下信息存在: 
Port=177 

Step3: 
修改/etc/inittab,将 
id:3:initdefault: 
修改为: 
id:5:initdefault: 
并将最后一行改为: 
x:5:respawn:/usr/bin/gdm 

Step4: 
确保/etc/X11/xdm/Xservers的属性为444,/etc/X11/xdm/Xsetup_0的属性为755。 
至此,服务器部分基本配置完毕。 

//
从其他的机器连到x server上,一般的windows上的x server(可以使用Exceed 3D)都有

passive模式,就是启动x server之后,不起动任何session.然后可以telnet到linux上(

假设windows的ip是192.168.0.4)
linux# export DISPLAY=192.168.0.4:0
linux# xterm
就会看到一个xterm出现在windows机器上。


//
首先确定服务器打开了SSH和X11 Forwarding
1)在Windoz底下装X-Server,比如X-Win32,X-Winpro之类
2)用PuttY之类的联接器,选Forward X11,ssh登陆
3)敲个mozilla回车试试看“`

Redhat9.0 patch ACL

目的:

主要为方便Linux CVS Server使用OS的来进行权限管理, 由于发现Linux 传统的权限管理不太方便, 由于考虑给Redhat 9.0添加 ACL(Access Control List)补丁, 以便可以方便地对文件或目录进行权限管理.


一、环境:
  操作系统: Redhat Linux 9.0
  内核版本:2.4.20-8

二、安装步骤:


1. 下载

1.1 下载Linux内核源码
http://www.kernel.org/下载2.4.29版到/root,文件名为: linux-2.4.29.tar.gz

1.2 下载ACL
http://acl.bestbits.at/download.html下载ACL patch for Kernel 2.4.29 到/root,文件名为:ea+acl+nfsacl+sec-2.4.29-0.8.73.diff.gz


2. 拷贝

2.1 拷贝内核源码
    使用tar -zxvf linux-2.4.29.tar.gz解压Kernel 2.4.29内核源码到/usr/src
    /root> cd /usr/src
    /usr/src>  rm -f  linux-2.4
    /usr/src>  ln  -s  /usr/src/linux-2.4.29  linux-2.4
   
2.2 patch ACL
    /usr/src> cd  linux-2.4
    /usr/src/linux-2.4>  zcat  /root/ea+acl+nfsacl+sec-2.4.29-0.8.73.diff.gz | patch -p1


3. 编译(make)内核

3.1 编译环境准备

3.1.1 清理工作环境
    清除原先此目录下残留的.config和.o(object文件)
    /usr/src/linux-2.4>   make mrproper       

3.1.2 配置make 环境  

3.1.2.1 获取原来Redhat Kernel 2.4.20-8的config文件
    /usr/src/linux-2.4>  cp /boot/config-2.4.20-8 .

3.1.2.2  设置kernel 2.4.29
   运行 /usr/src/linux-2.4> make menuconfig
   在菜单中选 Load config,选从文件 config-2.4.20-8 装入配置,然后再全选 File System 中的ext2和ext3,其他选项不变

3.2 编译

    3.2.1 检查依赖  (一到两分钟)
    #读取配置过程生成的配置文件,来创建对应于配置的依赖关系树,从而决定哪些需要编译而那些不需要 
    /usr/src/linux-2.4>  make dep

    3.2.2 生成核心   (15分钟左右)
  
    3.2.2.1 生成核心
    #清除不必要的文件 (少于一分钟) 
    /usr/src/linux-2.4>  make clean

    #编译内核, 并在 ./arch/i386/boot下生成压缩的内核文件bzImage
    /usr/src/linux-2.4>  make bzImage

    3.2.2.2 拷贝核心到/boot
    /usr/src/linux-2.4>  cp  arch/i386/boot/bzImage /boot/vmlinuz-2.4.29
    /usr/src/linux-2.4>  cp  System.map /boot/System.map-2.4.29

    3.2.3 生成模块 (耗时1小时左右)

    3.2.3.1 生成模块
    #完成删除前面步骤留下的文件,以避免出现一些错误 
    /usr/src/linux-2.4>  make clean

    #生成相应的模块, 时间很长
    /usr/src/linux-2.4>  make modules
   
    3.2.3.2 拷贝模块到需要的目录
    #把模块拷贝到需要的目录 /lib/modules/2.4.29
    /usr/src/linux-2.4>  make modules_install  
   
    3.2.3.3 生成模块依赖关系
    #生成模块间的依赖关系,启动新内核之后,使用modprobe命令加载模块时就能正确地定位模块
    /usr/src/linux-2.4>   depmod -a    

    3.2.4 制作初始化镜像 (initrd-version.img)
          如果你用的是SCSI硬盘并且采用的是ext3分区格式的话,请注意,您一定要制作initrd.img(因为SCSI卡的驱动包括在这个里边),里边主要有一些驱动,因为放在内核中就显得过大,所以编译进initrd.img,在启动后释放,如果你使用的是IDE硬盘,您可以跳过这一步。
     /usr/src/linux-2.4>    mkinitrd  /boot/initrd-2.4.29.img  2.4.29


4.  配置grub

4.1 修改/boot下的两个链接System.map和vmlinuz,使其指向新内核的文件
    System.map文件是当前正在运行的kernel的fuctions的说明,如果您编译内核后不更新System.map,如果碰到问题,Trouble shooting就很困难了。
    /boot>   rm  -f  System.map vmlinuz
    /boot>   ln  -s  vmlinuz-2.4.29  vmlinuz
    /boot>   ln  -s   System.map-2.4.29  System.map
    /boot>   mkinitrd  initrd-2.4.29.img  2.4.29

4.2 配置启动菜单
    /boot>  vi  /boot/grub/menu.lst

    default=0
    timeout=10
    splashimage=(hd0,0)/boot/grub/splash.xpm.gz
    title Red Hat Linux (2.4.20-8)
    root (hd0,0)
    kernel /boot/vmlinuz-2.4.20-8 ro root=/dev/hda1
    initrd /boot/initrd-2.4.20-8.img
   
#以下是我添加的
    title Red Hat Linux (2.4.29)
    root (hd0,0)
#下面行指定kernel 的路径,后面的ro 表示是readonly, root=/dev/hda1是指定根的路径
    kernel /boot/vmlinuz-2.4.29 ro root=/dev/hda1
#  下面行指定制作的启动初始化镜像
    initrd /boot/initrd-2.4.29.img

    title Red Hat Linux (2.4.20-8)开始是原先老版本的东东, 不要动,因为你还不知道新内核能不能用

    其中 root路径可以使用 df 确认,也可以从menu.lst前面有Redhat自动产生的对照。

5. 安装辅助工具
   使用rpm -qa 查看下面的rpm包是否安装, 如果没有安装,可以从Redhat9.0安装光盘安装。(rpm -Uhv xxxxx.rpm)
   attr-2.0.10-0.i386.rpm
   attr-devel-2.0.10-0.i386.rpm
   libattr-2.0.10-0.i386.rpm
   acl-2.0.18-0.i386.rpm
   acl-devel-2.0.18-0.i386.rpm
   libacl-2.0.18-0.i386.rpm
   fileutils-4.1.8acl-65.5.i386.rpm
   e2fsprogs-1.27ea-26.4.i386.rpm
   star-1.5a03-2.src.rpm


6. 安装完成之后的设置

    如果使用EA/ACL内核补丁,内核重新启动之后不会自动打开ACL功能,需要使用acl或者user_xattr选项mount文件系统才能使ACL生效。假设系统的/home目录位于/dev/hda7分区,可以使用如下命令使/home分区支持访问控制列表:

    # mount  -o remount,acl  /dev/hda7


三、EA/ACL的使用方法

1.Linux EA/ACL的语法

 安装了ACL系统之后,系统中的每个对象(文件和目录)都有一个ACL项目控制对这个目标的访问。每个目录之内所有对象的初始访问控制由目录的默认ACL项目决定。

 每个ACL项目由一系列ACL规则组成,这些规则设置单独用户或者一组用户对目标的访问权限,包括:读、写和搜索/执行。每个ACL条目被冒号分为三个部分:规则标签类型(tag type)、规则限制符(qualifier)和访问权限(access permission)。规则标签类型包括以下关键词:

user–以user关键词开头的ACL规则设置对象拥有者或者其他用户对对象的访问权限。例如:
        user::rw-                表示对象拥有者的访问权限;
        user:test:r–           表示用户test拥有读对象的权限。

group–设定某个用户组对对象的访问权限。例如:
        group::rw-                 表示用户所在用户组拥有读写权限;
        group:testgroup:r–   表示属于testgroup组的用户拥有读权限。

mask–以mask关键词开头的ACL规则用来限制赋予用户的最大访问权限,对象拥有者除外。例如:
        user::rw-
        user:test:rw-                  #有效的是user:test:r–
        group::rw-                      #有效的是group:r–
        group:testgroup::rw-     #有效的是group:testgroup:r–
        mask::r–
        other::r–

other–指定其他用户对对象的访问权限。


 每条ACL规则的第二部分是包含用户或者用户组识别符。用户识别符可以是用户名或者十进制的用户ID号;用户组识别符可以是用户组名或者十进制的用户组ID号。空白表示对象的拥有者或者拥有者所在的用户组。

 第三部分是对对象的访问权限。读、写和搜索(目录)/执行(文件)分别由r、w和x代表,和通常使用的权限表示方法完全相同。对应的权限被-代替表示不具有此权限。

 除了以上的关键词之外,还有一个只用于目录的关键词default。由default关键词修饰的ACL条目表示目录下所有子目录和文件的默认访问控制列表。

 为了方便,还有一种简化的ACL规则表示方式。user可以用u代替;g表示group;m表示mask;o表示other。简化方式的访问控制列表,条目之间使用逗号分割。这种表示方式为命令行设置访问控制列表提供了很大的便利。例如:

    /root> setfacl -m u::rw-,u:floatboat:rw-,g::r–,g:nixe0n:rw-,m::r–,o::r– foo.txt


2.访问控制列表的维护

 ACL生效之后,在使用ls -l命令罗列文件时,你会看到具有访问控制规则的目录或者文件的权限域会有一个加号(+)。例如,在打开ACL功能之前的文件如下所示:

    /root> ls -l
        -rw-rw-r–    1 test   test      11331 09-12 20:02 exam.txt

 使ACL功能生效之后,ls -l命令得到如下结果:

    /root>  ls -l
        -rw-rw-r–+   1 test  test      11331 09-12 20:02 exam.txt

2.1.setfacl

 setfacl工具设置文件和目录的访问控制列表,支持对ACL规则的设置(-s/-S)、修改(-m/-M)和删除(-x/-X)。我们可以使用自己喜欢的编辑器按照ACL语法事先编写好某个对象的访问控制列表,然后使用大写的命令行选项进行设置或者修改操作;我们也可以使用小写命令行选项直接修改对象的访问控制规则,例如:

    /root> setfacl -m -m u::rw-,u:floatboat:rw-,g::r–  exam.txt


2.2.getfacl

 ls命令能够获得某个对象的访问权限,与之类似,getfacl命令可以获得文件和目录的访问控制列表规则,其输出格式如下所示:

    /root>  getfacl  doc
        # file: doc/
        # owner: nixe0n
        # group: linuxaid
        user::rwx
        user:floatboat:rwx              
        group::rwx                      
        group:cool:r-x
        mask:r-x
        other:r-x
        default:user::rwx
        default:user:flatboat:rwx       
        default:group::r-x
        default:mask:r-x
        default:other:—


2005年08月09日

缺陷跟踪系统Bugzilla Linux安装

环境:
操作系统: Redhat 9.0
内核:2.4.20-8

步骤:
1. 下载并安装Bugzilla

1.1 下载Bugzilla
    到http://www.bugzilla.org/download/ 下载Bugzilla 2.18.3 (bugzilla-2.18.3.tar.gz)以及中文简体补丁(bugzilla-2.18rc3

-cn-0.9.rar)和繁体补丁(bugzilla-2.18.1-tw-1.3.rar)

1.2 下载rar for linux
    下载rar for linux(rarlinux-3.4.1.tar.gz), 解压并参考Makefile拷贝文件

1.3 拷贝Bugzilla文件
    在Linux下使用tar -zxvf bugzilla-2.18.3.tar.gz解压bugzilla-2.18.3并拷贝到/var/www/bugzilla
    使用unrar x bugzilla-2.18.1-tw-1.3.rar解压繁体补丁并使用命令 mv tw /var/www/bugzilla/template拷贝
    使用unrar x bugzilla-2.18rc3-cn-0.9.rar解压简体补丁并使用命令 mv cn /var/www/bugzilla/template拷贝

1.4 修改Bugzilla目录访问权限
    chown -R apache.apache bugzilla

2. 配置Bugzilla

2.1 安装并启动mysqld服务

2.2 配置mysql

2.2.1 修改mysql的root用户口令
如果是第一次使用mysql,一定要使用mysqladmin修改mysql口令
  mysqladmin -u root -p oldpassword newpasswd

2.2.2 建立数据库用户test 和bugs

2.2.2.1 添加数据库用户test
mysql>
    INSERT INTO mysql.user (Host,User,Password)
    VALUES (‘localhost’,'test’, PASSWORD(‘12345678′));
mysql>
    FLUSH PRIVILEGES;
 增加一个用户test,密码为12345678。注意要使用PASSWORD函数,然后还要使用FLUSH PRIVILEGES来执

行确认。

2.2.2.2. 添加数据库用户bugs
mysql>
    INSERT INTO mysql.user (Host,User,Password)
    VALUES (‘localhost’,'bugs’, PASSWORD(‘$db_pass’));
mysql>
    FLUSH PRIVILEGES;

2.2.3 建立测试数据库 test 和bugs

2.2.3.1 建立数据库test
#mysql -u root -p
mysql> create database bugs;
mysql> GRANT ALL ON test.* TO test@localhost IDENTIFIED BY "12345678";
mysql> FLUSH PRIVILEGES;

2.2.3.2 建立数据库bugs
#mysql -u root -p
mysql> create database bugs;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, INDEX, ALTER, CREATE, DROP, REFERENCES ON bugs.* TO bugs@localhost IDENTIFIED BY ‘$db_pass’;
mysql> FLUSH PRIVILEGES;
mysql> quit

这里的bugs, bugs@local, $db_pass分别表示bugzilla建立的数据库名、bugzilla的数据库用户名和密码(使用真是的

密码代替,不要输入$db_pass

2.2.4 修改bugzilla/localconfig文件
修改bugzilla/localconfig中的
$db_host = "localhost";
$db_name="bugs";
$db_user="bugs"
$db_pass="xxxx"; 刚才建立数据库时候用到的

2.3 安装perl

2.3.1 确定或安装perl包
可以使用rpm -qa | grep perl命令检查
rpm列表
    perl-5.6.1-26.72.3.i386.rpm
    perl-DB_File-1.75-26.72.3.i386.rpm
    perl-CGI-2.752-26.72.3.i386.rpm
    perl-NDBM_File-1.75-26.72.3.i386.rpm
    perl-CPAN-1.59_54-26.72.3.i386.rpm
如果没有某个包,可从Redhat 9.0安装光盘查找相应文件,并使用rpm -iUh ….rpm安装。

2.3.2 安装其他perl脚本
方法一、自动安装
perl -MCPAN -e ‘install "Bundle::Bugzilla"’

方法二、一个个安装
# cd bugzilla
bugzilla> ./checksetup.pl
按照提示需要安装的模块,到http://www.cpan.org/modules/下载相应的模块解压并一个个安装,比如CGI
#cd CGI
#perl Makefile.PL
#make
#make test
#make install
所有模块都可按此法安装,在安装一些模块如Template Tookit时会有一些信息要求确认,按默认一路回车即可
安装后在运行checksetup.pl,知道所有要求的模块都可以找到。

建议先使用方法一,然后使用方法二安装方法一中可能没有安装的模块。

2.4 再次运行./checksetup.pl
按提示输出管理员email地址,口令等。

2.5 apache设置
找到httpd.conf文件
在其中查找:
AddHandler cgi-script.cgi, 把注释去掉
查找:
AddDefaultCharset, 把ISO-8559-1改成GB2312
查找:
DirectoryIndex,在后面添加index.cgi

增加:
Alias /bug/ "var/www/bugzilla/"
<Directory "/var/www/bugzilla/">
Options ExecCGI
AllowOverride Limit
</Directory>

使用service httpd restart 重新启动apache

2.6 sendmail设置
修改/etc/mail/local-host-names
在里面指定一个hostname.domainname (主机名.域名)

3. 测试
http://127.0.0.1/bug/

3.1 修改administrator的email
在bugs数据库的profiles表中修改相应的元组

3.2 升级
#cd /var/www
# cp bugzilla/localconfig* bugzilla.new/
#cp -r bugzilla/data bugzilla.new/
#mv bugzilla bugzilla.old
#mv bugzilla.new bugzilla
#cd bugzilla
#./checksetup.pl

Linux ADSL共享上网设置

环境:
操作系统: Redhat 9.0
内核版本: 2.4.20-8

步骤:
1. 设置网卡
    安装内网网卡和连接ADSL盒的外网网卡。假设内网网卡别名为Localhost,设备名为 eth0, 外网网卡别名为Internet,设备名为 eth1 (简单判断eth0和eth1的方法,在主板上靠近显卡那段应该时eth0)。
    使用redhat-config-network设置eth0的IP地址为192.168.0.1,子网掩码为255.255.255.0,设置eth1的IP地址为192.168.0.2,子网掩码为255.255.255.0

2. 设置adsl
1) 运行adsl-setup,安步骤设置,注意选dns为(server), 选防火墙类型为2  (MASQUERADE)
2) 运行adsl-start启动adsl服务
3) 检验adsl设置
    使用ifconfig -a 查看adsl启动是否成功,启动成功应该有ppp0
    使用netstat -nr 查看缺省网关(目标地址为0.0.0.0)是否为ppp0的地址,如果不是, 可以使用 route add default ppp0的地址 来添加

3. 设置IP转发
1) 设置网络为转发模式
    echo 1 >> /proc/sys/ipv4/ip_forward

2) 设置内网通过ppp0访问internet
    iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE -o ppp0 

3) 设置通过设备eth0访问内网
    route add -net 192.168.0.0 netmask 255.255.255.0 dev eth0

4. 设置自动脚本
    为了不至于每次机器启动都要重复3,可以将它们加入自启动文件 /etc/rc.local中