Writing and reading code

Posted on 28th March 2013 in Development, KDE, Linux, Samba

flattr this!

You’ve probably heard that a developer of an established software project writes an average of 100 lines of code (loc) a day. I can say that this applies to me. So if you write 100 loc per day, how many do you read? I would estimate that the amount of time you spend on reading and understanding code is significantly more than on writing code. You probably also spend quite some time debugging code.

If you spend so much more time on reading and debugging code than writing code, shouldn’t you put more effort in writing clean and debuggable code? The Samba codebase is pretty old, more than 15 years now. I would say we have some experience with bad code and we have started to write much better and cleaner code, because we have wasted so much time trying to understand and debug code. However there is still room for improvement. Lets take a look at the following C code snippet.

if (!a) {
    return;
}

if (!b) {
    return;
}

if (!c) {
    return;
}

if (!*d) {
    return;
}

Can you guess from the code above what types of variables a, b, c and d are? The answer is no? Ok, lets take a look at the following code:

if (a == NULL) {
    return;
}

if (b == 0) {
    return;
}

if (c == false) {
    return;
}

if (d[0] == '\0') {
    return;
}

If you look at the code now, you can probably guess what types they are. Well not exactly which type, but in which superset they are. ‘a’ is a pointer, ‘b’ is an integer type, ‘c’ is a bool and ‘d’ is a string (char array). If you write code the way shown above, you don’t have to scroll up to find out as which type the variable is defined. Most of the time it is enough to know what type of superset you are checking and why.

Think about this: If you spend just a bit more time on writing clean code now, you will spend less time on reading, understanding and debugging the code later if you have to find a bug.

Lets look at some more best practices we do in the Samba code:

bool ok;
int rc;

/*
 * bool return codes should always have the name 'ok' or
 * start with 'is_' or 'do_'
 */
ok = fn_returning_a_bool();
if (!ok) {
    return;
}

/* We use rc or ret for an integer return code */
rc = do_something();
if (rc < 0) {
    return;
}

You can see that we have variables for the return codes and check them with an if-clause. The reason is that it is easy on the eyes and in a debugger you can simply print the return code variable. If you write it like this: if (do_something() < 0) You have a hard time in the debugger to find out the actual return code. You have to step into and through the function to get it. We allow the !ok syntax for bool types, cause ok is by definition in our code a bool.

To be continued ...

comments: 13 »

vim modelines in git config

Posted on 26th February 2013 in Development, KDE, Linux

flattr this!

I’m working on different Open Source projects and most of them have different coding style guidelines. Mostly spaces or tabs or different tabwidth. The easiest thing would be to store these information in the git config of the project. So here is a easy and secure way to have modelines in the git config.

So first I set the modelines (here for the Samba project):
git config --add vim.modeline "tabstop=8 shiftwidth=8 noexpandtab cindent"

Then copy this plugin into ~/.vim/plugin folder.

The modeline you defined in your git config will be appended to the :set command of vim. It only allows a limited set of set commands to be used. It will not execute any arbitrary code and you probably are the only person modifying the git config. You can change the allowed commands by adding the following to your ~/.vimrc file

    let g:git_modelines_allowed_items = [
                \ "textwidth",   "tw",
                \ "softtabstop", "sts",
                \ "tabstop",     "ts",
                \ "shiftwidth",  "sw",
                \ "expandtab",   "et",   "noexpandtab", "noet",
                \ "filetype",    "ft",
                \ "foldmethod",  "fdm",
                \ "readonly",    "ro",   "noreadonly", "noro",
                \ "rightleft",   "rl",   "norightleft", "norl",
                \ "cindent",     "cin",  "nocindent", "nocin",
                \ "smartindent", "si",   "nosmartindent", "nosi",
                \ "autoindent",  "ai",   "noautoindent", "noai",
                \ "spell",
                \ "spelllang"
                \ ]

