<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">

 <title>Mohd Amree</title>
 
 <link href="http://ieatbinary.com/" />
 <updated>2013-05-10T13:52:26-07:00</updated>
 <id>http://ieatbinary.com/</id>
 <author>
   <name>Mohd Amree</name>
   <email>amree@linux.org.my</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ieatbinary" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="ieatbinary" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>Rails, Unicorn and Nginx on Slackware</title>
   <link href="http://ieatbinary.com/2013/01/06/rails-unicorn-and-nginx-on-slackware/" />
   <updated>2013-01-06T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2013/01/06/rails-unicorn-and-nginx-on-slackware</id>
   <content type="html">&lt;h1 id='rails_unicorn_and_nginx_on_slackware'&gt;Rails, Unicorn and Nginx on Slackware&lt;/h1&gt;

&lt;p&gt;I was trying to deploy a Rails application using Apache and got into some problems when I tried to configure the app so that Apache will be the one that serves the precompiled assets (javascripts, css, images and others). Since I&amp;#8217;m on tight deadline (yeah, I should&amp;#8217;ve tested production mode much more earlier), I tried my luck with Nginx and it worked easily without any hassle. So, this is how I did it.&lt;/p&gt;

&lt;h2 id='goals'&gt;Goals&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Precompiled assets will be served by Nginx and not the Rails server itself.&lt;/li&gt;

&lt;li&gt;Assets will be served in gzip.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='environments'&gt;Environments&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Slackware v14&lt;/li&gt;

&lt;li&gt;Rails v3.2.10&lt;/li&gt;

&lt;li&gt;Ruby v1.9.3&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='guides'&gt;Guides&lt;/h2&gt;

&lt;p&gt;First of all, install &lt;a href='http://slackbuilds.org/repository/14.0/network/nginx/'&gt;nginx&lt;/a&gt; from Slackbuild.&lt;/p&gt;

&lt;p&gt;Be sure to turn off Apache&amp;#8217;s startup script if you have it installed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chmod -x /etc/rc.d/rc.httpd&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is to ensure no conflict since both of them by default will use port 80.&lt;/p&gt;

&lt;p&gt;Put &lt;code&gt;unicorn&lt;/code&gt; in your Gemfile and run &lt;code&gt;bundle&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m putting my Rails app in &lt;code&gt;/opt/neuro&lt;/code&gt;, so, adjust it accordingly.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;nginx.conf&lt;/code&gt; in &lt;code&gt;/opt/neuro/config/nginx.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='nginx'&gt;&lt;span class='k'&gt;upstream&lt;/span&gt; &lt;span class='s'&gt;unicorn&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kn'&gt;server&lt;/span&gt; &lt;span class='s'&gt;unix:/tmp/unicorn.neuro.sock&lt;/span&gt; &lt;span class='s'&gt;fail_timeout=0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='k'&gt;server&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kn'&gt;listen&lt;/span&gt; &lt;span class='mi'&gt;80&lt;/span&gt; &lt;span class='s'&gt;default&lt;/span&gt; &lt;span class='s'&gt;deferred&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='kn'&gt;server_name&lt;/span&gt; &lt;span class='s'&gt;neuro.husmnet&lt;/span&gt;
  &lt;span class='s'&gt;root&lt;/span&gt; &lt;span class='s'&gt;/opt/neuro/public&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='kn'&gt;location&lt;/span&gt; &lt;span class='s'&gt;^~&lt;/span&gt; &lt;span class='s'&gt;/assets/&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kn'&gt;root&lt;/span&gt; &lt;span class='s'&gt;/opt/neuro/public&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kn'&gt;gzip_static&lt;/span&gt; &lt;span class='no'&gt;on&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kn'&gt;expires&lt;/span&gt; &lt;span class='s'&gt;max&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kn'&gt;add_header&lt;/span&gt; &lt;span class='s'&gt;Cache-Control&lt;/span&gt; &lt;span class='s'&gt;public&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='kn'&gt;try_files&lt;/span&gt; &lt;span class='nv'&gt;$uri/index.html&lt;/span&gt; &lt;span class='nv'&gt;$uri&lt;/span&gt; &lt;span class='s'&gt;@unicorn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='kn'&gt;location&lt;/span&gt; &lt;span class='s'&gt;@unicorn&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kn'&gt;proxy_set_header&lt;/span&gt; &lt;span class='s'&gt;X-Forwarded-For&lt;/span&gt; &lt;span class='nv'&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kn'&gt;proxy_set_header&lt;/span&gt; &lt;span class='s'&gt;Host&lt;/span&gt; &lt;span class='nv'&gt;$http_host&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kn'&gt;proxy_redirect&lt;/span&gt; &lt;span class='no'&gt;off&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kn'&gt;proxy_pass&lt;/span&gt; &lt;span class='s'&gt;http://unicorn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='kn'&gt;error_page&lt;/span&gt; &lt;span class='mi'&gt;500&lt;/span&gt; &lt;span class='mi'&gt;502&lt;/span&gt; &lt;span class='mi'&gt;503&lt;/span&gt; &lt;span class='mi'&gt;504&lt;/span&gt; &lt;span class='s'&gt;/500.html&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='kn'&gt;client_max_body_size&lt;/span&gt; &lt;span class='s'&gt;4G&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='kn'&gt;keepalive_timeout&lt;/span&gt; &lt;span class='mi'&gt;10&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create &lt;code&gt;unicorn.rb&lt;/code&gt; in &lt;code&gt;/opt/neuro/config/unicorn.rb&lt;/code&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;root&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='no'&gt;Dir&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;pwd&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;

&lt;span class='c1'&gt;# Define worker directory for Unicorn&lt;/span&gt;
&lt;span class='n'&gt;working_directory&lt;/span&gt; &lt;span class='n'&gt;root&lt;/span&gt;

&lt;span class='c1'&gt;# Location of PID file&lt;/span&gt;
&lt;span class='n'&gt;pid&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;/tmp/pids/unicorn.pid&amp;quot;&lt;/span&gt;

&lt;span class='c1'&gt;# Define Log paths&lt;/span&gt;
&lt;span class='n'&gt;stderr_path&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;/log/unicorn.log&amp;quot;&lt;/span&gt;
&lt;span class='n'&gt;stdout_path&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;/log/unicorn.log&amp;quot;&lt;/span&gt;

&lt;span class='c1'&gt;# Listen on a UNIX data socket&lt;/span&gt;
&lt;span class='n'&gt;listen&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/tmp/unicorn.neuro.sock&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:backlog&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;64&lt;/span&gt;
&lt;span class='c1'&gt;# houllisten 8080, :tcp_nopush =&amp;gt; true&lt;/span&gt;

&lt;span class='n'&gt;worker_processes&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;

&lt;span class='c1'&gt;# Load rails before forking workers for better worker spawn time&lt;/span&gt;
&lt;span class='n'&gt;preload_app&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;

&lt;span class='c1'&gt;# Restart workes hangin&amp;#39; out for more than 240 secs&lt;/span&gt;
&lt;span class='n'&gt;timeout&lt;/span&gt; &lt;span class='mi'&gt;240&lt;/span&gt;

&lt;span class='no'&gt;Replace&lt;/span&gt; &lt;span class='sb'&gt;`/etc/nginx/nginx.conf`&lt;/span&gt; &lt;span class='n'&gt;with&lt;/span&gt; &lt;span class='n'&gt;this&lt;/span&gt; &lt;span class='ss'&gt;content&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;

&lt;span class='c1'&gt;# user  root;&lt;/span&gt;
&lt;span class='n'&gt;worker_processes&lt;/span&gt;  &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='n'&gt;error_log&lt;/span&gt;  &lt;span class='sr'&gt;/var/&lt;/span&gt;&lt;span class='n'&gt;log&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;nginx&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;error&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;log&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='c1'&gt;#error_log  logs/error.log  notice;&lt;/span&gt;
&lt;span class='c1'&gt;#error_log  logs/error.log  info;&lt;/span&gt;

&lt;span class='c1'&gt;#pid        logs/nginx.pid;&lt;/span&gt;

&lt;span class='n'&gt;events&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='n'&gt;worker_connections&lt;/span&gt;  &lt;span class='mi'&gt;1024&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='n'&gt;http&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kp'&gt;include&lt;/span&gt;       &lt;span class='n'&gt;mime&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;types&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='n'&gt;default_type&lt;/span&gt;  &lt;span class='n'&gt;application&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;octet&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;stream&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='n'&gt;sendfile&lt;/span&gt;        &lt;span class='n'&gt;on&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='n'&gt;keepalive_timeout&lt;/span&gt;  &lt;span class='mi'&gt;65&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='n'&gt;gzip&lt;/span&gt;  &lt;span class='n'&gt;on&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='sr'&gt;/etc/n&lt;/span&gt;&lt;span class='n'&gt;ginx&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;sites&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;enabled&lt;/span&gt;&lt;span class='o'&gt;/*&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create &lt;code&gt;sites-enabled&lt;/code&gt; directory in &lt;code&gt;/etc/nginx&lt;/code&gt; and create a softlink to the &lt;code&gt;nginx.conf&lt;/code&gt; in our app:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir /etc/nginx/sites-enabled
$ ln -s /opt/neuro/config/nginx.conf neuro.conf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Before starting it for the first time, let us monitor important logs (open it using different terminals) :&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ tail -f /var/log/nginx/error.log
$ tail -f /opt/neuro/log/unicorn.log&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make sure you&amp;#8217;ve precompiled your assets:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rake assets:clean
$ rake assets:precompile&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Start unicorn:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd /opt/neuro
$ unicorn -c config/unicorn.rb -E production -D&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Start nginx:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nginx&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Congratulation! Make sure there&amp;#8217;s no error in your logs. If there&amp;#8217;re, you can use these commands to stop &lt;code&gt;nginx&lt;/code&gt; and &lt;code&gt;unicorn&lt;/code&gt; to start everything back:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nginx -s stop
$ killall unicorn&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#8217;s test the gzip compression using &lt;code&gt;curl&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl -LI --compressed http://neuro.husmnet/&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&amp;#8217;ll get something like this (notice the gzip info):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
Server: nginx/1.2.2
Date: Sat, 05 Jan 2013 21:00:26 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Status: 200 OK
X-UA-Compatible: IE=Edge,chrome=1
ETag: &amp;quot;a66ac1d43d8f07ecc0737e64dd8a3366&amp;quot;
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: _neuro_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTQ2YTU2NjE3MDY0Y2RkNzk0Yzk3ODhhNDJlYmQ3ODA3BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMVNvOXVTS2I2RXJIcTljbS9WeGRDODZyTUpVZENXL2NPVnJhTGR0V2xydGM9BjsARg%3D%3D--173e9d56a5cc434eb675b6626d90aced1cc17cd6; path=/; HttpOnly
X-Request-Id: 760e233de4980dc75169f2c68a53dc31
X-Runtime: 0.017885
X-Rack-Cache: miss
Content-Encoding: gzip&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I admit, this is a very simple config, but it&amp;#8217;s good enough for a beginner like me to get started. So, good luck!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>MyKad Codes Takedown</title>
   <link href="http://ieatbinary.com/2012/11/04/mykad-codes-takedown/" />
   <updated>2012-11-04T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2012/11/04/mykad-codes-takedown</id>
   <content type="html">&lt;h1 id='mykad_codes_takedown'&gt;MyKad Codes Takedown&lt;/h1&gt;

&lt;p&gt;Last month my colleague and I had a meeting with Jabatan Pendaftaran Negara. From that meeting I learned people at JPN are not really happy with the code to read MyKad available publicly on the Internet especially not in the Github due to some reasons which I don&amp;#8217;t think should be mentioned here.&lt;/p&gt;

&lt;p&gt;Since I&amp;#8217;ve posted those codes (from Xenon and myself) on the Github, I had to take them down permanently. IMHO I should respect their decision since it&amp;#8217;s not mine to begin with. I love how those codes have helped a lot of people especially students as they do not really have the sufficient funds to buy the expensive SDK. I would love to comment further on this decision, but I don&amp;#8217;t think I should :(.&lt;/p&gt;

&lt;p&gt;Saya yang menurut perintah,&lt;/p&gt;

&lt;p&gt;Mohd Amree&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Getting Started with Xen on Slackware</title>
   <link href="http://ieatbinary.com/2012/09/12/getting-started-with-xen-on-slackware/" />
   <updated>2012-09-12T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2012/09/12/getting-started-with-xen-on-slackware</id>
   <content type="html">&lt;h1 id='getting_started_with_xen_on_slackware'&gt;Getting Started with Xen on Slackware&lt;/h1&gt;

&lt;h2 id='install_slackware'&gt;Install Slackware&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;ll be doing this on Slackware v13.37 64 bit.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create 1 partition for the whole disk&lt;/li&gt;

&lt;li&gt;Set its type to &lt;code&gt;8e&lt;/code&gt; (Linux LVM)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run these commands to setup the LVM partitions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ pvcreate /dev/sda1
$ vgcreate vg01 /dev/sda1
$ lvcreate -L 20G -n root vg01
$ lvcreate -L 20G -n iso vg01
$ lvcreate -L 8G -n swap vg01
$ mkswap /dev/vg01/swap
$ setup&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;Mount &lt;code&gt;/dev/vg01/root&lt;/code&gt; as &lt;code&gt;/&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Mount &lt;code&gt;/dev/vg01/iso&lt;/code&gt; as &lt;code&gt;/iso&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Install all packages from a, ap, d, f, l, n, t, tcl, x&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create custom &lt;code&gt;initrd&lt;/code&gt; after the setup complete:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ chroot /mnt
$ /usr/share/mkinitrd/mkinitrd_command_generator.sh &amp;gt; init
$ sh init
$ ln -sf /boot/vmlinuz-generic-2.6.37.6 /boot/vmlinuz&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add &lt;code&gt;initrd&lt;/code&gt; option in your &lt;code&gt;/etc/lilo.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/lilo.conf

image = /boot/vmlinuz
  initrd = /boot/initrd.gz # Add this line
  root = /dev/vg01/root
  label = slackware
  read-only  # Partitions should be mounted read-only for checking&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install the new bootloader and reboot:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ lilo
$ exit
$ reboot&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='setup_dom0_host'&gt;Setup Dom0 (Host)&lt;/h2&gt;

&lt;h3 id='install_xen'&gt;Install Xen&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href='http://slackbuilds.org/repository/13.37/development/acpica/'&gt;acpica&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Install &lt;a href='http://slackbuilds.org/repository/13.37/system/xen/'&gt;xen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='build_xen_kernel'&gt;Build Xen Kernel&lt;/h3&gt;

&lt;p&gt;We&amp;#8217;ll be using kernel v3.2.28 so that no patching will be required to enable Xen and for that we&amp;#8217;ll get the one from Slackware&amp;#8217;s repo. By the time of this writing, Slackware v14 has not been released yet (it&amp;#8217;s in the current).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ wget http://slackware.osuosl.org/slackware-current/source/k/linux-3.2.28.tar.xz
$ tar Jxvf linux-3.2.28.tar.xz
$ mv linux-3.2.28 linux-3.2.28-xen
$ mv linux-3.2.28-xen/ /usr/src/
$ cd /usr/src
$ rm linux
$ ln -s linux-3.2.28-xen linux&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Get Slackware&amp;#8217;s default kernel config for a start. From there, you must add all Xen&amp;#8217;s related kernel configs. You can refer to &lt;a href='http://wiki.xen.org/wiki/Mainline_Linux_Kernel_Configs'&gt;Xen&amp;#8217;s wiki&lt;/a&gt; on what kernel config that needs to be enabled.&lt;/p&gt;

&lt;p&gt;You can also get my configs from this &lt;a href='https://gist.github.com/3695518'&gt;gist&lt;/a&gt;. It&amp;#8217;s based on 3.2.28 kernel (you can use Gist&amp;#8217;s diff to see what config I&amp;#8217;ve added).&lt;/p&gt;

&lt;p&gt;Whatever you chose, make sure you&amp;#8217;ll change the LOCALVERSION so that you won&amp;#8217;t replace your current kernel. Use &lt;code&gt;cat /proc/cpuinfo | grep -i &amp;#39;processor&amp;#39; | wc -l&lt;/code&gt; + 1 to get your cpu core count to be used with &lt;code&gt;make -j&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd linux
$ wget http://slackware.osuosl.org/slackware-current/source/k/config-x86_64/config-generic-3.2.28.x64
$ cp config-generic-3.2.28.x64 .config
$ make oldconfig
$ make menuconfig
$ make -j13 bzImage modules
$ make modules_install
$ cp System.map /boot/System.map-xen-3.2.28
$ cp .config /boot/config-xen-3.2.28
$ cd /boot
$ rm System.map
$ ln -s System.map-xen-3.2.28 System.map&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='xen__dom0__initrd'&gt;Xen + Dom0 + Initrd&lt;/h3&gt;

&lt;p&gt;Since LILO doesn&amp;#8217;t support &amp;#8220;module&amp;#8221; directive of Grub, we need to use &lt;code&gt;mbootpack&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href='http://slackbuilds.org/repository/13.37/system/mbootpack/'&gt;mbootpack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use &lt;code&gt;/usr/share/mkinitrd/mkinitrd_command_generator.sh&lt;/code&gt; for &lt;code&gt;mkinitrd&lt;/code&gt; recommendation. Create an initrd for Xen&amp;#8217;s kernel:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ depmod 3.2.28-xen
$ mkinitrd -c -k 3.2.28-xen -f ext4 -r /dev/vg01/root -m mptbase:mptscsih:mptsas:usbhid:ehci-hcd:uhci-hcd:jbd2:mbcache:ext4 -L -u -o /boot/initrd-xen.gz&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create the boot image using &lt;code&gt;mbootpack&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd /boot
$ gzip -d -c /boot/xen-4.1.2.gz &amp;gt; /boot/xen-4.1.2
$ gzip -d -c /boot/initrd-xen.gz &amp;gt; /boot/initrd-xen
$ mbootpack -o /boot/vmlinuz-xen-3.2.28 -m /usr/src/linux-3.2.28-xen/vmlinux -m /boot/initrd-xen /boot/xen-4.1.2
$ ln -s vmlinuz-xen-3.2.28 vmlinuz-xen&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With &lt;code&gt;mbootpack&lt;/code&gt;, we don&amp;#8217;t have to specify &lt;code&gt;initrd&lt;/code&gt; option. Add these new configs into your &lt;code&gt;/etc/lilo.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/lilo.conf

image = /boot/vmlinuz-xen
  root = /dev/vg01/root
  label = slackware-xen
  append=&amp;quot;-- nomodeset&amp;quot;
  read-only&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Put these configs on the top of your &lt;code&gt;lilo.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;default = slackware-xen
timeout = 30&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Run &lt;code&gt;lilo&lt;/code&gt; and make sure there&amp;#8217;s no error from the output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ lilo
Warning: LBA32 addressing assumed
Added slackware
Added slackware-xen *
One warning was issued.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Put these settings in your &lt;code&gt;/etc/rc.d/rc.local&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/rc.d/rc.local

if [ -d /proc/xen ]; then
  if [ -x /etc/rc.d/rc.xencommons ]; then
    echo &amp;quot;Starting XEN commons:  /etc/rc.d/rc.xencommons&amp;quot;
    /etc/rc.d/rc.xencommons start
  fi
  if [ -x /etc/rc.d/rc.xendomains ]; then
    echo &amp;quot;Starting XEN domains:  /etc/rc.d/rc.xendomains&amp;quot;
    /etc/rc.d/rc.xendomains start
  fi
fi&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And these commands in your &lt;code&gt;/etc/rc.d/rc.local_shutdown&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/rc.d/rc.local_shutdown

if [ -d /proc/xen ]; then
  if [ -x /etc/rc.d/rc.xendomains ]; then
    echo &amp;quot;Stopping XEN domains:  /etc/rc.d/rc.xendomains&amp;quot;
    /etc/rc.d/rc.xendomains stop
  fi
  if [ -x /etc/rc.d/rc.xencommons ]; then
    echo &amp;quot;Stopping XEN commons:  /etc/rc.d/rc.xencommons&amp;quot;
    /etc/rc.d/rc.xencommons stop
  fi
fi&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After the reboot, you should get something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ uname -r
3.2.28-xen

$ cat /proc/xen/capabilities
control_d

$ cat /sys/hypervisor/properties/capabilities
xen-3.0-x86_64 xen-3.0-x86_32p hvm-3.0-x86_32 hvm-3.0-x86_32p hvm-3.0-x86_64

$ xl list
Name                                        ID   Mem VCPUs  State Time(s)
Domain-0                                     0 15243    12     r-----       9.0&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Disable autosave and restore of &lt;code&gt;DomU&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/default/xendomains

XENDOMAINS_RESTORE=false
XENDOMAINS_SAVE=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='setup_domu_guest'&gt;Setup DomU (Guest)&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m going to install a Slackware v13.37 64 bit as the first guest. I&amp;#8217;ll be using an ISO image that I&amp;#8217;ve copied into my &lt;code&gt;/iso&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd /iso
$ wget http://mirrors.xmission.com/slackware/slackware64-13.37-iso/slackware64-13.37-install-dvd.iso&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For a start, we need to create a config file for the Slackware installation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir ~/machines
$ cd ~/machines
$ vim slackware-install&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Put these initial configs in your &lt;code&gt;/root/machines/slackware-install&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;kernel = &amp;#39;hvmloader&amp;#39;
builder=&amp;#39;hvm&amp;#39;
memory = 1024
name = &amp;quot;slackware&amp;quot;
vif = [ &amp;#39;mac=00:16:3E:AD:81:AE, bridge=virbr0, model=e1000&amp;#39; ]
dhcp = &amp;quot;dhcp&amp;quot;
disk = [&amp;#39;phy:/dev/vg01/slackware,hda,w&amp;#39;, &amp;#39;file:/iso/slackware64-13.37-install-dvd.iso,hdc:cdrom,r&amp;#39;]
boot=&amp;#39;dc&amp;#39;
sdl=0
opengl=1
vnc=1
vncpasswd=&amp;#39;&amp;#39;
serial=&amp;#39;pty&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, there&amp;#8217;re various of thing thats we need to take care of before we start the installation. First of all the networking.&lt;/p&gt;

&lt;h3 id='generate_random_mac'&gt;Generate Random MAC&lt;/h3&gt;

&lt;p&gt;Use this command (thanks to &lt;a href='http://unixtitan.net/main/2009/12/01/xen-mac-generator/'&gt;Unixtitan&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;perl -e &amp;#39;printf &amp;quot;00:16:3E:%02X:%02X:%02X\n&amp;quot;, rand 0xFF, rand 0xFF, rand 0xFF&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='setup_networking_bridging'&gt;Setup Networking Bridging&lt;/h3&gt;

&lt;p&gt;There are a few methods for a DomU to access the network. For this guide, I&amp;#8217;ll use network bridging.&lt;/p&gt;

&lt;p&gt;Put these configs (before starting anything related to Xen) into your &lt;code&gt;/etc/rc.d/rc.local&lt;/code&gt; to enable network bridge:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/rc.d/rc.local

ifconfig eth0 up
ifconfig eth0 0.0.0.0

brctl addbr virbr0
brctl addif virbr0 eth0
ifconfig virbr0 192.168.1.10 netmask 255.255.255.0
route add default gw 192.168.1.1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Clear out any values set in your &lt;code&gt;/etc/rc.d/rc.inet1.conf&lt;/code&gt;. Usually the value of &lt;code&gt;IPADDR[0]&lt;/code&gt;, &lt;code&gt;NETMASK[0]&lt;/code&gt; and &lt;code&gt;GATEWAY&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/rc.d/rc.inet1.conf

# Config information for eth0:
IPADDR[0]=&amp;quot;&amp;quot;
NETMASK[0]=&amp;quot;&amp;quot;
USE_DHCP[0]=&amp;quot;&amp;quot;
DHCP_HOSTNAME[0]=&amp;quot;&amp;quot;

# Default gateway IP address:
GATEWAY=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This configs assume your main networking interface is &lt;code&gt;eth0&lt;/code&gt;. Change other settings based on your network environment. Reboot your &lt;code&gt;Dom0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;ll get something that looks like this after the reboot (if you got it right).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ifconfig

eth0      Link encap:Ethernet  HWaddr bc:30:5b:db:e2:99
          inet6 addr: fe80::be30:5bff:fedb:e299/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:163836 errors:0 dropped:0 overruns:0 frame:0
          TX packets:337 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:18347806 (17.4 MiB)  TX bytes:30535 (29.8 KiB)
          Interrupt:36 Memory:d6000000-d6012800

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:336 (336.0 B)  TX bytes:336 (336.0 B)

virbr0    Link encap:Ethernet  HWaddr bc:30:5b:db:e2:99
          inet addr:192.168.1.10  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::be30:5bff:fedb:e299/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:147426 errors:0 dropped:506 overruns:0 frame:0
          TX packets:129 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:12417385 (11.8 MiB)  TX bytes:16779 (16.3 KiB)&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='enable_x11_forwarding_in_dom0'&gt;Enable X11 Forwarding in Dom0&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href='http://slackbuilds.org/repository/12.2/system/vncviewer/'&gt;vncviewer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uncomment or create these options in your &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/ssh/sshd_config

X11Forwarding yes&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Restart your &lt;code&gt;ssh&lt;/code&gt; server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ /etc/rc.d/rc.sshd restart
$ exit&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Reconnect to &lt;code&gt;Dom0&lt;/code&gt; using &lt;code&gt;-Y&lt;/code&gt; option:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ssh -Y root@192.168.1.10
$ xclock&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you can see a clock ticking, that means the X11 forward is working.&lt;/p&gt;

&lt;h3 id='prepare_space_for_domu'&gt;Prepare space for DomU&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;m going to store my &lt;code&gt;DomU&lt;/code&gt; in the a new logical volume.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ lvcreate -L 15G -n slackware vg01&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='install_slackware_in_domu'&gt;Install Slackware in DomU&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;$ cd machines
$ xl create slackware&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If everything is good, you should see &lt;code&gt;slackware&lt;/code&gt; when you run &lt;code&gt;xl list&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ xl list
Name                                        ID   Mem VCPUs  State Time(s)
Domain-0                                     0 13988    12     r-----      40.0
slackware                                    2  1019     1     -b----       4.6&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install Slackware through VNC:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ xl vncviewer slackware&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Just install as if you&amp;#8217;re installing on a normal server. &lt;code&gt;halt&lt;/code&gt; after you&amp;#8217;ve finished your installation.&lt;/p&gt;

&lt;h3 id='start_slackware_in_domu'&gt;Start Slackware in DomU&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;$ cd ~/machines
$ cp slackware-install slackware
$ vim slackware&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Change these two lines in your config file to make sure it&amp;#8217;ll boot from the hardisk:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /root/machines/slackware

disk = [&amp;#39;phy:/dev/vg01/slackware,hda,w&amp;#39;]
boot=&amp;#39;c&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Start the guest:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ xl create slackware&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='enable_console_in_domu'&gt;Enable Console in DomU&lt;/h3&gt;

&lt;p&gt;It&amp;#8217;s pretty annoying to use vnc everytime we need to access our &lt;code&gt;DomU&lt;/code&gt; directly. It&amp;#8217;s possible to connect to our &lt;code&gt;DomU&lt;/code&gt; using console connection:&lt;/p&gt;

&lt;p&gt;Uncomment these lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# /etc/inittab
s1:12345:respawn:/sbin/agetty -L ttyS0 9600 vt100

# /etc/securetty
ttyS0

$ reboot&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For Ubuntu&amp;#8217;s &lt;code&gt;DomU&lt;/code&gt;, please check out &lt;a href='https://help.ubuntu.com/community/SerialConsoleHowto'&gt;https://help.ubuntu.com/community/SerialConsoleHowto&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can now connect to your Slackware DomU using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ xl console slackware&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='additional_info'&gt;Additional Info&lt;/h2&gt;

&lt;p&gt;Disable auto save and restore of domUs on host reboot:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ vim /etc/default/xendomains

XENDOMAINS_RESTORE=false
XENDOMAINS_SAVE=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In order to run &lt;code&gt;xl shutdown guest&lt;/code&gt; so that your &lt;code&gt;DomU&lt;/code&gt; will shutdown gracefully, you need to use &lt;a href='http://wiki.xen.org/wiki/Xen_Linux_PV_on_HVM_drivers'&gt;PVHVM drivers&lt;/a&gt;. You can refer &lt;a href='http://wiki.xen.org/wiki/Mainline_Linux_Kernel_Configs'&gt;here&lt;/a&gt; for the related kernel configs that you need to enable in your kernel.&lt;/p&gt;

&lt;p&gt;There are still many things that I&amp;#8217;d like to add, but I think it&amp;#8217;s good enough for now. After all, this post is about getting started, not a complete guide. I&amp;#8217;ll update this post if I found anything worth of sharing.&lt;/p&gt;

&lt;p&gt;Good luck!&lt;/p&gt;

&lt;p&gt;More references:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://wiki.xen.org/wiki/XenCommonProblems'&gt;http://wiki.xen.org/wiki/XenCommonProblems&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://wiki.xen.org/wiki/Xen_Best_Practices'&gt;http://wiki.xen.org/wiki/Xen_Best_Practices&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://wiki.xen.org/wiki/Xen_Linux_PV_on_HVM_drivers'&gt;http://wiki.xen.org/wiki/Xen_Linux_PV_on_HVM_drivers&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://alien.slackbook.org/dokuwiki/doku.php?id=linux:kernelbuilding'&gt;http://alien.slackbook.org/dokuwiki/doku.php?id=linux:kernelbuilding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Corosync and Pacemaker in Slackware</title>
   <link href="http://ieatbinary.com/2012/05/14/corosync-and-pacemaker-in-slackware/" />
   <updated>2012-05-14T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2012/05/14/corosync-and-pacemaker-in-slackware</id>
   <content type="html">&lt;h1 id='corosync_and_pacemaker_in_slackware'&gt;Corosync and Pacemaker in Slackware&lt;/h1&gt;

&lt;p&gt;This will be multi part post about high availability solution for Slackware. My first post will be about Corosync and Pacemaker.&lt;/p&gt;

&lt;p&gt;You need to combine Corosync and Pacemaker with other distributed storage system such as &lt;a href='http://www.drbd.org/'&gt;DRBD&lt;/a&gt;/&lt;a href='http://oss.oracle.com/projects/ocfs2/'&gt;OCFS2&lt;/a&gt;/&lt;a href='http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/5/html-single/Global_File_System_2/'&gt;GFS&lt;/a&gt;. I&amp;#8217;ll talk about these stacks in another post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A MySQL server will always be available at the same IP even though it&amp;#8217;s actually down (another server will take over automatically without the needs for manual intervention).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Environments:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Slackware v13.37&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Two nodes will be used:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Node 1:
192.168.1.101

Node 2:
192.168.1.102

Cluster/Main/Failover IP:
192.168.1.100&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The MySQL data is not syncronized, this post is just about &lt;a href='http://www.corosync.org/'&gt;Corosync&lt;/a&gt; and &lt;a href='http://www.clusterlabs.org/'&gt;Pacemaker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Guides:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download and install these packages (by this order) in both nodes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://slackbuilds.org/repository/13.37/libraries/libnet/'&gt;http://slackbuilds.org/repository/13.37/libraries/libnet/&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://slackbuilds.org/repository/13.37/libraries/libesmtp/'&gt;http://slackbuilds.org/repository/13.37/libraries/libesmtp/&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://slackbuilds.org/repository/13.37/system/clusterglue/'&gt;http://slackbuilds.org/repository/13.37/system/clusterglue/&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://slackbuilds.org/repository/13.37/system/clusterresourceagents/'&gt;http://slackbuilds.org/repository/13.37/system/clusterresourceagents/&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://slackbuilds.org/repository/13.37/system/corosync/'&gt;http://slackbuilds.org/repository/13.37/system/corosync/&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://slackbuilds.org/repository/13.37/system/pacemaker/'&gt;http://slackbuilds.org/repository/13.37/system/pacemaker/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I strongly suggest you build these packages one by one just to be sure there are no missing dependencies. BTW, some script adjustments are needed for Cluster Resource Agents but I&amp;#8217;m sure you guys can handle it ;-)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;It would be easier for the next steps if &lt;a href='http://www.debian-administration.org/articles/152'&gt;password-less&lt;/a&gt; login with OpenSSH is enabled. In your &lt;code&gt;Node 1&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.102&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Generate an authentication key for Corosync:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;corosync-keygen&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you&amp;#8217;re connecting remotely, pressing your keyboard won&amp;#8217;t do any good. The fastest way would be typing directly into the server. The other way is running &lt;code&gt;find .&lt;/code&gt; on your &lt;code&gt;/&lt;/code&gt; directory (press &lt;code&gt;Control + C&lt;/code&gt; when the key has been generated).&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Copy the new generated authentication key to &lt;code&gt;Node 2&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp /etc/corosync/authkey 192.168.1.102:/etc/corosync&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Copy the default &lt;code&gt;corosync&lt;/code&gt; configuration file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Replace &lt;code&gt;bindnetaddr&lt;/code&gt; and &lt;code&gt;logfile&lt;/code&gt; (optional):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bindnetaddr: 192.168.1.0
logfile: /var/log/corosync&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can checkout the &lt;a href='http://www.corosync.org/doku.php?id=faq:configure_openais'&gt;reference&lt;/a&gt; about those values. From corosync:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;If the local interface was 10.12.12.93 and the netmask was 255.0.0.0, Totem would execute the logical operation 10.12.12.93 &amp;amp; 255.0.0.0 and produce the value 10.0.0.0. This value would be compared against bindnetaddr and bind Totem to the NIC that matches.
This can cause confusion if netmask or bindnetaddr are not set properly.
In the example above, if bindnetaddr is 10.12.12.0, the network interface will never be matched. If bindnetaddr is 10.0.0.0 the interface will be matched.&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Copy &lt;code&gt;corosync.conf&lt;/code&gt; to &lt;code&gt;Node 2&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp /etc/corosync/corosync.conf 192.168.1.102:/etc/corosync&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Create &lt;code&gt;pacemaker&lt;/code&gt; file so that &lt;code&gt;Corosync&lt;/code&gt; will automatically load &lt;code&gt;Pacemaker&lt;/code&gt; when it&amp;#8217;s started:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;touch /etc/corosync/service.d/pacemaker&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Put these configs in that file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;service {
  # Load the Pacemaker Cluster Resource Manager
  name: pacemaker
  ver:  0
}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Copy the &lt;code&gt;pacemaker&lt;/code&gt; file to Node 2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp /etc/corosync/service.d/pacemaker 192.168.1.102:/etc/corosync/service.d/&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Start your Corosync and let the magic begins:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/etc/rc.d/rc.corosync start&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Check your log for any error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tail -f /var/log/corosync&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Check your process list:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ps auxf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Corosync should also load other processes automatically:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root      2008  0.5  3.4  52668  3964 ?        Ssl  13:55   0:00 corosync
root      2015  0.0  1.9  12140  2248 ?        S    13:55   0:00  \_ /usr/lib/heartbeat/stonithd
226       2016  0.3  3.3  13004  3796 ?        S    13:55   0:00  \_ /usr/lib/heartbeat/cib
root      2017  0.0  1.6   6812  1848 ?        S    13:55   0:00  \_ /usr/lib/heartbeat/lrmd
226       2018  0.1  2.2  12404  2540 ?        S    13:55   0:00  \_ /usr/lib/heartbeat/attrd
226       2019  0.0  1.7   8664  2032 ?        S    13:55   0:00  \_ /usr/lib/heartbeat/pengine
226       2020  0.1  2.5  12528  2904 ?        S    13:55   0:00  \_ /usr/lib/heartbeat/crmd&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Monitor your cluster using Pacemaker tools:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;crm status&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It should be something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;============
Last updated: Sun May 13 13:57:43 2012
Stack: openais
Current DC: node1 - partition with quorum
Version: 1.1.1-b9b672590e79770afb63b9b455400d92fb6b5d9e
2 Nodes configured, 2 expected votes
0 Resources configured.
============

Online: [ node1 node2 ]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Give them some time to online if they&amp;#8217;re offline.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Put some main configurations to your cluster:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;crm
configure
property stonith-enabled=false
property no-quorum-policy=ignore
commit
quit&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you&amp;#8217;re getting some errors such as &lt;code&gt;ERROR: cib-bootstrap-options: attribute last-lrm-refresh does not exist&lt;/code&gt;, just proceed. It maybe a &lt;a href='http://www.gossamer-threads.com/lists/linuxha/users/63183'&gt;bug&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We had to disable &lt;code&gt;stonith&lt;/code&gt; since we just want our Pacemaker to be running. However, in real production environment, you really need to configure &lt;code&gt;stonith&lt;/code&gt;, you can read more about it &lt;a href='http://www.novell.com/support/kb/doc.php?id=7004817'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We also need to ignore quorum policy since we&amp;#8217;re only using 2 nodes and you can read more about it &lt;a href='http://www.clusterlabs.org/wiki/FAQ#I_Killed_a_Node_but_the_Cluster_Didn.27t_Recover'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can see your new configuration by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;	crm configure show&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which will output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;	node node1
	node node2
	property $id=&amp;quot;cib-bootstrap-options&amp;quot; \
		dc-version=&amp;quot;1.1.1-b9b672590e79770afb63b9b455400d92fb6b5d9e&amp;quot; \
		cluster-infrastructure=&amp;quot;openais&amp;quot; \
		expected-quorum-votes=&amp;quot;2&amp;quot; \
		stonith-enabled=&amp;quot;false&amp;quot; \
		last-lrm-refresh=&amp;quot;1336919205&amp;quot; \
		no-quorum-policy=&amp;quot;ignore&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you accidentally put some wrong configurations and don&amp;#8217;t know how to edit it, you can use &lt;code&gt;crm configure edit&lt;/code&gt; to change your configurations directly but this method is highly not recommended since it&amp;#8217;s error-prone.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;It&amp;#8217;s time to configure our main/failover/cluster IP (our client will use this IP, not the nodes IP):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;crm
configure
primitive ip ocf:heartbeat:IPaddr params ip=&amp;quot;192.168.1.100&amp;quot; op monitor interval=10s
commit&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;If everyting goes well, you should be able to ping the cluster IP (&lt;code&gt;192.168.1.100&lt;/code&gt;) and &lt;code&gt;crm status&lt;/code&gt; should yield this result:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;============
Last updated: Sun May 13 14:28:19 2012
Stack: openais
Current DC: node1 - partition with quorum
Version: 1.1.1-b9b672590e79770afb63b9b455400d92fb6b5d9e
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ node1 node2 ]

ip     (ocf::heartbeat:IPaddr):        Started node1&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;We&amp;#8217;ll now setup MySQL monitoring with &lt;code&gt;Pacemaker&lt;/code&gt;. But before that, make sure you:&lt;/p&gt;

&lt;p&gt;Installed MySQL in both of the nodes.&lt;/p&gt;

&lt;p&gt;Able to connect to your MySQL from other than &lt;code&gt;localhost&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;	mysql -u root -p -h 192.168.1.101
	mysql -u root -p -h 192.168.1.102&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can use this command to allow any host to connect to your MySQL:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;	GRANT ALL PRIVILEGES ON *.* TO &amp;#39;root&amp;#39;@&amp;#39;%&amp;#39; IDENTIFIED BY &amp;#39;password&amp;#39; WITH GRANT OPTION;
	FLUSH PRIVILEGES;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Created a database in &lt;code&gt;Node 1&lt;/code&gt; and &lt;code&gt;Node 2&lt;/code&gt;. For an example, a databased named &lt;code&gt;node1&lt;/code&gt; in &lt;code&gt;Node 1&lt;/code&gt; and &lt;code&gt;node2&lt;/code&gt; in &lt;code&gt;Node 2&lt;/code&gt;. This is just for verification.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Add this resource:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;crm
configure
primitive mysql ocf:heartbeat:mysql \
params binary=&amp;quot;/usr/bin/mysqld_safe&amp;quot; config=&amp;quot;/etc/my.cnf&amp;quot; user=&amp;quot;mysql&amp;quot; pid=&amp;quot;/var/run/mysql/mysql.pid&amp;quot; datadir=&amp;quot;/var/lib/mysql&amp;quot; socket=&amp;quot;/var/run/mysql/mysql.sock&amp;quot; \
op monitor interval=&amp;quot;30s&amp;quot; timeout=&amp;quot;30s&amp;quot; \
op start interval=&amp;quot;0&amp;quot; timeout=&amp;quot;120&amp;quot; \
op stop interval=&amp;quot;0&amp;quot; timeout=&amp;quot;120&amp;quot;
commit
quit&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The parameter above is purely based on the standard Slackware&amp;#8217;s MySQL package. So make sure you&amp;#8217;ve created &lt;code&gt;/etc/my.cnf&lt;/code&gt; which is not available by default. Just copy from the default file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cp /etc/my-small.cnf /etc/my.cnf&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Your latest &lt;code&gt;crm status&lt;/code&gt; would show something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;============
Last updated: Mon May 14 01:13:23 2012
Stack: openais
Current DC: node1 - partition with quorum
Version: 1.1.1-b9b672590e79770afb63b9b455400d92fb6b5d9e
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ node1 node2 ]

 ip	(ocf::heartbeat:IPaddr):	Started node1
 mysql	(ocf::heartbeat:mysql):	Started node2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, &lt;code&gt;mysql&lt;/code&gt; has been started on &lt;code&gt;Node 2&lt;/code&gt;. Actually it doesn&amp;#8217;t matter in which node it will start first (for this tutorial, not for the production server), what important is that if one of the nodes is down, the other node should start its MySQL automatically. You can test this situation by running these commands in your &lt;code&gt;Node 2&lt;/code&gt; to simulate a node failure:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;crm
node
standby
quit&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;crm status&lt;/code&gt; would show something like this (give &lt;code&gt;Node 1&lt;/code&gt; some time before it starts its MySQL):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;============
Last updated: Mon May 14 01:21:12 2012
Stack: openais
Current DC: node1 - partition with quorum
Version: 1.1.1-b9b672590e79770afb63b9b455400d92fb6b5d9e
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Node node2: standby
Online: [ node1 ]

 ip	(ocf::heartbeat:IPaddr):	Started node1
 mysql	(ocf::heartbeat:mysql):	Started node1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Right now, your client can use the cluster IP (&lt;code&gt;192.168.1.100&lt;/code&gt;) to connect to your MySQL. The client won&amp;#8217;t realize which node it connected to. In this case, he/she will connect to &lt;code&gt;Node 2&lt;/code&gt; if both of them (the nodes) are online. If &lt;code&gt;Node 2&lt;/code&gt; is offline, &lt;code&gt;192.168.1.100&lt;/code&gt; will automatically connect the client to MySQL in &lt;code&gt;192.168.1.101&lt;/code&gt;. If &lt;code&gt;Node 1&lt;/code&gt; is offline, &lt;code&gt;192.168.1.100&lt;/code&gt; will automatically uses MySQL in &lt;code&gt;Node 2&lt;/code&gt; which is in &lt;code&gt;192.168.1.102&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To reonline &lt;code&gt;Node 2&lt;/code&gt;, just use these commands in your &lt;code&gt;Node 2&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;crm
node
online
quit&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;However, usually you want to control which MySQL will be up first, either in &lt;code&gt;Node 1&lt;/code&gt; or in &lt;code&gt;Node 2&lt;/code&gt;. To make this happen, you need to use &lt;code&gt;colocation&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;crm
configure
colocation ip-mysql inf: ip mysql
commit
quit&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;crm status&lt;/code&gt; would show something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;============
Last updated: Mon May 14 01:26:41 2012
Stack: openais
Current DC: node1 - partition with quorum
Version: 1.1.1-b9b672590e79770afb63b9b455400d92fb6b5d9e
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ node1 node2 ]

 ip	(ocf::heartbeat:IPaddr):	Started node1
 mysql	(ocf::heartbeat:mysql):	Started node1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That means, your &lt;code&gt;mysql&lt;/code&gt; has been started on &lt;code&gt;Node 1&lt;/code&gt;. So, everytime &lt;code&gt;corosync&lt;/code&gt; is started on both of the nodes, &lt;code&gt;mysql&lt;/code&gt; will be started on &lt;code&gt;Node 1&lt;/code&gt; due to the &lt;code&gt;colocation&lt;/code&gt; configuration.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Try turning off &lt;code&gt;Node 1&lt;/code&gt; or &lt;code&gt;Node 2&lt;/code&gt; and see how MySQL switches side from both of the nodes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think that&amp;#8217;s it, next tutorial should be mainly about DRBD. Good luck!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using GRUB instead of LILO in Slackware</title>
   <link href="http://ieatbinary.com/2012/05/11/using-grub-instead-of-lilo-in-slackware/" />
   <updated>2012-05-11T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2012/05/11/using-grub-instead-of-lilo-in-slackware</id>
   <content type="html">&lt;h1 id='using_grub_instead_of_lilo_in_slackware'&gt;Using GRUB instead of LILO in Slackware&lt;/h1&gt;

&lt;p&gt;These are the steps I used to replace LILO with GRUB as the boot manager after &lt;a href='/2012/05/11/upgrading-to-kernel-v3-for-slackware-v13.37/'&gt;upgrading my kernel to v3&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download directly and install:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;wget http://slackware.osuosl.org/slackware-13.37/extra/grub/grub-0.97-i486-9.txz
installpkg grub-0.97-i486-9.txz&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then jump to Step 3 and make sure you&amp;#8217;ll skip Step 4.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;If you haven&amp;#8217;t set any mirror for your &lt;code&gt;slackpkg&lt;/code&gt;, you need to edit your mirror list:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;vim /etc/slackpkg/mirrors&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add a mirror, for an example, I use the one from Oregon State University:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://slackware.osuosl.org/slackware-13.37/&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Do not forget the trailing &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Run the update:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;slackpkg update&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Remove LILO&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;removepkg lilo&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Install GRUB&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;slackpkg install grub&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Run configuration editor for GRUB (just like &lt;code&gt;liloconfig&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;grubconfig&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is my working config from &lt;code&gt;/boot/grub/menu.lst&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# GRUB configuration file &amp;#39;/boot/grub/menu.lst&amp;#39;.
# generated by &amp;#39;grubconfig&amp;#39;.  Fri May 11 02:21:11 2012
#
# The backup copy of the MBR for drive &amp;#39;/dev/sda&amp;#39; is
# here &amp;#39;/boot/grub/mbr.sda.1594&amp;#39;.  You can restore it like this.
# dd if=mbr.sda.1594 of=/dev/sda bs=512 count=1
#
# Start GRUB global section
#timeout 30
#color light-gray/blue black/light-gray
# End GRUB global section
# Linux bootable partition config begins
  title slackware on (/dev/sda1)
  root (hd0,0)
  kernel /boot/vmlinuz root=/dev/sda1 ro vga=normal 
  initrd /boot/initrd-3.2.13-smp
# Linux bootable partition config ends
title --- For help press &amp;#39;c&amp;#39;, type: &amp;#39;help&amp;#39;
root (hd0)
title --- For usage examples, type: &amp;#39;cat /boot/grub/grub.txt&amp;#39;
root (hd0)&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That&amp;#8217;s it :)&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://gnu-linux-slackware.blogspot.com/2009/07/booting-slackware-with-grub-gnu-grand.html'&gt;Booting Slackware with GRUB (GNU Grand Unified Bootloader)&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.linuxquestions.org/questions/slackware-14/how-do-i-modify-grub-to-boot-using-the-generic-kernel-863073/'&gt;How do I modify GRUB to boot using the generic kernel?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Upgrading to Kernel v3 for Slackware v13.37</title>
   <link href="http://ieatbinary.com/2012/05/11/upgrading-to-kernel-v3-for-slackware-v13.37/" />
   <updated>2012-05-11T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2012/05/11/upgrading-to-kernel-v3-for-slackware-v13.37</id>
   <content type="html">&lt;h1 id='upgrading_to_kernel_v3_for_slackware_v1337'&gt;Upgrading to Kernel v3 for Slackware v13.37&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Get all the necessary packages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;wget http://slackware.osuosl.org/slackware-current/slackware/a/kernel-generic-smp-3.2.13_smp-i686-1.txz
wget http://slackware.osuosl.org/slackware-current/slackware/a/kernel-modules-smp-3.2.13_smp-i686-1.txz
wget http://slackware.osuosl.org/slackware-current/slackware/a/lilo-23.2-i486-1.txz&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Change your run level:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;telinit 1&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Install the kernel&amp;#8217;s package:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;installpkg kernel-generic-smp-3.2.13_smp-i686-1.txz
kernel-modules-smp-3.2.13_smp-i686-1.txz&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Create initial ramdisk images for preloading modules:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /boot
mkinitrd -c -k 3.2.2-smp -m ext4 -f ext4 -r /dev/sda1 -o initrd-3.2.2-smp&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Edit your &lt;code&gt;lilo.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Linux bootable partition config begins 
image = /boot/vmlinuz-generic-smp-3.2.2-smp 
initrd = /boot/initrd-3.2.2-smp 
  root = /dev/sda1 
  label = slackware 
  read-only # Partitions should be mounted read-only for checking 
# Linux bootable partition config ends&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Reload &lt;code&gt;lilo&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;lilo -v&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&amp;#8217;ll get:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Fatal: Setup length exceeds 31 maximum; kernel setup will overwrite boot loader&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#8220;It&amp;#8217;s because the kernel has grown so large. You can fix it by installing a fixed lilo from slackware-current, too&amp;#8221; - from &lt;a href='http://www.linuxquestions.org/questions/slackware-14/using-slackware-3-2-kernel-package-from-current-on-13-37-a-927856/'&gt;LQ&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;upgradepkg /root/lilo-23.2-i486-1.txz
lilo -v&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Reboot.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Check your new kernel information:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;uname -a&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should get something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Linux slackware 3.2.13-smp #1 SMP Fri Mar 23 23:21:11 CDT 2012 i686 Intel(R) Core(TM)2 Duo CPU     P8800  @ 2.66GHz GenuineIntel GNU/Linux&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;That&amp;#8217;s it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Redmine with Git and Subversion in HUSM</title>
   <link href="http://ieatbinary.com/2012/04/11/redmine-with-git-and-subversion-in-husm/" />
   <updated>2012-04-11T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2012/04/11/redmine-with-git-and-subversion-in-husm</id>
   <content type="html">&lt;h1 id='redmine_with_git_and_subversion_in_husm'&gt;Redmine with Git and Subversion in HUSM&lt;/h1&gt;

&lt;p&gt;It&amp;#8217;s official, almost every piece of our codes in Hospital Universiti Sains Malaysia (HUSM) has been versioned in either Git or Subversion (mostly the latter). We&amp;#8217;ve also linked all of the repositories into Redmine for easier project management. It&amp;#8217;s not really a walk in the park for us since this is the first time we tried to do it this big.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re hoping we can document our workloads using issues feature in Redmine. Maybe we&amp;#8217;re a few years late (most of our projects are already matured where no big features added every week), but IMHO this is the perfect time since we&amp;#8217;re in the process of upgrading our core application in the hospital which is Lifeline.&lt;/p&gt;

&lt;p&gt;So, here are some fun facts about our Redmine + (Git/Subversion):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;We&amp;#8217;re using the latest Redmine v1.3.2 (through its Git&amp;#8217;s distribution).&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;It&amp;#8217;s being served through Apache on our Slackware v13.37 box.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The Ruby and the gems are being managed with RVM for easier installation.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;It&amp;#8217;s using an old desktop PC model Acer M460 (2.4 GHz).&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;With advance Git and Subversion integrations, the repositories authentication are using the usernames and passwords from the Redmine itself.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Our Git repositories are being served using Smart HTTP Git protocol.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;There are about 56 repositories in it which comprises different type of code languages such as Java, C++, Ruby, HTML, JavaScript, CSS and Pascal.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;For backups, we&amp;#8217;re using RAID 1 for the hardisks. &lt;code&gt;rsync&lt;/code&gt; and &lt;code&gt;mysqldump&lt;/code&gt; are being ran three times a day. There&amp;#8217;s no offsite backup yet.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;There&amp;#8217;re about 40++ projects in the Redmine right now (still increasing).&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The repositories are hosting codes from different programming languages such as Pascal, Java, C++, Ruby and PHP. So, we need to be extra careful about the &lt;code&gt;.gitigore&lt;/code&gt; and &lt;code&gt;svn:ignore&lt;/code&gt; configurations.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Tutorials has been written for newcomers on how to use version control for Netbeans, Delphi and also Qt Creator. For the time being, everyone is encourage to use their IDE to do all the commits and not doing it through command line unless they know what they are doing.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Most developers chose Subversion due to its low lurning curve.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the next few days (or weeks), I&amp;#8217;m going to post the configuration that I used to make the intergration between Git/Subversion with Redmine. It seems that the wiki from Redmine itself is not complete enough and I had to dig deeper into other websites. So, hopefully it will help anyone who&amp;#8217;s lost just like me before.&lt;/p&gt;

&lt;p&gt;By the way, you can view a screenshot from the Redmine&amp;#8217;s projects page &lt;a href='https://twitter.com/#!/aurorius/status/187829585759580160'&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>See Full Referrer URL in Google Analytics</title>
   <link href="http://ieatbinary.com/2012/01/21/see-full-referrer-url-in-google-analytics/" />
   <updated>2012-01-21T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2012/01/21/see-full-referrer-url-in-google-analytics</id>
   <content type="html">&lt;h1 id='see_full_referrer_url_in_google_analytics'&gt;See Full Referrer URL in Google Analytics&lt;/h1&gt;

&lt;p&gt;Most of the tutorial on the web focuses on the old version of Google Analytics. So, after poking around Google Analytics, I found out that there are two ways to see it (I stopped looking once I found the second method, so, there might be more).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Go to Custom Reporting tab.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Click Edit.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;If you&amp;#8217;ve already added a tab, just click &amp;#8220;+add report tab&amp;#8221; for this purpose.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Put the name of this report.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Choose Flat Table as the type.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;For the Dimensions, search for Full Referrer.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;For the Metrics, use Unique Visitors (or anything you see fits).&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Click Save.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That&amp;#8217;s it. You can refer to the screenshot below if you&amp;#8217;re feeling lost:&lt;/p&gt;
&lt;img src='/images/posts/2012-01-21-ga.png' width='584' /&gt;
&lt;p&gt;Good luck!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A Not So Simple Introduction to Git</title>
   <link href="http://ieatbinary.com/2012/01/07/a-not-so-simple-introduction-to-git/" />
   <updated>2012-01-07T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2012/01/07/a-not-so-simple-introduction-to-git</id>
   <content type="html">&lt;h1 id='a_not_so_simple_introduction_to_git'&gt;A Not So Simple Introduction to Git&lt;/h1&gt;

&lt;p&gt;Found another presentation from Speaker Deck. I find it useful with its examples. Check it out.&lt;/p&gt;
&lt;script src='http://speakerdeck.com/embed/4ecfc649eee53a005000b88b.js' /&gt;</content>
 </entry>
 
 <entry>
   <title>A Good Introduction to Agile and Scrum</title>
   <link href="http://ieatbinary.com/2012/01/07/a-good-introduction-to-agile-and-scrum/" />
   <updated>2012-01-07T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2012/01/07/a-good-introduction-to-agile-and-scrum</id>
   <content type="html">&lt;h1 id='a_good_introduction_to_agile_and_scrum'&gt;A Good Introduction to Agile and Scrum&lt;/h1&gt;

&lt;p&gt;Found this in Speaker Deck. Love the simple explanation.&lt;/p&gt;
&lt;script src='http://speakerdeck.com/embed/4ea7b7b86428bd0054008cd4.js' /&gt;</content>
 </entry>
 
 <entry>
   <title>Renaming Author in Git</title>
   <link href="http://ieatbinary.com/2012/01/05/renaming-author-in-git/" />
   <updated>2012-01-05T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2012/01/05/renaming-author-in-git</id>
   <content type="html">&lt;h1 id='renaming_author_in_git'&gt;Renaming Author in Git&lt;/h1&gt;

&lt;p&gt;In Linux, I use Netbeans a lot as a diff viewer. For now, I think it&amp;#8217;s the best diff viewer in Linux with side by side comparison and its easy to navigate UI. Plus, it&amp;#8217;s free.&lt;/p&gt;

&lt;p&gt;Recently, I noticed that there are other authors with a different name in my Git&amp;#8217;s history. Apparently, I&amp;#8217;ve accidentally committed into the repository using a different author&amp;#8217;s name and email. This is mainly due to the way Netbeans stores author&amp;#8217;s information history.&lt;/p&gt;
&lt;img src='/images/posts/2011-01-05-diff.png' width='584' /&gt;
&lt;p&gt;So, in order to fix it, I ran this little script from Github in my master branch.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;#!/bin/sh&lt;/span&gt;

git filter-branch --env-filter &lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;

&lt;span class='s1'&gt;an=&amp;quot;$GIT_AUTHOR_NAME&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;am=&amp;quot;$GIT_AUTHOR_EMAIL&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;cn=&amp;quot;$GIT_COMMITTER_NAME&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;cm=&amp;quot;$GIT_COMMITTER_EMAIL&amp;quot;&lt;/span&gt;

&lt;span class='s1'&gt;if [ &amp;quot;$GIT_COMMITTER_EMAIL&amp;quot; = &amp;quot;your@email.to.match&amp;quot; ]&lt;/span&gt;
&lt;span class='s1'&gt;then&lt;/span&gt;
&lt;span class='s1'&gt;    cn=&amp;quot;Your New Committer Name&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;    cm=&amp;quot;Your New Committer Email&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;fi&lt;/span&gt;
&lt;span class='s1'&gt;if [ &amp;quot;$GIT_AUTHOR_EMAIL&amp;quot; = &amp;quot;your@email.to.match&amp;quot; ]&lt;/span&gt;
&lt;span class='s1'&gt;then&lt;/span&gt;
&lt;span class='s1'&gt;    an=&amp;quot;Your New Author Name&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;    am=&amp;quot;Your New Author Email&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;fi&lt;/span&gt;

&lt;span class='s1'&gt;export GIT_AUTHOR_NAME=&amp;quot;$an&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;export GIT_AUTHOR_EMAIL=&amp;quot;$am&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;export GIT_COMMITTER_NAME=&amp;quot;$cn&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;export GIT_COMMITTER_EMAIL=&amp;quot;$cm&amp;quot;&lt;/span&gt;
&lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To push it into the server, I need to use &lt;code&gt;git push -f&lt;/code&gt; instead of &lt;code&gt;git push&lt;/code&gt;. If you use the latter command, you&amp;#8217;ll end up with a merged history (every commit will have another one identical to it).&lt;/p&gt;

&lt;p&gt;If you use Redmine, you may need to fetch change set. Just run this command in your Redmine&amp;#8217;s directory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;script/runner &amp;quot;Repository.fetch_changesets&amp;quot; -e production&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Netbeans committer&amp;#8217;s info are stored in (change the path based on your version):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/.netbeans/7.0/config/Preferences/org/netbeans/modules/git.properties&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='references'&gt;References:&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://theelitist.net/git-change-revision-author'&gt;http://theelitist.net/git-change-revision-author&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://help.github.com/change-author-info/'&gt;http://help.github.com/change-author-info/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Git Remote Commands</title>
   <link href="http://ieatbinary.com/2011/12/11/git-remote-commands/" />
   <updated>2011-12-11T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2011/12/11/git-remote-commands</id>
   <content type="html">&lt;h1 id='git_remote_commands'&gt;Git Remote Commands&lt;/h1&gt;

&lt;p&gt;View some remote &lt;strong&gt;information&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git remote show origin&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;List&lt;/strong&gt; all remote branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git branch -r&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Pushing&lt;/strong&gt; a branch to the remote:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push origin newfeature&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or when you want to &lt;strong&gt;push in the checkout branch&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push origin HEAD&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And use &lt;code&gt;-u&lt;/code&gt; to &lt;strong&gt;push and track&lt;/strong&gt; the remote branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push -u origin newfeature&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make an existing git branch to &lt;strong&gt;track a remote&lt;/strong&gt; branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git branch --set-upstream newfeature1 origin/newfeature1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Deleting&lt;/strong&gt; a remote branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push origin :newfeature&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Refresh&lt;/strong&gt; remote branch list:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git remote prune origin&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Checkout&lt;/strong&gt; a remote branch and &lt;strong&gt;track&lt;/strong&gt; it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout -t origin/newfeature&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>How to Read MyKad</title>
   <link href="http://ieatbinary.com/2011/12/05/how-to-read-mykad/" />
   <updated>2011-12-05T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2011/12/05/how-to-read-mykad</id>
   <content type="html">&lt;h1 id='how_to_read_mykad'&gt;How to Read MyKad&lt;/h1&gt;

&lt;p&gt;I&amp;#8217;ve decided to merge posts about reading MyKad from my previous blog into a single post.&lt;/p&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The &lt;strong&gt;original codes were written by Xenon&lt;/strong&gt; from &lt;a href='http://forum.lowyat.net/'&gt;Lowyat.net&lt;/a&gt;. Somehow, he managed to reverse engineer MyKad&amp;#8217;s APDU so that we can read it without buying any SDK.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;This application &lt;strong&gt;only&lt;/strong&gt; reads data from Jabatan Pendaftaran Negara (JPN).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Xenon also wrote two small example applications to read MyKad. I&amp;#8217;ve listed them based on the programming language. Click on the link to download it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href='https://github.com/amree/mykad-c'&gt;Visual C&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/amree/mykad-vb.net'&gt;Visual Basic .NET&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since there&amp;#8217;s no Java implementation of the code yet, I&amp;#8217;ve decided to develop one. You can also get the source code from my &lt;a href='http://github.com/amree/mykad-java'&gt;Github&lt;/a&gt;. It&amp;#8217;s written using Netbeans.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m not going to give explanation about the code. Instead, I&amp;#8217;m going to guide you guys on how to setup your system (Linux and Windows) so that you can read the Java application to read a MyKad.&lt;/p&gt;

