Posts Tagged computing

Recover crashed Windows machine

So, the inevitable finally happened to our old Windows HP Laptop, it crashed… We have been waiting for it to happen, it is, after all OLD, but I must say it has done a really good job hanging in there this long.

Yep, we have been making backups, but not as regularly as with the Mac and the excellent Time Machine of the simple reason that it is more of a hassle doing it under windows.

So, although most files where backuped there where still some missing. So what to do? The machine didn’t even boot so no way of getting in and copy files to a USB stick. Considered trying a repair with the Windows XP CD, but I don’t really trust them not to do stupid things so discounted that option.

Having done this stuff before I remember beeing really happy with the System Rescue CD (SRCD), I consider it to be, by far, the best in the category! This is one excellent package! Its a Linux Live CD with all the stuff you’ll ever need, including a really good website. So downloaded that and burnt it to a CD and stuffed it into the old HP.

Linux booted with no problem, next step is to find the hard drive:
fsarchiver probe simple
showed it to be: /dev/hda1 with an NTFS filesystem, this used to be an issue, but not anymore. So mounted the hard drive with: ntfs-3g -o ro /dev/hda1 /mnt/windows The /mnt/windows exists from the start so no need to create that directory, the “-o ro” option mounts it read only so we can’t misstakenly remove or change anything on the drive, that feels good in these situations.

Ok, so the machine is up and running and we have access to all the files on it, good. My plan now was to backup the files and then try to reinstall Windows. So how to backup the files? Initially I figured I’d copy them over the network using sftp which was the suggested approach on the System Rescue CD website. So I got the network up and running by connecting a network cable and issuing dhclient eth0. No problem. ifconfig showed that the network was up and running and the ip-address I got. OpenSSH is already up and running on the crashed machine so I started cyberduck on my Mac and used sftp to connect to the crashed machine.

I then started copying the files I wanted, but unfortunately it would take about 13 hours. I didn’t really file like waiting that long, so in parallel I started looking for a USB drive. I found an old one with 220 GB free and connected that to the crashed machine. USB is of course supported by SRCD, so again, I ran fsarchiver probe simple to find the USB drive, it showed up as /dev/sda1 with a vfat filesystem on it.

So mounted that one with mount -t vfat /dev/sda1 /mnt/backup again the /mnt/backup already existed so no need to create that either.

Now I got a small issue, since normal users don’t really know (and shouldn’t need to know either) alot about filesystems they are blissfully unaware of the issues that can occur when you create files with the swedish characters “å”, “ä”, “ö” and the like in the filenames so they tend to do just that. Now when I tried to copy files and directories with the above mentioned swedish characters (“åäö”) in them I got some error along the lines of “Could not create file, Illegal argument ” and I suspected that the “åäö”‘s were the issue. It turns out that I needed to unmount the “/mnt/backup” and mount it with mount -t vfat -o iocharset=utf8 /dev/sda1 /mnt/backup instead, then it worked fine, I’m not sure why this was since it says that “iso8859-1” is the default which certainly is capable of representing “åäö”, but maybe it was due to how the USB drive had beed formatted or something.

Ok, so now we are capable of handling “åäö”, so it is time to start copying the files. Next question, what to use to copy the files…? This might sound like a silly question but anyone that has tried to copy large amount of files with windows explorer knows what kinds of problems you can have. For example a file somewhere in the middle of the copy process is broken or some other error occurs and the file copying stops dead in its track somewhere in the middle of everything and you have no idea what is copied or not and you basically have to try to find the offending file, remove it and start over, and again… and again… 😛

Now, there are a couple of options on Linux:

cp – The ordinary copy program
dd –
tar-
dar-
rsync- A very competent file sync program from the Samba team

I ended up using rsync mainly since “cp” doesn’t show any progress, tar, dar creates an archive which I didn’t really want, other than that I have very high confidence that rsync will “do the right thing”.