UPDATE:
* New script which only allows a specified list
* Use sandbox command for set
* Added git repository
* Set only locally when reading the buffer

comments: 8 » tags: ,

cmocka – a unit testing framework for C

Posted on 14th January 2013 in Development, KDE, Linux

flattr this!

I’m a big fan of unit testing frameworks. When I developed csync, a bidirectional file synchronizer, I used check to write unit tests from the start. check was ok, but it were running valgrind on your testcases to find memleaks in your code the mode reports were about check. So I needed to add valgrind suppressions to get rid of them. When I started to work on libssh, a library implementing the SSH protocol, I wrote unit tests with check too. libssh is multi platform and also works on Windows and with Visual Studio. So we needed a new unit testing framework which is platform independent and has better code quality. I stumbled upon cmockery, a unit testing framework from Google. It was easy to use, the code looked good and it worked with Visual Studio. The build system sucked, so I added CMake support to produce a NSIS installer for Windows. I sent all my patches upstream but nothing happened. I fixed more bugs and added all patches people posted in their bug tracking system. I tried to talk with friends at Google, but in the end I needed to fork it.

cmocka is a fork and the successor of cmockery. I started to fix a lot of bugs, got all examples working and wrote API documentation with doxygen. The result is this first release version 0.2.0.

cmocka is a great unit testing framework with support for mock objects. Mock objects are simulated objects that mimic the behavior of real objects in a controlled way. Instead of calling the real objects, the tested object calls a mock object that merely asserts that the correct methods were called, with the expected parameters, in the correct order. It is really easy to write a unit test, take a look at the API an get started.

Example:

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

/* A test case that does nothing and succeeds. */
static void null_test_success(void **state) {
(void) state; /* unused */
}
int main(void) {
const UnitTest tests[] = {
unit_test(null_test_success),
};
return run_tests(tests);
}

comments: 10 » tags: ,

jailbash

Posted on 2nd September 2011 in KDE, Linux

flattr this!

chroot for users suck!

It is work to maintain them and all in all you have to do a lot of nasty hacks to get it going! In the meantime AppArmor is in the mainline kernel. It is pretty simple to write rules for it and you can easily update it with tools like ‘logprof’.

Here is a small howto to trap users in their home directory with a simple AppArmor profile. First you need to compile the following C code:

#include <unistd.h>

int main(int argc, char *argv[]) {
    return execv("/bin/bash", argv);
}

gcc -o jailbash jailbash.c

Then move the binary to /bin.

The next step is to create an AppArmor profile for the jailbash. So create the file /etc/apparmor.d/bin.jailbash and add the following content:

# Last Modified: Tue Jun  7 08:53:41 2011
#----------------------------------------------------------
#
# JAILBASH
#
#----------------------------------------------------------

#include 

