Author Archives: alex - Page 2

Linking a flat binary from C with MinGW

If you’re trying to compile a kernel written in C for your own toy operating system, you may run into trouble compiling/linking your code. Assuming you’re using GRUB to load your kernel, or you’ve rolled your own boot sector, you’ll now want to compile your kernel code (written in C) to a flat binary. The toolchain provided by MinGW (gcc and ld) is well suited for this, as long as you know a few tricks.

Let’s start with a very simple kernel.c program just to see if we can get things working:

int main(void)
{
mylabel:
  goto mylabel;
}

We’ll compile this with gcc, switching on all warnings (the compiler is our friend):

gcc -Wall -pedantic-errors kernel.c -o kernel.exe

This will yield a working program that we can actually execute at the command prompt. It’ll pause indefinitely, as desired. However, there are a number of problems with the resulting binary:

First, the binary includes a PE header, which specifies how Windows must load and execute the program. We’re writing a kernel, so we don’t want any of this header data. We must find it way to remove it.

Second, the program is relocatable. The operating system (i.e. Windows) will load the code into memory where it wants, then use the information contained in the PE header to make sure that all references are correct. The references are provided relatively, that is, the can be relocated. For our kernel, this is not what we want: we want to load our kernel at a specific address (say 0×20000) and make all references work precisely (statically) there.

This can be illustrated by running objdump:

$ objdump -f kernel.exe
kernel.exe: file format pei-i386
architecture: i386, flags 0x00000132:
EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x00401160

Objdump’s output shows that a PE header is present (pei-i386 file format) and that a default random start adress of 0×00401160 has been defined. Let’s see what we can do about the start address. Since we want our kernel to always run at 0×20000, we can instruct the linked to use that address to place the code. Linker options can be passed to gcc:

Hint: do not use gcc to compile but not link, then ld to do the linking separately. Strange error messages will ensue. It’s easier to simply pass the linking options to gcc and let gcc call ld for you.

$ gcc -Wall -pedantic-errors kernel.c -o kernel.exe -Wl,-Ttext=0x20000
$ objdump -f kernel.exe
kernel.exe: file format pei-i386
architecture: i386, flags 0x00000132:
EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x00020160

Oh look: our start address is now 0×00020160. The excess 0×160 bytes are the space occupied by the header, which we don’t want. We can try to pass the option –oformat binary to the linker, which will make it link a flat binary for us. Unfortunately (under MinGW), we get this:

c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../../mingw32/bin/ld.exe:
cannot perform PE operations on non PE output file 'kernel.exe'.
collect2: ld returned 1 exit status

This can be resolved though: let the linker create the kernel.exe executable, then pass it through objcopy to create the flat binary:

objcopy -O binary -j .text kernel.exe kernel.bin

This will yield, finally, an executable. Unfortunately, it’s 3376 bytes in size! About 10 bytes would be closer to the mark. Obviously, code is being included that we didn’t write: references to standard libraries. Since we don’t have any standard libraries in our fledgling operating system, we’ll need to remove this. This can be done by passing the -nostdlib argument to gcc:

$ gcc -Wall -pedantic-errors kernel.c -o kernel.exe -nostdlib -Wl,-Ttext=0x20000
C:\Users\Alex\AppData\Local\Temp\cc5nshHf.o:kernel.c:(.text+0x7):
  undefined reference to `__main'
collect2: ld returned 1 exit status

Foiled again! Now that we have no standard libraries, ld is looking for startup code that doesn’t exist. We did write a main function, but it’s actually looking for a wrapper to that main function normally supplied by the standard libraries. Let’s try a different approach: we’ll rename our main function.

int start(void)
{
mylabel:
  goto mylabel;
}

Now our code compiles, and we’re down to a flat binary of 2011 bytes. It turns out that we must also pass -nostdlib to the linker:

$ gcc -Wall -pedantic-errors kernel.c -o kernel.exe -nostdlib
  -Wl,-Ttext=0x20000,-nostdlib

Now we get an executable of 24 bytes. In fact, on my system I get:

00000000h: 55 89 e5 eb fe 90 90 90 ff ff ff ff 00 00 00 00
00000010h: ff ff ff ff 00 00 00 00

When disassembled, this yields:

push ebp
mov ebp, esp
jmp .-2

This corresponds exactly to the code we wrote: a stack frame is created for the start function (even though we are not interested in it – a C program must always start with a function), then an infinite loop is entered (which we wrote using a label and a goto statement).

Wait… this code only occupies 5 bytes. So why are there 24 bytes in the flat binary image? We can see that the first three unneeded bytes have a value of 0×90, which corresponds to NOP instructions. This is probably added to get at least an 8-byte boundary. However, why an additional 16 bytes are added, I actually don’t know. If anyone can explain, I’d be grateful.

Nevertheless, we have now produced a flat binary that can be launched by our boot sector or second stage boot loader. It can be placed at 0×20000 and includes no undesired headers. Just the code, please, ma’am.

Installing Ruby’s mysql2 gem for MySQL 64-bits

I was trying to install Ruby’s mysql2 gem on my Windows 7 computer, running MySQL 64-bits. It turns out that the mysql2 gem is not compatible with MySQL 64-bits libmysql.dll file.

When installing, you get something like:

c:\>gem install mysql2 -- with-mysql-include=x:\include
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
ERROR:  Error installing mysql2:
ERROR: Failed to build gem native extension.
 
C:/Ruby192/bin/ruby.exe extconf.rb with-mysql-include=x:\include
checking for rb_thread_blocking_region()... yes
checking for main() in -llibmysql... yes
checking for mysql.h... yes
checking for errmsg.h... yes
checking for mysqld_error.h... yes
creating Makefile
 
make
C:/Ruby192/bin/ruby -e "puts 'EXPORTS', 'Init_mysql2'"  > mysql2-i386-mingw32.def
gcc -I. -IC:/Ruby192/include/ruby-1.9.1/i386-mingw32 -I/C/Ruby192/include/ruby-1.9.1/ruby/backward -I/C/Ruby192/include/ruby-1.9.1 -I. -DHAVE_RB_THREAD_BLOCKING_REGION -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQLD_ERROR_H -Ix:\include -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wall -funroll-loops  -o client.o -c client.c
gcc -I. -IC:/Ruby192/include/ruby-1.9.1/i386-mingw32 -I/C/Ruby192/include/ruby-1.9.1/ruby/backward -I/C/Ruby192/include/ruby-1.9.1 -I. -DHAVE_RB_THREAD_BLOCKING_REGION -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQLD_ERROR_H -Ix:\include    -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wall -funroll-loops -o mysql2_ext.o -c mysql2_ext.c
gcc -I. -IC:/Ruby192/include/ruby-1.9.1/i386-mingw32 -I/C/Ruby192/include/ruby-1.9.1/ruby/backward -I/C/Ruby192/include/ruby-1.9.1 -I. -DHAVE_RB_THREAD_BLOCKING_REGION -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQLD_ERROR_H -Ix:\include    -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wall -funroll-loops  -o result.o -c result.c
result.c: In function 'rb_mysql_result_fetch_fields':
result.c:376:35: warning: comparison between signed and unsigned integer expressions
gcc -shared -s -o mysql2.so client.o mysql2_ext.o result.o -L. -LC:/Ruby192/lib -L. -LC:\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\tk\\lib -LC:\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\tcl\\lib -LC :\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\libyaml\\lib -L
C:\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\pdcurses\\lib -LC:\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\openssl\\lib  -LC:\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\zlib\\lib -LC:\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\iconv\\lib -L
C:\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\gdbm\\lib -LC:\\Users\\Luis\\Projects\\oss\\oneclick\\rubyinstaller\\sandbox\\libffi\\lib  -Wl,--enable-auto-image-base,--enable-auto-import mysql2-i386-mingw32.def  -lmsvcrt -ruby191 -llibmysql  -lshell32 -lws2_32
client.o: In function `nogvl_connect':
C:\Ruby192\lib\ruby\gems\1.9.1\gems\mysql2-0.3.6\ext\mysql2/client.c:114: undefined reference to `mysql_real_connect@32'
client.o: In function `nogvl_init':
C:\Ruby192\lib\ruby\gems\1.9.1\gems\mysql2-0.3.6\ext\mysql2/client.c:105: undefined reference to `mysql_init@4'
client.o: In function `set_ssl_options':
C:\Ruby192\lib\ruby\gems\1.9.1\gems\mysql2-0.3.6\ext\mysql2/client.c:700: undefined reference to `mysql_ssl_set@24'
collect2: ld returned 1 exit status
make: *** [mysql2.so] Error 1
Gem files will remain installed in C:/Ruby192/lib/ruby/gems/1.9.1/gems/mysql2-0.3.6 for inspection.
Results logged to C:/Ruby192/lib/ruby/gems/1.9.1/gems/mysql2-0.3.6/ext/mysql2/gem_make.out

In other words, yet get a bunch of undefined references to functions that should exist in libmysql.dll. Except they don’t, because you’re running MySQL 64-bits and its functions have a different signature.

The solution is this: get the installation files for MySQL 32-bits (same version as yours), and copy the libmysql.dll file to your Ruby installation’s library directory  (C:\Ruby192\lib, for instance). Now linking will succeed.

Automating website & MySQL backups

I have a web server with a number of clients’ websites on it. It’s necessary to backup these websites every day, since clients use a content management system to make changes regularly. These changes can be updates to a website’s MySQL database, or they can be changes to the files stored within these websites. What I’d like is to backup the MySQL database and the filesystem for each website, every day, at a specific time. The backups must rotate: when there are, say, five backups, I want the oldest one to be removed as the newest one is written. Also, I’d like the backup solution to send me an email every day after it’s completed the backups with a summary of the procedure.

So, in summary, my needs are these:

  • Define a list of websites to back up
  • For each site, backup (dump) the MySQL database
  • For each site, backup the website’s file structure
  • Send an email to one or more people with a summary of the backup process.

It’s possible to do this with a shell script (like AutoMySQLBackup does). However, AutoMySQLBackup does not backup file systems or send email. Also, shell scripting tends to be messy code, so I decided to use Ruby.

Configuration file

First off, I’d like to store the list of websites to backup in a separate configuration file so that I can edit this list easily. Also, for reusability, I’ll store database access credentials and email addresses there too. The simplest way of making a configuration file to be read by Ruby is to actually write the configuration file in Ruby, like so:

BACKUPDIR = "/backup/webserver"
ROTATE = 5
DBUSER = "root"
DBPASSWORD = "myrootpassword"
EMAILS = [ "alex@email.com", "john@email.com" ]
WEBSITES = {
 "sample.com" => {
   "path" => "/usr/local/www/apache22/data/sample.com",
   "database" => "sampledb"
 },
 "example.net" => {
   "path" => "/usr/local/www/apache22/data/example.net",
   "database" => "exampledb"
 }
}

This file stores a variable ROTATE which indicates the number of backups to keep before throwing away the oldest one. For each website, I specify the path to the files to be backed up, and the name of the MySQL database. The configuration file will be included and parsed automatically by the backup script, since it is plain Ruby code.

Backup script

The backup script begins by requiring SMTP support, so that we can send emails later. It also starts an output buffer (“output”) where we will store all messages generated by the script to be included in the email. Before starting the backup procedure, we start a begin…rescue block so that me may catch any exceptions thrown by Ruby, in order to include these in the email as well.

require "net/smtp"
output = "Webserver backup script"
begin
  # Load config file:
  require "/usr/home/alex/backup-script/config.rb"
  # Does the backup directory exist?
  if not FileTest::exists?(BACKUPDIR)
    raise "Backup directory #{BACKUPDIR} does not exist."
    exit
  end

The script now loops through the list of websites defined in the configuration file, creating a backup directory with the name of the website for each if it doesn’t already exist:

  WEBSITES.each do |name, website|
 
    output << "\r\n\r\nBacking up #{name}:"
 
    # Establish backup dir
    path = BACKUPDIR + "/" + name
 
    # If website dir does not exist, create it.
    if not FileTest::exists?(path)
      Dir.mkdir path
      output << "\r\n  Directory #{path} created."
    end

Next, the script enumerates the subdirectories that already exist in the website’s backup directory. This is because we will create a subdirectory with date backup’s date for each backup (e.g. 20110810-105535, for 10 August 2011, 10:55:35). These directories are then sorted alphabetically, so that the least recent backup of the website is first in the list.

    # Get entries inside dir with modification times (sorted first to last)
    entries = []
    Dir.entries(path).each do |entry|
      next if entry == "." or entry == ".."
      mtime = File.mtime(path + "/" + entry).to_f
      entries << [ mtime, entry ]
    end
    entries.sort! { |x,y| x[0] <=> y[0] }
    output << "\r\n  #{entries.length} backups found (max #{ROTATE-1})."

The total number of backups found is compared to the value of ROTATE. If there are too many backups, the latest one(s) (first in the list) are removed.

    # Remove least recent entries if more than ROTATE available:
    while entries.length > ROTATE - 1
      entry = entries.shift
      cmd = "rm -R -f #{path}/#{entry[1]}"
      `#{cmd}`
      output << "\r\n  Removed #{path}/#{entry[1]}"
    end

Having cleaned up excess backups, the script now creates a fresh folder, naming it with the current date and time:

    # Create new folder for backup:
    subdir = Time.now.strftime("%Y%m%d-%H%M%S")
    Dir.mkdir path + "/" + subdir
    output << "\r\n  Created directory #{path}/#{subdir}"

If a website has a database defined in the configuration file, the script now calls mysqldump to create a backup of the database inside the newly created backup subdirectory. The backup is gzipped as well. Note that a full path to mysqldump must be provided, since cron, which we will use later to run our script at specific times, does not include a path to mysqldump in the shell that it runs in.

    # Dump database (if required)
    if website.has_key? "database"
      # Dump db
      cmd = "/usr/local/bin/mysqldump -u#{DBUSER} -p#{DBPASSWORD} #{website["database"]} | gzip > #{path}/#{subdir}/#{name}.sql.gz"
      `#{cmd}`
      output << "\r\n  Dumped database #{website["database"]} to #{path}/#{subdir}/#{name}.sql.gz"
    end

If a website has a path to files defined in the configuration file, the script now uses tar/gzip to create a tarball of the entire website file structure, recursing into subdirectories.

    # Dump code (if required)
    if website.has_key? "path"
      # Copy code
      `cd #{website["path"]}; tar -czf #{path}/#{subdir}/#{name}.tar.gz *`
      output << "\r\n  Created zipped tarball of code in #{path}/#{subdir}/code"
    end
  end

This completes the loop that backs up all the websites. We now end our rescue clause in order to catch any exception thrown by Ruby during this process. The exception text is appended to the running log (output) as well as written to standard output.

rescue StandardError => error
  output << "Error occurred: " + error
  puts "Error occurred: " + error
end

All that is left to do is to send the output off through email. This is easy to do (any one reason we’re using Ruby):

# Mail output:
Net::SMTP.start('127.0.0.1') do |smtp|
  output = "Subject: Webserver backup procedure\r\n" + output
  EMAILS.each do |email|
    smtp.send_message output, "alex@email.com", email
  end
end

Adding the script to cron

We can now add the script to the system’s crontab in order to run at regular times. We’ll write a small shell script that launches the script using the bash shell, to make sure that cron has access to a powerful shell to run in:

#/usr/local/bin/bash
/usr/local/bin/ruby /usr/home/alex/backup-script/backup.rb

The following entry is added to the system crontab (/etc/crontab). This will make sure that the script runs every day at 22:00.

# Run webserver backup script
00      22      *       *       *       root    /usr/home/alex/backup-script/backup.sh

SASS and CSScaffold

I think the concept that SASS brings to the table (or CSScaffold, for that matter) is one we’ve all had when we play with CSS and think, “Gee, I would be nice if you could use variables and constants here, and if you could duplicate less code.” And then we would think of splitting our CSS up into many little files, since they’re easier to organize by function, only to find that that wasn’t such a hot idea because a browser will have to make a new HTTP connection for each one to download it.

So here’s SASS/CSScaffold adding just those features that CSS was missing. But is it all good news? I’d say on the whole, yes, but here’s a few points:

SASS requires that you compile your stylesheets every time you update them. My typical development cycle is make a little change to CSS (one one monitor) and hit refresh in my browser (other monitor) to see if the change did what I wanted it to do. That would have to change: now I would need to compile my CSS before I hit refresh. Not insurmountable, but it’s one more thing I can and will forgot and then I’ll think, “Hey, now why didn’t that change do anything?” only to find out after some head-scratching that I forgot to compile.

CSScaffold doesn’t seem to have this problem: since it’s written in PHP, it’ll run every time the CSS is requested from the server. I’m sure the authors have built in some sort of caching, so it should be quick enough. That actually sounds handier to me than SASS does, merely because I don’t need to compile. So the question is then, is CSScaffold just as good, better, or worse? If it’s just as good, I’ll go with it instead of SASS!

But is what SASS/CSScaffold do really that new? Like I said at the start of this post, it’s an idea all of us have thought of… and implemented! It’s always been possible to produce CSS through PHP. You can put a link to a PHP file in your page’s header, have it output a text/css header and you’re good to go. That’ll allow you to use variables, like SASS, constants, like SASS, functions and mixins, like SASS, all at zero cost since you had PHP anyway. You’ll basically only need to write the fancy gradient functions that SASS adds.

In order to add caching, you could pull your CSS through Smarty, thus prettifying the syntax a bit (it never feels quite right having PHP produce actual HTML or CSS what with the separation of code and presentation, so using Smarty gives a fuzzy warm feeling of righteousness). You could even write some spiffy new functions for Smarty, thus creating your own Sassy Smarty. So why all the hullabaloo?

Well, for one thing… SASS does more than I ever implemented with a CSS/PHP/Smarty approach, so hats off for that. But I still don’t like the compilation requirement.

Dynamic CSS through PHP

When writing CSS,you will find yourself repeating information a lot, which is always a bad thing in programming. CSS 2 lacks constants, which would allow us to define a value once and refer to it many times. Instead, we are forced to repeat the actual value many times, making updating CSS a process that is prone to errors.

Also, in order to reduce the number of connections a client must make to the server, it’s necessary to place all CSS in a single file. But this may mean that you end up with a lot of possibly unrelated CSS in a single file, making it difficult to navigate while you’re developing. There are times when it’s simply handier to have lots of  small files instead of one big file, but it’s just not practical for download by your visitors.

These two problems can be resolved by loading your CSS through PHP. Instead of serving the CSS file directly, i.e.

<link rel="stylesheet" href="css/style.css" type="text/css" media="screen"/>

you can have the server load a PHP script that produces CSS like so:

<link rel="stylesheet" href="css/style.css.php" type="text/css" media="screen"/>

Note that this will only work if the scripts emits a text/css header:

<?php
  header("Content-type: text/css");
  ...
?>

Now your PHP script can define some constants that you simply insert into your CSS:

<?php
   header("Content-type: text/css");
   $mycolor = "#aaa";
?>
 
p {
  line-height: 1.1em;
  color: <?php echo $mycolor; ?>
}

Your script could also load various CSS files for processing and output the result in one go, solving the second problem we found. But we can do better still. You can have your PHP script use Smarty to produce the CSS, making the use of contants easier (and prettier):

<?php 
  header("Content-type: text/css"); 
  require_once "../smarty/Smarty.class.php";
  $smarty = new Smarty();
  $smarty->template_dir = "../smarty/templates";
  $smarty->compile_dir = "../smarty/templates_c";
  $smarty->cache_dir = "../smarty/cache";
  $smarty->config_dir = "../smarty/configs";
  $smarty->compile_check = true;
  $smarty->caching = 0;
  $smarty->display("file:style.css");
?>

The file style.css would be the main style sheet manifold; it could load other (sub-) stylesheets. For instance:

{assign var="defaultfont" value="normal 11px/1.2em Arial, sans-serif"}
{assign var="thinborder" value="solid 1px #aaa"}
{assign var="inputcolor" value="#666"}
{include file="sys/global-reset.css"}
{include file="sys/base.css"}
{include file="sys/loader.css"}
{include file="control/accordion.css"}
{include file="control/ajaxtable.css"}
{include file="control/button.css"}

The values that were assigned to defaultfont, thinborder and inputcolor can be used in the sub-stylesheets like so:

input
{
  border: {$thinborder};
  color: {$inputcolor};
}

FireFox 4 does not like script.aculo.us builder

After upgrading to FF4 I noticed that some of my JavaScript, which had been working perfectly fine, stopped working. I was able to isolate the problem to the use of the script.aculo.us Builder class to create a script element, like so:

var head = $$("head")[0];
js = Builder.node("script", { type: "text/javascript", src: path });
js.onreadystatechange = function() { if (js.readyState == 'loaded'
  || js.readyState == 'complete') js.onload(); };
js.onload = function() { console.log("loaded!"); };
head.insert(js);

However, the onload event would never be triggered. In fact, Firebug indicates that the JavaScript file I’m trying to load is never actually loaded from the server. So it’s back to basics without using script.aculo.us’s Builder:

var head = $$("head")[0];
var js = document.createElement('script');
js.type = 'text/javascript';
js.onreadystatechange = function() { if (js.readyState == 'loaded'
  || js.readyState == 'complete') js.onload(); };
js.onload = function() { console.log("loaded"); };
js.src = path;
head.appendChild(js);

And guess what: this works. The file is loaded. Now why does this happen? The new script element is in fact added to the DOM; I can see that in Firebug. But it never loads the JavaScript from the server.

Playing around with script.aculo.us’s builder.js shows that the script tag cannot be created through innerHTML but must be created through document.createElement instead. I don’t know why script.aculo.us tries the innerHTML approach first, but it does – and it works. It just doesn’t load the javascript file. If I deliberately make the innerHTML approach fail, it falls back to document.createElement, which works.

This is not the whole story, though. When adding attributes to the newly created element, builder.js again tries to use innerHTML before using document.create. And again, skipping innerHTML to make it fall back to document.create works.

The reason innerHTML is used can be found here, according to the source, but I could not access this URL at the time of this writing.

What to do about PHP 5.3′s timezone compaints

If you’ve just upgraded to PHP 5.3, your scripts will probably generate a bunch of errors in this vein:

Warning: date(): It is not safe to rely on the system's timezone settings.
You are *required* to use the date.timezone setting or the
date_default_timezone_set() function. In case you used any of those methods
and you are still getting this warning, you most likely misspelled the
timezone identifier. We selected 'Europe/Helsinki' for '2.0/no DST' instead.

Obviously, the solution is to use the date_default_timezone_set() function, but that means you need to change scripts that ran perfectly well and warning-free previously.

There’s another approach. You can set the default time zone in PHP’s configuration file so that it won’t bother you again (at least on your server). To do so, fine the date.timezone setting in php.ini and change it thusly:

date.timezone = Africa/Maputo

Now the warnings will be gone.

Creating a Forward Proxy with WEBrick

Building a simple forward proxy in Ruby with WEBRick requires very little code. Here is a small sample that forwards all requests but for the example.com domain, which it blocks.

require 'webrick/httpproxy'
 
def handle_request(req, res)
  puts "[REQUEST] " + req.request_line
  if req.host == "example.com" || req.host == "www.example.com"
    res.header['content-type'] = 'text/html'
    res.header.delete('content-encoding')
    res.body = "Access is denied."
  end
end
 
if $0 == __FILE__ then
  server = WEBrick::HTTPProxyServer.new(
    :Port => 8123,
    :AccessLog => [],
    :ProxyContentHandler => method(:handle_request))
  trap "INT" do server.shutdown end
  server.start
end

The interesting bit is the handle_request method. WEBRick provides us with the request and response instance for each request, so that we can check what’s being requested and block certain URLs. Since the response is also already available, we can even perform content filtering.

Get local machine’s MAC address in C#

Here’s a way to get the local machine’s MAC address in C#. Note that there may be various MAC addresses (Ethernet cards, local loopback devices, hooked up 3G devices etc.), so we try to find only the Ethernet MAC address:

static string GetMacAddress()
{
  string macAddresses = "";
  foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
  {
    // Only consider Ethernet network interfaces, thereby ignoring any
    // loopback devices etc.
    if (nic.NetworkInterfaceType != NetworkInterfaceType.Ethernet) continue;
    if (nic.OperationalStatus == OperationalStatus.Up)
    {
      macAddresses += nic.GetPhysicalAddress().ToString();
      break;
    }
  }
  return macAddresses;
}

Doctor Who – Robot

With the newly regenerated Doctor behaving violently, Brigadier Lethbridge-Stewart and UNIT have to contend with the theft of the plans for the new disintegrator gun by what seems to be a mechanical monster. The theft is the beginning of a plot to hold the world to nuclear ransom. The culprits are certain members of staff who work at the Scientific Reform Society who have stolen the beast and taught it to kill. This Doctor Who episode aired in 1974/1975.

Part 1

Section 1.1

Section 1.2

Section 1.3

Part 2

Section 2.1

Section 2.2

Section 2.3

Part 3

Section 3.1

Section 3.2

Section 3.3

Part 4

Section 4.1

Missing, unfortunately.

Section 4.2

Section 4.3