安装开源、免费的视频会议系统 OpenMeetings on CentOS

OpenMeetings 是一款免费、开源的网络视频会议系统,下面是在CentOS上安装 OpenMeetings 的手记。

首先确认以下系统服务正常运行
apmd
auditd
autofs
avahi-daemon
bluetooth
cpuspeed
cups
firstboot
gpm
hidd
ip6tables
iptables
irqbalance
mcstrans
mdmonitor
microcode_ctl
netfs
nfslock
pcscd
portmap
restorecond
rpcidmapd
rpcsvcgssd
sendmail
smartd
xfs
yum-updatesd

更新系统软件
yum update

安装好 MySQL 数据库
MySQL配置文件 /etc/my.cnf ,增加中文支持
[mysqld]
default-character-set=utf8
default-collation=utf8_general_ci
character-set-server=utf8
collation-server=utf8_general_ci
init-connect='SET NAMES utf8'

[client]
default-character-set=utf8

重启MySQL服务
/etc/init.d/mysqld start

如果不能关闭防火墙,请开放以下端口
1935 (RTMP), 8088 (基于HTTP的RTMP), 5080 (HTTP), 4445 (桌面共享), 8443 (基于SSL的RTMP)

导入 rpmforge 安装源
rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm

修改启动配置文件 /etc/rc.local,增加一行
/usr/lib/openoffice.org3/program/soffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -nologo -headless -nofirststartwizard &
如果是64位系统,则为
/usr/lib64/openoffice.org3/program/soffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -nologo -headless -nofirststartwizard &

安装以下所有的软件包
yum install freetype freetype-devel fontconfig fontconfig-devel java-1.6.0-openjdk-devel libtiff libtiff-devel libjpeg-devel libjpeg giflib giflib-devel libpaper libpaper-devel xml-commons-apis libpng libpng-devel libxml2 libxml2-devel fftw3 fftw3-devel cairo cairo-devel flac flac-devel wavpack wavpack-devel libsndfile libsndfile-devel libmad libmad-devel yasm-devel yasm gcc gcc-c++

安装 OpenOffice 产品
yum install openoffice.org-base openoffice.org-headless openoffice.org-writer openoffice.org-impress openoffice.org-calc
yum groupinstall 'Office/Productivity'
yum install openoffice.org-headless

修改文件 /etc/sysconfig/i18n
LANG="zh_CN.UTF-8"
SUPPORTED="zh_CN.UTF-8:zh_CN:zh"

安装中文字体支持
yum -y install fonts-chinese fonts-ISO8859-2-75dpi

安装 Ghostscript
yum install ghostscript

安装 Lame
yum install lame

安装 SWFTOOLS
yum install swftools

安装 ImageMagick
yum install ImageMagick

安装 FFmpeg
yum install ffmpeg

安装 SoX
yum install sox

准备 openmeetings 软件包
( 最新版本从Google 代码获得,目前为 v1.6.2 release 3675 )
cd /usr/src
wget http://openmeetings.googlecode.com/files/openmeetings_1_6_2_r3675.zip
unzip openmeetings_1_6_2_r3675.zip -d om

cd /usr/src/om/webapps/openmeetings/conf
cp mysql_hibernate.cfg.xml hibernate.cfg.xml

修改OpenMeetings 的配置文件 /usr/src/om/webapps/openmeetings/conf/hibernate.cfg.xml
输入数据库用户名、密码,其中 //localhost/openmeetings 是数据库地址和数据库名称 (可以先建好这个空数据库)

cd /usr/src/om
nohup ./red5.sh &

启动openoffice 服务
nohup /usr/lib/openoffice.org3/program/soffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -nologo -headless -nofirststartwizard &
如果是64位系统,则为
nohup /usr/lib64/openoffice.org3/program/soffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -nologo -headless -nofirststartwizard &

开始安装 OpenMeetings,输入下面的地址
http://www.域名.com:5080/openmeetings/install

DDOS Deflate 脚本 – 利用 Iptables 或 SPF 防范攻击

一个很有效的、通过Advanced Policy Firewall (APF) 或者 iptables 防止DDOS攻击的脚本:
(D)DoS Deflate

安装方法
wget http://www.inetbase.com/scripts/ddos/install.sh
chmod 0700 install.sh
./install.sh

安装后,脚本会每分钟运行一次,屏蔽的IP地址10分钟后自动解封。
这些参数也可以在配置文件 /usr/local/ddos/ddos.conf 中修改

设置永不屏蔽的IP地址白名单 /usr/local/ddos/ignore.ip.list

DDOS Deflate 的目前版本是 0.6,在我测试的 centos 上运行时不能正常解析出IP地址

修复方法
打开脚本文件 /usr/local/ddos/ddos.sh

修改原来的代码:
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

替换为
netstat -ntu | grep ':' | awk '{print $5}' | awk '{sub("::ffff:","");print}' | cut -f1 -d ':' | sort | uniq -c | sort -nr

备注:安装ddos deflate后,在系统的cron job里,会自动加上了命令 /usr/local/ddos/ddos.sh >/dev/null 2>&1

生成启用、禁止和删除外部关键字约束的SQL脚本

利用主关键字表来自动生成:启用、禁止和删除数据表中外部关键字约束的SQL脚本

源代码:

-- Enable, Disable, Drop and Recreate FKs based on Primary Key table  
-- Written 2007-11-18  
-- Edgewood Solutions / MSSQLTips.com  
-- Works for SQL Server 2005  

SET NOCOUNT ON  

DECLARE @operation VARCHAR(10)  
DECLARE @tableName sysname  
DECLARE @schemaName sysname  

SET @operation = 'DROP' --ENABLE, DISABLE, DROP  
SET @tableName = 'SpecialOfferProduct'  
SET @schemaName = 'Sales'  

DECLARE @cmd NVARCHAR(1000) 

DECLARE   
   @FK_NAME sysname,  
   @FK_OBJECTID INT,  
   @FK_DISABLED INT,  
   @FK_NOT_FOR_REPLICATION INT,  
   @DELETE_RULE    smallint,     
   @UPDATE_RULE    smallint,     
   @FKTABLE_NAME sysname,  
   @FKTABLE_OWNER sysname,  
   @PKTABLE_NAME sysname,  
   @PKTABLE_OWNER sysname,  
   @FKCOLUMN_NAME sysname,  
   @PKCOLUMN_NAME sysname,  
   @CONSTRAINT_COLID INT  


DECLARE cursor_fkeys CURSOR FOR   
   SELECT  Fk.name,  
           Fk.OBJECT_ID,   
           Fk.is_disabled,   
           Fk.is_not_for_replication,   
           Fk.delete_referential_action,   
           Fk.update_referential_action,   
           OBJECT_NAME(Fk.parent_object_id) AS Fk_table_name,   
           schema_name(Fk.schema_id) AS Fk_table_schema,   
           TbR.name AS Pk_table_name,   
           schema_name(TbR.schema_id) Pk_table_schema  
   FROM    sys.foreign_keys Fk LEFT OUTER JOIN   
           sys.tables TbR ON TbR.OBJECT_ID = Fk.referenced_object_id --inner join   
   WHERE   TbR.name = @tableName  
           AND schema_name(TbR.schema_id) = @schemaName  

OPEN cursor_fkeys  

FETCH NEXT FROM   cursor_fkeys   
   INTO @FK_NAME,@FK_OBJECTID,  
       @FK_DISABLED,  
       @FK_NOT_FOR_REPLICATION,  
       @DELETE_RULE,     
       @UPDATE_RULE,     
       @FKTABLE_NAME,  
       @FKTABLE_OWNER,  
       @PKTABLE_NAME,  
       @PKTABLE_OWNER  

