Computers Gadgets Linux Mac Windows

Filename encoding problems on Dlink DNS-323

I have had my Dlink NAS DNS-323 since early 2007. It has mostly served me well. Over the months I have put more and more files on it so that it now holds about 350GB of data. Out of fear of losing precious data I have not updated the firmware so I am still on 1.03 from May 2007.

I mounted a shared folder on the DNS-323 from a Ubuntu client and noticed that the Swedish characters were all messed up. First I thought the error was related to how I mounted the drive from Linux, but then I found out that the issue is with the DNS-323 itself and the fact that it uses a non-Unicode character set for the filenames. This should be solvable with the iocharset and the codepage parameters to the mount command in Linux but I couldn’t get it to work.

Later firmwares are said to fix the problem – but only if the drives are totally wiped. I got myself a USB drive sufficiently large to hold everything and copied all the data over using rsync so now I am just about ready to upgrade the firmware and reformat the drives and use some of the plugins on But more on that some other time.

Before I wipe the disks I wanted to make sure that I could rename all the files using Unicode but with some 50,000 files I didn’t want to do it manually. The Linux command iconv can convert between encodings but it works on a file level and I wanted something that only touches the filenames, not the contents of the files.

I found the Perl command convmv which is available through the standard Ubuntu repositories. Just type “apt-get install convmv”. It does the same as iconv but on filename level. Precisely what I needed. I then typed:

#/mnt/wd640gb# convmv -f cp850 -t utf8 -r .

This command shows how files would be renamed, switching from codepage CP850 (the default or DNS-323) to UTF8. Once you are happy with the suggestions, just issue the command again but with the extra switch –notest to actually rename the files.

My only issue now is that convmv only works on filenames, not directories. But at least I have reduced by problem by a factor 30 or something. The directories I can do manually.

Computers Gadgets

Thought about writing iPhone apps – now less sure

I have been thinking about doing some development for iPhone and have come up with some really cool application ideas that I would like to turn into real applications. However, after reading on various blogs I have realised that the limitations in the development environment on the iPhone mean that those applications are not possible; at least not in a way that would allow me to distribute them through AppStore. That, of course, means that they are dead in the water since the vast majority of iPhone users will only use the AppStore.

What is holding me back? Two words – background processes.

The sad story is that third-party applications can not be made to stay running in the background when the user switches task, takes a call or when the phone goes into sleep mode. Of course, this limitation does not apply to Apple’s own applications. The argument that Apple is pushing is that they need to ensure that background processes don’t slow down the phone or drain the battery. This may seem valid but personally I think it should be left for the end user to decide. It could even be done so that the AppStore clearly states how long the application may be running in the background before it is installed – after which time the OS shuts it down.

I hope this is fully addressed by Apple soon – and no, the promised notification service is nowhere near solving my problem. Otherwise I may go back to developing my applications for Symbian or Windows Mobile – both of which I have written applications for in the past.

Computers Linux

Adding roles to Ubuntu Server

I have set up a number of server based on the past four or five versions of Ubuntu Server. Every time I face the dialog where one can pick what additional software to install, I just select OpenSSH so that I can make the server headless and manage it remotely. I then install each individual package using apt-get until the system works as I wish.

Ubuntu 8.10 Server - additional software roles

First, I thought that the alternatives for software could be installed as meta packages using apt-get but I never managed to find any such meta packages in the package list on – or by searching the repositories with apt-cache.

I just now learned that the command tasksel brings up a menu similar (but extended) to the one shown during the installation. It is also possible to list which deb packages an individual task would install. A simple method would for instance be to run ‘tasksel install dns-server’ which would lead to the exact same result as if one had picked the DNS server from the beginning.

Computers Linux

Keeping track of installed apps, part 2

In an earlier post I wrote how to output a list the currently installed applications under Debian (and distributions based upon it). This will now be extended into a script that can be run each hour to record changes to the installed applications. Now, it should be said from the beginning that this information may already be stored in the file /var/log/apt/term.log but it can be a challenge to follow what it happening.

The following script stores a snapshot of the installed applications and then makes a diff against that on a period basis (e.g. by running it as an hourly cron job). If there is a difference, the changes are saved to a time stamped file and a new snapshot is taken. All files are placed in the same log directory as apt normally uses (i.e. /var/log/apt). The downside of this method is that changes will be recorded with a granularity of an hour but usually that is not an issue as the reason for writing this was to keep an automated record of changes to the system.

if [ ! -e $installed ]; then
  echo "Creating initial file"
  dpkg-query -W -f='${Package}\n' > $installed
  cp $installed $folder'initial'
# Compare package list against current
dpkg-query -W -f='${Package}\n' | diff $installed - \
  | grep -e '^[(<|>)]' > /dev/null
if [ $? -eq 0 ]; then
  # The set of installed packages has changed. Save the delta to a
  # file and save the new snapshot
  filename=$folder`date +%Y-%m-%d_%H-%M-%S`
  dpkg-query -W -f='${Package}\n' | diff $installed - \
    | grep -e '^[(<|>)]' > $filename
  dpkg-query -W -f='${Package}\n' > $installed
exit 0


Simple localisation of Rails validation messages

Rails scaffolding can be good to get up running quickly but it can also be a problem. This is for instance true when it comes to localising the error messages presented by Rails (e.g. “X errors prohibited this <object> from being saved”). The issue is caused by two things:

  1. Rails includes English default message headers for the error box without being apparent how to change them.
  2. Each individual error is prefixed by the capitalised field name. Regardless of GUI language these will probably be in English.

The first of these issues can easily be solved by replacing the default <%= f.error_messages %> with something like:

<%= error_messages_for :item,
:header_message => "Försök igen",
:message => "Några av värdena du har angivit är inte giltiga:" %>

The second is a little harder but can be solved by realising that Rails calls the method human_attribute_name on the model object, passing the column name. While it would be possible to do a switch statement or a lookup array to translate the column name, I have found it easier to just return an empty string and to provide the exact error message as part of the validation instead.

validates_presence_of :name, "Namnet måste anges"

def self.human_attribute_name(attr)
return ""


Boolean portability under Rails

Booleans should be so simple. They can only have two values. As a former colleague used to say – How hard can it be? With all the variants of “0/1”, “Y/N”, “t/f” the answer seems to be – Apparently quite so.

Rails 2.0 switched the default database engine to sqlite3 and this has now caused me two issues. The first I wrote about some time back. The last one I just stumbled upon was related to booleans.

This works in MySQL:

@guests = Guest.find(:all, :conditions => 'accept = 1')

But it fails in sqlite3 since Rails stores booleans as ‘t’ or ‘f’ on that database engine. The portable way to write the condition in Rails is to make Rails itself select the proper value depending on the underlying database by writing it like this:

@guests = Guest.find(:all, :conditions => ['accept = ?', true])

Computers Linux

Keeping track of installed apps under Debian

I am setting up my new server with Ubuntu 8.10. This time, I am planning to keep track on all the software I install on it so that I might restore it in the future. Thankfully, with the Debian package manager this is a simple task.

The following command creates a text file with all the installed applications on the system:

dpkg-query -W -f='${Package\n}' > installed-apps

The file will put one one package name on a line and end it with a line break, saving the output to the file installed-apps. By changing the \n at the end into a space it is possible to get a single long string with all the package names.

After a while you may want to know which packages have been installed since the initial operating system installation. There are no doubt many ways of doing this but the easiest I have come up with is to run the same command as above, but save the output to another file, and then to run ‘diff’ on those two files. Note that this requires that the output from the dpkg-query command above was using line breaks to separate packages.

%d bloggers like this: