<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sai Charan</title><link>https://www.saicharan.in</link><description>Recent content on Sai Charan</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 02 Mar 2026 15:25:00 +0000</lastBuildDate><atom:link href="https://www.saicharan.in/index.xml" rel="self" type="application/rss+xml"/><item><title>GB Shaw - The Unresonable Man</title><link>https://www.saicharan.in/blog/2026/03/02/quote-gb-shaw-the-unresonable-man</link><pubDate>Mon, 02 Mar 2026 15:25:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2026/03/02/quote-gb-shaw-the-unresonable-man</guid><description>&lt;blockquote&gt;
&lt;p&gt;The reasonable man adapts himself to the world. The unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;ndash; George Bernard Shaw&lt;/p&gt;
— As heard on David Senra&amp;rsquo;s &lt;a href="https://www.davidsenra.com/episode/daniel-ek-spotify"&gt;podcast&lt;/a&gt;.</description></item><item><title>Gitea with a dash Of Claude</title><link>https://www.saicharan.in/blog/2026/03/01/gitea-with-a-dash-of-claude</link><pubDate>Sun, 01 Mar 2026 20:59:56 +0000</pubDate><guid>https://www.saicharan.in/blog/2026/03/01/gitea-with-a-dash-of-claude</guid><description>&lt;p&gt;A note to self on my Gitea setup.&lt;/p&gt;
&lt;h3 id="basic-setup"&gt; &lt;a class="anchor" href="#basic-setup"&gt;Basic Setup &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I chose to set up manually, using the release binary, following the basic setup instructions from here Gitea &lt;a href="https://docs.gitea.com/installation/install-from-binary"&gt;docs&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="on-ubuntudebian"&gt; &lt;a class="anchor" href="#on-ubuntudebian"&gt;On Ubuntu/Debian &lt;/a&gt;&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ adduser \
 --system \
 --shell /bin/bash \
 --gecos &amp;#39;Gitea Version Control&amp;#39; \
 --group \
 --disabled-password \
 --home /home/gitea \
 gitea
