home *** CD-ROM | disk | FTP | other *** search
- /*
- The problem often seems to arise in dealing with terminated
- xterms. (This is yet another reason for why we need a real
- session manager.) Rebooting to fix utmp is unduly harsh!
- Just use a binary editor of some sort or write a single-purpose
- script to hammer a null at the beginning of the entry. In
- either case, you'll need to understand the format of utmp(5).
-
- Or you could use the following program, written by a younger
- version of myself long ago and far away. It's aesthetically
- bothersome in various ways, but it still works well enough to
- get the job done on the machines I have to deal with, even today.
-
- To clear an entry on say ttyp5, as root type:
-
- chusr '' ttyp5
-
- --tom
- */
-
- /*
- * chusr.c -- change user entry in utmp
- *
- * Tom Christiansen (1984), for BSD4.2 systems
- *
- * (various minor hacks since then, like 4.3 compat stuff)
- */
-
- #include <stdio.h>
- #include <pwd.h>
- #include <sys/file.h>
- #include <sysexits.h>
- #include <syslog.h>
- #include <utmp.h>
-
- #define SCPYN(to,from) (void) strncpy(to,from,sizeof(to))
-
- #ifndef BSD42
- # define BSD43 1
- #endif
-
-
- char *strncpy ();
- char *ttyname ();
- char *index ();
- char *rindex ();
- int strncmp ();
-
- main (ac, av)
- char **av;
- {
- struct utmp utmp; /* new utmp entry for utmp file */
-
- int nentries, /* how many we got */
- ufd, /* utmp's fd */
- tslot, /* where to put the entry */
- tflag = 0; /* update time? */
-
- char *mytty = "/dev/ttyXXXX",
- *ufile = "/etc/utmp",
- *s;
-
- if (ac < 2 || ac > 4)
- usage (*av);
-
-
- if (!strcmp (av[1], "-t")) {
- tflag++;
- av++;
- ac--;
- }
- s = av[2];
-
- if ((ufd = open (ufile, O_RDWR)) < 0) {
- perror (ufile);
- exit (EX_OSFILE);
- }
- if (ac == 2) {
- if ((mytty = ttyname (fileno (stdin))) == NULL) {
- fprintf (stderr, "%s: no tty\n", *av);
- exit (EX_UNAVAILABLE);
- }
- } else {
- if (strlen (s) == 2) {
- if (s[0] == 'c' && s[1] == 'o')
- strcpy (rindex (mytty, '/') + 1, "console");
- else if (s[0] == 'e' && s[1] == 'x')
- strcpy (rindex (mytty, '/') + 1, "express");
- else
- strcpy (index (mytty, 'X'), s);
- } else {
- char *i1 = index (mytty, 't');
- char *i2 = index (s, 't');
- if (!i1) {
- printf(stderr,"no t in %s\n", mytty);
- exit(17);
- }
- if (!i2) {
- printf(stderr,"no t in %s\n", s);
- exit(18);
- }
- strncpy (i1, i2, 7);
- }
- }
-
- mytty += 5; /* skip "/dev/" */
-
- if (!(tslot = ttyslot (mytty))) {
- fprintf (stderr, "no tty\n");
- exit (1);
- }
- lseek (ufd, (long) (tslot * sizeof (utmp)), 0);
- read (ufd, (char *) &utmp, sizeof (utmp));
-
- #ifdef LOG_AUTH
- openlog ("chusr", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
- #else
- openlog ("chusr", LOG_PID);
- #endif
-
- syslog (LOG_NOTICE, "\"%.*s\" changed to \"%s\" on %s\n",
- sizeof (utmp.ut_name), utmp.ut_name, av[1], mytty);
- closelog();
- SCPYN (utmp.ut_name, av[1]);
- SCPYN (utmp.ut_line, mytty);
- if (ac == 4)
- SCPYN (utmp.ut_host, av[3]);
- if (tflag)
- time (&utmp.ut_time);
- lseek (ufd, (long) (tslot * sizeof (utmp)), 0);
- write (ufd, (char *) &utmp, sizeof (utmp));
- (void) close (ufd);
- }
-
-
- usage (name)
- char *name;
- {
- fprintf (stderr, "usage: %s user [-t] [ tty [whence] ]\n", name);
- exit (EX_USAGE);
- }
-
- /*
- /*
- * Return the number of the slot in the utmp file
- * corresponding to the passed tty.
- * returns 0 on error.
- */
-
- char *getttys ();
- static char ttys[] = "/etc/ttys";
-
- #define NULL 0
-
- ttyslot (tty)
- register char *tty;
- {
- register char *tp, *p;
- register s;
- FILE *tf;
- tp = tty;
-
- if ((p = rindex (tp, '/')) == NULL)
- p = tp;
- else
- p++;
- if ((tf = fopen (ttys, "r")) == NULL)
- return (0);
- s = 0;
- while (tp = getttys (tf)) {
- s++;
- if (strncmp (p, tp, strlen (p)) == 0) {
- fclose (tf);
- return (s);
- }
- }
- fclose (tf);
- return (0);
- }
-
- static char *
- getttys (f)
- FILE *f;
- {
- static char line[256];
- register char *lp;
-
- do {
- if (fgets (line, 256, f) == NULL)
- return NULL;
- } while (*line == '#'); /* ignore comment lines */
-
- for (lp = line;; lp++) {
- if ((*lp == '\t') || (*lp == ' ') || (*lp == '\n')) {
- *lp = '\0';
- #ifdef BSD43
- return (line);
- #else
- return (line + 2);
- #endif
- }
- }
- }
-