Archives for: November 2005

11/25/05

Spam attack

This blog is under a massive referer spam attack at the moment by multiple spambots. I'm trying to get rid of them using .htaccess, but it hardly works.
Those spambots already consumed all my monthly bandwith, so I really need them to go away. If someone knows how to do this (I googled around, no usable help), please let me know asap, otherwise I'll be forced to take this blog down for some days I'm afraid... Maybe I should switch to WordPress here too.

My sincere apologies if I broke something in the blog setup, or if some people are unable to reach the site although they're not spammers.

Permalink . Ikke . 11:24:29 am . 109 Words . Technology . . 388 views . 6 comments

11/23/05

Non-tech people on tech stuff

Read this.

Reminds me on an article on "Web 2.0" in our newspaper some days ago, and a "readers reaction" on it yesterday. Obviously 2 people who don't understand what it's all about. Sadly enough.

Permalink . Ikke . 01:31:34 pm . 33 Words . Life, Linux . . 476 views . 3 comments

11/19/05

OOo2 on 770
Permalink . Ikke . 09:17:00 pm . 23 Words . Desktop . . 1059 views . 5 comments
Remote X on Nokia 770: schreenshots

Due to the fact that the screenshot tool had a bug at the time I gave remote X windows a try on the N770, I could't post any 'proof'.

But, that screenshot-bug has been solved, and I connected my N770 to the fresh install of Ubuntu Linux so I could take shoot some screens. It took me about 4 minutes to make my N770 talk to the pc (Ubuntu recognised my usb bluetooth key immediately, it really wasn't hard at all). I installed the openssh-server on the pc (enabled it in Synaptic, and pressed Apply, easy stuff), started it, and logged in with my N770.

This time I used some new command line options (thank you daf):

ssh -X user@server -c blowfish -C

And I started oowriter2 again:

oowriter2 starting...
(Larger image)

and a few seconds later (the pc is quite old):

oowriter2 on N770
(Larger image)

Then I gave The Gimp another try, but the lag was still there. It was better a bit faster than without the compression settings for the ssh connection, but nowhere near usable. :-(

btw, has anyone tried this keyboard with the N770 yet? Does it work? Or should/will it work? Plz let me know!

Permalink . RealNitro . 19:54:46 . 261 Words . Coding . Email . 1228 views
Small Valgrind introduction

Everyone writing C or C++ code should know what a memory leak is. You allocate some memory, and never free it.
It can be very hard to make your code memleak free, or even just to know whether your code contains any memleaks.
Luckily, in the Free Software world, we got a great tool to check our code for memleaks (or other errors): Valgrind.

As I don't have time to write a lot now, I'll just give a very simple sample of it's usage.

Here's my code (very bad code, obviously, but hey ;-)):

#include <stdio.h>
#include <stdlib.h>

static void function() {
        char *test = (char *)malloc(100 * sizeof(char));
        test[0] = '\0';

        printf("Function\n");

        /* Leaking 100 chars here, 100 bytes */
}

int main(int argc, char *argv[]) {
        int *i = NULL;

        function();
        i = (int *)malloc(50 * sizeof(int));
        printf("Done\n");

        return 0;

        /* Leaking 50 ints here. On x86, this is 50*4=200 bytes */
}

As you can see, we leak memory twice: once 100 bytes, once 200.
Let's compile and run our code:

$ gcc -o test -Wall -g test.c
$ ./test
Function
Done

Great, our code works fine (or at least, it looks like it).

Now we introduce valgrind. First we'll do a simple memory allocation check:

$ valgrind --tool=memcheck ./test ==18819== Memcheck, a memory error detector for x86-linux.
==18819== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==18819== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==18819== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==18819== For more details, rerun with: -v
==18819==
Function
Done
==18819==
==18819== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==18819== malloc/free: in use at exit: 300 bytes in 2 blocks.
==18819== malloc/free: 2 allocs, 0 frees, 300 bytes allocated.
==18819== For a detailed leak analysis,  rerun with: --leak-check=yes
==18819== For counts of detected errors, rerun with: -v

Valgrind tells us we leaked 300 bytes, in 2 blocks (one malloc call returns one block, obviously).
It also tells us to re-run the test with the --leak-check=yes flag, which is a good advice:

$ valgrind --tool=memcheck --leak-check=yes ./test
==18826== Memcheck, a memory error detector for x86-linux.
==18826== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==18826== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==18826== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==18826== For more details, rerun with: -v
==18826==
Function
Done
==18826==
==18826== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==18826== malloc/free: in use at exit: 300 bytes in 2 blocks.
==18826== malloc/free: 2 allocs, 0 frees, 300 bytes allocated.
==18826== For counts of detected errors, rerun with: -v
==18826== searching for pointers to 2 not-freed blocks.
==18826== checked 1404368 bytes.
==18826==
==18826== 100 bytes in 1 blocks are definitely lost in loss record 1 of 2
==18826==    at 0x1B906B82: malloc (vg_replace_malloc.c:131)
==18826==    by 0x80483B5: function (test.c:5)
==18826==    by 0x80483F4: main (test.c:14)
==18826==
==18826==
==18826== 200 bytes in 1 blocks are definitely lost in loss record 2 of 2
==18826==    at 0x1B906B82: malloc (vg_replace_malloc.c:131)
==18826==    by 0x8048400: main (test.c:15)
==18826==
==18826== LEAK SUMMARY:
==18826==    definitely lost: 300 bytes in 2 blocks.
==18826==    possibly lost:   0 bytes in 0 blocks.
==18826==    still reachable: 0 bytes in 0 blocks.
==18826==         suppressed: 0 bytes in 0 blocks.
==18826== Reachable blocks (those to which a pointer was found) are not shown.
==18826== To see them, rerun with: --show-reachable=yes

Great, here Valgrind tells us exactly what we're doing wrong.
There are 2 blocks where we leak memory:

  • The first one is at code path
    main (test.c:14) -> function (test.c:5) -> malloc (vg_replace_malloc.c:131)
    leaking 100 bytes.
    The vg_replace_malloc.c file isn't ours, it's a valgrind file where the malloc() wrapper (which keeps track of our allocations/free's/...) is located. We're mostly interested in the "function (test.c:5)" part. If we look at line 5, we see this is

    char *test = (char *)malloc(100 * sizeof(char));
    our first allocation. And indeed, if we look further, we never free these 100 chars.
  • Second is at main (test.c:15). Again, we can look at this line:
    i = (int *)malloc(50 * sizeof(int));
    and indeed, we never free these allocated integers again. We allocated 50 ints, and on x86 one int is 32 bits (4 bytes), so we leak 200 bytes (and valgrind was correct once again :-)).

Obviously, valgrind got much more options or checks:

$ valgrind
valgrind: Missing --tool option
Available tools:
        memcheck
        addrcheck
        cachegrind
        corecheck
        helgrind
        massif
        lackey
        none
        callgrind
valgrind: Use --help for more information.

I don't know all of them, actually I only use the memcheck thing, but even when only using one tool, it can be a very useful program.

I got one minor issue with valgrind currently: when it detects memory leaks in some program, it still returns 0 in the end, so it's not easy to integrate valgrind checks in automake's "make check" target. If someone got any pointers how to do this, please let me know!

Permalink . Ikke . 03:53:33 pm . 761 Words . Linux, Coding Corner . . 2158 views . 13 comments

11/17/05

Remote X sessions on Nokia 770

Some topics on internettablettalk.com have great views on what the N770 might have to offer in the future. One nice possibility is forwarding X sessions to a N770. I started with forwarding Gedit from my pc to my N770, but later on I had a go at 'oowriter2' (OpenOffice.org 2 Writer), Supertux and The Gimp. My experiences about those apps on the N770 are at the end of this post. First I'll tell you how to try it yourself.

Some basic requirements:

  • a computer running the X-server and sshd (a decent linux box ;-) )
  • a (fast) network connection between your N770 and the server
  • openSSH for the maemo platform

To install openSSH on your N770, download the openSSH .deb package to your N770. Next,open an X-terminal, and gain root access. If the .deb openSSH package is on your mmc, navigate to it:

cd /media/mmc1/

And install openSSH (it doesn't install using the graphical package installer):

dpkg -x ssh_*.deb /

Caution: make sure that your servers sshd allows X forwarding! Time to connect to the server:

ssh -X user@server

Change user to your login-name, and change server to your servers IP or domain name. The first time you log into your server from your N770, ssh wil ask you a question. Answer 'yes'. Then it will ask your password. Enter it. You should get a command prompt as 'user' on your server. Time to execute a program! I use the Gnome desktop environment, and the default text editor (like notepad in Windows -- but waaay better ;-) ) in Gnome is Gedit. The command to start Gedit from a terminal is 'gedit' (duh! :-p ). Execute

gedit

Give it some time to start, and you'll see Gedit running on your N770! To try any other programs, just tap their commands into the terminal and have fun!

But there are a few downsides. The first big downside is text-input: The onscreen-keyboard does not appear when you put the cursor inside a text-field of an X-forwarded window. Copy-pasting text is possible though. Maybe people with working Bluetooth keyboards will be able to type some text. Is somebody willing to try? One other downside is that X-forwarded windows vanish when they are minimized. There seems to be no way to get them back, killing the parent program and restarting it is the only solution. (You can kill the parent program by bringing your X-term back up, opening 'X Terminal'->'Terminal'->'Send Ctrl-some key', and tapping the 'c' keyboard button.) The fullscreen button didn't work aswell. Gedit just doesn't recognise/receive the signal emited by that fullscreen button, I guess.

Beside those little anoyances, Gedit ran quite smooth. So I decided to start the OpenOffice.org 2 Writer. And it worked too! The gui wasn't 100% snappy (i.e. scrolling was laggy), but it seemed fast enough to be usable. Later that day, I decided to give Supertux a try. (Supertux is a Super Mario clone.) The verdict: not playable. The bluetooth connection between my pc and my N770 just wasn't fast enough to transfer all that graphical goodness without (a LOT of) lag. The Gimp suffers from the same problem. Drawing with your stylus is possible, but the result lags several seconds behind.

A possible solution for the lag problems would be to compress the data that's being sent between the X-server and the client (your N770). A FreeNX-client would be great as the NX protocol is in fact a compressed (and secured) forwarded X-session. (FreeNX is a free alternative to NoMachine NX.)

Permalink . RealNitro . 21:31:01 . 658 Words . Linux, Coding . Email . 2279 views

11/13/05

Sharing internet with Nokia 770 over bluetooth

It's been a (very) long time since I have posted here (again), but I bought myself a Nokia 770 last week, and it took me a lot of time to get it on the net, so I thought I'd share how I got it to work.

First off, some interesting links:

You need to have your bluetooth stick working first. Gentoo users should read the first parts of the host to host bluetooth howto, other distro's should consult the proper information on the community forums/wiki. (Don't scan for other devices yet, just setup your kernel and BlueZ.)

Then open the X Terminal on your 770 and be root. Enter:

hcitool scan

The scan should display your pc's bluetooth name and its bluetooth ID. If the scan cannot find your computer, check again if your bluetooth stick is really working. Scanning for your 770 on your computer is no use, since your 770 will remain invisible. Now let's pair your 770 with the pc. Execute the following on your 770, but replace 00:10:20:30:40:50 with your computer's Bluetooth ID:

hcitool cc 00:10:20:30:40:50

If you get an error, try:

rm /etc/bluetooth/link_key

If the pairing works, you will be asked to enter the PIN code of your pc. There is no need to try to connect from your pc to your 770, it will not work anyway (your pc cannot see your 770, remember). Next, make your computer listen for an incoming (network) connection. As root execute:

pand --listen --role NAP

Now, on your 770, connect to your pc:

pand --connect 00:10:20:30:40:50

(Replace 00:10:20:30:40:50 with your pc's Bluetooth ID again.)

If the connection has been set up, the following command should work on your 770:

ifconfig bnep0 192.168.2.2 netmask 255.255.255.0 broadcast 192.168.2.255

Warning: if your local network already uses the 192.168.2.* subnet, replace the IP with another one that isn't in a subnet your pc is a part of!
On your pc, execute the same command, but change the IP:

ifconfig bnep0 192.168.2.1 netmask 255.255.255.0 broadcast 192.168.2.255

We're almost there now. Your 770 and your pc are part of the same subnet now! Let's try to ping the 770. On your pc:

ping 192.168.2.2

If you installed the ssh server, you can run it now, and log into it from your pc.

Now, let's set up the internet connection forwarding. First off, let your 770 know that your pc is its gateway to the internet:

route add default gw 192.168.2.1

Also add a dummy internet connection:

gconftool -s -t string /system/osso/connectivity/IAP/DEFAULT/type DUMMY

On your pc, display the content of /etc/resolv.conf:

cat /etc/resolv.conf

And add the rules to the /etc/resolv.conf file on your 770. For each line do:

echo "line" >> /etc/resolv.conf

All that's left to do is making your pc act as a router for your 770. One way to do that (not the easiest one), is to use a program called iptables. In this howto I will explain how to setup iptables on gentoo. Again, if you use an other distro, check the community forums and/or wiki. On gentoo, emerge iptables. You might have to recompile your kernel, just follow the 'Kernel Support' chapter of this howto on the gentoo wiki. To configure iptables, you can read this guide, or, if you just want a quick solution, use this script. As root, paste it inside a file. Then comment out IPTABLES=/usr/local/sbin/iptables, and uncomment #IPTABLES=/sbin/iptables. Change INTIF="eth1" to INTIF="bnep0". You might have to change EXTIF="eth0" too. (I had to change it to vpnlink because I connect to the internet with a vpn.) When you finished changing the script, make it executable, and run it. There should be no errors. Now save the script:

/etc/init.d/iptables save

and start iptables:

/etc/init.d/iptables start

If you want to start iptables everytime you boot, do:

rc-update add iptables default

You should be able to surf with your 770 now! I plan on writing a few script to make the linking more automatic. Plz share your comments here, and post any mistakes in the howto.

Permalink . RealNitro . 20:05:28 . 807 Words . Linux, Coding . Email . 3196 views

11/12/05

Nano on Maemo

So, you got SSH access to your Nokia 770, but can't edit any files? Try my Nano package...
It doesn't work yet in the xterm application (I didn't try myself yet, RealNitro told me ;-)), looks like there's some issue with that terminal's CTRL-key emulation...
Anyway, it's meant to be used over SSH, not for on-device purposes...

