- Subject: libc/1463: Want option to make utmpd create/delete utmp files
- From: Michael Deutschmann <michael at talamasca dot wkpowerlink dot com>
- Date: Fri Nov 26 14:04:05 1999
Topics:
libc/1463: Want option to make utmpd create/delete utmp files
----------------------------------------------------------------------
Date: Sun, 21 Nov 1999 15:45:50 -0800 (PST)
From: Michael Deutschmann <michael@talamasca.wkpowerlink.com>
To: bugs@gnu.org
Subject: libc/1463: Want option to make utmpd create/delete utmp files
Message-Id: <%gPIO4QtCW@khar-pern.talamasca>
>Number: 1463
>Category: libc
>Synopsis: Want option to make utmpd create/delete utmp files
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: libc-gnats
>State: open
>Class: change-request
>Submitter-Id: unknown
>Arrival-Date: Sun Nov 21 18:50:02 EST 1999
>Last-Modified:
>Originator: Michael Deutschmann
>Organization:
>Release: libc-2.1.2
>Environment:
Host type: i486-pc-linux-gnu
System: Linux khar-pern 2.0.38 #6 Wed Nov 10 02:25:51 PST 1999 i486 unknown
Addons: crypt linuxthreads
Build CFLAGS: -O3 -mcpu=i486 -march=i486 -fomit-frame-pointer -pipe
Build CC: gcc
Compiler version: 2.95.1 19990816 (release)
Symbol versioning: yes
Build static: yes
Build shared: yes
Build pic-default: no
Build profile: no
Build omitfp: no
Build bounded: no
Build static-nss: no
Stdio: libio
>Description:
I'd like the utmpd program to support an option, say --bootup, that would
cause it to:
* Create the /var/run/utmp and /var/run/utmpx files, truncating them
if they exist and setting their permissions correctly before starting.
Also add the startup record to WTMP.
* When utmpd is SIGTERMed, write a shutdown record to WTMP and delete both
files before exiting.
I'd like this as I have written and published a suite of programs,
runset-1.2, that do the work of an init daemon. My program automatically
handles the creation of the utmp file, and deletes it as shutdown.
Unfortunately, these operations change on a utmpd system, and there is no
way to express such boot-time actions using the libc functions.
I could add special case code to handle both the no-UTMPD and UTMPD
cases, but that's ugly. I'd rather tell my users to replace the internal
utmp-setup command with a call to the utmpd daemon, with this special flag.
Runset will then start/stop the daemon at an appropriate point in the
startup/shutdown sequence, and the system will be stable if utmpd ever
changes to use different files.
I also need a disable-autobackground flag.
>How-To-Repeat:
>Fix:
Here's a diff. However this is *only a model* of the changes
neccessary. I use a native glibc utmp on my own system and am not
willing to take the stability risk of temporarily switching to the old
format to run utmpd. Hence, I *cannot test it*.
Additionally, I am not sure how to do an updwtmp() safely within utmpd,
so I just left #error lines to indicate where the action is needed.
diff -durp utmpd-orig/utmpd.c utmpd-work/utmpd.c
- -- utmpd-orig/utmpd.c Sun Nov 21 01:38:22 1999
+++ utmpd-work/utmpd.c Sun Nov 21 15:40:26 1999
@@ -55,6 +55,8 @@ static const struct option long_options[
{ "debug", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
+ { "foreground", no_argument, NULL, 'F'},
+ { "bootup", no_argument, NULL, 'B'},
{ NULL, 0, NULL, 0}
};
@@ -67,6 +69,8 @@ int ro_sock = -1;
/* The socket for read/write requests. */
int rw_sock = -1;
+/* Whether we are handling boot/shutdown chores */
+int bootmode = 0;
/* Prototypes for the local functions. */
static void usage (int status) __attribute__ ((noreturn));
@@ -83,6 +87,7 @@ main (int argc, char *argv[])
{
mode_t mask;
int debug;
+ int foreground;
int do_help;
int do_version;
int opt;
@@ -95,10 +100,11 @@ main (int argc, char *argv[])
/* Initialize local variables. */
debug = 0;
+ foreground = 0;
do_help = 0;
do_version = 0;
- while ((opt = getopt_long (argc, argv, "dhV", long_options, NULL)) != -1)
+ while ((opt = getopt_long (argc, argv, "dhBFV", long_options, NULL)) != -1)
switch (opt)
{
case '\0': /* Long option. */
@@ -109,6 +115,12 @@ main (int argc, char *argv[])
case 'd':
debug = 1;
break;
+ case 'F':
+ foreground = 1;
+ break;
+ case 'B':
+ bootmode = 1;
+ break;
case 'V':
do_version = 1;
break;
@@ -146,6 +158,13 @@ warranty; not even for MERCHANTABILITY o
unlink (_PATH_UTMPD_RO);
unlink (_PATH_UTMPD_RW);
+ /* Flush away any old UTMP files leftover from previous boot */
+ if (bootmode)
+ {
+ unlink(_PATH_UTMP "x");
+ unlink(_PATH_UTMP);
+ }
+
/* Open UTMP database. */
utmp_db = open_database (_PATH_UTMP "x", _PATH_UTMP);
if (utmp_db == NULL)
@@ -165,7 +184,7 @@ warranty; not even for MERCHANTABILITY o
_("cannot enable socket to accept connections"));
/* Behave like a daemon. */
- if (!debug)
+ if (!debug && !foreground)
{
openlog ("utmpd", LOG_CONS | LOG_ODELAY, LOG_DAEMON);
@@ -182,9 +201,38 @@ warranty; not even for MERCHANTABILITY o
signal (SIGTSTP, SIG_IGN);
}
+ if (foreground)
+ {
+ openlog ("utmpd", LOG_CONS | LOG_ODELAY, LOG_DAEMON);
+
+ /* A lie... But if we run from an init daemon, we want to stay in
+ * foreground, but log to syslog.
+ *
+ * (probably should rename "forked" variable, but I'm trying to
+ * confine changes to one file)
+ */
+ forked = 1;
+ }
+
/* Drop priviliges. */
drop_priviliges ();
+ /* Add startup record */
+ if (bootmode)
+ {
+ struct utmp startup;
+ memset(&startup,0,sizeof (struct utmp));
+
+ time(&startup.ut_time);
+ strcpy(startup.ut_user,"reboot");
+ strcpy(startup.ut_id,"~~");
+ strcpy(startup.ut_line,"~");
+ startup.ut_type = BOOT_TIME;
+
+ /* Submit this to WTMP -- I can't figure out how to do this */
+#error Please supply command to write out record to WTMP
+ }
+
/* Handle incoming requests. */
handle_requests ();
}
@@ -203,7 +251,9 @@ usage (int status)
Usage: %s [OPTION]...\n\
-d, --debug do not fork and display messages on the current tty\n\
-h, --help display this help and exit\n\
- -V, --version output version information and exit\n"),
+ -V, --version output version information and exit\n\
+ -F, --foreground do not fork\n\
+ -B, --bootup perform boot logging, and flush UTMP at start/stop\n"),
program_invocation_name);
fputs (_("\
Report bugs using the `glibcbug' script to <bugs@gnu.org>.\n"),
@@ -367,11 +417,33 @@ termination_handler (int signum)
unlink (_PATH_UTMPD_RO);
unlink (_PATH_UTMPD_RW);
+ /* Add shutdown record */
+ if (bootmode)
+ {
+ struct utmp shutdown;
+ memset(&shutdown,0,sizeof (struct utmp));
+
+ time(&shutdown.ut_time);
+ strcpy(shutdown.ut_user,"shutdown");
+ strcpy(shutdown.ut_id,"~~");
+ strcpy(shutdown.ut_line,"~");
+ shutdown.ut_type = RUN_LVL;
+
+#error Please supply command to write out record to WTMP
+ }
+
if (utmp_db)
close_database (utmp_db);
/* Clean up pid file. */
unlink (_PATH_UTMPDPID);
+
+ /* Clean up database files */
+ if (bootmode)
+ {
+ unlink(_PATH_UTMP "x");
+ unlink(_PATH_UTMP);
+ }
exit (EXIT_SUCCESS);
}
>Audit-Trail:
>Unformatted:
------------------------------
End of forward0gC-_l Digest
***************************