Alhamdulillah Bersyukur Kepada Allah yang telah memberi kita semuanya

Homeasli wong ndeso yang nyasar di internetApr 8, 2007
Assalamualaikum Wrbb. Imam Ferianto, Begitulah Ayahku memberi nama, Imam adalah doa yang berarti harapan agar aku menjadi seorang pemimpin kelak. Ferianto merupakan riwayat Ayah dulu sewaktu aku masih dalam kandungan Ibuku, Ayahku merantau ke Sumatra naik kapal Feri, anto adalah nama panggilan yang umum yang dianggap keren pada masa itu. :).


Aku adalah orang yang biasa saja, tidak suka dengan kemewahan hidup, lebih suka sederhana apa adanya dan InsyaAlloh merasa cukup dengan apa yang dimiliki sekarang. Kebahagiaaanku adalah bila mendapatkan ilmu baru yang bermanfaat dan menemukan teman-teman baru didunia ini. Aku kerja hanyalah sebagai sarana untuk tetap bertahan hidup, mengambil yang secukupnya saja dan tidak ingin suka sesuatu yang berlebihan

Bila ada salah kata dan tulisan dalam blog ini mohon dimaafkan dan bila ada yang dapat diambil hikmahnya atau sekedar pengetahuan silahkan dicopy paste, tidak ada copyright, karena aku juga copypaste dari tempat lain :) dengan tambahan sedikit tulisanku sendiri.

Statusku sementara masih single sedang mencari pendamping hidup yang satu visi dan pandangan. InsyaAlloh aku orang yang pengertian, baik hati suka memberi dan mentraktir teman, sabar dan penyayang serta romantis, hanya saja aku sedikit pendiam dan pemalu :).

OK salam kenal aja dan have a nice day ;)







Blog EntryApache virtual host untuk virtual domain hostingMay 13, '08 1:47 PM
for everyone
Apache virtual host untuk virtual domain hosting

Pada sebuah environtment virtual domain hosting yang menggunakan apache sebagai webservernya
selain kita mengkonfigurasi name server (aka bind) kita juga perlu setting virtual host
pada apache agar redirect (request domain) yang dilempar dari bind dan kemudian diteruskan
ke apache server port 80 akan diarahkan ke virtual domain/path yang sesuai untuk account/domain
tersebut yang dimaksud.  Sebenarnya selanjutnya  solusi yang tepat adalah menggunakan
semacam DLZ tetapi pada apache agar tidak perlu restart ulang apache bila menambahkan
virtual hosting baru.  Tetapi baiklah untuk tahap belajar pertama kita set dulu virtual
host pada apache2. Berikut adalah langkah teknis membuat virtual hosting pada apache 2 :



1. Buat direktori (folder) khusus untuk menyimpan file2 data hostingan client
   dan tempat upload data sesuai dengan acccount masing masing, contohnya
   untuk 2 buah client dibuat sebagai berikut:

   # buat grup utama
   groupadd client

   # buat user dan folder stuktur untuk client1
   
   mkdir -p /home/vhost/client1/www
   mkdir -p /home/vhost/client1/logs
   mkdir -p /home/vhost/client1/cgi-bin
   useradd client1 -g client -d /home/vhost/client1/
   passwd client1
   chown client1.client -R  /home/vhost/client1


   # buat user dan folder stuktur untuk client2
  
   mkdir -p /home/vhost/client2/www
   mkdir -p /home/vhost/client2/logs
   mkdir -p /home/vhost/client2/cgi-bin
   useradd client2 -g client -d /home/vhost/client2/
   passwd client2
   chown client2.client -R  /home/vhost/client2


2. Tambahkan domain untuk account user tersebut ke dalam record database DNS
   seperti contoh pada posting sebelumnya tentang DLZ domain


3. Pointing domain name (virtual host) pada apache

   mkdir /home/vhost-conf/  
   mc -e /etc/httpd/httpd.conf

   # tambahkan include pada httpd.conf agar meload
   # semua *.conf pada folder  /home/vhost-conf

   ### Use name-based virtual hosting.
   DirectoryIndex index.html index.htm index.php
   NameVirtualHost *:80
   NameVirtualHost *:443
   Include /home/vhost-conf/*.conf
   LoadModule ssl_module lib/httpd/modules/mod_ssl.so

4. mengaktifkan ssl
(http://slacksite.com/apache/certificate.php )

mkdir /etc/httpd/ssl
cd /etc/httpd/ssl
openssl genrsa -des3 -rand file1:file2:file3:file4:file5 -out server.key 1024
openssl rsa -in server.key -out server.pem
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 60 -in server.csr -signkey server.key -out server.crt


5. konfigurasi untuk vhost untuk client 1

   mc -e /home/vhost-conf/client1.conf

   #paste kode berikut pada client1.conf

   <VirtualHost *:80>
    ServerAdmin client1@client1-domain1.com
    DocumentRoot /home/vhost/client1/www/
    ServerName client1-domain1.com
    ServerAlias client1-domain1.com *.client1-domain1.com
    ErrorLog /home/vhost/client2/logs/client1-domain1.com-error_log
    CustomLog /home/vhost/client2/logs/client1-domain1.com-access_log common
    ErrorDocument 403 /403.html
        ErrorDocument 404 /404.html
        <Directory "/home/vhost/client1/www/">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
        </Directory>
    ScriptAlias /cgi-bin/ "/home/vhost/client1/cgi-bin"
    <Directory "/home/vhost/client1/cgi-bin">
        AllowOverride None
        Options None
        Order allow,deny
        Allow from all
    </Directory>
   </VirtualHost>  
   <VirtualHost *:443>
        ServerName client1-domain1.com
        DocumentRoot /home/vhost/client1/www/
        CustomLog /home/vhost/client2/logs/client1-domain1.com-ssl-access.log combined
        ErrorLog /home/vhost/client2/logs/client1-domain1.com-ssl-error.log
        SSLEngine on
    SSLCertificateFile /etc/httpd/ssl/server.crt
    SSLCertificateKeyFile /etc/httpd/ssl/server.pem
    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
   </VirtualHost>


   #ubah permision client1.conf
   chown client1.client /home/vhost-conf/client1.conf


6.  ulangi step 4 pada untuk client-client lainnya

7.  restart apache
killall httpd
/etc/rc.d/rc.httpd restart

Mengatasi tidak bisa paste dengan mouse pada console vi (vim)
diatas ssh remote

Setelah menginstall zenwalk dan menggunakan ssh untuk meremote]
server dan melakukan berbagai macam konfigurasi ternyata ada
kesulitan yang sebenarnya simple tapi bikin repot juga.
Hal tersebut adalah ternyata editor vi (vim) pada zendwalk
tidak bisa melakukan paste langsung dari click kanan mouse
seperti pada distro yang lain....hmmm aku pikir apa ini
pasti bermasalah dengan konfigurasi vim nya , setelah baca
beberapa referensi ( http://bbs.archlinux.org/viewtopic.php?pid=271205  )
ternyata memang seperti itu, kita harus mengedit vimrc untuk
menormalkan (setting vim) seperti yang aku mau.
baiklah kita langsung saja pada teknis cara setting vim agar
bisa paste text dengan click kanan mouse.

find / |grep vimrc

edit kedua file .vimrc

mc -e /home/imam/.vimrc
mc -e /root/.vimrc

ubah properti baris :

  set mouse=a  

menjadi
 
  set mouse=r


selanjutnya save (f2) dan keluar (f10) dari editor mc
nah kalau kita membuka vim lagi (vi)  kita sekarang bisa melakukan
paste dengan mudah memakai click kanan pada mouse.


Instalasi Xen virtual os pada zenwalk/slackware untuk membuat VPS hosting

a. Pendahuluan

Tahap berikutnya dalam membuat virtual hosting server adalah menginstall
Xen virtual OS dengan beberapa alasan, Hmmm aku pikir untuk lebih amannya dan daripada repot nanti nantinya
bila suatu saat error atau kena hack dan juga untuk mempermudah dan
membuat fitur semacam VPS (virtual private hosting) maka aku putuskan
untuk menginstall Xen Virtual machine diatas zendwalk untuk kemudian
bisa diinstal bermacam distro lain diatasnya dan bisa dipindah2/dicopy
ke sembarang server backup dengan mudah dan tidak repot konfigurasi
bermacam hal bila kelak ada problem, dan juga mempermudah proses
restore backup server. Sebenarnya teknologi virtualisasi OS juga
banyak macam dan vendornya yang terkenal seperti VMWare, BOSCH,
Virtual PC, PearPC, QEMU, VirtualBox dan lainnya. Kelebihan Xen menurut
vendornya adalah lebih ringan dan lebih cepat sebab diload saat booting
dan melakukan emulasi di tingkat kernel jadi saat Virtual OS dijalankan sudah
menggunakan kernel xen default tersebut. Xen ini cara kerjanya mirip seperti UML
(user mode linux) dan chroot jail (environtment) dimana kita dapat berpindah2
root filesystem dengan mudah saat runtime.

Instalasi berikut aku buat pada distro zenwalk/zencafe yang masih
sekeluarga dengan slackware. karena di PC server tidak ada DVD
drive maka setelah di download DVD ISO aku mounting ke /mnt/slax

mount -o loop /home/iso/slackware-12.0-DVD.iso /mnt/slax

b. Berikut adalah instalasi grub pada slackware (zendwalk)

Untuk instalasi xen kita harus terlebih dulu melakukan instalasi
grub pada slackware (biasanya belum terinstall otomatis), jadi
boot manager default (lilo) harus kita ganti menggunakan Grub
agar bisa memasang Kernel Xen saat startup PC linux-nya.

installpkg  /mnt/slax/extra/grub/grub-0.97-i486-3.tgz
find /|grep grub
/usr/sbin/grubconfig

kemudian ikuti petunjuk dan step untuk instalasi grub


c. Berikut adalah step untuk menginstall xen virtual machine
pada distro zendwalk/slackware:

1. download source xen dari website dan extract

cd /home/compile
wget -c http://bits.xensource.com/oss-xen/release/3.1.0/src.tgz/xen-3.1.0-src.tgz
tar -xzf xen-3.1.0-src.tgz
cd xen-3.1.0-src

2. compile xen, untuk menyesuaikan dengan istro slackware kita make dist dulu

more README-xen31-tarballs.txt
make dist

selanjutnya xen akan melakukan compile, configurasi dan mendownload
otomatis kernel source yang sesuai dengan kernel yang dipakai distro
yang sekarang untuk membuat kernel xen sendiri.


3. install xen virtual machine

sh ./install.sh

4. konfigurasi xen virtual machine untuk startup saat booting, kita perlu
mengkonfigurasi grub dan menambahkan kernel xen saat startup linux

  title Distro Pake Xen (2.6.18-xen-3.1)
  root (hd0,0)
  kernel /boot/vmlinux-syms-2.6.18-xen root=/dev/sda1 ro vga=771
  initrd /boot/xen-3.1.0.gz



Referensi :

http://xen.xensource.com/download/docs/README-xen31-tarballs.txt

http://www.debian-administration.org/articles/304



Blog Entrytelkomnet instant loginMay 13, '08 8:51 AM
for everyone
Servis PC Di sekolah smp2 pwt. butuh driver printer Pixma ip1700, cd driver ga bawa, driver bawaan katanya udah ilang....duh gimana nih mo balik dulu kejauhan, pikir2 aku download aja  kali ya, mo pake Speedy ga bisa2 connect modem ADSLnya error terus. Ah untung bw laptop kesayangan ahirnya dialup aja ke telkom instant.

nomerdial = 080989999
user = telkomnet@instant
password = telkom

cs telkomnet = 147, pesawat 3

downloadnya lamaaaaaa banget sampe 2 jam lebih untuk mendonlod driver sebesar 30meg, yaaah kecepatan maximal yang didapat hanya 3 KBps, uuuugh cape deh nunggunya....

Lima langkah mudah membuat Realtime DNS server untuk bisnis domain hosting dengan Mysql record sebagai zone record

Seringkali kita susah melakukan konfigurasi Name server bind dimana konfigurasinya adalah
file texts misalnya yang berada pada /var/named. Kasus lainnya adalah ketika melakukan perubahan pada record NS (misalnya pada sebuah environment DOmain Hosting) dimana reabilitas & realtime sangat perlu kita harus merestart DNS/nameserver kita, dan hal ini tentu saja membuat problem yang fatal misalnya saat kita melakukan restart DNS dan ketika itu ada query maka NDS tidak akan mereply query domain name, akibatnya error pointing domain atau alamat domain tidak diketahui.

DLZ (Dinamilcy Loadable Zone) merupakan solusi terbaik untuk saat ini untuk mengkonfigurasi sebuah  nameserver dalam environtment domain hosting. Dengan menggunakan DLZ solusi baru didapat yaitu :

1. data NS record disimpan dalam database record (bukan test based)
2. perubahan terhadap record DNS dalam database mysql akan langsung diload oleh BIND tanpa perlu restart dns server.
3. pembuatan interface domain akan lebih mudah dicustomize sendiri karena hanya sebatas insert dan update record dalam database, sisanya akan dilakukan otomatis oleh BIND-DLZ

Untuk experiment ini saya memakai versi bind-9.4.1 dan dlz-patch versi DLZ-0.7 dan mysql versi 5.0.37 pada lingkungan zendwalk/zendcafe yang masih 1 jenis distro slackware dan kernel 2.6.21.3

Marilah langsung saja ke teknis instalasi:


##0.Download extrack source dari bind dan dlz misalnya ke home/compile, kemudian lakukan patch

mkdir /home/compile/
cd /home/compile/
wget http://ftp.isc.org/isc/bind/cur/9.4/bind-9.4.1.tar.gz
wget http://optusnet.dl.sourceforge.net/sourceforge/bind-dlz/DLZ-0.7.0.tar.gz
tar -xzf bind-9.4.1.tar.gz
cd bind-9.4.1
tar -xzf /home/compile/DLZ-0.7.0.tar.gz


##1. option compile bind
./configure --with-dlz-mysql=yes
make && make install

##2. tambahan untuk named.conf agar meload dlz
dlz "Mysql zone" {
     database "mysql
     {host=localhost dbname=dns user=dns pass=PasswordHere ssl=false port=3306 socket=/mysql/mysql.sock}
     {SELECT zone FROM resource_records WHERE zone = '%zone%'}
     {SELECT ttl, type, mx_priority, IF(type = 'TXT', CONCAT('\"',data,'\"'), data) AS data
      FROM resource_records
      WHERE zone = '%zone%' AND host = '%record%' AND type <> 'SOA' AND type <> 'NS'}
     {SELECT ttl, type, data, primary_ns, resp_contact, serial, refresh, retry, expire, minimum
      FROM resource_records
      WHERE zone = '%zone%' AND (type = 'SOA' OR type='NS')}
     {SELECT ttl, type, host, mx_priority, IF(type = 'TXT', CONCAT('\"',data,'\"'), data) AS data, resp_contact, serial, refresh, retry, expire, minimum
      FROM resource_records
      WHERE zone = '%zone%' AND type <> 'SOA' AND type <> 'NS'}";
};



###3. untuk memasukkan record 1 buah dns, nameserver ke mysql
mysql -u root -e "create database dns"
mysql -u root dns -e "
INSERT INTO dns.resource_records (   zone,
                        ttl,
                        type,
                        host,
                        primary_ns,
                        resp_contact,
                        serial,
                        refresh,
                        retry,
                        expire,
                        minimum ) VALUES (      'xmedia.com',
                                                86400,
                                                'SOA',
                                                '@',
                                                'ns1.xmedia.com.',
                                                'hostmaster.xmedia.com.',
                                                2007112201,
                                                10800,
                                                7200,
                                                604800,
                                                86400 );


INSERT INTO `resource_records` (`id`, `zone`, `ttl`, `type`, `host`, `mx_priority`, `data`, `primary_ns`, `resp_contact`, `serial`, `refresh`, `retry`, `expire`, `minimum`) VALUE (101, 'xmedia.com', 86400, 'NS', '@', NULL, 'ns1.xmedia.com.', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `resource_records` (`id`, `zone`, `ttl`, `type`, `host`, `mx_priority`, `data`, `primary_ns`, `resp_contact`, `serial`, `refresh`, `retry`, `expire`, `minimum`) VALUE (102, 'xmedia.com', 86400, 'NS', '@', NULL, 'ns2.xmedia.com.', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `resource_records` (`id`, `zone`, `ttl`, `type`, `host`, `mx_priority`, `data`, `primary_ns`, `resp_contact`, `serial`, `refresh`, `retry`, `expire`, `minimum`) VALUE (103, 'xmedia.com', 86400, 'MX', '@', 10, 'mail.xmedia.com.', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `resource_records` (`id`, `zone`, `ttl`, `type`, `host`, `mx_priority`, `data`, `primary_ns`, `resp_contact`, `serial`, `refresh`, `retry`, `expire`, `minimum`) VALUE (104, 'xmedia.com', 86400, 'A', '@', NULL, '192.168.1.50', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `resource_records` (`id`, `zone`, `ttl`, `type`, `host`, `mx_priority`, `data`, `primary_ns`, `resp_contact`, `serial`, `refresh`, `retry`, `expire`, `minimum`) VALUE (105, 'xmedia.com', 86400, 'A', 'www', NULL, '192.168.1.50', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
"

###4. start dns dalam mode debug agar bisa dilihat errornya
killall named
named -c /var/named.conf -g


###testing nameserver , harusnya keluar jawaban alamat NS & IP dari host
dig soa xmedia.com @localhost
nslookup xmedia.com localhost



# Bahan Bacaan tambahan
Setting up a BIND DLZ Nameserver with MySQL Replication, http://www.zazzybob.com/bind_dlz.html


Blog EntryMembuat Video Chat Converence dengan Red 5May 9, '08 4:50 AM
for everyone
Beberapa waktu yang lalu server aplikasi video broadcast/chat yang bagus dan multiplatform hanya tersedia pada versi komersial seperti flash media server dan sejenisnya. perkembangan yang terbaru kita bisa menggantikan Flash Media Server/FMS dengan aplikasi video streaming opensource yang disebut red 5. Red 5 lahir dari kebutuhan akan video share server yang mempunyai kemampuan dan protokol yang sama seperti standard rtmp dari FMS, bedanya Red 5 dibuat menggunakan java dan merupakan gabungan dari jetty untuk httpnya dan spring untuk aplikasi stremingnya. Red 5 sendiri saat tulisan ini dibuat sudah mencapai versi stabil  v0.7.0 Final  yang layak untuk digunakan sebagai pengganti FMS. Red 5 dapat di download pada alamat http://osflash.org/red5
Update Tulisan barus selanjutnya akan memuat bagaimana membuat aplikasi video chat/ video converence sederhana mengunakan Red 5 ini untuk lingkup Kota/WAN atau misalnya untuk pengganti jardiknas yang mahal itu tanpa perlu alat2 mahal semacam Tanderberg.  Kebutuhan yang diperlukan hanya PC dengan webcam dan koneksi LAN/WAN/Internet yang memadai serta sebuah server linux untuk diinstall Appserver Red 5. Tunggu saja!


Blog EntryMembuat Router dengan windows XPMay 9, '08 3:54 AM
for everyone
Seperti windows 2003, ternyata windows xp pun bisa dibuat sebagai router, hanya saja kita perlu mengedit/mengaktifkan parameter routing pada service tcpip. Berikut cara mengedit registry agar windows XP support routing,
1. set dword value menjadi 1, pada key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter

2. kemudian restart komputernya.

3. tambahkan routing yang perlu seperti perintah pada linux hanya ada perbedaan parameter sedikit, dengan,  start-> run -> cmd  , kemudian ketik " route /?       "
untuk menampilkan help dari cara menambahkan routingnya. ikuti contoh pada manual
untuk setup selanjutnya.


Referensi:
http://support.microsoft.com/kb/315236



Ada kalanya di kantor atau sedang piknik kita perlu menshare data lewat wireless maupun koneksi internet pada salahsatu laptop yang konek ke internet misalnya lewat gprs modem atau 3g modem. Cara yang dapat ditempuh adalah membuat laptop tersebut menjadi accespoint hotspot sementara atau istilahnya adhoc connection, dimana antar laptop yang mempunyai wireless bisa saling koneksi tanpa perlu menggunakan radio wireless accespoint seperti biasa.
caranya adalah sebagai berikut.
1. Enable routing , seperti posting artikel sebelumnya

2. Berikan IP static di tiap PC misalny 192.168.0.1 untuk komputer utama yang konek ke internet dan seterunya berurutan untuk komputer yang lain yang akan koneksi ke komputer tersebut dan setup gateway (pada komputer yang lain selain komputer utama) menggunakan IP komputer utama 192.168.0.1

(click untuk versi besar)

3. Enable share internet pada card wireless komputer yang koneksi ke internet,


2. buat koneksi adhoc di setiap PC,

3. Beri nama yang sama untuk addhoc nya pada tiap pc
 

5. Koneksi addhoc siap, konek ke wireless addhoc pada semua PC agar menggunakan jalur addhoc tersebut.

 

sumber:
http://www.raymond.cc/blog/archives/2008/03/22/how-to-share-internet-connection-in-xp-without-wireless-router/

Multiblog atau disebut juga komunitas blog-blog gratis yang memiliki banyak domain alias
misalnya iferianto.multiply.com pada dasarnya dapat diwujudkan dengan menggunakan "emulasi virtual domain" atau domain boongan, hal ini untuk mempermudah jika pendafaran subdomain sangat dinamis, keuntungannya kita tidak usah mengkonfigurasikan ulang name server kita untuk subdomain baru. Mekanisme ini diwujudkan dengan membolehkan wildcard akses "*"   pada server domain kita (misalnya menggunakan BIND). Jadi semua request subdomain tersebut diarahkan (pointing) ke domain utama, selanjutnya nameserver (misal BIND) akan melakukan forward langsung ke webserver (misalnya APACHE) kemudian dari webserver ini request subdomain akan ditranslasikan kembali misalnya menjadi URL asli (misalnya menggunakan URL rewriter atau mod rewrite ataupun menggunakan vhost), sebagai analogi misalkan request ke:

  1. http://iferianto.multiply.com          sebenarnya adalah  http://www.multiply.com/user/iferianto
  2. http://iferianto.blogdetik.com       bisa jadi adalah http://www.blogdetik.com/blog/iferianto
Berikut adalah langkah teknis untuk mewujudkan sebuah multiblog wordpressmu & Linux:

1. Install Apache2, bind9, mysql, php5, php5-mysql, php5-gd,apache-mod-rewrite
2. Install wordpressmu  http://mu.wordpress.org/download/
3. Konfigurasikan bind untuk menerima request semua subdomain (wilcard  *  DNS request)
    pada CNAME ataupun A records
    #FILE: /etc/bind/named.conf
 
   * 14400 IN CNAME blogs.unsoed.ac.id

4. Konfigurasikan Apache untuk menerima semua request wildcard ke 1 domain utama (contoh, misalnya)

<virtualhost >
  ServerAlias www.unsoed.ac.id
  ServerAdmin iferianto@yahoo.com
  DocumentRoot /var/www/blogs.unsoed.ac.id/public_html
  ServerName blogs.unsoed.ac.id
  User blogs
  Group blogs
  ServerAlias *.blogs.unsoed.ac.id
</virtualhost>

5. selanjutnya ada 2 cara yang dapat dipilih:
  a.Misal menggunakan Vhost,

UseCanonicalName off
VirtualDocumentRoot /var/www/%-2.0.%-1/%-3

 
  - buat symbolik link ke path asli, subdomain ke path asli
 

  b.Misal menggunakan mod rewrite, Konfigurasikan .htacces atau httpd.conf untuk mod rewrite, forward ke URL asli


<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

# Show Stats
# :: added this to show AWStats stats
RewriteCond %{REQUEST_URI} ^/(stats|failed_auth\.html)/?(.*)$ [NC]
RewriteRule ^.*$ - [L]

# Rewrite www.domain.com to domain.com
RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^(.*)       http://%1/$1 [R,L]


# mod_dir fix.
# :: Added from other mod_rewrite.com recipe
RewriteCond %{HTTP_HOST} ^([^\.]+)\.blogs.unsoed.ac.id$ [NC]
RewriteCond %{DOCUMENT_ROOT}/subsites/%1%{REQUEST_URI}/ -d
RewriteRule !/$ %{REQUEST_URI}/ [R=301,L]

# If directory exists for subdomain, rewrite it.
# :: Added from other mod_rewrite.com recipe
RewriteCond %{HTTP_HOST} ^([^\.]+)\.blogs.unsoed.ac.id$ [NC]
RewriteCond %{DOCUMENT_ROOT}/subsites/%1/ -d
RewriteCond %1%{REQUEST_URI} !^([^\.]+)/\1(/.*)?$
RewriteRule ^(.*)$ /subsites/%1/$1 [QSA,L]

# /subsites/subdomain/ --> subdomain.yourdomain.org
# :: Added from other mod_rewrite.com recipe
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/([^/]+)(/.*)?$
RewriteCond %{DOCUMENT_ROOT}/subsites/%1/ -d
RewriteRule .* http://%1.blogs.unsoed.ac.id%2 [R=301,L]
####################################
#
# Here below start the WPMU rules that work quite fine :)
#
####################################

#uploaded files
RewriteRule ^(.*)?/?files/(.*) wp-content/blogs.php?file=$2 [L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [L]
RewriteRule  ^([_0-9a-zA-Z-]+/)?(wp-.*) $2 [L]
RewriteRule  ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]


Edit wp-settings.php untuk menerima request URI asli tambahkan di baris paling atas

$_SERVER['REQUEST_URI']=$_SERVER['HTTP_X_ORIGINAL_URL'];

6. Restart BIND dan APACHE
7. Test request DNS dengan  nslookup, seharusnya apapun subdomainya mengarah ke domain utama.




Blog EntrySource Code Web Mailmerge C#, continue from pastMar 26, '08 8:22 PM
for everyone

Berhubung projectnya udah lama sekali selesai dan expired berikut aku posting code utama dari webmailmerge menggunakan C# mungkin dapat digunakan sebagai bahan referensi.

Beberapa requirement yang harus diinstall
- Office Xp atau 2007 (msword & excel)
- GNU PDF Printer


#Code file: Upload.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.IO.Compression;
using System.Xml;
using System.Xml.XPath;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Reflection;
using Microsoft.Office;
using Microsoft.Office.Core;
using System.Runtime.InteropServices;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Diagnostics;

using ICSharpCode.SharpZipLib.Zip;

/********external PROGRAM RUN class ********/
class RunProg{
  public RunProg()
  {
  }
  public void RunExecutable(string executable, string arguments)
  {
   ProcessStartInfo starter = new ProcessStartInfo(executable, arguments);
   starter.CreateNoWindow = true;
   starter.RedirectStandardOutput = true;
   starter.UseShellExecute = false;
   Process process = new Process();
   process.StartInfo = starter;
   process.Start();
   StringBuilder buffer = new StringBuilder();
   using (StreamReader reader = process.StandardOutput)
   {
    string line = reader.ReadLine();
    while (line != null)
    {
     buffer.Append(line);
     buffer.Append(Environment.NewLine);
     line = reader.ReadLine();
     Thread.Sleep(100);
    }
   }
   if (process.ExitCode != 0)
   {
    throw new Exception(string.Format(@"""{0}"" exited with ExitCode {1}. Output: {2}", executable, process.ExitCode, buffer.ToString())); 
   }
  }
}



/// Upload handler for uploading files.
public class Upload : IHttpHandler
{
    public Upload()
    {
    }

    #region IHttpHandler Members
    private HttpPostedFile htmltemplate;
    private string uploadpath;
    private string datasourcefile;
    private string datasourcetype;
    private string basepath;
    private DataSet sdataconf;
    private DataSet sdataset;
    private string outputtype;
    private string savein;
    private string loopingtags,starttag, closetag,  docinput;
    private bool debug;

    public bool IsReusable
    {
        get { return true; }
    }

    public void applyMerge()
    {
        if (docinputtype == "doc" || outputtype=="doc")
        {   //overridea as doc
            docinputtype = "doc";
            openTemplateDoc();
            applyMergeDoc();
            //dowlnload
            if (savein == "download") {
                FileOutput();
            }
            closeTemplateDoc();
            deleteTemplateDoc();

        }
        else if (docinputtype == "html") {
            openTemplateHTML();
            applyMergeHTML();
            //dowlnload
            if (savein == "download")
            {
                FileOutput();
            }
            closeTemplateHTML();
            deleteTemplateHTML();
        }
    }

    /***download: zip output and download as ZIP, need NET zip component***/
    private string filename;
    private string targetfile;
    private string html_ifolder,html_destfolder,html_base;
    private RunProg cmd_console;   
    private void FileOutput() {
        //create cmd external
        cmd_console = new RunProg();

        //rand str
        string randstr = DateTime.Now.Millisecond.ToString();

        //zipname
        string zipname = "output"+randstr+".zip";

        //fullpath of zipname target
        string zipoutput = this.outputpath+zipname;

        //generate random path
        string tempfolder=this.outputpath+"temp"+randstr+"\\";

        ///create random temp folder
        if (Directory.Exists(tempfolder)) Directory.Delete(tempfolder);
        Directory.CreateDirectory(tempfolder);

        ///move file to temp folder
        for (int i = 0; i < file_wrt.Count; i++)
        {
            filename = this.file_wrt[i].ToString();
            targetfile = tempfolder + System.IO.Path.GetFileName(filename);
            //HttpContext.Current.Response.Write("moving file: <b>" + filename + "</b> to <b>"+targetfile+"</b><br/>");
            if(File.Exists(filename)) File.Move(filename, targetfile);

            if (outputtype == "html") {
              html_base = System.IO.Path.GetFileNameWithoutExtension(filename) + "_files";
              html_ifolder=this.outputpath + html_base;
              html_destfolder = tempfolder ;
              if (Directory.Exists(html_ifolder)) {
                  string cmd = String.Format("/C move /Y \"{0}\" \"{1}\"", html_ifolder, html_destfolder);
                  //HttpContext.Current.Response.Write("run: <b>" + cmd + "</b><br/>");
                  cmd_console.RunExecutable("cmd.exe", cmd);
              }
            }

        }
        ///zip temp folder
        //HttpContext.Current.Response.Write("zip folder :" + tempfolder+"<br>");
        ZipDirectory(tempfolder,zipoutput);

        HttpContext.Current.Response.Write(String.Format("create zip file : <b>{0}</b> <a href=\"output/{1}\">click here for download zip</a><br/>",zipname,zipname));
        //recursive delete files in folder temp
        /*
        for (int i = 0; i < file_wrt.Count; i++)
        {
            filename = this.file_wrt[i].ToString();
            targetfile = tempfolder + System.IO.Path.GetFileName(filename);
            if(File.Exists(targetfile)) File.Delete(targetfile);
        }
        ///delete temp folder
        if (Directory.Exists(tempfolder)) Directory.Delete(tempfolder);
        */
        ///clean way to delete all files subfolder
        if (Directory.Exists(tempfolder))
        {
            string cmd = String.Format("/C RD /S /Q \"{0}\"", tempfolder);
            cmd_console.RunExecutable("cmd.exe", cmd);
        }


        ///create popup for download zip file
        string downloadurl = "downloadfile.aspx?zipfilename="+zipname;
        HttpContext.Current.Response.Write(String.Format("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"30,URL='{0}'\" /><script>window.open(\"{0}\")</script>", downloadurl));
        //HttpContext.Current.Response.Write("<BR>URL=" + downloadurl + "<br>");
    }
    public static void ZipDirectory(string sourceDirectory, string zipFileName)
    {
        (new FastZip()).CreateZip(zipFileName, sourceDirectory, true, null);
    }



    /*****PDF HANDLE*****/
    public PDFCreator.clsPDFCreator _PDFCreator;
    private PDFCreator.clsPDFCreatorError pErr;
    public bool ReadyState;
    private string fname;
    public string DefaultPrinter;
    private FileInfo fi;
    public PDFCreator.clsPDFCreatorOptions opt;
    public bool pdfstarted;
    private string parameters;

    public void initPDF()
    {
        if (pdfstarted) return;
        pErr = new PDFCreator.clsPDFCreatorError();
        _PDFCreator = new PDFCreator.clsPDFCreator();
        _PDFCreator.eError += new PDFCreator.__clsPDFCreator_eErrorEventHandler(_PDFCreator_eError);
        _PDFCreator.eReady += new PDFCreator.__clsPDFCreator_eReadyEventHandler(_PDFCreator_eReady);
        parameters = "/NoProcessingAtStartup";
            if (!_PDFCreator.cStart(parameters, false))
            {
                pdfstarted = false;
                HttpContext.Current.Response.Write("<font color=red>Printer Error Status: Error[" + pErr.Number + "]: " + pErr.Description + "<br/>Tell admin to Killall <b>PDFCreator.exe</b> on server</font><br/>");
                return;
            }
        pdfstarted = true;
    }


    public void WordPrintPDF(string Pfilefullname)
    {
        if (!pdfstarted) return;
        try
        {
            int FileTyp = 0;
            string destfolder = System.IO.Path.GetDirectoryName(Pfilefullname);
            fname = System.IO.Path.GetFileNameWithoutExtension(Pfilefullname);
            opt = _PDFCreator.cOptions;
            opt.UseAutosave = 1;
            opt.UseAutosaveDirectory = 1;
            opt.AutosaveDirectory = destfolder;
            opt.AutosaveFormat = FileTyp;
            opt.PDFOptimize = 1;
            opt.StandardSaveformat = 1;
            if (FileTyp == 5)
            {
                opt.BitmapResolution = 72;
            }
            opt.AutosaveFilename = fname;
            _PDFCreator.cOptions = opt;
            _PDFCreator.cClearCache();
            DefaultPrinter = _PDFCreator.cDefaultPrinter;
            _PDFCreator.cDefaultPrinter = "PDFCreator";
            _PDFCreator.cPrinterStop = false;
            this.ReadyState = false;
            _wordApplication.ActivePrinter = "PDFCreator";
            _wordApplication.PrintOut(ref oFalse, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue);
            int maxTime = 30; //in seconds
            int sleepTime = 250;
            int c = 0;
            int d = maxTime * 1000 / sleepTime;
            while (this.ReadyState == false && (c < d))
            {
                c = c + 1;
                Thread.Sleep(100);
            }
            _PDFCreator.cPrinterStop = true;
            _PDFCreator.cDefaultPrinter = DefaultPrinter;
            if (this.debug) HttpContext.Current.Response.Write("output:" + _PDFCreator.cOutputFilename + "<br>");
            swordoutputfile = _PDFCreator.cOutputFilename;
            ReadyState = false;
        }
        catch (Exception ecp)
        {
            HttpContext.Current.Response.Write("Error exception: <b>" + ecp.Message.ToString() + "</b><br/>");

        }
    }

    public void PrintFile(string Pfilefullname, string destfolder)
    {
        if (!pdfstarted) return;
        if (!File.Exists(Pfilefullname))
        {
            HttpContext.Current.Response.Write("<font color=red>Error:" + Pfilefullname + " is not exists!</font><br>");
            return;
        }
        if (!_PDFCreator.cIsPrintable(Pfilefullname))
        {
            HttpContext.Current.Response.Write("<font color=red>Error:" + Pfilefullname + " is not printable!</font><br>");
            return;
        }
        try
        {
            int FileTyp = 0;
            fi = new FileInfo(Pfilefullname);
            fname = fi.Name;
            if (fname.IndexOf(".") > 0) fname = fname.Substring(0, fname.IndexOf("."));
            opt = _PDFCreator.cOptions;
            opt.UseAutosave = 1;
            opt.UseAutosaveDirectory = 1;
            opt.AutosaveDirectory = destfolder;
            opt.AutosaveFormat = FileTyp;
            opt.PDFOptimize = 1;
            opt.StandardSaveformat = 1;
            if (FileTyp == 5)
            {
                opt.BitmapResolution = 72;
            }
            opt.AutosaveFilename = fname;
            _PDFCreator.cOptions = opt;
            _PDFCreator.cClearCache();
            DefaultPrinter = _PDFCreator.cDefaultPrinter;
            _PDFCreator.cDefaultPrinter = "PDFCreator";
            _PDFCreator.cPrintFile(fi.FullName);
            _PDFCreator.cPrinterStop = false;
            this.ReadyState = false;
            int maxTime = 30; //in seconds
            int sleepTime = 250;
            int c = 0;
            int d = maxTime * 1000 / sleepTime;
            while (this.ReadyState == false && (c < d))
            {
                c = c + 1;
                Thread.Sleep(100);
            }
            _PDFCreator.cPrinterStop = true;
            _PDFCreator.cDefaultPrinter = DefaultPrinter;
            //if (this.debug) HttpContext.Current.Response.Write("output:" + _PDFCreator.cOutputFilename + "<br>");
            swordoutputfile = _PDFCreator.cOutputFilename;
            ReadyState = false;
        }
        catch (Exception ecp)
        {
            HttpContext.Current.Response.Write("Error exception: <b>" + ecp.Message.ToString() + "</b><br/>");

        }
    }

    private void _PDFCreator_eReady()
    {
        _PDFCreator.cPrinterStop = true;
        this.ReadyState = true;
        //HttpContext.Current.Response.Write("ready state: <b>" + this.swordoutputfile + "</b><br/>");
    }

    public void _PDFCreator_eError()
    {
        try
        {
            pErr = _PDFCreator.cError;
            _PDFCreator.cPrinterStop = true;
            _PDFCreator.cDefaultPrinter = DefaultPrinter;
            _PDFClose_END();
        }
        catch { }
    }

    public void _PDFClose_END()
    {
        try
        {
            _PDFCreator.cClose();
            while (System.Runtime.InteropServices.Marshal.ReleaseComObject(_PDFCreator) > 0) ;
            _PDFCreator = null;
            pErr = null;
            GC.Collect();
        }
        catch(Exception ecp)
        {
            HttpContext.Current.Response.Write("Error exception: <b>" + ecp.Message.ToString() + "</b><br/>");
        }
    }
   
   

    /***string replacement for filename***/
    private string FixFileName(string s_outputfilename){
      s_outputfilename=s_outputfilename.Replace(" ", "_").Trim("'!@#$%^&*()_+".ToCharArray());
      return s_outputfilename;
    }

    /*doc handle*/
    private object oFalse, oTrue, oInpuTFile;
    public Word._Application _wordApplication;
    public Word._Document _wordDocument;
    private object oOutpuTFile, oFileFormat;
    private string swordoutputfile;

    private void applyMergeDoc(){
        if (datasourcetype == "xml") {
            readXMLDataSourceRow();
        }
        else if (datasourcetype == "excel")
        {
            readExcelDataSourceRow();
        }
    }
   

    private void openTemplateDoc()
    {
        //open app
        _wordApplication = null;
        _wordApplication = new Word.Application();
        _wordApplication.Visible = false;
        nullValue = Missing.Value;
        oTrue = true;
        oFalse = false;
    }

    private void docReplace(string s_tag2replace, string s_val2assign)
    {
        //HttpContext.Current.Response.Write("word replace : <b>" + s_tag2replace + "</b> with <b>" + s_val2assign + "</b><br/>");
        object vk_find = s_tag2replace;
        object vk_replace = s_val2assign;
        object vk_num = 1;
        object vk_read_only = false;
        object vk_visible = true;
        object vk_false = false;
        object vk_true = true;
        object vk_dynamic = 2;
        _wordApplication.Selection.Find.Execute(ref vk_find, ref vk_false, ref vk_false,
        ref vk_false, ref vk_false, ref vk_false, ref vk_true, ref vk_num, ref vk_false,
        ref vk_replace, ref vk_dynamic, ref vk_false, ref vk_false, ref vk_false, ref vk_false);
    }

    private void closeTemplateDoc()
    {
        _wordApplication.Quit(ref oFalse, ref nullValue, ref nullValue);
        while (System.Runtime.InteropServices.Marshal.ReleaseComObject(_wordApplication) > 0) ;
        _wordApplication = null;
    }

    private void deleteTemplateDoc() {
        //HttpContext.Current.Response.Write("word delete: <b>" + docinput + "</b><br/>");
        if (File.Exists(docinput)) File.Delete(docinput);
    }

    private void docInitNewPage() {
        oInpuTFile = docinput;
        _wordDocument = _wordApplication.Documents.Open(ref oInpuTFile, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue);
        //HttpContext.Current.Response.Write("init page: <b>"+docinput +" --</b><br/>");
    }

    private void docClosePage() {
        while (System.Runtime.InteropServices.Marshal.ReleaseComObject(_wordDocument) > 0) ;
        _wordDocument = null;
    }

    private void docWritePage() {
        //format output
        switch (outputtype)
        {
            case "doc": oFileFormat = Word.WdSaveFormat.wdFormatDocument; swordoutputfile = swordoutputfile + ".doc"; break;
            case "html": oFileFormat = Word.WdSaveFormat.wdFormatHTML; swordoutputfile = swordoutputfile + ".html"; break;
            case "pdf": oFileFormat = Word.WdSaveFormat.wdFormatDocument; swordoutputfile = swordoutputfile + ".doc"; break;
            default: oFileFormat = Word.WdSaveFormat.wdFormatDocument; swordoutputfile = swordoutputfile + ".doc"; break;
        }

        //print PDF
        if (outputtype == "pdf")
        {
            //write ouput file
            this.WordPrintPDF(swordoutputfile);
            _wordDocument.Close(ref oFalse, ref nullValue, ref nullValue);
            Thread.Sleep(100);
        }
        else
        {
            //write ouput file
            oOutpuTFile = swordoutputfile;
            if (File.Exists(swordoutputfile)) File.Delete(swordoutputfile);
            _wordDocument.SaveAs(ref oOutpuTFile, ref oFileFormat, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue, ref nullValue);
            _wordDocument.Close(ref oTrue, ref nullValue, ref nullValue);
        }
       
        //close page
        this.docClosePage();

        //add to arraylist
        file_wrt.Add(swordoutputfile);

        /*writing*/
        string downloadstr = "output/" + System.IO.Path.GetFileName(swordoutputfile);
        HttpContext.Current.Response.Write("writing files:: <b>" + swordoutputfile + "</b> <a href=\"" + downloadstr + "\">download</a><br><br>");

       
    }

/*html handle*/
    private void applyMergeHTML() {
        if (datasourcetype == "xml")
        {
            readXMLDataSourceRow();
        }
        else if (datasourcetype == "excel")
        {
            readExcelDataSourceRow();
        }
    }

    private string bufferHTML,newStringHTML;

    private void openTemplateHTML()
    {
        //HttpContext.Current.Response.Write("HTML open: <b>" + docinput + "</b><br/>");
        //reading input
        StreamReader objReader = new StreamReader(docinput);
        bufferHTML = objReader.ReadToEnd();
        objReader.Close();
    }
    private void closeTemplateHTML()
    {
        //HttpContext.Current.Response.Write("HTML close: <b>" + docinput + "</b><br/>");
    }
    private void deleteTemplateHTML()
    {
        //HttpContext.Current.Response.Write("HTML delete: <b>" + docinput + "</b><br/>");
        if (File.Exists(docinput)) File.Delete(docinput);
    }

    private void HTMLInitNewPage()
    {
        newStringHTML = bufferHTML;
    }
    private void HTMLReplace(string s_tag2replace, string s_val2assign)
    {
        //HttpContext.Current.Response.Write("word replace : <b>" + s_tag2replace + "</b> with <b>" + s_val2assign + "</b><br/>");
        newStringHTML=newStringHTML.Replace(s_tag2replace, s_val2assign);
    }
    private void HTMLWritePage()
    {
        switch (outputtype)
        {
            case "html": swordoutputfile = swordoutputfile + ".html"; break;
            case "pdf": swordoutputfile = swordoutputfile + ".html"; break;
            default: swordoutputfile = swordoutputfile + ".html"; break;
        }
        FileInfo fleNewFile = new FileInfo(swordoutputfile);
        StreamWriter swrNewFile = fleNewFile.CreateText();
        swrNewFile.Write(newStringHTML);
        swrNewFile.Flush();
        swrNewFile.Close();
        newStringHTML = "";

        if(outputtype=="pdf"){
            string lastfile = swordoutputfile;
            this.PrintFile(swordoutputfile, this.outputpath);
            if(File.Exists(lastfile)) File.Delete(lastfile);
        }
       
        file_wrt.Add(swordoutputfile);

        /*writing*/
        string downloadstr = "output/"+System.IO.Path.GetFileName(swordoutputfile);
        HttpContext.Current.Response.Write("writing files:: <b>" + swordoutputfile + "</b> <a href=\"" + downloadstr + "\">download</a><br>");
       
    }


 /*xml datasource*/
    private string tblname0;
    private String[] alooptags;

    private void openXMLDataSource(){
        sdataset = new DataSet();
        sdataset.ReadXml(datasourcefile);
        //HttpContext.Current.Response.Write("reading xml: <b>" + datasourcefile.ToString() + "</b><br/>");
        alooptags = loopingtags.Split(',');
        tblname0 = alooptags[0].ToString();
    }
    private void readXMLDataSourceRow(){
        for (int row = 0; row < sdataset.Tables[tblname0].Rows.Count; row++)
        {
            ///doc init page
            if (docinputtype == "doc") docInitNewPage();
            else if(docinputtype == "html") HTMLInitNewPage();

            string s_outputfilename = outputfilename;
            for (int tb = 0; tb < alooptags.Length; tb++)
            {
                string tblname = alooptags[tb].ToString();

                if (row < sdataset.Tables[tblname].Rows.Count)
                {
                    DataRow dtr = sdataset.Tables[tblname].Rows[row];
                    for (int col = 0; col < sdataset.Tables[tblname].Columns.Count; col++)
                    {
                        DataColumn c = sdataset.Tables[tblname].Columns[col];
                        string tag2replace = starttag + tblname + "." + c.ColumnName + closetag;
                        string val2assign= dtr[c.ColumnName].ToString();
                        //doc replace
                        if (docinputtype == "doc") docReplace(tag2replace, val2assign);
                        else if (docinputtype == "html") HTMLReplace(tag2replace, val2assign);
                        //filename replace
                        s_outputfilename = s_outputfilename.Replace(tag2replace, val2assign);
                    }
                }
            }

            if (s_outputfilename == "" || s_outputfilename == outputfilename) s_outputfilename = row.ToString();
            swordoutputfile = string.Format("{0}{1}", outputpath, FixFileName(s_outputfilename));
                   
            //doc writepage
            if (docinputtype == "doc") docWritePage();
            else if (docinputtype == "html") HTMLWritePage();
        }
    }
    private void closeXMLDataSource() {
        sdataset = null;

    }
       
 /*excel datasource*/
    public Excel._Application excelApp;
    public Excel.Workbook excelWorkbook;
    public Excel.Worksheet excelWorksheet;
    public Excel.Sheets excelSheets;
    private object nullValue;
    private OleDbConnection con;
    private OleDbDataAdapter da;
    private DataTable tbl,tbl2;
    public void openExcelDataSource() {
        nullValue = Missing.Value;
        oFalse = false;
    }

    public void closeExcelDataSource() {
    }

    private void readExcelDataSourceRow() {
       
        con = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + datasourcefile + ";Extended Properties=Excel 8.0");
        //get all sheet name
        con.Open();
        tbl2 = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
        if(tbl2 == null) return ;
        String[] excelSheets = new String[tbl2.Rows.Count];
        int i = 0;
        foreach(DataRow tblrow in tbl2.Rows)
        {
          excelSheets[i] = tblrow["TABLE_NAME"].ToString();
          i++;
        }
       
        tbl2=null;

        foreach (string currentSheet in excelSheets)
        {
            string s_currentSheet = currentSheet.Replace("$", "");
            da = new OleDbDataAdapter("select * from [" + currentSheet + "]", con);
            tbl = new DataTable();
            da.Fill(tbl);
            if (tbl.Columns.Count > 1)
            {
                for (int row = 0; row < tbl.Rows.Count; row++)
                {
                    ///doc init page
                    if (docinputtype == "doc") docInitNewPage();
                    else if (docinputtype == "html") HTMLInitNewPage();
                    DataRow dtr = tbl.Rows[row];
                    string s_outputfilename = outputfilename;
                    for (int col = 0; col < tbl.Columns.Count; col++)
                    {
                        DataColumn c = tbl.Columns[col];
                        string tag2replace = starttag + s_currentSheet + "." + c.ColumnName + closetag;
                        string val2assign = dtr[c.ColumnName].ToString();
                        //doc replace
                        if (docinputtype == "doc") docReplace(tag2replace, val2assign);
                   &n