The username and hostname in a utmp entry is not guarranteed to be NUL
terminated. Specifically, if a user's name is exactly UT_NAMESIZE (32 on
most systems today), the last character will not in fact be NUL. This
creates a problem in the line 866 for example, where strncpy is used to
copy all but the last byte of the utmp username in user. This will cause
an error in the specific case where strlen(utmpp->ut_user) =
UT_NAMESIZE.
The solution is to simply make user and host one byte longer, thereby
letting them have a place for the terminating NUL, after this, they can
be treated as regular strings without any error or extra precaution.
Since most of the #ifdef hacks are meant to facilitate the use of the
daemon under older versions of SunOS which didn't have many of the utmp
library functions and facilities most modern Unices have, and since they
significantly hamper the readability of the code, they have been
removed. For portabilities sake, further changes will have to be made
anyways, many modern systems, such as newer versions of FreeBSD, don't
support utmp anymore, and require use of utmpx instead. The program will
have to be changed accordingly.
The getdisc() function has been almost entirely stripped, and now is
just a stub that always returns N_TTY. This will have to be changed
quickly, so that the function returns the actual tty discipline, but
works in most cases.
Changed the startup in the main function to loop through all file
descriptors from getrlimit(RLIMIT_NOFILE) down to 0, and close them all
to make sure none are left opened by the parent process.
In order to start a daemon, a second call for fork() after changing
session ID is usually required, in order to prevent acquiring a
controlling tty when it eventually writes to one.
The variable ut_list_p, is used in two seperate functions, read_wtmp()
and free_wtmp(), it's state isn't preserved, nor is it important,
therefore it's cleaner to simply use two local variables in each
function, rather than one global variable, used across both.
The string array *messages[] in the config_ent structure, which is used
to store configuration data during runtime, has been shortened to have 4
strings, rather than 10, this is due to the fact that it's only used
with indeces IDLEMSG, SESSMSG, DAYMSG and NOLOGINMSG, or a variable with
one of these as a value. These indeces are all symbolic constants with
values 0 through 3, so only 4 members in the array are needed.
At the start of the check_idle() function, there is an unnecessary local
declaration of time(2), which is already declared at the start of the
program. It has been removed.
There were two lines in the check_idle() function, which were meant to
test if a given user has been found in a given line of the configuration
file. Rather than using the chkmatch function, to test for a match, and
any potential expansions, these two lines, comprising an if statement,
simply checked if the USER pattern matched the given username as a
string, or if it was simply a *.
This means that if a function was checking the user kappa, it would
match him for the USERS field "kappa" or "*", but not "ka*", this is not
the behaviour documented in the timeouts(5) manpage, which explicitly
states the expansion for the USERS field in the config, will be done in
the exact same way as the TTYS field.
There are three string literals in the code where rather than having the
usual \a escape sequence to represent an alert character, the literal
character was inserted, this makes it impractical to edit the lines in
most text editors. So they have been replaced with the more typical
escape sequence.
The entire source code of timeoutd.c has been passed through GNU indent,
in order to amend the inconsistencies, it uses the K&R C style, but
modified, so that tabs are replaced with 4 spaces, close to what a lot
of the code was already using. (Blasphemy, i know) Also the maximum line
length is 100 chars, apart from long strings, which don't get cut as a
result.
Several lines in the code either have whitespace where tabs are
expected, the converse, or trailing whitespace before a newline. All
of these have been removed or replaced.
There are several lines in the code which cause GCC to warn the user
about undefined behaviour. Most of these are potential buffer overflow
problems. Which come from either overwriting a buffer which may be too
small for a given input, or writing to, or from, a string not guaranteed
to be null-terminated, such as any of the char[] fields in a utmp
struct. Almost all come from an improper usage of strcmp or strncmp or
similar.