2007-09-30

C basics: using separate files/modules

My C programming experience is pretty limited, and recently I was trying to convert a monolithic program into separate files/modules. Here are a few notes on the process, in particular the various C language storage classes.

  • Each source file (e.g. mymodule.c) will be compiled to an object file (e.g. mymodule.o)
  • The object files are then linked together to form an executable file or image (i.e. the program file).
  • static global variables are visible to all functions within the current source file. They are not accessible to functions defined in other files.
  • Global variables are static unless declared otherwise.
  • static local variables (i.e. static variables declared within a function) are initialised at run-time but not re-initialised when the function is called.
  • extern global variables are visible to all modules, not just functions within the current source file. Use these for variables to be shared among modules/files.
  • extern variables cannot be initialised in the file declaring them as extern. However, other modules sharing them can initialise them, as they are not extern in that context.
  • If sharing a module among others, write its function prototypes in a header (.h) file, and the function definitions in a source (.c) file. Then just #include the .h file in any dependent modules (do not include the .c file, as this will double up on definitions!).

Typical compilation and linking routine to create an executable:

$ gcc -c -o mymodule.o mymodule.c
$ gcc -c -o anothermodule.o anothermodule.c
$ gcc -c -o main.o main.c
# Linking stage; note use of gcc, not ld!
$ gcc -o myprogram main.o mymodule.o anothermodule.o

New Zealand Daylight Savings Time changes

From 2007, daylight savings time in New Zealand starts one week earlier and finishes two weeks later. My Gentoo system still had the old timezone information, and so wasn't going to switch over on Sunday September 30 as it should:

$ zdump -v /etc/localtime | grep 2007
/etc/localtime  Sat Mar 17 13:59:59 2007 UTC = Sun Mar 18 02:59:59 2007 NZDT isdst=1
/etc/localtime  Sat Mar 17 14:00:00 2007 UTC = Sun Mar 18 02:00:00 2007 NZST isdst=0
/etc/localtime  Sat Oct  6 13:59:59 2007 UTC = Sun Oct  7 01:59:59 2007 NZST isdst=0
/etc/localtime  Sat Oct  6 14:00:00 2007 UTC = Sun Oct  7 03:00:00 2007 NZDT isdst=1

Solution: update the timezone-data package:

$ emerge -av sys-libs/timezone-data

(Alternatively, download the timezone data source directly from ftp://elsie.nci.nih.gov/pub/tzdata2007g.tar.gz and compile using zic.)

And restart the Network Time Protocol server, for good measure:

$ /etc/init.d/ntpd stop
$ ntpd -qgx
$ /etc/init.d/ntpd start
$ # wait a few minutes, then check the time...
$ ntptime

Once NTP’s timekeeping has settled down, you might also want to set the hardware clock.

$ hwclock --systohc
$ hwclock --show

2007-09-13

Simulating profiles with Echomixer

Echomixer is a mixer control utility for Echo Audio sound interfaces (I have a Gina24 PCI) on Linux. These cards have quite a few settings to control, and don't seem to fit into the generic controller approach taken by alsamixer.

AFAICT, Echomixer doesn’t support anything like a profile or the loading of a specific settings file: it always uses the file ~/.Emixer_Gina24. I would like to be able to configure the card for different applications, such as multitrack recording, gaming, playing a DVD, etc. For example, for DVD playback, I want to use the internal audio clock so that the sampling rate can be set exactly, without the need to resample the audio (e.g. for 46.08 kHz audio playback for 24 FPS movies deployed as 25 FPS PAL @ 48 kHz), with the PCM output level at 0 dB. For multitrack recording, I want to use the external ADAT clock so I can record the additional 8 channels I have on a chained ADAT interface, with the PCM output level at around -9 dB so I can hear live stuff easily over the backing tracks.

TODO: details, scripts, etc.

Bah, only it looks like Echomixer doesn’t save the clock source in its settings file. Dang.

2007-09-12

Installing PAM package on NetBSD a bad idea?

While installing and testing the RoundCube Web-mail system on my NetBSD-based Web server and network router, I found myself unable to shut down Apache (even with kill -9). Eventually I relented and restarted the OS, ruining my uptime of about 160 days in the process.

When the system came back up, I couldn’t log in! After entering the username, I just got returned to the login prompt after the following rudeness:

login: Undefined PLT symbol "openpam_ttyconv (symnum=47)"

The kernel mesages also included something like:

PAM unable to dlopen(/usr/pkg/lib/security/pam_cracklib.so)

Network access to the machine seemed to be down as well. Not the best scenario for trying to fix anything!

A reboot into single-user mode (-s kernel bootloader option) or two later, and some fun trying to research and resolve the problem with my main network router out of action(!), and I discovered that networking was OK after all, and I could ssh in and try to fix things.

It seems installing the PAM pluggable authentication modules system from pkgsrc was the culprit. I can’t remember when or why in the last 160 days I did this, but apparently I did, and it didn’t cause any problems until the recent reboot. It seems the login program was being dynamically linked to the PAM library from the package, not the main system one (which apparently already existed). With the extra PAM package installed, ldd /usr/bin/login showed that it was linking to /usr/pkg/lib/libpam.so.0, which didn't work. After uninstalling the extra PAM package, it was linked instead to /usr/lib/libpam.so.0, which worked fine.

AFAICT, there are two PAM libraries in pkgsrc, in addition to the main system one: openpam and Linux PAM (I think the one I had installed was the Linux one, PAM-0.77nb5).

Windows WinPopUp messages and Linux

I've known for a while that Samba provides a WinPopUp client, for sending instant messages to Microsoft Windows clients over the network. It’s a facility of the smbclient utility, and can be used like so:

$ smbclient -M SomeWindowsBox
Connected. Type your message, ending it with a Control-D
Hi, Windows user!
sent 19 bytes

The user on the computer named SomeWindowsBox will see the message pop up on their screen (possibly stealing focus and making an annoying dinging sound).

smbclient will also accept input from stdin. For example, to report disk free space remotely:

$ df -h | smbclient -M AdminMachine

It turns out you can also receive such messages on Linux, via Samba’s smbd server daemon. To enable this, add a message command directive in the Samba configuration file of the receiving system (usually /etc/samba/smb.conf). Here is the example from the smb.conf manual page:

message command = csh -c 'xedit %s;rm %s' &

This didn’t work on my Gentoo box for a number of reasons: I hadn't installed the csh or xedit commands, for a start! I also have two X Window System displays, and wanted the pop-up messages to appear on a specific display, requiring the DISPLAY environment variable to be set. Also, I had to use xhost to tell the X server to allow xmessage from the local system to display its goodies.

Here is the setting that I ended up using in smb.conf:

message command = /bin/bash -c 'export DISPLAY=:0.1; /usr/bin/xmessage -file %s; rm %s' &

TODO: integrate with the Ion window manager, perhaps to get the message to appear in an appropriate frame without stealing focus, etc.

First Post

How can I call myself a geek if I don’t even have a blog?! This is my attempt to remedy the situation. I will just have to hope that I’ll have something to say.

Even in the worst-case scenario, this blog will just degenerate into a collection of notes-to-self, which (with any luck) others might also find useful.

Wish me luck!

HTML Markup Testing

This is just a scratchpad for trying out different markup.

0 1 2 3
0 1 2 3
A B C D

XML

“Blessed are the forgetful, for they get the better even of their blunders.”

[.bashrc]
[.profile]
~>
df -h
Filesystem Size Used Avail Use% Mounted on
D:\cygwin\usr\X11R6\lib\X11\fonts
92G 43G 50G 47% /usr/X11R6/lib/X11/fonts
D:\cygwin\bin 92G 43G 50G 47% /usr/bin
D:\cygwin\lib 92G 43G 50G 47% /usr/lib
D:\cygwin 92G 43G 50G 47% /
df: `/cdrom': No medium found
d: 92G 43G 50G 47% /user
b: 64M 0 64M 0% /cygdrive/b
c: 21G 18G 2.4G 89% /cygdrive/c
g: 1.0T 941G 84G 92% /cygdrive/g
m: 1.0T 941G 84G 92% /cygdrive/m
v: 1.0T 941G 84G 92% /cygdrive/v
w: 102G 56G 47G 55% /cygdrive/w
x: 1.0T 941G 84G 92% /cygdrive/x
z: 1.0T 941G 84G 92% /cygdrive/z