WHILE @@FETCH_STATUS = 0   
BEGIN   

   -- create statement for enabling FK  
   IF @operation = 'ENABLE'   
   BEGIN  
       SET @cmd = 'ALTER TABLE [' + @FKTABLE_OWNER + '].[' + @FKTABLE_NAME   
           + ']  CHECK CONSTRAINT [' + @FK_NAME + ']'  

      PRINT @cmd  
   END  

   -- create statement for disabling FK  
   IF @operation = 'DISABLE'  
   BEGIN     
       SET @cmd = 'ALTER TABLE [' + @FKTABLE_OWNER + '].[' + @FKTABLE_NAME   
           + ']  NOCHECK CONSTRAINT [' + @FK_NAME + ']'  

      PRINT @cmd  
   END  

   -- create statement for dropping FK and also for recreating FK  
   IF @operation = 'DROP'  
   BEGIN  

       -- drop statement  
       SET @cmd = 'ALTER TABLE [' + @FKTABLE_OWNER + '].[' + @FKTABLE_NAME   
       + ']  DROP CONSTRAINT [' + @FK_NAME + ']'     

      PRINT @cmd  

       -- create process  
       DECLARE @FKCOLUMNS VARCHAR(1000), @PKCOLUMNS VARCHAR(1000), @COUNTER INT  

       -- create cursor to get FK columns  
       DECLARE cursor_fkeyCols CURSOR FOR   
       SELECT  COL_NAME(Fk.parent_object_id, Fk_Cl.parent_column_id) AS Fk_col_name,   
               COL_NAME(Fk.referenced_object_id, Fk_Cl.referenced_column_id) AS Pk_col_name  
       FROM    sys.foreign_keys Fk LEFT OUTER JOIN   
               sys.tables TbR ON TbR.OBJECT_ID = Fk.referenced_object_id INNER JOIN   
               sys.foreign_key_columns Fk_Cl ON Fk_Cl.constraint_object_id = Fk.OBJECT_ID   
       WHERE   TbR.name = @tableName  
               AND schema_name(TbR.schema_id) = @schemaName  
               AND Fk_Cl.constraint_object_id = @FK_OBJECTID -- added 6/12/2008  
       ORDER BY Fk_Cl.constraint_column_id  

       OPEN cursor_fkeyCols  

       FETCH NEXT FROM    cursor_fkeyCols INTO @FKCOLUMN_NAME,@PKCOLUMN_NAME  

       SET @COUNTER = 1  
       SET @FKCOLUMNS = ''  
       SET @PKCOLUMNS = ''  
         
       WHILE @@FETCH_STATUS = 0   
       BEGIN   

           IF @COUNTER > 1   
           BEGIN  
               SET @FKCOLUMNS = @FKCOLUMNS + ','  
               SET @PKCOLUMNS = @PKCOLUMNS + ','  
           END  

           SET @FKCOLUMNS = @FKCOLUMNS + '[' + @FKCOLUMN_NAME + ']'  
           SET @PKCOLUMNS = @PKCOLUMNS + '[' + @PKCOLUMN_NAME + ']'  

           SET @COUNTER = @COUNTER + 1  
             
           FETCH NEXT FROM    cursor_fkeyCols INTO @FKCOLUMN_NAME,@PKCOLUMN_NAME  
       END  

       CLOSE cursor_fkeyCols   
       DEALLOCATE cursor_fkeyCols   

       -- generate create FK statement  
       SET @cmd = 'ALTER TABLE [' + @FKTABLE_OWNER + '].[' + @FKTABLE_NAME + ']  WITH ' +   
           CASE @FK_DISABLED   
               WHEN 0 THEN ' CHECK '  
               WHEN 1 THEN ' NOCHECK '  
           END +  ' ADD CONSTRAINT [' + @FK_NAME   
           + '] FOREIGN KEY (' + @FKCOLUMNS   
           + ') REFERENCES [' + @PKTABLE_OWNER + '].[' + @PKTABLE_NAME + '] ('   
           + @PKCOLUMNS + ') ON UPDATE ' +   
           CASE @UPDATE_RULE   
               WHEN 0 THEN ' NO ACTION '  
               WHEN 1 THEN ' CASCADE '   
               WHEN 2 THEN ' SET_NULL '   
               END + ' ON DELETE ' +   
           CASE @DELETE_RULE  
               WHEN 0 THEN ' NO ACTION '   
               WHEN 1 THEN ' CASCADE '   
               WHEN 2 THEN ' SET_NULL '   
               END + '' +  
           CASE @FK_NOT_FOR_REPLICATION  
               WHEN 0 THEN ''  
               WHEN 1 THEN ' NOT FOR REPLICATION '  
           END  

      PRINT @cmd  

   END  

   FETCH NEXT FROM    cursor_fkeys   
      INTO @FK_NAME,@FK_OBJECTID,  
           @FK_DISABLED,  
           @FK_NOT_FOR_REPLICATION,  
           @DELETE_RULE,     
           @UPDATE_RULE,     
           @FKTABLE_NAME,  
           @FKTABLE_OWNER,  
           @PKTABLE_NAME,  
           @PKTABLE_OWNER  
END  

CLOSE cursor_fkeys   
DEALLOCATE cursor_fkeys  

测试数据库:AdventureWorks

实例一:
Table: SpecialOfferProduct
Schema: Sales
Operation: DROP

输出:

ALTER TABLE [Sales].[SalesOrderDetail] DROP CONSTRAINT [FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID]
ALTER TABLE [Sales].[SalesOrderDetail] WITH NOCHECK ADD CONSTRAINT [FK_SalesOrderDetail_SpecialOfferProduct_SpecialOfferIDProductID] FOREIGN KEY ([SpecialOfferID],[ProductID]) REFERENCES [Sales].[SpecialOfferProduct] ([SpecialOfferID],[ProductID]) ON UPDATE NO ACTION ON DELETE NO ACTION

实例二:
Table: SpecialOfferProduct
Schema: Sales
Operation: DISABLE

输出:

ALTER TABLE [Sales].[Individual] NOCHECK CONSTRAINT [FK_Individual_Contact_ContactID]
ALTER TABLE [Sales].[SalesOrderHeader] NOCHECK CONSTRAINT [FK_SalesOrderHeader_Contact_ContactID]

ALTER TABLE [Sales].[StoreContact] NOCHECK CONSTRAINT [FK_StoreContact_Contact_ContactID]

ALTER TABLE [Purchasing].[VendorContact] NOCHECK CONSTRAINT [FK_VendorContact_Contact_ContactID]

ALTER TABLE [Sales].[ContactCreditCard] NOCHECK CONSTRAINT [FK_ContactCreditCard_Contact_ContactID]

ALTER TABLE [HumanResources].[Employee] NOCHECK CONSTRAINT [FK_Employee_Contact_ContactID]

在Twitter上自动更新产品

下面的一段PHP代码,用于实现在zen cart网店后台添加新产品后,自动在twitter上发布关于该产品的信息。
(通常是加入 /admin/includes/modules/update_product.php 这个文件)

// BOF twitter feed
    
    if ($action == 'insert_product')
    {
      $purl = zen_catalog_href_link(FILENAME_PRODUCT_INFO, 'products_id=' . $products_id);
      $tinyPurl = file_get_contents('http://tinyurl.com/api-create.php?url='.$purl);
      function updateStatus($user, $password, $message)
      {
        $url = "http://twitter.com/statuses/update.xml";
        $curl = curl_init($url);
        $data = array('status'=>$message);
        curl_setopt($curl, CURLOPT_USERPWD, $user.':'.$password);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:'));
        $result = @curl_exec($curl);
        curl_close($curl);
        return $result;
      }
      $message = STORE_NAME . ' has a new product. ' . $tinyPurl;
      $user = 'YYYYYYYYY';
      $password = 'XXXXXXXXX';
      $result = updateStatus($user, $password, $message);
      $messageStack->add_session($result, 'error');
    }
    // EOF twitter feed