Archive for the ‘Tips and Tricks’ Category
On String.intern()
Where the author realizes the significance of the String.intern() method
I might have hinted about in in my previous post on the subject of strings in Java, yet I did not realize the significance of String.intern() method. The following code sample demonstrates the behavior of the String.intern() method, similar to what I demonstrated in the post.
Bits on info on Java strings
Update: I don’t keep IRC logs and thus cited the wrong guy. Sorry Vince.
On this blog entry I will take on an assertion stated by systemfault. He declared on the #programmeur IRC channel on Freenode that:
<systemfault> String foo = new String("lol"); est pareil que String foo = "lol";
<systemfault> Quand le compilo voit: String foo = "lol";
quand il compile, il va vraiment faire String foo = new String("lol");
Which in english means that:
String s = "hello";
is syntaxic sugar for:
String s = new String("hello");
Automatically set terminal title in X
I’ve been using the Mercurial Shell Prompt hack for a while until I got annoyed at it. It caused a Python interpeter to start at every prompt, which is expansize especially if your system is already under strain.
Good safeguards
In my last post I’ve shown that some people are annoyed at the fact that they can no longer erase their root directory simply by typing rm -rf /. I’m happy that this possibility is removed. I’m not scared that means Linux is being dumbed down. There are already some safeguards in Linux and nobody is complaining about them because they guard even seasoned users to do things that are dangerous or silly.
Database design tools
I have been looking for database design application on Linux for a while. I even recently started searching for something compatible with Linux through Wine too. The Ubuntu and Debian package database is devoid of anything useful beyond Dia, which I hate for reasons that do not belong to this rant-free blog. There are some tools around for MySQL but it is not the SGDB I’m the most found of. I’m particularily interested in PostgreSQL
It was a revelation to me when I found 2 free (as in beer) design application on the PostgreSQL Wiki. I was even more surprised that both loaded and seemed to work out of the box in just about 30 seconds after their download. I’m not sure about the licensing terms but they certainly look safe to use for FOSS development.
I have not tried either extensively. I just believe both application needs to be linked since they seem to be hard to find. I might review one of them here some day.
Open System Architect
This has an impressive number of button, menus and and various gadgets. It is in fact pretty intimidating at first. It has the feel of a professionally developed application.
It is open-source but sadly does not seem to be actively maintained. This is something I fear I might discover after some prolongued use.
SQLPower Power*Architect
This simple looking application is in Java, which is a showstopper for some people. A good Java application isn’t something that stops me, but I admit Java applications sometimes have problem at setup time if they are not properly packaged.
This application doesn’t have that problem. It run fine when started with a canonical java -jar file.jar command.
The application does look funky a bit on my computer. The fonts are serif and heavily anti-aliased. It look clunky a bit. The screenshots on the site don’t have that problem. It might be a quirk related to my Java distribution or my some font handling problem on my Linux distribution. I need to investigate. That aside, the GUI is simple and no as scary as Open System Architect. If I could fix the font glitch, it will be sweet.
This is also open source. They have a Google Code project.
Annoying non-breakable spaces in Bash/Zsh
This is an annoyance I found got around to solve. In Konsole, with a basic X configuration, when you type AltGr Space, you get a non-breakable space. It might happen in other things X terminal/shell combo, or the both of them might not matter at all.
If you are an heavy shell user, you might hit the AltGr Space combo by accident. This wouldn’t be bad if the shell made it somehow obvious that what you entered in a non-breakable space. The fact is that it doesn’t and it’s then totally impossible to distinguish a regular space with a non-breakable space after it was typed in the shell.
cd $HOME zsh: no such file or directory: cd /home/fdgonthier
After typing such a command quickly, I was often left wondering what the hell was wrong with my command, since, as far as I could see, it was syntaxically correct.
The problem is that since there is a non-breakable space between cd and $HOME, Zsh wants to execute the whole command as a single command. Since I didn’t know I could even type non-breakable space in X, I checked what the hell the shell was doing by using strace. strace is my favorite diagnosis tool for any kind of problems in Linux. Programs don’t lie when they are spied with strace. The problem is obvious:
execve("cd\302\240/home/fdgonthier", ["cd\302\240/home/fdgonthier"], [/* 30 vars */]) = -1 ENOENT (No such file or directory)
It took me a while but I’ve found that \302\240 is the Unicode sequence for non-breakable space. Once I have found that, I Google search lead me to Launchpad bug 218637.
On this page, you see that you can disable non-breakable space using a xkb option in xorg.conf. Simply add the following in the InputDevice section related to your keyboard.
... Option "XkbOptions" "nbsp:none" ...
or use
setxkbmap -option "nbsp:none"
in a console, your favorite initialization file, or elsewhere.
Partial Debian Mirrors
The following is a description of the technique I’ve used to create partial Debian mirrors. I have damn near mastered that technique that is not immediately obvious if you don’t know the tool. Nothing there is black magic though, as you will see.
The following example will use the programs called reprepro and
germinate. Both are available on several versions of Ubuntu, Debian Lenny and Debian Sid. I’m not going to explain either in great details. They are well documented in the case of reprepro, and there is enough documentation in germinate.
Required steps
This configuration is necessary in both case.
reprepro is by far my favorite Debian repository manager. It has a steep learning curve at first but once you get past the initial configuration and the first few commands you’ll see it cannot really be made easier.
The first step is to create the directory that will contain the mirror. In that directory create a directory called conf.
In that directory, edit a file named distribution in your favorite editor At this point I usually pop-open the man page for reprepro. Write the following in that file:
Codename: etch Architectures: amd64 source Description: Debian Etch (required package only) Components: main Update: debian-etch-update
That’s all we need in that file right now. This describes what distribution this mirror will include. You can have several distributions in a mirror. Most field are self explanatory except perhaps the Updates field which will explain below.
Partial mirror, using reprepro only
The next step explain how to create a partial mirror using just reprepro. reprepro is powerful enough to select a subset of a whole package archive.
Name: debian-etch-update Method: http://gulus.usherbrooke.ca/debian Components: main Architectures: amd64 source FilterFormula: Priority (==required)
The content above is the content of your conf/updates file. It includes all the rules needed to update the distributions configured in the distributions file. The distribution etch we created in is linked to its respective update rule by the Update configuration field.
The key to partial mirroring in this case is the FilterFormula field, which selects just the Debian package in required in a very basic installation. There is also a FilterList field which can select just the set of package you list. This is the basis of the next section.
To start mirroring, go in the mirror directory and do:
reprepro -V update etch
and reprepro will start downloading packages. The -V argument activates verbose mode. After successfully creating the archive, you can reuse the same command to update your mirror.
Germinate and reprepro
germinate is an oddball program which, given a set of package, will recursively find all packages a set of package depend on.
As a simple example, if you tell germinate to germinate the dependencies from the package python, it will list libssl, libreadline and will eventually find libc6. It can also fetch build dependencies if you want everything needed to build the package you want.
We will use germinate to create a Debian repository that mirrors just the set of package the python2.5 package depends on.
germinate is a very specialised tool which sees little use outside making new Debian and Ubuntu derivative distributions. It’s very powerful but a bit confusing. I’ll give the basic recipe you need to know to accomplish our current goal. If there is enough or any interest, I give more use cases for germinate.
-
Create directories called
seedsandgerminate. The former will include the files we give as input togerminate. The later will includegerminate‘s output. -
In the
seedsdirectory, create files calledblacklist,required,STRUCTUREandsupported. Theblacklistandrequiredwill stay empty. -
In the
STRUCTUREfile, put the following:required: supported:
-
In the
requiredfile, put the following:* python2.5
Don’t forget the space at the start of the line.
-
You can then run
germinate.(MIRROR=http://gulus.usherbrooke.ca/debian cd germinate && \ germinate -v \ -m $MIRROR \ -d etch \ -c main \ -s seeds \ -S file:///tmp/temp-distro \ --no-rdepends)where you can replace
/tmp/temp-distrowith the base directory of your mirror.
You should see a bunch of files created in the germinate directory. The only file we are interested in is germinate/required.
germinate output is meant to be human-readable so we need a bit of parsing to extract the required information.
The following Bash magic does the trick:
for pkg in $(cat germinate/required \ | tail -n +3 \ | head -n -2 \ | cut -d '|' -f 1); do\ echo $pkg install; \ done > mirror.packages
The resulting mirror.package is now suitable to act as a filter for reprepro.
Replace the FilterFormula line in conf/updates by:
FilterList: purge ../mirror.packages
purge tells reprepro not to do anything for packages not in the list.
Then run:
reprepro -V update etch
to create your mirror.
Superuser-edit in Emacs
I’m a big fan of GNU Emacs. It’s a very good programming editor but tends to be much more then that once you start digging into its feature and extensions people have spent a lot of time to write.
This makes Emacs quite unique in the world of generic text editor. Emacs users very often have their editor fired and ready to go. It might be because they always have a file to edit; programmers do that. It might also be because they use some Emacs extensions to fill-in for other programs like their IRC or mail client, like I do.
For me Emacs is always on. I can use it for most of my editing tasks by using the remote controller gnuclient.
What I could not use it for, and which annoyed me, was that I couldn’t edit files owned by root inside Emacs opened as my current use.
Luckily, somebody on Planet Emacsen lead me to discover you can use TRAMP to edit files using the ‘sudo’ method. TRAMP enables you to access remote files from inside Emacs, like on an FTP or SFTP server, for
instance. The ‘sudo’ access method, in that case, is just a twist of the concept, allowing you to edit files as another user on your own system.
TRAMP comes standard with Emacs 22. I personnaly use Emacs 23.something on all the computers I use, so I have not personally tested it on Emacs 22 but I have the feeling it should work fine.
To open a file as root, for example, do:
M-x find-file, /sudo::/etc/motd
And, TA-DA, it might work out of the box like that!
Yes, might. On my systems, I prefer to use ZSH. The prompt I use, and a ZSH-specific feature, conflict with TRAMP default configuration. TRAMP loads a shell with sudo in background and needs to see the shell prompt to make sure its able to send editing commands. So to be able to use TRAMP, I had to change the prompt for Emacs, or make TRAMP recognize my active prompt.
Changing the prompt is easier than it look, and can be made into a special-case for Emacs. TRAMP set the TERM environment variable to ‘dumb’ when it loads the shell. Since the dumb terminal mode is not
something I use or want to use, I just did something like this in root’s .zshrc:
if [ $TERM = "dumb" ]; then ... unsetopt zle PS1='$ ' fi
‘$’ being the cannonical UNIX shell prompt. The unsetopt zle disables the feature that might conflict with ZSH.
Receiving Mail Directly
This is for the record. As I write this entry, I no longer use this technique.
For no particular reason, I’ve always wanted to receive emails directly on my computer through SMTP. For readers not familiar with how SMTP works, let’s just say that SMTP is a postman able to deliver your emails to the post-office, but that is also able to deliver emails directly to your door.
People have got used to get their emails through a Post-Officile Protocol (POP3). You can also use IMAP for the same purpose but it doesn’t really fit my metaphor so I will not talk about it. The SMTP postman can also knock to your door (port 25) and deposit the mail right at your computer if you let the rest of the Internet know you want to receive your mail that way (through MX records).
Using a cheap ISP with a dynamic IP address is like changing the door address every so often. Nobody out in the Internet really knows where you live at any point. You can mitigate that by using an handy dynamic DNS service, which I do, but it’s not like having a permanent home with a domain that everyone knows about.
Also, Sympatico, my ISP, blocks port 25. That means nobody will every be able to knock at my door. I can’t let the whole Internet know that I should receive mail at port 10025 for example.
There are some service that can receive mail for you then route it to the correct port. The prices vary with the features provided by the service. I have not seriously considered paying for something that I can find no practical advantages to.
Nonetheless, I still wanted to receive mail from the Internet directly on my small network, without needing to switch to another ISP.
I successfully received mails from the wide Internet yesterday.
What you need is:
- An Email Service Provider that lets you use procmail and a dumb SMTP sender.
- A SMTP server listening on an alternative port that is not blocked by your ISP.
- A simple procmail hack.
The provider
I use HCOOP. It it my Hosting Provider, and Email Provider, and Pretty-Much-Everything Provider. It’s quite cheap and very flexible. It doesn’t have any big uptime guarantees and expects a below average knownledge of Apache and DNS configuration but I can deal with that. In fact, I love to deal with that.
So the provider was not a problem for me. Other hosting solutions might not provide you with the possibility of using procmail at all.
The SMTP server
I use Postfix on the receiving computer. It defaults to port 25 of course. All I needed to do in order to make use another port was to edit the /etc/postfix/master.cf file, find the line describing the SMTP service, and change the service the port number you want Postfix to listen on for SMTP requests.
The dumb SMTP server
Some places call that a nullmailer. This is a SMTP client that is just meant to send a mail to an SMTP host.
My provider already had ssmtp installed. I also looked at esmtp for inspirations. There are probably several variants of such software out in the Internet.
The procmail hack
I did not find this verbatim on Internet, but I’m pretty sure you can find several variants of that through Google.
:0wc
| formail -k -X "From:" -X "Subject:" -X "To:" -n 3 -s \
/usr/sbin/ssmtp -Cssmtp.conf your@email.com
This rule basically tell procmail to send all mail through a pipe starting with the formail program. formail is used to format a mail message before further processing. The switch I pass it tells it to remove all headers but From and Subject from the mail before calling ssmtp. ssmtp.conf is the configuration file for ssmtp. I won’t paste it here since it’s quite trivial and anybody interested in using it will figure out what to write there from the manual page.
This is probably not an exhaustive shopping list of how I got it done, but without those basic blocks, you wont get it done.
Once I got that working. An avanlanche of problems and potential problems made me realize that this was way much troubles that it was worth.
- It meant that I needed to keep the receiving computer running at all time, and I don’t have the infrastructure for that. I have no UPS and no backup system
- That computer as limited capacity so I could not have used it has an store for emails, at least, not for every long. So I needed to send the mail to a computer that is more capable inside the network. That means I need to learn to configure Postfix, something I would certainly enjoy but that I don’t think is worth spending time on.
- Finally, the the formail command line I describe above is probably incorrect since the email I was receiving were partially munged, in various ways.
In short, such acrobatics with emails was too much trouble for me. It doesn’t mean I could not have made it work, but that the energy needed to make it work correctly was too much for the value of the end-result I was after. I write this entry as a statement to say that I will spend time trying working on this again, unless I find a reason better than “It’d be cool!”.
Mercurial shell prompt, followup
I have already found a solution for the problem I stated in my last post. I was able to make a shorty Python script that get the information out of the Mercurial repository using Mercurial classes.
It was more simple than I expected. If I manage to clean that up, it would probably be an useful Mercurial extension.
I only paste the Python code here. I would like to setup a git repository for my $HOME/bin scripts. This is definitely not the final product, but it’s already something you can use.
#!/usr/bin/python
import mercurial
import sys
from mercurial import ui, hg;
myui = ui.ui()
try:
# Instanciate the repository.
hg_repo = hg.repository(myui, sys.argv[1])
# Get some informations.
hg_branch = hg_repo.dirstate.branch()
hg_rev = hg_repo.changelog.rev(hg_repo.changelog.tip())
if hg_repo.dirstate._dirty:
hg_dirty = "1"
else:
hg_dirty = ""
print "hg_rev=%s\nhg_branch=%s\nhg_dirty=%s" % (hg_rev, hg_branch, hg_dirty)
except Exception, ex:
sys.exit(1)
