tag:blogger.com,1999:blog-801512213346849822024-03-05T12:10:48.967-05:00I wonder...cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.comBlogger56125tag:blogger.com,1999:blog-80151221334684982.post-14767100122348736242014-03-11T08:50:00.000-04:002014-03-12T03:59:01.395-04:00Certificate for courier esmtpdTo enable SSL/TLS support for the ESMTP, you need to have a server certificate. Usually, the installation process of the package in a Linux distribution will create a default, self-signed certificate for you. However, if you want to create a proper certificate for your site, following is some simple steps to do so.<br />
<br />
First, you need to generate a key for your server if you don't already have one:
<br />
<blockquote>
<pre><span style="color: #990000;">openssl</span> <span style="color: blue;">genrsa</span> -out <span style="color: #38761d;">server.key</span> 2048</pre>
</blockquote>
With that key, you can then generate a certificate request:
<br />
<blockquote>
<pre><span style="color: #990000;">openssl</span> <span style="color: blue;">req</span> -new -key <span style="color: #38761d;">server.key</span> -out <span style="color: #38761d;">server.csr</span></pre>
</blockquote>
If you did not customize your <span style="color: #38761d;">openssl.cnf</span> configuration file, the above command will prompt you for the details of identify for the server in the certificate. Answer all questions as you please except for the common name "CN", which should be the host name to connect to your server.<br />
<br />
Now, you need to get a Certificate Authority to sign your request. For example, if you have a demoCA setup for your openssl installation, you can do:
<br />
<blockquote>
<pre><span style="color: #990000;">openssl</span> <span style="color: blue;">ca</span> -config <span style="color: #38761d;">openssl.cnf</span> -policy policy_anything -out <span style="color: #38761d;">server.crt</span> -infiles <span style="color: #38761d;">server.csr</span></pre>
</blockquote>
This results in the certificate file <span style="color: #38761d;">server.crt</span>. You then can combine the server key and certificate files to create the certificate file for the courier mail server.
<br />
<blockquote>
<pre><span style="color: #990000;">cat</span> <span style="color: #38761d;">server.key</span> <span style="color: #38761d;">server.crt</span> <span style="color: #990000;">></span> <span style="color: #38761d;">esmtpd.pem</span></pre>
</blockquote>
This used to be sufficient. However, the newer version (0.73) of courier requires a "DH parameters" block in the certificate file. This can be generated and appended with:
<br />
<blockquote>
<pre><span style="color: #990000;">openssl</span> <span style="color: blue;">dhparam</span> 1024 <span style="color: #990000;">>></span> <span style="color: #38761d;">esmtpd.pem</span></pre>
</blockquote>
Now, you can point the "TLS_CERTFILE" in all the configuration files to the certificate <span style="color: #38761d;">esmtpd.pem</span> and restart your server.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-36307434727441090092014-01-07T10:40:00.002-05:002014-03-11T09:01:22.210-04:00Example: data preprocessing with BASH<h3>
Case situation</h3>
<br />
I have run some batch jobs on a cluster to process data files for different systems (msc, ms, sh, rd) and parameters (i and w). The files are in different subdirectories:<br />
<blockquote>
<pre><span style="color: #38761d;">[cjj@gust pattern]$</span> <span style="color: blue;">ls d-*/*.spd</span>
d-msc/i275w042526.spd d-ms/i285w025017.spd d-rd/i295w042812.spd
d-msc/i280w040241.spd d-ms/i290w023034.spd d-sh/i275w051138.spd
d-msc/i285w036791.spd d-ms/i295w020787.spd d-sh/i280w047315.spd
d-msc/i290w031925.spd d-rd/i270w065151.spd d-sh/i285w043415.spd
d-msc/i295w026791.spd d-rd/i275w060475.spd d-sh/i290w039589.spd
d-ms/i270w034433.spd d-rd/i280w055777.spd d-sh/i295w035791.spd
d-ms/i275w030644.spd d-rd/i285w051257.spd
d-ms/i280w027133.spd d-rd/i290w046948.spd
<span style="color: #38761d;">[cjj@gust pattern]$</span></pre>
</blockquote>
While, the output files are in the current directory:<br />
<blockquote>
<pre><span style="color: #38761d;">[cjj@gust pattern]$</span> <span style="color: blue;">ls *.o*</span>
i270w034433.spd.o172489 i275w060475.spd.o172496 i285w036791.spd.o172486
i270w065151.spd.o172495 i280w027133.spd.o172491 i290w023034.spd.o172493
i275w030644.spd.o172490 i280w040241.spd.o172485 i290w031925.spd.o172487
i275w042526.spd.o172484 i285w025017.spd.o172492 i295w026791.spd.o172488
<span style="color: #38761d;">[cjj@gust pattern]$</span></pre>
</blockquote>
The format of the output log files are as follows:<br />
<blockquote>
<pre><span style="color: #38761d;">[cjj@gust pattern]$</span> <span style="color: blue;">cat i270w034433.spd.o172489</span>
MinTemplateNumber = 3
JT = 5
JN = 1
spikeResolution = 2
Number of initial spike patterns have been found : <span style="color: red;">562</span>
ans = Creating surrogate data
ans = Creating time jittering surrogate data
ans = Creating neuron jittering surrogate data
Number of spike patterns have been valid by checking with sorrogate : <span style="color: red;">542</span>
Number of spike patterns have been ruled out because of having less complex : <span style="color: red;">205</span>
Number of valid spike patterns have been found : <span style="color: red;">337</span>
<span style="color: #38761d;">[cjj@gust pattern]$</span></pre>
</blockquote>
<h3>
Problem task</h3>
Gather the stats in the log files as those marked in red.<br />
<br />
<h3>
Solution 1</h3>
This is done with a one-liner:<br />
<blockquote>
<pre><span style="color: #38761d;">[cjj@gust pattern]$</span> <span style="color: blue;">for i in d-*/*.spd;do n=${i%/*};n=${n#d-};s=${i#*/};if [ -f ${s}.o* ];then w=${s%.spd};w=${w#*w}; echo ${n} ${s:1:2}.${s:3:1} $((1${w:0:2}-100)).${w:2} `grep ':' ${s}.o* | awk '{print $NF}'`;fi;done > matching_stat.txt</span></pre>
</blockquote>
which can be broken down to:<br />
<blockquote class="tr_bq">
<pre><span style="color: blue;">for i in d-*/*.spd;do
n=${i%/*}
n=${n#d-}
s=${i#*/}
if [ -f ${s}.o* ];then
w=${s%.spd}
w=${w#*w}
echo ${n} ${s:1:2}.${s:3:1} $((1${w:0:2}-100)).${w:2} `grep ':' ${s}.o* | awk '{print $NF}'`
fi
done > matching_stat.txt</span></pre>
</blockquote>
The data file generated is:<br />
<blockquote>
<pre><span style="color: #38761d;">[cjj@gust pattern]$</span> <span style="color: blue;">cat matching_stat.txt</span>
msc 27.5 4.2526 81 75 22 53
msc 28.0 4.0241 237 217 103 114
msc 28.5 3.6791 393 371 156 215
msc 29.0 3.1925 335 322 132 190
msc 29.5 2.6791 445 437 144 293
ms 27.0 3.4433 562 542 205 337
ms 27.5 3.0644 1037 1006 331 675
ms 28.0 2.7133 1141 1093 341 752
ms 28.5 2.5017 1325 1274 462 812
ms 29.0 2.3034 1652 1609 747 862
rd 27.0 6.5151 1031 953 313 640
rd 27.5 6.0475 1042 963 345 618
<span style="color: #38761d;">[cjj@gust pattern]$</span></pre>
</blockquote>
cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-11542098775944318922012-07-12T14:56:00.000-04:002012-07-12T14:57:06.891-04:00Mental shelterWhen one is not capable of standing the elements, one seeks shelter. This is a natural instinct that has facilitated our survival ever since we were weaklings. But, for one to arrive at an oasis, one must first grow capable of leaving the shelter and stand the elements. Such instinct extends to the mental aspect of our capability. There are small things that cater to ones mental comfort: Be it a game, be it a show, be it a sport, be it a habit, be it an article, or be it an addiction. They are all small compare to our goals that set on by our will. However, mental weakness leads to incapability of leaving such shelters.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-61005875974457415482012-06-06T12:50:00.001-04:002012-06-06T12:51:35.996-04:00Remote system upgrade (with grub and bmc-watchdog)IPMI is a very very powerful tool for system administrators, especially those telecommuting ones. It's serial over LAN (SOL) support eliminates the need to personally sit in front of a server to do any pre-network operations, including reconfiguring the BIOS settings. However, it does require (A) an additional IP address to access the IPMI network interface from the Internet; or, when no additional IP can be allocated, (B) the access to a second server on the same LAN (not necessarily with administrator privilege). When either (A) or (B) is available, you can theoretically do anything remotely including fresh installation of an operation system (starting, for example, with a network boot and/or a remote drive).<br />
<br />
Unfortunately, one of my recent situation allowed neither (A) nor (B). So, the first installation had no option but to be done by on-site personnel. But, once a networked system was up and running with a working grub boot manager, I could remotely install a new system on an unused (or a large enough swap) partition and test it out with the "boot once" support of grub. On a Debian based system with grub-2, this involves<br />
<ul>
<li>changing the value of "GRUB_DEFAULT" in /etc/default/grub to "saved",</li>
<li>running "update-grub",</li>
<li>editing /boot/grub/grub.cfg to make an entry for the new system (if it was not discovered correctly by grub-probe),</li>
<li>running "grub-reboot" for the entry, and</li>
<li>rebooting the machine.</li>
</ul>
However, in most cases, you are bound to make some mistakes in the new system and fail to recover network contact to the server until an on-site person can hit the reset button of the machine for you.<br />
<br />
Lucky for me, the BMC of the IPMI on the server did have a working watchdog timer. Therefore, I could setup the timer with enough time and start it before rebooting the machine. That way, if the new system worked, I could login to the server through the Internet and stopped the timer. But, if the new system got stuck, the watchdog would do a hard reset on the machine after the time ran out and returned to the original working system... no more waiting for on-site personnel. The actual command I used to setup the timer is bmc-watchdog from freeipmi:<br />
<ul>
<li>bmc-watchdog -s -u 4 -p 0 -a 1 -F -P -L -S -O -i 900</li>
</ul>
One can consult the man page for the meaning of these options. Simply, this sets up 15 minutes on the timer for a hard reset, which can be checked with<br />
<ul>
<li>bmc-watchdog -g</li>
</ul>
started with<br />
<ul>
<li>bmc-watchdog -r</li>
</ul>
and stopped with<br />
<ul>
<li>bmc-watchdog -y</li>
</ul>
(While, theoretically, one can achieve the same result with ipmitool, it did not work for me on the specific system.)cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-22046775490147985592011-09-15T13:39:00.003-04:002011-09-16T00:49:35.783-04:00Portable library for C++ GUI programmingIt has been for a few occasions that I find my self wanting to port my GUI programs (most of which were written with <a href="http://www.gtkmm.org/">gtkmm</a>) to other platforms for the enjoyment of my friends. However, while most GUI toolkits claim to be portable to all platforms (Linux, Windows, and Mac), they generally require installation of multiple shared libraries by the users.<br />
<br />
This is a major show stopper for most of my friends and is sufficient to kill any interest in them on the first mention. Therefore, the only viable mean is for me to make and send them statically-linked, monolithic executables that they can happily click on to start the shows. (They generally don't mind waiting a few minutes to download a bloated binary, as long as it remains a single step.)<br />
<br />
My recent survey of the GUI library landscape brought my attention to <a href="http://www.opengl.org/resources/libraries/glut/">GLUT</a>. While it still requires installation on Windows, I can easily find static versions of <a href="http://freeglut.sourceforge.net/">FreeGLUT</a> library for <a href="http://www.mingw.org/">MingW</a> that can be used to cross-compile, on Linux, statically-linked executables that can run independently on Windows. Furthermore, the GLUT framework, which, according to <a href="http://developer.apple.com/library/mac/qa/qa1613/">this</a>, "is installed with every install of Mac OS X".<br />
<br />
However, GLUT library only provides facilities for managing windows and handling user inputs. It is by no means a GUI toolkit and you will have to draw all user-interactive elements by yourself (in <a href="http://www.opengl.org/">OpenGL</a>). I do find a GUI library, <a href="http://glui.sourceforge.net/">GLUI</a>, that is built on and should be as portable as GLUT. However, after porting a couple programs to GLUI, I failed to find it enjoyable for me to break up the C++-elegant logic of gtkmm and redo my work in a less polished API.<br />
<br />
What follows is the birth of <a href="http://gltk.ccdw.org/">gltk</a>, it is an implementation of the gtkmm API on GLUT. I actually started with adding the <a href="http://libsigc.sourceforge.net/">libsigc++</a>'s signal-slot API to GLUI since the original callback mechanism only supported single static callback function and I needed more flexibility to port my programs. But, the hack soon proliferated into the entire source tree, and I decided it would be much more enjoyable for me to start something entirely from scratch.<br />
<br />
After a somewhat persisting part-time effort that lasted more than a month, I have just made the first <a href="http://freshmeat.net/projects/gltk">release</a> of the library. It's usable for a <a href="http://ccdw.org/%7Ecjj/prog/avagl.png">simple application</a> that only needs some buttons, checkboxes, sliders, single line text labels or entries to control calculations. For myself, this represent over 80% of the applications that I would have considered porting. I am feeling pretty happy about it and I hope some others will also find it useful.<br />
<br />
Project Homepage: <a href="http://gltk.ccdw.org/">http://gltk.ccdw.org/</a>cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-65829074900709851922011-04-26T22:31:00.007-04:002011-04-27T12:30:06.923-04:00PermutationThe following spaghetti prints all permutations of a string ("abcd"). I wrote it as an example to show the benefit of structured programming in my class.<br />
<pre><span style="color: #5374b0;">#include <iostream></span>
<span style="color: #ff3030;">using namespace</span> std<span style="color: #555555;">;</span>
<span style="color: #f48c23;">int</span> <span style="color: #d11ced;">main</span><span style="color: #555555;">()</span>
<span style="color: #555555;">{</span>
<span style="color: #f48c23;">char</span> c<span style="color: #555555;">[] =</span> <span style="color: #1861a7;">"abcd</span><span style="color: #a61761;">\n</span><span style="color: #1861a7;">"</span><span style="color: #555555;">;</span>
<span style="color: #f48c23;">int</span> size <span style="color: #555555;">=</span> <span style="color: #ff3030;">sizeof</span><span style="color: #555555;">(</span>c<span style="color: #555555;">) -</span> <span style="color: #32ba06;">2</span><span style="color: #555555;">;</span>
<span style="color: #f48c23;">int</span> n<span style="color: #555555;">[</span>size <span style="color: #555555;">+</span> <span style="color: #32ba06;">1</span><span style="color: #555555;">];</span>
n<span style="color: #555555;">[</span>size<span style="color: #555555;">] =</span> <span style="color: #32ba06;">1</span><span style="color: #555555;">;</span>
<span style="color: #f48c23;">int</span> idx <span style="color: #555555;">=</span> size<span style="color: #555555;">;</span>
<span style="color: #f48c23;">char</span> t<span style="color: #555555;">;</span>
new_round<span style="color: #555555;">:</span>
<span style="color: #ff3030;">for</span> <span style="color: #555555;">(</span><span style="color: #f48c23;">int</span> i <span style="color: #555555;">=</span> <span style="color: #32ba06;">0</span><span style="color: #555555;">;</span> i <span style="color: #555555;"><</span> idx<span style="color: #555555;">;</span> i <span style="color: #555555;">++)</span> n<span style="color: #555555;">[</span>i<span style="color: #555555;">] =</span> i <span style="color: #555555;">+</span> <span style="color: #32ba06;">1</span><span style="color: #555555;">;</span>
cout <span style="color: #555555;"><<</span> c<span style="color: #555555;">;</span>
start_shift<span style="color: #555555;">:</span>
idx <span style="color: #555555;">=</span> <span style="color: #32ba06;">0</span><span style="color: #555555;">;</span>
t <span style="color: #555555;">=</span> c<span style="color: #555555;">[</span><span style="color: #32ba06;">0</span><span style="color: #555555;">];</span>
shift_next<span style="color: #555555;">:</span>
<span style="color: #ff3030;">if</span> <span style="color: #555555;">(</span>n<span style="color: #555555;">[</span>idx<span style="color: #555555;">])</span> <span style="color: #ff3030;">goto</span> shift_done<span style="color: #555555;">;</span>
idx <span style="color: #555555;">++;</span>
c<span style="color: #555555;">[</span><span style="color: #32ba06;">0</span><span style="color: #555555;">] =</span> c<span style="color: #555555;">[</span>idx<span style="color: #555555;">];</span>
c<span style="color: #555555;">[</span>idx<span style="color: #555555;">] =</span> t<span style="color: #555555;">;</span>
t <span style="color: #555555;">=</span> c<span style="color: #555555;">[</span><span style="color: #32ba06;">0</span><span style="color: #555555;">];</span>
<span style="color: #ff3030;">goto</span> shift_next<span style="color: #555555;">;</span>
shift_done<span style="color: #555555;">:</span>
n<span style="color: #555555;">[</span>idx<span style="color: #555555;">] --;</span>
<span style="color: #ff3030;">if</span> <span style="color: #555555;">(</span>idx <span style="color: #555555;">==</span> size<span style="color: #555555;">)</span> <span style="color: #ff3030;">return</span> <span style="color: #32ba06;">0</span><span style="color: #555555;">;</span>
<span style="color: #ff3030;">if</span> <span style="color: #555555;">(</span>n<span style="color: #555555;">[</span>idx<span style="color: #555555;">] ==</span> <span style="color: #32ba06;">0</span><span style="color: #555555;">)</span> <span style="color: #ff3030;">goto</span> start_shift<span style="color: #555555;">;</span>
<span style="color: #ff3030;">goto</span> new_round<span style="color: #555555;">;</span>
<span style="color: #555555;">}</span>
</pre>The structured version is as follows: <br />
<pre><span style="color: #5374b0;">#include <iostream></span>
<span style="color: #ff3030;">using namespace</span> std<span style="color: #555555;">;</span>
<span style="color: #f48c23;">int</span> <span style="color: #d11ced;">main</span><span style="color: #555555;">()</span>
<span style="color: #555555;">{</span>
<span style="color: #f48c23;">char</span> c<span style="color: #555555;">[] =</span> <span style="color: #1861a7;">"abcd</span><span style="color: #a61761;">\n</span><span style="color: #1861a7;">"</span><span style="color: #555555;">;</span>
<span style="color: #f48c23;">int</span> size <span style="color: #555555;">=</span> <span style="color: #ff3030;">sizeof</span><span style="color: #555555;">(</span>c<span style="color: #555555;">) -</span> <span style="color: #32ba06;">2</span><span style="color: #555555;">;</span>
<span style="color: #f48c23;">int</span> n<span style="color: #555555;">[</span>size <span style="color: #555555;">+</span> <span style="color: #32ba06;">1</span><span style="color: #555555;">];</span>
n<span style="color: #555555;">[</span>size<span style="color: #555555;">] =</span> <span style="color: #32ba06;">1</span><span style="color: #555555;">;</span>
<span style="color: #f48c23;">int</span> idx <span style="color: #555555;">=</span> size<span style="color: #555555;">;</span>
<span style="color: #f48c23;">char</span> t<span style="color: #555555;">;</span>
<span style="color: #ff3030;">do</span> <span style="color: #555555;">{</span>
<span style="color: #ff3030;">if</span> <span style="color: #555555;">(</span>n<span style="color: #555555;">[</span>idx<span style="color: #555555;">]) {</span>
<span style="color: #ff3030;">for</span> <span style="color: #555555;">(</span><span style="color: #f48c23;">int</span> i <span style="color: #555555;">=</span> <span style="color: #32ba06;">0</span><span style="color: #555555;">;</span> i <span style="color: #555555;"><</span> idx<span style="color: #555555;">;</span> i <span style="color: #555555;">++)</span> n<span style="color: #555555;">[</span>i<span style="color: #555555;">] =</span> i <span style="color: #555555;">+</span> <span style="color: #32ba06;">1</span><span style="color: #555555;">;</span>
cout <span style="color: #555555;"><<</span> c<span style="color: #555555;">;</span>
<span style="color: #555555;">}</span>
idx <span style="color: #555555;">=</span> <span style="color: #32ba06;">0</span><span style="color: #555555;">;</span>
t <span style="color: #555555;">=</span> c<span style="color: #555555;">[</span><span style="color: #32ba06;">0</span><span style="color: #555555;">];</span>
<span style="color: #ff3030;">while</span> <span style="color: #555555;">(</span>n<span style="color: #555555;">[</span>idx<span style="color: #555555;">] ==</span> <span style="color: #32ba06;">0</span><span style="color: #555555;">) {</span>
idx <span style="color: #555555;">++;</span>
c<span style="color: #555555;">[</span><span style="color: #32ba06;">0</span><span style="color: #555555;">] =</span> c<span style="color: #555555;">[</span>idx<span style="color: #555555;">];</span>
c<span style="color: #555555;">[</span>idx<span style="color: #555555;">] =</span> t<span style="color: #555555;">;</span>
t <span style="color: #555555;">=</span> c<span style="color: #555555;">[</span><span style="color: #32ba06;">0</span><span style="color: #555555;">];</span>
<span style="color: #555555;">}</span>
n<span style="color: #555555;">[</span>idx<span style="color: #555555;">] --;</span>
<span style="color: #555555;">}</span> <span style="color: #ff3030;">while</span> <span style="color: #555555;">(</span>idx <span style="color: #555555;"><</span> size<span style="color: #555555;">);</span>
<span style="color: #ff3030;">return</span> <span style="color: #32ba06;">0</span><span style="color: #555555;">;</span>
<span style="color: #555555;">}</span>
</pre>The idea is to rotate a string by n times, where n is the length of the string. While, before each rotation, rotate the n-1 substring at the front n-1 times. And while, before each rotation, rotate the n-2 substring at the front n-2 times. And so on... We can see that this is more elegantly done recursively:<br />
<pre><span style="color:#5374b0">#include <iostream></span>
<span style="color:#ff3030">using namespace</span> std<span style="color:#555555">;</span>
<span style="color:#f48c23">char</span> c<span style="color:#555555">[] =</span> <span style="color:#1861a7">"abcd</span><span style="color:#a61761">\n</span><span style="color:#1861a7">"</span><span style="color:#555555">;</span>
<span style="color:#f48c23">int</span> size <span style="color:#555555">=</span> <span style="color:#ff3030">sizeof</span><span style="color:#555555">(</span>c<span style="color:#555555">) -</span> <span style="color:#32ba06">2</span><span style="color:#555555">;</span>
<span style="color:#f48c23">void</span> <span style="color:#d11ced">rotate</span><span style="color:#555555">(</span><span style="color:#f48c23">int</span> l<span style="color:#555555">)</span>
<span style="color:#555555">{</span>
<span style="color:#f48c23">char</span> ch <span style="color:#555555">=</span> c<span style="color:#555555">[</span>l <span style="color:#555555">-</span> <span style="color:#32ba06">1</span><span style="color:#555555">];</span>
<span style="color:#ff3030">for</span> <span style="color:#555555">(</span><span style="color:#f48c23">int</span> i <span style="color:#555555">=</span> l <span style="color:#555555">-</span> <span style="color:#32ba06">1</span><span style="color:#555555">;</span> i<span style="color:#555555">;</span> i <span style="color:#555555">--)</span> c<span style="color:#555555">[</span>i<span style="color:#555555">] =</span> c<span style="color:#555555">[</span>i <span style="color:#555555">-</span> <span style="color:#32ba06">1</span><span style="color:#555555">];</span>
c<span style="color:#555555">[</span><span style="color:#32ba06">0</span><span style="color:#555555">] =</span> ch<span style="color:#555555">;</span>
<span style="color:#555555">}</span>
<span style="color:#f48c23">void</span> <span style="color:#d11ced">perm</span><span style="color:#555555">(</span><span style="color:#f48c23">int</span> l<span style="color:#555555">)</span>
<span style="color:#555555">{</span>
<span style="color:#ff3030">if</span> <span style="color:#555555">(</span>l <span style="color:#555555">==</span> <span style="color:#32ba06">1</span><span style="color:#555555">)</span> cout <span style="color:#555555"><<</span> c<span style="color:#555555">;</span>
<span style="color:#ff3030">else for</span> <span style="color:#555555">(</span><span style="color:#f48c23">int</span> i <span style="color:#555555">=</span> <span style="color:#32ba06">0</span><span style="color:#555555">;</span> i <span style="color:#555555"><</span> l<span style="color:#555555">;</span> i <span style="color:#555555">++) {</span>
<span style="color:#d11ced">perm</span><span style="color:#555555">(</span>l <span style="color:#555555">-</span> <span style="color:#32ba06">1</span><span style="color:#555555">);</span>
<span style="color:#d11ced">rotate</span><span style="color:#555555">(</span>l<span style="color:#555555">);</span>
<span style="color:#555555">}</span>
<span style="color:#555555">}</span>
<span style="color:#f48c23">int</span> <span style="color:#d11ced">main</span><span style="color:#555555">()</span>
<span style="color:#555555">{</span>
<span style="color:#d11ced">perm</span><span style="color:#555555">(</span>size<span style="color:#555555">);</span>
<span style="color:#ff3030">return</span> <span style="color:#32ba06">0</span><span style="color:#555555">;</span>
<span style="color:#555555">}</span>
</pre>The above thinking counts on the string to have all distinct chars. When this isn't the case, a different approach is to consider the lexical order of the permutations. From a given permutation, we simply need to figure out the next in the lexical order until the order is "maximized". It turns out that this is in the <a href="http://www.cplusplus.com/reference/algorithm/next_permutation/">C++ STL</a>. My reimplementation is as follows:<br />
<pre><span style="color:#5374b0">#include <iostream></span>
<span style="color:#ff3030">using namespace</span> std<span style="color:#555555">;</span>
<span style="color:#f48c23">void</span> <span style="color:#d11ced">swap</span><span style="color:#555555">(</span><span style="color:#f48c23">char</span> <span style="color:#555555">&</span> a<span style="color:#555555">,</span> <span style="color:#f48c23">char</span> <span style="color:#555555">&</span> b<span style="color:#555555">)</span>
<span style="color:#555555">{</span>
<span style="color:#f48c23">char</span> c <span style="color:#555555">=</span> a<span style="color:#555555">;</span>
a <span style="color:#555555">=</span> b<span style="color:#555555">;</span>
b <span style="color:#555555">=</span> c<span style="color:#555555">;</span>
<span style="color:#555555">}</span>
<span style="color:#006633">// increase the order of string</span>
<span style="color:#f48c23">bool</span> <span style="color:#d11ced">incr</span><span style="color:#555555">(</span><span style="color:#f48c23">char</span> <span style="color:#555555">*</span> str<span style="color:#555555">,</span> <span style="color:#f48c23">size_t</span> len<span style="color:#555555">)</span>
<span style="color:#555555">{</span>
<span style="color:#f48c23">size_t</span> i <span style="color:#555555">=</span> <span style="color:#32ba06">1</span><span style="color:#555555">;</span>
<span style="color:#ff3030">while</span> <span style="color:#555555">(</span>i <span style="color:#555555"><</span> len <span style="color:#555555">&&</span> str<span style="color:#555555">[</span>i <span style="color:#555555">-</span> <span style="color:#32ba06">1</span><span style="color:#555555">] >=</span> str<span style="color:#555555">[</span>i<span style="color:#555555">])</span> i <span style="color:#555555">++;</span>
<span style="color:#ff3030">if</span> <span style="color:#555555">(</span>i <span style="color:#555555">==</span> len<span style="color:#555555">)</span> <span style="color:#ff3030">return false</span><span style="color:#555555">;</span> <span style="color:#006633">// no kink</span>
<span style="color:#006633">// found a kink</span>
<span style="color:#f48c23">size_t</span> j <span style="color:#555555">=</span> i <span style="color:#555555">-</span> <span style="color:#32ba06">1</span><span style="color:#555555">;</span>
<span style="color:#ff3030">while</span> <span style="color:#555555">(</span>j <span style="color:#555555">></span> <span style="color:#32ba06">0</span> <span style="color:#555555">&&</span> str<span style="color:#555555">[</span>j <span style="color:#555555">-</span> <span style="color:#32ba06">1</span><span style="color:#555555">] <</span> str<span style="color:#555555">[</span>i<span style="color:#555555">])</span> j <span style="color:#555555">--;</span> <span style="color:#006633">// size kink</span>
<span style="color:#d11ced">swap</span><span style="color:#555555">(</span>str<span style="color:#555555">[</span>i<span style="color:#555555">],</span> str<span style="color:#555555">[</span>j<span style="color:#555555">]);</span> <span style="color:#006633">// shave kink</span>
<span style="color:#006633">// reverse rest</span>
<span style="color:#ff3030">for</span> <span style="color:#555555">(</span>i <span style="color:#555555">--,</span> j <span style="color:#555555">=</span> <span style="color:#32ba06">0</span><span style="color:#555555">;</span> j <span style="color:#555555"><</span> i<span style="color:#555555">;</span> i <span style="color:#555555">--,</span> j <span style="color:#555555">++)</span> <span style="color:#d11ced">swap</span><span style="color:#555555">(</span>str<span style="color:#555555">[</span>i<span style="color:#555555">],</span> str<span style="color:#555555">[</span>j<span style="color:#555555">]);</span>
<span style="color:#ff3030">return true</span><span style="color:#555555">;</span>
<span style="color:#555555">}</span>
<span style="color:#f48c23">int</span> <span style="color:#d11ced">main</span><span style="color:#555555">()</span>
<span style="color:#555555">{</span>
<span style="color:#f48c23">char</span> c<span style="color:#555555">[] =</span> <span style="color:#1861a7">"aabbc</span><span style="color:#a61761">\n</span><span style="color:#1861a7">"</span><span style="color:#555555">;</span>
<span style="color:#f48c23">int</span> size <span style="color:#555555">=</span> <span style="color:#ff3030">sizeof</span><span style="color:#555555">(</span>c<span style="color:#555555">) -</span> <span style="color:#32ba06">2</span><span style="color:#555555">;</span>
<span style="color:#ff3030">do</span> cout <span style="color:#555555"><<</span> c<span style="color:#555555">;</span> <span style="color:#ff3030">while</span> <span style="color:#555555">(</span><span style="color:#d11ced">incr</span><span style="color:#555555">(</span>c<span style="color:#555555">,</span> size<span style="color:#555555">));</span>
<span style="color:#555555">}</span>
</pre>cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-89288863825811427332011-03-17T22:17:00.002-04:002011-04-27T19:12:07.498-04:00Building driver for AverMedia A827 on Linux kernel 2.6.38Vendor: AVerMedia<br />
Product: AVerTV Hybrid Volar HX<br />
Model: <a href="http://www.avermedia.com/avertv/product/ProductDetail.aspx?Id=293">A827</a><br />
<br />
This is a Analog+DVB-T USB TV receiver with official support for Linux up until 2009-11-26. The latest driver can be downloaded from the product page above.<br />
<br />
The "Normal" automatic process of installing the driver fails for 2.6.38 kernel. Using the "Expert" process to extract the driver source code to a selected location allows one to compile the driver manually and track down the problems. First, the function calls for mutex initialization are gone and should be replaced with those of semaphore initialization. Second, the Teletext support is also gone and should be eliminated from the driver source code. These fixes are summarized in <a href="http://ccdw.org/%7Ecjj/files/patch/H826D_2.6.38.patch">this patch</a>.<br />
<br />
However, compiling the driver with "make" results in the WARNINGs that the symbols "param_array_get" and "param_array_set" are undefined. This is due a prebuilt object file, "aver/osdep_dvb.o_shipped", that was built with an older version of kernel. Building this file requires some internal header files from kernel source tree that are not normally available in, e.g., linux-headers or kernel-headers packages. Provided that the kernel source tree for building the running kernel is installed/available in the system, the shipped object file can be removed. After this, the "make" command can complete without incidence. Installing the drivers ("averusbh826d.ko" "h826d.ko") to the module directory, e.g., "/lib/modules/2.6.38/kernel/drivers/media/dvb/dvb-usb" and updating the module dependency with "depmod -a", the adapter seems to work normally afterwards.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com6tag:blogger.com,1999:blog-80151221334684982.post-70818169670510358132011-02-26T02:15:00.000-05:002011-02-26T02:15:11.141-05:00StraightforwardWe make a choice. We stick to it. We can modify it. We can change it. But, we should never forget about it.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-55014167923235602011-01-17T23:49:00.000-05:002011-01-17T23:49:00.888-05:00Addiction is the lost of ability to move onLife is a tour of the world. You come without any preconception and build up a mind of yourself. You travel through time and space, through different stages of growth and experience. And when the time comes for you to leave, you leave with nothing but your mind. Just like for any tour, moving on is just as important as moving in. If you can not, the tour will still end wherever you are.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-31718972921679047232010-10-24T23:11:00.000-04:002010-10-24T23:11:46.344-04:00DisciplineMental discipline is much harder to adhere than physical discipline. However, it's the essential drive to a higher altitude in the cruise of life.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-36333908935891968122010-10-11T14:16:00.000-04:002010-10-11T14:16:15.406-04:00Setup isatap router on debianThe ifupdown package on Debian does not support <a href="http://en.wikipedia.org/wiki/ISATAP">isatap</a> as a mode for v4tunnel. Therefore, one can not simply create a single entry in <span style="color: purple;">/etc/network/interfaces</span> to make it work. Anyhow, following are the steps I took to set it up.<br />
<ol><li>Install <span style="background-color: yellow;">iproute</span> and <span style="background-color: yellow;">radvd</span></li>
<li>Add "<span style="color: blue;">net.ipv6.conf.all.forwarding=1</span>" to <span style="color: purple;">/etc/sysctl.conf</span></li>
<li>Add <span style="color: purple;">/etc/radvd.conf</span> containing:<div style="margin-left: 40px;"> <span style="color: blue;">interface is0</span><br style="color: blue;" /><span style="color: blue;"> {</span><br style="color: blue;" /><span style="color: blue;"> AdvSendAdvert on;</span><br style="color: blue;" /><span style="color: blue;"> UnicastOnly on;</span><br style="color: blue;" /><span style="color: blue;"> AdvHomeAgentFlag off;</span><br style="color: blue;" /><span style="color: blue;"> prefix 2002:aaaa:bbbb:1::/64</span><br style="color: blue;" /><span style="color: blue;"> {</span><br style="color: blue;" /><span style="color: blue;"> AdvOnLink on;</span><br style="color: blue;" /><span style="color: blue;"> AdvAutonomous on;</span><br style="color: blue;" /><span style="color: blue;"> AdvRouterAddr off;</span><br style="color: blue;" /><span style="color: blue;"> };</span><br style="color: blue;" /><span style="color: blue;"> };</span></div>(replace "<span style="color: blue;">2002:aaaa:bbbb:1</span>" with the prefix of your ipv6 subnet)</li>
<li>Since I have my default address connected to a 6to4 tunnel on my eth0 already, I need to add an additional ip4 address to eth0. In <span style="color: purple;">/etc/network/interfaces</span> I add the following post-up, and pre-down scripts to eth0:<br />
<div style="color: blue; margin-left: 40px;">post-up ip tunnel add is0 mode isatap local 192.168.1.12 ttl 64<br />
post-up ip link set is0 up<br />
post-up ip addr add 2002:aaaa:bbbb:1::5efe:192.168.1.12/64 dev is0<br />
post-up ip addr add 192.168.1.12/32 dev eth0<br />
pre-down ip addr del 192.168.1.12/32 dev eth0<br />
pre-down ip link set is0 down<br />
pre-down ip tunnel del is0</div>(again replace "<span style="color: blue;">2002:aaaa:bbbb:1</span>")</li>
<li>Restart the computer or do the following:<div style="margin-left: 40px;"><span style="color: purple;">$ sysctl -p</span><br style="color: purple;" /><span style="color: purple;">$ ifdown eth0</span><br style="color: purple;" /><span style="color: purple;">$ ifup eth0</span><br style="color: purple;" /><span style="color: purple;">$ invoke-rc.d radvd start</span><span style="color: black;"><br />
</span></div></li>
</ol>On the client side, I just installed <a href="http://www.saschahlusiak.de/linux/isatap.htm"><span style="background-color: yellow;">isatapd</span></a>, added<br />
<blockquote><span style="color: purple;"><span style="color: blue;">ISATAP_ROUTERS="192.168.1.12"</span></span></blockquote>to <span style="color: purple;">/etc/default/isatapd</span>, and restarted with "<span style="color: purple;">invoke-rc.d isatapd restart</span>". Then, everything works!cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-39942653435776525962010-07-19T01:42:00.000-04:002010-07-19T01:42:31.130-04:00TrapRudimentary are things that can get us stuck. If we can not have them scaled with ease, how are we going to navigate more intricate endeavor. Methodical is the approach...cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-45915317272628829212010-06-02T02:02:00.001-04:002010-06-02T02:09:30.313-04:00Non-interactive ssh password authThere are situations where only password authentication is allowed on a remote <a href="http://en.wikipedia.org/wiki/Secure_Shell">SSH</a> server. And, it may be desirable to have non-interactive password entry even under interactive terminal sessions, <i>e.g.</i>, running <a href="http://git-scm.com/">git</a>, <a href="http://samba.anu.edu.au/rsync/">rsync</a>, <i>etc</i>. through ssh. However, <a href="http://www.openssh.com/">OpenSSH</a> makes this difficult by requiring interactive keyboard entry whenever there is an associated tty to the process. While it is possible to bypass this with an <a href="http://expect.nist.gov/">expect</a> script, the easiest solution is <a href="http://sshpass.sourceforge.net/">sshpass</a>.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-25954054084203381292010-05-28T02:04:00.002-04:002010-05-28T02:06:09.697-04:00Tax for holding intellectual propertiesThere are a few parallelisms between intellectual properties and real estate properties: They last indefinitely. They exclude public access. They cost law enforcement.<br />
<br />
However, real estate properties are localized and the effect of any single property on general public is limited. (There could be exceptions, for example, the property of the only water source within a large area of land.) However, intellectual properties are generally universal since new knowledge is build on old. The effect of their restriction can grow and propagate to all aspects of public lives. (Imagine patent on wheels, clocks, or electricity; Copyrights on all classical texts or musics; Or, trademarks on commonly used words.)<br />
<br />
So, under a necessary condition that such an intellectual property is to be granted to a private holder, proper tax should be assessed to recover the cost to the public. This can include loss of free access, blockage of innovation, and cost of property right enforcement. It is easy to imagine the growth of such cost will generally speed up in time. Thus, the tax rate should increase with the time that such a right is held.<br />
<br />
Alternatively, the creation of intellectual properties can be compensated and rewarded up front and their access should be made free to the public. The only difficulty is in determining the value of these properties. As naive this may sound, it has been practiced since the incipiency of science, where scientific knowledge gained is open to the public and scientists are rewarded by fame and status for the impact they made. Similar difficulty exists in judging the value of a research, but the current system based on consensus appears to be working.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-76351501412290580622010-05-07T03:30:00.006-04:002011-09-13T21:05:08.836-04:00Processing command-line arguments in C++I just released <a href="http://ccdw.org/%7Ecjj/prog/arg/"><b>arg</b></a> as a standalone library under LGPL. It's a command-line parser for C++ programs. The aim is to keep the programming effort in adding command-line processing to C++ programs at a minimum. There are several considerations in this direction:<br />
<ol><li>simple and intuitive syntax</li>
<li>requiring no redundancy</li>
<li>localized codes</li>
<li>extensibility</li>
<li>completeness</li>
</ol>The simple example as given on the <b>arg</b> homepage,<br />
<blockquote>#include <arg.hh><br />
#include <iostream><br />
int main(int argc, char ** argv)<br />
{<br />
arg::Parser p;<br />
int n;<br />
p.add_opt('n').stow(n);<br />
p.parse(argc, argv);<br />
std::cout << n << '\n';<br />
return 0;<br />
}</blockquote>should be very close to the minimum as far as 1. goes.<br />
<br />
Programming is for a programmer to describe what he wants the computer to do. Per point 2., he should not be asked to provide the same information multiple times. <span style="background-color: white; color: #999999;">(Well, maybe except in situations where multiple confirmations are required: "Launch the missile. Please have the missile launched. Yes, I really want you to launch the missile! Launch the *&^%$ missile!!!"; Computer: "Aborted on Error: missile != *&^%$ missile".)</span><br />
<br />
When working on an item, <i>e.g.</i>, adding a new command-line option, the programmer won't be asked to go to multiple places in the codes if 3. is observed. While common and frequent usages should be supported and simplified in the library, new and novel applications will ask for 4. Finally, some rare, special, and/or tricky applications will demand 5. in the arsenal.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-35902766014403019132010-05-06T05:36:00.000-04:002010-05-06T05:36:42.811-04:00Push forwardAs an organic matter, one requires constant exertion to maintain tension. The process ends when tension is out.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-10220450177592283972009-10-04T11:14:00.003-04:002009-10-04T11:29:30.831-04:00OpenSync with Nokia 2730 ClassicMy Nokia 2730 classic is found to work with the following configuration file for the SyncML plugin for OpenSync:<br /><blockquote><?xml version="1.0"?><br /><config><br /><bluetooth_address>XX:XX:XX:XX:XX:XX</bluetooth_address><br /> <bluetooth_channel>11</bluetooth_channel><br /> <interface>0</interface><br /> <identifier>PC Suite</identifier><br /> <version>1</version><br /> <wbxml>1</wbxml><br /> <username></username><br /> <password></password><br /> <type>2</type><br /> <usestringtable>0</usestringtable><br /> <onlyreplace>0</onlyreplace><br /> <onlyLocaltime>0</onlyLocaltime><br /> <recvLimit>0</recvLimit><br /> <maxObjSize>0</maxObjSize><br /> <contact_db>Contacts</contact_db><br /> <calendar_db>Calendar</calendar_db><br /> <note_db>Notes</note_db><br /></config></blockquote>For more details see <a href="http://www.opensync.org/wiki/releases/0.2x/syncml-guide">this guide</a> and this <a href="http://ubuntuforums.org/showthread.php?t=260676">HOWTO</a>.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-88336399824178279202009-02-26T02:56:00.004-05:002011-04-27T04:14:16.840-04:00synchronize work spaces on different machinesWhile working on a set of files on different machines, it's a common problem to keep things in sync. A real solution is to use a <a href="http://en.wikipedia.org/wiki/Revision_control">revision control system</a> (with <a href="http://git-scm.com/">git</a> being my current favorite). However, a quick fix is to use <a href="http://samba.anu.edu.au/rsync/">rsync</a>. Following script tries to figure out which copy of the work space is newer and invokes rsync accordingly.<br />
<pre><span style="color:#006633">#!/bin/bash</span>
<span style="color:#ff3030">if</span> <span style="color:#555555">((</span> <span style="color:#d11ced">$#</span> <span style="color:#555555">!=</span> <span style="color:#32ba06">3</span> <span style="color:#555555">));</span> <span style="color:#ff3030">then</span>
<span style="color:#f48c23">echo</span> <span style="color:#1861a7">"Usage: `basename $0` <local file> <remote host> <remote file>"</span>
<span style="color:#f48c23">exit</span> <span style="color:#32ba06">1</span><span style="color:#555555">;</span>
<span style="color:#ff3030">fi</span>
LOCAL_FILE<span style="color:#555555">=</span><span style="color:#1861a7">"$1"</span>
REMOTE_HOST<span style="color:#555555">=</span><span style="color:#1861a7">"$2"</span>
REMOTE_FILE<span style="color:#555555">=</span><span style="color:#1861a7">"$3"</span>
<span style="color:#006633"># make sure directories end with '/'</span>
<span style="color:#ff3030">if</span> <span style="color:#555555">[ -</span>d <span style="color:#1861a7">"${LOCAL_FILE}"</span> <span style="color:#555555">];</span> <span style="color:#ff3030">then</span>
LOCAL_FILE<span style="color:#555555">=</span><span style="color:#d11ced">${LOCAL_FILE%/}</span><span style="color:#555555">/</span>
REMOTE_FILE<span style="color:#555555">=</span><span style="color:#d11ced">${REMOTE_FILE%/}</span><span style="color:#555555">/</span>
<span style="color:#f48c23">echo</span> <span style="color:#1861a7">"sync directory: '`basename ${LOCAL_FILE}`' with ${REMOTE_HOST}"</span>
<span style="color:#ff3030">else</span>
<span style="color:#f48c23">echo</span> <span style="color:#1861a7">"sync file: '`basename ${LOCAL_FILE}`' with ${REMOTE_HOST}"</span>
<span style="color:#ff3030">fi</span>
<span style="color:#006633"># find out the last modification time in the entire directory</span>
TM_LOCAL<span style="color:#555555">=</span><span style="color:#1861a7">`if [ -e "${LOCAL_FILE}" ]; then find $LOCAL_FILE -printf "%Ts %P</span><span style="color:#a61761">\n</span><span style="color:#1861a7">"|sort|tail -n1; else echo 0; fi`</span>
TM_REMOTE<span style="color:#555555">=</span><span style="color:#1861a7">`ssh ${REMOTE_HOST} "if [ -e</span> <span style="color:#a61761">\"</span><span style="color:#1861a7">${REMOTE_FILE}</span><span style="color:#a61761">\"</span> <span style="color:#1861a7">]; then find $REMOTE_FILE -printf</span> <span style="color:#a61761">\"</span><span style="color:#1861a7">%Ts %P</span><span style="color:#a61761">\n\"</span><span style="color:#1861a7">|sort|tail -n1; else echo 0; fi" < /dev/null`</span>
<span style="color:#f48c23">echo</span> Local Newest<span style="color:#555555">:</span> <span style="color:#d11ced">$TM_LOCAL</span>
<span style="color:#f48c23">echo</span> Remote Newest<span style="color:#555555">:</span> <span style="color:#d11ced">$TM_REMOTE</span>
<span style="color:#ff3030">if</span> <span style="color:#555555">[[</span> <span style="color:#d11ced">$TM_LOCAL</span> <span style="color:#555555"><</span> <span style="color:#d11ced">$TM_REMOTE</span> <span style="color:#555555">]];</span> <span style="color:#ff3030">then</span>
<span style="color:#f48c23">echo</span> <span style="color:#555555">-</span>n <span style="color:#1861a7">"remote => local"</span>
rsync <span style="color:#555555">-</span>auz <span style="color:#555555">-</span>e <span style="color:#0000ff">ssh</span> <span style="color:#555555">--</span>delete <span style="color:#d11ced">${REMOTE_HOST}</span><span style="color:#555555">:</span><span style="color:#1861a7">"</span><span style="color:#a61761">\"</span><span style="color:#1861a7">${REMOTE_FILE}</span><span style="color:#a61761">\"</span><span style="color:#1861a7">"</span> <span style="color:#1861a7">"${LOCAL_FILE}"</span>
<span style="color:#f48c23">echo</span> <span style="color:#1861a7">", Done!"</span>
<span style="color:#ff3030">elif</span> <span style="color:#555555">[[</span> <span style="color:#d11ced">$TM_LOCAL</span> <span style="color:#555555">></span> <span style="color:#d11ced">$TM_REMOTE</span> <span style="color:#555555">]];</span> <span style="color:#ff3030">then</span>
<span style="color:#f48c23">echo</span> <span style="color:#555555">-</span>n <span style="color:#1861a7">"local => remote"</span>
rsync <span style="color:#555555">-</span>auz <span style="color:#555555">-</span>e <span style="color:#0000ff">ssh</span> <span style="color:#555555">--</span>delete <span style="color:#1861a7">"${LOCAL_FILE}"</span> <span style="color:#d11ced">${REMOTE_HOST}</span><span style="color:#555555">:</span><span style="color:#1861a7">"</span><span style="color:#a61761">\"</span><span style="color:#1861a7">${REMOTE_FILE}</span><span style="color:#a61761">\"</span><span style="color:#1861a7">"</span>
<span style="color:#f48c23">echo</span> <span style="color:#1861a7">", Done!"</span>
<span style="color:#ff3030">else</span>
<span style="color:#f48c23">echo</span> <span style="color:#1861a7">"Nothing to do!"</span>
<span style="color:#ff3030">fi</span>
</pre>cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-65236019273477084632008-12-24T02:31:00.003-05:002008-12-29T02:47:38.134-05:00fox2html: foxmarks.json to HTML converterThis <a href="http://ccdw.org/%7Ecjj/prog/#fox2html">script</a> converts "foxmarks.json" saved by the Firefox plugin, Foxmarks, on a self hosted server to a styled HTML file with interactive folders. An example output is <a href="https://circle.ccdw.org/%7Ecjj/">here</a>.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-51620395402469729362008-09-25T14:18:00.005-04:002011-04-27T04:21:59.498-04:00Duplication eliminationIn engineering a computation project, one desires a single point of information entry. It's elegant to come up with coding structures that will facilitate this requirement, that is, a single place in the codes pertinent to the to-be-computed problems. However, while the programming language is an interface between human and machine. It's not generally friendly to the users. The ultimate way of choice is to have human readable/editable files and make programs to generate corresponding codes when needed.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-63253123798804967102008-08-14T01:02:00.000-04:002008-08-14T01:03:37.049-04:00Pay attentionIf you don't see people, you don't see intention.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-76785051958857411922008-06-01T21:54:00.004-04:002010-10-22T02:58:29.368-04:00adding OCR to djvu fileFor each page in the file "cake.djvu", we can use the "tesseract" to process the page image:<br />
<blockquote>djvused -e "select ${page};save-page-with \"cake_page.djvu\"" cake.djvu<br />
convert cake_page.djvu cake.tif<br />
tesseract cake.tif cake_box batch.nochop makebox<br />
tesseract cake.tif cake_txt batch.nochop</blockquote>This produces the information for the text structure (lines and words) and positioning (coordinate for each character). To convert this information to the hidden-text format for use with djvused, use<br />
<blockquote><pre>perl<<'EOL'>cake_text.txt
open TXT, "<:utf8", "cake_txt.txt";
open BOX, "<:utf8", "cake_box.txt";
$pxn = 1000000;
$pxx = 0;
$pyn = 1000000;
$pyx = 0;
$pagebuf = "";
while ($line = <TXT>) {
chop $line;
@words = split /\s+/, $line;
next if $#words < 0;
$lxn = 1000000;
$lxx = 0;
$lyn = 1000000;
$lyx = 0;
$linebuf = "";
foreach $word (@words) {
$xmin = 1000000;
$xmax = 0;
$ymin = 1000000;
$ymax = 0;
$w = "";
for ($i = 0; $i < length($word); $i ++) {
$c = substr($word, $i, 1);
do {
$cline = <BOX>;
} while (substr($cline, 0, 1) ne $c);
($xn, $yn, $xx, $yx) = substr($cline, 2) =~ /\S+/g;
$w = $w . '\\' if $c eq '"';
$w = $w . '\\' if $c eq '\\';
$w = $w . substr($cline, 0, 1);
$xmin = $xn if ($xmin > $xn);
$xmax = $xx if ($xmax < $xx);
$ymin = $yn if ($ymin > $yn);
$ymax = $yx if ($ymax < $yx);
}
$wline = '(word ' . $xmin . ' ' . $ymin . ' ' . $xmax . ' ' . $ymax . ' "' . $w . '")';
$linebuf = $linebuf . "\n " . $wline;
$lxn = $xmin if ($lxn > $xmin);
$lxx = $xmax if ($lxx < $xmax);
$lyn = $ymin if ($lyn > $ymin);
$lyx = $ymax if ($lyx < $ymax);
}
$pagebuf = $pagebuf . "\n (line $xmin $ymin $xmax $ymax" . $linebuf . ')';
$pxn = $lxn if ($pxn > $lxn);
$pxx = $lxx if ($pxx < $lxx);
$pyn = $lyn if ($pyn > $lyn);
$pyx = $lyx if ($pyx < $lyx);
}
close BOX;
close TXT;
binmode(STDOUT, ":utf8");
print "(page $pxn $pyn $pxx $pyx", $pagebuf, ')', "\n";
EOL
</pre></blockquote>which generates "cake_text.txt" in the accordant format. The hidden text can be saved back to the djvu file with<br />
<blockquote>djvused -e "select ${page};set-txt \"cake_text.txt\";save" cake.djvu</blockquote>We just need to repeat this for all the desired pages.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com2tag:blogger.com,1999:blog-80151221334684982.post-371629145252073362008-05-04T09:53:00.002-04:002008-05-04T10:05:25.009-04:00Information overflowThe growing world of connected is increasing all we have available to take in. It's bound to exceed ones capacity without some form of aids. But, in raw, where is the limit? And, how are we going to cook it? In person, where is the limit? And, how are we going to team up? Any tool building helps?cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-14968833638617424032008-04-24T01:23:00.001-04:002008-04-24T01:25:36.377-04:00CompetitionLife is like a game. Those who enjoy the most win.cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0tag:blogger.com,1999:blog-80151221334684982.post-19081882963545050272008-04-23T17:18:00.003-04:002008-04-23T17:29:38.523-04:00Live like what and when?People have said things like: "Live like you'll die tomorrow." Maybe, this is for just so that we don't put off things that's really important. Well, whenever and whatever we are doing, we better pause when we can and think: Is there a better thing to do than this?cjjhttp://www.blogger.com/profile/05878474310879908349noreply@blogger.com0