&lt;p&gt;$ mkdir -p /var/lib/gitea/{custom,data,log}
$ chown -R gitea:gitea /var/lib/gitea/
$ chmod -R 750 /var/lib/gitea/
$ mkdir /etc/gitea
$ chown root:gitea /etc/gitea
$ chmod 770 /etc/gitea&lt;/p&gt;
&lt;p&gt;$ chmod 750 /etc/gitea
$ chmod 640 /etc/gitea/app.ini
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then, copy the &lt;code&gt;gitea&lt;/code&gt; binary from the Gitea’s &lt;a href="https://github.com/go-gitea/gitea/releases/latest"&gt;latest&lt;/a&gt; Github release to &lt;code&gt;/usr/share/bin/gitea&lt;/code&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;h3 id="linux-service"&gt; &lt;a class="anchor" href="#linux-service"&gt;Linux service &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Follow the basic instructions from Gitea &lt;a href="https://docs.gitea.com/installation/linux-service"&gt;docs&lt;/a&gt;, customizing using the &lt;code&gt;user&lt;/code&gt;, and paths above.&lt;/p&gt;
&lt;h3 id="customize-the-explorerepos"&gt; &lt;a class="anchor" href="#customize-the-explorerepos"&gt;Customize the /explore/repos &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For personal hosting, a view similar to gitweb, or cgit, that shows categorized views of repos is helpful. With cgit / gitweb, specifying the category in the &lt;code&gt;category&lt;/code&gt; file in . Since Gitea&amp;rsquo;s primary audience is teams, and organizations, it needs a bit of unorthodox coaxing for this customization.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set the following in app.ini (see &lt;a href="https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini"&gt;app.example.ini&lt;/a&gt;):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[ui]
EXPLORE_PAGING_NUM=100
EXPLORE_PAGING_DEFAULT_SORT=alphabetical
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;
&lt;li&gt;
&lt;p&gt;Create an Organization (my preference) / User per &amp;ldquo;category&amp;rdquo; (see &lt;a href="https://git-scm.com/docs/gitweb#Documentation/gitweb.txt-categoryorgitwebcategory"&gt;gitweb&lt;/a&gt; and &lt;a href="https://linux.die.net/man/5/cgitrc"&gt;cgitrc&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a file at &lt;code&gt;$GITEA_CUSTOM/templates/shared/repo/list.tmpl&lt;/code&gt; to obtain a customized view that organizes repos by &amp;ldquo;category&amp;rdquo; (Organization), with this (mostly) Claude-Code generated template, with the following prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Customize &lt;a href="https://raw.githubusercontent.com/go-gitea/gitea/master/templates/shared/repo/list.tmpl"&gt;list.tmpl&lt;/a&gt; to organize the repositories by organization (.Name)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;list.tmpl&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{{/* Remember to set these in /etc/gitea/app.ini */}}
{{/* [ui] */}}
{{/* EXPLORE_PAGING_NUM = 100 */}}
{{/* EXPLORE_PAGING_DEFAULT_SORT = alphabetically */}}
&lt;p&gt;{{$repos := .Repos}}
{{if $repos}}&lt;/p&gt;
&lt;p&gt;{{/* Track the owner we last emitted a heading for. */}}
{{$lastOrg := &amp;quot;&amp;quot;}}&lt;/p&gt;
&lt;p&gt;{{range $repo := $repos}}
{{$ownerName := $repo.Owner.Name}}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{{/* ── Emit a new group heading when the owner changes ── */}}
{{if ne $ownerName $lastOrg}}
 {{/* Close the previous group&amp;amp;#39;s item-list (skip on first iteration) */}}
 {{/* Sai: not immediately apparent: yes, the code inserting the element-end needs to preceed the opening */}}
 {{if ne $lastOrg &amp;amp;#34;&amp;amp;#34;}}
 &amp;amp;lt;/div&amp;amp;gt;{{/* .grouped-repos */}}
 &amp;amp;lt;/div&amp;amp;gt;{{/* .ui.segment */}}
 {{end}}

 &amp;amp;lt;div class=&amp;amp;#34;ui segment org-group&amp;amp;#34;&amp;amp;gt;
 &amp;amp;lt;h3 class=&amp;amp;#34;ui dividing header org-group-header&amp;amp;#34;&amp;amp;gt;
 {{svg &amp;amp;#34;octicon-organization&amp;amp;#34; 18 &amp;amp;#34;tw-mr-2&amp;amp;#34;}}
 &amp;amp;lt;a href=&amp;amp;#34;{{AppSubUrl}}/{{$ownerName}}&amp;amp;#34;&amp;amp;gt;{{$ownerName}}&amp;amp;lt;/a&amp;amp;gt;
 &amp;amp;lt;/h3&amp;amp;gt;
 &amp;amp;lt;div class=&amp;amp;#34;grouped-repos item list&amp;amp;#34;&amp;amp;gt;
 {{$lastOrg = $ownerName}}
{{end}}

{{/* ── Individual repository card ── */}}
&amp;amp;lt;div class=&amp;amp;#34;item&amp;amp;#34;&amp;amp;gt;
 &amp;amp;lt;div class=&amp;amp;#34;ui grid&amp;amp;#34;&amp;amp;gt;
 &amp;amp;lt;div class=&amp;amp;#34;sixteen wide column&amp;amp;#34;&amp;amp;gt;
 {{if $repo.Avatar}}
 &amp;amp;lt;img class=&amp;amp;#34;ui avatar image&amp;amp;#34; src=&amp;amp;#34;{{$repo.Avatar}}&amp;amp;#34; alt=&amp;amp;#34;&amp;amp;#34;/&amp;amp;gt;
 {{end}}
 &amp;amp;lt;a class=&amp;amp;#34;name has-emoji&amp;amp;#34; href=&amp;amp;#34;{{$repo.Link}}&amp;amp;#34;&amp;amp;gt;
 &amp;amp;lt;span class=&amp;amp;#34;text truncate&amp;amp;#34;&amp;amp;gt;{{$repo.Name}}&amp;amp;lt;/span&amp;amp;gt;
 &amp;amp;lt;/a&amp;amp;gt;
 &amp;amp;lt;br /&amp;amp;gt;
 {{if $repo.IsPrivate}}
 &amp;amp;lt;span class=&amp;amp;#34;ui tiny basic label&amp;amp;#34;&amp;amp;gt;{{ctx.Locale.Tr &amp;amp;#34;repo.desc.private&amp;amp;#34;}}&amp;amp;lt;/span&amp;amp;gt;
 {{end}}
 {{if $repo.IsTemplate}}
 &amp;amp;lt;span class=&amp;amp;#34;ui tiny basic label&amp;amp;#34;&amp;amp;gt;{{ctx.Locale.Tr &amp;amp;#34;repo.desc.template&amp;amp;#34;}}&amp;amp;lt;/span&amp;amp;gt;
 {{end}}
 {{if $repo.IsArchived}}
 &amp;amp;lt;span class=&amp;amp;#34;ui tiny basic label&amp;amp;#34;&amp;amp;gt;{{ctx.Locale.Tr &amp;amp;#34;repo.desc.archived&amp;amp;#34;}}&amp;amp;lt;/span&amp;amp;gt;
 {{end}}
 {{if $repo.IsFork}}
 &amp;amp;lt;span class=&amp;amp;#34;text small&amp;amp;#34;&amp;amp;gt;
 {{svg &amp;amp;#34;octicon-repo-forked&amp;amp;#34; 14}}
 {{ctx.Locale.Tr &amp;amp;#34;repo.forked_from&amp;amp;#34;}}
 &amp;amp;lt;a href=&amp;amp;#34;{{$repo.BaseRepo.Link}}&amp;amp;#34;&amp;amp;gt;{{$repo.BaseRepo.FullName}}&amp;amp;lt;/a&amp;amp;gt;
 &amp;amp;lt;/span&amp;amp;gt;
 {{end}}
 &amp;amp;lt;div class=&amp;amp;#34;meta&amp;amp;#34;&amp;amp;gt;
 {{if $repo.PrimaryLanguage}}
 &amp;amp;lt;span class=&amp;amp;#34;text grey df ac tw-mr-3&amp;amp;#34;&amp;amp;gt;
 &amp;amp;lt;i class=&amp;amp;#34;color-icon tw-mr-1&amp;amp;#34; style=&amp;amp;#34;background-color: {{$repo.PrimaryLanguage.Color}}&amp;amp;#34;&amp;amp;gt;&amp;amp;lt;/i&amp;amp;gt;
 {{$repo.PrimaryLanguage.Language}}
 &amp;amp;lt;/span&amp;amp;gt;
 {{end}}
 &amp;amp;lt;span class=&amp;amp;#34;text grey tw-mr-3&amp;amp;#34;&amp;amp;gt;
 {{svg &amp;amp;#34;octicon-star&amp;amp;#34; 14 &amp;amp;#34;tw-mr-1&amp;amp;#34;}}
 {{$repo.NumStars}}
 &amp;amp;lt;/span&amp;amp;gt;
 &amp;amp;lt;span class=&amp;amp;#34;text grey tw-mr-3&amp;amp;#34;&amp;amp;gt;
 {{svg &amp;amp;#34;octicon-git-branch&amp;amp;#34; 14 &amp;amp;#34;tw-mr-1&amp;amp;#34;}}
 {{$repo.NumForks}}
 &amp;amp;lt;/span&amp;amp;gt;
 {{if $repo.UpdatedUnix}}
 &amp;amp;lt;span class=&amp;amp;#34;text grey&amp;amp;#34;&amp;amp;gt;
 {{svg &amp;amp;#34;octicon-clock&amp;amp;#34; 14 &amp;amp;#34;tw-mr-1&amp;amp;#34;}}
 &amp;amp;lt;relative-time format=&amp;amp;#34;datetime&amp;amp;#34; year=&amp;amp;#34;numeric&amp;amp;#34; month=&amp;amp;#34;short&amp;amp;#34; day=&amp;amp;#34;numeric&amp;amp;#34;
 datetime=&amp;amp;#34;{{$repo.UpdatedUnix.FormatDate}}&amp;amp;#34;
 data-tooltip-content=&amp;amp;#34;{{$repo.UpdatedUnix.FormatDate}}&amp;amp;#34;&amp;amp;gt;
 {{$repo.UpdatedUnix.FormatDate}}
 &amp;amp;lt;/relative-time&amp;amp;gt;
 &amp;amp;lt;/span&amp;amp;gt;
 {{end}}
 &amp;amp;lt;/div&amp;amp;gt;
 &amp;amp;lt;/div&amp;amp;gt;

 {{/* Star / watch actions column */}}
 {{if and $.IsSigned (not $repo.IsEmpty)}}
 &amp;amp;lt;div class=&amp;amp;#34;two wide column text right&amp;amp;#34;&amp;amp;gt;
 &amp;amp;lt;form method=&amp;amp;#34;post&amp;amp;#34;
 action=&amp;amp;#34;{{AppSubUrl}}{{$repo.Link}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}&amp;amp;#34;&amp;amp;gt;
 {{$.CsrfTokenHtml}}
 &amp;amp;lt;button class=&amp;amp;#34;ui compact mini basic button&amp;amp;#34; type=&amp;amp;#34;submit&amp;amp;#34;
 data-tooltip-content=&amp;amp;#34;{{if $.IsStaringRepo}}{{ctx.Locale.Tr &amp;amp;#34;repo.unstar&amp;amp;#34;}}{{else}}{{ctx.Locale.Tr &amp;amp;#34;repo.star&amp;amp;#34;}}{{end}}&amp;amp;#34;&amp;amp;gt;
 {{if $.IsStaringRepo}}
 {{svg &amp;amp;#34;octicon-star-fill&amp;amp;#34; 16}}
 {{else}}
 {{svg &amp;amp;#34;octicon-star&amp;amp;#34; 16}}
 {{end}}
 &amp;amp;lt;/button&amp;amp;gt;
 &amp;amp;lt;/form&amp;amp;gt;
 &amp;amp;lt;/div&amp;amp;gt;
 {{end}}
 &amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
{{/* end repo card */}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;{{end}}{{/* end range $repos */}}&lt;/p&gt;
&lt;p&gt;{{/* Close the final open group &lt;em&gt;/}}
{{if ne $lastOrg &amp;quot;&amp;quot;}}
&amp;lt;/div&amp;gt;{{/&lt;/em&gt; .grouped-repos &lt;em&gt;/}}
&amp;lt;/div&amp;gt;{{/&lt;/em&gt; .ui.segment */}}
{{end}}&lt;/p&gt;
&lt;p&gt;{{else}}
{{/* No repositories found – mirror the standard empty-state */}}
&amp;lt;div class=&amp;quot;ui secondary segment&amp;quot;&amp;gt;
&amp;lt;p&amp;gt;{{ctx.Locale.Tr &amp;quot;search.no_results&amp;quot;}}&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
{{end}}&lt;/p&gt;
&lt;p&gt;&amp;lt;style&amp;gt;
/* Extra styling for the org-group headers */
.org-group {
margin-bottom: 1.5em !important;
padding-bottom: 0px;
}
.org-group-header {
font-size: 1.1rem;
margin-bottom: 0em !important;
}
.org-group-header a {
color: inherit;
}
.grouped-repos .item {
padding: 0.75em 0;
border-bottom: 1px solid var(&amp;ndash;color-secondary);
}
.grouped-repos .item:last-child {
border-bottom: none;
padding-bottom: 0px;
}
.sixteen {
display: flex !important;
padding-bottom: 10px !important;
flex-wrap: wrap;
justify-content: space-between;
}
.name {
width: 35%; // Hack for mobile view: force metadata on separate line, by reserving large portion of line for repo name
}
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
</description></item><item><title>Just Figure Out What's Next</title><link>https://www.saicharan.in/blog/2025/12/04/quote-just-figure-out-whats-next</link><pubDate>Thu, 04 Dec 2025 11:42:42 +0000</pubDate><guid>https://www.saicharan.in/blog/2025/12/04/quote-just-figure-out-whats-next</guid><description>&lt;blockquote&gt;
&lt;p&gt;I think if you do something and it turns out pretty good, then you should go do something else wonderful, not dwell on it for too long. Just figure out what’s next.&lt;/p&gt;
&lt;/blockquote&gt;— Steve Jobs</description></item><item><title>Sometimes, it's Better Physics</title><link>https://www.saicharan.in/blog/2025/12/01/quote-better-physics-sometimes</link><pubDate>Mon, 01 Dec 2025 18:31:15 +0000</pubDate><guid>https://www.saicharan.in/blog/2025/12/01/quote-better-physics-sometimes</guid><description>&lt;blockquote&gt;
&lt;p&gt;When software problems get too hard, sometimes the answer is &amp;lsquo;better physics&amp;rsquo;.&lt;/p&gt;
&lt;/blockquote&gt;— Urs Hölzle, on &lt;a href="https://www.linkedin.com/posts/partharanganathan_gemini3-activity-7399495977633660928-QaoI/"&gt;LinkedIn&lt;/a&gt;.</description></item><item><title>Commencement Addresses</title><link>https://www.saicharan.in/blog/2025/06/12/commencement-addresses</link><pubDate>Thu, 12 Jun 2025 17:47:44 +0000</pubDate><guid>https://www.saicharan.in/blog/2025/06/12/commencement-addresses</guid><description>&lt;p&gt;We somehow ended up watching a few commencement speeches last night. And, these stuck with me.&lt;/p&gt;
&lt;h4 id="federer-dartmouth-2024"&gt; &lt;a class="anchor" href="#federer-dartmouth-2024"&gt;Federer, Dartmouth 2024 &lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;On tennis lessons &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Effortless is a myth.&lt;/p&gt;
&lt;p&gt;It’s only a point.&lt;/p&gt;
&lt;p&gt;Life is bigger than the court.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="seinfeld-duke-2024"&gt; &lt;a class="anchor" href="#seinfeld-duke-2024"&gt;Seinfeld, Duke 2024 &lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;On not losing one&amp;rsquo;s sense of humor &lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We’re proud of what we should be embarrassed by, and embarrassed by what we should be proud of.&lt;/p&gt;
&lt;p&gt;Don’t think of having, think of becoming.&lt;/p&gt;
&lt;p&gt;Don’t lose your humor.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="matt-damon-mit-2015"&gt; &lt;a class="anchor" href="#matt-damon-mit-2015"&gt;Matt Damon, MIT 2015 &lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;On problem solving &lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Turn to the problems and engage.&lt;/p&gt;
&lt;p&gt;Keep listening.&lt;/p&gt;
&lt;p&gt;Not every problem has a high-tech solution.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="david-foster-wallace-kenyon-college-2005"&gt; &lt;a class="anchor" href="#david-foster-wallace-kenyon-college-2005"&gt;David Foster Wallace, Kenyon College 2005 &lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;On being &lt;em&gt;&amp;ldquo;well adjusted&amp;rdquo;&lt;/em&gt; &lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is water.&lt;/p&gt;
&lt;p&gt;This, I submit, is the freedom of a real education, of learning how to be well-adjusted. You get to consciously decide what has meaning and what doesn’t.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=pqWUuYTcG-o"&gt;https://www.youtube.com/watch?v=pqWUuYTcG-o&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=76QV2SrSqgo"&gt;https://www.youtube.com/watch?v=76QV2SrSqgo&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=DFNgoZ5-qAM"&gt;https://www.youtube.com/watch?v=DFNgoZ5-qAM&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://fs.blog/david-foster-wallace-this-is-water"&gt;https://fs.blog/david-foster-wallace-this-is-water&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>NFS on WD MyCloud</title><link>https://www.saicharan.in/blog/2025/01/16/nfs-on-wd-mycloud</link><pubDate>Thu, 16 Jan 2025 19:07:59 +0000</pubDate><guid>https://www.saicharan.in/blog/2025/01/16/nfs-on-wd-mycloud</guid><description>&lt;p&gt;Note: this note pertains to &lt;a href="https://support-en.wd.com/app/products/product-detailweb/p/126"&gt;WD MyCloud&lt;/a&gt; running firmware &lt;code&gt;v04.06.00-111&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By default, WD MyCloud running OS 3, firmware &lt;code&gt;v04.06.00-111&lt;/code&gt; does not show an option to share via NFS. However, after years of getting tired of the slow CIFS / SMB shares, I was curious if the device actually supported NFS shares, but just did not advertise it on the UI, manuals, and other documentation.&lt;/p&gt;
&lt;p&gt;Surprise, surprise, running &lt;code&gt;rpcinfo -p &amp;lt;nas-ip&amp;gt; | grep nfs&lt;/code&gt; revealed a bunch of RPC services (in particular &lt;code&gt;10003&lt;/code&gt;, aka NFS) running on the usual &lt;code&gt;2049&lt;/code&gt; port.&lt;/p&gt;
&lt;p&gt;A simple &lt;code&gt;mount -t nfs nas-ip:/share /mnt/mountPoint&lt;/code&gt; pointed at a version mismatch, that was fixed by adding &lt;code&gt;-o nfsvers=3&lt;/code&gt; to the mount command.&lt;/p&gt;
&lt;p&gt;However, I kept getting permission denied for eithe &lt;code&gt;ls&lt;/code&gt; or for &lt;code&gt;cd&lt;/code&gt; commands. Turns out the default setup of NFS on WD MyCloud wasn&amp;rsquo;t tuned to allow mounting the shares using the NFS protocol by clients. That probably explains why the device didn&amp;rsquo;t advertise this capability. But, it&amp;rsquo;s software, and should be fixable for the technically inclined. Time to roll up my sleeves :-)&lt;/p&gt;
&lt;p&gt;Turns out the default setup in &lt;code&gt;/etc/exports&lt;/code&gt; was the culprit:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/nfs *(rw,all_squash,sync,no_subtree_check,insecure,crossmnt,anonuid=65534,anongid=1000)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;anonuid&lt;/code&gt; of &lt;code&gt;65534&lt;/code&gt; (the uid of the &lt;code&gt;anonymous&lt;/code&gt; user) didn&amp;rsquo;t match the &lt;code&gt;uid&lt;/code&gt; of the user I was running as on the client machine. Technically, per the &lt;a href="https://www.man7.org/linux/man-pages/man5/exports.5.html"&gt;man page&lt;/a&gt;, this shouldn&amp;rsquo;t have mattered given the &lt;code&gt;all_squash&lt;/code&gt; option in &lt;code&gt;/etc/exports&lt;/code&gt; should translate to &lt;code&gt;anonymous&lt;/code&gt; user. But&amp;hellip;&lt;/p&gt;
&lt;p&gt;In any case, there are two ways around this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove &lt;code&gt;anonuid=65534,anongid=1000&lt;/code&gt;, and let NFS map the permissions to the current user, or&lt;/li&gt;
&lt;li&gt;Adjust the &lt;code&gt;anonuid&lt;/code&gt;, and &lt;code&gt;anongid&lt;/code&gt; to match the &amp;ldquo;current&amp;rdquo; user (assuming the user uid / gid matches in all the places access is intended).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;is trivial, and works well.&lt;/li&gt;
&lt;li&gt;is a bit a more work:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;On the client, figure out the &lt;code&gt;uid&lt;/code&gt; and &lt;code&gt;gid&lt;/code&gt; of the current user:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As the user you wish to access the share, run &lt;code&gt;id&lt;/code&gt;, and note the uid and gid numbers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On NFS server:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check if &lt;code&gt;/etc/passwd&lt;/code&gt; shows any user and group with that same uid, or gid numbers from the client&lt;/li&gt;
&lt;li&gt;If no such group exists, run &lt;code&gt;groupadd &amp;lt;group-name&amp;gt; -g &amp;lt;gid-from-client&amp;gt;&lt;/code&gt;, else skip this step&lt;/li&gt;
&lt;li&gt;If no such user exits, run &lt;code&gt;useradd &amp;lt;user&amp;gt; -u &amp;lt;uid-from-client&amp;gt; -g &amp;lt;gid-from-client&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Update the exports line in &lt;code&gt;/etc/exports&lt;/code&gt;, setting &lt;code&gt;anonuid=uid-from-client&lt;/code&gt;, and &lt;code&gt;anongid=gid-from-client&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Restart NFS server: &lt;code&gt;service nfs-kernel-server restart&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once again, on the client:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mount the share: &lt;code&gt;mount -t nfs nfs.server:/share /mnt/mountPoint -o nfsvers=3&lt;/code&gt;, or equivalently in &lt;code&gt;/etc/fstab&lt;/code&gt;: &lt;code&gt;nfs.server:/share /mnt/mountPoint nfs nfsvers=3 0 0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s wonderful how &amp;lsquo;hackable&amp;rsquo; the Unix / Linux based systems are. Western Digital &lt;a href="https://support-en.wd.com/app/answers/detailweb/a_id/32168/h/p2"&gt;announced&lt;/a&gt; an end-of-life for my device. However, this &amp;lsquo;hack&amp;rsquo; has prolonged the life of the device, keeping it from the dump &amp;ndash; and it works just great!&lt;/p&gt;
&lt;p&gt;And, thanks to NFS, even more performant than before!&lt;/p&gt;
</description></item><item><title>On Debugging</title><link>https://www.saicharan.in/blog/2025/01/13/quote-on-debugging</link><pubDate>Mon, 13 Jan 2025 21:35:15 +0000</pubDate><guid>https://www.saicharan.in/blog/2025/01/13/quote-on-debugging</guid><description>&lt;p&gt;David A. Wheeler &lt;a href="https://dwheeler.com/essays/debugging-agans.html"&gt;writes&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Since the whole book revolves around the nine rules, it might help to understand the book by skimming the rules and their sub-rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Understand the system&lt;/li&gt;
&lt;li&gt;Make it fail&lt;/li&gt;
&lt;li&gt;Quit thinking and look&lt;/li&gt;
&lt;li&gt;Divide and conquer&lt;/li&gt;
&lt;li&gt;Change one thing at a time&lt;/li&gt;
&lt;li&gt;Keep an audit trail&lt;/li&gt;
&lt;li&gt;Check the plug&lt;/li&gt;
&lt;li&gt;Get a fresh view&lt;/li&gt;
&lt;li&gt;If you didn&amp;rsquo;t fix it, it ain&amp;rsquo;t fixed&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;lsquo;Quit thinking and look&amp;rsquo;&lt;/em&gt;, &lt;em&gt;&amp;lsquo;Check the plug&amp;rsquo;&lt;/em&gt;, and &lt;em&gt;&amp;lsquo;If you didn&amp;rsquo;t fix it, it ain&amp;rsquo;t fixed&amp;rsquo;&lt;/em&gt; are true, and absolute zingers!&lt;/p&gt;
</description></item><item><title>Experiment Running LLMs Locally</title><link>https://www.saicharan.in/blog/2024/12/31/experiment-running-llms-locally</link><pubDate>Tue, 31 Dec 2024 15:13:43 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/12/31/experiment-running-llms-locally</guid><description>&lt;p&gt;Note: Ollama is really easy to get started with.&lt;/p&gt;
&lt;h4 id="llamacpp"&gt; &lt;a class="anchor" href="#llamacpp"&gt;llama.cpp &lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git clone --depth 1 https://github.com/ggerganov/llama.cpp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt install nvidia-cuda-toolkit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt install gcc-12 g++12&lt;/code&gt; (GCC 13+ isn&amp;rsquo;t supported)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cmake -B build -DGGML_CUDA=ON -DCMAKE_CUDA_CXX_COMPILER=/usr/bin/g++-12 -DCMAKE_CUDA_HOST_COMPILER=/usr/bin/g++-12&lt;/code&gt; (needed to explicitly set the compilers)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cmake --build build --config Release&lt;/code&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;llama-server&lt;/code&gt; by default only processes a single request, use &lt;code&gt;--parallel N&lt;/code&gt; to enable processing concurrent requests.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="ollama"&gt; &lt;a class="anchor" href="#ollama"&gt;ollama &lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;curl -fsSL https://ollama.com/install.sh | sh&lt;/code&gt;&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;
&lt;ul&gt;
&lt;li&gt;As of 2024-12-30, this also runs ollma (i.e., there&amp;rsquo;s no need to separately run &lt;code&gt;ollama serve&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;ollama run llama3&lt;/code&gt;, and this opens a chat session.&lt;/li&gt;
&lt;li&gt;This does not seem to remember stuff though, like my name. Hmm :think:&lt;/li&gt;
&lt;li&gt;Running Ollama behind a a reverse proxy (like Nginx) requires setting &lt;code&gt;proxy_buffering off;&lt;/code&gt;&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Caveat using JavaScript to stream using the &lt;code&gt;fetch&lt;/code&gt; API: Safari does not support using &lt;code&gt;response.body&lt;/code&gt; as a readable bytestream&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;, and instead this needs a long-form code to deal with this&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;By default, Ollama only allows requests from &lt;code&gt;localhost&lt;/code&gt;. To allow seving behind a rever sproxy (like Nginx), set &lt;code&gt;Environment=&amp;quot;OLLAMA_ORIGINS=*&amp;quot;&lt;/code&gt; in the &lt;code&gt;systemd&lt;/code&gt; configuration file (&lt;code&gt;/etc/systemd/system/ollama.serice&lt;/code&gt; by default on Ubuntu 24.04 LTS).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://github.com/ggerganov/llama.cpp/blob/master/docs/build.md#cuda"&gt;https://github.com/ggerganov/llama.cpp/blob/master/docs/build.md#cuda&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://github.com/ollama/ollama/blob/main/docs/linux.md#linux"&gt;https://github.com/ollama/ollama/blob/main/docs/linux.md#linux&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/a/77040347/162471"&gt;https://stackoverflow.com/a/77040347/162471&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Response/body#browser_compatibility"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Response/body#browser_compatibility&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/a/77040347/162471"&gt;https://stackoverflow.com/a/77040347/162471&lt;/a&gt;&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>Changing tty Console's Screen Resolution on Ubuntu</title><link>https://www.saicharan.in/blog/2024/12/30/tty-console-resolution</link><pubDate>Mon, 30 Dec 2024 09:46:16 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/12/30/tty-console-resolution</guid><description>&lt;p&gt;Note: these notes apply to Ubuntu 24.04 LTS.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reboot to get to the GRUB screen.&lt;/li&gt;
&lt;li&gt;At the GRUB screen, type &lt;code&gt;c&lt;/code&gt; to enter the &lt;code&gt;grub &amp;gt; &lt;/code&gt; shell.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;videoinfo&lt;/code&gt;, and identify the particular screen resolution you would like to use.
&lt;ul&gt;
&lt;li&gt;In this case, say we want to use &lt;code&gt;2560x1440&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reboot into Linux.&lt;/li&gt;
&lt;li&gt;Edit &lt;code&gt;/etc/default/grub&lt;/code&gt; to add / update the following lines
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GRUB_CMDLINE_LINUX_DEFAULT='quiet nosplash nomodeset'&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;in my case, I appended &lt;code&gt;'nomodeset'&lt;/code&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; to &lt;code&gt;'quiet splash'&lt;/code&gt; which was already present on this line; ensure the content is inside a single quote).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GRUB_GFXPAYLOAD=2560x1440&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GRUB_GFXPLAYLOAD_LINUX=keep&lt;/code&gt; (note: no quotes around &amp;lsquo;keep&amp;rsquo; here)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;'sudo update-grub'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;'sudo reboot now'&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://ubuntuforums.org/showthread.php?t=2411985&amp;amp;p=13836125#post13836125"&gt;https://ubuntuforums.org/showthread.php?t=2411985&amp;amp;p=13836125#post13836125&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>Mail-in-a-Box on Oracle Cloud (aarch64)</title><link>https://www.saicharan.in/blog/2024/12/27/miab-oracle-cloud</link><pubDate>Fri, 27 Dec 2024 22:22:16 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/12/27/miab-oracle-cloud</guid><description>&lt;p&gt;Notes for installing MiaB for a subdomain (not the root domain) on OCI&amp;rsquo;s aarch64 Ampere shape VMs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Turn up a VM, note it&amp;rsquo;s Public IP&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pick an Ubuntu LTS version listed at &lt;a href="https://mailinabox.email/"&gt;https://mailinabox.email/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The tol only support every other LTS version, see &lt;a href="https://discourse.mailinabox.email/t/ubuntu-24-04-support/12223"&gt;this&lt;/a&gt; support thread&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set up NS records for&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create Glue records (DNS type A for ns1.box.sub.domain.ext and ns2.box.sub.domain.ext pointing at the VM&amp;rsquo;s public IP from above)&lt;/li&gt;
&lt;li&gt;Create NS records for sub.domain.ext and box.sub.domain.ext pointing at ns1.box.sub.domain.ext, and ns2.box.sub.domain.ext&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Login to the VM, and run &lt;code&gt;curl -s https://mailinabox.email/setup.sh | sudo -E bash&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Provision SSL / TLS certificates at &lt;a href="https://box.sub.domain.ext/admin#tls"&gt;https://box.sub.domain.ext/admin#tls&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Setup a catch-all email for the domain at &lt;a href="https://box.sub.domain.ext/admin#aliases"&gt;https://box.sub.domain.ext/admin#aliases&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Setup 2-factor auth for the domain at &lt;a href="https://box.sub.domain.ext/admin#mfa"&gt;https://box.sub.domain.ext/admin#mfa&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[Optional] Setup a secondary DNS&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; using &lt;a href="https://dns.he.net"&gt;he.net&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;ns1.he.net ns2.he.net ns3.he.net ns4.he.net ns5.he.net xfr:216.218.133.2 xfr:2001:470:600::2&lt;/code&gt; into the &lt;code&gt;Hostname&lt;/code&gt; box in the &lt;code&gt;Using a secondary nameserver&lt;/code&gt; section at &lt;a href="https://box.sub.domain.ext/admin#custom_dns"&gt;https://box.sub.domain.ext/admin#custom_dns&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;On the domain&amp;rsquo;s primary registrar, add DNS entries of type &lt;code&gt;NS&lt;/code&gt; for &lt;code&gt;sub.domain.ext&lt;/code&gt; pointing at &lt;code&gt;ns1.he.net&lt;/code&gt;, &lt;code&gt;ns2.he.net&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Go to &lt;a href="https://dns.he.net"&gt;https://dns.he.net&lt;/a&gt; &amp;gt; Zones &amp;gt; Add a new slave&lt;/li&gt;
&lt;li&gt;Enter &lt;code&gt;sub.domain.ext&lt;/code&gt; for the domain, and &lt;code&gt;ns1.box.sub.domain.ext&lt;/code&gt; as master NS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://discourse.mailinabox.email/t/secondary-ns-on-hurricane-electric/6405/6"&gt;https://discourse.mailinabox.email/t/secondary-ns-on-hurricane-electric/6405/6&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>Seeing A Short Distance</title><link>https://www.saicharan.in/blog/2024/11/08/quote-seeing-a-short-distance</link><pubDate>Fri, 08 Nov 2024 17:37:38 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/11/08/quote-seeing-a-short-distance</guid><description>&lt;blockquote&gt;
&lt;p&gt;We can only see a short distance ahead, but we can see plenty there that needs to be done.&lt;/p&gt;
&lt;/blockquote&gt;— Alan Turing, as seen at &lt;a href="https://mlajtos.mu/posts/new-kind-of-paper-5"&gt;mlajtos.mu&lt;/a&gt;.</description></item><item><title>The Reasonable Person Principle</title><link>https://www.saicharan.in/blog/2024/11/05/quote-the-reasonable-person-principle</link><pubDate>Tue, 05 Nov 2024 17:32:23 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/11/05/quote-the-reasonable-person-principle</guid><description>&lt;blockquote&gt;
&lt;p&gt;Reasonable Person Principle:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Everyone will be reasonable.&lt;/li&gt;
&lt;li&gt;Everyone expects everyone else to be reasonable.&lt;/li&gt;
&lt;li&gt;No one is special.&lt;/li&gt;
&lt;li&gt;Do not be offended if someone suggests you are not being reasonable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;hellip;And it leaves some room for difference of opinion.&lt;/p&gt;
— CMU&amp;rsquo;s &lt;a href="https://www.cs.cmu.edu/~weigand/staff/"&gt;School of CS, Support Staff&lt;/a&gt;.</description></item><item><title>John Williams on Music</title><link>https://www.saicharan.in/blog/2024/11/01/quote-john-williams-music</link><pubDate>Fri, 01 Nov 2024 21:20:26 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/11/01/quote-john-williams-music</guid><description>&lt;blockquote&gt;
&lt;p&gt;I was filled with the love of music, and the pleasure if doing it with great musicians.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Music for musicians is like breathing. It supports us, sustains us, gives us energy.&lt;/p&gt;
&lt;p&gt;Music is enough for a lifetime, but a lifetime is not enough for music.&lt;/p&gt;
— John Williams, in &lt;a href="https://ondisneyplus.disney.com/movie/music-by-john-williams"&gt;Music by John Williams&lt;/a&gt;</description></item><item><title>Acting with Intent</title><link>https://www.saicharan.in/blog/2024/10/19/quote-acting-with-intent</link><pubDate>Sat, 19 Oct 2024 16:57:22 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/10/19/quote-acting-with-intent</guid><description>&lt;blockquote&gt;
&lt;p&gt;There is space, however small, between the thoughts. And in that space, if we are patient, we can decide how to respond rather than being dragged along by every impulse or fear. This is not about control in the traditional sense, but about clarity. To act, not from reflex, but from intent.&lt;/p&gt;
&lt;/blockquote&gt;— Stormrider, at &lt;a href="https://billwear.github.io/art-of-attention.html"&gt;billwear&lt;/a&gt;.</description></item><item><title>The Gervais Principle</title><link>https://www.saicharan.in/blog/2024/10/19/quote-the-gervais-principle</link><pubDate>Sat, 19 Oct 2024 21:23:10 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/10/19/quote-the-gervais-principle</guid><description>&lt;blockquote&gt;
&lt;p&gt;The Office is not a random series of cynical gags aimed at momentarily alleviating the existential despair of low-level grunts. It is a fully realized theory of management that falsifies 83.8% of the business section of the bookstore.&lt;/p&gt;
&lt;/blockquote&gt;— Venkatesh G. Rao, writing at &lt;a href="https://www.ribbonfarm.com/2009/10/07/the-gervais-principle-or-the-office-according-to-the-office/"&gt;ribbonfarm.com&lt;/a&gt;.</description></item><item><title>Self Hosting Ghost with SQLite3</title><link>https://www.saicharan.in/blog/2024/10/16/self-hosting-ghost-with-sqlite3</link><pubDate>Wed, 16 Oct 2024 20:42:05 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/10/16/self-hosting-ghost-with-sqlite3</guid><description>&lt;p&gt;Note to self on setting up Ghost with SQLite3 in production (Ghost only officially recommends and supports MySQL in production, so figuring this out was a bit of an effort).&lt;/p&gt;
&lt;h3 id="environment-setup"&gt; &lt;a class="anchor" href="#environment-setup"&gt;Environment Setup &lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Install the latest required NodeJS version (see &lt;a href="https://ghost.org/docs/faq/node-versions/"&gt;https://ghost.org/docs/faq/node-versions/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Install nginx: &lt;code&gt;sudo apt install nginx -y&lt;/code&gt; (apt, assuming a Debian-based Linux distribution)&lt;/li&gt;
&lt;li&gt;Install ghost-cli: &lt;code&gt;sudo npm install ghost-cli@latest -g&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="setup-commands"&gt; &lt;a class="anchor" href="#setup-commands"&gt;Setup Commands &lt;/a&gt;&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ mkdir /var/www/my-site
$ sudo chown &amp;lt;user&amp;gt;:&amp;lt;user&amp;gt; /var/www/my-site
$ sudo chmod 755 /var/www/my-site
$ cd /var/www/my-site
$ ghost install --db sqlite3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Other helpful ghost commands&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ ghost config [get | set] &amp;lt;key&amp;gt;
$ ghost backup
$ ghost restart
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Sir C.A.R. Hoare on Software Design</title><link>https://www.saicharan.in/blog/2024/06/27/quote-two-ways-of-constructing-software-design</link><pubDate>Thu, 27 Jun 2024 19:40:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2024/06/27/quote-two-ways-of-constructing-software-design</guid><description>&lt;blockquote&gt;
&lt;p&gt;There are two ways of constructing a software design; one way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.&lt;/p&gt;
&lt;/blockquote&gt;— Sir Antony Hoare&amp;rsquo;s, Computer History Museum &lt;a href="https://computerhistory.org/profile/sir-antony-hoare/"&gt;citation&lt;/a&gt;.</description></item><item><title>DIY Water Leak Sensor with ESP8266 NodeMCU and Homebridge Server</title><link>https://www.saicharan.in/blog/2023/01/22/diy-water-leak-sensor-with-esp8266</link><pubDate>Sun, 22 Jan 2023 18:05:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2023/01/22/diy-water-leak-sensor-with-esp8266</guid><description>&lt;p&gt;A leak at home got me looking at water level sensors, but Arlo&amp;rsquo;s recent &lt;a href="https://9to5google.com/2023/01/02/arlo-end-of-life-policy/"&gt;annoucement&lt;/a&gt; EOL&amp;rsquo;ing camera support pushed me over the edge into DIY IoT devices.&lt;/p&gt;
&lt;p&gt;Luckily, in a really simple form, a water leak sensor simply uses water to close the circuit; so a closed circuit indicates water (or some other conductor!) was detected between the leads. Note that this set up cannot be used to detect leak of distilled water, because, well, distilled water cannot conduct electricity.&lt;/p&gt;
&lt;p&gt;A brief search for a low-cost MCU with ADC and WiFi support turned up the ESP8266 family which costs ~$3 as of this writing. Awesome!&lt;/p&gt;
&lt;p&gt;Specifically, I picked up the &amp;lsquo;ESP8266 ESP-12 D1 Mini NodeMCU Lua WeMos D1 Mini WIFI 4M Bytes Module&amp;rsquo;. I powered the MCU via a micro-USB. Solder 24-gauge wires to the 3.3V and the ADC pins on the chip, and let the open leads on the other ends of the wire lay on the floor where I&amp;rsquo;d like to detect leaks. And, done &amp;ndash; that&amp;rsquo;s the hardware set up.&lt;/p&gt;
&lt;p&gt;Next up, software. Programming for the ESP8266 is pretty straight forward, given the really awesome set of libraries for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connecting the MCU to WiFi&lt;/li&gt;
&lt;li&gt;Running a basic web server on the MCU&lt;/li&gt;
&lt;li&gt;mDNS support so new devices can be auto-discovered&lt;/li&gt;
&lt;li&gt;And, of course, to read the sensor values via ADC&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next bit is to integrate with HomeKit (using &lt;a href="https://homebridge.io"&gt;Homebridge&lt;/a&gt;). Fortunately, again, I stumbled upon the very simple, and readable &lt;a href="https://github.com/dauden/homebridge-nodeMCU"&gt;dauden/homebridge-nodeMCU&lt;/a&gt; repository that I tweaked a bit to include mDNS-based device discovery support. My adaptation of this Homebridge plugin is &lt;a href="https://github.com/scharan/homebridge-nodeMCU"&gt;here&lt;/a&gt;, and also includes the NodeMCU code.&lt;/p&gt;
&lt;p&gt;Easy peasy!&lt;/p&gt;
&lt;p&gt;Future:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&amp;rsquo;m also experimenting running this set up with 2x1.5v AA batteries; the Blink wireless camera has demonstrated that even with a WiFi device onboard, the set up can be made to last ~2 years, but let&amp;rsquo;s see how efficient this particular set up is!&lt;/li&gt;
&lt;li&gt;One can of course 3D-print enclosures for this setup and make it appropriately water proof, perhaps? I&amp;rsquo;ll include 3D-print model files, if I get that far!&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Terence Tao on Work</title><link>https://www.saicharan.in/blog/2021/08/30/quote-terence-tao-work-hard</link><pubDate>Mon, 30 Aug 2021 20:28:28 +0000</pubDate><guid>https://www.saicharan.in/blog/2021/08/30/quote-terence-tao-work-hard</guid><description>&lt;blockquote&gt;
&lt;p&gt;Relying on intelligence alone to pull things off at the last minute may work for a while, but, generally speaking, at the graduate level or higher it doesn’t.&lt;/p&gt;
&lt;/blockquote&gt;— Terence Tao&amp;rsquo;s &lt;a href="https://terrytao.wordpress.com/career-advice/work-hard/"&gt;career advice&lt;/a&gt;.</description></item><item><title>Automating Let's Encrypt Certs for DD-WRT with acme.sh</title><link>https://www.saicharan.in/blog/2021/01/17/automate-letsencrypt-certs-dd-wrt-acme-sh</link><pubDate>Sun, 17 Jan 2021 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2021/01/17/automate-letsencrypt-certs-dd-wrt-acme-sh</guid><description>&lt;p&gt;Following up on previous notes on setting up &lt;a href="https://www.saicharan.in/blog/2021/01/05/letsencrypt-renew-certs-private-network-dns/"&gt;Let&amp;rsquo;s Encrypt for private networks&lt;/a&gt; and &lt;a href="https://www.saicharan.in/blog/2021/01/05/letsencrypt-ssl-certs-dd-wrt/"&gt;SSL for DD-WRT routers&lt;/a&gt;, here&amp;rsquo;s notes on automating renewal of Let&amp;rsquo;s Encrypt certificates using &lt;a href="https://acme.sh"&gt;acme.sh&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I use Hurricane Electric&amp;rsquo;s free DNS service for delegating DNS management for the the private subdomains &amp;ndash; DNS resolution is handled externally, but certificates are provisioned on the private network. You can find other free DNS providers on the Let&amp;rsquo;s Encrypt &lt;a href="https://community.letsencrypt.org/t/dns-providers-who-easily-integrate-with-lets-encrypt-dns-validation/86438"&gt;community page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t want to make your private subdomain public, you can create a &lt;code&gt;dummy.domain.ext&lt;/code&gt;, for example, and fetch wildcard certificates instead. If you are willing to open port 53 on your router and port forward, here&amp;rsquo;s &lt;a href="https://www.saicharan.in/blog/2021/01/05/letsencrypt-renew-certs-private-network-dns/"&gt;another alternative&lt;/a&gt;. Open to more suggestions, please post them in the comments.&lt;/p&gt;
&lt;h3 id="setup-instructions"&gt; &lt;a class="anchor" href="#setup-instructions"&gt;Setup Instructions &lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Prerequistites are a DD-WRT router with exeternal USB storage support. My notes on the setup are &lt;a href="https://www.saicharan.in/blog/2020/06/24/managing-your-internet-of/#choosing-a-version-of-dd-wrt"&gt;here&lt;/a&gt; and &lt;a href="https://www.saicharan.in/blog/2021/01/05/letsencrypt-ssl-certs-dd-wrt/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;First, delegate your subdomain&amp;rsquo;s &lt;em&gt;public&lt;/em&gt; DNS resolution to &lt;a href="https://dns.he.net"&gt;https://dns.he.net&lt;/a&gt; by setting up &lt;code&gt;NS&lt;/code&gt; records for &lt;code&gt;subdomain.domain.ext&lt;/code&gt; to point to &lt;code&gt;ns[1-5].he.net&lt;/code&gt;, then add the subdomain to &lt;a href="https://dns.he.net"&gt;https://dns.he.net&lt;/a&gt; via &amp;lsquo;Add a new domain&amp;rsquo; page on the &amp;lsquo;Zone Functions&amp;rsquo; menu.&lt;/li&gt;
&lt;li&gt;Then, download &lt;a href="https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh"&gt;https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh&lt;/a&gt;, give it execute permissions: &lt;code&gt;chmod +x ./acme.sh&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Next, run the following by adjusting the variables as appropriate.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;export HE_Username=&amp;#34;&amp;#34;
export HE_Password=&amp;#34;&amp;#34;
&lt;p&gt;./acme.sh &amp;ndash;install &lt;br&gt;
&amp;ndash;home /jffs/etc/acme.sh/ &lt;br&gt;
&amp;ndash;config-home /jffs/etc/acme.sh/data &lt;br&gt;
&amp;ndash;cert-home /jffs/etc/acme.sh/certs &lt;br&gt;
&amp;ndash;accountemail &amp;quot;email@domain.ext&amp;quot; &lt;br&gt;
&amp;ndash;useragent &amp;quot;DD-WRT acme.sh&amp;quot; &amp;ndash;force
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;/p&gt;
&lt;li&gt;Then copy the corresponding &lt;code&gt;dns_&amp;lt;provider&amp;gt;.sh&lt;/code&gt; from &lt;a href="https://github.com/acmesh-official/acme.sh/tree/master/dnsapi"&gt;https://github.com/acmesh-official/acme.sh/tree/master/dnsapi&lt;/a&gt; to &lt;code&gt;/jffs/etc/acme.sh/dnsapi/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Test issuing a new cert:
&lt;code&gt;# /jffs/etc/acme.sh/acme.sh --issue --dns dns_he -d subdomain.domain.ext --config-home /jffs/etc/acme.sh/data 2&amp;gt;&amp;amp;1 &amp;gt;&amp;gt; /jffs/etc/acme.sh/logs/log.txt --staging --force&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Revoke the test cert
&lt;code&gt;# /jffs/etc/acme.sh/acme.sh --revoke -d subdomain.domain.ext --revoke-reason 4 --config-home /jffs/etc/acme.sh/data/ --staging&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Issue a production certificate by running the issue command above without &lt;code&gt;--staging&lt;/code&gt; option.&lt;/li&gt;
&lt;li&gt;Setup cron. Remember to prefix the cron command with &lt;code&gt;root&lt;/code&gt; as pointed out &lt;a href="https://wiki.dd-wrt.com/wiki/index.php/CRON#Cron_Job_Instruction:_Locations"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Every day at 3 AM: https://crontab.guru/#0_3_*_*_*
0 3 * * * root /jffs/etc/acme.sh/acme.sh --renew --dns dns_he -d subdomain.domain.ext --config-home /jffs/etc/acme.sh/data &amp;gt;&amp;gt; /jffs/etc/acme.sh/logs/log.txt # --staging --force
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/acmesh-official/acme.sh/wiki/How-to-install"&gt;https://github.com/acmesh-official/acme.sh/wiki/How-to-install&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.letsencrypt.org/t/dns-providers-who-easily-integrate-with-lets-encrypt-dns-validation/86438"&gt;https://community.letsencrypt.org/t/dns-providers-who-easily-integrate-with-lets-encrypt-dns-validation/86438&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>The Best Test of Truth...</title><link>https://www.saicharan.in/blog/2021/01/12/best-test-of-truth</link><pubDate>Tue, 12 Jan 2021 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2021/01/12/best-test-of-truth</guid><description>&lt;p&gt;Reading Stratechery&amp;rsquo;s &lt;a href="https://stratechery.com/2019/tech-and-liberty/"&gt;Tech and Liberty&lt;/a&gt;, &amp;lsquo;The Marketplace of Ideas&amp;rsquo; section, I see this quote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The theory of our Constitution is “that the best test of truth is the power of the thought to get itself accepted in the competition of the market,” Abrams v. United States, 250 U.S. 616, 630, 40 S.Ct. 17, 63 L.Ed. 1173 (1919) (Holmes, J., dissenting).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And, the first thing that jumps at me is the implication that &lt;em&gt;Truth&lt;/em&gt;, by this interpretation, &lt;em&gt;is a point-in-time artifact&lt;/em&gt;. What&amp;rsquo;s marketable today is different from yesterday, and arguably, will change tomorrow; the need of each hour would vary, even if history repeats. I realize Justice Holmes is focused on the judgement at hand and this statement is completely accurate in that context.&lt;/p&gt;
&lt;p&gt;This may be experience bias, but makes me wonder what would fall into the &lt;em&gt;Vedic&lt;/em&gt; interpretation of truth &amp;ndash; eternal, changeless, even if interpreted differently by experts: Ekam Sat, Viprah Bahudah Vadanti/एकं सद्विप्रा बहुधा वदन्ति - &lt;a href="https://en.wikisource.org/wiki/The_Rig_Veda/Mandala_1/Hymn_164"&gt;Rig Veda 1:164:46&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Or, may be I interpreted the above ancient statement as referring to Truth? This &lt;em&gt;is&lt;/em&gt; open to interpretation: from the context of Hymn 164, the physical allusion is to a deity, but an overload of the word &lt;em&gt;Sat&lt;/em&gt; is Truth, and therefore, the corresponding interpretation would be one of &lt;em&gt;Absolute Truth&lt;/em&gt;, if I may. This is the interpretation I&amp;rsquo;ve grown up with.&lt;/p&gt;
&lt;p&gt;What is Truth, to you?&lt;/p&gt;
</description></item><item><title>Let's Encrypt SSL Certificates for DD-WRT</title><link>https://www.saicharan.in/blog/2021/01/05/letsencrypt-ssl-certs-dd-wrt</link><pubDate>Tue, 05 Jan 2021 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2021/01/05/letsencrypt-ssl-certs-dd-wrt</guid><description>&lt;p&gt;Note to self on setting up Let&amp;rsquo;s Encrypt SSL certificates for DD-WRT.&lt;/p&gt;
&lt;p&gt;Prerequisites: a router with DD-WRT with a USB port (to mount external USB drive via jffs), an external USB drive, and a domain to assign to your router. My notes on the router setup are &lt;a href="https://www.saicharan.in/blog/2020/06/24/managing-your-internet-of/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://certbot.eff.org/docs/using.html#nginx"&gt;Create&lt;/a&gt; or &lt;a href="https://certbot.eff.org/docs/using.html#renewing-certificates"&gt;renew&lt;/a&gt; the necessary certificate.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openssl rsa -in privkey.pem -out key.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scp *.pem root@router:/jffs/etc/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Router settings &amp;gt; Administration &amp;gt; Web Access &amp;gt; Protocol &amp;gt; HTTPS (check this box)&lt;/li&gt;
&lt;li&gt;Router settings &amp;gt; Administration &amp;gt; Remote Access &amp;gt; Use HTTPS (check this box), and set Web GUI Port to &lt;code&gt;443&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save, Apply Settings, and Reboot Router (for good measure).&lt;/li&gt;
&lt;li&gt;Copy to &lt;code&gt;/jffs/etc/&lt;/code&gt; and run this &lt;a href="https://gist.githubusercontent.com/alexandrusavin/69b26846d6593d6f217219b5bd8882c4/raw/a832c0b89cf8e975acda14f46355e93a676a2893/binds_on_mount.sh"&gt;script&lt;/a&gt;, following instructions from this &lt;a href="https://gist.github.com/alexandrusavin/69b26846d6593d6f217219b5bd8882c4#file-letsencrypt-ddwrt-md"&gt;gist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Effectively, this mount-binds the corresponding &lt;code&gt;cert.pem&lt;/code&gt;, and &lt;code&gt;key.pem&lt;/code&gt; into &lt;code&gt;/etc/*.pem&lt;/code&gt; followed by &lt;code&gt;servicestart httpd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Worked like a charm!&lt;/p&gt;
&lt;h3 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://forum.dd-wrt.com/phpBB2/viewtopic.php?p=1194082#1194082"&gt;https://forum.dd-wrt.com/phpBB2/viewtopic.php?p=1194082#1194082&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/alexandrusavin/69b26846d6593d6f217219b5bd8882c4"&gt;https://gist.github.com/alexandrusavin/69b26846d6593d6f217219b5bd8882c4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Renewing Let's Encrypt SSL Certificates for Private Networks using DNS Challenge</title><link>https://www.saicharan.in/blog/2021/01/05/letsencrypt-renew-certs-private-network-dns</link><pubDate>Tue, 05 Jan 2021 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2021/01/05/letsencrypt-renew-certs-private-network-dns</guid><description>&lt;p&gt;Note to self on setup for auto-renewing Let&amp;rsquo;s Encrypt SSL certificates from an (almost) private network.&lt;/p&gt;
&lt;h3 id="the-usual-rant"&gt; &lt;a class="anchor" href="#the-usual-rant"&gt;The Usual Rant &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This would&amp;rsquo;ve been really simple if &lt;a href="//domains.google.com"&gt;Google Domains&lt;/a&gt; provided an API interface to add/update/remove DNS TXT records &amp;ndash; and would be fully workable from a fully private network, I could (or maybe should?) use a DNS provider with an API and be done, but this setup is worth documenting for myself. For DNS providers with APIs to change DNS records, Certbot&amp;rsquo;s &lt;a href="https://certbot.eff.org/docs/using.html#dns-plugins"&gt;DNS plugins&lt;/a&gt; are, IMO, easy ways to renew certs. You could also go manual with your own auth, cleanup, and deploy hooks&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;. Anyway, here goes.&lt;/p&gt;
&lt;h3 id="the-idea"&gt; &lt;a class="anchor" href="#the-idea"&gt;The Idea &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The idea behind this setup is that of the &lt;a href="https://github.com/siilike/certbot-dns-standalone#standalone-dns-authenticator-plugin-for-certbot"&gt;Standalone DNS Authenticator Plugin for Certbot&lt;/a&gt; &amp;ndash; I just could not get it to work&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; out of the box even with port forwarding enabled, so I improvise by replicating the setup. Basically: send DNS resolution requests off to a DNS that you can update really quick (or even better, automate). This is achieved by inserting an &lt;code&gt;NS&lt;/code&gt; record for the subdomain in question and pointing &lt;code&gt;_acme-challenge.subdomain&lt;/code&gt; to a dummy.subdomain.domain.ext &lt;code&gt;CNAME&lt;/code&gt; that sends off resolvers to your new DNS, where you work your magic.&lt;/p&gt;
&lt;h3 id="prerequisites"&gt; &lt;a class="anchor" href="#prerequisites"&gt;Prerequisites: &lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A DNS provider with no API support to add/update/remove DNS &lt;code&gt;TXT&lt;/code&gt; records.&lt;/li&gt;
&lt;li&gt;A local/remote instance of AdGuardHome v0.105.0&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt; or later &amp;ndash; this nifty application has a &lt;a href="https://github.com/AdguardTeam/AdGuardHome/blob/master/openapi/"&gt;REST API&lt;/a&gt; with a &lt;a href="https://github.com/AdguardTeam/AdGuardHome/blob/master/openapi/openapi.yaml"&gt;swagger spec&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;An internet router that allows port forwarding (forward 53 to your local server hosting AdGuardHome)&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt; &lt;sup id="fnref1:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;Local server with certbot on a private network.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="the-setup"&gt; &lt;a class="anchor" href="#the-setup"&gt;The Setup &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For each subdomain of domain.ext, set up these two DNS entries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;subdomain NS ns.domain.ext&lt;/li&gt;
&lt;li&gt;_acme-challenge.subdomain CNAME dummy.subdomain.domain.ext&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Pro tip: always use &amp;ndash;staging servers else you will run up against the really low (~5 failures/hour) &lt;a href="https://letsencrypt.org/docs/rate-limits/"&gt;rate limits&lt;/a&gt; for production servers.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next, run the certbot command to renew certificate manually: &lt;code&gt;# certbot --manual --preferred-challenges dns certonly -d subdomain.domain.ext --verbose --debug-challenge --staging&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Go to AdGuardHome &amp;gt; Filters &amp;gt; Custom Filtering Rules and add appropriate entries
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;||subdomain.domain.ext^$dnsrewrite=NOERROR;A;W.X.Y.Z&lt;/code&gt; (private IP is acceptable)&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;||_acme-challenge.subdomain.domain.ext^$dnsrewrite=NOERROR;TXT;challenge-txt&lt;/code&gt;, where challenge-txt is from the output of &lt;code&gt;certbot&lt;/code&gt; command above.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Continue the command above, your certificates from staging Let&amp;rsquo;s Encrypt&amp;rsquo;s servers would be ready.&lt;/li&gt;
&lt;li&gt;Revoke these test certs with &lt;code&gt;# certbot revoke --cert-path /etc/letsencrypt/live/subdomain.domain.ext/cert.pem [--staging]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Repeat the &lt;code&gt;certbot&lt;/code&gt; command without the &lt;code&gt;--staging&lt;/code&gt; flag.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Best part &amp;ndash; all of this can be automated.&lt;sup id="fnref2:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id="references--notes"&gt; &lt;a class="anchor" href="#references--notes"&gt;References &amp;amp; Notes &lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://digwebinterface.com/?hostnames=_acme-challenge.saibox.saicharan.in&amp;amp;type=A&amp;amp;showcommand=on&amp;amp;colorize=on&amp;amp;trace=on&amp;amp;ns=resolver&amp;amp;useresolver=8.8.4.4&amp;amp;nameservers=sains.mooo.com"&gt;https://digwebinterface.com/?hostnames=_acme-challenge.saibox.saicharan.in&amp;amp;type=A&amp;amp;showcommand=on&amp;amp;colorize=on&amp;amp;trace=on&amp;amp;ns=resolver&amp;amp;useresolver=8.8.4.4&amp;amp;nameservers=sains.mooo.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.letsencrypt.org/t/solved-dns-problem-servfail-looking-up-caa-for-mit42-de/20965/5"&gt;https://community.letsencrypt.org/t/solved-dns-problem-servfail-looking-up-caa-for-mit42-de/20965/5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/siilike/certbot-dns-standalone"&gt;https://github.com/siilike/certbot-dns-standalone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dnsviz.net/d/saitest.saicharan.in/X_QJ1g/dnssec/"&gt;https://dnsviz.net/d/saitest.saicharan.in/X_QJ1g/dnssec/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AdguardTeam/AdGuardHome/blob/master/openapi/openapi.yaml"&gt;https://github.com/AdguardTeam/AdGuardHome/blob/master/openapi/openapi.yaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.withoutthesarcasm.com/letsencrypt-for-private-networks/"&gt;https://www.withoutthesarcasm.com/letsencrypt-for-private-networks/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;This renewal can be automated by using auth- and deploy- &lt;a href="https://certbot.eff.org/docs/using.html#manual"&gt;hooks&lt;/a&gt;. Example commands &lt;code&gt;certbot -d subdomain.domain.ext --agree-tos --manual --preferred-challenges dns --manual-auth-hook ./adguard-dns-auth.sh --manual-cleanup-hook ./adguard-dns-clean.sh --manual-public-ip-logging-ok --force-renewal certonly&lt;/code&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref2:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;For my record, this command did not work: &lt;code&gt;certbot --non-interactive --agree-tos --email certmaster@domain.ext certonly --preferred-challenges dns --authenticator certbot-dns-standalone:dns-standalone --certbot-dns-standalone:dns-standalone-address=0.0.0.0 --certbot-dns-standalone:dns-standalone-ipv6-address=:: --certbot-dns-standalone:dns-standalone-port=53 -d subdomain.domain.ext --force-renewal --staging --verbose --debug-challenges&lt;/code&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;AdGuardHome v0.105.0+ is required to support &lt;a href="https://github.com/AdguardTeam/AdGuardHome/wiki/Hosts-Blocklists#dnsrewrite"&gt;&lt;code&gt;dnsrewrite&lt;/code&gt;&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;By default, only allow allow: 127.0.0.1, and your public IP: &lt;code&gt;curl -k https://domains.google.com/checkip&lt;/code&gt;. &lt;strong&gt;&lt;em&gt;Temporarily&lt;/em&gt;&lt;/strong&gt; update firewall rules to allow out-of-network requests. This too can be automated via AdGuardHome&amp;rsquo;s REST API: &lt;code&gt;GET /control/access/list&lt;/code&gt; and &lt;code&gt;POST /control/access/set&lt;/code&gt; in combination with &lt;code&gt;ufw&lt;/code&gt; or similar.&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;I ran into &lt;code&gt;SERVFAIL looking up CAA for ...&lt;/code&gt; error from certbot. Turns out the problem was a missing &lt;code&gt;A&lt;/code&gt; record for subdomain.domain.ext in AdGuardHome, which is where the need for this entry originates from. &lt;a href="https://dnsviz.net"&gt;https://dnsviz.net&lt;/a&gt; was very helpful deduce this problem. It was on top of the list of DNS errors reported!&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;&lt;code&gt;GET /status&lt;/code&gt;, add/update corresponding dnsrewrite entry into &lt;code&gt;user_rules[]&lt;/code&gt; and &lt;code&gt;POST /control/filtering/set_rules&lt;/code&gt; can be used in conjunction with the auth- and deploy- hook scripts to automate the entries that get inserted for &lt;code&gt;challenge-txt&lt;/code&gt;.&amp;#160;&lt;a href="#fnref:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>Airprint with CUPS on DD-WRT</title><link>https://www.saicharan.in/blog/2020/07/27/dd-wrt-cups-airprint</link><pubDate>Mon, 27 Jul 2020 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2020/07/27/dd-wrt-cups-airprint</guid><description>&lt;p&gt;Another note to self on enabling Airprint for a legacy network printer with Avahi and CUPS on DD-WRT (HP P3005).&lt;/p&gt;
&lt;p&gt;Prerequisites: router with DD-WRT and a USB port (to install cupsd via Entware), a network capable printer. My notes on the router setup are &lt;a href="https://www.saicharan.in/blog/2020/06/24/managing-your-internet-of/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mostly a rehash of the tutorials from TomatoUSB&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; and EzUnix&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;, in case those links go dead:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;opkg install hplip-full&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;opkg install cups cups-filters cups-pdf&lt;/code&gt; # this was required to get CUPS to recognize &lt;code&gt;application/pdf&lt;/code&gt; as valid filter and to enable &lt;code&gt;pdftoraster&lt;/code&gt; needed below.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add this to Firewall starup script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; # CUPSd WebInterface (http/tcp)
 iptables -I INPUT -p tcp --dport 631 -i vlan2 -j ACCEPT
 # CUPSd printer port
 iptables -I INPUT -p tcp --dport 9100 -i vlan2 -j ACCEPT
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Navigate to CUPS web interface http://&amp;lt; router-ip &amp;gt;:631 &amp;gt; Administration &amp;gt; &lt;code&gt;Add Printer&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choose HP Printer (HPLIP), &lt;code&gt;Continue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Connection: socket://&amp;lt; network-printer-ip &amp;gt;:9100, &lt;code&gt;Continue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Provide Name, Description, Location and choose to &amp;lsquo;Share This Printer&amp;rsquo;, &lt;code&gt;Continue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Choose Make: HP, &lt;code&gt;Continue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Choose Model: HP LaserJet p3005&amp;hellip;, &lt;code&gt;Add Printer&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; echo &amp;quot;image/urf application/pdf 100 pdftoraster&amp;quot; &amp;gt; /opt/share/cups/mime/airprint.convs
 echo &amp;quot;image/urf urf string(0,UNIRAST&amp;lt;00&amp;gt;)&amp;quot; &amp;gt; /opt/share/cups/mime/airprint.types
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create &lt;code&gt;/opt/etc/avahi/services/airprint-hpp3005.service&lt;/code&gt; with the following content &lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;,&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;
 &amp;lt;!DOCTYPE service-group SYSTEM &amp;quot;avahi-service.dtd&amp;quot;&amp;gt;
 &amp;lt;service-group&amp;gt;
   &amp;lt;name replace-wildcards=&amp;quot;yes&amp;quot;&amp;gt;AirPrint HP1220C @ %h&amp;lt;/name&amp;gt;
   &amp;lt;service&amp;gt;
     &amp;lt;type&amp;gt;_ipp._tcp&amp;lt;/type&amp;gt;
     &amp;lt;subtype&amp;gt;_universal._sub._ipp._tcp&amp;lt;/subtype&amp;gt;
     &amp;lt;port&amp;gt;631&amp;lt;/port&amp;gt;
     &amp;lt;txt-record&amp;gt;txtvers=1&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;qtotal=1&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;Transparent=T&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;URF=none&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;rp=printers/(name-from-cups)&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;note=your note&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;product=(GPL Ghostscript)&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;printer-state=3&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;printer-type=0x82b01c&amp;lt;/txt-record&amp;gt;
     &amp;lt;txt-record&amp;gt;pdl=application/octet-stream,application/pdf,application/postscript,image/gif,image/jpeg,image/png,image/tiff,image/urf,text/html,text/plain,application/vnd.cups-banner,application/vnd.cups-command,application/vnd.cups-pdf,application/vnd.cups-postscript&amp;lt;/txt-record&amp;gt;
   &amp;lt;/service&amp;gt;
 &amp;lt;/service-group&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You could generate this file from TJ Fontaine&amp;rsquo;s &lt;a href="https://github.com/tjfontaine/airprint-generate"&gt;airprint-generate&lt;/a&gt;, but that did not work for me with some Python errors I chose not to pursue.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/opt/etc/init.d/rc.unslung restart&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Done, you should find this printer via Airprint. You can use the CUPS web interface to configure printer defaults (duplex, two-sided printing, economy/high quality etc.).&lt;/p&gt;
&lt;p&gt;For the record, HP p3005 has a decent web interface at http://&amp;lt; printer-ip &amp;gt; and also at the CUPS port: http://&amp;lt; printer-ip &amp;gt;:631.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="http://tomatousb.org/forum/t-638158/airprint-and-google-cloud-print-via-optware"&gt;http://tomatousb.org/forum/t-638158/airprint-and-google-cloud-print-via-optware&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://www.ezunix.org/index.php?title=Enable_iOS_AirPrint_with_any_printer_supported_by_CUPS"&gt;https://www.ezunix.org/index.php?title=Enable_iOS_AirPrint_with_any_printer_supported_by_CUPS&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="https://www.linuxbabe.com/ubuntu/set-up-cups-print-server-ubuntu-bonjour-ipp-samba-airprint"&gt;https://www.linuxbabe.com/ubuntu/set-up-cups-print-server-ubuntu-bonjour-ipp-samba-airprint&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://wiki.archlinux.org/index.php/Avahi#AirPrint_from_Mobile_Devices"&gt;https://wiki.archlinux.org/index.php/Avahi#AirPrint_from_Mobile_Devices&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>Managing Your Internet Of</title><link>https://www.saicharan.in/blog/2020/06/24/managing-your-internet-of</link><pubDate>Wed, 24 Jun 2020 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2020/06/24/managing-your-internet-of</guid><description>&lt;p&gt;This is yet another note to self on setting up my home network to isolate &amp;lsquo;smart&amp;rsquo; and other IoT devices into isolated networks in their own subnets, but having a functional UX for the family.&lt;/p&gt;
&lt;h3 id="contents"&gt; &lt;a class="anchor" href="#contents"&gt;Contents &lt;/a&gt;&lt;/h3&gt;
&lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#contents"&gt;Contents&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#end-goal"&gt;End Goal&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#choosing-a-version-of-dd-wrt"&gt;Choosing a version of DD-WRT&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#virtual-interface-wlan-and-vlan-setup"&gt;Virtual Interface (WLAN) and VLAN Setup&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#mdns-setup-for-media-devices"&gt;mDNS Setup for Media Devices&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#static-route"&gt;Static Route&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#firewall"&gt;Firewall&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#acknowledgements"&gt;Acknowledgements&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;h3 id="end-goal"&gt; &lt;a class="anchor" href="#end-goal"&gt;End Goal &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s an outline of the end goal in ASCII art:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; / WLAN B1 (10.2.2.1/24) - Miscl. Devices
 / 
ISP -- Gateway/Router-A ---- Gateway/Router-B ---- WLAN B2 (10.3.3.1/24) - IoT Devices
 | (DD-WRT) \
 | [10.1.1.100/32] \ LAN B3 (10.4.4.1/24)
 WLAN A1 | |
 (10.1.1.1/24) AppleTV Chromecast
 | | |
 Mobile Phones
&lt;/code&gt;&lt;/pre&gt;&lt;p /&gt;
&lt;h3 id="choosing-a-version-of-dd-wrt"&gt; &lt;a class="anchor" href="#choosing-a-version-of-dd-wrt"&gt;Choosing a version of DD-WRT &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The version of firmware recommended on DD-WRT&amp;rsquo;s &lt;a href="https://dd-wrt.com/support/router-database/"&gt;router database&lt;/a&gt; is quite a bit dated, and using the bleeding edge beta from the forums isn&amp;rsquo;t always dependable, so I&amp;rsquo;ve recently started picking up builds recommended on &lt;a href="https://support.flashrouters.com/setup-guides/dd-wrt-features/i-want-to-upgrade-the-dd-wrt-firmware-of-my-flashrouter/"&gt;flashrouter&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="virtual-interface-wlan-and-vlan-setup"&gt; &lt;a class="anchor" href="#virtual-interface-wlan-and-vlan-setup"&gt;Virtual Interface (WLAN) and VLAN Setup &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Router-B runs &lt;a href="https://www.dd-wrt.com"&gt;DD-WRT&lt;/a&gt; firmware in the Gateway mode. The basic setup itself is a straight forward adaptation of Guest Wi-Fi &lt;a href="https://wiki.dd-wrt.com/wiki/index.php/Guest_WiFi_+_abuse_control_for_beginners"&gt;setup on dd-wrt wiki&lt;/a&gt;. Basically, Wireless &amp;gt; Basic Settings &amp;gt; new Virtual interface with AP Isolation enabled, and running a Unbridged network configuration with NAT, Net Isolation and DNS redirection enabled. In addition, I have a VLAN setup for &lt;code&gt;LAN B3&lt;/code&gt; with one of the physical LAN ports on the router. Similar configuration for the VLAN, can be configured under Setup &amp;gt; Networking. The IP Address/subnet here will be that of the interface, eg. &lt;code&gt;10.x.y.z/24&lt;/code&gt;. At the bottom of Setup &amp;gt; Networking &amp;gt; DHCPD, I setup a different DHCPD for each of the WLANs, and VLAN.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.saicharan.in/images/vap-setup.png" alt="Virtual Interface Setup"&gt;&lt;/p&gt;
&lt;h3 id="mdns-setup-for-media-devices"&gt; &lt;a class="anchor" href="#mdns-setup-for-media-devices"&gt;mDNS Setup for Media Devices &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;These rely on &lt;a href="https://en.wikipedia.org/wiki/Multicast_DNS"&gt;mDNS&lt;/a&gt; broadcasts to allow client devices to discover services. However, by default these broadcasts don&amp;rsquo;t are local to the subnet of the (AppleTV/Chromecast) device. A solution for cross subnet/interface broadcasts would be the &lt;a href="https://www.avahi.org/"&gt;avahi-daemon&lt;/a&gt;. Fortunately, DD-WRT supports installing tools such as this via &lt;a href="https://github.com/Entware/Entware"&gt;Entware&lt;/a&gt; &lt;code&gt;opkg&lt;/code&gt; command. I have Entware running off a tiny flash drive setup as described in &lt;a href="https://wiki.dd-wrt.com/wiki/index.php/Installing_Entware"&gt;installing Entware&lt;/a&gt; followed by &lt;code&gt;opkg update &amp;amp;&amp;amp; opkg upgrade &amp;amp;&amp;amp; opkg install avahi-utils&lt;/code&gt;. Here&amp;rsquo;s my &lt;code&gt;/opt/etc/avahi/avahi-daemon.conf&lt;/code&gt; &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[server]
use-ipv4=yes
use-ipv6=no
check-response-ttl=no
use-iff-running=no
allow-interfaces=br0,vlan2,vlan6
allow-point-to-point=yes
enable-dbus=no
&lt;p&gt;[publish]
publish-addresses=yes
publish-hinfo=yes
publish-workstation=no
publish-domain=yes&lt;/p&gt;
&lt;p&gt;[reflector]
enable-reflector=yes
reflect-ipv=no&lt;/p&gt;
&lt;p&gt;[rlimits]
rlimit-core=0
rlimit-data=4194304
rlimit-fsize=0
rlimit-nofile=30
rlimit-stack=4194304
rlimit-nproc=3&lt;/p&gt;
&lt;p&gt;[wide-area]
enable-wide-area=yes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This snippet in Administration &amp;gt; Commands &amp;gt; Save Startup will auto start &lt;code&gt;avahi-daemon&lt;/code&gt;:&lt;/p&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Start avahi/mDNS
echo &amp;#34;nogroup:x:114:nobody&amp;#34; &amp;gt;&amp;gt; /etc/group
/opt/etc/init.d/rc.unslung start
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And save the following with &amp;lsquo;Save Firewall&amp;rsquo;. [The TTL bit was a nice find][1].&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Chromecast/AppleTV mDNS advertisements on vlan6 (AppleTV/Chromecast), from WAN
iptables -I INPUT -p udp --dport 1900 -i `get_wanface` -j ACCEPT
iptables -I INPUT -p udp --dport 1900 -i vlan6 -j ACCEPT
iptables -I FORWARD -p udp --dport 5353 -i `get_wanface` -j ACCEPT
iptables -I FORWARD -p udp --dport 5353 -i vlan6 -j ACCEPT
iptables -I INPUT -p udp --dport 5353 -i `get_wanface` -j ACCEPT
iptables -I INPUT -p udp --dport 5353 -i vlan6 -j ACCEPT

# Increase IP TTL so it can go an extra hop
iptables -t mangle -A PREROUTING -d 239.255.255.250 -j TTL --ttl-inc 1
iptables -t mangle -A PREROUTING -d 224.0.0.251 -j TTL --ttl-inc 1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I verified avahi-daemon/mDNS working by firing up &lt;a href="http://tildesoft.com/"&gt;Tildesoft&lt;/a&gt;&amp;rsquo;s Discovery app and looking for my devices and also by firing up YouTube app for casting and the phone&amp;rsquo;s AirPlay to mirror the screen. The devices are now discoverable by phones and other clients.&lt;/p&gt;
&lt;p&gt;However, the actual AirPlay mirroring and casting don&amp;rsquo;t work :-)&lt;/p&gt;
&lt;h3 id="static-route"&gt; &lt;a class="anchor" href="#static-route"&gt;Static Route &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;mDNS discovery responses contain the IP/Port of the service so clients know how to reach these devices.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;_googlecast._tcp.
 Chromecast-xyz
 10.4.4.4:8009
 ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Starting with a simple &lt;code&gt;traceroute 10.4.4.4&lt;/code&gt; in &lt;code&gt;WLAN A1&lt;/code&gt; in subnet 10.1.1.1/24, it was clear that the network did not know how to route the packets destined for 10.4.4.4. So a friend suggested adding a static route in Gateway/Router-A for packets bound to 10.4.4.0/24 with Gateway 10.1.1.100. And &lt;code&gt;traceroute&lt;/code&gt; went until the gateway, and stopped at that with 100% packet loss.&lt;/p&gt;
&lt;h3 id="firewall"&gt; &lt;a class="anchor" href="#firewall"&gt;Firewall &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The final piece of the puzzle was in figuring out the firewall rules. I started off with a catchall rule that accepted all forwarded traffic to &lt;code&gt;vlan2&lt;/code&gt; (which is the default WAN interface on DD-WRT devices; run &lt;code&gt;get_wanface&lt;/code&gt; in an SSH session into your router to check).&lt;/p&gt;
&lt;p&gt;Then I added ports 8008, 8009, and high ports as a FORWARD rule, an adaptation from &lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;, including this to the &amp;lsquo;Save Firewall&amp;rsquo; script. Note that I had also added TCP ports based on a packet type from a &lt;a href="https://www.wireshark.org/"&gt;Wireshark&lt;/a&gt; packet capture of the session that failed to connect with firewall enabled for UDP packets.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# https://blog.g3rt.nl/allow-google-chromecast-host-firewall-iptables.html
# Punch a hole out of the router into the private &amp;#39;WAN&amp;#39;
iptables -I FORWARD -i vlan2 -p tcp --dport 7000 -j ACCEPT
iptables -I FORWARD -i vlan2 -p tcp -m multiport --sports 32768:61000 -m multiport --dports 32768:61000 -j ACCEPT
iptables -I FORWARD -i vlan2 -p tcp -m multiport --dports 8008:8009 -j ACCEPT
# van6: Media Center
iptables -I FORWARD -i vlan6 -p tcp --dport 7000 -j ACCEPT
iptables -I FORWARD -i vlan6 -p tcp -m multiport --sports 32768:61000 -m multiport --dports 32768:61000 -j ACCEPT
iptables -I FORWARD -i vlan6 -p tcp -m multiport --dports 8008:8009 -j ACCEPT
&lt;/code&gt;&lt;/pre&gt;&lt;p /&gt;
### Caveat
We have some early Wemo light switches which did not really play nice with AP and Net Isolation on the Virtual Interfaces, so for the corresponding VAP, these are disabled.
&lt;h3 id="conclusion"&gt; &lt;a class="anchor" href="#conclusion"&gt;Conclusion &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;And, that&amp;rsquo;s all folks. With this, I have devices isolated in their own networks/subnets that are firewalled off, but still usable across subnets for casting/AirPlay mirroring.&lt;/p&gt;
&lt;h3 id="acknowledgements"&gt; &lt;a class="anchor" href="#acknowledgements"&gt;Acknowledgements &lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Thanks to the DD-WRT contributors, community for the very usable software and readable documentation. Thank you to the authors of &lt;a href="https://www.shackleton.io"&gt;https://www.shackleton.io&lt;/a&gt; and &lt;a href="https://blog.gert.nl"&gt;https://blog.gert.nl&lt;/a&gt; for the very helpful tips. Many thanks to &lt;a href="https://github.com/zyxmon"&gt;@zyxmon&lt;/a&gt; and &lt;a href="https://github.com/ryzhovau"&gt;@ryzhovau&lt;/a&gt; of Entware for quickly &lt;a href="https://github.com/Entware/Entware/issues/483"&gt;fixing a bug&lt;/a&gt; with avahi-utils on DD-WRT.&lt;/p&gt;
&lt;p&gt;And of course, to my family, for bearing with many, many, many network disruptions!&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://www.shackleton.io/blog/2019/05/07/internet-of-shit.html"&gt;https://www.shackleton.io/blog/2019/05/07/internet-of-shit.html&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://blog.g3rt.nl/allow-google-chromecast-host-firewall-iptables.html"&gt;https://blog.g3rt.nl/allow-google-chromecast-host-firewall-iptables.html&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>On Good and Evil</title><link>https://www.saicharan.in/blog/2020/06/20/quote-good-and-evil-van-gogh</link><pubDate>Sat, 20 Jun 2020 11:10:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2020/06/20/quote-good-and-evil-van-gogh</guid><description>&lt;blockquote&gt;
&lt;p&gt;Yes, evil often seems to surpass good. But then, in spite of us, and without our permission, there comes at last an end to the bitter frosts. One morning the wind turns, and there is a thaw. And so I must still have hope.&lt;/p&gt;
&lt;/blockquote&gt;— Vincent van Gogh, quoted on &lt;a href="https://twitter.com/mizze43/status/1274114571675095044?s=12"&gt;Twitter&lt;/a&gt;.</description></item><item><title>OpenVPN Client on ASUS RT-AC68U with DD-WRT Firmware</title><link>https://www.saicharan.in/blog/2020/05/26/ddwrt-openvpn-client-httpserver</link><pubDate>Tue, 26 May 2020 11:11:30 +0000</pubDate><guid>https://www.saicharan.in/blog/2020/05/26/ddwrt-openvpn-client-httpserver</guid><description>&lt;p&gt;Note to self on setting up OpenVPN Client on Asus RT-AC68U Router with DD-WRT.&lt;/p&gt;
&lt;p&gt;The goal of this exercise was to have OpenVPN client installed on a router that allows my family to enable/disable VPN via simple webapp, without dealing with the full settings page of the router management tool.&lt;/p&gt;
&lt;p&gt;I had an old TM-AC1900 Cellspot router, but that&amp;rsquo;s basically a hobbled (in software) version of the capable RT-AC168U hardware. So, first step is to get a capable firmware installed.&lt;/p&gt;
&lt;p&gt;I could not host this stand-alone webapp on a local store or webserver as CORS protection kicks in (both for DD-WRT and for the stock ASUS RT-AC68U firmware). With &lt;code&gt;ssh&lt;/code&gt; access to the router, I can host the standalone webapp on the same webserver and avoid the CORS restriction.&lt;/p&gt;
&lt;p&gt;Between the stock ASUS firmware vs DD-WRT, I prefer DD-WRT &lt;del&gt;for this setup since access to &lt;a href="http://router.local/user/"&gt;http://router.local/user/&lt;/a&gt; is not password protected, so the user experience (UX) is seamless &amp;ndash; for local users connected to. Another &amp;lsquo;benefit&amp;rsquo; with DD-WRT is the use of &amp;lsquo;Basic Authentication&amp;rsquo; as opposed to some other protocol with the ASUS stock firmware&lt;/del&gt; (for an early iteration, I leant towards an insecure setup to simplify UX for the family &amp;ndash; in my case, the DD-WRT router wasn&amp;rsquo;t directly connected to the WAN, but behind another router, so I was taking a risky chance). For actual auth with the router firmware to enable/disable the OpenVPN client, I simply hard-coded the &lt;code&gt;Authentication: Basic &amp;lt;hash&amp;gt;&lt;/code&gt; header. Much of the &amp;lsquo;reverse engineering&amp;rsquo; of the request/response for the enable/disable OpenVPN client were by simply observing the network traffic with the browser developer tool&amp;rsquo;s &lt;a href="https://developers.google.com/web/tools/chrome-devtools/network/#search"&gt;network tab&lt;/a&gt; &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; and looking at the request/response headers and the form data.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Transform an old TM-AC1900 to RT-AC68U with this excellent guide from &lt;a href="https://www.bayareatechpros.com/ac1900-to-ac68u/"&gt;Bay Area Tech Pros&lt;/a&gt;&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;
&lt;ul&gt;
&lt;li&gt;Crucial to getting the CFE to show up was clear NVRAM in step 20 (Power off, Hold WPS button and power on while holding WPS button until the power LED begins to flash quickly)&lt;/li&gt;
&lt;li&gt;And, navigating to 192.168.1.1 very quickly (seems like the CFE page is only available for a short window after reboot/reset/nvram clear)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Upgrade RT-AC68U to DD-WRT, with the latest beta from the ftp location &lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;Setup OpenVPN client. I tried both &lt;a href="https://protonvpn.com"&gt;ProtonVPN&lt;/a&gt; and &lt;a href="https://surfshark.com"&gt;Surfshark VPN&lt;/a&gt; &lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt; as the providers, both of which have &lt;a href="https://support.surfshark.com/hc/en-us/articles/360003086114-DD-WRT-router-tutorial"&gt;excellent&lt;/a&gt; &lt;a href="https://protonvpn.com/support/vpn-router-ddwrt/"&gt;documentation&lt;/a&gt; &lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;. Retrieve the OpenVPN credentials from &lt;a href="https://account.protonvpn.com/account#openvpn"&gt;https://account.protonvpn.com/account#openvpn&lt;/a&gt; or &lt;a href="https://account.surfshark.com/setup/manual"&gt;https://account.surfshark.com/setup/manual&lt;/a&gt;, respectively.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ssh&lt;/code&gt; into the router, copy the standalone webapp to &lt;code&gt;/jffs/&amp;lt;user&amp;gt;/&lt;/code&gt;, and run &lt;code&gt;ln -s /jffs/&amp;lt;user&amp;gt;/webapp.html /www/user/webapp.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/jffs/&amp;lt;user&amp;gt;/&lt;/code&gt; is persistent storage, but &lt;code&gt;/www/user&lt;/code&gt; isn&amp;rsquo;t and gets reset on reboot. So create a startup script with the above &lt;code&gt;ln&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;A stripped down version of the webapp I hacked up is &lt;a href="https://www.saicharan.in/work/VPNWebapp.html"&gt;here&lt;/a&gt; &lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://developers.google.com/web/tools/chrome-devtools/network/#search"&gt;https://developers.google.com/web/tools/chrome-devtools/network/#search&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://www.bayareatechpros.com/ac1900-to-ac68u/"&gt;https://www.bayareatechpros.com/ac1900-to-ac68u/&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="ftp://ftp.dd-wrt.com/betas/2020/05-26-2020-r43261/asus-rt-ac68u/"&gt;ftp://ftp.dd-wrt.com/betas/2020/05-26-2020-r43261/asus-rt-ac68u/&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://account.protonvpn.com/account#openvpn"&gt;https://account.protonvpn.com/account#openvpn&lt;/a&gt;, &lt;a href="https://account.surfshark.com/setup/manual"&gt;https://account.surfshark.com/setup/manual&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;&lt;a href="https://protonvpn.com/support/vpn-router-ddwrt/"&gt;https://protonvpn.com/support/vpn-router-ddwrt/&lt;/a&gt;, &lt;a href="https://support.surfshark.com/hc/en-us/articles/360003086114-DD-WRT-router-tutorial"&gt;https://support.surfshark.com/hc/en-us/articles/360003086114-DD-WRT-router-tutorial&lt;/a&gt;&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;&lt;a href="https://wiki.dd-wrt.com/wiki/index.php/Web_server"&gt;https://wiki.dd-wrt.com/wiki/index.php/Web_server&lt;/a&gt;&amp;#160;&lt;a href="#fnref:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>Wireguard VPN Setup</title><link>https://www.saicharan.in/blog/2020/01/07/wireguard-vpn</link><pubDate>Tue, 07 Jan 2020 22:04:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2020/01/07/wireguard-vpn</guid><description>&lt;p&gt;Note to self on setting up Wireguard VPN service.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Enable wireguard PPA (not required on Ubuntu Eoan)
sudo add-apt-repository ppa:wireguard/wireguard -y
sudo apt-get update -y
# Install dependencies and wireguard
sudo apt-get install linux-headers-$(uname -r) -y
sudo apt-get install wireguard -y

&lt;h2 id="ip-forwarding"&gt; &lt;a class="anchor" href="#ip-forwarding"&gt;IP Forwarding &lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;sudo sed -i -e 's/#net.ipv4.ip_forward.&lt;em&gt;/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
sudo sed -i -e 's/#net.ipv6.conf.all.forwarding.&lt;/em&gt;/net.ipv6.conf.all.forwarding=1/g' /etc/sysctl.conf
sudo sysctl -p&lt;/p&gt;

&lt;h2 id="firewall"&gt; &lt;a class="anchor" href="#firewall"&gt;Firewall &lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;sudo ufw allow 51820/udp
sudo ufw allow 22/tcp
sudo ufw enable&lt;/p&gt;

&lt;h1 id="use-the-key-generated-here-below"&gt; &lt;a class="anchor" href="#use-the-key-generated-here-below"&gt;Use the key generated here below &lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;wg genkey&lt;/p&gt;
&lt;p&gt;sudo vim /etc/wireguard/wg0.conf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Add the following to &lt;code&gt;/etc/wireguard/wg0.conf&lt;/code&gt;&lt;/p&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Interface]
Address = 10.14.0.0/32
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = &amp;lt;output from wg genkey&amp;gt;

[Peer]
PublicKey = &amp;lt;from your client&amp;gt;
# This should match that of the client&amp;#39;s configuration. Ensure it is in the same subet as defined in the &amp;#39;Address&amp;#39; field of the [Interface] section above
AllowedIPs = 10.14.0.10/32

## WireGuard Service
wg-quick up wg0
sudo systemctl enable wg-quick@wg0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On the client, use configurations as this one.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Interface]
PrivateKey = &amp;lt;client&amp;#39;s private key, auto generated by most clients; else use &amp;#39;wg genkey&amp;#39;&amp;gt;
Address = 10.14.0.10/32
DNS = &amp;lt;Your preferred DNS or router Gateway IP address&amp;gt;

[Peer]
PublicKey = &amp;lt;Server&amp;#39;s public key; listed on running &amp;#39;sudo wg&amp;#39; on the server, after setting up the server config as above, with a private key included&amp;gt;
AllowedIPs = ::/0, 0.0.0.0/0
Endpoint = &amp;lt;server-dns-name&amp;gt;:52121
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On the server, repeat the &lt;code&gt;[Peer]&lt;/code&gt; section(s) as needed, one for each additional client. Remember to provide unique IPs to each client, ensuring the address fall in the subnet range provided in the server&amp;rsquo;s &lt;code&gt;Address&lt;/code&gt; field in the &lt;code&gt;[Interface]&lt;/code&gt; section.&lt;/p&gt;
&lt;h4 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://mikkel.hoegh.org/2019/11/01/home-vpn-server-wireguard"&gt;https://mikkel.hoegh.org/2019/11/01/home-vpn-server-wireguard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vijayshinva/AzureWireGuard/blob/master/AzureWireGuard/CustomScripts/AzureWireGuard.sh"&gt;https://github.com/vijayshinva/AzureWireGuard/blob/master/AzureWireGuard/CustomScripts/AzureWireGuard.sh&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description></item><item><title>Computation is a means, not an end.</title><link>https://www.saicharan.in/blog/2019/12/23/quote-apollo-computation-means</link><pubDate>Mon, 23 Dec 2019 22:53:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2019/12/23/quote-apollo-computation-means</guid><description>&lt;blockquote&gt;
&lt;p&gt;The lesson, maybe, is simple: If your phone is so much more powerful than the computers that put humanity on the moon, then why are you just staring at Instagram all day? Computation is means, not end.&lt;/p&gt;
&lt;/blockquote&gt;— Alexis C. Madrigal, &lt;a href="https://www.theatlantic.com/science/archive/2019/07/underappreciated-power-apollo-computer/594121/"&gt;Your Smart Toaster Can’t Hold a Candle to the Apollo Computer&lt;/a&gt;.</description></item><item><title>Man's Troubles - Man Himself</title><link>https://www.saicharan.in/blog/2019/12/23/quote-mans-troubles</link><pubDate>Mon, 23 Dec 2019 23:09:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2019/12/23/quote-mans-troubles</guid><description>&lt;blockquote&gt;
&lt;p&gt;‘I gazed around myself, and my soul was wounded by human suffering. I then looked inside myself, and saw that man’s troubles come from man himself.’&lt;/p&gt;
&lt;/blockquote&gt;— Yegor Zhukov, quoting Alexander Radishchev during his &lt;a href="https://www.newyorker.com/news/our-columnists/a-powerful-statement-of-resistance-from-a-college-student-on-trial-in-moscow"&gt;trial&lt;/a&gt;.</description></item><item><title>Messaging in Smalltalk</title><link>https://www.saicharan.in/blog/2019/12/23/quote-messaging-smalltalk</link><pubDate>Mon, 23 Dec 2019 22:49:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2019/12/23/quote-messaging-smalltalk</guid><description>&lt;blockquote&gt;
&lt;p&gt;The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.&lt;/p&gt;
&lt;/blockquote&gt;— Alan Kay on Smalltalk Design on &lt;a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html"&gt;squeak-dev list&lt;/a&gt;.</description></item><item><title>On being in a hurry</title><link>https://www.saicharan.in/blog/2019/12/23/quote-being-in-a-hurry</link><pubDate>Mon, 23 Dec 2019 22:58:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2019/12/23/quote-being-in-a-hurry</guid><description>&lt;blockquote&gt;
&lt;p&gt;“We’re in such a hurry most of the time we never get much chance to talk,” Pirsig writes. “The result is a kind of endless day-to-day shallowness, a monotony that leaves a person wondering years later where all the time went and sorry that it’s all gone.”&lt;/p&gt;
&lt;/blockquote&gt;— Robert Prisig, Zen and the Art of Motorcycle Maintenance, &lt;a href="https://www.smithsonianmag.com/smithsonian-institution/cycle-zen-art-and-motorcycle-maintenance-comes-smithsonian-180973836/"&gt;Excerpt on Smithsonian Mag&lt;/a&gt;.</description></item><item><title>On Passing Statistical Tests</title><link>https://www.saicharan.in/blog/2019/12/23/quote-passing-statistical-tests</link><pubDate>Mon, 23 Dec 2019 22:47:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2019/12/23/quote-passing-statistical-tests</guid><description>&lt;blockquote&gt;
&lt;p&gt;To be brief, a CSRNG should be unbreakable by smart attackers with lots of resources. If a CSRNG does not pass statistical tests, then this means that it can be broken by a chimpanzee. But if it passes the tests, this does in no way prove that it is cryptographically strong; it just means that the chimpanzee will be stumped.&lt;/p&gt;
&lt;/blockquote&gt;— Thomas Pornin on &lt;a href="https://research.nccgroup.com/2019/12/19/on-linuxs-random-number-generation/"&gt;NCC Research&lt;/a&gt;.</description></item><item><title>On Poems &amp; Proofs</title><link>https://www.saicharan.in/blog/2019/12/23/quote-poems-and-proofs</link><pubDate>Mon, 23 Dec 2019 22:56:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2019/12/23/quote-poems-and-proofs</guid><description>&lt;blockquote&gt;
&lt;p&gt;A NON-MATHEMATICIAN MIGHT ASK if any of these problems have real-world applications, but is that fair? No one asks a poet what a new poem “does.” The poem’s simplicity, elegance, and beauty are sufficient reasons for its existence. Aren’t the same things true for a mathematical proof?&lt;/p&gt;
&lt;/blockquote&gt;— Mark F. Bernstein, quoting mathematician Terence Tao on the &lt;a href="https://paw.princeton.edu/article/mind-mathematician"&gt;PAW&lt;/a&gt;.</description></item><item><title>Meaning of Impossible</title><link>https://www.saicharan.in/blog/2019/02/05/quote-feynman-criticisms</link><pubDate>Tue, 05 Feb 2019 17:45:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2019/02/05/quote-feynman-criticisms</guid><description>&lt;blockquote&gt;
&lt;p&gt;After two years of working together, I finally knew for sure what I had long suspected: “Stupid” was just an expression Feynman applied to everyone, including himself, as a way to focus attention on an error so it was never made again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I also learned that “impossible,” when used by Feynman, did not necessarily mean “unachievable” or “ridiculous.” Sometimes it meant, “Wow! Here is something amazing that contradicts what we would normally expect to be true. This is worth understanding!”&lt;/p&gt;
— Prof. Paul J. Steinhardt on &lt;a href="http://nautil.us/issue/68/context/what-impossible-meant-to-feynman"&gt;What Impossible Meant to Feynman&lt;/a&gt;.</description></item><item><title>List Comprehensions in C++</title><link>https://www.saicharan.in/blog/2018/08/21/list-comprehensions-c</link><pubDate>Tue, 21 Aug 2018 00:30:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2018/08/21/list-comprehensions-c</guid><description>&lt;p&gt;From Bartosz Milewski&amp;rsquo;s &lt;a href="https://bartoszmilewski.com/2009/10/21/what-does-haskell-have-to-do-with-c/"&gt;What Does Haskell Have to Do with C++?&lt;/a&gt;: Haskell style list comprehensions of the form&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;one x = 1
count lst = sum [one x | x &amp;lt;- lst]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can be written in modern C++ like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;template&amp;lt;class T&amp;gt; struct
one {
 static const int value = 1;
};
&lt;p&gt;template&amp;lt;class&amp;hellip; lst&amp;gt; struct
count {
static const int value = sum&amp;lt;one&amp;lt;lst&amp;gt;::value&amp;hellip;&amp;gt;::value;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The author calls out the comparison between &lt;code&gt;one&amp;lt;lst&amp;gt;::value...&lt;/code&gt; and &lt;code&gt;[one x | x &amp;lt;- lst]&lt;/code&gt;. I&amp;rsquo;ve used packs like this before, but looking at this juxtaposition was a revelation.&lt;/p&gt;
</description></item><item><title>Emulating PDP-11 Abstract Machine as the Root Cause of Spectre and Meltdown</title><link>https://www.saicharan.in/blog/2018/08/20/root-cause-of-spectre-meltdown</link><pubDate>Mon, 20 Aug 2018 14:30:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2018/08/20/root-cause-of-spectre-meltdown</guid><description>&lt;p&gt;The following excerpts from the ACM Queue &lt;a href="https://queue.acm.org/detail.cfm?id=3212479"&gt;article&lt;/a&gt; caught my attention.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The root cause of the Spectre and Meltdown vulnerabilities was that processor architects were trying to build not just fast processors, but fast processors that expose the same abstract machine as a PDP-11. This is essential because it allows C programmers to continue in the belief that their language is close to the underlying hardware.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The quest for high ILP was the direct cause of Spectre and Meltdown.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;By the definition that a &amp;ldquo;low-level language&amp;rdquo; should be &amp;ldquo;close to metal&amp;rdquo;, C is not a low-level language anymore. &amp;ldquo;Close to metal&amp;rdquo; means the language constructs and memory model should &lt;em&gt;&lt;strong&gt;trivially&lt;/strong&gt;&lt;/em&gt; map to processor feature/instruction set. If the language, compiler and processor had first-class support for parallel constructs we would not have needed to encounter Spectre/Meltdown.&lt;/p&gt;
&lt;p&gt;The author makes the case for modern languages, compilers and processors to move away from the simplistic flat-memory and sequential-execution legacy that we have inherited from PDP-11. The paradigm shift from CPU to GPU is a case in point &amp;ndash; rather than resorting to speculative execution (ILP), parallelism is supported by the GUP processor and the language exposes the necessary vectorization and parallelization primitives, so programmers actively think and program for parallelism/concurrency.&lt;/p&gt;
&lt;p&gt;On a related note, the author David Chisnall, concludes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;There is a common myth in software development that parallel programming is hard. This would come as a surprise to Alan Kay, who was able to teach an actor-model language to young children, with which they wrote working programs with more than 200 threads. It comes as a surprise to Erlang programmers, who commonly write programs with thousands of parallel components. It&amp;rsquo;s more accurate to say that parallel programming in a language with a C-like abstract machine is difficult, and given the prevalence of parallel hardware, from multicore CPUs to many-core GPUs, that&amp;rsquo;s just another way of saying that C doesn&amp;rsquo;t map to modern hardware very well.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
</description></item><item><title>Parallels Between Physics and Distributed Systems Concepts</title><link>https://www.saicharan.in/blog/2018/08/20/physics-and-computerscience</link><pubDate>Mon, 20 Aug 2018 18:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2018/08/20/physics-and-computerscience</guid><description>&lt;p&gt;The ACM Queue article titled &lt;a href="https://queue.acm.org/detail.cfm?id=2953944"&gt;Standing on Distributed Shoulders of Giants&lt;/a&gt; was a fascinating read. Some excerpts:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Two-phase commit is the anti-availability protocol.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Computing is like Hubble&amp;rsquo;s universe&amp;hellip;Everything is getting farther away from everything else.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Shared memory works great&amp;hellip; as long as you don&amp;rsquo;t share memory.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This one took a bit of squinting at to make sense. Here, Pat Helland is referring to the fact that there are retries and given we store copies for redundancy, we can only know for certain &lt;em&gt;where&lt;/em&gt; the request was processed &lt;strong&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;/strong&gt; that it was successfully completed. In a sense, once you know it was completed, you can back trace where it was done, but that is hindsight.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;In a distributed system, you can know where the work is done or you can know when the work is done but you can&amp;rsquo;t know both.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This one&amp;rsquo;s on eventual consistency:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;While not yet observed, a put does not really exist&amp;hellip; it&amp;rsquo;s likely to exist but you can&amp;rsquo;t be sure. Only after it is seen by a get will the put really exist.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The references at the end of the article are also good refreshers on Distributed Systems/Computing.&lt;/p&gt;
</description></item><item><title>We are systematically creating races out of things that ought to be a journey</title><link>https://www.saicharan.in/blog/2013/05/02/quote-we-are-systematically-creating-races-out-of-things-that-ought-to-be-a-journey</link><pubDate>Thu, 02 May 2013 11:28:20 +0000</pubDate><guid>https://www.saicharan.in/blog/2013/05/02/quote-we-are-systematically-creating-races-out-of-things-that-ought-to-be-a-journey</guid><description>&lt;blockquote&gt;
&lt;p&gt;We are systematically creating races out of things that ought to be a journey.&lt;/p&gt;
&lt;/blockquote&gt;— Charles Wheelan, &lt;a href="http://online.wsj.com/article/SB10001424052702304811304577366332400453796.html"&gt;WSJ&lt;/a&gt;.</description></item><item><title>Static Website on Google App Engine</title><link>https://www.saicharan.in/blog/2013/04/10/static-website-on-google-app-engine</link><pubDate>Wed, 10 Apr 2013 08:32:52 +0000</pubDate><guid>https://www.saicharan.in/blog/2013/04/10/static-website-on-google-app-engine</guid><description>&lt;p&gt;I&amp;rsquo;ve been experimenting with hosting &lt;a href="https://developers.google.com/appengine/docs/python/gettingstarted/staticfiles"&gt;static&lt;/a&gt; websites on &lt;a href="https://developers.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;(GAE) for a while now. One major deterrent to an otherwise &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/app.yaml"&gt;straight&lt;/a&gt; &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/Makefile#L25"&gt;forward&lt;/a&gt; procedure was the fact that GAE did not automatically serve index.html when encountering static folders. Now that I found &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/app.yaml#L16"&gt;this&lt;/a&gt; workaround on &lt;a href="http://stackoverflow.com/a/6566464/162471"&gt;Stack Overflow&lt;/a&gt;, the static website is ready for GAE!&lt;/p&gt;
&lt;p&gt;But there was another hurdle waiting.&lt;/p&gt;
&lt;p&gt;GAE&amp;rsquo;s &lt;a href="https://developers.google.com/appengine/docs/domain"&gt;instructions&lt;/a&gt; on using custom domain names for GAE hosted apps did not work. Specifically, Step 5 (Add New URL), failed with the following error:
We are unable to process your request at this time. Please try again later. (Error #1000)
After a bit of searching and experimenting, &lt;em&gt;&lt;em&gt;only&lt;/em&gt;&lt;/em&gt; &lt;a href="https://code.google.com/p/googleappengine/issues/detail?id=5021#c13"&gt;this&lt;/a&gt; apparently silly technique actually worked. Along with &lt;a href="https://support.google.com/a/bin/answer.py?hl=en&amp;amp;answer=2518373"&gt;naked domain redirection&lt;/a&gt;, this is now a static site, fully hosted on Google App Engine. Even though this runs off GAE, there are zero machine instances running. This can be verified in the &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/app.yaml"&gt;app.yaml&lt;/a&gt; not relying on any executable script.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;em&gt;Update&lt;/em&gt;&lt;/em&gt;: GAE does not currently support &lt;a href="http://stackoverflow.com/q/14340373/162471"&gt;custom 404&lt;/a&gt; handlers. So, until then, back to Amazon S3 hosting.&lt;/p&gt;
</description></item><item><title>Levenshtein Distance for Handling Redirects from Blogger</title><link>https://www.saicharan.in/blog/2013/04/06/levenshtein-distance-for-handling-redirects-from-blogger</link><pubDate>Sat, 06 Apr 2013 08:07:26 +0000</pubDate><guid>https://www.saicharan.in/blog/2013/04/06/levenshtein-distance-for-handling-redirects-from-blogger</guid><description>&lt;p&gt;Here&amp;rsquo;s a problem I&amp;rsquo;ve long faced and a neat use of Levenshtein Distance.&lt;/p&gt;
&lt;p&gt;This website started off as a blog on &lt;a href="http://www.blogger.com"&gt;blogger.com&lt;/a&gt;. Over time, it was migrated to a self hosted Wordpress site and now runs off a &lt;a href="https://www.saicharan.in/blog/2011/08/22/migrating-to-jekyll/"&gt;Jekyll generated&lt;/a&gt;, Amazon &lt;a href="https://www.saicharan.in/blog/colophon.html"&gt;S3 hosted&lt;/a&gt; bucket.&lt;/p&gt;
&lt;p&gt;However, since the blogger hosted site still got a lot of traffic from search, I did not take it down. I&amp;rsquo;ve always wanted to redirect the traffic to my new website, but Blogger apparently only features redirects in the other &lt;a href="https://support.google.com/blogger/bin/answer.py?hl=en&amp;amp;answer=2472689"&gt;direction&lt;/a&gt;. While &lt;a href="http://www.webupd8.org/2009/06/how-to-redirect-your-blogger-blog-to.html"&gt;Webupd8.org&lt;/a&gt; has a solution, I could not get it working in this case. There were at least two problems that were in the way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;URL structure of the current website also includes the date of publication, in addition to the year and month.&lt;/li&gt;
&lt;li&gt;while migrating to Jelyll, some of the URL &amp;lsquo;&lt;a href="http://en.wikipedia.org/wiki/Clean_URL#Slug"&gt;slugs&lt;/a&gt;&amp;rsquo; also changed.&lt;/li&gt;
&lt;li&gt;I did not want to host a server to do this; I had &lt;a href="https://www.saicharan.in/blog/2009/07/06/redirecting-blogger-traffic/"&gt;tried this&lt;/a&gt; and have moved on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To deal with these two and also handle correct redirects automatically, here is my quick solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On the blogger.com hosted website, place a redirect to a special page to handle redirects from blogger (in this case, /blog/blogger-redirect.html).
&lt;meta expr:content='"0;url=http://saicharan.in/blog/blogger-redirect.html?from="+data:blog.url' http-equiv='refresh'/&gt;&lt;/li&gt;
&lt;li&gt;This special page first detects the &amp;lsquo;&lt;a href="http://en.wikipedia.org/wiki/HTTP_referer"&gt;referer&lt;/a&gt;&amp;rsquo;, then extracts the year, month and slug from the blogger URL. If the referer is not found, extract the query parameter &lt;code&gt;from&lt;/code&gt;. This is a minor optimization in case referer is set (eg. with Google Chrome); one could simply always use the query parameter method (IE and Firefox seem to remove &lt;code&gt;referer&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;It then lists the URLs on the month-page (eg. /blog/YYYY/MM/) of this website, and computes the &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Levenshtein_distance"&gt;Levenshtein&amp;rsquo;s distance&lt;/a&gt;&lt;/em&gt; between the blogger-slug from the blogger URL and the slugs from the month-page URLs.&lt;/li&gt;
&lt;li&gt;If the minimum amongst the computed Levenshtein distances is less than 5, automatically redirect to the URL with that minimal Levenshtein distance (&lt;a href="http://blogger.saicharan.in/2009/03/viewvc-integration-with-google-prettify.html"&gt;example&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;If not, admit that we made a booboo and list all pages for that month, and additionally providing the search box (&lt;a href="http://blogger.saicharan.in/2007/01/this-is-test-post-from-google-docs.html"&gt;example&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I am pretty sure this may affect the SEO ratings, but I am unsure how exactly that will be. So, if you use it, be cautious.&lt;/li&gt;
&lt;li&gt;This solution needs Javascript to work, but has the advantage of not requiring any server backend.&lt;/li&gt;
&lt;li&gt;I used &lt;a href="http://stackoverflow.com/a/11958496/162471"&gt;this&lt;/a&gt; JavaScript implementation of Levenshtein&amp;rsquo;s distance.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/scharan/scharan.github.com/blob/master/blog/blogger-redirect.html"&gt;This&lt;/a&gt; is the source code for my solution.&lt;/li&gt;
&lt;li&gt;Yes, the source code could do with some more optimization :/&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Handling 404 Errors in Javascript</title><link>https://www.saicharan.in/blog/2013/02/06/handling-404-errors-in-javascript</link><pubDate>Wed, 06 Feb 2013 08:41:54 +0000</pubDate><guid>https://www.saicharan.in/blog/2013/02/06/handling-404-errors-in-javascript</guid><description>&lt;p&gt;&lt;a href="https://www.saicharan.in/blog/colophon.html"&gt;Migrating&lt;/a&gt; between hosting and blogging solutions can cause headaches. Now that I&amp;rsquo;ve moved to an Amazon S3 hosted &lt;a href="https://www.saicharan.in/blog/2011/08/24/static-blog-using-jekyll/"&gt;static website&lt;/a&gt;, I needed an intelligent way to handle certain features like tags and categories that I had with the blogger.com and Wordpress hosted site, &lt;em&gt;&lt;strong&gt;without&lt;/strong&gt;&lt;/em&gt; the need to host a server.&lt;/p&gt;
&lt;p&gt;JavaScript to the &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/_includes/error.html"&gt;rescue&lt;/a&gt;!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I first identified the specific causes of problem using the crawl statistics from Google&amp;rsquo;s &lt;a href="https://www.google.com/webmasters/tools/home"&gt;Webmasters&lt;/a&gt; tool.&lt;/li&gt;
&lt;li&gt;I then &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/_includes/error.html"&gt;crafted&lt;/a&gt; JavaScript specifically tailored for these situations.&lt;/li&gt;
&lt;li&gt;Put that into my &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/_includes/error.html"&gt;404.html&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This solution is specific to my use case, but you can get the idea.&lt;/p&gt;
</description></item><item><title>Wonder without Googling</title><link>https://www.saicharan.in/blog/2013/01/01/wonder-without-googling</link><pubDate>Tue, 01 Jan 2013 21:15:12 +0000</pubDate><guid>https://www.saicharan.in/blog/2013/01/01/wonder-without-googling</guid><description>&lt;p&gt;Great advice on so many levels. Happy New Year!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Wonder without googling.&lt;/p&gt;
&lt;/blockquote&gt;
</description></item><item><title>When you have tasted flight</title><link>https://www.saicharan.in/blog/2012/09/23/when-you-have-tasted-flight</link><pubDate>Sun, 23 Sep 2012 14:13:18 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/09/23/when-you-have-tasted-flight</guid><description>&lt;blockquote&gt;
&lt;p&gt;When once you have tasted flight, you will forever walk the earth with your eyes turned skyward, for there you have been and there you will always long to return.&lt;/p&gt;
&lt;/blockquote&gt;— Leonardo da Vinci (seen on &lt;a href="http://www.markshuttleworth.com/"&gt;Mark Shuttleworth&lt;/a&gt;&amp;rsquo;s blog.)</description></item><item><title>Import Skype contacts into Gmail</title><link>https://www.saicharan.in/blog/2012/07/31/import-skype-contacts-into-gmail</link><pubDate>Tue, 31 Jul 2012 17:09:11 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/07/31/import-skype-contacts-into-gmail</guid><description>&lt;p&gt;Gmail&amp;rsquo;s contact details includes provision to add usernames from other IM networks. Having this in one place is very handy on the Android phone, for instance.&lt;/p&gt;
&lt;p&gt;Naïvely exporting Skype&amp;rsquo;s address book via Skype &amp;gt; Contacts &amp;gt; Advanced &amp;gt; Backup contacts to file &amp;amp; importing them into Gmail isn&amp;rsquo;t sufficient. This process imports the contact information alright, but not the skype names, defeating the purpose of the import.&lt;/p&gt;
&lt;p&gt;A little digging up reveals the culprit. Skype uses the vCard v3.0 Property &lt;code&gt;X-SKYPE-USERNAME:&lt;/code&gt;, while Gmail expects &lt;code&gt;X-SKYPE:&lt;/code&gt;. So, here is some wizardry to fix this (on a Linux/Unix machine).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Export contacts to skypename.vcf file from Skype &amp;gt; Contacts &amp;gt; Advanced &amp;gt; Backup contacts to file, and copy it to a linux machine.&lt;/li&gt;
&lt;li&gt;I did not want the pictures of my Skype contacts to be imported. I filtered out the relevant fields using:
egrep &amp;ldquo;^BEGIN:|^END:|^VERSION:|^TEL;|^EMAIL:|^ADR:|^N:|^FN:|^X-SKYPE-USERNAME:&amp;rdquo; skypename.vcf &amp;gt; skype-cleaned.vcf&lt;/li&gt;
&lt;li&gt;Change the vCard property to match Gmail&amp;rsquo;s expectations:
sed -i s/-USERNAME// skype-cleaned.vcf&lt;/li&gt;
&lt;li&gt;Prettify the vCard file to include newlines after each vCard entry &lt;em&gt;(note: this step is not absolutely necessary)&lt;/em&gt;.
sed -i &amp;ldquo;s/^END:VCARD/END:VCARD\&lt;code&gt;echo -e '\n\n'&lt;/code&gt;/g&amp;rdquo; skype-cleaned.vcf&lt;/li&gt;
&lt;li&gt;Import skype-cleaned.vcf into Gmail &amp;amp; choose to merge contacts appropriately.&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Installing mosh from source</title><link>https://www.saicharan.in/blog/2012/07/27/installing-mosh-from-source</link><pubDate>Fri, 27 Jul 2012 17:05:41 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/07/27/installing-mosh-from-source</guid><description>&lt;p&gt;Installing &lt;a href="http://mosh.mit.edu/"&gt;mosh&lt;/a&gt;, the MObileSHell on a linux box with no &lt;code&gt;sudo&lt;/code&gt; access can be quite a bit of a pain. And, with many users working with shared, managed linux gateways, I suppose this could be useful to a larger audience.&lt;/p&gt;
&lt;p&gt;In this note, I will attempt to install &lt;code&gt;mosh&lt;/code&gt; into the home directory of user &lt;code&gt;sai&lt;/code&gt; with home directory at &lt;code&gt;/home/sai&lt;/code&gt; assuming user &lt;code&gt;sai&lt;/code&gt; does not have root access on this machine. This note further assumes that a basic development environment is already set up and available.&lt;/p&gt;
&lt;p&gt;Installation notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First create the local directory to install into: &lt;code&gt;mkdir -p ~/usr&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;As listed in the &lt;a href="http://mosh.mit.edu/#getting"&gt;building from source&lt;/a&gt; section, &lt;a href="http://code.google.com/p/protobuf/"&gt;Protocol Buffers&lt;/a&gt; and &lt;a href="http://search.cpan.org/~rgiersig/IO-Tty-1.07/Pty.pm"&gt;IO::Pty&lt;/a&gt; Perl module. To do this, download Protocol Buffers, untar and run:
./configure &amp;ndash;prefix=/home/sai/usr &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make check &amp;amp;&amp;amp; make install
from the source root directory.&lt;/li&gt;
&lt;li&gt;Download mosh, untar and run
export PKG_CONFIG_PATH=/home/sai/usr/lib/pkgconfig &amp;amp;&amp;amp; ./configure &amp;ndash;prefix=/home/sai/usr &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install
from the mosh source root directory.&lt;/li&gt;
&lt;li&gt;Note that IO::Pty is not needed at compile/install time. Instead, it is needed to run mosh, which is a perl script. The steps are a little more involved, but I am going to gloss over the details here. Feel free to seek clarifications in the comments section below.
&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;cpan&lt;/code&gt; (I chose &amp;rsquo;no&amp;rsquo; for manual configuration).&lt;/li&gt;
&lt;li&gt;Inside cpan, run &lt;code&gt;install IO::Tty&lt;/code&gt;; if the files fail to download, download the files manually, transfer to &lt;code&gt;~/.cpan/sources/authors/&amp;lt;appropriate-path&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;These following two commands allow local install paths from within cpan command. Source: &lt;a href="http://www.perlmonks.org/?node_id=630027"&gt;PerlMonks&lt;/a&gt;.
cpan&amp;gt; o conf mbuildpl_arg &amp;ldquo;&amp;ndash;install_base /home/sai/usr/local/&amp;rdquo;
cpan&amp;gt; o conf makepl_arg &amp;ldquo;PREFIX=/home/sai/usr/local/&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Again, run &lt;code&gt;install IO::Tty&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add these lines to your .bashrc or appropriate startup shell configuration file:
export PERL5LIB=$PERL5LIB:/home/sai/usr/local/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/sai/usr/lib:
export PATH=$PATH:/home/sai/bin:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thats it. You should now be able to run &lt;code&gt;mosh&lt;/code&gt;. To test, you can run: &lt;code&gt;mosh localhost&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;. I used &lt;code&gt;cpan&lt;/code&gt; since &lt;code&gt;cpanm&lt;/code&gt; was not available on the system.&lt;/p&gt;
</description></item><item><title>The silent majority of experts</title><link>https://www.saicharan.in/blog/2012/07/14/the-silent-majority-of-experts</link><pubDate>Sat, 14 Jul 2012 09:14:58 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/07/14/the-silent-majority-of-experts</guid><description>&lt;p&gt;James Hague, in a piece titled &lt;em&gt;&lt;a href="http://prog21.dadgum.com/143.html"&gt;The Silent Majority of Experts&lt;/a&gt;&lt;/em&gt;, quotes &lt;a href="http://www.forth.com/resources/evolution/"&gt;Elizabeth Rather&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;hellip;there are people solving real problems with Forth, but they don&amp;rsquo;t hang-out in the newsgroup.&lt;/p&gt;
&lt;/blockquote&gt;
</description></item><item><title>Liquid, Fluid site layout</title><link>https://www.saicharan.in/blog/2012/07/12/liquid-fluid-site-layout</link><pubDate>Thu, 12 Jul 2012 22:48:38 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/07/12/liquid-fluid-site-layout</guid><description>&lt;p&gt;Inspired by &lt;a href="http://en.wikipedia.org"&gt;wikipedia&lt;/a&gt;, &lt;a href="http://www.marco.org"&gt;marco.org&lt;/a&gt; and other gorgeous websites, I added the necessary CSS for this website to adapt dynamically with varying layouts &amp;ndash; note: no Javascript, just plain CSS. The solution is two fold:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag, add the following &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag:
&lt;meta name="viewport" content="width=device-width" /&gt;&lt;/li&gt;
&lt;li&gt;In the CSS file, add special CSS rules for varying screen sizes using this syntax:
@media (max-width: 1024px) {
/* CSS rules for screen sizes &amp;lt; 1024 px */
}
And yes, as always you may need to provide IE specific rules/overrides in a separate CSS file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Go ahead and try it: for the most &amp;rsquo;effect&amp;rsquo; &amp;amp; live preview, resize your browser window. Or view this site on your tablet or mobile device.&lt;/p&gt;
</description></item><item><title>DNS migrated to Amazon's Route53</title><link>https://www.saicharan.in/blog/2012/07/11/dns-migrated-to-amazons-route53</link><pubDate>Wed, 11 Jul 2012 15:11:52 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/07/11/dns-migrated-to-amazons-route53</guid><description>&lt;p&gt;As of 3PM PST on 07/10/2012, the DNS provide for my domain &lt;a href="http://www.saicharan.in"&gt;saicharan.in&lt;/a&gt; is Amazon&amp;rsquo;s &lt;a href="https://aws.amazon.com/route53/"&gt;Route53&lt;/a&gt; service. Here is the migration log.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$ sudo pip install cli53&lt;/code&gt; (see &lt;a href="https://github.com/barnybug/cli53/#installation"&gt;installation notes&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Choose to &lt;a href="https://www.gandi.net/admin/domain?filter.zone.id=%3Czoneid%3E"&gt;&amp;lsquo;see the zone file&amp;rsquo;&lt;/a&gt; on Gandi.net&amp;rsquo;s &lt;a href="https://www.gandi.net/admin/domain/zone/list#main"&gt;DNS zones page&lt;/a&gt; and copy the zone file contents.&lt;/li&gt;
&lt;li&gt;Create a file name saicharan.in containing the copy of the zone file from previous step.&lt;/li&gt;
&lt;li&gt;As explained &lt;a href="http://opensourcehacker.com/2011/11/23/migrating-from-bind-dns-servers-to-amazon-route-53-by-using-cli53/"&gt;here&lt;/a&gt; unlike &lt;a href="http://en.wikipedia.org/wiki/BIND"&gt;BIND&lt;/a&gt;, cli53 does not infer &lt;code&gt;$ORIGIN&lt;/code&gt; from the zone file name. For import to be successful, add the following line to the top of the file from the previous step.
$ORIGIN saicharan.in&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ touch ~/.boto&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the following to ~/.boto:
[Credentials]
aws_access_key_id = [your AWS ID]
aws_secret_access_key = [your AWS key]&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ cli53 create saicharan.in&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ cli53 import example.com --file saicharan.in --replace --wait&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Change saicharan.in&amp;rsquo;s DNS servers on Gandi.net&amp;rsquo;s control panel. The new name servers can be got by running:
$ cli53 info saicharan.in&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Chrome Sync with Google Apps Accounts</title><link>https://www.saicharan.in/blog/2012/05/09/chrome-sync-with-google-apps-accounts</link><pubDate>Wed, 09 May 2012 22:04:09 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/05/09/chrome-sync-with-google-apps-accounts</guid><description>To enable &lt;a href="http://support.google.com/chrome/bin/answer.py?hl=en&amp;amp;answer=165139"&gt;Chrome Sync&lt;/a&gt; with a &lt;a href="https://google.com/a/saicharan.in/"&gt;Google Apps account&lt;/a&gt;, the admin must enable this feature. Instructions are in &lt;a href="https://code.google.com/p/chromium/issues/detail?id=19589#c64"&gt;comment 64&lt;/a&gt; as suggested on &lt;a href="http://stackoverflow.com/q/8566726/162471"&gt;stackoverflow.com&lt;/a&gt;.</description></item><item><title>RHEL RPM Repositories</title><link>https://www.saicharan.in/blog/2012/05/03/rhel-rpm-repositories</link><pubDate>Thu, 03 May 2012 19:46:35 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/05/03/rhel-rpm-repositories</guid><description>&lt;p&gt;For CentOS/RHEL, additional common packages are available at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EPEL 6 (i386): &lt;a href="http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm"&gt;http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;rpmforge (i386, EL 6): &lt;a href="http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.i386.rpm"&gt;http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.i386.rpm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For instance, &lt;code&gt;tmux&lt;/code&gt; is available on EPEL while &lt;code&gt;htop&lt;/code&gt; is available on rpmforge.&lt;/p&gt;
</description></item><item><title>Export &amp; Import of GPG Keys</title><link>https://www.saicharan.in/blog/2012/05/01/export-import-of-gpg-keys</link><pubDate>Tue, 01 May 2012 01:07:55 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/05/01/export-import-of-gpg-keys</guid><description>&lt;p&gt;To remedy a case of corrupted gpg keys on Linux (if you have the GPGKeys elsewhere):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;First create a &amp;lsquo;Backup&amp;rsquo; [on Windows, via the GPG4Win &amp;gt; GNU Privacy Assistant (GPA)].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next, copy the backup file to Linux &amp;amp; on Linux, run: &lt;code&gt;gpg &amp;ndash;import /path/to/backup/file&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lastly, set the necessary level of trust:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gpg --edit-key &amp;lt;uid&amp;gt;;
gpg&amp;gt; trust
...
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
...
Your decision? 1
gpg&amp;gt; quit
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thankfully, a trusted Windows machine had GPG4Win which allowed me to export the key and saving my day!&lt;/p&gt;
</description></item><item><title>FreeNX on Ubuntu</title><link>https://www.saicharan.in/blog/2012/04/29/freenx-on-ubuntu</link><pubDate>Sun, 29 Apr 2012 21:41:37 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/04/29/freenx-on-ubuntu</guid><description>&lt;p&gt;I have been a VNC user (both &lt;a href="http://www.realvnc.com"&gt;RealVNC&lt;/a&gt; &amp;amp; &lt;a href="http://www.tightvnc.com/"&gt;TightVNC&lt;/a&gt;) for a number of years. It definitely has advantages such as &amp;ldquo;accessing your &amp;lsquo;real&amp;rsquo; desktop&amp;rdquo;. But, it is slightly annoying to know that if your remote monitor is on, anybody watching it can actually see your screen without your knowledge. Further, with different screen resolutions on the remote and local systems, VNC only &amp;lsquo;scales&amp;rsquo; the display which is not very nice especially when resolution is scaled down.&lt;/p&gt;
&lt;p&gt;Which is where the alternative of &lt;a href="www.nomachine.com"&gt;NoMachine&lt;/a&gt; turned up on my radar. On my Ubuntu desktop, I installed the &lt;a href="http://www.nomachine.com/select-package.php?os=linux&amp;amp;id=1"&gt;NX Free Edition&lt;/a&gt; software; client, node &amp;amp; server: in that order. On my windows, I set up the &lt;a href="http://www.nomachine.com/download-package.php?Prod_Id=3655"&gt;NX Windows Client&lt;/a&gt;. Set up a tunnel from my Windows machine to my remote desktop, which is needed since my desktop is behind a gateway.&lt;/p&gt;
&lt;p&gt;Finally, to access the GNOME session, I had to change the configuration as &lt;a href="http://ubuntuforums.org/showpost.php?p=11586915&amp;amp;postcount=8"&gt;suggested here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/usr/NX/etc/node.cfg
&lt;p&gt;Comment out this line:
CommandStartGnome = &amp;quot;/etc/X11/Xsession gnome-session&amp;quot;&lt;/p&gt;
&lt;p&gt;And replace it with this line:
CommandStartGnome = &amp;quot;/usr/bin/gnome-session &amp;ndash;session=gnome-classic&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The screen resolution with NX is remarkably crisp &amp;amp; clear. Now I can get to work on remote GUI without squinting!&lt;/p&gt;
&lt;p&gt;Update: To access an existing X11 session, choose &amp;lsquo;Shadow&amp;rsquo; as the Desktop type. (See &lt;a href="http://serverfault.com/a/44326/88592"&gt;this link&lt;/a&gt; for details).&lt;/p&gt;
</description></item><item><title>Dtrace on Linux (Ubuntu)</title><link>https://www.saicharan.in/blog/2012/04/27/dtrace-on-linux-ubuntu</link><pubDate>Fri, 27 Apr 2012 18:17:37 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/04/27/dtrace-on-linux-ubuntu</guid><description>&lt;p&gt;So I needed to use on &lt;a href="http://www.crisp.demon.co.uk/"&gt;Dtrace&lt;/a&gt; on Linux. I picked the &lt;a href="ftp://crisp.dyndns-server.com/pub/release/website/dtrace/dtrace-20120409.tar.bz2"&gt;April 2012&lt;/a&gt; release of the &lt;a href="ftp://crisp.dyndns-server.com/pub/release/website/dtrace"&gt;software&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Followed these instructions from &lt;a href="http://mustalikachwala.blogspot.com/2012/03/lazyswamp-dtrace-on-linux.html"&gt;Mustali Kachwala&amp;rsquo;s blog&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ bunzip2 &amp;lt; dtrace-*.bz2 | tar xvf -
$ sudo apt-get install bison
$ sudo apt-get install flex
$ sudo apt-get install zlib1g-dev
$ sudo apt-get install libelf-dev 
$ cd dtrace-[TAB]
$ make all 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt; $ make install&lt;/code&gt; failed to find gnu/stubs-32.h. As suggested on &lt;a href="http://stackoverflow.com/a/7412698/162471"&gt;Stackoverflow&lt;/a&gt;, I did &lt;code&gt; sudo apt-get install libc6-dev-i386&lt;/code&gt;. Note that &lt;code&gt; sudo apt-get install libc6-dev&lt;/code&gt; did not work; probably &lt;a href="http://stackoverflow.com/questions/7412548/gnu-stubs-32-h-no-such-file-or-directory#comment8957902_7412698"&gt;Timothy&amp;rsquo;s comment&lt;/a&gt; in the same SO thread is a pertinent explanation. &lt;code&gt; make all&lt;/code&gt; was successful, but notified me that &lt;code&gt; build/ctfconverter&lt;/code&gt; did not exist, so no &lt;code&gt; linux*.ctf&lt;/code&gt; files were produced; but that did not seem an error; just a warning.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# First, I needed to comment out the lines 
# that attempted to install *.ctf files.
$ sudo make install 
$ sudo make load
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that the &lt;code&gt; install&lt;/code&gt; script installed &lt;code&gt; dtrace&lt;/code&gt; at &lt;code&gt; /usr/sbin&lt;/code&gt;, and not &lt;code&gt; /usr/bin&lt;/code&gt;. This distinction is important since there is a default version of &lt;code&gt; dtrace&lt;/code&gt; at &lt;code&gt; /usr/bin/dtrace&lt;/code&gt;, which does NOT take most of the options that the newly compiled version of &lt;code&gt;dtrace&lt;/code&gt; accepts.&lt;/p&gt;
&lt;p&gt;Then &amp;amp; only then did the &lt;a href="https://wikis.oracle.com/display/DTrace/Introduction"&gt;options &amp;amp; examples on the wiki&lt;/a&gt; begin to work.&lt;/p&gt;
</description></item><item><title>Remembering the Neverhood Chronicles</title><link>https://www.saicharan.in/blog/2012/03/29/remembering-the-neverhood-chronicles</link><pubDate>Thu, 29 Mar 2012 18:06:09 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/03/29/remembering-the-neverhood-chronicles</guid><description>&lt;p&gt;Since this morning, the memory of a computer game that I played as a kid kept surfacing in my head. Weirdly, the name kept eluding me; until a Google search for &lt;a href="https://www.google.com/search?q=computer+clay+game"&gt;&amp;lsquo;computer clay game&amp;rsquo;&lt;/a&gt; turned up the one and only &amp;lsquo;Neverhood Chronicles&amp;rsquo; :)&lt;/p&gt;
&lt;p&gt;Here is an image sourced from &lt;a href="http://en.wikipedia.org/wiki/The_Neverhood"&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/The_Neverhood"&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/en/1/12/The_Neverhood_-_box_art.jpg" alt="The Neverhood" title="The Neverhood!"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The opening line is unassumingly simple:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;Hello. Me Willie. Me Willie Trombone. You read this, you do good. Willie happy. &lt;br /&gt;
You play Neverhood you do more good. And look out for bad. &lt;br /&gt;
Willie knows, bad is always where you forget to look&lt;/em&gt;.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well, getting it running was painstakingly hard, even given its extremely modest system requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pentium 75 mhz&lt;/li&gt;
&lt;li&gt;8 Mg RAM (16 recommended)&lt;/li&gt;
&lt;li&gt;1 Mg VRAM&lt;/li&gt;
&lt;li&gt;SVGA monitor&lt;/li&gt;
&lt;li&gt;Quad speed CD ROM&lt;/li&gt;
&lt;li&gt;8-bit sound card &amp;amp; speakers (16-bit recommended)&lt;/li&gt;
&lt;li&gt;10 Mg available hard disk space for Installation&lt;/li&gt;
&lt;li&gt;Microsoft Windows 95.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Luckily, I tend to preserve my old original CDs/DVDs. And, with a little help from the free &lt;a href="http://www.microsoft.com/windows/virtual-pc/default.aspx"&gt;Windows VirtualPC&lt;/a&gt;, its pure gεεk joy!&lt;/p&gt;
</description></item><item><title>Migrated to Gandi.net</title><link>https://www.saicharan.in/blog/2012/03/25/migrating-to-gandinet</link><pubDate>Sun, 25 Mar 2012 16:15:43 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/03/25/migrating-to-gandinet</guid><description>&lt;p&gt;For various reasons &amp;amp; non-reasons, I decided to move my &lt;a href="http://saicharan.in"&gt;domain&lt;/a&gt; from &lt;a href="http://domains.nettigritty.com"&gt;Nettigritty&lt;/a&gt; to &lt;a href="http://gandi.net"&gt;Gandi.net&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As of this writing, the transition has been successful. With Nettigritty not my domain registrar, I also decided to move away from their hosting solution. If you have been following this blog, as noted &lt;a href="https://www.saicharan.in/blog/2011/08/22/migrating-to-jekyll/"&gt;here&lt;/a&gt;, &lt;a href="https://www.saicharan.in/blog/2011/08/24/static-blog-using-jekyll/"&gt;here&lt;/a&gt; &amp;amp; &lt;a href="https://www.saicharan.in/blog/colophon.html"&gt;here&lt;/a&gt;, this blog now runs as a &lt;a href="http://jekyllrb.com"&gt;Jekyll&lt;/a&gt; generated, &lt;a href="https://github.com/scharan/scharan.github.com/"&gt;Github&lt;/a&gt; hosted static site. I recently successfully experimented with Amazon&amp;rsquo;s &lt;a href="http://aws.amazon.com/s3/"&gt;S3&lt;/a&gt; to run a static site.&lt;/p&gt;
&lt;p&gt;Since this website does not have too much traffic I realize I don&amp;rsquo;t need a dedicated hosting solution. Therefore, for purposes of economy, speed &amp;amp; availability, I decided to run it off Amazon S3. So, this page you are seeing is now served off S3.&lt;/p&gt;
&lt;p&gt;Getting here has not been completely straight forward, so the rest of this piece is a little chronicle of the extras:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DNS setup on Gandi.net from scratch.&lt;/li&gt;
&lt;li&gt;Without a hosting provider, this site does not have a real A record. So, people who visit &lt;a href="http://saicharan.in"&gt;http://saicharan.in&lt;/a&gt; would then get an error message. As naked domains cannot be DNS mapped with CNAME records, a little &lt;a href="https://forums.aws.amazon.com/thread.jspa?threadID=55995"&gt;digging&lt;/a&gt; around revealed &lt;a href="http://wwwizer.com"&gt;wwwizer.com&lt;/a&gt; as a free(!) service for this very purpose. However, I also found that Google Apps also provides this service for Apps enabled sites. Since this domain has also been setup for Google Apps, I simply set up the appropriate A records as listed at on the &lt;a href="https://www.google.com/a/cpanel/saicharan.in/DomainSettingsDomains"&gt;dashboard page&lt;/a&gt; (warning: access restricted page). In summary, the DNS set up is:
&lt;ul&gt;
&lt;li&gt;saicharan.in. 10800 IN A 216.239.36.21&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.saicharan.in"&gt;www.saicharan.in&lt;/a&gt;. 10800 IN CNAME saicharan.in.s3-website-us-east-1.amazonaws.com.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set up S3 bucket, add bucket policy and enable bucket as a website. See &lt;a href="http://aws.typepad.com/aws/2011/02/host-your-static-website-on-amazon-s3.html"&gt;this&lt;/a&gt; for details.&lt;/li&gt;
&lt;li&gt;Wait for DNS entries to propagate.&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Give it five minutes</title><link>https://www.saicharan.in/blog/2012/03/01/give-it-five-minutes</link><pubDate>Thu, 01 Mar 2012 22:10:45 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/03/01/give-it-five-minutes</guid><description>&lt;blockquote&gt;
&lt;p&gt;Give it five minutes&lt;/p&gt;
&lt;/blockquote&gt;— Absolutely true wisdom from 37signals.com&amp;rsquo;s &lt;a href="https://37signals.com/svn/posts/3124-give-it-five-minutes"&gt;Jason&lt;/a&gt;.</description></item><item><title>Anyconnect VPN on Ubuntu x64</title><link>https://www.saicharan.in/blog/2012/02/04/anyconnect-vpn-on-ubuntu-x64</link><pubDate>Sat, 04 Feb 2012 12:16:28 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/02/04/anyconnect-vpn-on-ubuntu-x64</guid><description>Connecting to the VPN website to launch Anyconnect installer was not helping &amp;ndash; either with Firefox, nor with Chrome. The Applet kept loading to eternity with no installation. Chanced upon &lt;a href="http://blog.mattwoodward.com/installing-cisco-anyconnect-on-64-bit-ubuntu"&gt;http://blog.mattwoodward.com/installing-cisco-anyconnect-on-64-bit-ubuntu&lt;/a&gt;, which suggested that on Firefox, I disable the IcedTea-Web plugin for Java Applets &amp;ndash; and it worked. After the disable, I was given a link to download the installer for &amp;lsquo;Linux _x86_64&amp;rsquo; platforms, which when run installed the VPN without any further hassle.</description></item><item><title>Quest for a good Antivirus</title><link>https://www.saicharan.in/blog/2012/01/26/quest-for-a-good-free-antivirus</link><pubDate>Thu, 26 Jan 2012 11:55:41 +0000</pubDate><guid>https://www.saicharan.in/blog/2012/01/26/quest-for-a-good-free-antivirus</guid><description>&lt;p&gt;I have long been a loyal customer of Norton Internet Security product &amp;ndash; and I can vouch for its comprehensive, effective protection. However, when my most recent subscription expired, due to my Grad-student budget I decided to try other alternatives that I had access to via other subscriptions, or free software.&lt;/p&gt;
&lt;p&gt;My ISP, Charter Inc. provides its users a security solution titled &lt;a href="http://www.myaccount.charter.com/customers/supportgeneral.aspx?pagetype=1"&gt;&amp;lsquo;Charter Security Suite&amp;rsquo;&lt;/a&gt; which in turn is an offering from F-Secure. While I have been skeptic of anything other than Symantec/Mc Afee/Zone Alarm, I decided to give it a try. After all, F-Secure is a for-profit organization and I must be paying for it indirectly (by paying my ISP).&lt;/p&gt;
&lt;p&gt;It turns out to be quite noisy. I have grown used to Norton silently making decisions for me based on its &lt;a href="http://www.symantec.com/about/profile/universityresearch/sharing.jsp"&gt;Symantec WINE&lt;/a&gt;. But being an early adopter, I occasionally did manually choose my trust levels with Norton. The Charter Security Suite on the other hand, asked me if I trusted Google Talk, Yahoo Messenger and nearly every other prevalent software out there.&lt;/p&gt;
&lt;p&gt;And, curiously, this antivirus was not the first program to startup. It usually started after quite a few software that connect to the Internet were up and running &amp;ndash; bad, right?&lt;/p&gt;
&lt;p&gt;And then there was that fiasco with one software update &amp;ndash; Charter&amp;rsquo;s suite asked me if I trusted the exact same binary about 30 times! That was the limit.&lt;/p&gt;
&lt;p&gt;I had the free &lt;a href="http://windows.microsoft.com/en-US/windows/products/security-essentials"&gt;Microsoft Security Essentials&lt;/a&gt; running on my parent&amp;rsquo;s PCs and they never mentioned it nor was there any incident of virus on their systems - a good thing. So I decided to try it. Install was a breeze and the quick scan completed in under 15 minutes without affecting my system performance. Nice!&lt;/p&gt;
&lt;p&gt;But I was not comfortable with no firewall on my Windows PC &amp;ndash; enter &lt;a href="http://www.zonealarm.com/security/en-us/zonealarm-pc-security-free-firewall.htm"&gt;Zone Alarm&lt;/a&gt;. I had used it a master&amp;rsquo;s student and remember being very satisfied with it. The download size (~150MB) was a bit of a brow-riser, but the install and setup was fantastic. Funnily, I kept waiting for ZoneAlarm to pop-up and ask me to set up something &amp;ndash; but good thing I was disappointed there. I then dug into the settings to find all in good shape &amp;ndash; software that I trusted was already trusted; no pesky pop-ups.&lt;/p&gt;
&lt;p&gt;So that is my current setup - Microsoft Security Essentials and ZoneAlarm Firewall - both free &amp;amp; so far so good.&lt;/p&gt;
</description></item><item><title>Reading on the Internet</title><link>https://www.saicharan.in/blog/2011/11/01/reading-on-the-internet</link><pubDate>Tue, 01 Nov 2011 14:52:19 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/11/01/reading-on-the-internet</guid><description>&lt;p&gt;I tend to have this belief that one spends a fair amount of your time reading on the internet. If that is true now or in foreseeable future, you may want to read on.&lt;/p&gt;
&lt;p&gt;There has been a fair amount of work on making the world a more readable place. Of these, three tools are on my radar: &lt;a href="http://readability.com"&gt;http://readability.com&lt;/a&gt;, &lt;a href="http://instapaper.com"&gt;http://instapaper.com&lt;/a&gt; and Safari&amp;rsquo;s Reader mode.&lt;/p&gt;
&lt;p&gt;Readability.com specializes in making your reading experience a good one: it removes clutter, ads and all that and shows you just text. And renders it beautifully at that. They have a paid app and also a free bookmarklet that lets you do this.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://Instapaper.com"&gt;http://Instapaper.com&lt;/a&gt; is basically a reading list (read later option) that you can access from any browser with a native iPad/iPhone/iPod paid app. However, my interest in this is mostly the bookmarlket that cleans up the text.&lt;/p&gt;
&lt;p&gt;On the heels of Instapaper and Readability, Apple released a browser in-built &amp;lsquo;Reader&amp;rsquo; mode. Simply click on the reader button in the far end of the address bar for web-pages that are &amp;lsquo;readable&amp;rsquo; and you are presented with a fantastic clean view of the content. So far, my favorite has been readability.com&amp;rsquo;s bookmarklet, but now I find myself doing all my reading in Safari browser (available even for PC). See this for what I mean: &lt;a href="http://www.apple.com/safari/whats-new.html#gallery-read-reader"&gt;http://www.apple.com/safari/whats-new.html#gallery-read-reader&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Very easy on the eyes and zero distraction. Highly Recommended.&lt;/p&gt;
</description></item><item><title>Default runlevel on CentOS</title><link>https://www.saicharan.in/blog/2011/10/26/default-runlevel-on-centos</link><pubDate>Wed, 26 Oct 2011 08:20:18 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/10/26/default-runlevel-on-centos</guid><description>&lt;p&gt;A reminder to self (this should work for all BSD-like systems, including Fedora &amp;amp; RHEL) —&lt;/p&gt;
&lt;p&gt;Edit /etc/inittab as root. The number after the first colon after id is the default runlevel.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;id:3:initdefault:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;BTW, I prefer runlevel 3 (no GUI).&lt;/p&gt;
&lt;h5 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.centos.org/docs/5/html/Installation_Guide-en-US/s1-boot-init-shutdown-sysv.html"&gt;http://www.centos.org/docs/5/html/Installation_Guide-en-US/s1-boot-init-shutdown-sysv.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Ubuntu 11.10, PuTTy, tmux &amp; UTF-8</title><link>https://www.saicharan.in/blog/2011/10/17/ubuntu-1110-putty-tmux-utf8</link><pubDate>Mon, 17 Oct 2011 01:46:22 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/10/17/ubuntu-1110-putty-tmux-utf8</guid><description>After the upgrade today, firing up a tmux session via PuTTy with my usual &amp;ldquo;Session Settings &amp;gt; Translation &amp;gt; Remote Character Set&amp;rdquo; pointing to &amp;ldquo;ISO-8859-6:1999 (Latin/Arabic)&amp;rdquo;, I found that line drawings were all messed up: the lines were drawn with the &amp;lsquo;a&amp;rsquo; like characters, instead of lines. It occured to me that the newly updated Ubuntu ncursesw libraries and/or tmux may have fixed something. Promptly switching to &amp;lsquo;UTF-8&amp;rsquo; as the remote character set brought back the good looking line-drawings.</description></item><item><title>Gitweb with 'side-by-side' diff</title><link>https://www.saicharan.in/blog/2011/10/09/gitweb-with-sidebyside-diff</link><pubDate>Sun, 09 Oct 2011 23:20:40 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/10/09/gitweb-with-sidebyside-diff</guid><description>&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: With git v1.7.9.5, this hack below is not needed anymore. Gitweb comes with sidebyside diff.&lt;/p&gt;
&lt;p&gt;Bonus: Simultaneously scroll left and right files with overflow.&lt;/p&gt;
&lt;p&gt;Dependencies: &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Usage: Simply include jQuery in gitweb/gitweb.cgi (within the head tag).&lt;/p&gt;
&lt;p&gt;Future work: Going by &lt;a href="http://kerneltrap.org/mailarchive/git/2009/6/11/4701"&gt;this thread&lt;/a&gt; on kerneltrap.org, &amp;lsquo;side-by-side&amp;rsquo; diff appears to have been on the team&amp;rsquo;s TODO list and never gotton around to being implemented. So, except for the simultaneous scrolling, I intend to port this to Perl and hope to get it integrated into Gitweb core. Simultaneous scrolling needs to be done in Javascript and the fact that external dependencies are &lt;a href="http://kerneltrap.org/mailarchive/git/2009/6/11/4701"&gt;frowned upon&lt;/a&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note that we frown upon introducing extra dependencies for gitweb, unless they are optional, and best detected automatically.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;scrolling needs to be handled separately in gitweb.js (the currently implementation depends on &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Screenshot: &lt;a href="https://www.saicharan.in/images/side-by-side-diff-with-scroll.jpg"&gt;&lt;img src="https://www.saicharan.in/images/side-by-side-diff-with-scroll.jpg" alt="Gitweb side-by-side diff"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Gist: &lt;a href="https://gist.github.com/1274726"&gt;https://gist.github.com/1274726&lt;/a&gt;&lt;/p&gt;
&lt;script src="https://gist.github.com/1274726.js"&gt; &lt;/script&gt;
</description></item><item><title>Richard Stallman &amp; Steve Jobs</title><link>https://www.saicharan.in/blog/2011/10/08/richard-stallman--steve-jobs</link><pubDate>Sat, 08 Oct 2011 12:24:16 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/10/08/richard-stallman--steve-jobs</guid><description>&lt;p&gt;Richard Stallman &lt;a href="http://stallman.org/archives/2011-jul-oct.html#06_October_2011_(Steve_Jobs)"&gt;wrote&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Steve Jobs, the pioneer of the computer as a jail made cool, designed to sever fools from their freedom, has died.&lt;/p&gt;
&lt;p&gt;As Chicago Mayor Harold Washington said of the corrupt former Mayor Daley, &amp;ldquo;I&amp;rsquo;m not glad he&amp;rsquo;s dead, but I&amp;rsquo;m glad he&amp;rsquo;s gone.&amp;rdquo; Nobody deserves to have to die - not Jobs, not Mr. Bill, not even people guilty of bigger evils than theirs. But we all deserve the end of Jobs&amp;rsquo; malign influence on people&amp;rsquo;s computing.&lt;/p&gt;
&lt;p&gt;Unfortunately, that influence continues despite his absence. We can only hope his successors, as they attempt to carry on his legacy, will be less effective.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I first read it, I was shocked. Somehow, my respect and admiration for Steve, and the news of his demise seemed to confuse the whole thing. Perhaps, I thought, Stallman did not wait &amp;rsquo;the appropriate amount of time&amp;rsquo; after Jobs&amp;rsquo; passing - but hey, what is the appropriate amount of time? As &lt;a href="http://daringfireball.net/2011/10/thoughts_and_observations_iphone_4s"&gt;Gruber&lt;/a&gt; put it, &amp;lsquo;&amp;hellip;life goes on.&amp;rsquo;&lt;/p&gt;
&lt;p&gt;I could sense a fringe thought that I seemed to be actively fending away: that there was some truth in Stallman&amp;rsquo;s words; and that he was being very respectful in what he said. But then, I could not place my thoughts - like I mentioned earlier, I seemed to be in a limbo of sorts.&lt;/p&gt;
&lt;p&gt;And then there was light! Dave Winer, the guy credited with inventing RSS, first tweeted &lt;a href="https://twitter.com/#!/davewiner/status/122417111640453121"&gt;this&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Stallman&amp;rsquo;s epitaph for Jobs is appropriate and respectful. &lt;a href="http://r2.ly/7f3u"&gt;http://r2.ly/7f3u&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and followed up with &lt;a href="http://scripting.com/stories/2011/10/08/stallmanSteve.html"&gt;this&lt;/a&gt;. And I seem to agree - Stallman was right; and appropriately respectful too. Brilliant, well thought out &amp;amp; effectively communicating piece of writing from Dave.&lt;/p&gt;
&lt;p&gt;To relate with the concluding paragraph from Stallman, it helps to be familiar with Apple&amp;rsquo;s &amp;lsquo;Think Different&amp;rsquo; ad campaign. A transcript of it is here: &lt;a href="http://saicharan.in/blog/2011/10/06/heres-to-the-crazy-ones/"&gt;http://saicharan.in/blog/2011/10/06/heres-to-the-crazy-ones/&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Here's to the Crazy Ones</title><link>https://www.saicharan.in/blog/2011/10/06/heres-to-the-crazy-ones</link><pubDate>Thu, 06 Oct 2011 18:56:06 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/10/06/heres-to-the-crazy-ones</guid><description>&lt;p&gt;&lt;a href="http://www.loopinsight.com/"&gt;The Loop&lt;/a&gt; linked to a &lt;a href="http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=8rwsuXHA7RA"&gt;video&lt;/a&gt; on Youtube and titled it &lt;a href="http://www.loopinsight.com/2011/10/06/steve-jobs-narrates-the-crazy-ones/"&gt;&amp;lsquo;Steve Jobs narrates The Crazy Ones&amp;rsquo;&lt;/a&gt;. Here is a transcription (puctuation &amp;amp; emphasis is as I inferred, listening):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Here is to the crazy ones. The misfits. The rebels. The trouble makers. The round pegs in the square holes; the ones who see things differently. They&amp;rsquo;re not fond of rules and they have &lt;em&gt;no&lt;/em&gt; respect for the status quo. You can quote them, disagree with them; glorify or vilify them. About the only thing you &lt;strong&gt;can&amp;rsquo;t&lt;/strong&gt; do is ignore them - because they change things. They push the human race forward. While some may see them as the crazy ones, we, see genius. Because people who are crazy enough to think they can change the world, are the ones &lt;em&gt;who do&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And the video:&lt;br&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/8rwsuXHA7RA?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;
&lt;/p&gt;
&lt;!-- &lt;iframe width="160" height="120" src="http://www.youtube.com/embed/8rwsuXHA7RA?showinfo=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt; --&gt;
</description></item><item><title>Remembering Steve Jobs</title><link>https://www.saicharan.in/blog/2011/10/06/remembering-steve-jobs</link><pubDate>Thu, 06 Oct 2011 00:38:16 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/10/06/remembering-steve-jobs</guid><description>&lt;p&gt;In his commencement address at Stanford, &lt;a href="http://apple.com/stevejobs"&gt;Steve Jobs&lt;/a&gt; said (&lt;a href="http://news.stanford.edu/news/2005/june15/jobs-061505.html"&gt;Stanford News&lt;/a&gt;)-&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remembering that I&amp;rsquo;ll be dead soon is the most important tool I&amp;rsquo;ve ever encountered to help me make the big choices in life. Because almost everything — all external expectations, all pride, all fear of embarrassment or failure - these things just fall away in the face of death, leaving only what is truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the light of this, as &lt;a href="http://twitter.com/roshnimo"&gt;@roshnimo&lt;/a&gt; &lt;a href="https://twitter.com/krtgrphr/status/121736094776700928"&gt;notes&lt;/a&gt;, it feels a tad foolish to mourn. &lt;/p&gt;
</description></item><item><title>Steve on Courage, Heart and Intuition</title><link>https://www.saicharan.in/blog/2011/10/06/steve-on-courage-heart-and-intuition</link><pubDate>Thu, 06 Oct 2011 01:50:10 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/10/06/steve-on-courage-heart-and-intuition</guid><description>&lt;blockquote&gt;
&lt;p&gt;&amp;hellip;have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.&lt;/p&gt;
&lt;/blockquote&gt;— Steve Jobs&amp;rsquo; &lt;a href="http://news.stanford.edu/news/2005/june15/jobs-061505.html"&gt;Stanford Commencement Address&lt;/a&gt;.</description></item><item><title>Texnic Center error 'pdflatex.exe: Could not Initialize GUI'</title><link>https://www.saicharan.in/blog/2011/09/04/texnic-center-error-pdflatexexe-could-not-initialize-gui</link><pubDate>Sun, 04 Sep 2011 17:02:07 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/09/04/texnic-center-error-pdflatexexe-could-not-initialize-gui</guid><description>&lt;p&gt;Another note to self —&lt;/p&gt;
&lt;p&gt;This error only means that MikTeX was &lt;a href="http://www.latex-community.org/forum/viewtopic.php?f=31&amp;amp;t=310#p1043"&gt;unable to find and/or install some missing packages&lt;/a&gt;. To fix this (on Windows), run &amp;lsquo;mo.exe&amp;rsquo; from the command prompt and choose &amp;lsquo;Yes&amp;rsquo; for &amp;lsquo;Install missing pacakges on-the-fly&amp;rsquo;. (&amp;lsquo;Ask me first&amp;rsquo; did not work for me).&lt;/p&gt;
</description></item><item><title>You want to know how to do it</title><link>https://www.saicharan.in/blog/2011/09/03/quote-you-want-to-know-how-to-do-it</link><pubDate>Sat, 03 Sep 2011 10:01:34 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/09/03/quote-you-want-to-know-how-to-do-it</guid><description>&lt;blockquote&gt;
&lt;p&gt;You wanna know how you do it?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here&amp;rsquo;s how, they pull a knife, you pull a gun. He sends one of yours to the hospital, you send one of his to the morgue. That&amp;rsquo;s the Chicago way.&lt;/p&gt;
— The character &amp;lsquo;Malone&amp;rsquo; in the movie &lt;em&gt;The Untouchables&lt;/em&gt; (as seen at &lt;a href="http://www.groklaw.net/article.php?story=20110817200754569"&gt;Groklaw&lt;/a&gt;).</description></item><item><title>Jekyll feature: Retain Modified Time Stamp</title><link>https://www.saicharan.in/blog/2011/09/02/jekyll-feature-retain-modified-time-stamp</link><pubDate>Fri, 02 Sep 2011 12:54:03 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/09/02/jekyll-feature-retain-modified-time-stamp</guid><description>&lt;p&gt;To ease publishing via Jekyll, I needed to push via FTP to my hosting provider. I decided to the perl utility from sourceforge: &lt;a href="http://sourceforge.net/projects/ftpsync/"&gt;ftpsync&lt;/a&gt;. However, running it made me notice that Jekyll always regenerated all files and obviously, they had a &amp;rsquo;now&amp;rsquo; timestamp. This was basically throwing off the FTPSync utility which ended up pushing the entire site, defeating the very purpose of the utility.&lt;/p&gt;
&lt;p&gt;So, I made a two line fix that handles static pages and _posts/ as follows: The time stamp of the markdown/static page is copied to the published post page. So, even though Jekyll regenerates the entire site, the timestamps are adjusted to prevent unnecessary push via tools like FTPSync. Note that other pages will still have the &amp;rsquo;now&amp;rsquo; timestamp.&lt;/p&gt;
&lt;p&gt;The diff can be &lt;a href="https://github.com/scharan/jekyll/compare/handle-modified-timestamps#diff-0"&gt;viewed here&lt;/a&gt;. Feedback/suggestions welcome in comments.&lt;/p&gt;
</description></item><item><title>URL Selection in Putty</title><link>https://www.saicharan.in/blog/2011/09/01/url-selection-in-putty</link><pubDate>Thu, 01 Sep 2011 15:26:22 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/09/01/url-selection-in-putty</guid><description>Finally! Used &lt;a href="http://tech.arantius.com/select-urls-in-putty"&gt;this&lt;/a&gt; article to fix the partial URL selection problem with PuTTy. In addition to &amp;lsquo;:&amp;rsquo;, I also &amp;lsquo;set to class 2&amp;rsquo; the characters: &amp;lsquo;?&amp;rsquo; &amp;amp; &amp;lsquo;#&amp;rsquo;.</description></item><item><title>Tributes to Steve Jobs</title><link>https://www.saicharan.in/blog/2011/08/25/tributes-to-steve-jobs</link><pubDate>Thu, 25 Aug 2011 11:15:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/25/tributes-to-steve-jobs</guid><description>&lt;p&gt;Here are a few more reflections from people I read:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://daringfireball.net/2011/08/resigned"&gt;John Gruber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://scripting.com/stories/2011/08/25/thanksSteve.html"&gt;Dave Winer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pogue.blogs.nytimes.com/2011/08/25/steve-jobs-reshaped-industries/"&gt;David Pogue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.marco.org/2011/08/24/steve-jobs-resigns-as-apple-ceo"&gt;Marco Arment&lt;/a&gt; closes with -&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Steve, if for some crazy reason you&amp;rsquo;re reading this:&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ve defined a generation and changed the world.&lt;/p&gt;
&lt;p&gt;Thank you.&lt;/p&gt;
&lt;p&gt;We wish you the best.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;May be I&amp;rsquo;ll add a few more as they pop up.&lt;/p&gt;
</description></item><item><title>When GOD called Vic Gundotra</title><link>https://www.saicharan.in/blog/2011/08/25/when-god-called-vic-gundotra</link><pubDate>Thu, 25 Aug 2011 10:10:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/25/when-god-called-vic-gundotra</guid><description>&lt;p&gt;Being an Apple fanboy, I enjoyed this piece. It is interesting that after Steve Jobs resigned, many such stories have surfaced.&lt;/p&gt;
&lt;p&gt;Vic Gundotra &lt;a href="https://plus.google.com/107117483540235115863/posts/gcSStkKxXTw"&gt;recalls&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Steve laughed. He said, &amp;ldquo;Vic, unless the Caller ID said &amp;lsquo;GOD&amp;rsquo;, you should never pick up during services&amp;rdquo;. [&amp;hellip;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and concludes -&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But in the end, when I think about leadership, passion and attention to detail, I think back to the call I received from Steve Jobs on a Sunday morning in January. It was a lesson I&amp;rsquo;ll never forget. CEOs should care about details. Even shades of yellow. On a Sunday.&lt;/p&gt;
&lt;p&gt;To one of the greatest leaders I&amp;rsquo;ve ever met, my prayers and hopes are with you Steve.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nice!&lt;/p&gt;
</description></item><item><title>When Steve Held Open the Door</title><link>https://www.saicharan.in/blog/2011/08/25/when-steve-held-open-the-door</link><pubDate>Thu, 25 Aug 2011 09:40:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/25/when-steve-held-open-the-door</guid><description>&lt;p&gt;&lt;a href="http://tumblr.davidcairns.org/post/9359368094/so-steve-jobs-has-left-his-role-as-apples-ceo"&gt;David Cairns&lt;/a&gt; writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Anyway, I knew the distance pretty well, so when I sensed that I was reaching the other side of the quad, I opened my eyes and looked down and Steve was holding the door for me, grinning to himself. I have no idea how long he had been holding it, though it was probably only a couple seconds, long enough to cause him to smile at my basking in the open air.&lt;/p&gt;
&lt;p&gt;Those couple seconds probably cost Apple $1.4bn.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Must have quite an experience!&lt;/p&gt;
</description></item><item><title>Static Blog Using Jekyll</title><link>https://www.saicharan.in/blog/2011/08/24/static-blog-using-jekyll</link><pubDate>Wed, 24 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/24/static-blog-using-jekyll</guid><description>&lt;p&gt;This is what it took me to migrate from WordPress to Jekyll:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Import blog using the wordpressdotcom importer.&lt;/li&gt;
&lt;li&gt;Use Disqus WP plugin to export comments into Disqus.&lt;/li&gt;
&lt;li&gt;Generate static pages (include Disqus code in Jekyll template).&lt;/li&gt;
&lt;li&gt;Add search functionality.&lt;/li&gt;
&lt;li&gt;Add personal pages (about/search/rss).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Done! (A preview is available &lt;a href="http://aws.saicharan.in"&gt;here&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Update:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adding tags was a lot more effort. A little help from &lt;a href="https://gist.github.com/143571#gistcomment-7054"&gt;this gist&lt;/a&gt; saved the day.&lt;/li&gt;
&lt;li&gt;Adding pages for year, month and day was a ton more effort. I modified archive.rb from &lt;a href="https://github.com/josegonzalez/josediazgonzalez.com/_plugins"&gt;josegonzalez&lt;/a&gt; and also customized his _layout/archive_*.html&lt;/li&gt;
&lt;li&gt;Added an error handler with some JS to show my own custom error page.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can find the sources here: &lt;a href="https://github.com/scharan/scharan.github.com"&gt;https://github.com/scharan/scharan.github.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I also modified &lt;a href="https://github.com/metajack/jekyll/blob/master/emacs/jekyll.el"&gt;metajack&amp;rsquo;s jekyll.el&lt;/a&gt; to add a date: header (with date &amp;amp; time) on publish: &lt;a href="https://gist.github.com/1171592"&gt;https://gist.github.com/1171592&lt;/a&gt;. The gist:&lt;/p&gt;
&lt;script src="https://gist.github.com/1171592.js?file=jekyll.el"&gt;&lt;/script&gt;</description></item><item><title>Migrating to Jekyll</title><link>https://www.saicharan.in/blog/2011/08/22/migrating-to-jekyll</link><pubDate>Mon, 22 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/22/migrating-to-jekyll</guid><description>&lt;p&gt;Ah! The joy of &lt;a title="markdown" href="http://daringfireball.net/projects/markdown/" target="_blank"&gt;markdown&lt;/a&gt;! I preferred to write text, not markup. As @gruber states at the opening, markdown allows me write simply. However, it was painful to blog with this workflow:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;write in markdown&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://daringfireball.net/projects/markdown/dingus" target="_blank"&gt;convert to HTML&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;copy paste the HTML to blog editor&lt;/li&gt;
	&lt;li&gt;publish&lt;/li&gt;
&lt;/ul&gt;
It was just too painful. Enter &lt;a href="http://jekyllrb.com" target="_blank"&gt;Jekyll&lt;/a&gt;. I first came across &lt;a href="http://www.allthingsdistributed.com/2011/08/Jekyll-amazon-s3.html" target="_blank"&gt;Jekyll&lt;/a&gt; here on &lt;a href="http://allthingsdistributed.com" target="_blank"&gt;allthingsdistributed.com&lt;/a&gt;. &lt;a href="http://tom.preston-werner.com/" target="_blank"&gt;Tom Preston-Werner&lt;/a&gt; (Jekyll's author) notes &lt;a href="http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html" target="_blank"&gt;here&lt;/a&gt;, he needed something simpler - so he wrote Jekyll.
&lt;p&gt;I liked my new &lt;a title="munich theme" href="https://github.com/scharan/munich" target="_blank"&gt;munich theme&lt;/a&gt;, and so wrote my own &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/index.html" target="_blank"&gt;index.html&lt;/a&gt;, &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/_layouts/default.html" target="_blank"&gt;default.html&lt;/a&gt;, &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/_layouts/post.html" target="_blank"&gt;post.html&lt;/a&gt; and &lt;a href="https://github.com/scharan/scharan.github.com/blob/master/css/munich.css" target="_blank"&gt;css&lt;/a&gt;. You can see the work in progress here: &lt;a href="http://aws.saicharan.in" target="_blank"&gt;aws.saicharan.in&lt;/a&gt;.&lt;/p&gt;
</description></item><item><title>Google MP3 Player</title><link>https://www.saicharan.in/blog/2011/08/20/google-mp3-player</link><pubDate>Sat, 20 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/20/google-mp3-player</guid><description>&lt;p&gt;&lt;embed quality="best" height="27" width="400" flashvars="audioUrl=http://stream.radiosai.net:8002/" src="http://www.google.com/reader/ui/3523697345-audio-player.swf" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update 2025-01-16&lt;/em&gt;: The Google Reader Flash audio player is now defunct&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; and the embedded content does not load anymore, in case you were wondering :-). I&amp;rsquo;m keeping this post up (with the now invisible, but still very much present embed tag; view page source if curious) in memorium.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="http://www.google.com/reader/ui/3523697345-audio-player.swf"&gt;http://www.google.com/reader/ui/3523697345-audio-player.swf&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description></item><item><title>SaveURI has a new home!</title><link>https://www.saicharan.in/blog/2011/08/18/saveuri-has-a-new-home</link><pubDate>Thu, 18 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/18/saveuri-has-a-new-home</guid><description>On Github: &lt;a href="https://github.com/scharan/saveuri" target="_blank"&gt;&lt;a href="https://github.com/scharan/saveuri"&gt;https://github.com/scharan/saveuri&lt;/a&gt;&lt;/a&gt;</description></item><item><title>Persisting/restoring ssh-agent across screen/tmux sessions</title><link>https://www.saicharan.in/blog/2011/08/15/persistingrestoring-ssh-agent-across-screentmux-sessions</link><pubDate>Mon, 15 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/15/persistingrestoring-ssh-agent-across-screentmux-sessions</guid><description>As a heavy user of screen and now of tmux, I find it annoying that each time I disconnect the terminal and reconnect and then reattach to screen/tmux, I find that inside the screen/tmux sessions, SSH_AUTH_SOCK variable is stale: it does not point anymore to the &amp;lsquo;current&amp;rsquo; agent.pid file. So, here is a script to fix that: &lt;a href="https://github.com/scharan/Goodies/blob/master/ssh-agent-restore"&gt;&lt;a href="https://github.com/scharan/Goodies/blob/master/ssh-agent-restore"&gt;https://github.com/scharan/Goodies/blob/master/ssh-agent-restore&lt;/a&gt;&lt;/a&gt;</description></item><item><title>'gitweb' setup without root access</title><link>https://www.saicharan.in/blog/2011/08/14/gitweb-setup-without-root-access</link><pubDate>Sun, 14 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/14/gitweb-setup-without-root-access</guid><description>&lt;p&gt;&lt;em&gt;Setting up gitweb on a machine with no root access:&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;First, set up lighttpd:&lt;/div&gt;
&lt;div&gt;Download from &lt;a href="http://www.lighttpd.net/download"&gt;http://www.lighttpd.net/download&lt;/a&gt;&lt;/div&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ mkdir -p ~/usr
$ tar -xvf lighttpd-*; cd !$;
$ ./configure --prefix /home/&amp;amp;lt;you&amp;amp;gt;/usr
$ make
$ make install ## lighttpd is now at ~/usr/sbin/
&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;- Now, if all is well, you should be able to run git instaweb in your local git repository.&lt;/div&gt;
&lt;div&gt;- If you see a message like base-docroot not found at /PATH/TO/SOME/WHERE, then it probably did not find that directory.&lt;/div&gt;
&lt;div&gt;To resolve this, you can do one of two things:&lt;/div&gt;
&lt;div&gt; 1. Find the directory named gitweb/ that contains index.cgi, gitweb.cgi and static/ and run&lt;/div&gt;
&lt;p&gt;&lt;code&gt;$ git config --get instaweb.gitwebdir &amp;quot;/PATH/TO/gitweb/&amp;quot; (I figured this from /usr/bin/git-instaweb)&lt;/code&gt;&lt;/p&gt;
&lt;div&gt; 2. Emulate a local install&lt;/div&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ mkdir -p ~/www/static
$ git config --get instaweb.gitwebdir &amp;#34;/home//www&amp;#34;
$ scp ssh://my-ubuntu-machine-with-sudo-access:/usr/share/gitweb/* ~/www/
$ scp ssh://my-ubuntu-machine-with-sudo-access:/usr/share/gitweb/static/* ~/www/static
$ cd git-repo; git instaweb;
&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;  - If it instead start and you then see an error like: 404 Not found, the folder exists but&lt;/div&gt;
&lt;div&gt;  - the index.cgi file is not found, simply do step 2 above.&lt;/div&gt;
&amp;nbsp;
&lt;br /&gt;
&lt;p&gt;&lt;em&gt;Setting up highlight (on a machine with no root access):&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download hightlight from &lt;a href="http://www.andre-simon.de/zip/download.html"&gt;http://www.andre-simon.de/zip/download.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ tar -xvf hightlight*; cd !$;&amp;lt;/div&amp;gt;
$ make&amp;lt;/div&amp;gt;
$ edit &amp;#39;makefile&amp;#39;
# Destination directory for installation (intended for packagers)
DESTDIR =
# Root directory for final installation
PREFIX = /home/csgrads/scharan/usr # or something appropriate.
$ make install
$ PATH=$PATH:~/usr/bin/:
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Download lua from here: &lt;a href="http://www.lua.org/ftp/lua-5.1.4.tar.gz"&gt;http://www.lua.org/ftp/lua-5.1.4.tar.gz&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ make linux
$ Edit makefile to point INSTALL_TOP to ~/usr/local
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Edit ~/www/gitweb.cgi: enable highlight feature (you gotta grep for it).&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Vonage Usage: Python Script</title><link>https://www.saicharan.in/blog/2011/08/09/vonage-usage-python-script</link><pubDate>Tue, 09 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/09/vonage-usage-python-script</guid><description>&lt;p&gt;This eases checking international minutes used with a Vonage World plan &lt;a href="http://saicharan.in/work/vonage.py" target="_blank"&gt;&lt;a href="http://saicharan.in/work/vonage.py"&gt;http://saicharan.in/work/vonage.py&lt;/a&gt;&lt;/a&gt;. Just put in your vonage username/password in the script. You would also want to &lt;code&gt;$ sudo pip install libxml2dom&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Further, to avoid manual check, here is a crontab entry to automatically check usage at 6 AM everyday. It then emails you if you have overshot the usage (defaults to 3000 mins/month). My mail.sh is available on &lt;a href="https://github.com/scharan/Goodies/blob/master/mail.sh" target="_blank"&gt;Github&lt;/a&gt;:
&lt;code&gt;0 6 * * * vonage.py 1&amp;amp;gt;/tmp/vonage-mail; ret=$?; if [ $ret -ne 0 ]; then mail.sh &amp;quot;Vonage Usage: $ret&amp;quot; /tmp/vonage-mail; fi&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The script: &lt;a href="https://raw.githubusercontent.com/scharan/Goodies/master/vonage.py"&gt;https://raw.githubusercontent.com/scharan/Goodies/master/vonage.py&lt;/a&gt;.&lt;/p&gt;
&lt;script src="https://emgithub.com/embed-v2.js?target=https%3A%2F%2Fgithub.com%2Fscharan%2FGoodies%2Fblob%2Fmaster%2Fvonage.py&amp;style=default&amp;type=code&amp;showBorder=on&amp;showLineNumbers=on&amp;showFileMeta=on&amp;showFullPath=on&amp;showCopy=on"&gt;&lt;/script&gt; 
</description></item><item><title>Indian Almanac Bookmarklet</title><link>https://www.saicharan.in/blog/2011/08/08/indian-almanac-bookmarklet</link><pubDate>Mon, 08 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/08/indian-almanac-bookmarklet</guid><description>&lt;p&gt;Traditional events require fairly strict observances throughout the year. For this, I tend to rely on the online service: &lt;a href="http://mypanchang.com" target="_blank"&gt;&lt;a href="http://mypanchang.com"&gt;http://mypanchang.com&lt;/a&gt;&lt;/a&gt;. Though I bookmarked the page, it is error prone in that you will be always be shown the date that you bookmarked. Instead, it would be of immense help to view today&amp;rsquo;s almanac. So, here is my bookmarklet for showing today&amp;rsquo;s almanac for Los Angeles. You can edit it to show your city&amp;rsquo;s almanac by looking at the URL for your city from here: &lt;a href="http://www.mypanchang.com/selectyourcity2011.html" target="_blank"&gt;&lt;a href="http://www.mypanchang.com/selectyourcity2011.html"&gt;http://www.mypanchang.com/selectyourcity2011.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bookmarklet: &lt;a href="javascript: function panchangam(){var d = new Date(); var day=d.getDate(); var month=d.getMonth(); var year = d.getFullYear();location.href='http://www.mypanchang.com/phppanchang.php?'+'&amp;amp;yr='+year+'&amp;amp;cityhead=Los Angeles, CA&amp;amp;cityname=LosAngeles-CA'+'&amp;amp;monthtype=0&amp;amp;mn='+month+'#'+day};panchangam();"&gt; LA South Indian Almanac &lt;/a&gt;.&lt;/p&gt;
&lt;script src="https://emgithub.com/embed-v2.js?target=https%3A%2F%2Fgithub.com%2Fscharan%2FGoodies%2Fblob%2Fmaster%2Falmanac.js&amp;style=default&amp;type=code&amp;showBorder=on&amp;showLineNumbers=on&amp;showFileMeta=on&amp;showFullPath=on&amp;showCopy=on"&gt;&lt;/script&gt; 
&lt;!--pre class="brush: javascript"&gt;javascript: function panchangam(){var d = new Date(); var day=d.getDate(); var month=d.getMonth(); var year = d.getFullYear();location.href='http://www.mypanchang.com/phppanchang.php?'+'&amp;amp;yr='+year+'&amp;amp;cityhead=Los Angeles, CA&amp;amp;cityname=LosAngeles-CA'+'&amp;amp;monthtype=0&amp;amp;mn='+month+'#'+day};panchangam();&lt;/pre--&gt;
</description></item><item><title>Readability for Chrome: Save to Instapaper</title><link>https://www.saicharan.in/blog/2011/08/08/readability-for-chrome-save-to-instapaper</link><pubDate>Mon, 08 Aug 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/08/08/readability-for-chrome-save-to-instapaper</guid><description>&lt;p&gt;I love readability (readability.com) for the clutter free reading experience. As a student, I prefer freebies. Instapaper does a great job of reading lists - and its free too. I wanted to combine the Readability&amp;rsquo;s &amp;lsquo;Read Later&amp;rsquo; shortcut (shift + `) to save to Instapaper. Turns out, its easy:&lt;/p&gt;
&lt;p&gt;On Windows, goto:
%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Extensions\oadggleneidfmbhhedlildjnpgcggmch\1.6_0\js&lt;/p&gt;
&lt;p&gt;On Ubuntu Linux, goto:
~/.config/chromium/Default/Extensions/oadggleneidfmbhhedlildjnpgcggmch/1.6_0/js/&lt;/p&gt;
&lt;p&gt;Replace the contents of &amp;lsquo;save.js&amp;rsquo; with the script below. &lt;del datetime="2011-08-13T03:10:26+00:00"&gt;You will have to replace with the string that follows instapaper.com/j/ in your personal bookmarklet - sorry, its a wee little bit more effort.&lt;/del&gt; Found a way to avoid user specific token. This works out of the box.&lt;/p&gt;
&lt;script type="text/javascript" src="http://gist-it.appspot.com/github/scharan/Goodies/raw/master/save.js"&gt;&lt;/script&gt; 
&lt;!--pre class="brush: javascript"&gt;(function(){var d=document,z=d.createElement('scr'+'ipt'),b=d.body,l=d.location;try{if(!b)throw(0);d.title='(Saving...) '+d.title;z.setAttribute('src',l.protocol+'//www.instapaper.com/j/ms9ZEqYS9JfG?u='+encodeURIComponent(l.href)+'&amp;amp;t='+(new Date().getTime()));b.appendChild(z);}catch(e){alert('Please wait until the page has loaded.');}}());&lt;/pre--&gt; 
&lt;p&gt;That piece of code is and adaptation from Instapaper&amp;rsquo;s &amp;lsquo;Read Later&amp;rsquo; bookmarklet: &lt;a href="http://www.instapaper.com/extras"&gt;&lt;a href="http://www.instapaper.com/extras"&gt;http://www.instapaper.com/extras&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now simply disable/re-enable the Readability plugin, open (or reload if already open) the page you wish to &amp;lsquo;read later&amp;rsquo; and hit (shift + `) keys. If you are logged in with Instapaper, you should see the Saved! popup on the top left. Else, you will be prompted to login and then Instapaper saves your bookmark, returning you to the page you were on.&lt;/p&gt;
&lt;p&gt;Neat!&lt;/p&gt;
</description></item><item><title>Texnic Center and Adobe Reader X</title><link>https://www.saicharan.in/blog/2011/05/04/texnic-center-and-adobe-reader-x</link><pubDate>Wed, 04 May 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/05/04/texnic-center-and-adobe-reader-x</guid><description>&lt;p&gt;After I upgraded to Adobe Reader X, Texnic center started throwing up an error:&amp;quot;[DocOpen(&amp;quot;%bm.pdf&amp;quot;)][FileOpen(&amp;quot;%bm.pdf&amp;quot;)] Cannot execute the command.&amp;quot;&lt;/p&gt;
&lt;p&gt;Digging up a little on Adobe DDE, I found a solution here: &lt;a href="http://forums.adobe.com/message/3301219#3301219"&gt;http://forums.adobe.com/message/3301219#3301219&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is the fix:
Build &amp;gt; Define Output Profiles &amp;gt; Choose &amp;lsquo;LaTeX =&amp;gt; PDF&amp;rsquo; &amp;gt; Viewer tab. In three locations where &amp;lsquo;acroview&amp;rsquo; is the value, change it to &amp;lsquo;acroviewR10&amp;rsquo; and you are good to go!&lt;/p&gt;
</description></item><item><title>gContactSync bug</title><link>https://www.saicharan.in/blog/2011/04/12/gcontactsync-bug</link><pubDate>Tue, 12 Apr 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/04/12/gcontactsync-bug</guid><description>&lt;p&gt;Found a weird behavior with gContactSync 0.3.2 Thunderbird plugin- on both Windows and Linux (Fedora 14), the sync stops after 111 contacts. Poked around the internet and found that there were no documented bugs on this.&lt;/p&gt;
&lt;p&gt;Decided to fix it for myself cos I found that it &lt;em&gt;really&lt;/em&gt; syncs all the contact information to Thunderbird, including the photo.&lt;/p&gt;
&lt;p&gt;gContactSync has a nice &amp;lsquo;verbose log&amp;rsquo; feature for debugging information - but was not of much help since the log stopped after 111 contacts.&lt;/p&gt;
&lt;p&gt;Next tool for me was the &amp;lsquo;Error Console&amp;rsquo; in Thunderbird. Not surprisingly, I found an error on line 181 in content/GContact.js, that read &amp;quot; &amp;rsquo;type&amp;rsquo; not defined&amp;quot; :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;181 type = type.substring(type.indexOf(&amp;#34;#&amp;#34;) + 1); 
182 return new com.gContactSync.Property(arr[i].childNodes[0].nodeValue, 
183                                                                    type); 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Darn! Just as a test, I simply pre-pended &amp;lsquo;if(type)&amp;rsquo; to line 181, resulting in:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;181 if(type) type = type.substring(type.indexOf(&amp;#34;#&amp;#34;) + 1); 
182 return new com.gContactSync.Property(arr[i].childNodes[0].nodeValue, 
183                                                                    type); 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It worked! Not really got a chance to investigate what happens/does not happen when &amp;rsquo;type&amp;rsquo; is NOT defined, but things seem to work for now. I also submitted this here: &lt;a href="http://www.pirules.org/extensions/submit_error.php"&gt;http://www.pirules.org/extensions/submit_error.php&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Mapping Win key in Fedora (14)</title><link>https://www.saicharan.in/blog/2011/04/08/mapping-win-key-in-fedora-14</link><pubDate>Fri, 08 Apr 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/04/08/mapping-win-key-in-fedora-14</guid><description>&lt;p&gt;Learnt/inferred a few things here (correct me via comments if I am wrong conceptually; note that these have worked for me) -&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Win key is called/referred to as the 'super key'&lt;/li&gt;
	&lt;li&gt;You may have to get xmodmap to explicitly recognize the key.&lt;/li&gt;
	&lt;li&gt;You can get the keycode for any key using 'xev' command, as discussed here: &lt;a href="http://forums.fedoraforum.org/showpost.php?s=9af5fdea1041e19ff96815fb3470f904&amp;amp;p=913923&amp;amp;postcount=9" target="_blank"&gt;http://forums.fedoraforum.org/showpost.php?s=9af5fdea1041e19ff96815fb3470f904&amp;amp;p=913923&amp;amp;postcount=9&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Once you find out the keycode for you Win key, you can get xmodmap to 'recognize' it as noted in &lt;a href="http://forums.fedoraforum.org/showpost.php?s=9af5fdea1041e19ff96815fb3470f904&amp;amp;p=913308&amp;amp;postcount=3" target="_blank"&gt;http://forums.fedoraforum.org/showpost.php?s=9af5fdea1041e19ff96815fb3470f904&amp;amp;p=913308&amp;amp;postcount=3&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Then, configure Win+key combinations via System &amp;gt; Preferences &amp;gt; Keyboard Shortcuts.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>SaveURI Updated for Firefox 4</title><link>https://www.saicharan.in/blog/2011/03/31/saveuri-updated-for-firefox-4</link><pubDate>Thu, 31 Mar 2011 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2011/03/31/saveuri-updated-for-firefox-4</guid><description>&lt;p&gt;Made some time to update the firefox extension at &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/saveuri/"&gt;https://addons.mozilla.org/en-US/firefox/addon/saveuri/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It was a more than a minor compatibility break. I have submitted the new version for review. But for those of you wish to test it for me, here is a link: &lt;a href="http://saicharan.in/beta/saveuri/saveuri-0.3.3-fx.xpi"&gt;http://saicharan.in/beta/saveuri/saveuri-0.3.3-fx.xpi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Warning: This has not yet been approved by a Mozilla reviewer - for testing only!&lt;/p&gt;
&lt;p&gt;Instructions: If your Firefox browser saves the file rather than install it, simply drag and drop the file to the browser window and restart your browser!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; The extension has been approved and is now available at &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/saveuri/"&gt;https://addons.mozilla.org/en-US/firefox/addon/saveuri/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks everyone for the geek-joy!&lt;/p&gt;
</description></item><item><title>while(*a++ == *b++)</title><link>https://www.saicharan.in/blog/2010/05/11/whilea-b</link><pubDate>Tue, 11 May 2010 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2010/05/11/whilea-b</guid><description>&lt;p&gt;Among the most elegant implementations is the string copy function (assuming you have allocated enough memory in the dest buffer):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//Assuming for elegance you don&amp;#39;t have to return the number of bytes copied.
void strcpy(char* src, char* dest){
 while(*dest++ = *src++);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But I have often wondered what happens at the assembler such &lt;code&gt;*s&lt;/code&gt; gets you only a single byte/character. So here is a simple program that explores this - but in string compare:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;int main(){
 char *a=&amp;#34;String One&amp;#34;, *b=&amp;#34;String Two&amp;#34;;
 while(*a++==*b++);
&lt;p&gt;return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I compiled this with ‘gcc -S’ option and got the following assembly code:&lt;/p&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;display:grid;"&gt;&lt;code class="language-asm" data-lang="asm"&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 1&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#b44"&gt;.file&lt;/span&gt;	&lt;span style="color:#b44"&gt;&amp;#34;testpointer.c&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 2&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#b44"&gt;.def&lt;/span&gt;	&lt;span style="color:#800"&gt;___main&lt;/span&gt;&lt;span style="color:#080;font-style:italic"&gt;;	.scl	2;	.type	32;	.endef
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 3&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#b44"&gt;.section&lt;/span&gt; &lt;span style="color:#800"&gt;.rdata&lt;/span&gt;,&lt;span style="color:#b44"&gt;&amp;#34;dr&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a0a000"&gt;LC0:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 5&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#b44"&gt;.ascii&lt;/span&gt; &lt;span style="color:#b44"&gt;&amp;#34;a\0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 6&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a0a000"&gt;LC1:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 7&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#b44"&gt;.ascii&lt;/span&gt; &lt;span style="color:#b44"&gt;&amp;#34;b\0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 8&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#b44"&gt;.text&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 9&lt;/span&gt;&lt;span&gt;&lt;span style="color:#b44"&gt;.globl&lt;/span&gt; &lt;span style="color:#800"&gt;_main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;10&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#b44"&gt;.def&lt;/span&gt;	&lt;span style="color:#800"&gt;_main&lt;/span&gt;&lt;span style="color:#080;font-style:italic"&gt;;	.scl	2;	.type	32;	.endef
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;11&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a0a000"&gt;_main:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;12&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;pushl&lt;/span&gt;	&lt;span style="color:#b8860b"&gt;%ebp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;13&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;movl&lt;/span&gt;	&lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;, &lt;span style="color:#b8860b"&gt;%ebp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;14&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;andl&lt;/span&gt;	&lt;span style="color:#800"&gt;$-16&lt;/span&gt;, &lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;15&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;subl&lt;/span&gt;	&lt;span style="color:#800"&gt;$16&lt;/span&gt;, &lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;16&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;call&lt;/span&gt;	&lt;span style="color:#800"&gt;___main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;17&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;movl&lt;/span&gt;	&lt;span style="color:#800"&gt;$LC0&lt;/span&gt;, &lt;span style="color:#666"&gt;8&lt;/span&gt;(&lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;18&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;movl&lt;/span&gt;	&lt;span style="color:#800"&gt;$LC1&lt;/span&gt;, &lt;span style="color:#666"&gt;12&lt;/span&gt;(&lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;19&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a0a000"&gt;L2:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;20&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;movl&lt;/span&gt;	&lt;span style="color:#666"&gt;8&lt;/span&gt;(&lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;), &lt;span style="color:#b8860b"&gt;%eax&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;21&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;movb&lt;/span&gt;	(&lt;span style="color:#b8860b"&gt;%eax&lt;/span&gt;), &lt;span style="color:#b8860b"&gt;%dl&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;22&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;movl&lt;/span&gt;	&lt;span style="color:#666"&gt;12&lt;/span&gt;(&lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;), &lt;span style="color:#b8860b"&gt;%eax&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;23&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;movb&lt;/span&gt;	(&lt;span style="color:#b8860b"&gt;%eax&lt;/span&gt;), &lt;span style="color:#b8860b"&gt;%al&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex; background-color:#dfdfdf"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;24&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;cmpb&lt;/span&gt;	&lt;span style="color:#b8860b"&gt;%al&lt;/span&gt;, &lt;span style="color:#b8860b"&gt;%dl&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;25&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;sete&lt;/span&gt;	&lt;span style="color:#b8860b"&gt;%al&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;26&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;incl&lt;/span&gt;	&lt;span style="color:#666"&gt;8&lt;/span&gt;(&lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;27&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;incl&lt;/span&gt;	&lt;span style="color:#666"&gt;12&lt;/span&gt;(&lt;span style="color:#b8860b"&gt;%esp&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;28&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;testb&lt;/span&gt;	&lt;span style="color:#b8860b"&gt;%al&lt;/span&gt;, &lt;span style="color:#b8860b"&gt;%al&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;29&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;jne&lt;/span&gt;	&lt;span style="color:#800"&gt;L2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;30&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;movl&lt;/span&gt;	&lt;span style="color:#800"&gt;$0&lt;/span&gt;, &lt;span style="color:#b8860b"&gt;%eax&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;31&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;leave&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;32&lt;/span&gt;&lt;span&gt;	&lt;span style="color:#00a000"&gt;ret&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Line 24: &lt;code&gt;cmpb %al, %dl&lt;/code&gt; says it all. compare &lt;em&gt;Lower&lt;/em&gt; &lt;em&gt;Byte&lt;/em&gt; of register &lt;code&gt;a&lt;/code&gt; and register &lt;code&gt;d&lt;/code&gt;. Now I can be in peace ;)&lt;/p&gt;
&lt;h5 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References: &lt;/a&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9415"&gt;http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9415&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www3.itu.edu.tr/~kesgin/mul06/intel/instr/sete_setz.html"&gt;http://www3.itu.edu.tr/~kesgin/mul06/intel/instr/sete_setz.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/www.artofasm.com/DOS/ch09/CH09-6.html#HEADING6-83"&gt;http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/www.artofasm.com/DOS/ch09/CH09-6.html#HEADING6-83&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Binary Search Tree</title><link>https://www.saicharan.in/blog/2010/05/10/binary-search-tree</link><pubDate>Mon, 10 May 2010 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2010/05/10/binary-search-tree</guid><description>&lt;p&gt;The following code tests if the input binary tree is, in fact, a Binary Search Tree. This was as terse as I could get it. Any got more terse code? Suggestions/comments welcome.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;bool IsBST(TreeNode* node){
 if( !node ) return true;// trivially true.
 if( node-&amp;gt;left )
 if( node-&amp;gt;left-&amp;gt;val &amp;gt; node-&amp;gt;val ) return false; //fail early
 if( node-&amp;gt;right )
 if( node-&amp;gt;right-&amp;gt;val &amp;lt; node-&amp;gt;val ) return false; //fail early
&lt;p&gt;return ( IsBST(node-&amp;gt;left) &amp;amp;&amp;amp; IsBST(node-&amp;gt;right) ); //recursively test subtrees
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Update: &lt;del&gt;Notice the tail recursion? Its super-efficient!&lt;/del&gt;&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;Update-update: Thanks to Kartik (see comments below) for pointing out that the last line is NOT tail-recursive.&lt;/p&gt;
&lt;p&gt;Yet another update: The algorithm is does NOT check for &lt;code&gt;IsBST()&lt;/code&gt;. The criterion of root being greater than all right children and smaller than left children is not always checked. See &lt;a href="http://en.wikipedia.org/wiki/Binary_search_tree"&gt;http://en.wikipedia.org/wiki/Binary_search_tree&lt;/a&gt; for more details.&lt;/p&gt;
</description></item><item><title>Efficient Substr implementation</title><link>https://www.saicharan.in/blog/2010/05/10/efficient-substr-implementation</link><pubDate>Mon, 10 May 2010 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2010/05/10/efficient-substr-implementation</guid><description>&lt;p&gt;I came up with this implementation of substring method. Anyone got ideas to make it more terse &lt;strong&gt;&lt;em&gt;and&lt;/em&gt;&lt;/strong&gt; more efficient?&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;bool substring(const char* str, const char* substr){
 const char *currentString = str, *backTrackString = str, *currSubstr = substr;
 while( strlen(backTrackString) &amp;gt;= strlen(substr) ){
 while( *currSubstr &amp;amp;&amp;amp; *currentString++ == *currSubstr++);
 if( !*currSubstr ) return true;
 currentString = backTrackString++;
 currSubstr = substr;
 }
 return false;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In particular, can we do without atleast one of the local variables - while still being as efficient or better? A more basic question - so you think this is efficient?&lt;/p&gt;
</description></item><item><title>With Great Power Comes Great Responsibility</title><link>https://www.saicharan.in/blog/2010/05/07/with-great-power-comes-great-responsibility</link><pubDate>Fri, 07 May 2010 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2010/05/07/with-great-power-comes-great-responsibility</guid><description>&lt;p&gt;I was working on a remote FreeBSD system and issued a sudo command. I really liked what the &amp;lsquo;preamble&amp;rsquo; to the &amp;lsquo;password:&amp;rsquo; prompt was -&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things:
&lt;p&gt;#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.&lt;/p&gt;
&lt;p&gt;Password:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With great power comes great responsibility - and my mind instantly went to this story: &lt;a href="http://www.justpasha.org/folk/rm.html"&gt;&lt;a href="http://www.justpasha.org/folk/rm.html"&gt;http://www.justpasha.org/folk/rm.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;Hail Unix!&lt;/p&gt;
</description></item><item><title>JS e-mail Validator</title><link>https://www.saicharan.in/blog/2009/11/19/js-e-mail-validator</link><pubDate>Thu, 19 Nov 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/11/19/js-e-mail-validator</guid><description>&lt;p&gt;NOTE: I have avoided character classes to aid understanding for newbies. Wizards, bear with the verbosity!&lt;/p&gt;
&lt;p&gt;Came up with this nice little email validator JS regexp. Someone got something shorter?&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;function validateEmail( email ){
 var emailRe = new RegExp(&amp;#34;^[a-zA-Z]+([a-zA-Z0-9_]*.[a-zA-Z0-9_]+)*@([a-zA-Z0-9_]+.[a-zA-Z0-9_]+)*$&amp;#34;,&amp;#39;i&amp;#39;);
 return( emailRe.test( email ) );
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Does this miss any cases? Try it out here: &lt;input id="email" type="text" placeholder="Enter an email" /&gt; &lt;button onclick="validateEmail( getElementById('email').value );return false;"&gt; Validate email! &lt;/button&gt;&lt;/p&gt;
&lt;script type="text/javascript"&gt;
 function validateEmail( email ){ var emailRe = new RegExp("^[a-zA-Z]+([a-zA-Z0-9_.][a-zA-Z0-9_]+)+@([a-zA-Z0-9]+([.a-zA-Z0-9_])+)$",'i'); alert( emailRe.test( email ) ? "Valid" : "Invalid email" ); }
&lt;/script&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Update:&lt;/em&gt;&lt;/strong&gt; This script allowed &amp;lsquo;*&amp;rsquo; in the email ID. The correct re would be:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;var emailRe = new RegExp(&amp;#34;^[a-zA-Z]+([a-zA-Z0-9_].[a-zA-Z0-9_]+)+@([a-zA-Z0-9_]+.[a-zA-Z0-9_]+)+$&amp;#34;,&amp;#39;i&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Bug again!&lt;/em&gt;&lt;/strong&gt; The &amp;lsquo;&lt;code&gt;.&lt;/code&gt;&amp;rsquo; character outside the character class &lt;code&gt;[]&lt;/code&gt; matches &lt;em&gt;ANY&lt;/em&gt; single character. This, however, definitely works!&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;var emailRe = new RegExp(&amp;#34;^[a-zA-Z]+([a-zA-Z0-9_.][a-zA-Z0-9_]+)+@([a-zA-Z0-9]+([.a-zA-Z0-9_])+)$&amp;#34;.&amp;#39;i&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The test code now does not permit &amp;lsquo;&lt;code&gt;*&lt;/code&gt;&amp;rsquo; in the email ID.&lt;/p&gt;
</description></item><item><title>Interesting recursion problem</title><link>https://www.saicharan.in/blog/2009/11/12/interesting-recursion-problem</link><pubDate>Thu, 12 Nov 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/11/12/interesting-recursion-problem</guid><description>&lt;p&gt;Found this interesting recursion problem on StackOverflow.
&lt;a href="http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function"&gt;&lt;a href="http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function"&gt;http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;int resultSize(vector&amp;lt;vector&amp;lt;string&amp;gt;&amp;gt; vector ) {
 int x=1;
 for(int i=0; i&amp;lt;vector.size(); i++)
 x *= vector[i].size();
 return x;
}
&lt;p&gt;vector&amp;lt;string&amp;gt; enumAll(const vector&amp;lt;vector&amp;gt; allVecs ) {
//__ASSERT(allVecs.size() &amp;gt; 0);
vector result;
if (allVecs.size() == 1) {
for(int i=0 ; i&amp;lt;allVecs[0].size(); i++) {
result.push_back(allVecs[0][i]);
}
return result;
}
const vector&amp;lt;vector&amp;lt;string&amp;gt;&amp;gt; tempVector(allVecs.begin()+1, allVecs.end());
vector tempResult = enumAll(tempVector); // recurse
int size = resultSize(tempVector);
for(int i=0; i&amp;lt;allVecs[0].size(); i++) {
for(int j=0; j&amp;lt;size; j++) {
//enumAll on each tempVector is called multiple times. Can be optimzed.
result.push_back(allVecs[0][i] + tempResult[j]);
}
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Also see the other solution by Young which solves this problem using tail-recursion.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;It is interesting problem in itself to transform a plain recursion into tail-recursion. The general method to do this is to eliminate the need for any processing post recursion. For this, one needs to pass all the data as parameters. This is pretty obvious when comparing the two solutions. Plain recursion takes only one parameter, while tail-recursion takes a lot more parameters.&lt;/p&gt;
&lt;p&gt;In my view, the advantage of plain recursion is pedagogy: it is very easy to follow the algorithm - the divide and conquer is so very obvious! With tail-recursion, we manually do a lot of book-keeping. This part is not so obvious in the present example.&lt;/p&gt;
&lt;p&gt;Plain recursion:
&lt;a href="http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function/1723192#1723192"&gt;&lt;a href="http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function/1723192#1723192"&gt;http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function/1723192#1723192&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tail Recursion:
&lt;a href="http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function/1707808#1707808"&gt;&lt;a href="http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function/1707808#1707808"&gt;http://stackoverflow.com/questions/1705374/how-to-capture-a-string-into-variable-in-a-recursive-function/1707808#1707808&lt;/a&gt;
&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Stackoverflow Teacher Badge</title><link>https://www.saicharan.in/blog/2009/11/11/stackoverflow-teacher-badge</link><pubDate>Wed, 11 Nov 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/11/11/stackoverflow-teacher-badge</guid><description>&lt;p&gt;Yay! Just got the stackoverflow teacher badge! Yay!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://stackexchange.com/users/54315"&gt;&lt;img src="https://stackexchange.com/users/flair/54315.png" width="208" height="58" alt="profile for Sai Charan on Stack Exchange, a network of free, community-driven Q&amp;amp;A sites" title="profile for Sai Charan on Stack Exchange, a network of free, community-driven Q&amp;amp;A sites"&gt;&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Metaprogramming is not magic</title><link>https://www.saicharan.in/blog/2009/11/03/metaprogramming-is-not-magic</link><pubDate>Tue, 03 Nov 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/11/03/metaprogramming-is-not-magic</guid><description>&lt;p&gt;I have always wondered why I like programming languages like Lisp etc. Sort of found an answer here:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Metaprogramming is not magic. It is simply another tool in the prepared programmer&amp;rsquo;s toolbox. It&amp;rsquo;s awfully nice when that tool is also part of the programming language we use. Otherwise, we are limited in what we can say conveniently in our programs by the somewhat arbitrary lines drawn between real and meta.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source: &lt;a href="http://www.cs.uni.edu/~wallingf/blog/archives/monthly/2009-11.html#e2009-11-02T18_59_40.htm"&gt;&lt;a href="http://www.cs.uni.edu/~wallingf/blog/archives/monthly/2009-11.html#e2009-11-02T18_59_40.htm"&gt;http://www.cs.uni.edu/~wallingf/blog/archives/monthly/2009-11.html#e2009-11-02T18_59_40.htm&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>What I read, am reading and want to read</title><link>https://www.saicharan.in/blog/2009/10/12/what-i-readam-reading-and-want-to-read</link><pubDate>Mon, 12 Oct 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/10/12/what-i-readam-reading-and-want-to-read</guid><description>&lt;p&gt;This is a list for my reference. It will be a &amp;ldquo;live&amp;rdquo; post and act as my SPOC for reading.&lt;/p&gt;
&lt;p&gt;In progress:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Beautiful Code&lt;/li&gt;
&lt;li&gt;Code Complete 2&lt;/li&gt;
&lt;li&gt;The Pragmatic programmer&lt;/li&gt;
&lt;li&gt;Structure and Interpretation of Computer programs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Done:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Lost Symbol&lt;/li&gt;
&lt;li&gt;The mythical man-month&lt;/li&gt;
&lt;li&gt;Joel on Software&lt;/li&gt;
&lt;li&gt;More Joel on Software&lt;/li&gt;
&lt;li&gt;make (O&amp;rsquo;Rielly)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wishlist:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Coders at work by Peter Siebel&lt;/li&gt;
&lt;li&gt;The Innovator&amp;rsquo;s Dilemma&lt;/li&gt;
&lt;li&gt;Elements of Style&lt;/li&gt;
&lt;li&gt;Godel, Escher &amp;amp; Bach&lt;/li&gt;
&lt;li&gt;The story of Civilization by Will &amp;amp; Durant&lt;/li&gt;
&lt;li&gt;Paradigms Of Artificial Intelligence Programming by Peter Norvig&lt;/li&gt;
&lt;li&gt;The design of everyday things&lt;/li&gt;
&lt;li&gt;Founders at work&lt;/li&gt;
&lt;li&gt;The Brothers Karamazov&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Why hitting 'reload' speeds up page rendering</title><link>https://www.saicharan.in/blog/2009/08/17/why-hitting-reload</link><pubDate>Mon, 17 Aug 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/08/17/why-hitting-reload</guid><description>&lt;p&gt;This is a response to David Pogues&amp;rsquo; tweet question: &lt;a href="http://twitter.com/Pogue/status/3332520918" target="_blank"&gt;&lt;a href="http://twitter.com/Pogue/status/3332520918"&gt;http://twitter.com/Pogue/status/3332520918&lt;/a&gt; &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &amp;lsquo;rendering&amp;rsquo; or &amp;lsquo;drawing-model&amp;rsquo; of a browser is based on HTML. Each visual in HTML element is defined by a HTML &amp;rsquo;tag&amp;rsquo;. For browsers to display/render the page, they need some a certain amount of HTML tags to be available. So when you are faced with a blank page, it means that the browser is waiting for the HTML.&lt;/p&gt;
&lt;p&gt;Now, when you hit the reload button, remember that a part of the page has already been downloaded to the browser. Instead of discarding this info, the browser merely spits it out onto the window (thus displaying the page partially) and requests for the page once again. Now that a part of the page is already displayed (even if only partially), the user believes that the page has rendered rather quickly.&lt;/p&gt;
&lt;p&gt;If you hit the stop button, however, you will be stuck with a blank page. By hitting stop, you are telling the browser &amp;lsquo;dont bother to try and render this page&amp;rsquo;. By hitting reload, you are still showing interest. Another way to observe progressive rendering is while the page is loading ( the browser shows a blank or a partially rendred page), go to File &amp;gt; Work Offline (in Firefox). You will see the page quickly render the partial page that was succuessfully downloaded. It is a sort of &amp;lsquo;best-effort&amp;rsquo; service.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Related concept: &lt;/strong&gt;Progressive rendering. Jeff Atwood&amp;rsquo;s take on the &amp;lsquo;Lost Art of Progressive Rendering&amp;rsquo;: &lt;a href="http://www.codinghorror.com/blog/archives/000444.html"&gt;&lt;a href="http://www.codinghorror.com/blog/archives/000444.html"&gt;http://www.codinghorror.com/blog/archives/000444.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This means that browsers don&amp;rsquo;t need to really download the entire page before it can be displayed to the user. But, this depends on how the page has been desinged: &lt;a href="http://www.vbulletin.org/forum/showthread.php?t=161099 " target="_blank"&gt;&lt;a href="http://www.vbulletin.org/forum/showthread.php?t=161099"&gt;http://www.vbulletin.org/forum/showthread.php?t=161099&lt;/a&gt;&lt;/a&gt;.&lt;/p&gt;
</description></item><item><title>Deleting files</title><link>https://www.saicharan.in/blog/2009/08/06/deleting-files</link><pubDate>Thu, 06 Aug 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/08/06/deleting-files</guid><description>&lt;p&gt;In my quest for speeding up automated, no-questions asked deletion of the corrupt dev SDKs (which go upto 25 GB), I discovered this:
&lt;code&gt;&amp;gt; rmdir /S /Q .&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I even timed it this time: about an hour to delete a 25 GB SDK. And no questions asked. The above command does not write any output to the console! While this can be quite disconcerting initially, it does save a lot of computation time and resources ( I/O is the most expensive operation, remember? ).&lt;/p&gt;
&lt;p&gt;Earlier on, I used to use &lt;code&gt;&amp;gt; del /s /f /q *. &lt;/code&gt;. But that used to delete only the files and not the directories. Deleting the directories manually was another pain. Also, this command had the habit of “informing the user” of what it is deleting – and would take about 3 to 4 hours!&lt;/p&gt;
&lt;p&gt;Do let me know if you find some faster way to delete the SDK!!&lt;/p&gt;
</description></item><item><title>GMail: Automatic Message Translation</title><link>https://www.saicharan.in/blog/2009/07/12/gmail-autmatic-message-translation</link><pubDate>Sun, 12 Jul 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/07/12/gmail-autmatic-message-translation</guid><description>&lt;p&gt;This morning GMail surprised me yet again. Opening an email, I saw a new functional bar: Translate this message: From:&amp;lt;Language&amp;gt; To:&amp;lt;Language&amp;gt;.&lt;/p&gt;
&lt;p&gt;I tried out the machine translation from English to Hindi. It was amazing. Took under 2 second (yes, to send the request to the servers, do the translation and to render the translated text on the browser window).&lt;/p&gt;
&lt;p&gt;There was also that pretty helpful (right-)side bar: &amp;ldquo;Translate this conversation&amp;rdquo;.
Pretty neat translation. And very seamless user experience too! Man I am blown away.&lt;/p&gt;
</description></item><item><title>HN Submit button</title><link>https://www.saicharan.in/blog/2009/07/12/hn-submit-button</link><pubDate>Sun, 12 Jul 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/07/12/hn-submit-button</guid><description>&lt;p&gt;I have been attempting to add &amp;ldquo;share&amp;rdquo; functionality to my website. Initially, I used the Digg button (&lt;a href="http://digg.com/tools/integrate" target="_blank"&gt;&lt;a href="http://digg.com/tools/integrate"&gt;http://digg.com/tools/integrate&lt;/a&gt;&lt;/a&gt;) and Reddit button (&lt;a href="http://www.reddit.com/button" target="_blank"&gt;&lt;a href="http://www.reddit.com/button"&gt;http://www.reddit.com/button&lt;/a&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Next I wanted to add &lt;a title="Hacker News" href="http://news.ycombinator.com/news" target="_blank"&gt;Hacker News&lt;/a&gt; button. But there was none. But then again, there was this bookmarklet (&lt;a href="http://ycombinator.com/bookmarklet.html" target="_blank"&gt;&lt;a href="http://ycombinator.com/bookmarklet.html"&gt;http://ycombinator.com/bookmarklet.html&lt;/a&gt;&lt;/a&gt;). So I created the required HTML to get the required functionality, just using the bookmarklet:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;a href=&amp;#34;javascript:window.location=%22http://news.ycombinator.com/submitlink?u=%22+encodeURIComponent(document.location)+%22&amp;amp;amp;t=%22+encodeURIComponent(document.title)&amp;#34;&amp;gt; Submit &amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then I thought of making a Hacker News submit button, just like Reddit and Digg. So I decided to read the sources and build the HN button based on that.  Man, Digg&amp;rsquo;s JS was such mess (yes, it was the minified version, but still, far too many lines of code). Reddit&amp;rsquo;s was a great deal simpler, easy-to-read and intuitive. Check them out: &lt;a href="http://digg.com/tools/diggthis.js" target="_blank"&gt;&lt;a href="http://digg.com/tools/diggthis.js"&gt;http://digg.com/tools/diggthis.js&lt;/a&gt;&lt;/a&gt; and &lt;a href="http://www.reddit.com/button.js" target="_blank"&gt;&lt;a href="http://www.reddit.com/button.js"&gt;http://www.reddit.com/button.js&lt;/a&gt;.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So I modelled the HN button based on Reddits&amp;rsquo; Javascript. Here it is: &lt;a href="http://saicharan.in/work/hn.js" target="_blank"&gt;&lt;a href="http://saicharan.in/work/hn.js"&gt;http://saicharan.in/work/hn.js&lt;/a&gt;&lt;/a&gt; OR &lt;a href="https://github.com/scharan/Goodies/blob/master/hn.js" target="_blank"&gt;&lt;a href="https://github.com/scharan/Goodies/blob/master/hn.js"&gt;https://github.com/scharan/Goodies/blob/master/hn.js&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To use it, simply include the following line:
&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://saicharan.in/work/hn.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;
Here is the code:&lt;/p&gt;
&lt;script src="https://emgithub.com/embed-v2.js?target=https%3A%2F%2Fgithub.com%2Fscharan%2FGoodies%2Fblob%2Fmaster%2Fhn.js&amp;style=default&amp;type=code&amp;showBorder=on&amp;showLineNumbers=on&amp;showFileMeta=on&amp;showFullPath=on&amp;showCopy=on"&gt;&lt;/script&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Update:&lt;/em&gt;&lt;/strong&gt;&lt;/strong&gt; This article briefly made it to the front page of HN! I saw it at #19!. Here are the comments from HN: &lt;a title="HN Button &lt;&lt; Comments from HN" href="http://news.ycombinator.com/item?id=700053" target="_blank"&gt;&lt;a href="http://news.ycombinator.com/item?id=700053"&gt;http://news.ycombinator.com/item?id=700053&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Redirecting blogger traffic</title><link>https://www.saicharan.in/blog/2009/07/06/redirecting-blogger-traffic</link><pubDate>Mon, 06 Jul 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/07/06/redirecting-blogger-traffic</guid><description>&lt;p&gt;Having moved to my own domain, I was monitoring traffic to my site on Google Webmasters site. I notices that Google still returned results from my blogger-hosted domain. I wanted people to be redirected to my new domain.&lt;/p&gt;
&lt;p&gt;Here is what I did:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Blogger &amp;gt; Settings &amp;gt; Publishing &amp;gt; Advanced Settings. Chose to redirect to my sub-domain blog.saicharan.in&lt;/li&gt;
&lt;li&gt;In my domain management cpanel &amp;gt; Subdomains, created blog.saicharan.in and added the home directory as my blog directory.&lt;/li&gt;
&lt;li&gt;Using the wordpress admin interface, I changed the structure of my blog permalinks to be of blog/year/month/date/title.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now come the interesting part. While wordpress provided me text to add in my .htaccess, it did not provide the code for redirection. Google helped me add the following line in my .htaccess file that did the trick!&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;RedirectMatch permanent ^/[0-9]{4}/[0-9]{2}/([a-z0-9]+) http://saicharan.in/blog/$1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That did the trick. Thanks to BlogBloke!&lt;/p&gt;
&lt;h4 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References: &lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.blogbloke.com/migrating-redirecting-blogger-wordpress-htaccess-apache-best-method/"&gt;http://www.blogbloke.com/migrating-redirecting-blogger-wordpress-htaccess-apache-best-method/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>.bash_profile in ubuntu</title><link>https://www.saicharan.in/blog/2009/07/01/bash_profile-in-ubuntu</link><pubDate>Wed, 01 Jul 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/07/01/bash_profile-in-ubuntu</guid><description>&lt;p&gt;I updated my &lt;code&gt;.bash_profile&lt;/code&gt; in my ubuntu instance but the changes were not getting reflected in my shell.&lt;/p&gt;
&lt;p&gt;A bit of searching revealed that I have to instead add a new &lt;code&gt;.sh&lt;/code&gt; file in &lt;code&gt;/etc/profile.d/&lt;/code&gt; that contained the necessary aliases and updates to my &lt;code&gt;PATH&lt;/code&gt; etc. It appears like Ubuntu auto runs all &lt;code&gt;.sh&lt;/code&gt; files in &lt;code&gt;/etc/profile.d/&lt;/code&gt; whenever a login session is created.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.bash_profile&lt;/code&gt; was a lot more personal customization. Wonder how I could this personal customization in ubuntu. Any one any ideas? Let us know via comments.&lt;/p&gt;
&lt;p&gt;@update: Thanks to manoj for pointing out &lt;code&gt;.bashrc&lt;/code&gt; (had forgotton about it). &lt;code&gt;.bashrc&lt;/code&gt; does help with personalizing the environment.&lt;/p&gt;
</description></item><item><title>Default runlevel on Ubuntu</title><link>https://www.saicharan.in/blog/2009/07/01/default-runlevel-on-ubuntu</link><pubDate>Wed, 01 Jul 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/07/01/default-runlevel-on-ubuntu</guid><description>Changing the default runlevel on ubuntu was quite different from that of RedHat/Fedora. Ubuntu has no &lt;code&gt;inittab&lt;/code&gt;. Instead, I had to rename the &lt;code&gt;S30gdm*&lt;/code&gt; and &lt;code&gt;S30kdm*&lt;/code&gt; files in &lt;code&gt;/etc/rc2.d/&lt;/code&gt; to &lt;code&gt;KS30gdm*&lt;/code&gt; and &lt;code&gt;KS30kdm*&lt;/code&gt; (the renaming is just like in fedora).</description></item><item><title>ld terminated with signal 9</title><link>https://www.saicharan.in/blog/2009/06/30/ld-terminated-with-signal-9</link><pubDate>Tue, 30 Jun 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/06/30/ld-terminated-with-signal-9</guid><description>&lt;p&gt;I&amp;rsquo;d been trying to build substantial amout of code on linux vmware image. Three times the build has failed with &lt;em&gt;&amp;ldquo;ld terminated with signal 9&amp;rdquo;&lt;/em&gt;. A simple google revlealed that I might have run out of swap space!&lt;/p&gt;
&lt;p&gt;So I run &lt;code&gt;sudo swaon -s&lt;/code&gt; and get nothing at all!&lt;/p&gt;
&lt;p&gt;Then a google for &lt;strong&gt;&lt;em&gt;&amp;ldquo;turning on swap space&amp;rdquo;&lt;/em&gt;&lt;/strong&gt; got me to do the following:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;# sudo dd if=/dev/zero of=/moreswap bs=1M count=512&lt;/code&gt;: that creates a 512 MB file named moreswap filled with zeros.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; # sudo mkswap /moreswap
 # sudo swapon /moreswap
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Appended the following line to &lt;code&gt;/etc/fstab&lt;/code&gt; to make this change permanent.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; /moreswap none swap sw 0 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Worked like a charm!&lt;/p&gt;
&lt;h4 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.linux.com/archive/feature/113956"&gt;http://www.linux.com/archive/feature/113956&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Ubuntu sshd</title><link>https://www.saicharan.in/blog/2009/06/30/ubuntu-sshd</link><pubDate>Tue, 30 Jun 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/06/30/ubuntu-sshd</guid><description>&lt;p&gt;&lt;code&gt;#sudo apt-get install openssh-server&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Done! Simple as that.&lt;/p&gt;
&lt;h4 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.cyberciti.biz/tips/howot-install-ubuntu-linux-ssh-server.html"&gt;http://www.cyberciti.biz/tips/howot-install-ubuntu-linux-ssh-server.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Hello WordPress! My new home online!</title><link>https://www.saicharan.in/blog/2009/06/19/hello-world</link><pubDate>Fri, 19 Jun 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/06/19/hello-world</guid><description>&lt;p&gt;Migrated to Wordpress. In about 5 seconds. Yup. I am as impressed with the 5-second install as I am with this import feature.&lt;/p&gt;
&lt;p&gt;The Dashboard &amp;gt; Tools &amp;gt; Import &amp;gt; Blogger option is fantastic. Once with WordPress, I guess I will stay with it for a real long time!&lt;/p&gt;
&lt;p&gt;Three cheers to WordPress :)&lt;/p&gt;
</description></item><item><title>CVS, ViewVC integration with Google Prettify</title><link>https://www.saicharan.in/blog/2009/03/19/cvs-viewvc-integration-with-google-prettify</link><pubDate>Thu, 19 Mar 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/03/19/cvs-viewvc-integration-with-google-prettify</guid><description>&lt;p&gt;I&amp;rsquo;d been wanting to do this for long: browse SVN/CVS via a web interface. Ofcourse, it is a solved problem. But I wanted this set up for my own local CVS repos.&lt;/p&gt;
&lt;p&gt;ViewVC to the rescue.&lt;/p&gt;
&lt;p&gt;Prerequisites: Python2.x, Apache2.0+, CVS, CVS/SVN Python Bindings.&lt;/p&gt;
&lt;p&gt;Detailed installation process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ViewVC:
I have CVSNT on my workstation. So I downloaded ViewVC-1.0.7 from &lt;a href="http://www.viewvc.org/download.html"&gt;&lt;a href="http://www.viewvc.org/download.html"&gt;http://www.viewvc.org/download.html&lt;/a&gt;&lt;/a&gt; (spcecifically, version 1.0.7 from&lt;a href="http://viewvc.tigris.org/servlets/ProjectDocumentList?folderID=6004"&gt; &lt;a href="http://viewvc.tigris.org/servlets/ProjectDocumentList?folderID=6004"&gt;http://viewvc.tigris.org/servlets/ProjectDocumentList?folderID=6004&lt;/a&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;To install ViewVC, first unpack it to some folder, run &amp;lsquo;python viewvc-install&amp;rsquo; from the command line, with the current directory as the unpacked directory. I chose all the defaults values when prompted.&lt;/p&gt;
&lt;p&gt;Next, I configured viewvc to pick up my repositories by editing the &lt;install-dir&gt;/viewvc.conf file. I changed the cvs_roots and cvsnt_exe_path variables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SVN Python bindings for ViewVC:
ViewVC is written in python and &lt;a href="http://www.blogger.com/tigris.org"&gt;tigris.org&lt;/a&gt; provides python bindings to talk to the CVS/SVN repository. This can be got from &lt;a href="http://subversion.tigris.org/getting.html#windows%20http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100"&gt;subversion.tigris.org Documents Area.&lt;/a&gt; Be sure to download the version appropirate for your version of python. Simply run the installer. You will be asked to point the installer to the Apache installation directory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mod_python:
You will need to download the mod_python for Apache if you dont have it already. You can check the &lt;apache-install-dir&gt;/modules/ directory. Look for mod_python.so file. If it is not here, download it from here: &lt;a href="http://www.apache.org/dist/httpd/modpython/win/3.3.1/"&gt;&lt;a href="http://www.apache.org/dist/httpd/modpython/win/3.3.1/"&gt;http://www.apache.org/dist/httpd/modpython/win/3.3.1/&lt;/a&gt;&lt;/a&gt; I used this: &lt;a href="http://www.apache.org/dist/httpd/modpython/win/3.3.1/mod_python-3.3.1.win32-py2.5-Apache2.2.exe"&gt;&lt;a href="http://www.apache.org/dist/httpd/modpython/win/3.3.1/mod_python-3.3.1.win32-py2.5-Apache2.2.exe"&gt;http://www.apache.org/dist/httpd/modpython/win/3.3.1/mod_python-3.3.1.win32-py2.5-Apache2.2.exe&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configuring Apache: edit the httpd.conf file to add the following:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; LoadModule python_module modules/mod_python.so
 ScriptAlias /viewcvs &amp;#34;C:/Program Files/viewvc-1.0.7/bin/mod_python/viewvc.py&amp;#34;
 &amp;lt;location&amp;gt;
 AddHandler python-program .py
 PythonPath &amp;#34;[r&amp;#39;c:\\Program Files\\viewvc-1.0.7\\bin\\mod_python&amp;#39;]+sys.path&amp;#34;
 PythonHandler apache
 PythonDebug On
 AddDefaultCharset UTF-8
 &amp;lt;/location&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;NOTE: The above will work if you have chosen the defaults while installing ViewVC.&lt;/p&gt;
&lt;p&gt;Done! Goto: http://your-machine/viewcvs.&lt;/p&gt;
&lt;p&gt;However, I got an error when I did this: &amp;ldquo;ImportError: No module named apache&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;So, I tried the alternate approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Copy &lt;code&gt;&amp;lt;viewvc-install-dir&amp;gt;/bin/cgi/*.cgi&lt;/code&gt; to &lt;code&gt;&amp;lt;apache-install-dir&amp;gt;/cgi-bin/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the following line to the &lt;code&gt;&amp;lt;apache-install-dir&amp;gt;/conf/httpd.conf&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; ScriptAlias /viewvc /cgi-bin/viewvc.cgi
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Restart Apache.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Done! Go to: http://localhost/cgi-bin/viewvc.cgi. It works for me!! I wish I could fix the other method too.&lt;/p&gt;
&lt;p&gt;Good. Now that it works, I should be happy. But I was not :( When I &amp;lsquo;view&amp;rsquo; a source file, it does not do the syntax highlighting (I use CVS with C++/C projects and I was not getting the syntax highlighting for these languages). So what do I do? Wanted to integrate some open source syntax highlighters. I dug thru&amp;rsquo; the code of viewvc.py and from there went on to find the place where the markup is done. (search the code base for view_markup function. I use &lt;a href="http://sourcenav.sourceforge.net/download.html"&gt;RedHat sourcenavigator&lt;/a&gt; to browse and read code). They seemed to be using some PHP code to get the job done. However, I remembered I was very happy with Google&amp;rsquo;s Prettify (any code you browse on code.google.com has probably used Google prettify to syntax highlight the code). So I decided to use it.&lt;/p&gt;
&lt;p&gt;Also, using the Google Pettify is quite simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add the following lines to the &amp;ldquo;head&amp;rdquo; section:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; &amp;lt;link href=&amp;#34;[docroot]/prettify/prettify.css&amp;#34; type=&amp;#34;text/css&amp;#34; rel=&amp;#34;stylesheet&amp;#34; /&amp;gt;
 &amp;lt;script type=&amp;#34;text/javascript&amp;#34; src=&amp;#34;[docroot]/prettify/prettify.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;onload=prettyPrint()&lt;/code&gt; attribute to the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag.&lt;/li&gt;
&lt;li&gt;Put your code in &lt;code&gt;&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;code class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;/code&gt; tags.&lt;/li&gt;
&lt;li&gt;Done!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It took quite some reading of the ViewVC python code to figure out simple ways to do it. Here is my story:&lt;/p&gt;
&lt;p&gt;I read thru the ViewVC python code and found that there was a header and footer being used for each page. Then there was a template for markup and each of the different views that ViweVC supports. Then I stumbled upon the EZT class (EaZyTemplates). Just what I needed to integrate with Google Prettify!! So I found the templates being loaded by ViewVC. They are loacated under &lt;code&gt;&amp;lt;viewvc-install-dir&amp;gt;/templates/&lt;/code&gt;. Here are my modifications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download Google Prettify from: &lt;a href="http://code.google.com/p/google-code-prettify"&gt;http://code.google.com/p/google-code-prettify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Unzip it. Copy the src folder to &lt;code&gt;&amp;lt;viewvc-install-dir&amp;gt;/templates/docroot/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I renamed the &lt;code&gt;src&lt;/code&gt; folder to &lt;code&gt;prettify&lt;/code&gt; (just to help me later)&lt;/li&gt;
&lt;li&gt;Add the following lines to &lt;code&gt;&amp;lt;viewvc-install-dir&amp;gt;/templates/include/header.ezt&lt;/code&gt;, in the &lt;code&gt;head&lt;/code&gt; section:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; &amp;lt;link href=&amp;#34;[docroot]/prettify/prettify.css&amp;#34; type=&amp;#34;text/css&amp;#34; rel=&amp;#34;stylesheet&amp;#34;/&amp;gt;
 &amp;lt;script type=&amp;#34;text/javascript&amp;#34; src=&amp;#34;%5Bdocroot%5D/prettify/prettify.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Also, modify the body tag to: &lt;code&gt;&amp;lt;body onload=&amp;quot;prettyPrint()&amp;quot;&amp;gt;&lt;/code&gt;;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Modify &lt;code&gt;&amp;lt;viewvc-install-dir&amp;gt;/templates/markup.ezt&lt;/code&gt;. Change this:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; &amp;lt;div id=&amp;#34;vc_markup&amp;#34;&amp;gt; &amp;lt;pre&amp;gt;[markup]&amp;lt;/pre&amp;gt; &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; &amp;lt;div id=&amp;#34;vc_markup&amp;#34;&amp;gt; &amp;lt;pre class=&amp;#34;prettyprint&amp;#34;&amp;gt;[markup]&amp;lt;/pre&amp;gt; &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Done!. Have fun! And post your questions as comments.&lt;/p&gt;
</description></item><item><title>Google default language</title><link>https://www.saicharan.in/blog/2009/03/02/google-default-language</link><pubDate>Mon, 02 Mar 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/03/02/google-default-language</guid><description>&lt;p&gt;Each time I use Google from office, Google responds in Thai. I fixed that by going to &lt;a href="https://www.google.com/ncr"&gt;https://www.google.com/ncr&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now onwards, I hope to always get results in English :) Btw, if you happen to clear your cookies, you should go to &lt;a href="https://www.google.com/ncr"&gt;https://www.google.com/ncr&lt;/a&gt; again.&lt;/p&gt;
</description></item><item><title>NS2 nam error</title><link>https://www.saicharan.in/blog/2009/03/02/ns2-nam-error</link><pubDate>Mon, 02 Mar 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/03/02/ns2-nam-error</guid><description>&lt;p&gt;I have been bothered by this error while running ns/nam for a long time now. Finally found that &lt;code&gt;tk&lt;/code&gt; needed patching :( Here is the error that I got and the solution that helped me fix it. Error:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; [root@localhost]# nam: 
 [code omitted because of length]
 : no event type or button # or keysym
 while executing
 &amp;#34;bind Listbox &amp;lt;mousewheel&amp;gt; {&amp;lt;/mousewheel&amp;gt;
 %W yview scroll [expr {- (%D / 120) * 4}] units
 }&amp;#34;
 invoked from within
 &amp;#34;if {[tk windowingsystem] eq &amp;#34;classic&amp;#34; || [tk windowingsystem] eq &amp;#34;aqua&amp;#34;} {
 bind Listbox &amp;lt;mousewheel&amp;gt; {&amp;lt;/mousewheel&amp;gt;
 %W yview scroll [expr {- (%D)}] units
 }
 bind Li...&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And, I got the solution to this on: &lt;a href="http://forums.fedoraforum.org/showthread.php?t=206795"&gt;http://forums.fedoraforum.org/showthread.php?t=206795&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Essentially you need to patch tk8.4.18 with the patches from: &lt;a href="http://bugs.gentoo.org/show_bug.cgi?id=225999"&gt;http://bugs.gentoo.org/show_bug.cgi?id=225999&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Details of how to patch are available at: &lt;a href="http://forums.fedoraforum.org/showpost.php?s=a2bb89875669ff26ed61cd371399a517&amp;amp;amp;p=1131049&amp;amp;amp;postcount=3"&gt;http://forums.fedoraforum.org/showpost.php?s=a2bb89875669ff26ed61cd371399a517&amp;amp;amp;p=1131049&amp;amp;amp;postcount=3&lt;/a&gt;.&lt;/p&gt;
</description></item><item><title>My Reading List</title><link>https://www.saicharan.in/blog/2009/02/17/my-reading-list</link><pubDate>Tue, 17 Feb 2009 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2009/02/17/my-reading-list</guid><description>&lt;p&gt;Very frequently my friends ask for my reading list. So I decided to follow the &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;SRP&lt;/a&gt; principles to help them and help myself. Hence this blog entry. Here goes:&lt;/p&gt;
&lt;p&gt;My favourite tech blogs/sites:&lt;/p&gt;
&lt;h5 id="programming-blogs"&gt; &lt;a class="anchor" href="#programming-blogs"&gt;Programming blogs &lt;/a&gt;&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://codinghorror.com/"&gt;codinghorror.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.objectmentor.com/"&gt;blog.objectmentor.com&lt;/a&gt; (along with its original site at &lt;a href="http://butunclebob.com/"&gt;butunclebob.com&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://thedailywtf.com/"&gt;thedailywtf.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://c2.com/"&gt;c2.com&lt;/a&gt; ➔ Advanced stuff. Really interesting though. It takes some time to follow their style of expression - but is definitely worth a shot.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.reddit.com/"&gt;reddit.com&lt;/a&gt; In particular, &lt;a href="http://www.reddit.com/r/programming/"&gt;/r/programming&lt;/a&gt; &amp;amp; &lt;a href="http://www.reddit.com/r/technology/"&gt;/r/technology&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id="programming-technology-perspectives-my-favourite-pass-times"&gt; &lt;a class="anchor" href="#programming-technology-perspectives-my-favourite-pass-times"&gt;Programming, Technology, Perspectives (my favourite pass-times) &lt;/a&gt;&lt;/h5&gt;
&lt;ol start="0"&gt;
&lt;li&gt;&lt;a href="http://news.ycombinator.com"&gt;news.ycombinator.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://steve-yegge.blogspot.com/"&gt;steve-yegge.blogspot.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://paulgraham.com/"&gt;paulgraham.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://joelonsoftware.com"&gt;joelonsoftware.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://norvig.com"&gt;norvig.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://googleblog.blogspot.com/"&gt;googleblog.blogspot.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ted.com/"&gt;TED.com&lt;/a&gt; - My personal favorite for advances in human thought and creativity!&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id="tech-news"&gt; &lt;a class="anchor" href="#tech-news"&gt;Tech News &lt;/a&gt;&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://digg.com/"&gt;digg.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://slashdot.org/"&gt;slashdot.org&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id="management"&gt; &lt;a class="anchor" href="#management"&gt;Management &lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;(yeah, I am interested in &lt;em&gt;Genuine&lt;/em&gt; management!)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://sethgodin.typepad.com/"&gt;sethgodin.typepad.com&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;PS: I will update this post as my reading list changes (Yes. that includes additions &lt;em&gt;and&lt;/em&gt; deletions as well. For deletions, I will keep the links, but the text will be struck off like &lt;del&gt;this&lt;/del&gt;).&lt;/p&gt;
</description></item><item><title>Creating DLLs with MinGW</title><link>https://www.saicharan.in/blog/2008/09/17/creating-dlls-with-mingw</link><pubDate>Wed, 17 Sep 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/09/17/creating-dlls-with-mingw</guid><description>&lt;p&gt;This morning, I was asked how to use existing C code in C++ code. So I took the route of converting the C code into a DLL and then linking to it from the C++ code. So I had to figure out how to do this using MinGW on Windows. Here is an account of my experiments (distilled ofcourse!):&lt;/p&gt;
&lt;p&gt;There are three things you need to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Convert the existing into a DLL.&lt;/li&gt;
&lt;li&gt;Include the header of the DLL in the sources where you wish to use the library.&lt;/li&gt;
&lt;li&gt;Build your code, linking against your DLL.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here are the steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For this, you need to add the following code to the header file containing the declarations of the functions that are to be used:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#ifdef __cplusplus
#define cppfudge &amp;#34;C&amp;#34;
#else
#define cppfudge
#endif
&lt;p&gt;#ifdef BUILD_DLL
// the dll exports
#define EXPORT __declspec(dllexport)
#else
// the exe imports
#define EXPORT extern cppfudge __declspec(dllimport)
#endif
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;&lt;/p&gt;
&lt;li&gt;Front of each function that you want to use from the DLL, prepend the word &lt;code&gt;EXPORT&lt;/code&gt;. For example:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;EXPORT int hello(void);
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Create the create the object code using the following command (where &lt;code&gt;TestDLL.c&lt;/code&gt; is the source file):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt; gcc -c -DBUILD_DLL TestDLL.c
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Next, use the object code to create the DLL with the following command (note that &lt;code&gt;TestDLL&lt;/code&gt; has to be replaced with whatever is the actual DLL name):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt; gcc -shared -o TestDLL.dll TestDLL.o -Wl,--out-implib,TestDLL.a
&amp;gt; Creating library file: TestDLL.a` # (this is the output of the command)
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="5"&gt;
&lt;li&gt;Now, compile the actual file (note that this file should include the TestDLL.h header)&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-." data-lang="."&gt;&amp;gt;gcc Main.cpp -o Main.exe TestDLL.dll
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="6"&gt;
&lt;li&gt;Done! Run the executable:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;Main.exe
Hello World!
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://sites.google.com/site/scharan20/Home/DLL.zip?attredirects=0"&gt;Here&lt;/a&gt; are the files that I have used to test these things. I have tested them on Windows XP using MinGW32.&lt;/p&gt;
&lt;h4 id="reference"&gt; &lt;a class="anchor" href="#reference"&gt;Reference &lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.emmestech.com/moron_guides/moron2.html"&gt;http://www.emmestech.com/moron_guides/moron2.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Global C++ Exception Handler</title><link>https://www.saicharan.in/blog/2008/07/29/global-c-exception-handler</link><pubDate>Tue, 29 Jul 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/07/29/global-c-exception-handler</guid><description>&lt;p&gt;Just found out that many C++ compilers provide the &lt;code&gt;std::set_terminate()&lt;/code&gt; function for catching any unanticipated exceptions.&lt;/p&gt;
&lt;h4 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.extinguishedscholar.com/wpglob/?p=176"&gt;http://www.extinguishedscholar.com/wpglob/?p=176&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>C/C++ resources online</title><link>https://www.saicharan.in/blog/2008/06/11/cc-resources-online</link><pubDate>Wed, 11 Jun 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/06/11/cc-resources-online</guid><description>&lt;p&gt;The following is a continually updated list of my personal favorites for C/C++ reference:&lt;/p&gt;
&lt;h5 id="c"&gt; &lt;a class="anchor" href="#c"&gt;C &lt;/a&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;C-FAQs: &lt;a href="http://c-faq.com/index.html"&gt;http://c-faq.com/index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Overflows in C: &lt;a href="http://www.fefe.de/intof.html"&gt;http://www.fefe.de/intof.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="c-1"&gt; &lt;a class="anchor" href="#c-1"&gt;C++ &lt;/a&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Stanford Library: &lt;a href="http://cslibrary.stanford.edu"&gt;http://cslibrary.stanford.edu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C++ Coding Conventions (CERN): &lt;a href="http://pst.web.cern.ch/PST/HandBookWorkBook/Handbook/Programming/CodingStandard/c++standard.pdf"&gt;http://pst.web.cern.ch/PST/HandBookWorkBook/Handbook/Programming/CodingStandard/c++standard.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C++ Casting: &lt;a href="http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/cast.html"&gt;http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/cast.html&lt;/a&gt; &amp;amp; &lt;a href="http://www.nacs.uci.edu/dcslib/sun/compilers/c-plusplus/c%2B%2B_ug/Cast.new.doc.html"&gt;http://www.nacs.uci.edu/dcslib/sun/compilers/c-plusplus/c%2B%2B_ug/Cast.new.doc.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>ThinkPad T60 TouchPad Scroll in Office 2007</title><link>https://www.saicharan.in/blog/2008/06/10/thinkpad-t60-touchpad-scroll-in-office-2007</link><pubDate>Tue, 10 Jun 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/06/10/thinkpad-t60-touchpad-scroll-in-office-2007</guid><description>Found this link on Google. It was reported as on the day of posting as a possibly problematic site. But I went on and found the info in that site very useful. So here is the link: &lt;a href="http://www.lvlolvlo.net/2007/02/11/office-2007-on-a-thinkpad-ultranav-support-for-scrolling-fix/"&gt;http://www.lvlolvlo.net/2007/02/11/office-2007-on-a-thinkpad-ultranav-support-for-scrolling-fix/&lt;/a&gt;.</description></item><item><title>Wrong Characters being Displayed</title><link>https://www.saicharan.in/blog/2008/06/10/wrong-characters-being-displayed</link><pubDate>Tue, 10 Jun 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/06/10/wrong-characters-being-displayed</guid><description>&lt;p&gt;Had this problem with my keyboard layout getting changed just too often. The problem was as follows: Off and on, my keyboard was behaving erratically. It would mis-behave and then come back to normal. I suspected a change of keyboard layout - I had this problem earlier on my Linux Box and RI pointed out that my keyboard layout was UK English!&lt;/p&gt;
&lt;p&gt;So, I too started off searching google for this, and things were mostly pointing to IME/Languages. When I opened the Regional Language Options in the Control Panel, the language bar popped up. I noticed that the language was set to Finnsh. Once I changed that to English, another icon appeared next to it - the Keyboard icon. It was in Finnish. So I changed it to English and all was well. But then I was wondering how these settings were changing so often. SO I went to the Regional Language Options in the Control Panel. Went to the languages tab and clicked on the Details button. From there, I selected the Finnish Language and Keyboard settings. At the bottom there is a Key Settings button. That was the major culprit. Click that button and you will see that Alt+Shift is assigned to &amp;ldquo;Switch between input Languages&amp;rdquo; option. I simply removed that key-binding to avoid un-intended switching between languages.&lt;/p&gt;
&lt;p&gt;Also, I use the alt+shift combo often in my work - so that was the probem! Now we know! So change your keyboard settings and get back to efficient mode.&lt;/p&gt;
&lt;p&gt;One last advice. If you ever face such a problem, make the language bar visible: &lt;code&gt;Control Panel &amp;gt; Regional Language Options &amp;gt; Details &amp;gt; Language Bar Button &amp;gt; Show Language Bar&lt;/code&gt;. Once you see the language bar, you can know at once if your keyboard layout is the problem.&lt;/p&gt;
</description></item><item><title>VirusRemoval.vbs Windows Script Host</title><link>https://www.saicharan.in/blog/2008/03/27/virusremoval-vbs-windows-script-host</link><pubDate>Thu, 27 Mar 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/03/27/virusremoval-vbs-windows-script-host</guid><description>&lt;p&gt;Atlast! Got rid of that damn warning.&lt;/p&gt;
&lt;p&gt;msconfig did not show up this thing. No amount of standard registry scans helped me find this. I looked at the standard Run, RunOnce &amp;amp; Shell hives under &lt;code&gt;HKLM/Software/Microsoft/Windows/CurrentVersion&lt;/code&gt;. Just no use. No entries that were tell-tale traces of this VirusRemoval.vbs.&lt;/p&gt;
&lt;p&gt;But done at last! Took some patient Google-searching though. Some kind soul had provided the entire code of the VirusRemoval.vbs script file at:
&lt;a href="http://www.thinkdigit.com/forum/showthread.php?t=71097"&gt;http://www.thinkdigit.com/forum/showthread.php?t=71097&lt;/a&gt;. Looking at the code was enough to tell me where the virus had made entries in the registry.&lt;/p&gt;
&lt;p&gt;Goto: HKLM/Software/Microsoft/WindowsNT/CurrentVersion/Winlogon. Under that, you will find a key called Userinit. Double click that key. A dialog box will open up with a string parameter. Edit that to remove just the offending entry. &lt;em&gt;Warning:&lt;/em&gt; If you are not sure what the offending entry is, DONOT modify the key. Please post back the contents of the key here, and we could work out something!&lt;/p&gt;
&lt;p&gt;After cleaning up my registry, the value of &lt;code&gt;Userinit&lt;/code&gt; for me is: &lt;code&gt;C:\WINDOWS\system32\userinit.exe&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Good Luck!&lt;/p&gt;
</description></item><item><title>Install RPMs on Ubuntu</title><link>https://www.saicharan.in/blog/2008/03/19/install-rpms-on-ubuntu</link><pubDate>Wed, 19 Mar 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/03/19/install-rpms-on-ubuntu</guid><description>&lt;p&gt;Check this link. It describes the use of a tool called &amp;lsquo;alien&amp;rsquo; to install RPMs on Ubuntu linux!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://theunixgeek.blogspot.com/2008/03/why-i-switched-back-to-ubuntu.html#c2746545558233032385"&gt;http://theunixgeek.blogspot.com/2008/03/why-i-switched-back-to-ubuntu.html#c2746545558233032385&lt;/a&gt;.&lt;/p&gt;
</description></item><item><title>yum ntfs-3g</title><link>https://www.saicharan.in/blog/2008/02/16/yum-ntfs-3g</link><pubDate>Sat, 16 Feb 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/02/16/yum-ntfs-3g</guid><description>&lt;p&gt;To install ntfs support for Fedora linux, use the following as root:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;yum install fuse fuse-libs ntfs-3g
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.mjmwired.net/resources/mjm-fedora-f7.html#ntfs"&gt;http://www.mjmwired.net/resources/mjm-fedora-f7.html#ntfs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Adobe Reader Commenting Not Allowed</title><link>https://www.saicharan.in/blog/2008/02/06/adobe-reader-commenting-not-allowed</link><pubDate>Wed, 06 Feb 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/02/06/adobe-reader-commenting-not-allowed</guid><description>&lt;p&gt;At last!
Wanted to allow my prof. to be able to comment the pdf files that my LaTeX produces. But, even though I was NOT setting any such restrictions in LaTeX, the Adobe Reader always showed that Commenting was not allowed. After a Google search, I got this post in the Adobe Forums: &lt;a href="http://www.adobeforums.com/webx/.3c05f5b1"&gt;http://www.adobeforums.com/webx/.3c05f5b1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In short: You cannot comment unless explicitly permitted. For this, you need to get to Adobe Acrobat (not the reader), and set the permission from: &lt;code&gt;Commenting &amp;gt; Enable for Commenting&lt;/code&gt; in Adobe Reader.&lt;/p&gt;
&lt;p&gt;Then you will be allowed to comment or markup :)&lt;/p&gt;
&lt;p&gt;Update: If you don&amp;rsquo;t mind a few additions of Foxit, you might want to try Foxit reader (&lt;a href="https://www.foxitsoftware.com"&gt;foxitsoftware.com&lt;/a&gt;) for commenting your PDF documents without any of the above hassle.&lt;/p&gt;
</description></item><item><title>TeXnicCenter and Adobe Reader 8.0</title><link>https://www.saicharan.in/blog/2008/02/04/texniccenter-and-adobe-reader-8-0</link><pubDate>Mon, 04 Feb 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/02/04/texniccenter-and-adobe-reader-8-0</guid><description>&lt;p&gt;I recently upgraded my Adobe Reader to version 8. The new interface is cool and all that, but I had an issue with using TeXnicCenter. Whenever I view a compiled document from TeXnicCenter, and then closed the Adobe reader or recompiled the file (causing adobe reader to close the document), the Adobe reader was crashing. A Google search yielded the following link which is very useful. It is almost a text-book type of solution which just works!&lt;/p&gt;
&lt;h5 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://dikkie.net/2007/02/16/texniccenter-and-adobe-reader-80/"&gt;http://dikkie.net/2007/02/16/texniccenter-and-adobe-reader-80/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>WIndows Script Host: Unable to open file</title><link>https://www.saicharan.in/blog/2008/02/04/windows-script-host-unable-to-open-file</link><pubDate>Mon, 04 Feb 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/02/04/windows-script-host-unable-to-open-file</guid><description>&lt;p&gt;For quite some time a lot of my friends kept getting a windows script host error whenever they tried to open a drive. It says: &lt;code&gt;Windows Script Error: Unable to find file: &amp;quot;....vbs&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Spending some time on google led me to this site:
&lt;a href="http://www.mydigitallife.info/2007/04/19/unable-to-open-hard-or-usb-flash-drive-with-windows-script-host-cannot-find-script-file-autorunvbs-error/"&gt;http://www.mydigitallife.info/2007/04/19/unable-to-open-hard-or-usb-flash-drive-with-windows-script-host-cannot-find-script-file-autorunvbs-error/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;All we need to do is to either delete the autorun.inf file there or modify the content in to get rid of the offending startup file info. To delete the file:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;del:\autorun.inf /f /s /q /a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To modify the file, first remove its hidden-file attribute: &lt;code&gt;attrib -s -h -r:\autorun.inf&lt;/code&gt; (see &lt;a href="http://forums.techarena.in/showthread.php?t=717194)"&gt;http://forums.techarena.in/showthread.php?t=717194)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Go ahead and edit this file now.&lt;/p&gt;
</description></item><item><title>Why is switch case better than if else if?</title><link>https://www.saicharan.in/blog/2008/01/28/why-is-switch-case-better-than-if-else-if</link><pubDate>Mon, 28 Jan 2008 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2008/01/28/why-is-switch-case-better-than-if-else-if</guid><description>&lt;p&gt;Why is switch case better than else if? Or is it?
Here is some code I got into trouble with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;...
if(dim==0){
 //do lots of things
 return;
}
doSomeCommonThingsHere();
if(dim==3)
 doSomething3();
else if(dim==4)
 doSomething4();
else if(dim==5);
 doSomething5();
doSomeMoreCommonSomethings();
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See anything?&lt;/p&gt;
&lt;p&gt;I did not, initially. The semi colon after else &lt;code&gt;if(dim==5)&lt;/code&gt;. How I unearthed the bug? GDB was crashing. So no debugger to help me:( I figured out that only the dim==5 case was working well - and that none of the cases above it were working correctly. So I considered moving one of the earlier case code to the end to see if I can figure out the problem. While moving the code I accidentally noticed the semi-colon. Man! Computers are dumb - or was it me dumb?&lt;/p&gt;
&lt;p&gt;Now did say switch case might have been better? Maybe. Because we are &lt;em&gt;taught&lt;/em&gt; to put the &lt;code&gt;break;&lt;/code&gt; statement at the end of each case to prevent it from falling-through right? What if I forgot to put the &lt;code&gt;break;&lt;/code&gt;? I guess it is easier to &amp;ldquo;find&amp;rdquo; a missing break than a missing &lt;code&gt;;&lt;/code&gt;. Did you see the semi-colon after missing?&lt;/p&gt;
&lt;p&gt;Now why did I use such a large number of &lt;code&gt;if-else-if&lt;/code&gt; statements? I was using &amp;ldquo;Incremental development&amp;rdquo;. I did not see the other cases coming in hordes. Shortsighted you might say, but I did not even intend to do the other cases in the first place. WOW! How easily changing requirements can screw up such wonderfully working code. Screw the changing requirements. Now you see how difficult is the job of a designer - he has to really think of extensibility - see extensibility in a new light?&lt;/p&gt;
&lt;p&gt;Consider for a moment the above code. I was actually telling the computer to do things wrong!!! When will these computers learn to understand (:D) Or will they ever?&lt;/p&gt;
</description></item><item><title>MinGW GProf with Eclipse 3.3 (Europa )</title><link>https://www.saicharan.in/blog/2007/09/14/mingw-gprof-with-eclipse-3-3-europa</link><pubDate>Fri, 14 Sep 2007 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2007/09/14/mingw-gprof-with-eclipse-3-3-europa</guid><description>&lt;p&gt;To use MinGW gprof with Eclipse, in the project settings, under complier, enable the gprof option. Further, in the Linker section, under command line, add &lt;code&gt;-pg&lt;/code&gt; to your list. Build the program. Run the program and check that the &lt;code&gt;gmon.out&lt;/code&gt; file has been created.&lt;/p&gt;
&lt;p&gt;You can run gprof as follows: &lt;code&gt;gprof.exe&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can run gprof from within eclipse by configuring the external tools:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the external tools dialog&lt;/li&gt;
&lt;li&gt;Double click on program to create a new program configuration&lt;/li&gt;
&lt;li&gt;Give this profile a name, eg. gprof&lt;/li&gt;
&lt;li&gt;In the location text box, give the FULL path to the grpof command&lt;/li&gt;
&lt;li&gt;In the working directory, choose: ${workspace_loc:/path/to/executable}&lt;/li&gt;
&lt;li&gt;Arguements: ${file_prompt} ${GMON}, where GMON has been assigned the path to the gmon.out file using the variables button.&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://publib.boulder.ibm.com/infocenter/systems/topic/com.ibm.aix.cmds/doc/aixcmds2/gprof.htm"&gt;http://publib.boulder.ibm.com/infocenter/systems/topic/com.ibm.aix.cmds/doc/aixcmds2/gprof.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gcc.gnu.org/ml/fortran/2006-11/msg00217.html"&gt;http://gcc.gnu.org/ml/fortran/2006-11/msg00217.html&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description></item><item><title>ब्लोग्गीं, और हिंदी मे!</title><link>https://www.saicharan.in/blog/2007/04/18/%E0%A4%AC%E0%A5%8D%E0%A4%B2%E0%A5%8B%E0%A4%97%E0%A5%8D%E0%A4%97%E0%A5%80%E0%A4%82-%E0%A4%94%E0%A4%B0-%E0%A4%B9%E0%A4%BF%E0%A4%82%E0%A4%A6%E0%A5%80-%E0%A4%AE%E0%A5%87</link><pubDate>Wed, 18 Apr 2007 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2007/04/18/%E0%A4%AC%E0%A5%8D%E0%A4%B2%E0%A5%8B%E0%A4%97%E0%A5%8D%E0%A4%97%E0%A5%80%E0%A4%82-%E0%A4%94%E0%A4%B0-%E0%A4%B9%E0%A4%BF%E0%A4%82%E0%A4%A6%E0%A5%80-%E0%A4%AE%E0%A5%87</guid><description>&lt;p&gt;हेल्लो वर्ल्ड!
गूगल ki गूढ़ विल से हिंदी मे ब्लोग करना बहुत आसान हैं। इस फेतुरे के लिए शुक्रिया!!! लव यू गूगल! कीप उप थे गूढ़ वर्क!&lt;/p&gt;
&lt;p&gt;Please excuse my rustic hindi&amp;hellip;I was just experimenting :) If you are unable to read the Hindi correctly, then please read this article on enabling Indic fonts for various OSs: &lt;a href="http://en.wikipedia.org/wiki/Wikipedia:Enabling_complex_text_support_for_Indic_scripts"&gt;&lt;a href="http://en.wikipedia.org/wiki/Wikipedia:Enabling_complex_text_support_for_Indic_scripts"&gt;http://en.wikipedia.org/wiki/Wikipedia:Enabling_complex_text_support_for_Indic_scripts&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Routing and Remote Access Service Fails!</title><link>https://www.saicharan.in/blog/2007/01/27/routing-and-remote-access-service-fails</link><pubDate>Sat, 27 Jan 2007 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2007/01/27/routing-and-remote-access-service-fails</guid><description>This afternoon, we were suddenly unable to browse the internet. Suspicious about the proxy server being down, I checkout from our main browsing computers. I was able to ping the students proxy.
A little more digging up led me to figure out that there was something wrong with our lab router that handles the internet traffic to the student&amp;rsquo;s proxy; the main browsing systems bypass the router.
I disabled the routing service and set it up again. Though the routing service itself did not throw up any error, the event log had logged the error message. I was unable to browse even from the router itself. Also, the IIS server on the router also failed.
I restarted the system thinking it might help - but to no avail!
Checking the event log revealed that the Routing and Remote Access service had thrown up an error - Unable to add the internal adapter to the routing service - incorrect parameter. Looking at the event log messages for a few hours earlier, I hit upon a message saying that a duplicate name had been detected on the network. I then realized that this was quite likely since our server had a name Dell1, which was quite possible to be duplicated over the network since there were a plethora of Dell machines springing up here. So I renamed our machine and restarted - Bingo! it was running like a good ol&amp;rsquo; boy!
Lesson to be learnt: Event log &lt;em&gt;&lt;strong&gt;is&lt;/strong&gt;&lt;/em&gt; Holy Grail!.</description></item><item><title>Now, thats a Palindrome...</title><link>https://www.saicharan.in/blog/2006/12/16/now-thats-a-palindrome</link><pubDate>Sat, 16 Dec 2006 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/12/16/now-thats-a-palindrome</guid><description>&lt;p&gt;Now &lt;span style="font-style: italic;"&gt;that&lt;/span&gt; is a palindrome:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal &amp;ndash; Panama!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;‐ From &lt;em&gt;Common Lisp, the Language (2nd ed)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And now, &lt;em&gt;&lt;a href="http://www.norvig.com/"&gt;this&lt;/a&gt;&lt;/em&gt; is a &lt;a href="http://www.norvig.com/pal2.html"&gt;geek&lt;/a&gt;, and &lt;em&gt;this&lt;/em&gt; is a &lt;a href="http://www.norvig.com/pal1txt.html"&gt;palindrome&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Read more at the &lt;a href="http://googleblog.blogspot.com/2004/06/man-plan-pointless-program.html"&gt;Google Blog&lt;/a&gt;.&lt;/p&gt;
</description></item><item><title>Subclipse Proxy Configuration</title><link>https://www.saicharan.in/blog/2006/12/14/subclipse-proxy-configuration</link><pubDate>Thu, 14 Dec 2006 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/12/14/subclipse-proxy-configuration</guid><description>&lt;p&gt;Whew! That was a real big deal.&lt;/p&gt;
&lt;p&gt;I wanted to checkout the newly open-sourced &lt;a href="http://code.google.com/p/google-web-toolkit/source"&gt;Google Web Toolkit&lt;/a&gt; using &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; via the &lt;a href="http://subclipse.tigris.org/"&gt;Subversion plugin&lt;/a&gt;. I work behind a proxy and have a choice of three proxies offering varying capabilities and restrictions - some require authentication while others don&amp;rsquo;t. When I tried checkout, I was in for a real surprise - I was getting an error message saying &lt;strong&gt;Error 407: Proxy authentication required&lt;/strong&gt;. Since I did not set any proxy in the first place, I was wondering how a proxy was picked up and why I was not being &lt;em&gt;prompted&lt;/em&gt; for authentication!&lt;/p&gt;
&lt;p&gt;When I searched the Eclipse preferences dialog for SVN, I did not find any place where I can set up a proxy. Also, I wondered if Subclipse had somehow chosen to use my Windows default proxy configuration. So, I went to &lt;code&gt;Control Panel &amp;gt; Internet Connection &amp;gt; Connections &amp;gt; LAN Settings&lt;/code&gt;. Nope, the default proxy that I had configured for my windows was different from the one that Subclipse was using - the default proxy did not require authentication while Subclipse was trying a proxy that required authentication. Exasperating!&lt;/p&gt;
&lt;p&gt;Just wanted to be sure which proxy was being used. As usual, the &lt;a href="http://www.ethereal.com"&gt;Ethereal&lt;/a&gt; network protocol analyzer came to my rescue. I figured out that by default, Subclipse had chosen a proxy that needed authentication (I am yet to find out how it found the proxy address in the first place!) and had not prompted me for authentication. Then, a search through Eclipse help led me to this link: &lt;a href="http://svnbook.red-bean.com/en/1.1/ch07.html#svn-ch-7-sect-1.2"&gt;http://svnbook.red-bean.com/en/1.1/ch07.html#svn-ch-7-sect-1.2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In short, I had to edit the registry to set my proxy - call that user friendly??? Well, since most of the time people who check out code are geeks, may be I should excuse this!!! Here is where I had to go:
&lt;code&gt;HKCU\Software\Tigris.org\Subersion\Servers\Global\http-proxy-host&lt;/code&gt; and &lt;code&gt;http-proxy-port&lt;/code&gt; values. Once I set up the proxy there, all worked well.&lt;/p&gt;
&lt;p&gt;Whew!!! Breathe easy now :)&lt;/p&gt;
</description></item><item><title>Testing the RAM for defects on Windows</title><link>https://www.saicharan.in/blog/2006/11/29/testing-the-ram-for-defects-on-windows</link><pubDate>Wed, 29 Nov 2006 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/29/testing-the-ram-for-defects-on-windows</guid><description>&lt;p&gt;Somebody had asked me to look at some problem being created by Ulead DVD Factory 10.0. The error reported was some failure to read a memory location. This message repeated for Nero also, after a few days.
I suspected faulty RAM, after seeing the log. The message was &lt;code&gt;EXCEPTION_ACCESS_VIOLATION&lt;/code&gt;. But, I did not know the right tools for testing the RAM. So, a Google Search led me to the following tools:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.memtest86.com/"&gt;MemTesthttp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft&amp;rsquo;s &lt;a href="http://oca.microsoft.com/en/windiag.asp"&gt;Windows Memory Diagnostic&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I did not test Memtest, but I used the Microsoft solution. It was easy to use, but the UI is not for the layman.&lt;/p&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Please keep a floppy disk handy. If you are one of those forward looking geeks, and do not have a floppy drive, you need to have a CD writer. Check out the details provided &lt;a href="http://oca.microsoft.com/en/windiag.asp#quick"&gt;here&lt;/a&gt; for working with a CD.&lt;/li&gt;
&lt;li&gt;After you run the program and have created a floppy, boot from the floppy.&lt;/li&gt;
&lt;li&gt;To run Advanced Diagnostic tests, hit the T button on your keyboard.&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Sorting Algorithms : A visual treatment</title><link>https://www.saicharan.in/blog/2006/11/20/sorting-algorithms-a-visual-treatment</link><pubDate>Mon, 20 Nov 2006 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/20/sorting-algorithms-a-visual-treatment</guid><description>&lt;p&gt;Check out this link at: &lt;a href="http://netlib.bell-labs.com/cm/cs/pearls/sortanim.html"&gt;http://netlib.bell-labs.com/cm/cs/pearls/sortanim.html&lt;/a&gt;.
It is from the &lt;a href="http://netlib.bell-labs.com/cm/cs/pearls/"&gt;Programming Pearls&lt;/a&gt; site. Gives some insight into the working of the algorithm. Check the behaviour of different algorithms on different inputs. However, it would be more helpful if we also have some control over the speed; this will help the visualization better!&lt;/p&gt;
&lt;p&gt;Let me see if I can fix that recipe (ofcourse, I will start with the &lt;a href="http://netlib.bell-labs.com/cm/cs/pearls/SortAnim.java"&gt;SortAnim.java&lt;/a&gt; provided at &lt;a href="http://netlib.bell-labs.com/cm/cs/pearls/"&gt;this site&lt;/a&gt;).&lt;/p&gt;
</description></item><item><title>Eclipse Update behind a proxy</title><link>https://www.saicharan.in/blog/2006/11/18/eclipse-update-behind-a-proxy</link><pubDate>Sat, 18 Nov 2006 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/18/eclipse-update-behind-a-proxy</guid><description>&lt;p&gt;Updating Eclipse from behind a proxy was quite counter-intuitive for me; or was it???&lt;/p&gt;
&lt;p&gt;I had expected to find the proxy setting in the same window where the updater hooks up to the internet. Unfortunately, with Eclipse, it was under &lt;code&gt;Window &amp;gt; Preferences &amp;gt; Install/Update &amp;gt; Use HTTP Proxy...&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But this option of not having to hunt around the eclipse site for the plug-ins is a real killer concept. Saves a lot of time too. One up to the &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; project.&lt;/p&gt;
</description></item><item><title>Installation of Sun Studio 10 on Sun Solaris Machine</title><link>https://www.saicharan.in/blog/2006/11/16/installation-of-sun-studio-10-on-sun-solaris-machine</link><pubDate>Thu, 16 Nov 2006 00:00:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/16/installation-of-sun-studio-10-on-sun-solaris-machine</guid><description>&lt;ol&gt;
&lt;li&gt;First uninstall the existing version by typing:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cd /var/sadm/prod/com.sun.studio_10&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run the batch uninstaller&lt;/li&gt;
&lt;li&gt;Further info on uninstalling can be found at: &lt;a href="http://docs.sun.com/source/819-0485/remove.html"&gt;http://docs.sun.com/source/819-0485/remove.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Next, put the Tar file in the directory in which you wish to install. Untar it. Keep the tar file in the same directory as the installer file.&lt;/li&gt;
&lt;li&gt;Run the installer and follow instructions.&lt;/li&gt;
&lt;/ol&gt;
</description></item><item><title>Adding a Favicon</title><link>https://www.saicharan.in/blog/2006/11/15/adding-a-favicon</link><pubDate>Wed, 15 Nov 2006 05:31:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/adding-a-favicon</guid><description>Check out this Wiki article: &lt;a href="http://en.wikipedia.org/wiki/Favicon"&gt;http://en.wikipedia.org/wiki/Favicon&lt;/a&gt;.</description></item><item><title>C Tidbit</title><link>https://www.saicharan.in/blog/2006/11/15/c-tidbit</link><pubDate>Wed, 15 Nov 2006 08:21:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/c-tidbit</guid><description>&lt;p&gt;The assignment operator returns something! In the case of a character, it returns the character that was assigned.&lt;/p&gt;
&lt;p&gt;So, it is useful to write code this way:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; while ((to[i] = from[i]) != &amp;#39;\0&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Changing the default command for RedHat8 Launch Panel</title><link>https://www.saicharan.in/blog/2006/11/15/changing-the-default-command-for-redhat8-launch-panel</link><pubDate>Wed, 15 Nov 2006 08:09:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/changing-the-default-command-for-redhat8-launch-panel</guid><description>&lt;p&gt;For accessing the Windows Network using Samba, only Nautilus seemed to be understanding the &lt;code&gt;smb://&lt;/code&gt; protocol. I did not want to each time start a terminal and type nautilus to start Nautilus. So, I wanted to add a launch panel icon. I could not find a way to add and configure a new icon. So I dragged the Help icon from the Main Menu and modified its Properties to run the command &lt;code&gt;/usr/bin/nautilus&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But this by default opened my home directory. I wanted it to open &lt;code&gt;smb://hostname&lt;/code&gt;. I had experimented earlier at the terminal and found that nautilus took as its command line arguements the location to be opened. So, I changed the command to &lt;code&gt;/usr/bin/nautilus smb://hostname&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This worked well for me. But, I wanted some more sophistication. I wanted to log in directly since &lt;code&gt;smb://&lt;/code&gt; (like &lt;code&gt;ftp://&lt;/code&gt;), takes the username and password separated by a colon followed by @ and the hostname. So, I changed the command to &lt;code&gt;/usr/bin/nautilus smb://user name:password@hostname&lt;/code&gt;. Nuts, commandline did not parse the space separated user name (which Windows allows). So, as an additional change, using my instincts from my working with Linux, I enclosed the &lt;code&gt;user name&lt;/code&gt; within single quotes. This worked well. Similar strategy is also required to be used with the password if it contains spaces. Remember that while typing the username and password in the address bar of Nautilus or at the Properties panel of the Launch Panel, the Password in NOT masked. So, it is at your risk that you do this.&lt;/p&gt;
&lt;p&gt;So, all said and done, here is how the command looked at the end of the experimental session:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/usr/bin/nautilus smb://&amp;#39;user name&amp;#39;:&amp;#39;password&amp;#39;@hostname
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Excellent, free iCal Calendars</title><link>https://www.saicharan.in/blog/2006/11/15/excellent-free-ical-calendars</link><pubDate>Wed, 15 Nov 2006 08:20:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/excellent-free-ical-calendars</guid><description>&lt;p&gt;This is a log of my adventures with iCal Calendar clients and format.&lt;/p&gt;
&lt;p&gt;I tried Outlook Calendar &amp;amp; Google Calendar. Both were good. But, when I tried Google Calendar, it was in the offing and so I could not get much out of it. It was good but was accessible only when on the net.&lt;/p&gt;
&lt;p&gt;So, I hit upon &lt;a href="http://www.ipi.fi/%7Erainy/index.php?pn=projects&amp;amp;project=rainlendar"&gt;Rainlander&lt;/a&gt;. It was good, it integrated with Outlook and also understood the iCal format. But, I wanted to fill out just one calendar and use it on any client - both application and web-based. So, I filled out the Google Calendar (whew, that took really long!). Then, I realized that I could not actually use it anywhere else at that stage of development of Google Calendar.&lt;/p&gt;
&lt;p&gt;So, I again filled out the Outlook calendar (because I had read this time that I can use the &lt;a href="http://outlook2ical.sourceforge.net"&gt;outlook2ical&lt;/a&gt; utility, which is free!!!). Bingo, I used the &lt;code&gt;outlook2ical&lt;/code&gt; utility and could export my Outlook calendar to the iCal format which is widely supported.&lt;/p&gt;
&lt;p&gt;Next, I experimented with &lt;a href="http://phpicalendar.com"&gt;phpicalendar&lt;/a&gt; using the .ics file that I exported with outlook2ical utility. It is cool and easy to use (as long as I had XAMPP with me, I had nothing to worry!).&lt;/p&gt;
</description></item><item><title>FTP Server on Windows 2003 Server R2</title><link>https://www.saicharan.in/blog/2006/11/15/ftp-server-on-windows-2003-server-r2</link><pubDate>Wed, 15 Nov 2006 05:30:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/ftp-server-on-windows-2003-server-r2</guid><description>&lt;p&gt;We had set up IIS on Windows 2003 server. Along with HTTP, we also had to set up FTP server to allow our staff members to be able to upload info to their respective folders.&lt;/p&gt;
&lt;p&gt;The initial set up worked, but it was readonly, inspite of the folder permission being write. Then, I checked out that if I logged in as admin, I could create folders! So, I went to check out the folder permissions for the admin account. It was exactly as I had configured the staff account (FULL CONTROL), except that the permission were only for the current folder. For the staff account permissions, I had chosen to give full control to &lt;code&gt;This folder, and subfolders and files&lt;/code&gt; (as intuition and common sense would have served anyone). But, I must confess that I donot fully understand the NTFS permissions structure. So, I changed the staff permissions to this folder only and bingo! it worked.&lt;/p&gt;
</description></item><item><title>Linux : Mounting a USB device - made simpler</title><link>https://www.saicharan.in/blog/2006/11/15/linux-mounting-a-usb-device-made-simpler</link><pubDate>Wed, 15 Nov 2006 08:09:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/linux-mounting-a-usb-device-made-simpler</guid><description>&lt;ol&gt;
&lt;li&gt;At the terminal, log in as root.&lt;/li&gt;
&lt;li&gt;Open the &lt;code&gt;/etc/fstab&lt;/code&gt; file for editing.&lt;/li&gt;
&lt;li&gt;Append the following entry to the file: &lt;code&gt;/dev/sda1 /mnt/usb autofs 0 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Naviagte to &lt;code&gt;Start &amp;gt; System Tools &amp;gt; Disk Management&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select the device to be mounted and mount.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;NOTES:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;/dev/sda1&lt;/code&gt; is the name of the device whose file system you want to mount at &lt;code&gt;/mnt/usb&lt;/code&gt; (this too is your choice!)&lt;/li&gt;
&lt;li&gt;autofs tells the mount command that the filesystem type should (attempted to) be detected automatically. If you want, you can explicitly specify a file system.&lt;/li&gt;
&lt;li&gt;In the options, DONOT specify the kudzu option. The kudzu option will cause &lt;code&gt;/etc/fstab&lt;/code&gt; to be updated when the usb device is unmounted or unplugged. Thus, the entry will vanish after this. For more information regarding kudzu, use man kudzu at the terminal.&lt;/li&gt;
&lt;li&gt;In the options, please specify user and NOT owner. If you donot specify user, the DiskManagement will not show the USB device if this is launched by a non-root user (by default). The GUI for DiskManagement is actually a command called usermount that reads from &lt;code&gt;/etc/fstab&lt;/code&gt; and displays a list. Hence, if user is NOT specified, the device will not show up in the list. Further, the user option indicates that ANY user can mount this device!!!&lt;/li&gt;
&lt;li&gt;For convinience, the DiskManagement can be added to the launcher panel (&lt;code&gt;Start &amp;gt; System Tools&lt;/code&gt;. Right Click on &lt;code&gt;DiskManagement&lt;/code&gt; and click on Add to &lt;code&gt;Launcher Panel&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Matlab license manager error: Solaris 10</title><link>https://www.saicharan.in/blog/2006/11/15/matlab-license-manager-error-solaris-10</link><pubDate>Wed, 15 Nov 2006 05:15:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/matlab-license-manager-error-solaris-10</guid><description>&lt;p&gt;If the Sun Machine is not properly shut down when Matlab (license) server is running, you will be unable to start matlab after the reboot. You will get an &lt;code&gt;error -15&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To trouble shoot, I did the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I knew that lmstart command present int &lt;code&gt;$MATLAB/etc&lt;/code&gt; directory starts the matlab license manager.&lt;/li&gt;
&lt;li&gt;To start the license manager (i.e., to run the lmstart command), you need to be logged in as a non-root user.&lt;/li&gt;
&lt;li&gt;So, I tried to start the license manager.&lt;/li&gt;
&lt;li&gt;I got a message saying that I needed to delete some files: &lt;code&gt;/var/tmp/lm_*.log&lt;/code&gt; and &lt;code&gt;/var/tmp/lm_*.dat&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For this you need to log in as root.&lt;/li&gt;
&lt;li&gt;Once this is done, run &lt;code&gt;lmstart&lt;/code&gt; again.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Done!&lt;/p&gt;
</description></item><item><title>Minix - FTP &amp; Tlenet Access</title><link>https://www.saicharan.in/blog/2006/11/15/minix-ftp-tlenet-access</link><pubDate>Wed, 15 Nov 2006 05:32:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/minix-ftp-tlenet-access</guid><description>&lt;p&gt;I had a problem accessing my Minix VMWare guest OS, via FTP or Telnet. Here is how the problem was solved&amp;hellip;&lt;/p&gt;
&lt;p&gt;A little bit of history:
Yesterday, I had to set up a RedHat 9 Guest OS for one of my faculty members. I realized that even though telnet was installed and running, I was unable to access it even locally!!! Then I realized that I had to edit the &lt;code&gt;telnet&lt;/code&gt; file in &lt;code&gt;/etc/xinetd.d&lt;/code&gt; to allow incoming telnet connections (inspite of changes to the firewall configuration to allow incoming telnet connections).&lt;/p&gt;
&lt;p&gt;Back to the present:
So I realized that perhaps something similar needs to be done even with Minix (after all, it is a variant of Unix and must have similar security features!!!). But, when I went to the /etc folder in Minix, I found no xinetd.d folder. Looking around, I found the serv.access file. Guessing that it must be the right place to look, I opened it. Bingo!&lt;/p&gt;
&lt;p&gt;There it was. Only, I had to decipher how the entires should look like in that file. Ever so helpful, a comment asked me to man serv.access. Also, I looked at the&lt;code&gt;/usr/adm/log&lt;/code&gt; file. It was all there - all those access denied messages&amp;hellip;&lt;/p&gt;
&lt;p&gt;Initially, my &lt;code&gt;/etc/serv.access&lt;/code&gt; file was like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# /etc/serv.access
# 2006-05-21
# See the serv.access(5) man pages to learn how to edit this file
# to make your system safe on the network.
# this is insecure! replace with something more specific asap
telnet ftp: +* log;

&lt;h1 id="this-is-better-keep-outsiders-out"&gt; &lt;a class="anchor" href="#this-is-better-keep-outsiders-out"&gt;this is better, keep outsiders out &lt;/a&gt;&lt;/h1&gt;

&lt;h1 id="telnet-ftp-local-log"&gt; &lt;a class="anchor" href="#telnet-ftp-local-log"&gt;telnet ftp: +*.local log; &lt;/a&gt;&lt;/h1&gt;

&lt;h1 id="this-records-all-unsuccessful-access-attempts-inusradmlog"&gt; &lt;a class="anchor" href="#this-records-all-unsuccessful-access-attempts-inusradmlog"&gt;this records all unsuccessful access attempts in/usr/adm/log &lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;: -&lt;/em&gt; log;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After a reading the man page and a little tinkering, I changed the line “telnet ftp: +* log;” to “telnet ftp: + log;”. i.e., I just removed the *. May be very insecure, but it does the job for me. Perhaps one could add an IP address or a range of IPs to enhance security (as described in the man page).&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;One another word, this might be very helpful on the VMWare front: I am still using NAT. I had to just set the IP address of my Minix to be on the same subnet as VMNet8 (which is the default subnet on which VMWare does NAT-ing). Also, the default gateway on the guest OS - Minix - had to be set to VMNet8-subnet-.2` ( The .2 IP is the gateway across which VMWare does NAT).&lt;/p&gt;
&lt;p&gt;Thats it!!!. All works fine now&amp;hellip;&lt;/p&gt;
</description></item><item><title>Network Access across a router</title><link>https://www.saicharan.in/blog/2006/11/15/network-access-across-a-router</link><pubDate>Wed, 15 Nov 2006 05:22:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/network-access-across-a-router</guid><description>&lt;p&gt;This document recapitulates the tasks that were needed to be done by us to enable access between the online and offline systems in the lab at my hostel:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First set up a DNS (with a domain name say, &lt;code&gt;ssshcc.edu&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;Set up the forward and reverse lookup zones&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set up the DNS machine to act as the router also between the two segments.&lt;/li&gt;
&lt;li&gt;For each computer on the online and offline segments, change the primary DNS suffix of the computer to the DNS domain name ( as specified in step 1)
&lt;ul&gt;
&lt;li&gt;Right Click &lt;code&gt;My Computer &amp;gt; Properties&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Computer Name&lt;/li&gt;
&lt;li&gt;Change&lt;/li&gt;
&lt;li&gt;More&lt;/li&gt;
&lt;li&gt;Type in the new Primary DNS Suffix&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For each machine in the online and offline segements, make sure that the guest account is allowed network access.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Start &amp;gt; Control Panel &amp;gt; Local Security Policy &amp;gt; Local Policy &amp;gt; User Rights Assignment &amp;gt; Deny Logon over Network&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Remove the Users whom you wish to allow network access (if the name is in the list)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Make sure that the default gateways and Primary and Secondary DNServers are correctly entered in the Network Configuration.&lt;/li&gt;
&lt;li&gt;In the lab, i.e., in the SSSHCC, the online systems donot have guest login interactively, but we want the guest users from the offline segement to be able to access the online systems. For this, we enable the Guest user account on the Online systems, but prevent their Interactive Login as follows:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Start &amp;gt; Control Panel &amp;gt; Local Security Policy &amp;gt; Local Policy &amp;gt; User Rights Assignment &amp;gt; Deny Logon Locally&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add Guest user.
7)Here, you can choose the custom list and add the required IPs or choose then Any computer option as required.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;One last setting: The windows firewall by default allows only computers on the same segment to access each other. This needs to be changed:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It is like this: Port &lt;code&gt;445&lt;/code&gt; (which is what windows uses for file and printer sharing) by default accepts connections only from computers on the same subnet as itself. This behaviour can be changed as described in the document: &lt;a href="https://docs.google.com/view?docid=ajgs46pc346b_9dxvvjc"&gt;https://docs.google.com/view?docid=ajgs46pc346b_9dxvvjc&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can find Microsoft&amp;rsquo;s description of the solution (KB840634) at &lt;a href="http://support.microsoft.com/kb/840634"&gt;http://support.microsoft.com/kb/840634&lt;/a&gt;.&lt;/p&gt;
</description></item><item><title>Networking Lessons</title><link>https://www.saicharan.in/blog/2006/11/15/networking-lessons</link><pubDate>Wed, 15 Nov 2006 05:29:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/networking-lessons</guid><description>&lt;p&gt;Subnets, Non-routable IPS:
Learner&amp;rsquo;s Perspective - &lt;a href="http://www.easydesksoftware.com/news/news28.htm"&gt;http://www.easydesksoftware.com/news/news28.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Admin&amp;rsquo;s Perspective - &lt;a href="http://www.pku.edu.cn/academic/research/computer-center/tc/html/TC0000.html"&gt;http://www.pku.edu.cn/academic/research/computer-center/tc/html/TC0000.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Admin&amp;rsquo;s Perspective - &lt;a href="http://www.pku.edu.cn/academic/research/computer-center/tc/html/TC0305.html"&gt;http://www.pku.edu.cn/academic/research/computer-center/tc/html/TC0305.html&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Samba Server Setup</title><link>https://www.saicharan.in/blog/2006/11/15/samba-server-setup</link><pubDate>Wed, 15 Nov 2006 08:04:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/samba-server-setup</guid><description>&lt;p&gt;Check if the Samba server is installed: You can check this by going to &lt;code&gt;Main Menu &amp;gt; System Settings &amp;gt; Server Settings &amp;gt; Services&lt;/code&gt;. Then, look for a service named smb. If it is present, that means, the Samba server is installed. If it is not started, start it up.&lt;/p&gt;
&lt;p&gt;If you donot have the Samba server installed on your system, you should install it from the RedHat 9 CDs. The server along with the GUI to configure Samba are present on CDs 1, 2 &amp;amp; 3.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Insert CD1.&lt;/li&gt;
&lt;li&gt;Go to the CDROM and navigate to &lt;code&gt;RedHat &amp;gt; RPMS&lt;/code&gt;. Here, look for a file called &lt;code&gt;samba*.rpm&lt;/code&gt;. Install it.&lt;/li&gt;
&lt;li&gt;Insert CD2. Navigate to &lt;code&gt;RedHat &amp;gt; RPMS&lt;/code&gt;. Install a package called &lt;code&gt;redhat-config-samba*&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Insert CD3. Navigate to &lt;code&gt;RedHat &amp;gt; RPMS&lt;/code&gt;. Install a package &lt;code&gt;called samba-swat*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NOTE: &lt;strong&gt;SWAT&lt;/strong&gt; is a browser based configuration tool for Samba. It talks be default on port 901. So, to use this, httpd should be running on Linux and the firewall should not block this port.&lt;/p&gt;
&lt;p&gt;We will use the GUI rather than SWAT for configuration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to the command prompt and type: &lt;code&gt;/usr/bin/redhat-config-samba&lt;/code&gt; (it is in &lt;code&gt;/usr/bin&lt;/code&gt; folder).&lt;/li&gt;
&lt;li&gt;Login as root.&lt;/li&gt;
&lt;li&gt;You will get a screen similar to the one shown here.&lt;/li&gt;
&lt;li&gt;Go to &lt;code&gt;Preferences &amp;gt; Server Settings&lt;/code&gt;. The default settings are shown here. I had to keep the group to something different from what was the Workgroup on my Windows system. Give a nice description; this is what people from other systems will see as the title for the Server (eg. In Windows, in the My Network Places, Show Work Group Computer, this is what will be seen.)&lt;/li&gt;
&lt;li&gt;On the Security tab:
&lt;ul&gt;
&lt;li&gt;set the Authentication Mode to User.&lt;/li&gt;
&lt;li&gt;set the Encrypted Password to Yes.&lt;/li&gt;
&lt;li&gt;set Guest account to the user for whom you are setting up this share (I donot as yet know how to allow for anonymous shares&amp;hellip;).&lt;/li&gt;
&lt;li&gt;click OK.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Go to &lt;code&gt;Preferences &amp;gt; Samba&lt;/code&gt; Users.
&lt;ul&gt;
&lt;li&gt;click add.&lt;/li&gt;
&lt;li&gt;Select the Unix username for the user whom you want topermit to use the share. When he logs in, he will be takent to his homedirectory unless some other shared folder has been specified.&lt;/li&gt;
&lt;li&gt;If the user is logging in from Windows, provide his Windows username
(this simplifies authentication and hepls to map Windows users to Linux users, I think so, I am not sure about this part).&lt;/li&gt;
&lt;li&gt;Provide a password (preferrably different from his Linux login password).&lt;/li&gt;
&lt;li&gt;click OK.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click Add, and add a shared folder to allow access from outside the Linux machine.&lt;/li&gt;
&lt;li&gt;To access this share from Windows, Go to My Network Places &amp;gt; View Workgroup Computers &amp;gt; Microsoft Windows Networks. Go to the appropriate workgroup that you had specified earlier. Here you will find the Samba Server with the description you provided earlier. Open this Samba and there you go!!!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now someone please tell me how to access the Windows Shares from Linux. Any help would be appreciated. :)&lt;/p&gt;
&lt;p&gt;UPDATE: Okay, just discovered that File &amp;amp; Printer Sharing must be enabled on Windows for accessing the Shared Files! For this, please run the Network Setup Wizard with appropriate options!!!&lt;/p&gt;
</description></item><item><title>Using Minix on VMWare</title><link>https://www.saicharan.in/blog/2006/11/15/using-minix-on-vmware</link><pubDate>Wed, 15 Nov 2006 08:15:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/using-minix-on-vmware</guid><description>&lt;ul&gt;
&lt;li&gt;There is nothing special that you need to do incase you need to run Minix on VMWare. Infact, you can download the VMWare ready image of Minix from here. Only, this image is not allowing ftp access to VMWare. After much effort, I found an image file for Minix 2.0.4 which was consolidated. The website is so confusing. It does not specify clearly what needs to be downloaded and they have lots of things there too!!!&lt;/li&gt;
&lt;li&gt;To allow ping to work, just set up NAT as described &lt;a href="http://sricharan-log.blogspot.com/2006/11/vmware-internet-access-from-guest-vm.html"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read &lt;a href="http://groups-beta.google.com/group/comp.os.minix/browse_thread/thread/0d6ca6030eba125a"&gt;this post&lt;/a&gt; or &lt;a href="http://sricharan-log.blogspot.com/2006/11/minix-ftp-tlenet-access.html"&gt;this post&lt;/a&gt; to enable FTP and Telnet access to Minix.&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>VMWare : Do's &amp; Donts</title><link>https://www.saicharan.in/blog/2006/11/15/vmware-dos-donts</link><pubDate>Wed, 15 Nov 2006 08:12:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/vmware-dos-donts</guid><description>&lt;ul&gt;
&lt;li&gt;VMWare by default creates two Vitual Network Adapters: VMNet1 &amp;amp;&amp;amp; VMNet8.&lt;/li&gt;
&lt;li&gt;VMNet1 is useful for host-only connection.&lt;/li&gt;
&lt;li&gt;VMNet8 is for NAT access.&lt;/li&gt;
&lt;li&gt;Donot change the IP domains which are assigned by default. You could wreck the DHCP, DNS, &amp;amp; Routing domian that VMWare creates.&lt;/li&gt;
&lt;li&gt;To change these settings, please use: &lt;code&gt;Edit &amp;gt; Virtual Network Settings &amp;gt; NAT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;By default, the IP Address &lt;code&gt;.2&lt;/code&gt; with the VMNet8 segment, is the IP address of VMWare&amp;rsquo;s DNS &amp;amp;&amp;amp; router.&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>VMWare : Internet / FTP / Telnet Access to Linux Guest from Windows Host</title><link>https://www.saicharan.in/blog/2006/11/15/vmware-internet-ftp-telnet-access-to-linux-guest-from-windows-host</link><pubDate>Wed, 15 Nov 2006 05:36:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/vmware-internet-ftp-telnet-access-to-linux-guest-from-windows-host</guid><description>&lt;ol&gt;
&lt;li&gt;After installing VMWare workstation or VMWare Player, find out the IP Subnet of the VM Network Adapter named &lt;code&gt;VMNet8&lt;/code&gt;. This is the &lt;code&gt;VMAdapter&lt;/code&gt; that is used for NAT connectivity.&lt;/li&gt;
&lt;li&gt;Set up the Linux host&amp;rsquo;s IP address to be in the same IP Subnet as &lt;code&gt;VMNet8&lt;/code&gt;. Just make sure that you donot use the IP addresses &lt;code&gt;Subnet.1&lt;/code&gt; OR &lt;code&gt;Subnet.2&lt;/code&gt;. &lt;code&gt;Subnet.1&lt;/code&gt; is used by VMNet8 while subnet &lt;code&gt;.2&lt;/code&gt; is used as the IP of the NAT Gateway. (Refer to VMWorkstation documentation for more details).&lt;/li&gt;
&lt;li&gt;Set the default Gateway to subnet &lt;code&gt;.2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set up VMWare to use Ethernet in NAT mode.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Done!&lt;/p&gt;</description></item><item><title>VMWare : Internet access from Guest VM (RedHat 9)</title><link>https://www.saicharan.in/blog/2006/11/15/vmware-internet-access-from-guest-vm-redhat-9</link><pubDate>Wed, 15 Nov 2006 08:13:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/vmware-internet-access-from-guest-vm-redhat-9</guid><description>&lt;ul&gt;
&lt;li&gt;You donot need to create any internet sharing in windows etc. VMWare will take care of that for you.&lt;/li&gt;
&lt;li&gt;To set up internet access from the guest VM, set the VM to use NAT for ethernet.&lt;/li&gt;
&lt;li&gt;Set the IP address to the same segment as that of &lt;code&gt;VMNet8&lt;/code&gt;. (just make sure that it is not &lt;code&gt;.2&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now you can access the Internet from the Guest VM!&lt;/p&gt;</description></item><item><title>VMWare : Sharing Files by Connecting to Windows from Linux</title><link>https://www.saicharan.in/blog/2006/11/15/vmware-sharing-files-by-connecting-to-windows-from-linux</link><pubDate>Wed, 15 Nov 2006 05:34:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/vmware-sharing-files-by-connecting-to-windows-from-linux</guid><description>Check out this link from VMWare Documentation: &lt;a href="http://www.vmware.com/support/gsx3/doc/running_fileshare_lin2win_gsx.html#1089626"&gt;&lt;a href="http://www.vmware.com/support/gsx3/doc/running_fileshare_lin2win_gsx.html#1089626"&gt;http://www.vmware.com/support/gsx3/doc/running_fileshare_lin2win_gsx.html#1089626&lt;/a&gt;&lt;/a&gt;</description></item><item><title>VMWare : SSH access to RH9 from Windows using PuTTY</title><link>https://www.saicharan.in/blog/2006/11/15/vmware-ssh-access-to-rh9-from-windows-using-putty</link><pubDate>Wed, 15 Nov 2006 08:13:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/vmware-ssh-access-to-rh9-from-windows-using-putty</guid><description>&lt;p&gt;Refer to my &lt;a href="http://sricharan-log.blogspot.com/2006/11/vmware-internet-access-from-guest-vm.html"&gt;previous post&lt;/a&gt; regarding setting up Internet access via RH9 Guest OS. Make sure you have similar settings. Then, just change the firewall settings to allow incoming SSH connections.&lt;/p&gt;
&lt;p&gt;Nothing else needs to be done.&lt;/p&gt;
</description></item><item><title>Windows : Autorun is Disabled?</title><link>https://www.saicharan.in/blog/2006/11/15/windows-autorun-is-disabled</link><pubDate>Wed, 15 Nov 2006 08:11:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/windows-autorun-is-disabled</guid><description>&lt;p&gt;Here is a solution for the Geeks; it modifies the Windows registry:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start RegEdit (&lt;code&gt;regedt32.exe&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Go to &lt;code&gt;HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/Cdrom&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Edit the Autorun value to &amp;lsquo;&lt;code&gt;1&lt;/code&gt;&amp;rsquo; to enable autorun, and &amp;lsquo;&lt;code&gt;0&lt;/code&gt;&amp;rsquo; to disable autorun.&lt;/li&gt;
&lt;li&gt;Close RegEdit.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;NOTE: You may have to restart the system.&lt;/p&gt;
&lt;p&gt;A simpler solution (not guaranteed to work if autorun has been disabled in the registry, as in my case) is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Right-click on the drive.&lt;/li&gt;
&lt;li&gt;Choose properties.&lt;/li&gt;
&lt;li&gt;Choose Autoplay.&lt;/li&gt;
&lt;li&gt;Choose the action you want to take for various file types.&lt;/li&gt;
&lt;/ol&gt;
</description></item><item><title>Windows XP Pro: Network access: logon failure</title><link>https://www.saicharan.in/blog/2006/11/15/windows-xp-pro-network-access-logon-failure</link><pubDate>Wed, 15 Nov 2006 05:20:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/11/15/windows-xp-pro-network-access-logon-failure</guid><description>&lt;p&gt;Windows XP Pro: Network access: logon failure: the user has not been granted the requested logon type at this computer&lt;/p&gt;
&lt;p&gt;Solutions:&lt;/p&gt;
&lt;ol start="0"&gt;
&lt;li&gt;&lt;code&gt;Start &amp;gt; Control Panel &amp;gt; Administrative Tools &amp;gt; Local Security Policy &amp;gt; Local Policies &amp;gt; User Rights Assignment&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;Goto : Deny Access to this Computer from the Network&lt;/li&gt;
&lt;li&gt;Remove the user name to whom you wish give permission to access the computer over the network.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Just run the network setup wizard and turn on file and printer sharing. If that does not help, try the next two links.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.experts-exchange.com/Operating_Systems/Windows_Server_2003/Q_21072962.html?qid=21072962"&gt;http://www.experts-exchange.com/Operating_Systems/Windows_Server_2003/Q_21072962.html?qid=21072962&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.experts-exchange.com/Operating_Systems/Windows_Server_2003/Q_21072962.html"&gt;http://www.experts-exchange.com/Operating_Systems/Windows_Server_2003/Q_21072962.html&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description></item><item><title>The Best GDB tutorial....</title><link>https://www.saicharan.in/blog/2006/04/20/the-best-gdb-tutorial</link><pubDate>Thu, 20 Apr 2006 08:52:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/04/20/the-best-gdb-tutorial</guid><description>&lt;p&gt;Once again, GDB comes to my rescue. Preparing for some exam, I need to debug. I need some advanced debug commands. Man pages are too long and do not provide examples. So, where do I go? To where I always went for GDB. To Peter Jay Salzman&amp;rsquo;s web site &lt;a href="http://www.dirac.org/linux/gdb/"&gt;tutorial&lt;/a&gt; ofcourse!&lt;/p&gt;
&lt;p&gt;It seems to have been recently updated and it is great. Very technical and yet understandable too! - a rare combination. It is still under massive reconstruction as the web site puts it, but still great to go.&lt;/p&gt;
&lt;p&gt;You can find his homepage &lt;a href="http://www.dirac.org/p/"&gt;here&lt;/a&gt; and his usful linux notes &lt;a href="http://www.dirac.org/p/linux/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;He seems to use all those things that I am interested in (kind of one-stop for me!), except that I use Matlab while he prefers Mathematica. His LaTeX links are &lt;a href="http://www.dirac.org/tex/"&gt;here&lt;/a&gt;. And &lt;a href="http://www.dirac.org/hackers/"&gt;here&lt;/a&gt; is his list of hackers (both good and bad as he puts it.)&lt;/p&gt;
</description></item><item><title>Installing Mandrake Linux</title><link>https://www.saicharan.in/blog/2006/04/16/installing-mandrake-linux</link><pubDate>Sun, 16 Apr 2006 08:29:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/04/16/installing-mandrake-linux</guid><description>&lt;p&gt;The other day, my one of my friends had a problem installing Mandrake Linux. On first thougts, I thought I would get an image aided tutorial ready, but then, I checked out the all resourceful Google and found these. The second link is classic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://member.melbpc.org.au/~parsonsd/linux/Mandrake10_Install.html"&gt;http://member.melbpc.org.au/~parsonsd/linux/Mandrake10_Install.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mandrake.tips.4.free.fr/install100.html"&gt;http://www.mandrake.tips.4.free.fr/install100.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, happy Mandraking!&lt;/p&gt;
</description></item><item><title>Lookout - Outlook!!</title><link>https://www.saicharan.in/blog/2006/04/16/lookout-outlook</link><pubDate>Sun, 16 Apr 2006 08:03:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/04/16/lookout-outlook</guid><description>&lt;p&gt;Here is where I again had a hell lot of problems. I wanted to make a birthday calendar and export it in the standard iCal format to my Google Calendar etc, as iCal was hailed on the web as the defacto standard for calendars.&lt;/p&gt;
&lt;p&gt;I started with Sunbird 0.3a1. Thinking that I could export things in iCal format, I filled in all the birthdays I wanted to. And, then I found that all I had done was a waste. It only allowed me to export selected items as iCal. Thinking that maybe the default format for the calendar is iCal, I looked in my profile directory and bingo! nothing like *.ical, *.vsc or *.vcal. Then the Mozilla Foundation&amp;rsquo;s documentation told me that from this version of sunbird, the default file format was .sdb, some SQLite format. Gone waste was my effort.&lt;/p&gt;
&lt;p&gt;Lesson #1: Always look for the existance of the features you need in the s/w you choose.&lt;/p&gt;
&lt;p&gt;So, what do I do? Google it ofcourse!&lt;/p&gt;
&lt;p&gt;This is what Google yielded and had some good reviews too: &lt;a href="http://outlook2ical.sourceforge.net/"&gt;&lt;a href="http://outlook2ical.sourceforge.net/"&gt;http://outlook2ical.sourceforge.net/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It was some VB script. Things went cool till I exported the calendar and imported it into Sunbird. The recurring events which were supposed to recur every year once were recurring every day for a month! Give up?&lt;/p&gt;
&lt;p&gt;Lesson #2: Never trust feature description. Check out the features ur self.&lt;/p&gt;
&lt;p&gt;What next?&lt;/p&gt;
&lt;p&gt;I wanted to somehow get this b&amp;rsquo;day business running, so I filled out the calendar in Outlook (for the simple reason that it was faster to add in Outlook than in Sunbird, donno why). Then, I bumped into this: &lt;a href="http://www.rainlendar.com"&gt;http://www.rainlendar.com&lt;/a&gt;. A very cute utility that seamlessly integrates with Outlook (oh my God!), reads from and understands iCal files! Thought this was a jackpot. Installed the software and loved its interface and cool features. Under the config &amp;gt; Plugins, i checked the Outlook option and refreshed the rainlendar on my desktop, it began showing the bithdays on the CORRECT days and onMouseOver(), it displayed the subject and description in a pop-up!&lt;/p&gt;
&lt;p&gt;Cute piece of work.&lt;/p&gt;
&lt;p&gt;Next, I wanted to take this calendar of outlook to my workplace. How?&lt;/p&gt;
&lt;p&gt;I chose Calendar. Then I said File &amp;gt; Archive. I saved only the Calendar to an archive.pst (which was non-empty (~256 kb)). Then I closed Outlook and made another copy of this file.&lt;/p&gt;
&lt;p&gt;Next, on my Win XP with Outlook 2003, I found the archive of the current Outlook files here &lt;code&gt;C:\Documents and Settings\%USER_NAME%\Local Settings\Application Data\Microsoft\Outlook\Outlook.pst&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Just to see if I can import, I changed the name of the file from Outlook.pst to OldOutlook.pst. As expected, Outlook did not open saying it could not find the file Outlook.pst; but, it gave me file open dialog where I chose the archive.pst. Then agagin it gave some error and closed. The next time I opened Outlook, it opened, but there was nothing there. So, I decided to import the stuff. I chose &lt;code&gt;File &amp;gt; Import and Export &amp;gt; Import from another file or program &amp;gt; Personal Files Folder (.pst)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here I chose the backup file of the Outlook.pst that I had made earlier (did not want to take any chances with my calendar!). Then, I chose to import the calendar and hit the Finish button. Done!&lt;/p&gt;
&lt;p&gt;I opened my calendar on the left tab and yo! the birthdays were there!!!&lt;/p&gt;
&lt;p&gt;Okay, so much so far, but not good enough for me to export to iCal yet. Anyone ne ideas? Please lemme know.&lt;/p&gt;
</description></item><item><title>What the hell is that service?</title><link>https://www.saicharan.in/blog/2006/04/16/what-the-hell-is-that-service</link><pubDate>Sun, 16 Apr 2006 08:33:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/04/16/what-the-hell-is-that-service</guid><description>&lt;p&gt;Two days ago, my system became damn slow. Then, I started looking at the processes and services running. Then, I Googled them and found these amazing sites:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.liutilities.com"&gt;http://www.liutilities.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.processlibrary.com"&gt;http://www.processlibrary.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.auditmypc.com"&gt;http://www.auditmypc.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For my own quick reference, here is the list of the processes that were running on my machine; now, most of them are scrapped. BTW, my machine is now like a tuned string, waiting to be played with.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bonjour: Apple Computer&amp;rsquo;s&lt;/li&gt;
&lt;li&gt;vptray : Symatec AV VirusProtectionTray&lt;/li&gt;
&lt;li&gt;qttask : QuickTime Task&lt;/li&gt;
&lt;li&gt;cftmon :The cftmon.exe process is a component used in MsOffice to perform language related functions. It is closely tied to the &amp;lsquo;Language Bar&amp;rsquo; present in MsOffice, so if you use the Language Bar you should leave this process running. If, on the other hand, you do not use the language bar, you should terminate this process to free up system resources.&lt;/li&gt;
&lt;li&gt;igfxtray.exe is a process which allows you to access the Intel Graphics configuration and diagnostic application for the Intel 810 series graphics chipset. This program is a non-essential system process, and is installed for ease of use via the desktop tray.&lt;/li&gt;
&lt;li&gt;Intel hotcommand hkcmd.exe is installed alongside Intel multimedia devices and allows configuration and diagnostic options for these devices. This program is non-essential process to the running of the system, but should not be terminated unless suspected to be causing problems.&lt;/li&gt;
&lt;li&gt;vsmon.exe is a processs associated with the ZoneAlarm personal firewall. It is used to monitor Internet traffic and generate alerts depending on the security rules configured by the user.&lt;/li&gt;
&lt;li&gt;Adobelmsvc.exe is a process which belongs to Adobe Acrobat. This program is non-essential process to the running of the system, but should not be terminated unless suspected to be causing problems.&lt;/li&gt;
&lt;li&gt;mdnsresponder.exe is a process associated with &amp;ldquo;Bonjour for Windows&amp;rdquo; software. It is used by ITunes for music sharing. This is a non-essential process. Disabling or enabling this is down to user preference.&lt;/li&gt;
&lt;li&gt;mdm.exe is associated with Microsoft Windows process debugging system. It allows the user to debug Internet Explorer errors by using a script interface tool. This is a non-essential process. Disabling or enabling this is down to user preference. Note: is also a process which is registered as the Win32.Lydra.a information stealing Trojan. This Trojan allows attackers to access your computer, personal data and information. It is a registered security risk and should be removed immediately.&lt;/li&gt;
&lt;li&gt;AcroTray.exe is the Acrobat Assistant used when you print your documents to a PDF. While converting documents to a PDF this process should not be removed.&lt;/li&gt;
&lt;li&gt;Adobelm_Cleanup.0001 is a process which belongs to Adobe Acrobat. This program is non-essential process to the running of the system, but should not be terminated unless suspected to be causing problems.&lt;/li&gt;
&lt;li&gt;lsass.exe is a system process of the Microsoft Windows security mechanisms. It specifically deals with local security and login policies. This program is important for the stable and secure running of your computer and should not be terminated.&lt;/li&gt;
&lt;li&gt;Scrss.exe is a process which is registered as the HacDef-R Trojan. This Trojan allows attackers to access your computer, stealing passwords, Internet banking and personal data. It is a registered security risk and should be removed immediately.&lt;/li&gt;
&lt;li&gt;smss.exe is a process which is a part of the Microsoft Windows Operating System. It is called the Session Manager SubSystem and is responsible for handling sessions on your system. This program is important for the stable and secure running of your computer and should not be terminated.&lt;/li&gt;
&lt;li&gt;PSNGive.exe is a process associated with the lite version of Post-it Note from 3M.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="references"&gt; &lt;a class="anchor" href="#references"&gt;References &lt;/a&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.auditmypc.com"&gt;http://www.auditmypc.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.processlibrary.com"&gt;http://www.processlibrary.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.liutilities.com"&gt;http://www.liutilities.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><title>Firefox extension updated!</title><link>https://www.saicharan.in/blog/2006/04/12/firefox-extension-updated</link><pubDate>Wed, 12 Apr 2006 03:28:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/04/12/firefox-extension-updated</guid><description>&lt;p&gt;At last! The &lt;a href="http://sricharan-log.blogspot.com/2006/04/new-firefox-extension.html"&gt;SaveURI&lt;/a&gt; 0.1 for firefox is ready! Now I can breathe easy. It is available &lt;a href="http://scharan20.googlepages.com/SaveURI-0.1-fx.xpi"&gt;here&lt;/a&gt;. Try it and post your comments.&lt;/p&gt;
&lt;p&gt;As I said earlier, this extension is useful for &amp;ldquo;remembering&amp;rdquo; the URL of every page that you visited and saved. This is still in beta as it has only just been submitted to &lt;a href="https://addons.mozilla.org/developers/main.php"&gt;Mozilla Foundation&lt;/a&gt; for review.&lt;/p&gt;
&lt;p&gt;Cheers! Now I can do something else while I wait for the review. :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Update&lt;/em&gt;:&lt;/strong&gt; Yesterday, the Firefox 1.5.0.1 running on my system said I needed to upgrade, on saying go ahead, it checked my extensions for compatibility and said SaveURI is incompatible with 1.5.0.2! Anyway, later, I downloaded FF 1.5.0.2 from &lt;a href="http://getfirefox.com/"&gt;Get Firefox&lt;/a&gt; and installed it. Then, I installed the SaveURI extension and it works just right!
Any ideas? &lt;a href="mailto:me-at-saicharan-dot-in"&gt;Buzz me&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Update:&lt;/em&gt;&lt;/strong&gt; This morning (20th April), SaveURI 0.3 was ready. Queued it up for approval at the MDC. Waiting for their approval. If you want to try it, it is available &lt;a href="http://scharan20.googlepages.com/SaveURI-0.3.0.1-fx.xpi"&gt;here&lt;/a&gt;. Try it and let me know.&lt;/p&gt;
</description></item><item><title>New Firefox Extension</title><link>https://www.saicharan.in/blog/2006/04/10/new-firefox-extension</link><pubDate>Mon, 10 Apr 2006 05:55:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/04/10/new-firefox-extension</guid><description>&lt;p&gt;Today, SaveURI, a firefox extension that I wrote is ready. It was a litte difficult to get things going, but it was fun.&lt;/p&gt;
&lt;p&gt;By the way, this extension simply saves the URI or URL of every page that you save so that you don&amp;rsquo;t have to search for the parent site link. This was a problem I had for long, especially when I was doing my master&amp;rsquo;s project. The links were just not available on any of the pages that I had saved. I needed them all for my report references. I am glad I could solve my own problems.&lt;/p&gt;
&lt;p&gt;You can download the extension &lt;a href="http://scharan20.googlepages.com/SaveURI.xpi"&gt;here&lt;/a&gt;. Just be careful if you are using the CustomizeGooogle extension as SaveURI is in the test phase and WILL clash with the latter extenssion.&lt;/p&gt;
</description></item><item><title>Post-it notes for the PC</title><link>https://www.saicharan.in/blog/2006/04/10/post-it-notes-for-the-pc</link><pubDate>Mon, 10 Apr 2006 09:42:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/04/10/post-it-notes-for-the-pc</guid><description>&lt;p&gt;That is one hell of a software for forgetfulls like me. You can cover your desktop with post-its and even set off an alarm on specific notes!. Terrific! You can download the lite version from &lt;a href="http://dw.com.com/redir?pid=10508740&amp;amp;merid=59813&amp;amp;amp;mfgid=59813&amp;amp;ltype=dl_dlnow&amp;amp;lop=link&amp;amp;edId=3&amp;amp;siteId=4&amp;amp;oId=3040-2351_4-10508740&amp;amp;ontId=2351_4&amp;amp;destUrl=http://www.download.com%2F3001-2351_4-10508740.html"&gt;here&lt;/a&gt;. You can try the newest version for 30 days from &lt;a href="http://www.3m.com/us/office/postit/digital/digital_notes.html"&gt;here&lt;/a&gt;. Beware! version 4.2 needs .Net framework 1.1. You can get that &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=262d25e3-f589-4842-8157-034d1e7cf3a3&amp;amp;displaylang=en"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The maker is father of paper-post-its &amp;ndash; &lt;a href="http://www.3m.com/"&gt;3M&lt;/a&gt;. Three cheers to 3M!&lt;/p&gt;
</description></item><item><title>Welcome!</title><link>https://www.saicharan.in/blog/2006/04/10/welcome</link><pubDate>Mon, 10 Apr 2006 05:52:00 +0000</pubDate><guid>https://www.saicharan.in/blog/2006/04/10/welcome</guid><description>&lt;p&gt;Welcome to my (b)log.&lt;/p&gt;
&lt;p&gt;Here, I will be recording my experiments with Computers &amp;amp; Computing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My experiments with Computers, Computing, Programming &amp;amp; Software.&lt;/p&gt;
&lt;/blockquote&gt;
</description></item></channel></rss>