May 30, 2008

try cnetworkmanager 0.3

cnetworkmanager is a command line interface for Network Manager. It is still lacking many features but I decided to announce it now, when it can:

  1. connect to WiFi networks
  2. read the configuration file of KNetworkManager

It is working for me on RC1 of openSUSE-11.0, which has NetworkManager-0.7.0.r3685-3. It is my first project in Python, so the code is somewhat cumbersome. Thanks to Mišo for getting me started (idea.o.o, abclinuxu.cz), and Bille for the API docs.

Regarding related projects, I have seen network-manager-cli, but it is for 0.6 only and the developers were only active last August, so I decided that I should first write some working code for 0.7.

I am interested in comments, bugs, feature requests, patches, any feedback.

Here are some screenshots ;-)

$ cnetworkmanager -h
cnetworkmanager 0.3 - Command Line Interface for NetworkManager
Options:
-d, --dev list devices
-c, --actcon list active connections
-s, --syscon list system connection settings
-u, --usrcon list user connection settings (can CRASH nm-applet)
-a, --ap list found access points
-n, --nets list found wireless networks
-C<net>, --connect=<net> connect to a wireless network (using knetworkmanagerrc)
-m, --monitor loop to show dbus signals

Listing the networks:

$ cnetworkmanager -n
cnetworkmanager 0.3 - Command Line Interface for NetworkManager
Wifi Networks:
49: onenet (54Mb, protected)
46: IT (54Mb, protected)
48: TiborBrunclik (11Mb, protected)
46: linksys (54Mb)
46: IT (54Mb, protected)
46: 23 (54Mb)

Testing Scribefire

Thanks to Duncan for suggesting an editor, Scribefire for Firefox. I have yet to see if it proves better than the one built in.

Let's try a command:
$ zypper moo
\\\\\
\\\\\\\__o
__\\\\\\\'/_

May 26, 2008

Installation without YaST

With 96MB of RAM, Linuxrc will not start on 11.0 (RC1). So I decided to exploit the image based installation, and not to use YaST at all for a change.

The target machine has dual boot and I am logged on the other system via the network, so I could paste this all in. Fasten your hats...

Update: Planet SUSE is eating the dollar variables :-( See the original post at Blogspot for the real thing.

Target partition:
# mkfs.ext3 /dev/hda1
# mount /dev/hda1 /mnt

A flash drive with images and kernel:
# mount /dev/sda1 /media
# cd /media/misc

Note I used unlzma beforehand because the target machine is way slow for that
# du -m *
5 base-i386.tar
12 base-meta-i386.tar
527 common-base-i386.tar
22 kernel-default-2.6.25.4-8.i586.rpm

Unpack!
# for i in *.tar; do dd if=$i bs=1M | tar -C /mnt -xf -; done &

While it is running, watch the progress:
# pkill -USR1 -x dd
...
552202240 bytes (552 MB) copied, 709,291 s, 779 kB/s

# cp kernel-default-*.i586.rpm /mnt/tmp

Before installing the kernel, we must do some setup so that the post-install script works.

# for i in dev proc sys; do mount --bind /$i /mnt/$i; done

# chroot /mnt
Now I use ## to mark that we are chrooted in the target system.

Modify partitions as needed.
Also see ls -l /dev/disk/by-id
## ROOT=/dev/hda1
## SWAP=/dev/hda4
## cat <<EOF > /etc/fstab
$ROOT / ext3 acl,user_xattr 1 1
$SWAP swap swap defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs noauto 0 0
debugfs /sys/kernel/debug debugfs noauto 0 0
usbfs /proc/bus/usb usbfs noauto 0 0
devpts /dev/pts devpts mode=0620,gid=5 0 0
EOF

You probably don't need to set this one and the others starting with FIX_

## FIX_BOOT=acpi=force
## GROOT="(hd0,0)"
## cat <<EOF > /boot/grub/menu.lst
default 0
timeout 60
gfxmenu $GROOT/boot/message

title openSUSE 11.0
root $GROOT
kernel /boot/vmlinuz root=$ROOT resume=$SWAP vga=787 $FIX_BOOT
initrd /boot/initrd

title Failsafe -- openSUSE 11.0
root $GROOT
kernel /boot/vmlinuz root=$ROOT ide=nodma apm=off acpi=off noresume nosmp noapic maxcpus=0 edd=off x11failsafe vga=787
initrd /boot/initrd
EOF

Put GRUB to MBR
## GDEST="(hd0)"
## cat <<EOF > /boot/grub/device.map
$GDEST /dev/hda
EOF

## cat <<EOF > /etc/grub.conf
setup --stage2=/boot/grub/stage2 $GDEST $GROOT
quit
EOF

## sysconfig() { sed -i -s "/^$2=/s/=\"/=\"$3/" /etc/sysconfig/$1; }

I also need this. You probably don't
## FIX_MODS="ide-generic ide-core"
## sysconfig kernel INITRD_MODULES "$FIX_MODS"

I don't know whether these 2 are strictly necessary
## sysconfig bootloader LOADER_TYPE grub
## sysconfig bootloader LOADER_LOCATION boot

## rpm -Uhv /tmp/kernel-default-*.rpm
It will get the resume device wrong (according to *current* swap partition), but it seems harmless.

## grub-install

## passwd
## chkconfig SuSEfirewall2_init on
## chkconfig SuSEfirewall2_setup on

## exit
# reboot

BTW, I am fed up with the Blogger editor. Can I use an offline one so that I don't have to change blog hosting?

May 19, 2008

Easier Bugzilla search

I realized that I dislike beta bug reporting because it is so painful to search for duplicates before I report a problem. The search form is so ****ing painful to use!

So I wrote a replacement. Enjoy, view source, share, improve.

Search a substring in openSUSE 11.0 bugs (even closed ones):

v 0.3

May 6, 2008

YaST from the Command Line

The Automatic Configuration in openSUSE 11.0 installation is good because you don't have to click Next so much, but now I am missing the button for opening SSH in the firewall.
Here's a one-liner to do it using YaST:
# yast2 firewall services add zone=EXT service=service:sshd
Try also:
# yast2 firewall help
# yast2 firewall longhelp
# yast2 firewall summary
# yast2 firewall services list
# yast2 -l
# yast2 FOO help
(Saying "yast" instead of "yast2" should work too, but there is bug 374259.)

May 5, 2008

cnetworkmanager 0.1

Thanks to Mišo for getting me started on this...
$ cnetworkmanager -d -c
cnetworkmanager 0.1 - Command Line Interface for NetworkManager
state: CONNECTED
wifi: 1
wifi hw: 1
/org/freedesktop/Hal/devices/net_00_02_3f_0d_7d_93
Udi: /org/freedesktop/Hal/devices/net_00_02_3f_0d_7d_93
Interface: eth0
Driver: 8139too
Ip4Address: 268702730
Capabilities: NM_SUPPORTED,CARRIER_DETECT
Dev State: FAILED
Dev Type: 802_3_ETHERNET
HwAddress: 00:02:3F:0D:7D:93
Speed: 100
Carrier: 1
/org/freedesktop/Hal/devices/net_00_11_d8_70_00_2f
Udi: /org/freedesktop/Hal/devices/net_00_11_d8_70_00_2f
Interface: wlan0
Driver: rt2500pci
Ip4Address: 1476989962
Capabilities: NM_SUPPORTED
Dev State: FAILED
Dev Type: 802_11_WIRELESS
Dev Mode: INFRA
Wifi Capabilities: RSN,CIPHER_WEP40,CIPHER_WEP104,CIPHER_TKIP,CIPHER_CCMP,WPA
HwAddress: 00:11:D8:70:00:2F
Bitrate: 1000
ActiveAccessPoint: /org/freedesktop/NetworkManager/AccessPoint/4
Active Connections
/org/freedesktop/NetworkManager/ActiveConnection/8
ServiceName: org.freedesktop.NetworkManagerSystemSettings
Connection: /org/freedesktop/NetworkManagerSettings/0
SpecificObject: /
SharedServiceName:
SharedConnection: /
Devices: dbus.Array([dbus.ObjectPath('/org/freedesktop/Hal/devices/net_00_02_3f_0d_7d_93')], signature=dbus.Signature('o'), variant_level=1)
/org/freedesktop/NetworkManager/ActiveConnection/9
ServiceName: org.freedesktop.NetworkManagerUserSettings
Connection: /org/freedesktop/NetworkManagerSettings/Connection/0
SpecificObject: /org/freedesktop/NetworkManager/AccessPoint/4
SharedServiceName:
SharedConnection: /
Devices: dbus.Array([dbus.ObjectPath('/org/freedesktop/Hal/devices/net_00_11_d8_70_00_2f')], signature=dbus.Signature('o'), variant_level=1)

May 2, 2008

D-Bus Spying

I found how to make dbus-monitor show me more than just signals on the system bus. The documentation in dbus-daemon(1) is very terse about that. This is probably insecure, although I don't know of an interesting exploit.
--- /etc/dbus-1/system.conf.orig        2008-05-02 17:08:03.000000000 +0200
+++ /etc/dbus-1/system.conf 2008-05-02 17:08:30.000000000 +0200
@@ -55,6 +55,9 @@
<allow send_requested_reply="true">
<allow receive_requested_reply="true">
</allow>
+ <policy context="mandatory">
+ <allow receive_interface="*" eavesdrop="true">
+ </policy>

<!-- Config files are placed here that among other things, punch
holes in the above policy for specific services. -->
Then you need to tell the daemon to reread the config:
# pkill -HUP -u messagebus
BTW I still haven't figured out how to monitor method_return. I guess receive_requested_reply="false" should do it but not sure how. Does anyone know?

Apr 30, 2008

D-Bus Sightseeing

I figured it was time to learn more about D-Bus. Today, let me share some useful calls that I found so far. Hopefully they will inspire you to experimenting too and together we will have a chance of learning more.
$ dbus-send --print-reply \
--dest=org.kde.klipper \
/klipper \
org.kde.klipper.klipper.getClipboardContents
method return sender=:1.37 -> dest=:1.73 reply_serial=2
string "Hello D-Bus"

Your result will be probably different. In fact, I spent several minutes wondering why the method does not return anything and just repeats its name ;-)
The meaning of the parameters: --dest is the destination connection; apparently D-Bus cannot find it out from the following parameter: /klipper: the destination object. org.kde.klipper.klipper is the interface. Most objects have their own interface plus the introspection interface org.freedesktop.DBus.Introspectable. getClipboardContents is of course the method name.

For further exploration, the GUI tool qdbusviewer is very useful. Try it for calling getClipboardContents now.
$ dbus-send --type=method_call --dest=org.kde.kwin \
/KWin org.kde.KWin.nextDesktop
$ dbus-send --type=method_call --dest=org.kde.kwin \
/KWin org.kde.KWin.previousDesktop
$ dbus-send --type=method_call --dest=org.kde.plasma \
/App org.kde.plasma.App.toggleDashboard
The type option is necessary because dbus-call defaults to type=signal which would not work. (BTW does anyone have a nice example for demonstrating a signal?) With print-reply in the first example, type=method_call is implied.

Let's pass some arguments:
$ dbus-send --type=method_call --dest=org.kde.klipper \
/klipper org.kde.klipper.klipper.setClipboardContents \
string:'Test Beta2!'
$ dbus-send --type=method_call --dest=org.kde.krunner \
/Interface org.kde.krunner.Interface.display \
string:'system'
So far we have been using the session bus. The system-wide bus offers even more fun:
$ dbus-send --system --print-reply \
--dest=org.freedesktop.NetworkManagerSystemSettings \
/org/freedesktop/NetworkManagerSettings \
org.freedesktop.NetworkManagerSettings.ListConnections

array [
object path "/org/freedesktop/NetworkManagerSettings/0"
object path "/org/freedesktop/NetworkManagerSettings/1"
object path "/org/freedesktop/NetworkManagerSettings/2"
]

$ dbus-send --system --print-reply \
--dest=org.freedesktop.NetworkManagerSystemSettings \
/org/freedesktop/NetworkManagerSettings/1 \
org.freedesktop.NetworkManagerSettings.Connection.GetSettings

array [
dict entry(
string "802-11-wireless"
array [
dict entry(
string "ssid"
variant array [
byte 102
byte 114
byte 111
byte 103
byte 115
]
)
dict entry(
string "security"
variant string "802-11-wireless-security"
)
]
)
/* more data. BTW you can't see any of this in qdbusviewer. */
]
(Interesting, every even call to NMS fails with a timeout)

Finally, a long list to scroll up while the music plays:
$ dbus-send --system --print-reply \
--dest=org.freedesktop.Hal \
/org/freedesktop/Hal/Manager \
org.freedesktop.Hal.Manager.GetAllDevices

Apr 21, 2008

TWM tip

TWM is the ancient window manager that you can use when troubleshooting the problems with X. It has always annoyed me that it can't make up its own mind and you have to place the windows manually when they first appear.

Solution:
cp /usr/share/X11/twm/system.twmrc ~
echo RandomPlacement >> ~/.twmrc
TODO: make it the default in openSUSE.

Apr 18, 2008

openSUSE 11.0 Beta 1: Is that the murderer's name and address in the victim's hand?

As Beta 1 is getting mirrored, I am excited to tell you about obscure parts of the installation that I hope you will never see.

YaST does not crash. Never. Well, only rarely. Especially not during the initial installation. Seldom. So what do we do when it does? We want the backtrace and the debugging logs. So before 11.0 we would ask you to please let it crash again, but with some special options to produce the backtrace and the debugging info. Spoils the fun.

Since Alpha 2 YaST will take care of the backtrace. Since Beta 1, it will also produce tons of the debugging messages, but throw most of them away and only show the last few of them in case of a crash. Reporting a bug has become much easier!

This has actually helped us already in debugging one crash that blocked the release of Beta 1, bug 380283. If you want to see for yourself, search the log for "got signal". The next line says "Liberating suppressed debugging messages" and afterwards there is "Back trace".

References: FATE#302167, FATE#302166.

Apr 8, 2008

iogrind in openSUSE Build Service

iogrind is Michael Meeks' I/O profiler and visualizer. I wanted to see if it can help me with improving YaST performance, and I was surprised to find that there are no RPMs.

Well now there are: iogrind in openSUSE Build Service. The packaging is very crude for now, but it appears to work. Now I have to make some sense of the tool :-)

Apr 1, 2008

kezboard.rpm - Adapts zour QWERTY habits to a QWERTZ world

$ yzpper info kezboard
* ...
* Reading installed packages [100%]

Information for package kezboard:

Repository:
Name: kezboard
Version: 1.0-1
Arch: noarch
Installed: Yes
Status: up-to-date
Installed Size: 0 B
Summary: Adapts zour QWERTY habits to a QWERTZ world
Description:

Do zou keep tzping loadkeys instead of loadkezs and zypper instead of yzpper?
Then this package could help zou.

Authors:
--------
Martin Vidner
$ rpm -ql kezboard
/bin/gunyip
/bin/gyip
/bin/loadkezs
/bin/sznc
/bin/ycat
/usr/bin/byip2
/usr/bin/compiy
/usr/bin/pzthon
/usr/bin/rubz
/usr/bin/unyip
/usr/bin/yip
/usr/bin/yzpper


Get kezboard as an RPM in the openSUSE Build Service.

Jul 24, 2007

First Time with Mono

vi a.cs:
using System;
using Mono.Unix;

public class Foo {
public static void Main (string[] args) {
foreach (UnixDriveInfo d in UnixDriveInfo.GetDrives ()) {

Console.WriteLine(String.Format("drive {0} available {1}",
d.Name, d.AvailableFreeSpace));

}
}
}
And then:
mjolnir:~ # mcs -r:Mono.Posix a.cs
mjolnir:~ # mono ./a.exe
drive / available 1136402432
drive /big available 22027657216
drive /proc available 0
drive /sys available 0
drive /sys/kernel/debug available 0
drive /proc/bus/usb available 0
drive /dev/pts available 0
drive /media/floppy available 1136402432
That did the trick in figuring out why rug thought it did not have enough disk space to install updates. (Answer: the cache-directory must have an entry in fstab; just mounting it is not enough.)
Before you ask, this does not mean that I'm rewriting all my shell scripts to Mono. I'm just happy to have passed this unknown territory successfully.

Jun 28, 2007

YaST User Interface Library Useable From Perl

It has been possible for some time now to write YaST modules in Perl. But to call the UI code you had to use YCP. For the Hack Week I decided to finish Stano's earlier work on the subject and make the UI callable from Perl or any of the soon to be available languages. This is a first step on the way to completely liberate the YaST UI from YCP.

Want to try it out? It works alongside your stock YaST on openSUSE 10.2. Install the binary tarball to /home/martin (really there, the binaries have the path hardwired!)

wget http://www.suse.de/~mvidner/hackweek/yast-ui-from-perl.tar.bz2
sudo sh -c "mkdir /home/martin && bzcat yast-ui-from-perl.tar.bz2 | tar x -C /home/martin"

Here's an example perl script. Note the links to the UI reference.


#! /usr/bin/perl -w
use YaST::YCP qw(:DATA);
YaST::YCP::Import "UI";
YaST::YCP::init_ui ($ARGV[0] || "qt");

my $c = Term("VBox",
Term("Label", "Now we can call YaST UI from other languages!"),
Term("PushButton", "&So What?")
);

UI->OpenDialog($c);
UI->UserInput();
UI->CloseDialog();
Let's try with the stock YaST
sh$ perl /home/martin/pfx/bin/helloui.pm
Nothing happens. If you are interested in the error messages, they are in ~/.y2log

Now let's use the new and improved environment and retry

sh$ /home/martin/pfx/bin/pfxsh
STARTING A NEW SHELL
sh$ perl /home/martin/pfx/bin/helloui.pm

sh$ perl /home/martin/pfx/bin/helloui.pm ncurses


Remember, this is just a preview. It is not packaged properly and has bugs. The source is at svn.opensuse.org.

Mar 26, 2007

YaST Log Summarizer

When dealing with YaST logs, it happens every now and then that you wade through the voluminous output only to discover that you are looking at the wrong run and the bug happened three days after the start of the log file.

So I wrote a simple log summarizer y2logpids, that shows the first and last lines for each process ID in the log. And as a side feature, it also measures time differences for the case where the reporter says "and then it hangs for 30 minutes".

$ y2logpids -h
Usage:
y2logpids -h|--help
y2logpids [-m] [-d [<seconds>]] [log-files]

Options and Arguments:
-m, --maximum
Show the maximum time difference between log lines, within a single
PID.

-d [seconds], --difference[=seconds]
Show where the time difference is larger than seconds (60 if
unspecified), within a single PID

$ wc -l logs/255012-y2log
23501 logs/255012-y2log
$ y2logpids logs/255012-y2log
2007-03-20 11:13:31 <1> e111(4034) [liby2] genericfrontend.cc(main):200 Launched YaST2 component 'y2base' 'inst_suse_register' 'qt' ''
2007-03-20 11:13:45 <1> e111(4034) [media] MediaManager.cc(restoreAutoMounter):248 Restored HAL volume handling (automounter)
2007-03-20 11:14:15 <1> e111(4222) [liby2] genericfrontend.cc(main):200 Launched YaST2 component 'y2base' 'inst_suse_register' 'qt' ''
2007-03-20 11:29:07 <1> e111(4222) [media] MediaManager.cc(restoreAutoMounter):248 Restored HAL volume handling (automounter)
2007-03-20 11:32:51 <1> e111(5265) [liby2] genericfrontend.cc(main):200 Launched YaST2 component 'y2base' 'online_update' 'qt' ''
2007-03-20 11:33:12 <1> e111(5265) [media] MediaManager.cc(restoreAutoMounter):248 Restored HAL volume handling (automounter)
2007-03-20 11:34:07 <1> e111(5310) [liby2] genericfrontend.cc(main):200 Launched YaST2 component 'y2base' 'online_update' 'qt' ''
2007-03-20 12:02:02 <1> e111(5310) [YCP] OnlineUpdateCallbacks.ycp:50 PatchProgressCallback 100
2007-03-20 12:02:18 <1> e111(7003) [liby2] genericfrontend.cc(main):200 Launched YaST2 component 'y2base' 'print-product' 'qt' ''
2007-03-20 12:03:51 <1> e111(7003) [zypp] ZYppFactory.cc(unLockFile):139 unlocked
2007-03-20 12:03:55 <0> e111(5310) [zypp] ExternalProgram.cc(checkStatus):333 pid 5881 successfully completed
2007-03-20 12:24:22 <1> e111(5310) [media] MediaManager.cc(restoreAutoMounter):248 Restored HAL volume handling (automounter)
2007-03-20 12:35:41 <1> e111(8715) [liby2] genericfrontend.cc(main):200 Launched YaST2 component 'y2base' 'online_update' 'qt' ''
2007-03-20 12:38:51 <1> e111(8715) [media] MediaManager.cc(restoreAutoMounter):248 Restored HAL volume handling (automounter)


Download the script.

Mar 20, 2007

Bugzilla Automation - Downloading Logs

I have tons of bugs and most of them have logs attached. All of them called y2logs.tgz. I made a little system not to get lost in the heap of logs: ~/logs/$BUGNUMBER-$LOGFILENAME

Now, it is pretty tedious to type in the bug number when downloading the log file. I have finally managed to script it. It works like this:

buglog --install will install a Konqueror action (in ~/.kde/share/apps/konqueror/servicemenus).

In Konqueror, right-click an attachment, select Actions / Copy Bugzilla log. (A debugging xterm opens). The attachment is downloaded to ~/logs/$BUGNUMBER-$FILENAME.

Or just call buglog attachment-url
Reading attachment metadata
You are using an old browser

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 32385 100 32385 0 0 19380 0 0:00:01 0:00:01 --:--:-- 83898
Reading attachment data > /home/mvidner/logs/29751-xkbd-cz.png
You are using an old browser

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6714 100 6714 0 0 5562 0 0:00:01 0:00:01 --:--:-- 2678k
Waiting 30 seconds, press Enter to finish now.


Enjoy and improve. Especially let me know if you know how to integrate this with other browsers than Konqueror.

See a previous post about bnc_curl, a required script to automate the iChain authentication in Novell Bugzilla.

Also thanks to our Bugzilla admins who have meanwhile built in automatic numbering of attachments. I still think my code is better - say NIH! :)

Download the script.

Mar 8, 2007

Argument Debugging in Bash

Debugging bash scripts? Need to see what arguments you get? See the
difference between echo "$@" and (the bash builtin) printf "%q".
First we set some tricky arguments and then set them again, pasting
the output of the inspection command.

As you can see, plain echo degrades quickly:
e5:~ # set -- arg1 "arg two" back\\slash "'single'" '"double"'
e5:~ # echo "$@"
arg1 arg two back\slash 'single' "double"
e5:~ # set -- arg1 arg two back\slash 'single' "double"
e5:~ # echo "$@"
arg1 arg two backslash single double
But printf %q keeps working:
e5:~ # set -- arg1 "arg two" back\\slash "'single'" '"double"'
e5:~ # printf "%q " "$@"; echo
arg1 arg\ two back\\slash \'single\' \"double\"
e5:~ # set -- arg1 arg\ two back\\slash \'single\' \"double\"
e5:~ # printf "%q " "$@"; echo
arg1 arg\ two back\\slash \'single\' \"double\"

Mar 7, 2007

XML Package Metadata Verifier

I needed to check the consistency of a RPM repository that I created by hand, in the XML Package Metadata format ("YUM"). So I wrote a verifier in bash using xsltproc and sha1sum.
Here: verify-repodata
Greetings to Harald and Matt.

Mar 1, 2007

Bugzilla Automation - Logging In

I want to show you my tools to automate some tasks in Bugzilla, in particular in bugzilla.novell.com.

  • a Konqueror plugin that downloads attached logs to a particular directory and prepends the bug number to compensate for the fact that they are all named y2log.
  • a categorized visual map of my open bugs, automatically updated with new data as I squash current bugs and new ones keep raining.
But not yet today. First we must be able to log in. Otherwise a saved query of yours will just redirect you to the iChain login page.
$ QUERY=Moje   # modify to have it work on your own account
$ curl >bugs.html https://bugzilla.novell.com/buglist.cgi?cmdtype=runnamed&namedcmd=$QUERY
$ w3m bugs.html

Meet bnc_curl, a handy wrapper around curl that takes care of the authentication.

$ ./bnc_curl --install
Bugzilla.Novell.com username (not email): mvidner
Bugzilla.Novell.com password (no echo):

This creates a file ~/.bnc_creds readable only by you containing the credentials. They are hex-escaped to protect them from gentlemen attackers. Now the retrieval will work.

$ ./bnc_curl >bugs.html https://bugzilla.novell.com/buglist.cgi?cmdtype=runnamed&namedcmd=$QUERY
$ w3m bugs.html

Download the script.

Feb 8, 2007

picasa + suse: ulimit -v unlimited

I installed Picasa on openSUSE 10.2 but it would not start.

After some playing with WINEDEBUG=1 and strace I noticed many failures of mmap. Kissed by the debugging muse I tried ulimit -v unlimited and that was it. Problem solved. See also SOFTVIRTUALLIMIT in /etc/sysconfig/ulimit.

Level 2: take the directory with 3500 images and sort it somehow.