Now I still should be able to get USB networking working somehow :-( Didn't spend any more time on it though...

Permalink . Ikke . 10:25:42 pm . 121 Words . Technology, Desktop . . 435 views . 10 comments

11/05/05

Maemo and mDNS

Porting Avahi to the Maemo platform seems to be quite hard (if not impossible) because of the DBUS version conflict (Avahi needs DBUS >= 0.34, whilst the Maemo platform is still based on DBUS 0.2x). There's a DBUS 0.3x branch in Maemo's SVN repository, but that's not stable yet, and will only be used in the InternetTablet2006 releases, so I gave up on Avahi for now :oops:.
Instead, I'm trying to create a good package of Howl now (I know, I don't like the Howl API either), then I'll attempt to build a small (Hildon?) application on top of it, just as a test case for "the real thing" ;-)

*edit*
It works inside my scratchbox (i386) :-)
Built an arm deb package too, installed it on my "real" device, the software runs (no ld errors), but I couldnt test it yet as I don't have a wireless network at home, and didn't manage to get USB networking working yet :-(

Permalink . Ikke . 07:25:18 pm . 197 Words . Technology, Linux, Networks, Coding Corner . . 1115 views . 4 comments

11/03/05

Using C++ classes in C

Today I had a little chat with Michiel on #gnome-nl regarding the use of C++ classes in C code (he started learning C again ;-)).

I was fascinated (well, sort of) by this, and tried to get something working. Here's the result:

  • First we need a C++ class, using one header file (Test.hh)

    class Test {
            public:
                    void testfunc();
                    Test(int i);
    
            private:
                    int testint;
    };
    

    and one implementation file (Test.cc)

    #include <iostream>
    #include "Test.hh"
    
    using namespace std;
    
    Test::Test(int i) {
            this->testint = i;
    }
    
    void Test::testfunc() {
            cout << "test " << this->testint << endl;
    }

    This is just basic C++ code.

  • Then we need some glue code. This code is something in-between C and C++. Again, we got one header file (TestWrapper.h, just .h as it doesn't contain any C++ code)

    typedef void CTest;
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    CTest * test_new(int i);
    void test_testfunc(const CTest *t);
    void test_delete(CTest *t);
    #ifdef __cplusplus
    }
    #endif
    

    and the function implementations (TestWrapper.cc, .cc as it contains C++ code):

    #include "TestWrapper.h"
    #include "Test.hh"
    
    extern "C" {
    
    CTest * test_new(int i) {
           Test *t = new Test(i);
    
           return (CTest *)t;
    }
    
    void test_testfunc(const CTest *test) {
            Test *t = (Test *)test;
            t->testfunc();
    }
    
    void test_delete(CTest *test) {
            Test *t = (Test *)test;
    
            delete t;
    }
    }
    

    Some things you should notice:

    1. typedef void CTest
      We typedef CTest to void. This way we can use "CTest *" in our C code as if it's a normal C type, whilst we have compile-time type checks (sort of at least :-)), and it's cleaner than always using "void *"

    2. The use of "extern "C" { }" around all functions (both definitions and implementations). We need this so the compiler won't name-mangle the resulting binaries. If you want to see what name-mangling is:

      $ cat test.c
      #include <iostream>
      using namespace std;
      
      void test() {
              cout << "test" << endl;
      }
      
      int main(int argc, char *argv[]) {
              test();
              return 0;
      }
      $ g++ -o nmtest test.c
      $ ./nmtest
      test
      $ nm nmtest
      ***blablabla***
      08048818 t _Z41__static_initialization_and_destruction_0ii
      080487c4 T _Z4testv
               U _ZNKSs4sizeEv@@GLIBCXX_3.4
               U _ZNKSsixEj@@GLIBCXX_3.4
      ***blablabla***

      As you can see, our "test()" function has been renamed to "_Z4testv" by the compiler. This is needed to allow polyphormism in C++, but we don't want this in our C wrapper of course, as we want to know the name of the function we will call!
      This implies we need another function name for every polyphormistic (SP?) class function of our C++ class in the C wrapper.

  • At last, we need some code to test our work (main.c):

    #include <stdio.h>
    #include "TestWrapper.h"
    
    int main() {
            CTest *t = NULL;
    
            t = test_new(5);
            test_testfunc(t);
            test_delete(t);
            t = NULL;
    
            return 0;
    }
    

    This is, once more, braindead simple (C) code, where we use the functions defined in TestWrapper.h.

  • Last but not least, we need to compile everything. I made a basic Makefile to do this (Makefile):

    CFLAGS=-Wall -Werror -g -ansi -pedantic -std=c89
    CCFLAGS=-Wall -Werror -g
    LDFLAGS=-g -Wall -lstdc++
    
    OBJS=Test.o TestWrapper.o main.o
    PROG=test
    
    all: $(PROG)
    default: all
    
    %.o: %.cc
            $(CC) $(CCFLAGS) -c $<
    
    %.o: %.c
            $(CC) $(CFLAGS) -c $<
    
    $(PROG): $(OBJS)
            $(CC) $(OBJS) $(LDFLAGS) -o $@
    
    clean:
            rm -f $(OBJS)
            rm -f $(PROG)
    

Now we can simply call "make" to build the project:

$ make
cc -Wall -Werror -g -c Test.cc
cc -Wall -Werror -g -c TestWrapper.cc
cc -Wall -Werror -g -ansi -pedantic -std=c89 -c main.c
cc Test.o TestWrapper.o main.o -g -Wall -lstdc++ -o test

Finally, we test the resulting binary:

$ ./test
test 5

which is the expected result.

Obviously, writing a wrapper like this by hand can be a boring task. It might be possible to automate/script this, but I don't know whether the result is worth the time one puts into it. Just use plain C, we don't need C++ ;-)

Permalink . Ikke . 10:40:42 pm . 678 Words . Technology, Coding Corner . . 7777 views . 2 comments
Scratchbox working

Thanks to Bram (and VTK Computer) I got an old 20Gb hard drive, which I needed to be able to install a Scratchbox environment and play around with the Maemo platform.
I managed to install everything by now (although I had one crash again :-(), so I hope I'll be able to start hacking on some apps/libs soon. One of the things I'd love to get working is Avahi, the GPL'ed mDNS stack.

The obligatory shot:

I just followed these steps. They contain one error though: when editing your ~/.bash_profile, you got to add a line containing

export LC_ALL=en_GB

too.

Permalink . Ikke . 10:15:20 pm . 152 Words . Technology, Linux, Desktop, Coding Corner . . 735 views . 3 comments