&lt;h1 id='windows'&gt;Windows&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download &lt;a href='http://www.musclecard.com/middle.html'&gt;Windows binary&lt;/a&gt; of JPC/SC Java API.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Download the application which is in Netbeans project format from my Github.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;You &lt;strong&gt;must include&lt;/strong&gt; &lt;code&gt;jpcsc.jar&lt;/code&gt; as the library. You can get the file from Step 1.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;You also &lt;strong&gt;must put&lt;/strong&gt; &lt;code&gt;jpcsc.dll&lt;/code&gt; into your main project folder. Furthermore, if you want to distribute the application, you need to put it together with your main jar file. You can also get the file from Step 1.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Plug in your reader (obviously).&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Run the application. I&amp;#8217;d recommend you run it through Netbeans.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Insert a MyKad.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Wait until the application finish reading it (usually once the LED stop blinking).&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;A GUI will be displayed presenting your MyKad data.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;If there&amp;#8217;s no data showing, there&amp;#8217;s a possibility that your MyKad chip is spoiled.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id='linux'&gt;Linux&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Login as a &lt;strong&gt;root&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Download &lt;a href='http://pcsclite.alioth.debian.org/'&gt;PCSC Lite&lt;/a&gt; and install it. You need to put some parameters in your &lt;code&gt;./configure&lt;/code&gt; if you want to enable &lt;code&gt;libusb&lt;/code&gt; support. Please check the &lt;code&gt;README&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tar xvjf pcsc-lite-1.8.1.tar.bz2
cd pcsc-lite-1.8.1
./configure --enable-libusb --disable-libudev
make
make install&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Download and install your reader&amp;#8217;s driver. I&amp;#8217;m using &lt;a href='http://www.hidglobal.com/prod_detail.php?prod_id=171'&gt;OMNIKEY 5321 USB&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Get &lt;a href='http://www.musclecard.com/middle.html'&gt;Windows binary&lt;/a&gt; of JPC/SC Java API. It&amp;#8217;s for Windows but it also has a precompiled Linux library in it.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Extract, copy and update:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;unzip jpcsc-0.8.0.zip
cd jpcsc/bin/linux
cp libjpcsc.so /usr/lib
ldconfig&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Start the pcsc service:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pcscd -d -f&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should get something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;00000000 pcscdaemon.c:233:main() pcscd set to foreground with debug send to stdout
00000044 configfile.l:287:DBGetReaderList() Parsing conf file: /usr/local/etc/reader.conf.d
00000008 pcscdaemon.c:518:main() pcsc-lite 1.8.1 daemon ready.
00001566 hotplug_libusb.c:514:HPAddHotPluggable() Adding USB device: 4:2:0
00008631 readerfactory.c:934:RFInitializeReader() Attempting startup of OMNIKEY CardMan 5x21 (USB iClass Reader) 00 00 using /usr/local/lib/pcsc/drivers/ifdokrfid_lnx_i
00000179 readerfactory.c:824:RFBindFunctions() Loading IFD Handler 3.0 HID HID Global OMNIKEY RFID  IA32 v2.9.1
00300863 readerfactory.c:296:RFAddReader() Using the reader polling thread
00001975 readerfactory.c:934:RFInitializeReader() Attempting startup of OMNIKEY CardMan 5x21 (USB iClass Reader) 00 01 using /usr/local/lib/pcsc/drivers/ifdokrfid_lnx_i
00000012 readerfactory.c:738:RFLoadReader() Reusing already loaded driver for /usr/local/lib/pcsc/drivers/ifdokrfid_lnx_i686-2.9.1.bundle/Contents/Linux/ifdokrfid.so
00000014 readerfactory.c:824:RFBindFunctions() Loading IFD Handler 3.0 HID HID Global OMNIKEY RFID  IA32 v2.9.1
00424985 readerfactory.c:453:RFAddReader() Using the reader polling thread
00444313 readerfactory.c:1301:RFWaitForReaderInit() Waiting init for reader: OMNIKEY CardMan 5x21 (USB iClass Reader) 00 01&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Run the Java application, it should be working right now.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That&amp;#8217;s it, again, the full credit should goes to Xenon :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>HUSM at Malaysia Open Source Conference 2011</title>
   <link href="http://ieatbinary.com/2011/07/12/husm-at-malaysia-open-source-conference-2011/" />
   <updated>2011-07-12T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2011/07/12/husm-at-malaysia-open-source-conference-2011</id>
   <content type="html">&lt;h1 id='husm_at_malaysia_open_source_conference_2011'&gt;HUSM at Malaysia Open Source Conference 2011&lt;/h1&gt;

&lt;p&gt;On the 5th of July 2011, Hospital Universiti Sains Malaysia (HUSM) has been chosen as one of the speakers in Malaysia Open Source Conference 2011. It was presented by &lt;a href='http://my.linkedin.com/in/yusdirman'&gt;Mr Yusdirman Bin Yusoff&lt;/a&gt; as “Open Source in Health Care: HUSM 10 Years of Innovation”.&lt;/p&gt;

&lt;p&gt;Basically it’s about &lt;strong&gt;what&lt;/strong&gt; and &lt;strong&gt;how&lt;/strong&gt; HUSM as one among few hospitals in Malaysia managed to develop its own Total Hospital Information System thus saved millions ringgit of taxpayers money. This is actually the first step for us (IT Unit, HUSM) to show to the world what we have done in this 10 years where most hospitals not willing to do.&lt;/p&gt;
&lt;script src='http://speakerdeck.com/embed/4efe89ef1b765f004c0015ea.js' /&gt;</content>
 </entry>
 
 <entry>
   <title>How to enable MySQL Support in Qt SDK for Windows</title>
   <link href="http://ieatbinary.com/2011/07/11/how-to-enable-mysql-support-in-qt-sdk-for-windows/" />
   <updated>2011-07-11T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2011/07/11/how-to-enable-mysql-support-in-qt-sdk-for-windows</id>
   <content type="html">&lt;h1 id='how_to_enable_mysql_support_in_qt_sdk_for_windows'&gt;How to enable MySQL Support in Qt SDK for Windows&lt;/h1&gt;

&lt;p&gt;It has been quite a while since I wrote the previous guide. Since that particular post gained a lot of visitors, I decided to write a new guide based on the new Qt SDK and MySQL so that it will help people with new version for both softwares.&lt;/p&gt;

&lt;p&gt;Download Qt SDK and install it. In my case, I installed it at &lt;code&gt;C:\QtSDK&lt;/code&gt;. You must make sure that you’ve chosen to install Qt Sources. If you have Qt SDK installed but you haven’t install Qt sources, just go to &lt;strong&gt;Start &amp;gt; All Programs &amp;gt; Qt SDK &amp;gt; Maintain Qt SDK&lt;/strong&gt; to install it.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/posts/2011-07-11-qt.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;Download MySQL and install it. In my case, I choose to install it at:&lt;/p&gt;

&lt;p&gt;C:\Program Files (x86)\MySQL\MySQL Server 5.5.&lt;/p&gt;

&lt;p&gt;You don’t need to install everything if you want to compile the plugin. Make sure you will at least choose to &lt;strong&gt;install Client C API Library&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/posts/2011-07-11-mysql.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;Open &lt;strong&gt;Start &amp;gt; All Programs &amp;gt; Qt SDK &amp;gt; Desktop &amp;gt; Qt 4.7.3 for Desktop (MingW)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run these commands (change according to your environment):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bat'&gt;&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;set&lt;/span&gt; mysql&lt;span class='o'&gt;=&lt;/span&gt;C:\PROGRA~&lt;span class='m'&gt;2&lt;/span&gt;\MySQL\MYSQLS~&lt;span class='m'&gt;1&lt;/span&gt;.&lt;span class='m'&gt;5&lt;/span&gt;
&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;cd&lt;/span&gt; \
&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;cd&lt;/span&gt; QtSDK\QtSources\&lt;span class='m'&gt;4&lt;/span&gt;.&lt;span class='m'&gt;7&lt;/span&gt;.&lt;span class='m'&gt;3&lt;/span&gt;\src\plugins\sqldrivers\mysql\

&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;qmake&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;INCLUDEPATH+=%mysql%\include&amp;quot;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;LIBS+=%mysql%\lib\libmysql.lib&amp;quot;&lt;/span&gt; -o Makefile mysql.pro
&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;mingw32&lt;/span&gt;-make

&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;qmake&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;INCLUDEPATH+=%mysql%\include&amp;quot;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;LIBS+=%mysql%\lib\libmysql.lib&amp;quot;&lt;/span&gt; -o Makefile mysql.pro &lt;span class='s2'&gt;&amp;quot;CONFIG+=release&amp;quot;&lt;/span&gt;
&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;mingw32&lt;/span&gt;-make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You should be able to run these commands &lt;strong&gt;without any error&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You’ll find two directories (&lt;strong&gt;debug&lt;/strong&gt; and &lt;strong&gt;release&lt;/strong&gt;) created in the current directory.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;debug&lt;/strong&gt; directory, you’ll find &lt;code&gt;libqsqlmysqld4.a&lt;/code&gt; and &lt;code&gt;qsqlmysqld4.dll&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Meanwhile, in &lt;strong&gt;release&lt;/strong&gt; directory, you’ll find &lt;code&gt;libqsqlmysql4.a&lt;/code&gt; and &lt;code&gt;qsqlmysql4.dll&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy all these 4 files into&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\QtSDK\Desktop\Qt\4.7.3\mingw\plugins\sqldrivers&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Copy &lt;code&gt;libmysql.dll&lt;/code&gt; (found in your MySQL installation directory) into C:\Windows.&lt;/p&gt;

&lt;p&gt;Create new project and put these codes to test your new plugin&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='cpp'&gt;&lt;span class='cp'&gt;#include &amp;lt;QApplication&amp;gt;&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;QtSql&amp;gt;&lt;/span&gt;

&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;main&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;argc&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;char&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;argv&lt;/span&gt;&lt;span class='p'&gt;[])&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='n'&gt;QCoreApplication&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;argc&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;argv&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='n'&gt;qDebug&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;QSqlDatabase&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='n'&gt;drivers&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;exec&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Make sure you have QtSql Module in your project configuration file (.pro file)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;QT += sql&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You’ll get these outputs showing that your Qt has supports for MySQL:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(&amp;quot;QSQLITE&amp;quot;, &amp;quot;QMYSQL3&amp;quot;, &amp;quot;QMYSQL&amp;quot;, &amp;quot;QODBC3&amp;quot;, &amp;quot;QODBC&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Things to watch out for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You can’t use MySQL 64 Bit (at the moment)&lt;/strong&gt; to compile the plugin.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Make sure you’ll &lt;strong&gt;use short path&lt;/strong&gt; type if you’ve installed MySQL into directory’s name containing spaces.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Load sql module&lt;/strong&gt; in your .pro file.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tested on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;11/7/2011 – Windows 64 Bit, MySQL Server 5.5.1 32 Bit (Community Version) and Qt 4.7.3.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;I’m currently dedicating most of my time developing Rails application. So, I strongly encourage you guys to get help at &lt;a href='http://developer.qt.nokia.com/'&gt;Qt Developer Network&lt;/a&gt; if you have any problem. Those guys are very helpful.&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A Simple Working Example for Qt NCReport</title>
   <link href="http://ieatbinary.com/2011/07/09/a-simple-working-example-for-qt-ncreport/" />
   <updated>2011-07-09T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2011/07/09/a-simple-working-example-for-qt-ncreport</id>
   <content type="html">&lt;h1 id='a_simple_working_example_for_qt_ncreport'&gt;A Simple Working Example for Qt NCReport&lt;/h1&gt;

&lt;h2 id='windows'&gt;Windows&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download NCReport with MingW for Windows.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Install NCReport at&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\NCReport\2.6.1.mingw.eval&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Get the full &lt;a href='https://github.com/amree/ncreport-example'&gt;source code&lt;/a&gt; of the project at my Github.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Go to Projects (bar at the left) &amp;gt; Run Settings &amp;gt; Click Details on the Run Environment &amp;gt; Edit PATH’s variable and append the following line at the end of the string.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;;C:\NCReport\2.6.1.mingw.eval\bin&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Run the project in &lt;strong&gt;Debug&lt;/strong&gt; and &lt;strong&gt;Release&lt;/strong&gt; mode. You should be able to run the report by clicking the button.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tested on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows 7 (64 bit), NCReport 2.6.1 with MingW for Windows, QtSDK 1.1.2, Qt 4.7.3 and Qt Creator 2.2.1.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='linux'&gt;Linux&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download NCReport for Linux.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Install NCReport at &lt;code&gt;/opt/ncreport&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Get the full &lt;a href='https://github.com/amree/ncreport-example'&gt;source code&lt;/a&gt; of the project at my Github.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Run the project in &lt;strong&gt;Debug&lt;/strong&gt; and &lt;strong&gt;Release&lt;/strong&gt; mode. You should be able to run the report by clicking the button.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tested on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slackware 13.37 (32 Bit), NCReport 2.6.1 for Linux, QtSDK 1.1.2, Qt 4.7.3 and Qt Creator 2.2.1&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Using Sybase with Ruby on Rails on Linux</title>
   <link href="http://ieatbinary.com/2011/07/01/using-sybase-with-ruby-on-rails-on-linux/" />
   <updated>2011-07-01T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2011/07/01/using-sybase-with-ruby-on-rails-on-linux</id>
   <content type="html">&lt;h1 id='using_sybase_with_ruby_on_rails_on_linux'&gt;Using Sybase with Ruby on Rails on Linux&lt;/h1&gt;

&lt;pre&gt;&lt;code&gt;Updated: 22 May 2012&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This guide will help you (mostly will help me in the future) to configure your Ruby on Rails to support connection to Sybase. I wrote this tutorial after everything’s good, so, I might miss a few steps that I’ve forgotten. Feel free to comment about it. With some adjustments, this guide &lt;strong&gt;will also works with Mac OS X&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install FreeTDS. For Slackware users, you can get Slackbuild script at &lt;a href='http://slackbuilds.org/repository/13.37/development/freetds/'&gt;http://slackbuilds.org/repository/13.37/development/freetds/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Edit &lt;code&gt;/etc/freetds/freetds.conf&lt;/code&gt; and put your database configurations in it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[myserver]
	host = myserver.com
	port = 5000
	tds version = 5.0&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Test the configuration, you should get something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ tsql -S myserver -U username

locale is &amp;quot;C&amp;quot;
locale charset is &amp;quot;ANSI_X3.4-1968&amp;quot;
using default charset &amp;quot;ISO-8859-1&amp;quot;
Msg 5704 (severity 10, state 1) from ???:
	&amp;quot;Changed client character set setting to &amp;#39;iso_1&amp;#39;.
&amp;quot;
1&amp;gt; &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Put this gems in your &lt;code&gt;Gemfile&lt;/code&gt; and run &lt;code&gt;bundle&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &amp;#39;arel-sybase-visitor&amp;#39;, :git =&amp;gt; &amp;#39;https://github.com/ifad/arel-sybase-visitor&amp;#39;
gem &amp;#39;activerecord-sybase-adapter&amp;#39;, :git =&amp;gt; &amp;quot;https://github.com/ifad/activerecord-sybase-adapter&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;An example configuration for your &lt;code&gt;database.yml&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;development:
  adapter: sybase
  dataserver: myserver
  username: 
  password: 
  database: &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;You can try some query using your &lt;code&gt;rails console&lt;/code&gt; to make sure everything works fine.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;If you&amp;#8217;re trying to connect from your &lt;code&gt;irb&lt;/code&gt; directly without using ActiveRecord you may want to put additional parameters. This works for me:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;client = TinyTds::Client.new(
			:username =&amp;gt; &amp;#39;&amp;#39;, 
			:password =&amp;gt; &amp;#39;&amp;#39;, 
			:dataserver =&amp;gt; &amp;#39;myserver&amp;#39;,  
			:tds_version =&amp;gt; &amp;#39;100&amp;#39;, 
			:encoding =&amp;gt; &amp;#39;iso_1&amp;#39;) &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Running Multiple MySQL on a Single Server</title>
   <link href="http://ieatbinary.com/2011/03/15/running-multiple-mysql-on-a-single-server/" />
   <updated>2011-03-15T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2011/03/15/running-multiple-mysql-on-a-single-server</id>
   <content type="html">&lt;h1 id='running_multiple_mysql_on_a_single_server'&gt;Running Multiple MySQL on a Single Server&lt;/h1&gt;

&lt;p&gt;I’m pretty sure I’m going to forget these steps, so, just to be safe, I’m putting it here.&lt;/p&gt;

&lt;p&gt;I’m dividing this tutorial into two sections, one for default MySQL that comes from Slackware and the other one is for new MySQL.&lt;/p&gt;

&lt;h2 id='using_the_default_mysql'&gt;Using the Default MySQL&lt;/h2&gt;

&lt;p&gt;We need to create separate (different from the default) directory for the data to be stored. I’m going to create a new one for it. I’m going to name the directory as &lt;code&gt;mysql-1&lt;/code&gt;. Make sure you use full path when running &lt;code&gt;mysql_install_db&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd /var/lib
$ mkdir mysql-1
$ chown -R mysql.mysql mysql-1
$ mysql_install_db --datadir=/var/lib/mysql-1 --user=mysql&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We also need a new configuration file so that it won’t clash with the default MySQL.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cp /etc/my-small.cnf /etc/my-1.cnf
$ nano /etc/my-1.cnf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These are the settings that I’ve changed from the default file (other settings remain unchanged).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[client]
port = 3307
socket = /var/run/mysql/mysql-1.sock

[mysqld]
port = 3307
socket = /var/run/mysql/mysql-1.sock
server-id = 10

innodb_data_home_dir = /var/lib/mysql-1/
innodb_log_group_home_dir = /var/lib/mysql-1/&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To run our newly configured MySQL instance, use this command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ /usr/bin/mysqld_safe --defaults-file=/etc/my-1.cnf --datadir=/var/lib/mysql-1 &amp;amp;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By checking background process, you should see something like this&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ps ax | grep mysql

23416 pts/1    S      0:00 /bin/sh /usr/bin/mysqld_safe --defaults-file=/etc/my-1.cnf --datadir=/var/lib/mysql-1
23515 pts/1    Sl     0:00 /usr/libexec/mysqld --defaults-file=/etc/my-1.cnf --basedir=/usr --datadir=/var/lib/mysql-1 --user=mysql --log-error=/var/lib/mysql-1/eebox.err --pid-file=/var/lib/mysql-1/eebox.pid --socket=/var/run/mysql/mysql-1.sock --port=3307&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Time for some test, we need to make sure we’re connecting to the correct server. One way to do this is by checking the &lt;code&gt;server_id&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mysql -u root -h 127.0.0.1 -P 3307
mysql&amp;gt; SHOW VARIABLES LIKE &amp;quot;server_id&amp;quot;;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 10    |
+---------------+-------+
1 row in set (0.00 sec)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, we have the same server_id as we specified in our my-1.cnf. You can use this command to shut it down.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mysqladmin -h 127.0.0.1 -P 3307 shutdown&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='using_new_downloaded_mysql'&gt;Using new Downloaded MySQL&lt;/h2&gt;

&lt;p&gt;Download &lt;a href='http://dev.mysql.com/downloads/'&gt;MySQL Download&lt;/a&gt; &amp;gt; MySQL Community Server &amp;gt; Linux Generic &amp;gt; Linux – Generic 2.6 (x86, 32-bit), Compressed TAR Archive&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cp mysql-5.5.9-linux2.6-i686.tar.gz /opt
$ cd opt
$ tar zxvf mysql-5.5.9-linux2.6-i686.tar.gz
$ mv mysql-5.5.9-linux2.6-i686 mysql
$ cd mysql
$ chown -R mysql.mysql .
$ ./scripts/mysql_install_db --user=mysql
$ cp support-files/my-small.cnf /etc/my-2.cnf
$ nano /etc/my-2.cnf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;/etc/my-2.cnf&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[client]
port = 3308
socket = /var/run/mysql/mysql-2.sock

[mysqld]
port = 3308
socket = /var/run/mysql/mysql-2.sock
server-id = 20

innodb_data_home_dir = /var/lib/mysql-1/
innodb_log_group_home_dir = /var/lib/mysql-1/&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To run it, you need to specify some parameters&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/opt/mysql/bin/mysqld --defaults-file=/etc/my-2.cnf --basedir=/opt/mysql --datadir=/opt/mysql/data --plugin-dir=/opt/mysql/lib/plugin --user=mysql --log-error=/opt/mysql/data/eebox.err&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To shut it down, you can use the following command&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./bin/mysqladmin -h 127.0.0.1 -P 3308 shutdown&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can test the server connection just like the method I used above.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s it, good luck!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Adding memcached support to PHP in Slackware 13.1</title>
   <link href="http://ieatbinary.com/2010/10/09/adding-memcached-support-to-php-in-slackware-13-1/" />
   <updated>2010-10-09T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2010/10/09/adding-memcached-support-to-php-in-slackware-13-1</id>
   <content type="html">&lt;h1 id='adding_memcached_support_to_php_in_slackware_131'&gt;Adding memcached support to PHP in Slackware 13.1&lt;/h1&gt;

&lt;p&gt;I just started learning Zend Framework and in one of the tutorials I read, I need to enable memcached in my PHP which is not available by default.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;a href='http://slackbuilds.org/repository/13.1/libraries/libevent/'&gt;libevent&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Install &lt;a href='http://slackbuilds.org/repository/13.1/network/memcached/'&gt;memcached&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Install &lt;a href='http://slackbuilds.org/repository/13.1/libraries/libmemcached/'&gt;libmemcached&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Install memcache.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;wget http://pecl.php.net/get/memcache-2.2.6.tgz
tar -zxvf memcache-2.2.6.tgz
cd memcache-2.2.6
phpize &amp;amp;&amp;amp; ./configure --enable-memcache &amp;amp;&amp;amp; make
cp modules/memcache.so /usr/lib/php/extensions/&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Load the module using .ini files in /etc/php&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;touch /etc/php/memcached.ini
echo &amp;#39;extension=memcache.so&amp;#39; &amp;gt; /etc/php/memcached.ini&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Run memcached as a daemon (d = daemon, m = memory, u = user, l = IP to listen to, p = port).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;memcached -d -m 1024 -u root -l 127.0.0.1 -p 11211&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Put this file in your web directory and run it. It should be rendered without any error.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='php'&gt;&lt;span class='cp'&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class='nv'&gt;$memcache&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Memcache&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nv'&gt;$memcache&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;11211&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;or&lt;/span&gt; &lt;span class='k'&gt;die&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Could not connect&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='nv'&gt;$version&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$memcache&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;getVersion&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='k'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Server&amp;#39;s version: &amp;quot;&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;$version&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='nv'&gt;$tmp_object&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='k'&gt;stdClass&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nv'&gt;$tmp_object&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;str_attr&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nv'&gt;$tmp_object&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;int_attr&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;123&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='nv'&gt;$memcache&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;set&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;key&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nv'&gt;$tmp_object&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;false&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;10&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;or&lt;/span&gt; &lt;span class='k'&gt;die&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Failed to save data at the server&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='k'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Store data in the cache (data will expire in 10 seconds)&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='nv'&gt;$get_result&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$memcache&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;key&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='k'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Data from the cache:&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='nb'&gt;var_dump&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$get_result&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='cp'&gt;?&amp;gt;&lt;/span&gt;&lt;span class='x' /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://my2.php.net/manual/en/memcache.installation.php'&gt;http://my2.php.net/manual/en/memcache.installation.php&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://stackoverflow.com/questions/1442411/using-memcache-vs-memcached-with-php'&gt;http://stackoverflow.com/questions/1442411/using-memcache-vs-memcached-with-php&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Configuring Linux to work with NVidia Hybrid SLI Technology</title>
   <link href="http://ieatbinary.com/2010/02/21/configuring-linux-to-work-with-nvidia-hybrid-sli-technology/" />
   <updated>2010-02-21T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2010/02/21/configuring-linux-to-work-with-nvidia-hybrid-sli-technology</id>
   <content type="html">&lt;h1 id='configuring_linux_to_work_with_nvidia_hybrid_sli_technology'&gt;Configuring Linux to work with NVidia Hybrid SLI Technology&lt;/h1&gt;

&lt;p&gt;First of all, at the time of this writing, NVIDIA Hybrid SLI Technology is &lt;a href='http://www.nvnews.net/vbulletin/showpost.php?p=1613349&amp;amp;postcount=2'&gt;not supported&lt;/a&gt; on Linux and without proper configuration, you won’t even be able to load your Desktop Environment such as Xfce.&lt;/p&gt;

&lt;p&gt;That’s not the only problem, based on an &lt;a href='http://www.nvnews.net/articles/hybrid_sli_interview/index.shtml'&gt;interview&lt;/a&gt; with NVIDIA’s Tom Petersen, one of its main feature is called HybridPower which basically allows users to shut off the graphics card when not needed and dramatically reduce power consumption. This means, there is a possibility that if we can’t find a way to turn off the second GPU, it will consume more power that it should be.&lt;/p&gt;

&lt;p&gt;But that’s another problem. Right now, we just want to boot into our Desktop Environment properly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Running &lt;code&gt;startx&lt;/code&gt; would show these error messages from &lt;code&gt;/var/log/Xorg.0.log&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(!!) More than one possible primary device found
(--) PCI: (0:2:0:0) 10de:06e8:1028:0271 rev 161, Mem @ 0xae000000/16777216, 0xd0000000/268435456, 0xac000000/33554432, I/O @ 0x00004000/128
(--) PCI: (0:3:0:0) 10de:0866:1028:0271 rev 177, Mem @ 0xaa000000/16777216, 0xb0000000/268435456, 0xcc000000/33554432, I/O @ 0x00005000/128, BIOS @ 0x????????/131072&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Generate the default configuration for your X (using root):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nvidia-xconfig&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Get the list of the GPUs.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ lspci
02:00.0 VGA compatible controller: nVidia Corporation G98 [GeForce 9200M GS] (rev a1)
03:00.0 VGA compatible controller: nVidia Corporation C79 [GeForce 9400M G] (rev b1)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will get a long list of devices connected to your PCI buses. We are only interested with the VGA controller.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;As you can see, we have two VGA controller, we just need to specify which one we would like to use.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nano /etc/X11/xorg.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Go to your Device section and set Bus ID for your controller in it. So, in the end, if I chose the second controller, my &lt;code&gt;Xorg.conf&lt;/code&gt; would somehow look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Section &amp;quot;Device&amp;quot;
    Identifier     &amp;quot;Device0&amp;quot;
    Driver         &amp;quot;nvidia&amp;quot;
    VendorName     &amp;quot;NVIDIA Corporation&amp;quot;
    BoardName      &amp;quot;GeForce 9400M G&amp;quot;
    BusID          &amp;quot;PCI:3:0:0&amp;quot;
EndSection&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The configuration is simple, you just need to &lt;strong&gt;add the 6th line&lt;/strong&gt;. Just make sure you put it in the correct format &lt;code&gt;PCI:X:X:X&lt;/code&gt;, X possibly refers to the last 3 digit number in your error log.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>How to Enable MySQL Support in Qt SDK for Linux</title>
   <link href="http://ieatbinary.com/2009/07/22/how-to-enable-mysql-support-in-qt-sdk-for-linux/" />
   <updated>2009-07-22T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2009/07/22/how-to-enable-mysql-support-in-qt-sdk-for-linux</id>
   <content type="html">&lt;h1 id='how_to_enable_mysql_support_in_qt_sdk_for_linux'&gt;How to Enable MySQL Support in Qt SDK for Linux&lt;/h1&gt;

&lt;pre&gt;&lt;code&gt;Updated: 8 May 2012&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Known to work with:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slackware v13.37, Qt SDK v1.1.5 (32 bit), Qt v4.8.0, MySQL v5.5.18&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please follow this guide properly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download Qt SDK for Linux/X11 at Qt Software.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Install it anywhere you want, just make sure you remember the path. I installed mine at &lt;code&gt;/opt&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;To build MySQL as a plugin, you need to know two other paths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MySQL header directory&amp;#8217;s files example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;decimal.h   m_string.h      my_dbug.h    my_list.h        my_sys.h     mysql_embed.h    mysqld_error.h  sql_state.h        typelib.h
errmsg.h    my_alloc.h      my_dir.h     my_net.h         my_xml.h     mysql_time.h     raid.h          sslopt-case.h
keycache.h  my_attribute.h  my_getopt.h  my_no_pthread.h  mysql.h      mysql_version.h  readline.h      sslopt-longopts.h
m_ctype.h   my_config.h     my_global.h  my_pthread.h     mysql_com.h  mysqld_ername.h  sql_common.h    sslopt-vars.h&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;MySQL library directory&amp;#8217;s files example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;libdbug.a    libmyisammrg.a      libmysqlclient.so@         libmysqlclient_r.a    libmysqlclient_r.so.15@      libmysys.a
libheap.a    libmysqlclient.a    libmysqlclient.so.15@      libmysqlclient_r.la*  libmysqlclient_r.so.15.0.0*  libvio.a
libmyisam.a  libmysqlclient.la*  libmysqlclient.so.15.0.0*  libmysqlclient_r.so@  libmystrings.a&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;I installed my MySQL at &lt;code&gt;/opt&lt;/code&gt;, so those files will be in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Headers directory
/opt/mysql-5.5.18-linux2.6-i686/include/  

# Libraries directory
/opt/mysql-5.5.18-linux2.6-i686/lib      &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Go to your main Qt SDK installation&amp;#8217;s path:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /opt/QtSDK/
cd QtSources/4.8.0/src/plugins/sqldrivers
# Replace all the path based on your computer environment. 
/opt/QtSDK/Desktop/Qt/4.8.0/gcc/bin/qmake -o Makefile &amp;quot;INCLUDEPATH+=/opt/mysql-5.5.18-linux2.6-i686/include/&amp;quot; &amp;quot;LIBS+=-L/opt/mysql-5.5.18-linux2.6-i686/lib -lmysqlclient&amp;quot; mysql.pro
make
/opt/QtSDK/Desktop/Qt/4.8.0/gcc/bin/qmake &amp;quot;INCLUDEPATH+=/opt/mysql-5.5.18-linux2.6-i686/include/&amp;quot; &amp;quot;LIBS+=-L/opt/mysql-5.5.18-linux2.6-i686/lib -lmysqlclient_r&amp;quot; mysql.pro
make
make install&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Some files with &lt;code&gt;mysql&lt;/code&gt; in the name will be copied in your sqldrivers path:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/opt/QtSDK/Desktop/Qt/4.8.0/gcc/plugins/sqldrivers&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Before trying your MySQL coding, please make sure &lt;code&gt;libmysqlclient.so&lt;/code&gt; is in the&lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Create a new project and put these codes to test your new plugin.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;QT       += core sql
QT       -= gui

TARGET    = mysql
CONFIG   += console
CONFIG   -= app_bundle
	
TEMPLATE = app

SOURCES += main.cpp&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make sure you have &lt;code&gt;mysql&lt;/code&gt; included in your &lt;code&gt;.pro&lt;/code&gt; file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;QCoreApplication&amp;gt;
#include &amp;lt;QtSql&amp;gt;
	
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() &amp;lt;&amp;lt; QSqlDatabase::drivers();

    return a.exec();
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should get &lt;code&gt;QMYSQL&lt;/code&gt; in the outputs when you ran the application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(&amp;quot;QSQLITE&amp;quot;, &amp;quot;QMYSQL3&amp;quot;, &amp;quot;QMYSQL&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can find my info at &lt;a href='http://qt-project.org/doc/qt-4.8/sql-driver.html'&gt;http://qt-project.org/doc/qt-4.8/sql-driver.html&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Reading Mifare 1K Card using Java in Linux</title>
   <link href="http://ieatbinary.com/2009/02/11/reading-mifare-1k-card-using-java-in-linux/" />
   <updated>2009-02-11T00:00:00-08:00</updated>
   <id>http://ieatbinary.com/2009/02/11/reading-mifare-1k-card-using-java-in-linux</id>
   <content type="html">&lt;h1 id='reading_mifare_1k_card_using_java_in_linux'&gt;Reading Mifare 1K Card using Java in Linux&lt;/h1&gt;

&lt;h2 id='the_story'&gt;The Story&lt;/h2&gt;

&lt;p&gt;In the end of last year, my friends and I were tasked to read our staff card. The main objective was pretty simple which is to create a library where we don’t have to depend on the vendor every time we want to read our own staff card and the library should also work in Linux and Windows (that means Java to us).&lt;/p&gt;

&lt;p&gt;Working environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slackware 12.2&lt;/li&gt;

&lt;li&gt;JDK 6 Update 11&lt;/li&gt;

&lt;li&gt;Netbeans 6.5&lt;/li&gt;

&lt;li&gt;libusb 0.1.12&lt;/li&gt;

&lt;li&gt;Windows Binary of JPC/SC Java API 0.8.0&lt;/li&gt;

&lt;li&gt;Smartcard Reader&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s talk about the reader first. You need to get a reader that supports Mifare 1K card (obviously) which to be exact a reader that supports ISO14443A/B or ISO15693 (contactless standard). Now, to make your life easier, you should get a reader that can read contactless standards compliant using the same framework as ISO7816 compliant contact cards. In simple terms, you can use APDU to get the data that you want.&lt;/p&gt;

&lt;p&gt;So, for this little project, we use &lt;strong&gt;OMNIKEY CardMan 5321&lt;/strong&gt; RFID reader. It has everything that we need, Linux/Windows supports, APDU calls to the contactless card, it even comes a contact card’s reader too and it’s also inexpensive.&lt;/p&gt;

&lt;p&gt;Make sure you choose the correct reader or you won’t be able to use this tutorial. Some reader requires you to read using their own specific code, which means you can only use the code you wrote on that particular reader, unlike readers that support APDU calls to contactless cards.&lt;/p&gt;

&lt;h2 id='the_card'&gt;The Card&lt;/h2&gt;

&lt;p&gt;1024 byte memory is organised as sixteen sectors, each of which is made up of four blocks and each block is 16 bytes long. The first block in the memory (Block 0) is read-only and is set in the factory to contain the four-byte serial number (UID), check bytes and manufacturers data. The last block of each sector (Blocks 3, 7, 11, 15 … 59, 63) is the Sector Trailer Block which contains the &lt;strong&gt;two security Key codes (KeyA and KeyB&lt;/strong&gt;) and the Access bits that define how the sector can be accessed.&lt;/p&gt;

&lt;p&gt;Taking into account the Serial Number/Manufacturers Block and the Sector Trailer Blocks then there are 752 bytes of free memory for user storage. For all Read and Write operations the Mifare card memory is addressed by Block number (in hexadecimal format).&lt;/p&gt;

&lt;h2 id='the_installation'&gt;The Installation&lt;/h2&gt;

&lt;p&gt;Before you begin coding your codes, you need to make sure your environment is ready for you. To do that, just follow steps from my previous tutorial which is pretty much the same.&lt;/p&gt;

&lt;h2 id='general_steps_to_read_the_card'&gt;General Steps to Read the Card&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Load Mifare key&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Authenticate&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Read&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id='the_code'&gt;The Code&lt;/h2&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kn'&gt;package&lt;/span&gt; &lt;span class='n'&gt;my&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;husm&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;mifare&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.nio.ByteBuffer&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.util.List&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.smartcardio.Card&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.smartcardio.CardChannel&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.smartcardio.CardException&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.smartcardio.CardTerminal&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.smartcardio.TerminalFactory&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Read&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

   &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='nf'&gt;Read&lt;/span&gt;&lt;span class='o'&gt;()&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
       
       &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

           &lt;span class='n'&gt;CardTerminal&lt;/span&gt; &lt;span class='n'&gt;terminal&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

           &lt;span class='c1'&gt;// show the list of available terminals&lt;/span&gt;
           &lt;span class='n'&gt;TerminalFactory&lt;/span&gt; &lt;span class='n'&gt;factory&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;TerminalFactory&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getDefault&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
           &lt;span class='n'&gt;List&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;CardTerminal&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;terminals&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;factory&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;terminals&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;list&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;

           &lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;readerName&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

           &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;terminals&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;size&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;++)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

               &lt;span class='n'&gt;readerName&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;terminals&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;get&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='na'&gt;toString&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;substring&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;
                                   &lt;span class='n'&gt;terminals&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;get&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='na'&gt;toString&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;length&lt;/span&gt;&lt;span class='o'&gt;()&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;

               &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;readerName&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;equalsIgnoreCase&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;01&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;))&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
                   &lt;span class='n'&gt;terminal&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;terminals&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;get&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
               &lt;span class='o'&gt;}&lt;/span&gt;
           &lt;span class='o'&gt;}&lt;/span&gt;

           &lt;span class='c1'&gt;// Establish a connection with the card&lt;/span&gt;
           &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Waiting for a card..&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='n'&gt;terminal&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;waitForCardPresent&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;

           &lt;span class='n'&gt;Card&lt;/span&gt; &lt;span class='n'&gt;card&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;terminal&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;connect&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;T=0&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='n'&gt;CardChannel&lt;/span&gt; &lt;span class='n'&gt;channel&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;card&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getBasicChannel&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;

           &lt;span class='c1'&gt;// Start with something simple, read UID, kinda like Hello World!&lt;/span&gt;
           &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;baReadUID&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;];&lt;/span&gt;

           &lt;span class='n'&gt;baReadUID&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]{(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xCA&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x00&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
                                  &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x00&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x00&lt;/span&gt;&lt;span class='o'&gt;};&lt;/span&gt;

           &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;UID: &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;baReadUID&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;channel&lt;/span&gt;&lt;span class='o'&gt;));&lt;/span&gt;
           &lt;span class='c1'&gt;// If successfull, the output will end with 9000&lt;/span&gt;

           &lt;span class='c1'&gt;// OK, now, the real work&lt;/span&gt;
           &lt;span class='c1'&gt;// Get Serial Number&lt;/span&gt;
           &lt;span class='c1'&gt;// Load key&lt;/span&gt;
           &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;baLoadKey&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;12&lt;/span&gt;&lt;span class='o'&gt;];&lt;/span&gt;

           &lt;span class='n'&gt;baLoadKey&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]{(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x82&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x20&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
                                     &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x1A&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x06&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
                                     &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
                                     &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;};&lt;/span&gt;

           &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;LOAD KEY: &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;baLoadKey&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;channel&lt;/span&gt;&lt;span class='o'&gt;));&lt;/span&gt;
           &lt;span class='c1'&gt;// If successfull, will output 9000&lt;/span&gt;

           &lt;span class='c1'&gt;// Authenticate&lt;/span&gt;
           &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;baAuth&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;];&lt;/span&gt;

           &lt;span class='n'&gt;baAuth&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]{(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x88&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x00&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
                               &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x09&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x60&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x00&lt;/span&gt;&lt;span class='o'&gt;};&lt;/span&gt;

           &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;AUTHENTICATE: &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;baAuth&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;channel&lt;/span&gt;&lt;span class='o'&gt;));&lt;/span&gt;
           &lt;span class='c1'&gt;// If successfull, will output 9000&lt;/span&gt;

           &lt;span class='c1'&gt;// Read Serial&lt;/span&gt;
           &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;baRead&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;];&lt;/span&gt;

           &lt;span class='n'&gt;baRead&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]{(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xFF&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0xB0&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x00&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
                               &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x09&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mh'&gt;0x10&lt;/span&gt;&lt;span class='o'&gt;};&lt;/span&gt;

           &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;READ: &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;baRead&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;channel&lt;/span&gt;&lt;span class='o'&gt;));&lt;/span&gt;
           &lt;span class='c1'&gt;// If successfull, the output will end with 9000&lt;/span&gt;

       &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
           &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
       &lt;span class='o'&gt;}&lt;/span&gt;
   &lt;span class='o'&gt;}&lt;/span&gt;

   &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='nf'&gt;send&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;cmd&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;CardChannel&lt;/span&gt; &lt;span class='n'&gt;channel&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

       &lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;res&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

       &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;baResp&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;258&lt;/span&gt;&lt;span class='o'&gt;];&lt;/span&gt;
       &lt;span class='n'&gt;ByteBuffer&lt;/span&gt; &lt;span class='n'&gt;bufCmd&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ByteBuffer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;wrap&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;cmd&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
       &lt;span class='n'&gt;ByteBuffer&lt;/span&gt; &lt;span class='n'&gt;bufResp&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ByteBuffer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;wrap&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;baResp&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;

       &lt;span class='c1'&gt;// output = The length of the received response APDU&lt;/span&gt;
       &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;output&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

       &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

           &lt;span class='n'&gt;output&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;channel&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;transmit&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;bufCmd&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;bufResp&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;

       &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;CardException&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
           &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
       &lt;span class='o'&gt;}&lt;/span&gt;

       &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;output&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;++)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
           &lt;span class='n'&gt;res&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;format&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;%02X&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;baResp&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;]);&lt;/span&gt;
           &lt;span class='c1'&gt;// The result is formatted as a hexadecimal integer&lt;/span&gt;
       &lt;span class='o'&gt;}&lt;/span&gt;

       &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;res&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
   &lt;span class='o'&gt;}&lt;/span&gt;

   &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;static&lt;/span&gt; &lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
       &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nf'&gt;Read&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
   &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Make sure you have set the right connection protocol at line 43, as pointed out by Animesh (previous commentator).&lt;/p&gt;

&lt;p&gt;These codes use Java API to read the smartcard, but I suggest you use the jpcsc library. It’s much more robust when it comes to error handling.&lt;/p&gt;

&lt;h2 id='the_apdu_commands'&gt;The APDU Commands&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;# Load Key
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
|   FF   |   82   |   20   |   1A   |   06   |   FF   |   FF   |   FF   |   FF   |   FF   |   FF   |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
|   1    |   2    |   3    |   4    |   5    |   6    |   7    |   8    |   9    |   10   |   11   |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+

1   = CLA : (Fixed)
2   = INS : (Fixed)
3   = P1  : (Fixed)
4   = P2  : Key type, could be 00, 1A, 1B
5   = LC  : Key length, usually 6 for 6 byte
6   = XX  : ----+
7   = XX  :     |
8   = XX  :     |__ The Key (eg. FF FF FF FF FF FF)
9   = XX  :     |
10  = XX  :     |
11  = XX  : ----+

# Autenthicate
+--------+--------+--------+--------+--------+--------+
|   FF   |   88   |   00   |   01   |   60   |   00   |
+--------+--------+--------+--------+--------+--------+
|   1    |   2    |   3    |   4    |   5    |   6    |
+--------+--------+--------+--------+--------+--------+

1   = CLA : (Fixed)
2   = INS : (Fixed)
3   = P1  : (Fixed)
4   = P2  : Block Number you want to authenticate in Hex
5   = P3  : Mifare Block Number LSB
6   = XX  : Key type, could be 00, 1A, 1B

# Read
+--------+--------+--------+--------+--------+
|   FF   |   B0   |   00   |   01   |   10   |
+--------+--------+--------+--------+--------+
|   1    |   2    |   3    |   4    |   5    |
+--------+--------+--------+--------+--------+

1   = CLA : (Fixed)
2   = INS : (Fixed)
3   = P1  : (Fixed)
4   = P2  : Block Number that you want to read in Hex
5   = Le  : (Fixed)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, that’s it, good luck!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Printing to PDF using CUPS</title>
   <link href="http://ieatbinary.com/2008/09/10/printing-to-pdf-using-cups/" />
   <updated>2008-09-10T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2008/09/10/printing-to-pdf-using-cups</id>
   <content type="html">&lt;h1 id='printing_to_pdf_using_cups'&gt;Printing to PDF using CUPS&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install CUPS-PDF&lt;/strong&gt; based on your distro, you can download if from &lt;a href='http://www.physik.uni-wuerzburg.de/~vrbehr/cups-pdf/download.shtml'&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Go to &lt;a href='http://localhost:631'&gt;http://localhost:631&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;If the page requested a username and password, just enter your root as username and password for your root.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Go to &lt;strong&gt;Administration &amp;gt; Add Printer&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;Add Printer&lt;/strong&gt; page, &lt;strong&gt;put a name&lt;/strong&gt; for your virtual PDF printe, any name will do. Then click &lt;strong&gt;Continue&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;For the &lt;strong&gt;Device for a&lt;/strong&gt;, you should &lt;strong&gt;select CUPS-PDF&lt;/strong&gt; (Virtual PDF Driver). If it’s not there, then you haven’t executed &lt;strong&gt;Step 1&lt;/strong&gt; successfully.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;In the 3rd page, choose &lt;strong&gt;Generic as the Make&lt;/strong&gt; and then click &lt;strong&gt;Continue&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;In the 4th page, &lt;strong&gt;choose Generic CUPS-PDF Printer (en)&lt;/strong&gt; as the model and then click &lt;strong&gt;Add Printer&lt;/strong&gt;. For now, you’re done, but we need to customize where the file will be generated when you printed it.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Edit &lt;code&gt;/etc/cups/cups-pdf.conf&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Put these lines at the end of the file and save it (both can be customized):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Out /home/${USER}/Desktop
Label 1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first line actually tell CUPS to print your file to the Desktop and the second line will make sure your file won’t be overwritten by a newer one.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Restart CUPS&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, that’s all and good luck !&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Java Printing Fix for Linux</title>
   <link href="http://ieatbinary.com/2008/09/09/java-printing-fix-for-linux-with-cups/" />
   <updated>2008-09-09T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2008/09/09/java-printing-fix-for-linux-with-cups</id>
   <content type="html">&lt;h1 id='java_printing_fix_for_linux'&gt;Java Printing Fix for Linux&lt;/h1&gt;

&lt;p&gt;Apparently, there&amp;#8217;s a bug in Java where people using newer version of CUPS cannot print (can&amp;#8217;t even display the print dialog) due to a null pointer exception and this is actually a known bug. So, how do we fix this? For people who use Gnome, you can refer to this &lt;a href='https://bugs.launchpad.net/ubuntu/+source/sun-java6/+bug/156191/comments/18'&gt;page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, for people who uses non desktop environment such as Fluxbox, Openbox and etc (Gnome and KDE user can use these steps too), you can fix it by editing your CUPS printers configuration file. You can get edit the file at &lt;code&gt;/etc/cups/printers.conf&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;DefaultPrinter Printer&amp;gt;
# Printer configuration file for CUPS v1.3.7
# Written by cupsd on 2008-09-08 11:24
.
.
.
Option orientation-requested 3
&amp;lt;/Printer&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make sure you &lt;code&gt;Option orientation-requested 3&lt;/code&gt; to every configuration for every printer you&amp;#8217;ve installed. If you cannot find the file, it&amp;#8217;s possible that you haven&amp;#8217;t configured any printer yet.&lt;/p&gt;

&lt;p&gt;This fix is simply to make sure CUPS will provide a page orientation setting to Java.&lt;/p&gt;

&lt;p&gt;The exception:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Caused by: java.lang.NullPointerException: null attribute
        at sun.print.IPPPrintService.isAttributeValueSupported(IPPPrintService.java:1147)
        at sun.print.ServiceDialog$OrientationPanel.updateInfo(ServiceDialog.java:2121)
        at sun.print.ServiceDialog$PageSetupPanel.updateInfo(ServiceDialog.java:1263)
        at sun.print.ServiceDialog.updatePanels(ServiceDialog.java:437)
        at sun.print.ServiceDialog.initPrintDialog(ServiceDialog.java:195)
        at sun.print.ServiceDialog.(ServiceDialog.java:124)
        at javax.print.ServiceUI.printDialog(ServiceUI.java:188)
        at sun.print.RasterPrinterJob.printDialog(RasterPrinterJob.java:855)
        at sun.print.PSPrinterJob.printDialog(PSPrinterJob.java:421)&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please refer to some of the discussions here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://bugs.launchpad.net/ubuntu/+source/sun-java6/+bug/156191/'&gt;Ubuntu Bugs Report&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6633656'&gt;Java Bugs Report&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FYI, you need to &lt;strong&gt;restart your CUPS&lt;/strong&gt; after editing the configuration (Thanks to Brandon Bell).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Auto Resize JTable Column Width</title>
   <link href="http://ieatbinary.com/2008/08/13/auto-resize-jtable-column-width/" />
   <updated>2008-08-13T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2008/08/13/auto-resize-jtable-column-width</id>
   <content type="html">&lt;h1 id='auto_resize_jtable_column_width'&gt;Auto Resize JTable Column Width&lt;/h1&gt;

&lt;p&gt;This code should resize your JTable column width based on the contents of the header and data.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='n'&gt;JTable&lt;/span&gt; &lt;span class='nf'&gt;autoResizeColWidth&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;JTable&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;DefaultTableModel&lt;/span&gt; &lt;span class='n'&gt;model&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;setAutoResizeMode&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;JTable&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;AUTO_RESIZE_OFF&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;setModel&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;model&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;

    &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;margin&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getColumnCount&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;++)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
        &lt;span class='kt'&gt;int&lt;/span&gt;                     &lt;span class='n'&gt;vColIndex&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
        &lt;span class='n'&gt;DefaultTableColumnModel&lt;/span&gt; &lt;span class='n'&gt;colModel&lt;/span&gt;  &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;DefaultTableColumnModel&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getColumnModel&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
        &lt;span class='n'&gt;TableColumn&lt;/span&gt;             &lt;span class='n'&gt;col&lt;/span&gt;       &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;colModel&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getColumn&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;vColIndex&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
        &lt;span class='kt'&gt;int&lt;/span&gt;                     &lt;span class='n'&gt;width&lt;/span&gt;     &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

        &lt;span class='c1'&gt;// Get width of column header&lt;/span&gt;
        &lt;span class='n'&gt;TableCellRenderer&lt;/span&gt; &lt;span class='n'&gt;renderer&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;col&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getHeaderRenderer&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;

        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;renderer&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;renderer&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getTableHeader&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;getDefaultRenderer&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
        &lt;span class='o'&gt;}&lt;/span&gt;

        &lt;span class='n'&gt;Component&lt;/span&gt; &lt;span class='n'&gt;comp&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;renderer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getTableCellRendererComponent&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;col&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getHeaderValue&lt;/span&gt;&lt;span class='o'&gt;(),&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;

        &lt;span class='n'&gt;width&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;comp&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getPreferredSize&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;width&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

        &lt;span class='c1'&gt;// Get maximum width of column data&lt;/span&gt;
        &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;r&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;r&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getRowCount&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt; &lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;++)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;renderer&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getCellRenderer&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;vColIndex&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
            &lt;span class='n'&gt;comp&lt;/span&gt;     &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;renderer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getTableCellRendererComponent&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getValueAt&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;vColIndex&lt;/span&gt;&lt;span class='o'&gt;),&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
                    &lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;vColIndex&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
            &lt;span class='n'&gt;width&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;Math&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;max&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;width&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;comp&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getPreferredSize&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;width&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
        &lt;span class='o'&gt;}&lt;/span&gt;

        &lt;span class='c1'&gt;// Add margin&lt;/span&gt;
        &lt;span class='n'&gt;width&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;margin&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

        &lt;span class='c1'&gt;// Set the width&lt;/span&gt;
        &lt;span class='n'&gt;col&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;setPreferredWidth&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;width&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
    &lt;span class='o'&gt;}&lt;/span&gt;

    &lt;span class='o'&gt;((&lt;/span&gt;&lt;span class='n'&gt;DefaultTableCellRenderer&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getTableHeader&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;getDefaultRenderer&lt;/span&gt;&lt;span class='o'&gt;()).&lt;/span&gt;&lt;span class='na'&gt;setHorizontalAlignment&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;
        &lt;span class='n'&gt;SwingConstants&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;LEFT&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;

    &lt;span class='c1'&gt;// table.setAutoCreateRowSorter(true);&lt;/span&gt;
    &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getTableHeader&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;setReorderingAllowed&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;

    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;table&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='c1'&gt;// Must pass the model&lt;/span&gt;
&lt;span class='n'&gt;DefaultTableModel&lt;/span&gt; &lt;span class='n'&gt;model&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;DefaultTableModel&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
&lt;span class='n'&gt;jTable&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;autoResizeColWidth&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;jTable&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;model&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Printing to Zebra S4M Using Java and ZPL II</title>
   <link href="http://ieatbinary.com/2008/05/11/printing-to-zebra-s4m-using-java-and-zpl-ii/" />
   <updated>2008-05-11T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2008/05/11/printing-to-zebra-s4m-using-java-and-zpl-ii</id>
   <content type="html">&lt;h1 id='printing_to_zebra_s4m_using_java_and_zpl_ii'&gt;Printing to Zebra S4M Using Java and ZPL II&lt;/h1&gt;

&lt;p&gt;Apparently there&amp;#8217;re some codes scattered on the net telling people that you can print to a Zebra printer by sending ZPL II codes using &lt;code&gt;PrintService&lt;/code&gt;. But the problem is, it&amp;#8217;s not working, I don&amp;#8217;t know why, maybe because of a different version of printer or model but I&amp;#8217;m pretty sure the thing that came out from the printer are just ordinary texts not barcode which is what the code was supposed to output.&lt;/p&gt;

&lt;h2 id='new_version'&gt;New Version&lt;/h2&gt;

&lt;p&gt;Thanks to Oleg (a commentator) for pointing out on how to print using Zebra S4M connected either via USB or network.&lt;/p&gt;

&lt;p&gt;The solution is pretty simple, all you have to do is do not install Zebra S4M as a Zebra S4M (sounds weird, I know), instead, just install it as a local raw printer (Linux) or generic text printer (Windows).&lt;/p&gt;

&lt;p&gt;For CUPS user in Linux, this is the example for the correct configurations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;/etc/cups/printers.conf&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Printer Zebra&amp;gt;
  Info
  Location
  DeviceURI socket://10.1.1.5:9100
  State Idle
  StateTime 1223445299
  Accepting Yes
  Shared Yes
  JobSheets none none
  QuotaPeriod 0
  PageLimit 0
  KLimit 0
  OpPolicy default
  ErrorPolicy stop-printer
  Option orientation-requested 3
&amp;lt;/Printer&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can always add the printer using the web interface, just make sure you choose RAW as the Make/Manufacturer and Model/Driver.&lt;/p&gt;

&lt;p&gt;Test this Java code, it should print out a barcode:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.Doc&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.DocFlavor&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.DocPrintJob&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.PrintException&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.PrintService&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.PrintServiceLookup&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.SimpleDoc&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.attribute.PrintServiceAttribute&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;javax.print.attribute.standard.PrinterName&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;SimplePrint&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

   &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;static&lt;/span&gt; &lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
       
       &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
           
           &lt;span class='n'&gt;PrintService&lt;/span&gt; &lt;span class='n'&gt;psZebra&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
           &lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;sPrinterName&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
           &lt;span class='n'&gt;PrintService&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;services&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;PrintServiceLookup&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;lookupPrintServices&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           
           &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;services&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;length&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;++)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
               
               &lt;span class='n'&gt;PrintServiceAttribute&lt;/span&gt; &lt;span class='n'&gt;attr&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;services&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='na'&gt;getAttribute&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;PrinterName&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;class&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
               &lt;span class='n'&gt;sPrinterName&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;((&lt;/span&gt;&lt;span class='n'&gt;PrinterName&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;attr&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='na'&gt;getValue&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
               
               &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;sPrinterName&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;toLowerCase&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;indexOf&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;zebra&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
                   &lt;span class='n'&gt;psZebra&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;services&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;];&lt;/span&gt;
                   &lt;span class='k'&gt;break&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
               &lt;span class='o'&gt;}&lt;/span&gt;
           &lt;span class='o'&gt;}&lt;/span&gt;
           
           &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;psZebra&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
               &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Zebra printer is not found.&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
               &lt;span class='k'&gt;return&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
           &lt;span class='o'&gt;}&lt;/span&gt;
           &lt;span class='n'&gt;DocPrintJob&lt;/span&gt; &lt;span class='n'&gt;job&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;psZebra&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;createPrintJob&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;

           &lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;s&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;^XA^FO100,40^BY3^B3,,30^FD123ABC^XZ&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

           &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;by&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getBytes&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
           &lt;span class='n'&gt;DocFlavor&lt;/span&gt; &lt;span class='n'&gt;flavor&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;DocFlavor&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;BYTE_ARRAY&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;AUTOSENSE&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
           &lt;span class='n'&gt;Doc&lt;/span&gt; &lt;span class='n'&gt;doc&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;SimpleDoc&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;by&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;flavor&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='n'&gt;job&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;print&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;doc&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           
       &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;PrintException&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
           &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
       &lt;span class='o'&gt;}&lt;/span&gt;      
   &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Print using FTP:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.io.FileInputStream&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;org.apache.commons.net.ftp.FTP&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;org.apache.commons.net.ftp.FTPClient&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;FtpPrint&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

   &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;static&lt;/span&gt; &lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

       &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

           &lt;span class='n'&gt;FTPClient&lt;/span&gt; &lt;span class='n'&gt;f&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;FTPClient&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;            

           &lt;span class='n'&gt;f&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;connect&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;10.1.127.3&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='n'&gt;f&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;login&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;anonymous&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='n'&gt;f&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;setFileType&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;FTP&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;ASCII_FILE_TYPE&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;                            

           &lt;span class='n'&gt;FileInputStream&lt;/span&gt; &lt;span class='n'&gt;in&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;FileInputStream&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;/path/to/file&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;f&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;storeFile&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;filename&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;in&lt;/span&gt;&lt;span class='o'&gt;))&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
               &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Upload ok&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='o'&gt;}&lt;/span&gt;                

           &lt;span class='n'&gt;f&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;logout&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
           &lt;span class='n'&gt;f&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;disconnect&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;

       &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
           &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
       &lt;span class='o'&gt;}&lt;/span&gt;
   &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Print using socket:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.io.DataOutputStream&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.net.Socket&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;SocketPrint&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

   &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;static&lt;/span&gt; &lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;argv&lt;/span&gt;&lt;span class='o'&gt;[])&lt;/span&gt; &lt;span class='kd'&gt;throws&lt;/span&gt; &lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;

       &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;lt&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='mi'&gt;10&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;++)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
           &lt;span class='n'&gt;Socket&lt;/span&gt; &lt;span class='n'&gt;clientSocket&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;Socket&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;10.1.127.3&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;9100&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='n'&gt;DataOutputStream&lt;/span&gt; &lt;span class='n'&gt;outToServer&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;DataOutputStream&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;clientSocket&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getOutputStream&lt;/span&gt;&lt;span class='o'&gt;());&lt;/span&gt;
           &lt;span class='n'&gt;outToServer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;writeBytes&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;^XA^FO100,40^BY3^B3,,30^FD123ABC^XZ&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
           &lt;span class='n'&gt;clientSocket&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;close&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
       &lt;span class='o'&gt;}&lt;/span&gt;
   &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(got it from &lt;a href='https://support.zebra.com'&gt;Zebra&amp;#8217;s website&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.zebra.com/id/zebra/na/en/index/products/printers/industrial_commercial/s4m.4.tabs.html'&gt;Download guide to ZPL II&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Automatically Sign JARs Using Ant and Bash</title>
   <link href="http://ieatbinary.com/2008/04/14/automatically-sign-jars-using-ant-and-bash/" />
   <updated>2008-04-14T00:00:00-07:00</updated>
   <id>http://ieatbinary.com/2008/04/14/automatically-sign-jars-using-ant-and-bash</id>
   <content type="html">&lt;h1 id='automatically_sign_jars_using_ant_and_bash'&gt;Automatically Sign JARs Using Ant and Bash&lt;/h1&gt;

&lt;p&gt;This guide is more towards Netbeans project, but it can be used as a reference for you to customize the script to suit your needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;signer.bash&lt;/strong&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;#!/bin/bash&lt;/span&gt;
find . -name &lt;span class='s2'&gt;&amp;quot;*.jar&amp;quot;&lt;/span&gt; -exec jarsigner -keystore /path/to/your/key -storepass yourpassword &lt;span class='s1'&gt;&amp;#39;{}&amp;#39;&lt;/span&gt; yourkeystorename &lt;span class='se'&gt;\;&lt;/span&gt;
&lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;JARs signed&amp;#39;&lt;/span&gt;;
&lt;span class='nb'&gt;exit &lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This script &lt;strong&gt;will search all files ending with .jar&lt;/strong&gt; from the current directory recursively and &lt;strong&gt;then sign it&lt;/strong&gt;. This means, it can be used separately without ant script. Just make it executable and run it.&lt;/p&gt;

&lt;p&gt;Put this in the last line of your &lt;code&gt;build.xml&lt;/code&gt; but it must before the closing tag of the &amp;#8220;project&amp;#8221; (&lt;code&gt;build.xml&lt;/code&gt; can be found in your main project directory)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;build.xml&lt;/strong&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;project&amp;gt;&lt;/span&gt;
    .
    .
    .
    &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;-post-jar&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;exec&lt;/span&gt; &lt;span class='na'&gt;dir=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${dist.dir}&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;executable=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;/path/to/your/signer.bash&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;os=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Linux&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This script will basically sign the jars after all the jars has been build. Please note that it&amp;#8217;d better if you set all the path using absolute path.&lt;/p&gt;

&lt;p&gt;After this, you just have to use &lt;strong&gt;Clean and Build&lt;/strong&gt; to generate the jars and also automatically sign it. This script will also sign all of your included libraries.&lt;/p&gt;

&lt;p&gt;Good luck :)&lt;/p&gt;</content>
 </entry>
 

</feed>
