<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en" xml:base="http://tech.waltco.biz/wp-atom.php">
	<title type="text">WaltCo Tech</title>
	<subtitle type="text">Writing things down so I can remember them later</subtitle>

	<updated>2008-03-03T01:04:34Z</updated>
	<generator uri="http://wordpress.org/" version="2.3.2">WordPress</generator>

	<link rel="alternate" type="text/html" href="http://tech.waltco.biz" />
	<id>http://tech.waltco.biz/feed/atom/</id>
	

			<link rel="self" href="http://feeds.feedburner.com/waltcotech" type="application/atom+xml" /><entry>
		<author>
			<name>Walter Wilfinger</name>
						<uri>http://tech.waltco.biz/</uri>
					</author>
		<title type="html"><![CDATA[Working on the Edge can be frustrating and amazing at the same time]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/waltcotech/~3/240507835/" />
		<id>http://tech.waltco.biz/2008/02/24/working-on-the-edge-can-be-frustrating-and-amazing-at-the-same-time/</id>
		<updated>2008-02-24T20:31:14Z</updated>
		<published>2008-02-24T20:30:21Z</published>
		<category scheme="http://tech.waltco.biz" term="Haml" /><category scheme="http://tech.waltco.biz" term="Merb" />		<summary type="html"><![CDATA[I&#8217;m messing around with the edge of the Merb 0.9 developer release and Haml.  I have very little experience in Haml and I&#8217;ve never used Merb before, so it&#8217;s probably a bad idea to start off with a developer release but hey whatever.  I could not get the form_tag function from merb_helpers to [...]]]></summary>
		<content type="html" xml:base="http://tech.waltco.biz/2008/02/24/working-on-the-edge-can-be-frustrating-and-amazing-at-the-same-time/"><![CDATA[<p>I&#8217;m messing around with the edge of the Merb 0.9 developer release and Haml.  I have very little experience in Haml and I&#8217;ve never used Merb before, so it&#8217;s probably a bad idea to start off with a developer release but hey whatever.  I could not get the <code>form_tag</code> function from <code>merb_helpers</code> to work.  This&#8230;</p>
<pre><code class="ruby">%p
  This will be the most basic DNS lookup ever

- form_tag(:action => url(:controller => :dns, :action => :index)) do
  = text_control "target", :label => "Domain/IP"</code></pre>
<p>Gave me this&#8230;</p>
<pre><code class="plain">undefined local variable or method `_buf' for #<Dns:0xb6e0e9d8> - (NameError)</code></pre>
<p>I wasn&#8217;t sure if I was using Haml wrong, Merb wrong, or both.  Google indexed <a href="http://p.ramaze.net/copy/480">an error log of the exact same problem</a> and a few minutes later <a href="http://merb.lighthouseapp.com/projects/7588/tickets/53-_buf-_buffer-issue-when-using-haml">the bug entry which was entered just 45 minutes before I found it.</a></p>
<p>That&#8217;s just crazy cool.</p>
]]></content>
	<feedburner:origLink>http://tech.waltco.biz/2008/02/24/working-on-the-edge-can-be-frustrating-and-amazing-at-the-same-time/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Walter Wilfinger</name>
						<uri>http://tech.waltco.biz/</uri>
					</author>
		<title type="html"><![CDATA[Use SWIG to Build a Ruby Extension to Wrap a Windows DLL]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/waltcotech/~3/240134269/" />
		<id>http://tech.waltco.biz/2008/02/23/use-swig-to-build-a-ruby-extension-to-wrap-a-windows-dll/</id>
		<updated>2008-03-03T01:04:34Z</updated>
		<published>2008-02-24T00:00:37Z</published>
		<category scheme="http://tech.waltco.biz" term="AutoIt" /><category scheme="http://tech.waltco.biz" term="ruby" />		<summary type="html"><![CDATA[I had a need to do some automation in Windows.  AutoIt is an excellent tool for the job.  It comes with its own scripting language and, more importantly, a well documented DLL interface called AutoItX.  Why settle for learning a new, limited-scope, scripting language when you can build a Ruby Extension to wrap the API?  On top of getting all of AutoIt's automation functions, I get everything that comes with Ruby:  Modules, classes, functions, mix-ins, inheritance, and access to hundreds of pre-written libraries.

I'm going to be using SWIG to semi-automatically build the C extension code that will wrap the AutoItX DLL.  SWIG can take a chunk of C/C++ code and generate the C/C++ code necessary to build support in Ruby.  It has support for several other dynamic languages as well and it is actually rather useful.]]></summary>
		<content type="html" xml:base="http://tech.waltco.biz/2008/02/23/use-swig-to-build-a-ruby-extension-to-wrap-a-windows-dll/"><![CDATA[<p>I had a need to do some automation in Windows.  <a href="http://www.autoitscript.com/autoit3/">AutoIt</a> is an excellent tool for the job.  It comes with its own scripting language and, more importantly, a well documented DLL interface called AutoItX.  Why settle for learning a new, limited-scope, scripting language when you can build a Ruby Extension to wrap the API?  On top of getting all of AutoIt&#8217;s automation functions, I get everything that comes with Ruby:  Modules, classes, functions, mix-ins, inheritance, and access to hundreds of pre-written libraries.</p>
<p>I&#8217;m going to be using <a href="http://www.swig.org/">SWIG</a> to semi-automatically build the C extension code that will wrap the AutoItX DLL.  SWIG can take a chunk of C/C++ code and generate the C/C++ code necessary to build support in Ruby.  It has support for several other dynamic languages as well and it is actually rather useful.</p>
<h2>Pre-requisites</h2>
<p>Remember that this is going to be built on Windows.  We&#8217;re going to run into some snags because of this.  Setting up the build environment is actually going to take more time than writing the extension with SWIG.  Download and install the following&#8230;</p>
<ul>
<li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=200B2FD9-AE1A-4A14-984D-389C36F85647&#038;displaylang=en">The Visual Studio 8.0 Runtimes</a> If you don&#8217;t already have them installed</li>
<li><a href="http://www.microsoft.com/downloads/details.aspx?familyid=E6E1C3DF-A74F-4207-8586-711EBE331CDC&#038;displaylang=en">Microsoft Platform SDK (Windows Server 2008)</a></li>
<li><a href="https://rubyforge.org/frs/?group_id=167">The Ruby One-click Installer for Windows</a></li>
<li><a href="http://www.autoitscript.com/autoit3/">AutoIt3</a></li>
<li><a href="http://www.swig.org/download.html">SWIG for Windows (swigwin)</a> Search the page for &#8220;Windows users&#8221;.  The link is kind of hard to see at first.</li>
</ul>
<p>SWIG&#8217;s Windows installer isn&#8217;t really an installer at all.  I extracted it into <code>C:\Program Files\SWIG</code>.  I and then added that to my PATH in my <code>Makefile</code>, which we&#8217;ll do shortly.</p>
<h2>Set up the project directory</h2>
<p>In my project directory at <code>My Documents\Projects\Autoit</code> I have the following.</p>
<pre><code class="shell">AutoIt.h # Copy from C:\Program Files\AutoIt3\AutoItX\StandardDLL\VC6
AutoItX3.lib # Copy from C:\Program Files\AutoIt3\AutoItX\StandardDLL\VC6
AutoItX3.dll # Copy from C:\Program Files\AutoIt3\AutoItX
# We will make the following three files
autoit.i # SWIG configuration file
extconf.rb # Ruby file to create our Makefile
Makefile # Will be generated by extconf.rb
</code></pre>
<h2>Modify Ruby&#8217;s config.h</h2>
<p>The one-click install of ruby is compiled with Visual Studio 6.0 which I would be surprised if you were using (<a href="http://en.wikipedia.org/wiki/Visual_studio#Visual_Studio_6.0">it was released 10 years ago</a>).  I do not know why the One-click Windows Rubyists decided to go with Visual Studio 6.0 and I really don&#8217;t care.  <a href="http://www.ruby-forum.com/topic/128864">I&#8217;ve seen pretty dumb compatibility arguments from Rubyists before</a> and I don&#8217;t feel like reading through another one.</p>
<p>This won&#8217;t hurt us until we try to compile our extension, but let&#8217;s take care of it now.  Open up <code>C:\ruby\lib\ruby\1.8\i386-mswin32\config.h</code>.  Right at the top you see this.</p>
<pre><code class="c">#if _MSC_VER != 1200
#error MSC version unmatch
#endif</code></pre>
<p>This says, &#8220;If you&#8217;re not using VC 6.0 bail.&#8221;  Why?  I don&#8217;t know.  Comment it out.</p>
<p>Many thanks to anelson and his blog <a href="http://apocryph.org/totally_bullshit_ruby_extension_experience_windows">The Totally Bullshit Ruby Extension Experience on Windows</a>.  He helped me with the <code>config.h</code> problem and the writing of much of this guide.</p>
<h2>Create the SWIG configuration file</h2>
<p>You can check the <a href="http://www.swig.org/Doc1.3/Sections.html#Sections">SWIG documentation</a> for more details, but the syntax is rather easy.  Put this in a file called <code>autoit.i</code> in your project directory.</p>
<pre><code class="plain">%module autoit
%include typemaps.i

%inline %{
#include "AutoIt3.h"
%}

#define WINAPI // Only needed for AutoIt3.h

long WINAPI AU3_Run(const char *INPUT, const char *INPUT, long nShowFlags);

%include "AutoIt3.h"
</code></pre>
<p>Here&#8217;s a quick run down of the SWIG source.</p>
<p><code>%module% autoit</code> defines the name of the resultant module.  This means that eventually we will include our module with a call of <code>require 'autoit'</code>.</p>
<p><code>%include typemaps.i</code> is required for the INPUT macros you see below in the AU3_Run line.  In C-style programs you will often see pointers used for function input and output.  The <code>typemaps.i</code> macros will take care of making this work in Ruby for you.  In very simple terms, you will want to do the following.</p>
<ul>
<li>If you see a pointer used for function input, change the function prototype to use <code>INPUT</code></li>
<li>If you see a pointer used for function output, change the function prototype to use <code>OUTPUT</code></li>
<li>If you see a pointer used for function input <strong>and</strong> output, change the function prototype to use <code>INOUT</code></li>
</ul>
<p>You can read more about these macros in the <a href="http://www.swig.org/Doc1.3/Ruby.html#Ruby_nn32">SWIG documentation for Ruby.</a></p>
<p>The <code>%inline</code> block of code will insert everything between %{ and %} verbatim into the resultant extension code.  Here, we&#8217;re making sure that the extension code includes <code>AutoIt3.h</code>.</p>
<p><code>#define WINAPI</code> was included because there are WINAPI macros all over the <code>AutoIt3.h</code> file.  This lets us <code>%include "AutoIt3.h"</code> later without modifying it.</p>
<p>The <code>AU3_Run</code> line is an example of how to use the <code>INPUT</code> SWIG macro.  The first two parameters are input pointers, so I have changed the name of the variable to be <code>INPUT</code>.</p>
<p>Finally, <code>%include "AutoIt3.h"</code> copies the contents of <code>AutoIt3.h</code> into our SWIG file verbatim, much like how <code>#include</code> works in C.  This saves us from having to manually type out all the function prototypes in <code>AutoIt3.h</code>.</p>
<p>Run SWIG part of our build by running this in the Platform SDK command prompt that we modified previously.</p>
<pre><code class="plain">swig -c++ -ruby autoit.i</code></pre>
<p>This should not report any errors and create a file called <code>autoit_wrap.cxx</code> in your project directory.  <strong>You must do this before you create and run the Makefile we generate below.</strong>  If you don&#8217;t have any C/C++ files in your project when you generate the Makefile, your project will be very boring and very empty.</p>
<h2>Set up mkmf configuration file</h2>
<p>Create a file called <code>extconf.rb</code> in your project directory and put in the following.  I got this code from <a href="http://www.rubyinside.com/how-to-create-a-ruby-extension-in-c-in-under-5-minutes-100.html">Peter Cooper&#8217;s guide to creating a Ruby C Extension</a> and then modified it.</p>
<p><code>extconf.rb</code> will create a file <code>Makefile</code> in the project directory.  You <em>should</em> be able to just run <code>nmake</code> from here to build the Ruby extension, but because we&#8217;re working in Windows and not *nix we have to take some extra steps.  Again, you can read all about Ruby&#8217;s problems with building extensions in Windows in the blog post <a href="http://apocryph.org/totally_bullshit_ruby_extension_experience_windows">The Totally Bullshit Ruby Extension Experience on Windows</a>.  Basically, the Makefile generated by mkmf does NOT work on Windows.  The <a href="http://www.ruby-doc.org/stdlib/libdoc/mkmf/rdoc/index.html">documentation for mkmf</a> isn&#8217;t very helpful either.  For Windows, we need to add a .manifest file into the final <code>autoit.so</code> output.  For my project, we need to add the SWIG program directory to our build path, add a dependency line for <code>autoit_wrap.cxx</code>, and add AutoItX3.lib as library dependency.</p>
<p>I found that the best way to embed the .manifest file is to edit the <code>mkmf</code> source code.  You can modify the <code>Makefile</code> that is generated, but if you change the source code you&#8217;ll never have to worry about it again.  If you used the Ruby One-click installer, <code>mkmf.rb</code> can be found at <code>C:\ruby\lib\ruby\1.8\mkmf.rb</code>.</p>
<pre><code class="ruby"># Line 1324
  mfile.print "$(RUBYARCHDIR)/" if $extout
  mfile.print "$(DLLIB): ", (makedef ? "$(DEFFILE) " : ""), "$(OBJS)\n"
  mfile.print "\t@-$(RM) $@\n"
  mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
  # link_so = LINK_SO.gsub(/^/, "\t")
  # mfile.print link_so, "\n\n"
  # Add the lines below
  link_so = LINK_SO.gsub(/^/, "\t")
  mfile.print link_so, "\n"
  mfile.print "\tmt.exe -manifest $(DLLIB).manifest -outputresource:$(DLLIB);2\n" if $mswin
  mfile.print "\n\n"</code</pre>
<p>This will add <code>mt.exe -manifest $(DLLIB).manifest -outputresource:$(DLLIB);2</code> to the Makefile dependency for our output .so file if we&#8217;re building for Windows.</p>
<p>Below is the code for <code>extconf.rb</code>.</p>
<pre><code class="ruby"># Loads mkmf which is used to make makefiles for Ruby extensions
require 'mkmf'

# Give it a name
extension_name = 'autoit'

# The destination
dir_config(extension_name)

# Add autoitx.lib
$libs = append_library($libs,"AutoItX3")

# Do the work
create_makefile(extension_name)

# For SWIG
File.open("Makefile", "a") do |mf|
  mf.puts "PATH=$(PATH);C:\\Program Files\\SWIG"
  mf.puts "\n\n"
  mf.puts "autoit_wrap.cxx: autoit.i\n"
  mf.puts "\tswig -c++ -ruby autoit.i\n"
end</code></pre>
<p>The lines I modified are just for my project.  Explanations follow.</p>
<p>The line <code class="ruby">$libs = append_library($libs,"AutoItX3")</code> is something I gleaned off of the <a href="http://www.swig.org/Doc1.3/Ruby.html#Ruby_nn8">SWIG Ruby documentation</a>.  This tells the Makefile to compile <code>AutoItX3.lib</code> into our project.</p>
<p>The last chunk of code after <code class="ruby"># For SWIG</code> both adds the SWIG directory to the build PATH and adds a dependency for <code>autoit_wrap.cxx</code>.  This way if I modify <code>autoit.i</code> the file <code>autoit_wrap.cxx</code> will automatically be regenerated by <code>nmake</code>.</p>
<h2>Generate Makefile using mkmf</h2>
<p>Run the command line shortcut for Windows XP 32-bit that was installed into the Start menu by the Platform SDK.  This is in <code>Microsoft Windows SDK 6.1 -&gt; CMD Shell</code>.  Run the following to generate the Makefile.</p>
<pre><code class="ruby">ruby extconf.rb
</code></pre>
<h2>Build the extension library</h2>
<p>Now in the Platform SDK command prompt run this.</p>
<pre><code class="plain">nmake</code></pre>
<p>If you crossed your fingers hard enough you will end up with a <code>autoit.so</code> file in your project directory.  You <strong>WILL</strong> get errors from the compiler about depreciated and unknown options.  Blame this on mkmf, but the build should still work.</p>
<h2>Install the library</h2>
<p>Cross your fingers again and run this from the command prompt.</p>
<pre><code class="plain">nmake install</code></pre>
<p>This copies <code>autoit.so</code> to Ruby&#8217;s Windows library path.  With the one click install defaults that would be <code>c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt/autoit.so</code></p>
<h2>Copy AutoitX3.dll into a system path</h2>
<p>Because our Ruby library depends on AutoItX3.dll, Windows needs to be able to find AutoItX3.dll.  It can either be somewhere in your PATH or in the current directory of your Ruby script.  I didn&#8217;t really care about dirtying up my system, so I copied it into <code>C:\windows\system32</code> and forgot about it.</p>
<h2>Test the extension with irb</h2>
<pre><code class="plain">C:\>irb
irb(main):001:0> require 'autoit'
=> true
irb(main):002:0> Autoit.AU3_Run "notepad.exe", "", 1
=> 912
irb(main):003:0></code></pre>
<p>This should open up Notepad.  Magic!</p>
<h2>Troubleshooting</h2>
<p>If Windows cannot find AutoItX3.dll, Ruby will error out with the following uninformative error.</p>
<pre><code class="shell">c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt/autoit.so: 126: The specified module could not be found.   - c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt/autoit.so (LoadError)
    from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
    from MyTest/autoit.rb:1</code></pre>
<p>Make sure AutoItX3.dll is in a system path or in the current directory.</p>
<p>If the manifest was not correctly embedded you will get errors about not being able to find MSVC80.dll when we finally run our extension.  Ruby itself will error out with a <code>LoadError</code> exception.  If you run the script from a command prompt, Windows will popup complaining about missing MSVC80.dll.  This happens <em>even if</em> you do have the MFC 8.0 run times installed.</p>
<p>If running <code>nmake</code> ends without compiling anything, you more than likely generated the Makefile before any source files were in your project directory.  Run <code>swig -c++ -ruby autoit.i</code> to generate <code>autoit_wrap.cxx</code> and then run <code>nmake</code> again.</p>
<p><span style="text-decoration:strikethrough">Currently, I cannot get OUTPUT parameters to work.</span> <em>The solution to this lies in SWIG typemaps.  I&#8217;m going to write up another post about that.</em></p>
<h2>Wrap the wrapper (optional)</h2>
<p>You may not like the interface that the dll gives you.  You can of course write wrappers around the extension to make things easier on yourself.  For example.</p>
<pre><code class="ruby">module Autoit
  def Autoit.run(file,directory="",flag=1)
    Autoit.AU3_Run(file,directory,flag)
  end
end

# These two are now equivalent
Autoit.AU3_Run("notepad.exe", "", 1)
Autoit.run "notepad.exe"
</code></pre>
<p>A whole bunch of convenience functions and error handling can all be handled in Ruby itself.  You barely have to know any C/C++ to make working with the third party library <em>much</em> more convenient.  For example, the AutoIt API will set an error flag to 1 if a function fails.  You can retrieve the value of the error flag by calling <code>AU3_Error</code>.  I can write wrappers that will check this error code and throw a Ruby exception if it is set.  This saves me from having to manually check the error code every time.  Neato.</p>
<h2>Conclusion</h2>
<p>I hope this helps anyone that might be trying to wrap third party DLLs into a Ruby extension.  This is <strong>not</strong> a very simple process and there is a lot of work to be done just to get to the point of creating the Ruby module library.  You&#8217;ll have to deal with several things not being written with Windows in mind:  SWIG not having a real installer, mkmf not creating a very useful Makefile, and the manifest issue.  If you have any problems getting this to work, please leave a comment.  I&#8217;ll see if I can help and, in turn, hopefully make this guide better.</p>
]]></content>
	<feedburner:origLink>http://tech.waltco.biz/2008/02/23/use-swig-to-build-a-ruby-extension-to-wrap-a-windows-dll/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Walter Wilfinger</name>
						<uri>http://tech.waltco.biz/</uri>
					</author>
		<title type="html"><![CDATA[SSH slow to connect in Ubuntu 7.10 Gutsy Gibbon]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/waltcotech/~3/228040275/" />
		<id>http://tech.waltco.biz/2008/02/02/ssh-slow-to-connect-in-ubuntu-710-gutsy-gibbon/</id>
		<updated>2008-02-17T00:11:34Z</updated>
		<published>2008-02-02T22:15:36Z</published>
		<category scheme="http://tech.waltco.biz" term="Ubuntu Gutsy Gibbon" />		<summary type="html"><![CDATA[I have a laptop and desktop &#8220;server&#8221; on a local network both running Ubuntu 7.10.  Today, I decided to get an SSH server running on both of them.  To my dismay, it took SSH 15-20 seconds to prompt me for a password.  After the delay, I didn&#8217;t run into any further speed [...]]]></summary>
		<content type="html" xml:base="http://tech.waltco.biz/2008/02/02/ssh-slow-to-connect-in-ubuntu-710-gutsy-gibbon/"><![CDATA[<p>I have a laptop and desktop &#8220;server&#8221; on a local network both running Ubuntu 7.10.  Today, I decided to get an SSH server running on both of them.  To my dismay, it took SSH 15-20 seconds to prompt me for a password.  After the delay, I didn&#8217;t run into any further speed issues.  The problem ended up being with the way the server machine was looking up the reverse DNS of the client machine.</p>
<p>The OpenSSH server on the server attempts to look up the reverse DNS of the connecting machine.  In my case, as would be the case in most local networks I suspect, the client machine does not have a host name (i.e. reverse DNS) set up.  The quick solution is to edit <code>/etc/nsswitch.conf</code> <strong>on the server machine</strong>&#8230;</p>
<pre><code class="shell">...
# Change this line
# hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4
# To this (removed mdns4)
hosts:          files mdns4_minimal [NOTFOUND=return] dns
...
</code></pre>
<h2>Explanation</h2>
<p><code>nsswitch.conf</code> defines how dns host lookups are performed.  The system will try every method in turn until it finds one that succeeds or until it runs out of options.  All of the lookup options in the default configuration are lightning quick except for <code>mdns4</code>.  I&#8217;m not exactly sure what mdns4 is or in what situations I would absolutely need it enabled.  <a href="http://en.wikipedia.org/wiki/Zeroconf">Wikipedia</a> says it&#8217;s some sort of zero configuration network protocol that spawned from Apple.  Great.  I&#8217;m not using it, so I&#8217;m ok with removing it from the configuration.  If for whatever reason you are <em>not</em> OK with ditching it, I see two other options for you.</p>
<h3>Configure sshd to not do any rDNS lookups</h3>
<p>On the <strong>server</strong> machine, do the following</p>
<pre><code class="shell">sudo echo "UseDNS no" >> /etc/ssh/sshd_config
sudo /etc/init.d/ssh restart
</code></pre>
<p>The OpenSSH daemon will now not attempt any reverse DNS lookups when a client connects.  If you are using host names to authorize connections to the server, this is obviously not an option for you.</p>
<h3>Add your client machine&#8217;s ip to the hosts file on the server machine</h3>
<p>On the <strong>server</strong> machine, do the following</p>
<pre><code class="shell">sudo echo "[your_client_ip] [your_client_hostname]" >> /etc/hosts
</code></pre>
<p>This is, of course, dependent on your client machine having a static IP.  If the IP of the client changes, the server won&#8217;t have a host name to go on again, and you&#8217;ll be back to slow SSH connections.</p>
<h2>Debugging SSH</h2>
<p>To figure out the above I had to do a lot of sifting through debug logs.  For reference, here is how to set up verbose logging for SSH on both the client and server side.</p>
<h3>Server Side SSH Debug Logs</h3>
<h4>/etc/ssh/sshd_config</h4>
<pre><code class="shell"># Logging
SyslogFacility AUTH
LogLevel DEBUG3 # DEBUG3 is the most verbose, default is INFO
</code></pre>
<p>Then do <code>tail -f /var/log/auth.log</code></p>
<h3>Client Side SSH Debug</h3>
<p><code>ssh -vvv [normal connection string]</code> will output big logs on the client side.</p>
<h2>File Versions</h2>
<pre><code class="shell">$ ssh -V
OpenSSH_4.6p1 Debian-5build1, OpenSSL 0.9.8e 23 Feb 2007
</code></pre>
<pre><code class="shell">$ dpkg-query --search nsswitch.conf
manpages: /usr/share/man/man5/nsswitch.conf.5.gz
base-files: /usr/share/base-files/nsswitch.conf
$ dpkg-query --show base-files
base-files      4.0.0ubuntu5
</code></pre>
<pre><code class="shell">$ dpkg-query --search /usr/sbin/sshd
openssh-server: /usr/sbin/sshd
$ dpkg-query --show openssh-server
openssh-server  1:4.6p1-5ubuntu0.1
</code></pre>
<h2>Sources:</h2>
<p><a href="https://bugs.edge.launchpad.net/ubuntu/+source/openssh/+bug/84899">Ubuntu Bug report on slow SSH blaming it on GSSAPIAuthentication setting on client</a></p>
<p><a href="https://bugs.launchpad.net/ubuntu/+source/avahi/+bug/94940">Another Bug report about how mdns4 in nsswitch is really slow</a></p>
<p><a href="https://help.ubuntu.com/community/AdvancedOpenSSH">Ubuntu Wiki on SSH</a></p>
<p><a href="http://netbsd.gw.com/cgi-bin/man-cgi?nsswitch.conf+5+NetBSD-current">Format for nsswitch.conf</a></p>
]]></content>
	<feedburner:origLink>http://tech.waltco.biz/2008/02/02/ssh-slow-to-connect-in-ubuntu-710-gutsy-gibbon/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Walter Wilfinger</name>
						<uri>http://tech.waltco.biz/</uri>
					</author>
		<title type="html"><![CDATA[Private and guest (no password prompt) Samba shares with security=user]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/waltcotech/~3/223642408/" />
		<id>http://tech.waltco.biz/2008/01/26/private-and-guest-no-password-prompt-samba-shares-with-securityuser/</id>
		<updated>2008-02-02T21:28:42Z</updated>
		<published>2008-01-26T20:03:11Z</published>
		<category scheme="http://tech.waltco.biz" term="InstallationAndSetup" /><category scheme="http://tech.waltco.biz" term="Samba" /><category scheme="http://tech.waltco.biz" term="Ubuntu Gutsy Gibbon" />		<summary type="html"><![CDATA[I wanted to share out files from my Ubuntu Gutsy desktop "server" on to my home network.  I wanted two different shares: a public read/write share and a private read/write share.  Every guide I found explained only how to do one kind of share or the other.  Either you specified all shares to require a login -or- all shares to be public.  I needed both served out at the same time.  The key ended up being map to guest. ]]></summary>
		<content type="html" xml:base="http://tech.waltco.biz/2008/01/26/private-and-guest-no-password-prompt-samba-shares-with-securityuser/"><![CDATA[<p>I wanted to share out files from my Ubuntu Gutsy desktop &#8220;server&#8221; on to my home network.  I wanted two different shares: </p>
<p><strong>A private read/write share</strong><br />
Only I will have the credentials to access this share.  This will host out my more precious files.  I do not want my family either knowing about this share or accessing it and accidentally deleting everything I have.</p>
<p><strong>A public read/write share</strong><br />
This will be used as an anonymous dumping ground to transfer files to/from the server.  This will also be the share that my other family members will be using.  For ease of use, I do not want them to have to specify a user or password to connect.  There should be no password prompt.  It should act like a public Windows share.</li>
<p>Every guide I found explained only how to do one kind of share or the other.  Either you specified all shares to require a login -or- all shares to be public.  I needed both served out at the same time.  The key ended up being <code class="shell">map to guest</code>.  Here&#8217;s a stripped down version of my smb.conf, but if you want explanations, read on.</p>
<h1>Short Version</h1>
<h2>/etc/samba/smb.conf on server</h2>
<pre><code class="shell">[global]
        # Browsing / Identification #
        netbios name = fileserver
        server string = %h server (Samba, Ubuntu)

        # Authentication #
        security = user
        encrypt passwords = true
        map to guest = bad user
        guest account = nobody

        passdb backend = tdbsam
        obey pam restrictions = yes
        invalid users = root

# Public Share.  Mount this on a Unix client with the following.
# sudo mount -t smbfs -o username=[username],password=[password],\
# rw,uid=[your Unix user],gid=[your Unix group] \
# //[netbios or ip of server]/private /path/to/mount/point
#
# Optionally use a credentials file and credentials=/path/to/credentials (see below)

[private]
        comment = Private Share
        path = /mnt/private
        browseable = no
        read only = no
        create mask = 0640
        directory mask = 0750

# Public Share.  Mount this on a Unix client with the following.
# sudo mount -t smbfs -o username=,password=,\
# rw,uid=[your Unix user],gid=[your Unix group] \
# //[netbios or ip of server]/public /path/to/mount/point

[public]
        comment = Public Share
        path = /mnt/public
        read only = no
        create mask = 0640
        directory mask = 0750
        guest only = yes
        guest ok = yes
</code></pre>
<p>After this is saved.  Restart Samba with <code>sudo /etc/init.d/samba restart</code></p>
<h2>Set up samba user</h2>
<p>Here <code>smbprivate</code> is the user that will have access to the Private share.  Make sure that this user exists on the server and has appropriate permissions on the share directory.  Then let Samba know about this user by executing the following.</p>
<pre><code style="shell">$ sudo smbpasswd -a smbprivate
</code></pre>
<h2>Using a credentials file to mount in Unix</h2>
<p>You can create a credentials file so that your username and password aren&#8217;t sitting in plain text in /etc/fstab.  Create this file on your client Linux machine (I put it in /etc/samba/credentails.fileserver).</p>
<pre><code>username=[username]
password=[password]</code></pre>
<p>Give it only read access to root.</p>
<pre><code>$ sudo chown root:root /path/to/credentials
$ sudo chmod 400 /path/to/credentials</code></pre>
<p>Then the mount command becomes</p>
<pre><code>sudo mount -t smbfs -o credentials=/path/to/credentials,\
rw,uid=[your Unix user],gid=[your Unix group] \
//[netbios or ip of server]/private /path/to/mount/point</code></pre>
<h1>Long Version</h1>
<h2>The Private Share</h2>
<p>To set up private shares in Samba we need to do three things.</p>
<ul>
<li>Set <code>security = user</code>.  This tells Samba that we want to authenticate login attempts based on the Unix users on the server.</li>
<li>Set <code>encrypt passwords = yes</code>.  The newer versions of Windows require that share passwords be encrypted when transmitted over the network.  This is default in Samba 3.0.26a, but if you&#8217;re running an older version of Samba you may have to define this explicitly.</li>
<li>Use <code>smbpasswd</code> on the command line to create the encrypted password information for your private share user.</li>
</ul>
<p>The deal is that you&#8217;re going to <em>have</em> to use encrypted passwords unless all the Windows computers on your network are running Windows 95.  Samba can&#8217;t map directly to the Unix passwd file because Windows encrypts using a different algorithm.  This is why the smbpasswd exists.  It will store the passwords you supply it in a format that can be understood by Windows.</p>
<p>All of this comes down to putting this under the global section of your smb.conf.</p>
<pre><code class="shell">security = user
encrypt passwords = yes</code></pre>
<p>And then executing this on the command line for each user you want access your private share.  These users must be legitimate Unix users on the server.</p>
<pre><code class="shell">smbpasswd -a username</code></pre>
<p><em><strong>Note:</strong> It is possible to sync your Samba users with your Unix users.  Ubuntu Gutsy Gibbon has this enabled with its default configuration of Samba.  This can cause unexpected effects if your Windows users names are the same as the user names on your Samba server.  See the Public Share section for more details.  To see which users already exist in the Samba password database run this in a shell: <code>pdbedit -L</code></em></p>
<p>All that is left is to define your private shares in smb.conf.</p>
<pre><code class="shell">[private]
        comment = Private Share
        # Path to directory you want to share out
        path = /mnt/private
        # Allow writing to the share
        read only = No
        # Do not allow computers on the network to see that this share
        # exists while browsing (i.e. Network Neighborhood)
        browseable = No
        # These two are optional.
        # Sets the umask for files/directories created on this share.
        create mask = 0640
        directory mask = 0750
        # This is also optional.  Restrict access to only certain users.
        # This gives access to Harry and to anyone in the group Family
        valid users = harry @family
</code></pre>
<p>After restarting Samba with <code>sudo /etc/init.d/samba restart</code>, you should be able to access this private share.</p>
<ul>
<li><strong>Windows</strong> Browse to \\[netbios or ip of server\private and provide a valid user and password</li>
<li><strong>Linux</strong> Mount the share with <code>sudo mount -t smbfs -o username=[username],password=[password],rw,uid=[your Unix user],gid=[your Unix group] //[netbios or ip of server]/private /path/to/mount/point</code></li>
</ul>
<p>If this doesn&#8217;t work, I would suggest reading through <a href="http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch12_:_Samba_Security_and_Troubleshooting">this excellent troubleshooting guide.</a>  If you find something wrong with how I did things, drop me a comment.</p>
<p><em>Note:  In Linux, if you can successfully mount the share but do not have write permissions to it, make sure that you have write permissions on the mount point on the <strong>client</strong> side.  That is, if you specified the user <code>smbuser</code> as the uid in the mount command, make sure <code>smbuser</code> has write permissions to /path/to/mount/point.</em></p>
<h2>Using a credentials file</h2>
<p>You&#8217;re probably going to want to mount this share automatically at boot by putting it in your <code>/etc/fstab</code> file.  Storing a password in plain text in fstab is probably a bad idea.  Samba lets you specify a credentials file in the mount command to get around this.  The format is a set of simple name=value pairs.</p>
<pre><code>username=[username]
password=[password]</code></pre>
<p>Store this file where ever you want.  I put it in <code>/etc/samba/</code> because that seemed convenient.  Give it only read access to root.</p>
<pre><code>$ sudo chown root:root /path/to/credentials
$ sudo chmod 400 /path/to/credentials</code></pre>
<p>Then the mount command becomes <code>sudo mount -t smbfs -o credentials=/path/to/credentials,rw,uid=[your Unix user],gid=[your Unix group] //[netbios or ip of server]/private /path/to/mount/point</code></p>
<h2>The Public Share</h2>
<p>This was actually the hard part to figure out, even though in the end there isn&#8217;t much configuring to do.  The key is the <code>map to guest</code> directive in smb.conf.  This allows you to map invalid user/password attempts to the guest account.  The guest account can be specified globally or per-share. <code>map to guest</code> has four options.</p>
<ul>
<li><strong>never (default)</strong> If you give a bad user/password, the connection is rejected</li>
<li><strong>bad user</strong>If a bad user is given, map the connection to the guest account</li>
<li><strong>bad password</strong> If a valid user but bad password is given, map the connection to the guest account.</li>
<li><strong>bad uid</strong> This is only applicable when you are using security = domain or security = ads</li>
</ul>
<p>What we want here is <code>map to guest = bad user</code>.  You see, when Windows connects to a Samba share it will provide the user and password of the currently logged on user.  Since, usually, the account names on the Windows machine will not exist on the Samba server, the map to user directive will be triggered and the connection will be mapped to the guest account you specify.  This lets Windows machines connect to the share with no password prompt.  What&#8217;s even better, this will only work if you specify <code>guest = ok</code> in your share definition.  Your private shares can remain private.</p>
<p>To set this up add this to the [global] section of smb.conf</p>
<pre><code class="shell">map to guest = bad user
# Optionally, specify a global default guest
guest account = nobody
</code></pre>
<p>Here is the public share definition </p>
<pre><code class="shell">[public]
        comment = Public Share
        # Path to directory you want to share out
        path = /mnt/nas/public
        # Allow writing to the share
        read only = No
        # Force connections as guests
        guest only = Yes
        guest ok = Yes
        # Optionally, specify the guest account here
        guest account = nobody
        # These two are optional.
        # Sets the umask for files/directories created on this share.
        create mask = 0640
        directory mask = 0750
</code></pre>
<p>After restarting Samba with <code>sudo /etc/init.d/samba restart</code>, you should be able to access this public share.</p>
<ul>
<li><strong>Windows</strong> Browse to \\[netbios or ip of server\private.  You shouldn&#8217;t be prompted for a password.  Booyah.</li>
<li><strong>Linux</strong> Mount the share with <code>sudo mount -t smbfs -o username=,password=,rw,uid=[your Unix user],gid=[your Unix group] //[netbios or ip of server]/public /path/to/mount/point</code>.  Note the blank user and password.</li>
</ul>
<p>If this doesn&#8217;t work, I would again suggest reading through <a href="http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch12_:_Samba_Security_and_Troubleshooting">this excellent troubleshooting guide.</a></p>
<p>Again, in Linux, make sure that your client-side user has write permissions to the mount point.</p>
<h1>Caveat with duplicate user names and Unix/Samba password sync</h1>
<p>This took me forever to figure out.  With the public share does&#8230;</p>
<ul>
<li>Windows still prompt for a username and password when connecting?</li>
<li>Linux successfully mounts the public share without specifying a user or password?</li>
<li>Your Windows user name match your Unix user name on the Samba server?</li>
<li>Your Windows password does <em>not</em> match your Unix password?</li>
</ul>
<p>What is happening is that Windows is silently attempting to authenticate with the current Windows username and password.  When that fails, it prompts for another set of credentials.  But why is it failing?  Because you are silently trying to login with a valid Samba user name.</p>
<p>Remember what <code>map to guest = bad user</code> does?  It will map to the guest account if a bad user name is provided.  However, Windows is giving the Samba server a <strong>valid</strong> user name with a <strong>invalid</strong> password.  Samba will straight up reject the connection.  The mount command given above will still work because you are giving an invalid user name (null).</p>
<p>But I didn&#8217;t explicitly use <code>smbpasswd</code> to set up this user?  If password sync is enabled, which it is by default in Ubuntu Gutsy, <em>all</em> of your Unix users are already part of the Samba password database.  Check out <code>pdbedit -L</code> to confirm.  This is what perplexed me the longest.  I ended up specifying <code>debug level = 3</code> in the [global] section of smb.conf.  In the logs I found when Windows tried to connect Samba would respond to NT_STATUS_WRONG_PASSWORD.</p>
<p>I find this terribly lame.  This means if I have a friend over that brings their laptop and their Windows login happens to exist on the Samba server they won&#8217;t be able to access the public share.  The easiest solution I found was to remove the duplicate user name from Samba&#8217;s database.</p>
<pre><code class="shell"># See what users are set up with Samba
pdbedit -L
# Remove the duplicate user name
smbpasswd -x [username]
</code></pre>
<p>There is still a problem though.  We just removed the Samba user that I was going to use to access my private shares.  What I did was create a Unix and Samba user on the server, <code>smbprivate</code>.  I use this account to access all of my private shares.  Just make sure that this user has correct permissions on the files and directories that are shared.</p>
<h1>References</h1>
<p><a href="http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch12_:_Samba_Security_and_Troubleshooting">Samba Security and Troubleshooting at linuxhomenetworking.com</a></p>
<p><a href="http://www.oreilly.com/catalog/samba/chapter/book/">O&#8217;Reilly&#8217;s excellent online Samba book</a></p>
<p><a href="http://us4.samba.org/samba/docs/man/Samba-HOWTO-Collection/">Official Samba HOWTO collection</a></p>
]]></content>
	<feedburner:origLink>http://tech.waltco.biz/2008/01/26/private-and-guest-no-password-prompt-samba-shares-with-securityuser/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Walter Wilfinger</name>
						<uri>http://tech.waltco.biz/</uri>
					</author>
		<title type="html"><![CDATA[Install VirtualBox in Ubuntu 7.10 Gutsy Gibbon]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/waltcotech/~3/212973425/" />
		<id>http://tech.waltco.biz/2008/01/06/install-virtualbox-in-ubuntu-710-gutsy-gibbon/</id>
		<updated>2008-01-11T05:12:28Z</updated>
		<published>2008-01-07T01:36:22Z</published>
		<category scheme="http://tech.waltco.biz" term="InstallationAndSetup" /><category scheme="http://tech.waltco.biz" term="Ubuntu Gutsy Gibbon" /><category scheme="http://tech.waltco.biz" term="VirtualBox" />		<summary type="html"><![CDATA[Short and Sweet
sudo apt-get install virtualbox-ose
gpasswd -a yourusername vboxusers
# Log out and back in at this point
sudo /etc/init.d/vboxdrv restart
# See below for instructions on tweaking an Ubuntu Guest OS
My terrible experience getting Rails installed on Ubuntu prompted me to toy around with virtualization.  Virtualization allows me to test installation and setup procedures off of [...]]]></summary>
		<content type="html" xml:base="http://tech.waltco.biz/2008/01/06/install-virtualbox-in-ubuntu-710-gutsy-gibbon/"><![CDATA[<h2>Short and Sweet</h2>
<pre><code class="shell">sudo apt-get install virtualbox-ose
gpasswd -a yourusername vboxusers
# Log out and back in at this point
sudo /etc/init.d/vboxdrv restart
# See below for instructions on tweaking an Ubuntu Guest OS</code></pre>
<p>My <a href="http://tech.waltco.biz/2007/12/24/installing-ruby-and-ruby-on-rails-in-ubuntu-710-gutsy-gibbon/">terrible experience getting Rails installed on Ubuntu</a> prompted me to toy around with virtualization.  Virtualization allows me to test installation and setup procedures off of a fresh install of Ubuntu.  I like this idea because it means I can make my setups repeatable.  I&#8217;ve had too many installation projects (especially with Gentoo) where I get it working, but have no idea how I got there.  But the best part of virtualization is if I screw up the virtual machine, I can load up an earlier snapshot and retry.  This is much better than nuking my entire laptop.</p>
<p>My hard time installing Rails made me want to install VirtualBox.  As luck would have it, this install was not straight forward either.  A plain <tt>sudo apt-get install virtualbox-ose</tt> did not successfully install VirtualBox for me on my Ubuntu install.  Here are the extra steps I had to take to get it working.</p>
<h2>Install VirtualBox</h2>
<p><a href="https://wiki.ubuntu.com/Testing/VirtualBox">This page on the Ubuntu wiki</a> makes out the VirtualBox install to be a simple apt-get and then adding yourself to the vboxusers group.  Easy enough.</p>
<pre><code class="shell">sudo apt-get install virtualbox-ose</code></pre>
<p>This install went ok for a while but then I saw this scroll by in the console</p>
<pre><code>chown: `:vboxusers': invalid group
* Cannot change owner vboxusers for device /dev/vboxdrv.</code></pre>
<p>Well that&#8217;s not cool.  What was even more perplexing was that post-install I checked my system and the vboxusers group <em>did</em> exist.  I&#8217;m not sure if this is a quirk with my system or an actual bug.  I went ahead and added myself to the vboxusers group anyway.</p>
<pre><code class="shell">gpasswd -a yourusername vboxusers</code></pre>
<p>I logged out and back in, then gave running VirtualBox a try.  I started creating a virtual machine, which went well for a while until it gave me an error about the <tt>vboxdrv</tt> kernel module.  After some snooping I came across <a href="https://bugs.launchpad.net/ubuntu/+source/virtualbox-ose/+bug/179807">this Ubuntu bug report</a> which didn&#8217;t apply to me but did give me the idea of restarting the module.</p>
<pre><code class="shell">sudo /etc/init.d/vboxdrv restart</code></pre>
<p>I tried creating a virtual machine again and VIOLA!  Everything worked!</p>
<p>After installing Ubuntu on a virtual machine it&#8217;s a good idea to install VirtualBox Guest Additions as well.  The below instructions, unless specified otherwise, deal with an Ubuntu Guest OS / virtual machine.  <em>Don&#8217;t run these commands in your Host OS.</em></p>
<h2>Install VirtualBox Guest Additions</h2>
<p>The Guest Additions package installs some add-ons into the Guest OS.  The most noticeable of these is Mouse Integration which allows the mouse to function without the need to &#8216;lock&#8217; it into the VM.  I also believe that the Guest Additions install special display drivers.  This is important if you want your VirtualBox to run in higher resolutions.  I pulled these instructions from the <a href="http://www.virtualbox.org/wiki/Downloads">official VirtualBox documentation</a>.  It&#8217;s a PDF.  I don&#8217;t know why.  They also want you to run the script with <tt>sh</tt> but why bother?</p>
<p>In the Guest window, that is, the window that is displaying your Guest OS, do <tt>Devices -&gt; Install Guest Additions</tt>.  VirtualBox will prompt you to download the .iso if you haven&#8217;t already. After the download finishes you will be prompted to mount the ISO in your VM.  Say yes.  Run this on the command line <strong>of the Guest OS</strong>.</p>
<pre><code class="shell">sudo /media/cdrom0/VBoxLinuxAdditions.run</code></pre>
<p>The VirtualBox documentation says you can choose which drivers you want to install.  If you&#8217;re interested in this take a look at <tt>sudo /media/cdrom0/VBoxLinuxAdditions.run help</tt></p>
<p>I shut down the Guest OS and took a snapshot at this point.  I planned on fiddling with Xorg configurations next and it is much easier to load up a VM snapshot than it is to restore a backup xorg.conf.</p>
<h2>Change the VirtualBox Resolution</h2>
<p>After my Ubuntu install, Xorg was configured to only support 800&#215;600.  This was way too small for me.  My main machine is a widescreen laptop running at 1680&#215;1050.  I want two options.</p>
<ul>
<li>1024&#215;768 for running VirtualBox windowed</li>
<li>1680&#215;1050 for running VirtualBox fullscreen</li>
</ul>
<p>The VirtualBox documentation has the following to say about running higher resolutions in your VM (page 50 if you&#8217;re curious)</p>
<blockquote><p>VirtualBox can use any default X graphics mode which fits into the virtual video memory allocated to the virtual machine, as described in chapter 3.7.1, General settings, page 37. You can also add your own modes to the X server configuration file. You simply need to add them to the “Modes” list in the “Display” subsection of the “Screen” section.</p></blockquote>
<p><strong>In your Guest OS</strong>, edit your <tt>xorg.conf</tt> file by running <tt>sudo gedit /etc/X11/xorg.conf</tt>.  Here is what I ended up with.</p>
<pre><code class="ruby">Section "Screen"
  Identifier    "Default Screen"
  Device        "Generic Video Card"
  Monitor       "Generic Monitor"
  DefaultDepth  24
  SubSection    "Display"
    Modes         "1680x1050" "1024x768" "800x600"
  EndSubSection
EndSection</code></pre>
<p>I rebooted to make sure things worked.  I then shut down the Guest OS and took another snapshot.</p>
<p>I am not an Xorg expert.  I found if I listed 1680&#215;1050 first Ubuntu&#8217;s login screen would be 1680&#215;1050.  After logging into my user account I was able to do <tt>System -&gt; Preferences -&gt; Screen Resolution</tt> and change to 1024&#215;768 without problems.  If instead I listed 1024&#215;768 first Ubuntu&#8217;s login screen would be 1024&#215;768.  After logging in if I attempted to change the Screen Resolution to 1680&#215;1050 (I believe) the horizontal sync would be set incorrectly.  By this I mean I couldn&#8217;t see jack.  I tried figuring out a way to have the default be 1024&#215;768 with the option of switching to 1680&#215;1050, but after an hour of tweaking I gave up.  <em>If you are more familiar with Xorg and know what I&#8217;m doing wrong, please leave a comment.</em></p>
<h2>Notes</h2>
<ul>
<li>The Ubuntu install DVD decided that the VM&#8217;s max resolution should be 800&#215;600.  This, hilariously, is too small to click on the Forward and Ok buttons in the install wizard.  I had to figure out that Alt-F went forward in the dialogs.  The final dialog needed an Enter to start the install.</li>
<li> As of this writing, the version of VirtualBox that is installed by virtualbox-ose is 1.5.0.
<pre><code class="shell">$ dpkg-query --show virtualbox-ose
virtualbox-ose  1.5.0-dfsg2-1ubuntu3</code></pre>
<p>It looks like <a href="https://bugs.launchpad.net/ubuntu/+source/virtualbox-ose/+bug/156210">the Ubuntu guys are currently working</a> on getting a <a href="http://www.virtualbox.org/wiki/Changelog">VirtualBox 1.5.4</a> package up.  I suppose if you really wanted to, you could install VirtualBox 1.5.4 from source.  I found <a href="http://www.howtoforge.com/virtualbox_ubuntu">this guide</a> to install from source, but didn&#8217;t bother with it.</li>
<li> I still need to figure out how VirtualBox network bridging works.  My VM does have net access because it is able to download packages from online repositories with apt-get.  At the same time I couldn&#8217;t do something simple like ping my web server.  <em>Apparently this is expected.  Page 58 of the <a href="http://www.virtualbox.org/wiki/Downloads">VirtualBox documentation</a> says: Please note that the ping utility does not work over NAT.</em>  There is another option, <em>host interface networking</em>, that might give me more control over the VM&#8217;s networking.</li>
</ul>
]]></content>
	<feedburner:origLink>http://tech.waltco.biz/2008/01/06/install-virtualbox-in-ubuntu-710-gutsy-gibbon/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Walter Wilfinger</name>
						<uri>http://tech.waltco.biz/</uri>
					</author>
		<title type="html"><![CDATA[Adding languages to Google Syntax Highlighter plugins for WordPress]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/waltcotech/~3/212973426/" />
		<id>http://tech.waltco.biz/2008/01/01/adding-languages-to-google-syntax-highlighter-plugins-for-wordpress/</id>
		<updated>2008-01-01T21:34:28Z</updated>
		<published>2008-01-01T21:09:59Z</published>
		<category scheme="http://tech.waltco.biz" term="WordPress" />		<summary type="html"><![CDATA[I use the excellent Google Syntax Highlighter by Alex Gorbatchev to highlight my code snippets here (called GSH from here on out).  A couple of WordPress plugins exist that integrate it into WordPress.  I personally use SyntaxHighlight by Eric Range, but you can find Plenty of others on WordPress&#8217;s site1.  Several languages [...]]]></summary>
		<content type="html" xml:base="http://tech.waltco.biz/2008/01/01/adding-languages-to-google-syntax-highlighter-plugins-for-wordpress/"><![CDATA[<p>I use the excellent <a href="http://code.google.com/p/syntaxhighlighter/">Google Syntax Highlighter</a> by Alex Gorbatchev to highlight my code snippets here (called GSH from here on out).  A couple of WordPress plugins exist that integrate it into WordPress.  I personally use <a href="http://erik.range-it.de/wordpress/plugins/syntaxhighlighter/">SyntaxHighlight</a> by <a href="http://erik.range-it.de/">Eric Range</a>, but you can find <a href="http://wordpress.org/extend/plugins/syntaxhighlighter/#post-2284">Plenty</a> <a href="http://wordpress.org/extend/plugins/syntaxhighlighter-plus/#post-2702">of</a> <a href="http://wordpress.org/extend/plugins/google-syntax-highlighter/#post-2183">others</a> on WordPress&#8217;s site<sup>1</sup>.  Several languages are supported right out of the box, but I came across situations where I wanted to display code with very little to no formatting (shell scripts, config files&#8230;)  Turns out, adding languages to GSH isn&#8217;t very difficult.  This guide should work with any plugin based on Alex Gorbatchev&#8217;s code.  The only difference between plugins is how they tie the GSH&#8217;s javascript files into WordPress.  My examples will use Eric Range&#8217;s plugin.</p>
<h2>A very simple shell script language definition</h2>
<p>I want to highlight some shell script files.  I don&#8217;t need anything too complicated.  I just need to have # highlight as a comment to the end of the line.</p>
<h2>Add a language Brush</h2>
<p>We start by opening up one of the existing language &#8220;Brush&#8221; js files to use as a reference.  These are called <tt>shBrush[language].js</tt> and are located in <tt>Scripts/</tt>.  Let&#8217;s look at the definition for Ruby because it isn&#8217;t too complicated.</p>
<textarea name="code" class="js:nocontrols" cols="60" rows="10">
/* Ruby 1.8.4 syntax contributed by Erik Peterson */
dp.sh.Brushes.Ruby = function()
{
var keywords =	'alias and BEGIN begin break case class def define_method defined do each else elsif ' +
'END end ensure false for if in module new next nil not or raise redo rescue retry return ' +
'self super then throw true undef unless until when while yield';

var builtins =	'Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload ' +
'Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol ' +
'ThreadGroup Thread Time TrueClass'

this.regexList = [
{ regex: dp.sh.RegexLib.SingleLinePerlComments,			css: 'comment' },	// one line comments
{ regex: dp.sh.RegexLib.DoubleQuotedString,				css: 'string' },	// double quoted strings
{ regex: dp.sh.RegexLib.SingleQuotedString,				css: 'string' },	// single quoted strings
{ regex: new RegExp(':[a-z][A-Za-z0-9_]*', 'g'),		css: 'symbol' },	// symbols
{ regex: new RegExp('[\\$|@|@@]\\w+', 'g'),				css: 'variable' },	// $global, @instance, and @@class variables
{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),	css: 'keyword' },	// keywords
{ regex: new RegExp(this.GetKeywords(builtins), 'gm'),	css: 'builtin' }	// builtins
];

this.CssClass = 'dp-rb';
}

dp.sh.Brushes.Ruby.prototype	= new dp.sh.Highlighter();
dp.sh.Brushes.Ruby.Aliases	= ['ruby', 'rails'];
</textarea>
<p>Most of the work lies in changing and <tt>this.CssClass</tt> and <tt>this.regexList</tt>.  <tt>this.CssClass</tt> will end up being the class of the &lt;ol&gt; element in the output html.  Each element of <tt>this.regexList</tt> defines a RegExp object and a corresponding CSS class.  If a segment of code matches the RegExp it will be put in a &lt;span&gt; with the class you specify.  The actual highlighting portion is all done through CSS, as it should be.</p>
<p><tt>this.GetKeywords()</tt> will take a space delimited string and convert it into an appropriate RegExp.  You can see how it is used above.</p>
<p><tt>dp.sh.Brushes.Ruby.Aliases</tt> is an array of strings that define what code blocks will invoke this highlighting rule.  If I specify that my code is &#8216;ruby&#8217; or &#8216;rails&#8217; GSH will highlight it using these rules.</p>
<p>Luckily, my requirements are so terse that we&#8217;re left with very little code.</p>
<textarea name="code" class="js:nocontrols" cols="60" rows="10">
// Scripts/shBrushShell.js
p.sh.Brushes.Shell = function()
{

this.regexList = [
{ regex: new RegExp('#(.*)$', 'gm'),   css: 'comment' }, // one line comments
];

this.CssClass = 'dp-shell';
}

dp.sh.Brushes.Shell.prototype	= new dp.sh.Highlighter();
dp.sh.Brushes.Shell.Aliases	= ['shell'];
</textarea>
<p>I save this as <tt>Scripts/shBrushShell.js</tt></p>
<h2>Edit the CSS</h2>
<p>All the CSS is stored in one file <tt>Scripts/SyntaxHighlighter.css</tt>.  Following the conventions in the rest of the CSS styles we add our rules for <tt>.dp-shell</tt> and <tt>.dp-shell .comment</tt></p>
<textarea name="code" class="css:nocontrols" cols="60" rows="10">
/* At the end of Scripts/SyntaxHighlighter.css */
.dp-shell {}
.dp-shell .comment { color: blue; }
</textarea>
<h2>Edit the plugin source</h2>
<p>This will vary plugin to plugin.  For Eric Range&#8217;s plugin there is one array that I have to change in <tt>syntax.php</tt></p>
<textarea name="code" class="php:nocontrols" cols="60" rows="10">
// syntax.php
function syntaxBrushes() {

return array(
"Cpp" 		=&gt; "C++",
"CSharp" 	=&gt; "C#",
"Css" 		=&gt; "CSS",
"Delphi" 	=&gt; "Delphi, Pascal",
"Java" 		=&gt; "Java",
"JScript" 	=&gt; "JavaScript",
"Php" 		=&gt; "PHP",
"Python" 	=&gt; "Python",
"Ruby" 		=&gt; "Ruby",
"Sql" 		=&gt; "SQL",
"Vb" 		=&gt; "VisualBasic, VB.NET",
"Xml" 		=&gt; "XML, XHTML, XSLT, HTML",
"Shell"     =&gt; "Shell",
);
}
</textarea>
<p>I also had to enable Shell language in the WordPress-&gt;Options-&gt;Syntax menu.</p>
<h2>Test</h2>
<textarea name="code" class="shell:nocontrols" cols="60" rows="10">
sudo apt-get install vlc # This will install vlc
# Below is somewhat useless
echo "Strings don't highlight but I don't care!"
</textarea>
<h2>A Brush with no highlighting</h2>
<p>I created a Plain language that won&#8217;t do any highlighting.  I&#8217;ll use this when I don&#8217;t have an applicable Brush and  I don&#8217;t want to bother writing a new one.</p>
<p><tt>Script/shBrushPlain.js</tt></p>
<textarea name="code" class="js:nocontrols" cols="60" rows="10">
dp.sh.Brushes.Plain = function()
{
this.regexList = [];
this.CssClass = 'dp-plain';
}
dp.sh.Brushes.Plain.prototype	= new dp.sh.Highlighter();
dp.sh.Brushes.Plain.Aliases	= ['plain'];
</textarea>
<p><tt>Style/SyntaxHighlighter.css</tt></p>
<textarea name="code" class="css:nocontrols" cols="60" rows="10">
/* Really just a placeholder.  I could make the text all certain color here if I wanted */
.dp-plain {}
</textarea>
<p><tt>syntax.php</tt></p>
<textarea name="code" class="php:nocontrols" cols="60" rows="10">
function syntaxBrushes() {

return array(
"Cpp" 		=&gt; "C++",
"CSharp" 	=&gt; "C#",
"Css" 		=&gt; "CSS",
"Delphi" 	=&gt; "Delphi, Pascal",
"Java" 		=&gt; "Java",
"JScript" 	=&gt; "JavaScript",
"Php" 		=&gt; "PHP",
"Python" 	=&gt; "Python",
"Ruby" 		=&gt; "Ruby",
"Sql" 		=&gt; "SQL",
"Vb" 		=&gt; "VisualBasic, VB.NET",
"Xml" 		=&gt; "XML, XHTML, XSLT, HTML",
"Shell"   =&gt; "Shell",
"Plain"   =&gt; "Plain",
);
}
</textarea>
<p>Proof that it works</p>
<textarea name="code" class="plain:nocontrols" cols="60" rows="10">
I can put whatever I want here and nothing will be highlighted.  JF*(AJ*
"Python" 	=&gt; "Python",
"Ruby" 		=&gt; "Ruby",
"Sql" 		=&gt; "SQL",
</textarea>
<h5>Notes:</h5><ol class="footnotes"><li id="footnote_0_9" class="footnote">Unfortunately, Eric Range&#8217;s plugin shares its name with a plugin on WordPress&#8217;s site.  Like I said, any plugin based on GSH should be rather easy to modify.</li></ol>]]></content>
	<feedburner:origLink>http://tech.waltco.biz/2008/01/01/adding-languages-to-google-syntax-highlighter-plugins-for-wordpress/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Walter Wilfinger</name>
						<uri>http://tech.waltco.biz/</uri>
					</author>
		<title type="html"><![CDATA[My .vimrc file]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/waltcotech/~3/212973427/" />
		<id>http://tech.waltco.biz/2007/12/25/my-vimrc-file/</id>
		<updated>2008-01-11T06:06:24Z</updated>
		<published>2007-12-25T21:05:40Z</published>
		<category scheme="http://tech.waltco.biz" term="InstallationAndSetup" />		<summary type="html"><![CDATA[&#8221; set options
set    background=dark
set    nocompatible
set    hlsearch
set    incsearch
set    ignorecase
set    ruler
set    showcmd
set    showmatch
set    showmode
set    tabstop=2
set    shiftwidth=2
set    expandtab
set    wmh=0
set [...]]]></summary>
		<content type="html" xml:base="http://tech.waltco.biz/2007/12/25/my-vimrc-file/"><![CDATA[<pre><source>&#8221; set options
set    background=dark
set    nocompatible
set    hlsearch
set    incsearch
set    ignorecase
set    ruler
set    showcmd
set    showmatch
set    showmode
set    tabstop=2
set    shiftwidth=2
set    expandtab
set    wmh=0
set   cindent

colorscheme torte

&#8221; set mappings

&#8221; control n kills search hilighting
nmap &lt;silent&gt; &lt;C-N&gt; :silent noh&lt;CR&gt;

&#8221; control j and control k switch panes and maximize
nmap &lt;C-J&gt; &lt;C-W&gt;j&lt;C-W&gt;_
nmap &lt;C-K&gt; &lt;C-W&gt;k&lt;C-W&gt;_

&#8221; moving over wrapped lines moves to next visual not physical line
imap &lt;silent&gt; &lt;Down&gt; &lt;C-o&gt;gj
imap &lt;silent&gt; &lt;Up&gt; &lt;C-o&gt;gk
nmap &lt;silent&gt; &lt;Down&gt; gj
nmap &lt;silent&gt; &lt;Up&gt; gk
nmap &lt;silent&gt; j gj
nmap &lt;silent&gt; k gk

&#8221; block commenting mappings , and comment characteer will add lhs comment
&#8221; character ,c will clear
map ,# :s/^/#/&lt;CR&gt;
map ,/ :s/^/\/\//&lt;CR&gt;
map ,&gt; :s/^/&gt; /&lt;CR&gt;
map ,&#8221; :s/^/\&#8221;/&lt;CR&gt;
map ,% :s/^/%/&lt;CR&gt;
map ,! :s/^/!/&lt;CR&gt;
map ,; :s/^/;/&lt;CR&gt;
map ,- :s/^/&#8211;/&lt;CR&gt;
map ,c :s/^\/\/\\|^&#8211;\\|^&gt; \\|^[#&#8221;%!;]//&lt;CR&gt;</source></pre>
]]></content>
	<feedburner:origLink>http://tech.waltco.biz/2007/12/25/my-vimrc-file/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Walter Wilfinger</name>
						<uri>http://tech.waltco.biz/</uri>
					</author>
		<title type="html"><![CDATA[Installing Ruby and Ruby on Rails in Ubuntu 7.10 Gutsy Gibbon]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/waltcotech/~3/212973428/" />
		<id>http://tech.waltco.biz/2007/12/24/installing-ruby-and-ruby-on-rails-in-ubuntu-710-gutsy-gibbon/</id>
		<updated>2008-01-11T06:12:14Z</updated>
		<published>2007-12-25T02:13:44Z</published>
		<category scheme="http://tech.waltco.biz" term="InstallationAndSetup" /><category scheme="http://tech.waltco.biz" term="Rails" /><category scheme="http://tech.waltco.biz" term="Ubuntu Gutsy Gibbon" /><category scheme="http://tech.waltco.biz" term="installation" /><category scheme="http://tech.waltco.biz" term="ruby" /><category scheme="http://tech.waltco.biz" term="ubuntu" />		<summary type="html"><![CDATA[tl;dr version
sudo apt-get install ruby rdoc irb libyaml-ruby libzlib-ruby ri libopenssl-ruby
wget http://rubyforge.org/frs/download.php/29548/rubygems-1.0.1.tgz
tar xzvf rubygems-1.0.1.tgz
cd rubygems-1.0.1
sudo ruby setup.rb
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
sudo gem update --system
sudo gem install rails
sudo apt-get install build-essential ruby1.8-dev
sudo gem install mongrel
sudo apt-get install mysql-client mysql-admin mysql-query-browser libmysqlclient15-dev
sudo gem install mysql
sudo apt-get install sqlite3 swig libsqlite3-ruby libsqlite3-dev
sudo gem install sqlite3-ruby
echo "export RUBYOPT=rubygems" &#62;&#62; [...]]]></summary>
		<content type="html" xml:base="http://tech.waltco.biz/2007/12/24/installing-ruby-and-ruby-on-rails-in-ubuntu-710-gutsy-gibbon/"><![CDATA[<h3>tl;dr version</h3>
<pre><code class="shell">sudo apt-get install ruby rdoc irb libyaml-ruby libzlib-ruby ri libopenssl-ruby
wget http://rubyforge.org/frs/download.php/29548/rubygems-1.0.1.tgz
tar xzvf rubygems-1.0.1.tgz
cd rubygems-1.0.1
sudo ruby setup.rb
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
sudo gem update --system
sudo gem install rails
sudo apt-get install build-essential ruby1.8-dev
sudo gem install mongrel
sudo apt-get install mysql-client mysql-admin mysql-query-browser libmysqlclient15-dev
sudo gem install mysql
sudo apt-get install sqlite3 swig libsqlite3-ruby libsqlite3-dev
sudo gem install sqlite3-ruby
echo "export RUBYOPT=rubygems" &gt;&gt; ~/.profile
rails path/to/your/app
</code></pre>
<p>Coming from Gentoo, I thought installing anything on Ubuntu would be a breeze.  Especially something with so much Internet-hype as Ruby on Rails.  Unfortunately, the process isn&#8217;t completely intuitive.  After breaking my teeth on my first few Ubuntu installs (<em>sudo apt-get install vlc</em>&#8230;wow that worked?), I was expecting something along the following to work for Rails:</p>
<pre><code class="shell">sudo apt-get install ruby rubyonrails</code></pre>
<p>At which point Ubuntu&#8217;s magical installer gnomes would pop a working installation of Rails onto my laptop.</p>
<p>This, to my dismay, was not the case.  From what I can gather, this is because <strong>you</strong> want to use RubyGems to manage your Ruby&#8230;gems.  Ubuntu, on the other hand, really wants to use Aptitude to manage your Ruby gems.  It wants to do this so much, in fact, that if you install RubyGems using Aptitude pretty much nothing will work. You can work around this by installing RubyGems to your home directory.  I tried out that method, but found <em>sudo gems update &#8211;system</em> calls would try to update to /usr/lib.</p>
<p>For those playing at home, /usr/lib is not your home directory.</p>
<p>I would expect the open source super-nerds to figure this out. Leaving me, being a dumb end-user, only to do a single apt-get command, make a cup of tea, and then while still waiting for the water to boil Rails would finish installing.  I would come back to an impatient laptop who is wondering why I thought the whole process would take so long.</p>
<p>The open-source nerds have instead decided &#8212; <a href="http://www.ruby-forum.com/topic/128864" title="Nerd Fight" target="_blank">as far as I can tell by this nerd fight from October of this year</a> &#8212; to just bitch about who is putting what in the wrong place.  This leaves us longing for a Rails install; and that cup of tea now that we mentioned it.  Hold on one minute&#8230;</p>
<p>Mmmm.  Chai tea.  Ok.  We&#8217;re going to install Ruby using apt-get. Then we will install RubyGems from source, forgoing Aptitude altogether.</p>
]]></content>
	<feedburner:origLink>http://tech.waltco.biz/2007/12/24/installing-ruby-and-ruby-on-rails-in-ubuntu-710-gutsy-gibbon/</feedburner:origLink></entry>
	</feed>