To use rsync to just do a simple copy and show progress I use the following command: rsync -avh --progress /mnt/windows/Documents\ and\ Settings/Tess ./ (I had already cd’d to /mnt/backup/). As you can see I copied the “Documents and Settings/” folder, but I don’t really know if it contains everything that is needed, I hope that most applications save their data in the “Application Data” folder under that directory. Of specific interest was Firefox Bookmarks and Thunderbird emails and adressbook.

When all files where copied with rsync (40 GB) the sftp had managed to copy around 17% (6GB). Ok, so what’s next?

If I need to reinstall Windows, “My Documents” might be whiped, don’t want that, so while still running SRCD I moved everything in the “Documents and Settings/<username>/Mina Document/” folder to “c:/bak”, which is /mnt/windows/bak on the SRCD (the “bak” folder was not there so I created that first with mkdir /mnt/windows/bak.

Ok, after having secured the files I feel more confident starting to experiment with the machine. I then booted from a Windows XP Professional CD and chose the “Repair using the Recovery Console”. Then I tested the boot configuration with the command bootcfg /list it turns out that it is broken. “Dir” did not work either probably because the “Recovery Console” didn’t manage to find any “Windows Installation” to “log in” to. None of the “/rebuild”, “/scan”, “/add” options worked, so at this stage I wanted to delete the boot.ini file. I first had to make it deletable at all using the commands:

attrib -H C:\boot.ini
attrib -R C:\boot.ini
attrib -S C:\boot.ini

Now was able to delete the boot.ini, my first and so far only mistake, I should of course just have moved it to some other filename.

At this point I tried to boot the system in safe mode. And this time it actually managed to boot it using “Safe mode”, the first time since the crash. After rebooting it can now boot normally even though it prints a message that it cant find a boot and informs that it uses “c:\..something..windows..something”, pretty remarkable…

The final step was using the Windows XP (pro) CD to create a new boot.ini file. After this and a reboot it was again back to normal… let’s see how long it will make it!

Tags: , , , , , , ,

Passing Perl regexes as arguments

I often find myself wanting to pass a regex as and argument to some function or another with the initial idea of passing the regex either as a string or a compiled regex (see the qr operator) and I invariably end up with problems. One example is for instance when I pass it as a string I mess up quoting ? / * . etc..

Another example of problems with this approach is the following, imagine that you have written a function to take a regex and you imagine searching all cells in an Excel sheet for cells matching this regex, as follows:

sub find_in_worksheet {
  my $regex = shift;
  my $workbook = shift;
  my $worksheet_name = shift;
  my $worksheet  = $workbook->worksheet($worksheet_name);

  my ( $row_min, $row_max ) = $worksheet->row_range();
  my ( $col_min, $col_max ) = $worksheet->col_range();

  for my $row ( $row_min .. $row_max ) {
    for my $col ( $col_min .. $col_max ) {

      my $cell = $worksheet->get_cell( $row, $col );
      next unless $cell;

      if( $cell->unformatted() =~ $regex ) {
	return ($row, $col);
      }
    }
  }
  return undef;
}

That works fine, until inevetably you want the cell contents NOT to match the regex… *sigh*, what now…?
Well it turns out that a much more fruitful (and a more general) approach is as follows:

sub find_in_worksheet {
  my $predicate = shift;
  my $workbook = shift;
  my $worksheet_name = shift;
  my $worksheet  = $workbook->worksheet($worksheet_name);

  my ( $row_min, $row_max ) = $worksheet->row_range();
  my ( $col_min, $col_max ) = $worksheet->col_range();

  for my $row ( $row_min .. $row_max ) {
    for my $col ( $col_min .. $col_max ) {

      my $cell = $worksheet->get_cell( $row, $col );
      next unless $cell;

      if( $predicate->($cell->unformatted()) ) {
	return ($row, $col);
      }
    }
  }
  return undef;
}

You would call this functions as follows:

my ($row, $col) = find_in_worksheet( sub { $_[0] =~ /regex to match cell contents/ } , $workbook, $worksheetname);

See the “sub { $_[0] =~ /regex to match cell contents/ }” part? There’s the magic. Now if you later on figure out that you want the cell contents NOT to match, you just call the method thusly:

my ($row, $col) = find_in_worksheet( sub { $_[0] !~ /regex to match cell contents/ } , $workbook, $worksheetname);

Volá!

Now you can even change the code for the predicate to something completely different, maybe not even involving regexes… for instance:

my ($row, $col) = find_in_worksheet( sub { $_[0] == 10 } , $workbook, $worksheetname);

This is just a small example of the power of using “sub’s” as arguments to functions and the very nice syntax in Perl for achieveing it. It also carries the benefit of giving you compile time checking of your regex! (Yes, Perl is a compiled language!)

Tags: , ,

Perl date difference

As a followup on date calculations, here’s small one to calculate the number of days between two dates, the same disclamer as for the previous post applies, so, without further ado, here goes:

# Given two dates, calculate the number of days between them
sub diff_dates {
  my ($sec1,$min1,$hour1,$mday1,$mon1,$year1) = @_[0..5];
  my ($sec2,$min2,$hour2,$mday2,$mon2,$year2) = @_[6..11];
  my $time1 = timegm($sec1,$min1,$hour1,$mday1,$mon1,$year1);
  my $time2 = timegm($sec2,$min2,$hour2,$mday2,$mon2,$year2);
  my $diff_seconds = $time1 - $time2;
  my $daydiff = $diff_seconds / 24 / 3600;

  return int( $daydiff );
}

Tags: , ,

Perl calculate X days forward or backwards

Ok, here’s a small snippet for calculating a new date given a date and the numer of days forward or backwards from that date without having to include Date::Time or some other big date handling lib which is not part of the standard perl distro. It wouldn’t surprise me if there are some subtile problems with this way of doing it, maybe leap years or something will mess it up, but I have found that it works fine for the most for me at least YMMV!

The format of the input is of course according to timegm.

# Given a date and the number of days forward or backwards (negative) calculate that date
sub calc_date {
  my ($sec,$min,$hour,$mday,$mon,$year) = @_[0..5];
  my $diff_days = $_[6];
  my $time = timegm($sec,$min,$hour,$mday,$mon,$year);
  my $diff_seconds = $diff_days * 24 * 3600;
  my $end_time = $time + $diff_seconds;

  return localtime($end_time);
}

Tags: , ,

Firefox download manager

Just discovered the other day that the Firefox “Downloads” (“Filhämtaren”) thingy is really a full fledged “Download Manager”, i.e you can drag-and-drop url’s on it and it will download them for you. Now, maybe it is only me in the whole world that didn’t know that, but from time to time I have been looking for a simple download manager to solve this particular problem for me, without realizing I had one under my nose the whole time. 🙂

Tags: , ,

Steve’s a funny guy…

“In the OS business, it’s generally advisable to get it right and stay right.” -Steve Ballmer

Tags: , , ,

Perl member

I find myself writing perl member functions since there is no one built in…

sub member {
  my $elm = shift;
  my @lst = @_;

  for( my $i=0; $i < @lst; $i++) {
    return 1 if lc($elm) eq lc($lst[$i]);
  }

  return 0;
}

I like this one better... it reads better I think, but sadly I believe "foreach" will disappear in Perl 6 is it not?

sub member {
  my $elm = shift;
  my @lst = @_;

  foreach my $item (@lst) {
    return 1 if lc($elm) eq lc($item);
  }

  return 0;
}

Update: Now, if you use "use 5.010;" (which I strongly recommend that you do!) (of course running Perl 5.10 or higher) this can be done with the very cool "smart match" operator "~~".

$scalar ~~ @list; # Member with new smart match operator in Perl 5.10 or higher.

Tags: , ,