/bin/jailbash {
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 


  deny /bin/df r,
  deny /etc/bash_command_not_found r,

  /bin/ r,
  /bin/bash rix,
  /bin/cat rix,
  /bin/chmod rix,
  /bin/chown rix,
  /bin/cp rix,
  /bin/date rix,
  /bin/egrep rix,
  /bin/grep rix,
  /bin/gunzip rix,
  /bin/gzip rix,
  /bin/jailbash rix,
  /bin/ln rix,
  /bin/ls rix,
  /bin/mkdir rix,
  /bin/mktemp rix,
  /bin/more rix,
  /bin/mv rix,
  /bin/ping rix,
  /bin/readlink rix,
  /bin/rm rix,
  /bin/rmdir rix,
  /bin/sed rix,
  /bin/sleep rix,
  /bin/tar rix,
  /bin/touch rix,
  /bin/uname rix,
  /bin/vim rix,
  /bin/vim-normal rix,
  /bin/zcat rix,
  /dev/null rw,
  /dev/urandom r,
  /etc/ r,
  /etc/manpath.config r,
  /etc/opt/ r,
  /etc/sysconfig/console r,
  /etc/sysconfig/mail r,
  /etc/sysconfig/news r,
  /etc/sysconfig/proxy r,
  /etc/sysconfig/suseconfig r,
  /etc/sysconfig/windowmanager r,
  /etc/vimrc r,
  owner /home/*/ r,
  owner /home/*/** rwl,
  /opt/ r,
  owner /proc/*/cmdline r,
  owner /proc/*/exe r,
  owner /proc/*/mounts r,
  /proc/loadavg r,
  /usr/X11R6/bin/ r,
  /usr/bin/ r,
  /usr/bin/dircolors rix,
  /usr/bin/head rix,
  /usr/bin/id rix,
  /usr/bin/less rix,
  /usr/bin/man rix,
  /usr/bin/manpath rix,
  /usr/bin/mc rix,
  /usr/bin/scp rix,
  /usr/bin/screen rix,
  /usr/bin/ssh rix,
  /usr/bin/ssh-add rix,
  /usr/bin/ssh-agent rix,
  /usr/bin/ssh-copy-id rix,
  /usr/bin/ssh-keygen rix,
  /usr/bin/ssh-keyscan rix,
  /usr/bin/tail rix,
  /usr/bin/tty rix,
  /usr/bin/vim-enhanced rix,
  /usr/bin/wget rix,
  /usr/bin/which rix,
  /usr/lib*/git/git-update-ref rix,
  /usr/lib*/mc/cons.saver rix,
  /usr/lib*/ssh/sftp-server rix,
  /usr/lib*/ssh/ssh-keysign rix,
  /usr/local/bin/ r,
  /usr/share/git-core/*/ r,
  /usr/share/mc/** r,
  /usr/share/vim/** r,
}

This allows the user to execute the most basic commands he needs and allows ssh, sftp and git access. The user has access to some binaires and and can read directories he need for a working shell, like /usr/lib. The owner flag allows him only to write in his own home directory and browse only his home directory.

The next step is to create a new user and use /bin/jailbash as the bash. You can update the profile using logprof or manually if you watch /var/log/audit/audit.log.

comments: 5 »

libsmbconf

Posted on 14th April 2011 in Development, KDE, Linux, Samba

flattr this!

Three years ago Michael Adam created a nice library to easily read the Samba configuration or modify it if it is stored in the registry. Since we have a new build system it is much easier to create shared libraries, I’ve created a public smbconf library now. The library can be used to setup Samba or Winbind without touching any files. Ok, smb.conf needs one entry: config backend = registry. This library should be available with Samba 3.6 which will be released some time this year.

You can find the documentation for the new library here.

comments: 0 »

Logitech Linux Mouse Support

Posted on 22nd February 2011 in Gaming, Hardware, KDE, Linux

flattr this!

Maybe you ask: Why is there still no new version of lomoco to support the latest Logitech Mice?

The answer is that I still don’t know how they detect a mouse connected to a receiver. Maybe they just have a table which defines which mice come with which receiver and then try some commands. If it fails it is mouse X and if not it must be mouse Y.

I already wrote some proof of concept for the new protocol and sometimes people contact me and the proof of concept is enough for them. So here is a list of small proof of concept utils:

g_hack.c

This is a tool to change the resolution on some gaming mice like the G5, G7 and G9.

http://git.lomoco.org/projects/lomoco.git/tree/proof-of-concept/g_hack.c

lomoco_battery.c

Battery information for a lot of cordless mice like MX, VX and VX Nano.

http://git.lomoco.org/projects/lomoco.git/tree/proof-of-concept/lomoco_battery.c

lomoco_reconnect.c

This allows you to reconnect your cordless mouse to the receiver. This is for MX, VX or VX Nano.

http://git.lomoco.org/projects/lomoco.git/tree/proof-of-concept/lomoco_reconnect.c

comments: 46 »

Weave for PIM?

Posted on 9th January 2011 in KDE, Linux

flattr this!

Last year I discovered Mozilla Weave (now Sync). Weave is a Firefox addon and they offer the server components to install your own weave server. It offers everything I would like to have for PIM. So lets start with some details…

The Firefox Sync addon synchronizes the following things between your browsers/computers:

  • bookmarks
  • history
  • forms
  • prefs
  • tabs
  • passwords

The data stored on the weave server should be as private, and as safe, as data on your personal computer or device so they get encrypted on the client by a password only the user knows. So a server operator can’t read the information or disclose them.
The bookmarks are translated into a json format and added as a part to the weave json format. This is encrypted and the encrypted data is sent to the server. You can find more information about the storage format here.

On a second machine you configure the Firefox addon too. You select the synchronization profile (merge this data with my sync data, replace all data with my sync data, replace all other computers data with this data), enter your password for the encrypted data and start the synchronization. The data is downloaded and the sync engine synchronizes everything ins the json format and then translates it to the data store of firefox. I was really astonished how perfect this works.

And exactly this is what I miss for my PIM data! I would like to have my calender and addressbook in weave. This way it would be stored safely on my server. As soon as my machine has a connection to the weave server it should be synchronized or merged together.

I need a 72 hour day.

comments: 9 » tags: ,

gdb backtrace to file

Posted on 23rd December 2010 in KDE, Linux

flattr this!

I wanted a simple command to get a backtrace in a file from gdb. It took me years to finally discover and craft this command!

alias bt='echo 0 | gdb -batch-silent -ex "run" -ex "set logging overwrite on" -ex "set logging file gdb.bt" -ex "set logging on" -ex "set pagination off" -ex "handle SIG33 pass nostop noprint" -ex "echo backtrace:\n" -ex "backtrace full" -ex "echo \n\nregisters:\n" -ex "info registers" -ex "echo \n\ncurrent instructions:\n" -ex "x/16i \$pc" -ex "echo \n\nthreads backtrace:\n" -ex "thread apply all backtrace" -ex "set logging off" -ex "quit" --args'

bt $crashing_application

This will create gdb.bt in your current directory.

comments: 4 » tags: ,

The pain of poll(2)?

Posted on 5th September 2010 in KDE, Linux

flattr this!

If you’re working on a multi-platform project which does network communication you will end up thinking about replacing select(2) with poll(2) sooner or later. The problem with select are well known. poll(2) removes the limitations of select(2) and improves speed and features. The problem is that poll(2) isn’t available on all platforms. This means you need a poll(2)-emulation or create wrappers around other similar poll() functions.

In libssh we use a poll(2)-emulation based on select for platforms which don’t provide a poll(2) function like some Windows versions or UNIX systems.

Windows Vista or newer version provide a poll(2) like function called WSAPoll(). To be able to support this call which is faster the the poll(2)-emulation and allows to use more file descriptors we implemented a runtime detection for WSAPoll(). This means during initialization of the socket, we check if the functions can be found in the relevant library. If Windows doesn’t provide it, we fallback to the poll(2)-emulation.

I took several month to get this working correctly on UNIX and Windows. This feature starts to work correctly with libssh 0.4.6 released today.

comments: 2 » tags: , ,

Featurecasts

Posted on 23rd February 2010 in KDE

flattr this!

Yesterday I’ve visited the Tokamak4 Sprint. I’ve attended the talks in the evening and then had dinner with some KDE hackers. Today I’ve looked at PlanetKDE and saw the KDE bluetooth screencast from Alex Fiestas. I liked the screencasts in the KDE 4.4 announcement, it should the users what’s cool and new. Yesterday I’ve heard the first time about activities in KDE4. I wondered what Aaron is talking about.

Here comes the conclusion:

We need a Featurecast section on the KDE website with screencasts that shows all the cool hidden stuff!

This should be the first thing a user finds on the KDE website. The user normally hasn’t installed KDE at all or doesn’t have the latest version. So the first thing should be something which shows what you can do with it and how cool this stuff is.

comments: 2 » tags: