diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:53 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:53 +0000 |
commit | 4a979ad921e2733b8e3e178928240cf8a60ad07b (patch) | |
tree | c98f771b2a8e193bdd21702bbd5af30ff01cfd5d |
R6.6 is the Xorg base-lineXORG-MAINXORG-STABLE
-rw-r--r-- | sessreg.c | 495 | ||||
-rw-r--r-- | sessreg.man | 120 |
2 files changed, 615 insertions, 0 deletions
diff --git a/sessreg.c b/sessreg.c new file mode 100644 index 0000000..748608a --- /dev/null +++ b/sessreg.c @@ -0,0 +1,495 @@ +/* + * $Xorg: sessreg.c,v 1.5 2000/08/17 19:54:15 cpqbld Exp $ + * + * Copyright 1990, 1998 The Open Group + * + * All Rights Reserved. + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of The Open Group shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization + * from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + * Lastlog support and dynamic utmp entry allocation + * by Andreas Stolcke <stolcke@icsi.berkeley.edu> + */ + +/* + * sessreg + * + * simple wtmp/utmp frobber + * + * usage: sessreg [ -w <wtmp-file> ] [ -u <utmp-file> ] + * [ -l <line> ] + * [ -h <host-name> ] / BSD only + * [ -s <slot-number> ] [ -x Xservers-file ] / BSD only + * [ -t <ttys-file> ] / BSD only + * [ -a ] [ -d ] user-name + * + * one of -a or -d must be specified + */ + + +# include <X11/Xos.h> +# include <X11/Xfuncs.h> +# include <stdio.h> +# include <utmp.h> + +#if defined(SYSV) || defined(_SEQUENT_) +#define NO_LASTLOG +#endif + +#ifndef NO_LASTLOG +# ifndef CSRG_BASED +# include <lastlog.h> +# endif +# include <pwd.h> +#endif + +#if defined(SVR4) || defined(linux) +#define SYSV /* nice System V utmp interface still the same */ +#endif + +#ifndef WTMP_FILE +# ifdef _PATH_WTMP +# define WTMP_FILE _PATH_WTMP +# else +# define WTMP_FILE "/usr/adm/wtmp" +# endif +#endif +#ifndef UTMP_FILE +# ifdef _PATH_UTMP +# define UTMP_FILE _PATH_UTMP +# else +# define UTMP_FILE "/etc/utmp" +# endif +#endif +#ifndef NO_LASTLOG +# ifndef LLOG_FILE +# ifdef _PATH_LASTLOG +# define LLOG_FILE _PATH_LASTLOG +# else +# define LLOG_FILE "/usr/adm/lastlog" +# endif +# endif +#endif +#ifndef SYSV +# ifndef TTYS_FILE +# define TTYS_FILE "/etc/ttys" +# endif +#endif + +#ifdef X_NOT_STDC_ENV +#define Time_t long +extern Time_t time (); +#else +#include <time.h> +#define Time_t time_t +#endif +#ifdef X_NOT_POSIX +extern long lseek (); +extern char *ttyname (); +#endif + +int wflag, uflag, lflag; +char *wtmp_file, *utmp_file, *line; +int utmp_none, wtmp_none; +/* + * BSD specific variables. To make life much easier for Xstartup/Xreset + * maintainers, these arguments are accepted but ignored for sysV + */ +int hflag, sflag, xflag, tflag; +char *host_name; +int slot_number; +char *xservers_file, *ttys_file; +char *user_name; +int aflag, dflag; +#ifndef NO_LASTLOG +char *llog_file; +int llog_none, Lflag; +#endif + +char *program_name; + +usage (x) +{ + if (x) { + fprintf (stderr, "%s: usage %s {-a -d} [-w wtmp-file] [-u utmp-file]", program_name, program_name); +#ifndef NO_LASTLOG + fprintf (stderr, " [-L lastlog-file]"); +#endif + fprintf (stderr, "\n"); + fprintf (stderr, " [-t ttys-file] [-l line-name] [-h host-name]\n"); + fprintf (stderr, " [-s slot-number] [-x servers-file] user-name\n"); + exit (1); + } + return x; +} + +char * +getstring (avp, flagp) +char ***avp; +int *flagp; +{ + char **a = *avp; + + usage ((*flagp)++); + if (*++*a) + return *a; + ++a; + usage (!*a); + *avp = a; + return *a; +} + +syserr (x, s) +int x; +char *s; +{ + if (x == -1) { + perror (s); + exit (1); + } + return x; +} + +sysnerr (x, s) +int x; +char *s; +{ + if (x == 0) { + perror (s); + exit (1); + } + return x; +} + +main (argc, argv) +int argc; +char **argv; +{ +#ifndef SYSV + int utmp; +#endif + char *line_tmp; + int wtmp; + Time_t current_time; + struct utmp utmp_entry; + + program_name = argv[0]; + while (*++argv && **argv == '-') { + switch (*++*argv) { + case 'w': + wtmp_file = getstring (&argv, &wflag); + if (!strcmp (wtmp_file, "none")) + wtmp_none = 1; + break; + case 'u': + utmp_file = getstring (&argv, &uflag); + if (!strcmp (utmp_file, "none")) + utmp_none = 1; + break; +#ifndef NO_LASTLOG + case 'L': + llog_file = getstring (&argv, &Lflag); + if (!strcmp (llog_file, "none")) + llog_none = 1; + break; +#endif + case 't': + ttys_file = getstring (&argv, &tflag); + break; + case 'l': + line = getstring (&argv, &lflag); + break; + case 'h': + host_name = getstring (&argv, &hflag); + break; + case 's': + slot_number = atoi (getstring (&argv, &sflag)); + break; + case 'x': + xservers_file = getstring (&argv, &xflag); + break; + case 'a': + aflag++; + break; + case 'd': + dflag++; + break; + default: + usage (1); + } + } + usage (!(user_name = *argv++)); + usage (*argv != 0); + /* + * complain if neither aflag nor dflag are set, + * or if both are set. + */ + usage (!(aflag ^ dflag)); + usage (xflag && !lflag); + /* set up default file names */ + if (!wflag) + wtmp_file = WTMP_FILE; + if (!uflag) + utmp_file = UTMP_FILE; +#ifndef NO_LASTLOG + if (!Lflag) + llog_file = LLOG_FILE; +#endif +#if !defined(SYSV) && !defined(linux) + if (!tflag) + ttys_file = TTYS_FILE; + if (!sflag && !utmp_none) { + if (xflag) + sysnerr (slot_number = Xslot (ttys_file, xservers_file, line, host_name, aflag), "Xslot"); + else + sysnerr (slot_number = ttyslot (), "ttyslot"); + } +#endif + if (!lflag) { + sysnerr ((int) (line_tmp = ttyname (0)), "ttyname"); + line = strrchr(line_tmp, '/'); + if (line) + line = line + 1; + else + line = line_tmp; + } + current_time = time ((Time_t *) 0); + set_utmp (&utmp_entry, line, user_name, host_name, current_time, aflag); + if (!utmp_none) { +#ifdef SYSV + utmpname (utmp_file); + setutent (); + (void) getutid (&utmp_entry); + pututline (&utmp_entry); + endutent (); +#else + utmp = open (utmp_file, O_RDWR); + if (utmp != -1) { + syserr ((int) lseek (utmp, (long) slot_number * sizeof (struct utmp), 0), "lseek"); + sysnerr (write (utmp, (char *) &utmp_entry, sizeof (utmp_entry)) + == sizeof (utmp_entry), "write utmp entry"); + close (utmp); + } +#endif + } + if (!wtmp_none) { + wtmp = open (wtmp_file, O_WRONLY|O_APPEND); + if (wtmp != -1) { + sysnerr (write (wtmp, (char *) &utmp_entry, sizeof (utmp_entry)) + == sizeof (utmp_entry), "write wtmp entry"); + close (wtmp); + } + } +#ifndef NO_LASTLOG + if (aflag && !llog_none) { + int llog; + struct passwd *pwd = getpwnam(user_name); + + sysnerr( pwd != NULL, "get user id"); + llog = open (llog_file, O_WRONLY); + + if (llog != -1) { + struct lastlog ll; + + bzero((char *)&ll, sizeof(ll)); + ll.ll_time = current_time; + if (line) + (void) strncpy (ll.ll_line, line, sizeof (ll.ll_line)); + if (host_name) + (void) strncpy (ll.ll_host, host_name, sizeof (ll.ll_host)); + + sysnerr (lseek(llog, (long) pwd->pw_uid*sizeof(ll), 0) != -1, "seeking lastlog entry"); + sysnerr (write (llog, (char *) &ll, sizeof (ll)) + == sizeof (ll), "write lastlog entry"); + close (llog); + } + } +#endif + return 0; +} + +/* + * fill in the appropriate records of the utmp entry + */ + +set_utmp (u, line, user, host, date, addp) +struct utmp *u; +char *line, *user, *host; +Time_t date; +{ + if (line) + (void) strncpy (u->ut_line, line, sizeof (u->ut_line)); + else + bzero (u->ut_line, sizeof (u->ut_line)); + if (addp && user) + (void) strncpy (u->ut_name, user, sizeof (u->ut_name)); + else + bzero (u->ut_name, sizeof (u->ut_name)); +#ifdef SYSV + if (line) { + int i; + /* + * this is a bit crufty, but + * follows the apparent conventions in + * the ttys file. ut_id is only 4 bytes + * long, and the last 4 bytes of the line + * name are written into it, left justified. + */ + i = strlen (line); + if (i >= sizeof (u->ut_id)) + i -= sizeof (u->ut_id); + else + i = 0; + (void) strncpy (u->ut_id, line + i, sizeof (u->ut_id)); + } else + bzero (u->ut_id, sizeof (u->ut_id)); + if (addp) { + u->ut_pid = getppid (); + u->ut_type = USER_PROCESS; + } else { + u->ut_pid = 0; + u->ut_type = DEAD_PROCESS; + } +#else + if (addp && host) + (void) strncpy (u->ut_host, host, sizeof (u->ut_host)); + else + bzero (u->ut_host, sizeof (u->ut_host)); +#endif + u->ut_time = date; +} + +#ifndef SYSV +/* + * compute the slot-number for an X display. This is computed + * by counting the lines in /etc/ttys and adding the line-number + * that the display appears on in Xservers. This is a poor + * design, but is limited by the non-existant interface to utmp. + * If host_name is non-NULL, assume it contains the display name, + * otherwise use the tty_line argument (i.e., the tty name). + */ + +Xslot (ttys_file, servers_file, tty_line, host_name, addp) +char *ttys_file; +char *servers_file; +char *tty_line; +char *host_name; +int addp; +{ + FILE *ttys, *servers; + int c; + int slot = 1; + int column0 = 1; + char servers_line[1024]; + char disp_name[512]; + int len; + char *pos; + + /* remove screen number from the display name */ + strcpy(disp_name, host_name ? host_name : tty_line); + pos = strrchr(disp_name, ':'); + if (pos) { + pos = strchr(pos, '.'); + if (pos) + *pos = '\0'; + } + sysnerr (ttys = fopen (ttys_file, "r"), ttys_file); + while ((c = getc (ttys)) != EOF) + if (c == '\n') { + ++slot; + column0 = 1; + } else + column0 = 0; + if (!column0) + ++slot; + (void) fclose (ttys); + sysnerr (servers = fopen (servers_file, "r"), servers_file); + + len = strlen (disp_name); + column0 = 1; + while (fgets (servers_line, sizeof (servers_line), servers)) { + if (column0 && *servers_line != '#') { + if (!strncmp (disp_name, servers_line, len) && + (servers_line[len] == ' ' || + servers_line[len] == '\t')) + return slot; + ++slot; + } + if (servers_line[strlen(servers_line)-1] != '\n') + column0 = 0; + else + column0 = 1; + } + /* + * display not found in Xservers file - allocate utmp entry dinamically + */ + return findslot (tty_line, host_name, addp, slot); +} + +/* + * find a free utmp slot for the X display. This allocates a new entry + * past the regular tty entries if necessary, reusing existing entries + * (identified by (line,hostname)) if possible. + */ +findslot (line_name, host_name, addp, slot) +char *line_name; +char *host_name; +int addp; +int slot; +{ + int utmp; + struct utmp entry; + int found = 0; + int freeslot = -1; + + syserr(utmp = open (utmp_file, O_RDONLY), "open utmp"); + + /* + * first, try to locate a previous entry for this display + * also record location of a free slots in case we need a new one + */ + syserr ((int) lseek (utmp, (long) slot * sizeof (struct utmp), 0), "lseek"); + + if (!host_name) + host_name = ""; + + while (read (utmp, (char *) &entry, sizeof (entry)) == sizeof (entry)) { + if (strncmp(entry.ut_line, line_name, + sizeof(entry.ut_line)) == 0 && + strncmp(entry.ut_host, host_name, + sizeof(entry.ut_host)) == 0) { + found = 1; + break; + } + if (freeslot < 0 && *entry.ut_name == '\0') + freeslot = slot; + ++slot; + } + + close (utmp); + + if (found) + return slot; + else if (!addp) + return 0; /* trying to delete a non-existing entry */ + else if (freeslot < 0) + return slot; /* first slot past current entries */ + else + return freeslot; +} +#endif diff --git a/sessreg.man b/sessreg.man new file mode 100644 index 0000000..9af0168 --- /dev/null +++ b/sessreg.man @@ -0,0 +1,120 @@ +.\" $Xorg: sessreg.man,v 1.4 2001/02/09 02:05:40 xorgcvs Exp $ +.\" Copyright 1994, 1998 The Open Group +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and its +.\" documentation for any purpose is hereby granted without fee, provided that +.\" the above copyright notice appear in all copies and that both that +.\" copyright notice and this permission notice appear in supporting +.\" documentation. +.\" +.\" The above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.TH SESSREG 1 "Release 6.4" "X Version 11" +.SH NAME +sessreg \- manage utmp/wtmp entries for non-init clients +.SH SYNOPSIS +.B sessreg +[-w \fIwtmp-file\fP] +[-u \fIutmp-file\fP] +[-l \fIline-name\fP] +[-h \fIhost-name\fP] +[-s \fIslot-number\fP] +[-x \fIXservers-file\fP] +[-t \fIttys-file\fP] +[-a] +[-d] +\fIuser-name\fP +.SH DESCRIPTION +.PP +\fISessreg\fP is a simple program for managing utmp/wtmp +entries for xdm sessions. +.PP +System V has a better interface to /etc/utmp than BSD; it +dynamically allocates entries in the file, instead of writing them at fixed +positions indexed by position in /etc/ttys. +.PP +To manage BSD-style utmp files, \fIsessreg\fP has two strategies. In +conjunction with xdm, the -x option counts the number of lines in /etc/ttys +and then adds to that the number of the line in the Xservers file which +specifies the display. The display name must be specified as the +"line-name" using the -l option. This sum is used as the "slot-number" in +/etc/utmp that this entry will be written at. In the more general case, the +-s option specifies the slot-number directly. If for some strange reason +your system uses a file other that /etc/ttys to manage init, the -t option +can direct +\fIsessreg\fP to look elsewhere for a count of terminal sessions. +.PP +Conversely, System V managers will not ever need to use these options (-x, +-s and -t). To make the program easier to document and explain, +\fIsessreg\fP accepts the BSD-specific flags in the System V +environment and ignores them. +.PP +BSD also has a host-name field in the utmp file which doesn't exist in +System V. This option is also ignored by the System V version of +\fIsessreg\fP. +.SH USAGE +.PP +In Xstartup, place a call like: +.nf + + sessreg -a -l $DISPLAY -x /usr/X11R6/lib/xdm/Xservers $USER + +.fi +and in Xreset: +.nf + + sessreg -d -l $DISPLAY -x /usr/X11R6/lib/xdm/Xservers $USER +.fi +.SH OPTIONS +.IP "\fB-w\fP \fIwtmp-file\fP" +This specifies an alternate wtmp file, instead of /usr/adm/wtmp for BSD or +/etc/wtmp for sysV. The special name "none" disables writing records to +/usr/adm/wtmp. +.IP "\fB-u\fP \fIutmp-file\fP" +This specifies an alternate utmp file, instead of "/etc/utmp". The special +name "none" disables writing records to /etc/utmp. +.IP "\fB-l\fP \fIline-name\fP" +This describes the "line" name of the entry. For terminal sessions, +this is the final pathname segment of the terminal device filename +(e.g. ttyd0). For X sessions, it should probably be the local display name +given to the users session (e.g. :0). If none is specified, the +terminal name will be determined with ttyname(3) and stripped of leading +components. +.IP "\fB-h\fP \fIhost-name\fP" +This is set for BSD hosts to indicate that the session was initiated from +a remote host. In typical xdm usage, this options is not used. +.IP "\fB-s\fP \fIslot-number\fP" +Each potential session has a unique slot number in BSD systems, most are +identified by the position of the \fIline-name\fP in the /etc/ttys file. +This option overrides the default position determined with ttyslot(3). +This option is inappropriate for use with xdm, the -x option is more useful. +.IP "\fB-x\fP \fIXservers-file\fP" +As X sessions are one-per-display, and each display is entered in this file, +this options sets the \fIslot-number\fP to be the number of lines in +the \fIttys-file\fP plus the index into this file that the \fIline-name\fP +is found. +.IP "\fB-t\fP \fIttys-file\fP" +This specifies an alternate file which the \fI-x\fP option will use to count +the number of terminal sessions on a host. +.IP "\fB-a\fP" +This session should be added to utmp/wtmp. +.IP "\fB-d\fP" +This session should be deleted from utmp/wtmp. One of -a/-d must +be specified. +.SH "SEE ALSO" +xdm(1) +.SH AUTHOR +Keith Packard, MIT X Consortium |