Пример #1
0
static int utmp_get_runlevel(struct lxc_utmp *utmp_data)
{
	#if HAVE_UTMPX_H
	struct utmpx *utmpx;
	#else
	struct utmp *utmpx;
	#endif
	char path[MAXPATHLEN];
	struct lxc_handler *handler = utmp_data->handler;

	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run/utmp",
		     handler->pid) > MAXPATHLEN) {
		ERROR("path is too long");
		return -1;
	}

	if (!access(path, F_OK) && !utmpxname(path))
		goto utmp_ok;

	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run/utmp",
		     handler->pid) > MAXPATHLEN) {
		ERROR("path is too long");
		return -1;
	}

	if (utmpxname(path)) {
		SYSERROR("failed to 'utmpxname'");
		return -1;
	}

utmp_ok:

	setutxent();

	while ((utmpx = getutxent())) {

		if (utmpx->ut_type == RUN_LVL) {
			utmp_data->prev_runlevel = utmpx->ut_pid / 256;
			utmp_data->curr_runlevel = utmpx->ut_pid % 256;
			DEBUG("utmp handler - run level is %c/%c",
			      utmp_data->prev_runlevel,
			      utmp_data->curr_runlevel);
		}
	}

	endutxent();

	return 0;
}
Пример #2
0
int main(int argc, char **argv)
{
    struct utmpx u;
    const char file[256] = "/home/flueg/workspace/utmp/ftmpx";
    memset(&u, 0, sizeof(struct utmpx));

    if (utmpxname(file) == -1) perror("failed to set ftmpx file");
    strcpy(u.ut_user, getpwuid(getuid())->pw_name);
    printf("ttyname is: %s\n", ttyname(0)+strlen("/dev/"));
    strcpy(u.ut_id, ttyname(0) + strlen("/dev/tty"));
    strcpy(u.ut_line, ttyname(0) + strlen("/dev/"));
    u.ut_pid = getpid();
    u.ut_type = LOGIN_PROCESS;

    setutxent();
    if (pututxline(&u) == NULL) perror("failed to pututxline.\n");

    sleep(2);
    u.ut_type = DEAD_PROCESS;
    time((time_t *) &u.ut_tv.tv_sec);
    setutxent();
    if (pututxline(&u) == NULL) perror("failed to pututxline.\n");

    endutxent();
    exit(0);
}
Пример #3
0
static void
sendmes_tozone(zoneid_t zid, int aflag) {
	int i = 0;
	char zonename[ZONENAME_MAX], root[MAXPATHLEN];
	struct utmpx *p;

	if (zid != getzoneid()) {
		root[0] = '\0';
		(void) getzonenamebyid(zid, zonename, ZONENAME_MAX);
		(void) zone_get_rootpath(zonename, root, sizeof (root));
		(void) strlcat(root, UTMPX_FILE, sizeof (root));
		if (!utmpxname(root)) {
			(void) fprintf(stderr, "Cannot open %s\n", root);
			return;
		}
	} else {
		(void) utmpxname(UTMPX_FILE);
	}
	setutxent();
	while ((p = getutxent()) != NULL) {
		if (p->ut_type != USER_PROCESS)
			continue;
		/*
		 * if (-a option OR NOT pty window login), send the message
		 */
		if (aflag || !nonuserx(*p))
			sendmes(p, zid);
	}
	endutxent();

	(void) alarm(60);
	do {
		i = (int)wait((int *)0);
	} while (i != -1 || errno != ECHILD);

}
Пример #4
0
int
main(int argc, char *argv[])
{
    struct utmpx *ut;
    struct in_addr in;

    if (argc > 1 && strcmp(argv[1], "--help") == 0)
        usageErr("%s [utmp-pathname]\n", argv[0]);

    if (argc > 1)               /* Use alternate file if supplied */
        if (utmpxname(argv[1]) == -1)
            errExit("utmpxname");

    setutxent();

    printf("user     type            PID line   id  host     ");
    printf("term exit session  address         date/time\n");

    while ((ut = getutxent()) != NULL) {        /* Sequential scan to EOF */
        printf("%-8s ", ut->ut_user);
        printf("%-9.9s ",
                (ut->ut_type == EMPTY) ?         "EMPTY" :
                (ut->ut_type == RUN_LVL) ?       "RUN_LVL" :
                (ut->ut_type == BOOT_TIME) ?     "BOOT_TIME" :
                (ut->ut_type == NEW_TIME) ?      "NEW_TIME" :
                (ut->ut_type == OLD_TIME) ?      "OLD_TIME" :
                (ut->ut_type == INIT_PROCESS) ?  "INIT_PR" :
                (ut->ut_type == LOGIN_PROCESS) ? "LOGIN_PR" :
                (ut->ut_type == USER_PROCESS) ?  "USER_PR" :
                (ut->ut_type == DEAD_PROCESS) ?  "DEAD_PR" : "???");
        printf("(%1d) ", ut->ut_type);
        printf("%5ld %-6.6s %-3.5s %-9.9s ", (long) ut->ut_pid,
                ut->ut_line, ut->ut_id, ut->ut_host);
        printf("%3d %3d ", ut->ut_exit.e_termination, ut->ut_exit.e_exit);
        printf("%8ld ", (long) ut->ut_session);

        /* Display IPv4 address */

        in.s_addr = ut->ut_addr_v6[0];
        printf(" %-15.15s ", inet_ntoa(in));
        printf("%s", ctime((time_t *) &(ut->ut_tv.tv_sec)));
    }

    endutxent();
    exit(EXIT_SUCCESS);
}
Пример #5
0
int
main(int argc, char **argv)
{
    struct utmpx *p;

    if (argc < 3)
        (void) fprintf(stderr, "Usage: %s reason wtmpx_file\n",
                       argv[0]), exit(1);

    (void) strncpy(wb.ut_line, argv[1], sizeof (wb.ut_line));
    wb.ut_line[11] = NULL;
    wb.ut_type = ACCOUNTING;
    time(&wb.ut_xtime);
    utmpxname(argv[2]);
    setutxent();

    if (pututxline(&wb) == NULL)
        printf("acctwtmp - pututxline failed\n");
    endutxent();
    exit(0);
}
Пример #6
0
int
main(int argc, char *argv[])
{
    struct utmpx *ut;

    if (argc > 1 && strcmp(argv[1], "--help") == 0) {
        fprintf(stderr, "usage: %s [utmp-pathname]\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* Use alternate file if supplied */
    if (argc > 1) {
        if (utmpxname(argv[1]) == -1) {
            perror("utmpxname");
        }
    }

    setutxent();
    printf("user     type        PID line   id   host     date/time\n");
    /* Sequential scan to EOF */
    while ((ut = getutxent()) != NULL) {
        printf("%-8s ", ut->ut_user);
        printf("%-9.9s ",
                (ut->ut_type == EMPTY) ? "EMPTY" :
                (ut->ut_type == RUN_LVL) ? "RUN_LVL" :
                (ut->ut_type == BOOT_TIME) ? "BOOT_TIME" :
                (ut->ut_type == NEW_TIME) ? "NEW_TIME" :
                (ut->ut_type == OLD_TIME) ? "OLD_TIME" :
                (ut->ut_type == INIT_PROCESS) ? "INIT_PR" :
                (ut->ut_type == LOGIN_PROCESS) ? "LOGIN_PR" :
                (ut->ut_type == USER_PROCESS) ? "USER_PR" :
                (ut->ut_type == DEAD_PROCESS) ? "DEAD_PR" : "???");
        printf("%5ld %-6.6s %-3.5s %-9.9s ",
                (long) ut->ut_pid, ut->ut_line, ut->ut_id, ut->ut_host);
        printf("%s", ctime(&(ut->ut_tv.tv_sec)));
    }

    endutxent();
    exit(EXIT_SUCCESS);
}
Пример #7
0
int
main(int argc, char *argv[])
{
	struct utmpx	*ut;
	struct utmpx	*utmpbegin;
	struct utmpx	*utmpend;
	struct utmpx	*utp;
	struct uproc	*up, *parent, *pgrp;
	struct psinfo	info;
	struct sigaction actinfo[ACTSIZE];
	struct pstatus	statinfo;
	size_t		size;
	struct stat	sbuf;
	DIR   		*dirp;
	struct	dirent	*dp;
	char		pname[64];
	char 		*fname;
	int		procfd;
	char		*cp;
	int		i;
	int		days, hrs, mins;
	int		entries;
	double		loadavg[3];

	/*
	 * This program needs the proc_owner privilege
	 */
	(void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_PROC_OWNER,
	    (char *)NULL);

	(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	login = (argv[0][0] == '-');
	cp = strrchr(argv[0], '/');
	firstchar = login ? argv[0][1] : (cp == 0) ? argv[0][0] : cp[1];
	prog = argv[0];

	while (argc > 1) {
		if (argv[1][0] == '-') {
			for (i = 1; argv[1][i]; i++) {
				switch (argv[1][i]) {

				case 'h':
					header = 0;
					break;

				case 'l':
					lflag++;
					break;
				case 's':
					lflag = 0;
					break;

				case 'u':
				case 'w':
					firstchar = argv[1][i];
					break;

				default:
					(void) fprintf(stderr, gettext(
					    "%s: bad flag %s\n"),
					    prog, argv[1]);
					exit(1);
				}
			}
		} else {
			if (!isalnum(argv[1][0]) || argc > 2) {
				(void) fprintf(stderr, gettext(
				    "usage: %s [ -hlsuw ] [ user ]\n"), prog);
				exit(1);
			} else
				sel_user = argv[1];
		}
		argc--; argv++;
	}

	/*
	 * read the UTMPX_FILE (contains information about each logged in user)
	 */
	if (stat(UTMPX_FILE, &sbuf) == ERR) {
		(void) fprintf(stderr, gettext("%s: stat error of %s: %s\n"),
		    prog, UTMPX_FILE, strerror(errno));
		exit(1);
	}
	entries = sbuf.st_size / sizeof (struct futmpx);
	size = sizeof (struct utmpx) * entries;
	if ((ut = malloc(size)) == NULL) {
		(void) fprintf(stderr, gettext("%s: malloc error of %s: %s\n"),
		    prog, UTMPX_FILE, strerror(errno));
		exit(1);
	}

	(void) utmpxname(UTMPX_FILE);

	utmpbegin = ut;
	utmpend = (struct utmpx *)((char *)utmpbegin + size);

	setutxent();
	while ((ut < utmpend) && ((utp = getutxent()) != NULL))
		(void) memcpy(ut++, utp, sizeof (*ut));
	endutxent();

	(void) time(&now);	/* get current time */

	if (header) {	/* print a header */
		prtat(&now);
		for (ut = utmpbegin; ut < utmpend; ut++) {
			if (ut->ut_type == USER_PROCESS) {
				if (!nonuserx(*ut))
					nusers++;
			} else if (ut->ut_type == BOOT_TIME) {
				uptime = now - ut->ut_xtime;
				uptime += 30;
				days = uptime / (60*60*24);
				uptime %= (60*60*24);
				hrs = uptime / (60*60);
				uptime %= (60*60);
				mins = uptime / 60;

				PRINTF((gettext("up")));
				if (days > 0)
					PRINTF((gettext(
					    " %d day(s),"), days));
				if (hrs > 0 && mins > 0) {
					PRINTF((" %2d:%02d,", hrs, mins));
				} else {
					if (hrs > 0)
						PRINTF((gettext(
						    " %d hr(s),"), hrs));
					if (mins > 0)
						PRINTF((gettext(
						    " %d min(s),"), mins));
				}
			}
		}

		ut = utmpbegin;	/* rewind utmp data */
		PRINTF((((nusers == 1) ?
		    gettext("  %d user") : gettext("  %d users")), nusers));
		/*
		 * Print 1, 5, and 15 minute load averages.
		 */
		(void) getloadavg(loadavg, 3);
		PRINTF((gettext(",  load average: %.2f, %.2f, %.2f\n"),
		    loadavg[LOADAVG_1MIN], loadavg[LOADAVG_5MIN],
		    loadavg[LOADAVG_15MIN]));

		if (firstchar == 'u')	/* uptime command */
			exit(0);

		if (lflag) {
			PRINTF((dcgettext(NULL, "User     tty      "
			    "login@         idle    JCPU    PCPU what\n",
			    LC_TIME)));
		} else {
			PRINTF((dcgettext(NULL,
			    "User     tty         idle what\n",
			    LC_TIME)));
		}

		if (fflush(stdout) == EOF) {
			perror((gettext("%s: fflush failed\n"), prog));
			exit(1);
		}
	}

	/*
	 * loop through /proc, reading info about each process
	 * and build the parent/child tree
	 */
	if (!(dirp = opendir(PROCDIR))) {
		(void) fprintf(stderr, gettext("%s: could not open %s: %s\n"),
		    prog, PROCDIR, strerror(errno));
		exit(1);
	}

	while ((dp = readdir(dirp)) != NULL) {
		if (dp->d_name[0] == '.')
			continue;
retry:
		(void) sprintf(pname, "%s/%s/", PROCDIR, dp->d_name);
		fname = pname + strlen(pname);
		(void) strcpy(fname, "psinfo");
		if ((procfd = open(pname, O_RDONLY)) < 0)
			continue;
		if (read(procfd, &info, sizeof (info)) != sizeof (info)) {
			int err = errno;
			(void) close(procfd);
			if (err == EAGAIN)
				goto retry;
			if (err != ENOENT)
				(void) fprintf(stderr, gettext(
				    "%s: read() failed on %s: %s \n"),
				    prog, pname, strerror(err));
			continue;
		}
		(void) close(procfd);

		up = findhash(info.pr_pid);
		up->p_ttyd = info.pr_ttydev;
		up->p_state = (info.pr_nlwp == 0? ZOMBIE : RUNNING);
		up->p_time = 0;
		up->p_ctime = 0;
		up->p_igintr = 0;
		(void) strncpy(up->p_comm, info.pr_fname,
		    sizeof (info.pr_fname));
		up->p_args[0] = 0;

		if (up->p_state != NONE && up->p_state != ZOMBIE) {
			(void) strcpy(fname, "status");

			/* now we need the proc_owner privilege */
			(void) __priv_bracket(PRIV_ON);

			procfd = open(pname, O_RDONLY);

			/* drop proc_owner privilege after open */
			(void) __priv_bracket(PRIV_OFF);

			if (procfd < 0)
				continue;

			if (read(procfd, &statinfo, sizeof (statinfo))
			    != sizeof (statinfo)) {
				int err = errno;
				(void) close(procfd);
				if (err == EAGAIN)
					goto retry;
				if (err != ENOENT)
					(void) fprintf(stderr, gettext(
					    "%s: read() failed on %s: %s \n"),
					    prog, pname, strerror(err));
				continue;
			}
			(void) close(procfd);

			up->p_time = statinfo.pr_utime.tv_sec +
			    statinfo.pr_stime.tv_sec;	/* seconds */
			up->p_ctime = statinfo.pr_cutime.tv_sec +
			    statinfo.pr_cstime.tv_sec;

			(void) strcpy(fname, "sigact");

			/* now we need the proc_owner privilege */
			(void) __priv_bracket(PRIV_ON);

			procfd = open(pname, O_RDONLY);

			/* drop proc_owner privilege after open */
			(void) __priv_bracket(PRIV_OFF);

			if (procfd < 0)
				continue;

			if (read(procfd, actinfo, sizeof (actinfo))
			    != sizeof (actinfo)) {
				int err = errno;
				(void) close(procfd);
				if (err == EAGAIN)
					goto retry;
				if (err != ENOENT)
					(void) fprintf(stderr, gettext(
					    "%s: read() failed on %s: %s \n"),
					    prog, pname, strerror(err));
				continue;
			}
			(void) close(procfd);

			up->p_igintr =
			    actinfo[SIGINT-1].sa_handler == SIG_IGN &&
			    actinfo[SIGQUIT-1].sa_handler == SIG_IGN;

			/*
			 * Process args.
			 */
			up->p_args[0] = 0;
			clnarglist(info.pr_psargs);
			(void) strcat(up->p_args, info.pr_psargs);
			if (up->p_args[0] == 0 ||
			    up->p_args[0] == '-' && up->p_args[1] <= ' ' ||
			    up->p_args[0] == '?') {
				(void) strcat(up->p_args, " (");
				(void) strcat(up->p_args, up->p_comm);
				(void) strcat(up->p_args, ")");
			}
		}

		/*
		 * link pgrp together in case parents go away
		 * Pgrp chain is a single linked list originating
		 * from the pgrp leader to its group member.
		 */
		if (info.pr_pgid != info.pr_pid) {	/* not pgrp leader */
			pgrp = findhash(info.pr_pgid);
			up->p_pgrpl = pgrp->p_pgrpl;
			pgrp->p_pgrpl = up;
		}
		parent = findhash(info.pr_ppid);

		/* if this is the new member, link it in */
		if (parent->p_upid != INITPROCESS) {
			if (parent->p_child) {
				up->p_sibling = parent->p_child;
				up->p_child = 0;
			}
			parent->p_child = up;
		}
	}

	/* revert to non-privileged user after opening */
	(void) __priv_relinquish();

	(void) closedir(dirp);
	(void) time(&now);	/* get current time */

	/*
	 * loop through utmpx file, printing process info
	 * about each logged in user
	 */
	for (ut = utmpbegin; ut < utmpend; ut++) {
		if (ut->ut_type != USER_PROCESS)
			continue;
		if (sel_user && strncmp(ut->ut_name, sel_user, NMAX) != 0)
			continue;	/* we're looking for somebody else */

		/* print login name of the user */
		PRINTF(("%-*.*s ", LOGIN_WIDTH, NMAX, ut->ut_name));

		/* print tty user is on */
		if (lflag) {
			PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, ut->ut_line));
		} else {
			if (ut->ut_line[0] == 'p' && ut->ut_line[1] == 't' &&
			    ut->ut_line[2] == 's' && ut->ut_line[3] == '/') {
				PRINTF(("%-*.*s ", LINE_WIDTH, LMAX,
				    &ut->ut_line[4]));
			} else {
				PRINTF(("%-*.*s ", LINE_WIDTH, LMAX,
				    ut->ut_line));
			}
		}

		/* print when the user logged in */
		if (lflag) {
			time_t tim = ut->ut_xtime;
			prtat(&tim);
		}

		/* print idle time */
		idle = findidle(ut->ut_line);
		prttime(idle, 8);
		showtotals(findhash(ut->ut_pid));
	}
	if (fclose(stdout) == EOF) {
		perror((gettext("%s: fclose failed"), prog));
		exit(1);
	}
	return (0);
}
Пример #8
0
static void
updateXtmp_unix (TimeInternal oldTime, TimeInternal newTime)
{

/* Add the old time entry to utmp/wtmp */

/* About as long as the ntpd implementation, but not any less ugly */

#ifdef HAVE_UTMPX_H
		struct utmpx utx;
	memset(&utx, 0, sizeof(utx));
		strncpy(utx.ut_user, "date", sizeof(utx.ut_user));
#ifndef OTIME_MSG
		strncpy(utx.ut_line, "|", sizeof(utx.ut_line));
#else
		strncpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line));
#endif /* OTIME_MSG */
#ifdef OLD_TIME
		utx.ut_tv.tv_sec = oldTime.seconds;
		utx.ut_tv.tv_usec = oldTime.nanoseconds / 1000;
		utx.ut_type = OLD_TIME;
#else /* no ut_type */
		utx.ut_time = oldTime.seconds;
#endif /* OLD_TIME */

/* ======== BEGIN  OLD TIME EVENT - UTMPX / WTMPX =========== */
#ifdef HAVE_UTMPXNAME
		utmpxname("/var/log/utmp");
#endif /* HAVE_UTMPXNAME */
		setutxent();
		pututxline(&utx);
		endutxent();
#ifdef HAVE_UPDWTMPX
		updwtmpx("/var/log/wtmp", &utx);
#endif /* HAVE_IPDWTMPX */
/* ======== END    OLD TIME EVENT - UTMPX / WTMPX =========== */

#else /* NO UTMPX_H */

#ifdef HAVE_UTMP_H
		struct utmp ut;
		memset(&ut, 0, sizeof(ut));
		strncpy(ut.ut_name, "date", sizeof(ut.ut_name));
#ifndef OTIME_MSG
		strncpy(ut.ut_line, "|", sizeof(ut.ut_line));
#else
		strncpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line));
#endif /* OTIME_MSG */

#ifdef OLD_TIME

#ifdef HAVE_STRUCT_UTMP_UT_TIME
		ut.ut_time = oldTime.seconds;
#else
		ut.ut_tv.tv_sec = oldTime.seconds;
		ut.ut_tv.tv_usec = oldTime.nanoseconds / 1000;
#endif /* HAVE_STRUCT_UTMP_UT_TIME */

		ut.ut_type = OLD_TIME;
#else /* no ut_type */
		ut.ut_time = oldTime.seconds;
#endif /* OLD_TIME */

/* ======== BEGIN  OLD TIME EVENT - UTMP / WTMP =========== */
#ifdef HAVE_UTMPNAME
		utmpname(UTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
#ifdef HAVE_UTMPNAME
		utmpname(WTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
/* ======== END    OLD TIME EVENT - UTMP / WTMP =========== */

#endif /* HAVE_UTMP_H */
#endif /* HAVE_UTMPX_H */

/* Add the new time entry to utmp/wtmp */

#ifdef HAVE_UTMPX_H
		memset(&utx, 0, sizeof(utx));
		strncpy(utx.ut_user, "date", sizeof(utx.ut_user));
#ifndef NTIME_MSG
		strncpy(utx.ut_line, "{", sizeof(utx.ut_line));
#else
		strncpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line));
#endif /* NTIME_MSG */
#ifdef NEW_TIME
		utx.ut_tv.tv_sec = newTime.seconds;
		utx.ut_tv.tv_usec = newTime.nanoseconds / 1000;
		utx.ut_type = NEW_TIME;
#else /* no ut_type */
		utx.ut_time = newTime.seconds;
#endif /* NEW_TIME */

/* ======== BEGIN  NEW TIME EVENT - UTMPX / WTMPX =========== */
#ifdef HAVE_UTMPXNAME
		utmpxname("/var/log/utmp");
#endif /* HAVE_UTMPXNAME */
		setutxent();
		pututxline(&utx);
		endutxent();
#ifdef HAVE_UPDWTMPX
		updwtmpx("/var/log/wtmp", &utx);
#endif /* HAVE_UPDWTMPX */
/* ======== END    NEW TIME EVENT - UTMPX / WTMPX =========== */

#else /* NO UTMPX_H */

#ifdef HAVE_UTMP_H
		memset(&ut, 0, sizeof(ut));
		strncpy(ut.ut_name, "date", sizeof(ut.ut_name));
#ifndef NTIME_MSG
		strncpy(ut.ut_line, "{", sizeof(ut.ut_line));
#else
		strncpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line));
#endif /* NTIME_MSG */
#ifdef NEW_TIME

#ifdef HAVE_STRUCT_UTMP_UT_TIME
		ut.ut_time = newTime.seconds;
#else
		ut.ut_tv.tv_sec = newTime.seconds;
		ut.ut_tv.tv_usec = newTime.nanoseconds / 1000;
#endif /* HAVE_STRUCT_UTMP_UT_TIME */
		ut.ut_type = NEW_TIME;
#else /* no ut_type */
		ut.ut_time = newTime.seconds;
#endif /* NEW_TIME */

/* ======== BEGIN  NEW TIME EVENT - UTMP / WTMP =========== */
#ifdef HAVE_UTMPNAME
		utmpname(UTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
#ifdef HAVE_UTMPNAME
		utmpname(WTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
/* ======== END    NEW TIME EVENT - UTMP / WTMP =========== */

#endif /* HAVE_UTMP_H */
#endif /* HAVE_UTMPX_H */

}
Пример #9
0
int
main(int argc, char **argv)
{
	int	goerr = 0;	/* non-zero indicates cmd error	*/
	int	i;
	int	optsw;		/* switch for while of getopt()	*/

	(void) setlocale(LC_ALL, "");

#if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
#define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
#endif
	(void) textdomain(TEXT_DOMAIN);

	validtype[USER_PROCESS] = 1;
	validtype[EMPTY] = 0;
	stbufp = &stbuf;

	/*
	 *	Strip off path name of this command
	 */
	for (i = strlen(argv[0]); i >= 0 && argv[0][i] != '/'; --i);
	if (i >= 0)
		argv[0] += i+1;
	program = argv[0];

	/*
	 *	Buffer stdout for speed
	 */
	setbuf(stdout, outbuf);

	/*
	 *	Retrieve options specified on command line
	 *	XCU4 - add -m option
	 */
	while ((optsw = getopt(argc, argv, "abdHlmn:pqrstTu")) != EOF) {
		optcnt++;
		switch (optsw) {

		case 'a':
			optcnt += 7;
			validtype[BOOT_TIME] = 1;
			validtype[DEAD_PROCESS] = 1;
			validtype[LOGIN_PROCESS] = 1;
			validtype[INIT_PROCESS] = 1;
			validtype[RUN_LVL] = 1;
			validtype[OLD_TIME] = 1;
			validtype[NEW_TIME] = 1;
			validtype[USER_PROCESS] = 1;
#ifdef	XPG4
			aopt = 1;
#endif	/* XPG4 */
			uopt = 1;
			Topt = 1;
			if (!sopt) terse = 0;
			break;

		case 'b':
			validtype[BOOT_TIME] = 1;
			if (!uopt) validtype[USER_PROCESS] = 0;
			break;

		case 'd':
			validtype[DEAD_PROCESS] = 1;
			if (!uopt) validtype[USER_PROCESS] = 0;
#ifdef	XPG4
			dopt = 1;
#endif	/* XPG4 */
			break;

		case 'H':
			optcnt--; /* Don't count Header */
			Hopt = 1;
			break;

		case 'l':
			validtype[LOGIN_PROCESS] = 1;
			if (!uopt) validtype[USER_PROCESS] = 0;
			terse = 0;
			break;
		case 'm':		/* New XCU4 option */
			justme = 1;
			break;

		case 'n':
			errno = 0;
			number = strtol(optarg, &end, 10);
			if (errno != 0 || *end != '\0') {
				(void) fprintf(stderr, gettext(
				    "%s: Invalid numeric argument\n"),
				    program);
				exit(1);
			}
			if (number < 1) {
				(void) fprintf(stderr, gettext(
				    "%s: Number of users per line must "
					"be at least 1\n"), program);
				exit(1);
			}
			break;

		case 'p':
			validtype[INIT_PROCESS] = 1;
			if (!uopt) validtype[USER_PROCESS] = 0;
			break;

		case 'q':
			qopt = 1;
			break;

		case 'r':
			validtype[RUN_LVL] = 1;
			terse = 0;
			if (!uopt) validtype[USER_PROCESS] = 0;
			break;

		case 's':
			sopt = 1;
			terse = 1;
			break;

		case 't':
			validtype[OLD_TIME] = 1;
			validtype[NEW_TIME] = 1;
			if (!uopt) validtype[USER_PROCESS] = 0;
			break;

		case 'T':
			Topt = 1;
#ifdef	XPG4
			terse = 1;	/* XPG4 requires -T */
#else	/* XPG4 */
			terse = 0;
#endif	/* XPG4 */
			break;

		case 'u':
			uopt = 1;
			validtype[USER_PROCESS] = 1;
			if (!sopt) terse = 0;
			break;

		case '?':
			goerr++;
			break;
		default:
			break;
		}
	}
#ifdef	XPG4
	/*
	 * XCU4 changes - check for illegal sopt, Topt & aopt combination
	 */
	if (sopt == 1) {
		terse = 1;
		if (Topt == 1 || aopt == 1)
		goerr++;
	}
#endif	/* XPG4 */

	if (goerr > 0) {
#ifdef	XPG4
		/*
		 * XCU4 - slightly different usage with -s -a & -T
		 */
		(void) fprintf(stderr, gettext("\nUsage:\t%s"), program);
		(void) fprintf(stderr,
		    gettext(" -s [-bdHlmpqrtu] [utmpx_like_file]\n"));

		(void) fprintf(stderr, gettext(
		    "\t%s [-abdHlmpqrtTu] [utmpx_like_file]\n"), program);
#else	/* XPG4 */
		(void) fprintf(stderr, gettext(
		    "\nUsage:\t%s [-abdHlmpqrstTu] [utmpx_like_file]\n"),
		    program);
#endif	/* XPG4 */
		(void) fprintf(stderr,
		    gettext("\t%s -q [-n x] [utmpx_like_file]\n"), program);
		(void) fprintf(stderr, gettext("\t%s [am i]\n"), program);
		/*
		 * XCU4 changes - be explicit with "am i" options
		 */
		(void) fprintf(stderr, gettext("\t%s [am I]\n"), program);
		(void) fprintf(stderr, gettext(
		    "a\tall (bdlprtu options)\n"));
		(void) fprintf(stderr, gettext("b\tboot time\n"));
		(void) fprintf(stderr, gettext("d\tdead processes\n"));
		(void) fprintf(stderr, gettext("H\tprint header\n"));
		(void) fprintf(stderr, gettext("l\tlogin processes\n"));
		(void) fprintf(stderr, gettext(
		    "n #\tspecify number of users per line for -q\n"));
		(void) fprintf(stderr,
		    gettext("p\tprocesses other than getty or users\n"));
		(void) fprintf(stderr, gettext("q\tquick %s\n"), program);
		(void) fprintf(stderr, gettext("r\trun level\n"));
		(void) fprintf(stderr, gettext(
		"s\tshort form of %s (no time since last output or pid)\n"),
		    program);
		(void) fprintf(stderr, gettext("t\ttime changes\n"));
		(void) fprintf(stderr, gettext(
		    "T\tstatus of tty (+ writable, - not writable, "
			"? hung)\n"));
		(void) fprintf(stderr, gettext("u\tuseful information\n"));
		(void) fprintf(stderr,
		    gettext("m\tinformation only about current terminal\n"));
		(void) fprintf(stderr, gettext(
		    "am i\tinformation about current terminal "
			"(same as -m)\n"));
		(void) fprintf(stderr, gettext(
		    "am I\tinformation about current terminal "
			"(same as -m)\n"));
		exit(1);
	}

	/*
	 * XCU4: If -q option ignore all other options
	 */
	if (qopt == 1) {
		Hopt = 0;
		sopt = 0;
		Topt = 0;
		uopt = 0;
		justme = 0;
		validtype[ACCOUNTING] = 0;
		validtype[BOOT_TIME] = 0;
		validtype[DEAD_PROCESS] = 0;
		validtype[LOGIN_PROCESS] = 0;
		validtype[INIT_PROCESS] = 0;
		validtype[RUN_LVL] = 0;
		validtype[OLD_TIME] = 0;
		validtype[NEW_TIME] = 0;
		validtype[USER_PROCESS] = 1;
	}

	if (argc == optind + 1) {
		optcnt++;
		ck_file(argv[optind]);
		(void) utmpxname(argv[optind]);
	}

	/*
	 *	Test for 'who am i' or 'who am I'
	 *	XCU4 - check if justme was already set by -m option
	 */
	if (justme == 1 || (argc == 3 && strcmp(argv[1], "am") == 0 &&
	    ((argv[2][0] == 'i' || argv[2][0] == 'I') &&
		argv[2][1] == '\0'))) {
		justme = 1;
		myname = nameval;
		(void) cuserid(myname);
		if ((mytty = ttyname(fileno(stdin))) == NULL &&
		    (mytty = ttyname(fileno(stdout))) == NULL &&
		    (mytty = ttyname(fileno(stderr))) == NULL) {
			(void) fprintf(stderr, gettext(
			"Must be attached to terminal for 'am I' option\n"));
			(void) fflush(stderr);
			exit(1);
		} else
			mytty += 5; /* bump past "/dev/" */
	}

	if (!terse) {
		if (Hopt)
			(void) printf(gettext(
	"NAME       LINE         TIME          IDLE    PID  COMMENTS\n"));

		timnow = time(0);

		if ((fildes = open("/etc/inittab",
		    O_NONBLOCK|O_RDONLY)) == -1) {
			(void) snprintf(errmsg, sizeof (errmsg),
			    gettext("%s: Cannot open /etc/inittab"), program);
			perror(errmsg);
			exit(errno);
		}

		if (fstat(fildes, stbufp) == -1) {
			(void) snprintf(errmsg, sizeof (errmsg),
			    gettext("%s: Cannot stat /etc/inittab"), program);
			perror(errmsg);
			exit(errno);
		}

		if ((inittab = malloc(stbufp->st_size + 1)) == NULL) {
			(void) snprintf(errmsg, sizeof (errmsg),
			    gettext("%s: Cannot allocate %ld bytes"),
			    program, stbufp->st_size);
			perror(errmsg);
			exit(errno);
		}

		if (read(fildes, inittab, stbufp->st_size)
		    != stbufp->st_size) {
			(void) snprintf(errmsg, sizeof (errmsg),
			    gettext("%s: Error reading /etc/inittab"),
			    program);
			perror(errmsg);
			exit(errno);
		}

		inittab[stbufp->st_size] = '\0';
		iinit = inittab;
	} else {
		if (Hopt) {
#ifdef	XPG4
			if (dopt) {
				(void) printf(gettext(
			"NAME       LINE         TIME		COMMENTS\n"));
			} else {
				(void) printf(
				    gettext("NAME       LINE         TIME\n"));
			}
#else	/* XPG4 */
			(void) printf(
			    gettext("NAME       LINE         TIME\n"));
#endif	/* XPG4 */
		}
	}
	process();

	/*
	 *	'who -q' requires EOL upon exit,
	 *	followed by total line
	 */
	if (qopt)
		(void) printf(gettext("\n# users=%d\n"), totlusrs);
	return (0);
}
Пример #10
0
void KPty::logout()
{
#ifdef HAVE_UTEMPTER
    Q_D(KPty);

    removeLineFromUtmp(d->ttyName, d->masterFd);
#else
    Q_D(KPty);

    const char *str_ptr = d->ttyName.data();
    if (!memcmp(str_ptr, "/dev/", 5)) {
        str_ptr += 5;
    }
# ifdef __GLIBC__
    else {
        const char * sl_ptr = strrchr(str_ptr, '/');
        if (sl_ptr) {
            str_ptr = sl_ptr + 1;
        }
    }
# endif
# ifdef HAVE_LOGIN
#  ifdef HAVE_LOGINX
    ::logoutx(str_ptr, 0, DEAD_PROCESS);
#  else
    ::logout(str_ptr);
#  endif
# else
#  ifdef HAVE_UTMPX
    struct utmpx l_struct, *ut;
#  else
    struct utmp l_struct, *ut;
#  endif
    memset(&l_struct, 0, sizeof(l_struct));

    strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));

#  ifdef HAVE_UTMPX
    utmpxname(_PATH_UTMPX);
    setutxent();
    if ((ut = getutxline(&l_struct))) {
#  else
    utmpname(_PATH_UTMP);
    setutent();
    if ((ut = getutline(&l_struct))) {
#  endif
        memset(ut->ut_name, 0, sizeof(*ut->ut_name));
        memset(ut->ut_host, 0, sizeof(*ut->ut_host));
#  ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
        ut->ut_syslen = 0;
#  endif
#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
        ut->ut_type = DEAD_PROCESS;
#  endif
#  ifdef HAVE_UTMPX
        gettimeofday(&ut->ut_tv, 0);
        pututxline(ut);
    }
    endutxent();
#  else
    ut->ut_time = time(0);
    pututline(ut);
}
endutent();
#  endif
# endif
#endif
}
Пример #11
0
void KPty::login(const char * user, const char * remotehost)
{
#ifdef HAVE_UTEMPTER
    Q_D(KPty);

    addToUtmp(d->ttyName, remotehost, d->masterFd);
    Q_UNUSED(user);
#else
# ifdef HAVE_UTMPX
    struct utmpx l_struct;
# else
    struct utmp l_struct;
# endif
    memset(&l_struct, 0, sizeof(l_struct));
    // note: strncpy without terminators _is_ correct here. man 4 utmp

    if (user) {
        strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name));
    }

    if (remotehost) {
        strncpy(l_struct.ut_host, remotehost, sizeof(l_struct.ut_host));
# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
        l_struct.ut_syslen = qMin(strlen(remotehost), sizeof(l_struct.ut_host));
# endif
    }

# ifndef __GLIBC__
    Q_D(KPty);
    const char * str_ptr = d->ttyName.data();
    if (!memcmp(str_ptr, "/dev/", 5)) {
        str_ptr += 5;
    }
    strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));
#  ifdef HAVE_STRUCT_UTMP_UT_ID
    strncpy(l_struct.ut_id,
            str_ptr + strlen(str_ptr) - sizeof(l_struct.ut_id),
            sizeof(l_struct.ut_id));
#  endif
# endif

# ifdef HAVE_UTMPX
    gettimeofday(&l_struct.ut_tv, 0);
# else
    l_struct.ut_time = time(0);
# endif

# ifdef HAVE_LOGIN
#  ifdef HAVE_LOGINX
    ::loginx(&l_struct);
#  else
    ::login(&l_struct);
#  endif
# else
#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
    l_struct.ut_type = USER_PROCESS;
#  endif
#  ifdef HAVE_STRUCT_UTMP_UT_PID
    l_struct.ut_pid = getpid();
#   ifdef HAVE_STRUCT_UTMP_UT_SESSION
    l_struct.ut_session = getsid(0);
#   endif
#  endif
#  ifdef HAVE_UTMPX
    utmpxname(_PATH_UTMPX);
    setutxent();
    pututxline(&l_struct);
    endutxent();
#   ifdef HAVE_UPDWTMPX
    updwtmpx(_PATH_WTMPX, &l_struct);
#   endif
#  else
    utmpname(_PATH_UTMP);
    setutent();
    pututline(&l_struct);
    endutent();
    updwtmp(_PATH_WTMP, &l_struct);
#  endif
# endif
#endif
}
Пример #12
0
void
servo_perform_clock_step(RunTimeOpts * rtOpts, PtpClock * ptpClock)
{
	if(rtOpts->noAdjust){
		WARNING("Could not step clock - clock adjustment disabled\n");
		return;
	}

	TimeInternal oldTime, newTime;
	/*No need to reset the frequency offset: if we're far off, it will quickly get back to a high value */
	getTime(&oldTime);
	subTime(&newTime, &oldTime, &ptpClock->offsetFromMaster);

	setTime(&newTime);

#ifdef HAVE_LINUX_RTC_H
	if(rtOpts->setRtc) {
		setRtc(&newTime);
	}
#endif /* HAVE_LINUX_RTC_H */

	initClock(rtOpts, ptpClock);

#ifdef HAVE_SYS_TIMEX_H
	if(ptpClock->clockQuality.clockClass > 127)
		restoreDrift(ptpClock, rtOpts, TRUE);
#endif /* HAVE_SYS_TIMEX_H */
	ptpClock->servo.runningMaxOutput = FALSE;
	toState(PTP_FAULTY, rtOpts, ptpClock);		/* make a full protocol reset */

	/* Major time change - need to inform utmp / wtmp */
	if(oldTime.seconds != newTime.seconds) {

/* Add the old time entry to utmp/wtmp */

/* About as long as the ntpd implementation, but not any less ugly */

#ifdef HAVE_UTMPX_H
		struct utmpx utx;
	memset(&utx, 0, sizeof(utx));
		strncpy(utx.ut_user, "date", sizeof(utx.ut_user));
#ifndef OTIME_MSG
		strncpy(utx.ut_line, "|", sizeof(utx.ut_line));
#else
		strncpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line));
#endif /* OTIME_MSG */
#ifdef OLD_TIME
		utx.ut_tv.tv_sec = oldTime.seconds;
		utx.ut_tv.tv_usec = oldTime.nanoseconds / 1000;
		utx.ut_type = OLD_TIME;
#else /* no ut_type */
		utx.ut_time = oldTime.seconds;
#endif /* OLD_TIME */

/* ======== BEGIN  OLD TIME EVENT - UTMPX / WTMPX =========== */
#ifdef HAVE_UTMPXNAME
		utmpxname("/var/log/utmp");
#endif /* HAVE_UTMPXNAME */
		setutxent();
		pututxline(&utx);
		endutxent();
#ifdef HAVE_UPDWTMPX
		updwtmpx("/var/log/wtmp", &utx);
#endif /* HAVE_IPDWTMPX */
/* ======== END    OLD TIME EVENT - UTMPX / WTMPX =========== */

#else /* NO UTMPX_H */

#ifdef HAVE_UTMP_H
		struct utmp ut;
		memset(&ut, 0, sizeof(ut));
		strncpy(ut.ut_name, "date", sizeof(ut.ut_name));
#ifndef OTIME_MSG
		strncpy(ut.ut_line, "|", sizeof(ut.ut_line));
#else
		strncpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line));
#endif /* OTIME_MSG */

#ifdef OLD_TIME
		ut.ut_tv.tv_sec = oldTime.seconds;
		ut.ut_tv.tv_usec = oldTime.nanoseconds / 1000;
		ut.ut_type = OLD_TIME;
#else /* no ut_type */
		ut.ut_time = oldTime.seconds;
#endif /* OLD_TIME */

/* ======== BEGIN  OLD TIME EVENT - UTMP / WTMP =========== */
#ifdef HAVE_UTMPNAME
		utmpname(UTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
#ifdef HAVE_UTMPNAME
		utmpname(WTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
/* ======== END    OLD TIME EVENT - UTMP / WTMP =========== */

#endif /* HAVE_UTMP_H */
#endif /* HAVE_UTMPX_H */

/* Add the new time entry to utmp/wtmp */

#ifdef HAVE_UTMPX_H
		memset(&utx, 0, sizeof(utx));
		strncpy(utx.ut_user, "date", sizeof(utx.ut_user));
#ifndef NTIME_MSG
		strncpy(utx.ut_line, "}", sizeof(utx.ut_line));
#else
		strncpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line));
#endif /* NTIME_MSG */
#ifdef NEW_TIME
		utx.ut_tv.tv_sec = newTime.seconds;
		utx.ut_tv.tv_usec = newTime.nanoseconds / 1000;
		utx.ut_type = NEW_TIME;
#else /* no ut_type */
		utx.ut_time = newTime.seconds;
#endif /* NEW_TIME */

/* ======== BEGIN  NEW TIME EVENT - UTMPX / WTMPX =========== */
#ifdef HAVE_UTMPXNAME
		utmpxname("/var/log/utmp");
#endif /* HAVE_UTMPXNAME */
		setutxent();
		pututxline(&utx);
		endutxent();
#ifdef HAVE_UPDWTMPX
		updwtmpx("/var/log/wtmp", &utx);
#endif /* HAVE_UPDWTMPX */
/* ======== END    NEW TIME EVENT - UTMPX / WTMPX =========== */

#else /* NO UTMPX_H */

#ifdef HAVE_UTMP_H
		memset(&ut, 0, sizeof(ut));
		strncpy(ut.ut_name, "date", sizeof(ut.ut_name));
#ifndef NTIME_MSG
		strncpy(ut.ut_line, "}", sizeof(ut.ut_line));
#else
		strncpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line));
#endif /* NTIME_MSG */
#ifdef NEW_TIME
		ut.ut_tv.tv_sec = newTime.seconds;
		ut.ut_tv.tv_usec = newTime.nanoseconds / 1000;
		ut.ut_type = NEW_TIME;
#else /* no ut_type */
		ut.ut_time = newTime.seconds;
#endif /* NEW_TIME */

/* ======== BEGIN  NEW TIME EVENT - UTMP / WTMP =========== */
#ifdef HAVE_UTMPNAME
		utmpname(UTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
#ifdef HAVE_UTMPNAME
		utmpname(WTMP_FILE);
#endif /* HAVE_UTMPNAME */
#ifdef HAVE_SETUTENT
		setutent();
#endif /* HAVE_SETUTENT */
#ifdef HAVE_PUTUTLINE
		pututline(&ut);
#endif /* HAVE_PUTUTLINE */
#ifdef HAVE_ENDUTENT
		endutent();
#endif /* HAVE_ENDUTENT */
/* ======== END    NEW TIME EVENT - UTMP / WTMP =========== */

#endif /* HAVE_UTMP_H */
#endif /* HAVE_UTMPX_H */
	}


}
Пример #13
0
int
main(int argc, char **argv)
{
    int c;
    int all, is_utmpx, do_getut;
    int f;
    char *fn;
    size_t recsize;
    size_t nread;
    union {
        struct utmp ut;
#ifdef UTMPX
        struct utmpx utx;
#endif
    } u;

    all = is_utmpx = do_getut = 0;
    recsize = sizeof(struct utmp);

    while ((c = getopt(argc, argv, OPTS)) != EOF) {
        switch (c) {
        case 'a':
            all = 1;
            break;
#ifdef UTMPX
        case 'x':
            is_utmpx = 1;
            recsize = sizeof(struct utmpx);
            break;
#endif
#ifdef UTN
        case 'g':
            do_getut = 1;
            break;
#endif
        default:
            usage(argv[0]);
        }
    }
    if (argc <= optind)
        usage(argv[0]);
    fn = argv[optind];
    if (!do_getut) {
        f = open(fn, O_RDONLY);
        if (f == -1) {
            perror(fn);
            exit(1);
        }
        while ((nread = read(f, &u, recsize)) > 0) {
            if (nread < recsize) {
                fprintf(stderr, "short read");
                close(f);
                exit(1);
            }
            if (is_utmpx) {
#ifdef UTMPX
                print_utx(all, &u.utx);
#else
                abort();
#endif
            } else {
                print_ut(all, &u.ut);
            }
        }
        if (nread == -1) {
            perror("read");
            exit(1);
        }
        close(f);
    } else {
        if (is_utmpx) {
#ifdef UTMPX
#ifdef HAVE_UTMPXNAME
            struct utmpx *utxp;
            utmpxname(fn);
            setutxent();
            while ((utxp = getutxent()) != NULL)
                print_utx(all, utxp);
#else
            fprintf(stderr, "no utmpxname(); can't use getutxent()\n");
            exit(1);
#endif
#else
            abort();
#endif
        } else {
#ifdef HAVE_UTMPNAME
            struct utmp *utp;
            utmpname(fn);
            setutxent();
            while ((utp = getutent()) != NULL)
                print_ut(all, utp);
#else
            fprintf(stderr, "no utmpname(); can't use getutent()\n");
            exit(1);
#endif
        }
    }
    exit(0);
}
Пример #14
0
/*
 * Update wtmp and utmp logs.
 */
static void log_utmp(struct login_context *cxt)
{
	struct utmpx ut;
	struct utmpx *utp;
	struct timeval tv;

	utmpxname(_PATH_UTMP);
	setutxent();

	/* Find pid in utmp.
	 *
	 * login sometimes overwrites the runlevel entry in /var/run/utmp,
	 * confusing sysvinit. I added a test for the entry type, and the
	 * problem was gone. (In a runlevel entry, st_pid is not really a pid
	 * but some number calculated from the previous and current runlevel.)
	 * -- Michael Riepe <*****@*****.**>
	 */
	while ((utp = getutxent()))
		if (utp->ut_pid == cxt->pid
		    && utp->ut_type >= INIT_PROCESS
		    && utp->ut_type <= DEAD_PROCESS)
			break;

	/* If we can't find a pre-existing entry by pid, try by line.
	 * BSD network daemons may rely on this. */
	if (utp == NULL && cxt->tty_name) {
		setutxent();
		ut.ut_type = LOGIN_PROCESS;
		str2memcpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line));
		utp = getutxline(&ut);
	}

	/* If we can't find a pre-existing entry by pid and line, try it by id.
	 * Very stupid telnetd daemons don't set up utmp at all. (kzak) */
	if (utp == NULL && cxt->tty_number) {
	     setutxent();
	     ut.ut_type = DEAD_PROCESS;
	     str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id));
	     utp = getutxid(&ut);
	}

	if (utp)
		memcpy(&ut, utp, sizeof(ut));
	else
		/* some gettys/telnetds don't initialize utmp... */
		memset(&ut, 0, sizeof(ut));

	if (cxt->tty_number && ut.ut_id[0] == 0)
		str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id));
	if (cxt->username)
		str2memcpy(ut.ut_user, cxt->username, sizeof(ut.ut_user));
	if (cxt->tty_name)
		str2memcpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line));

	gettimeofday(&tv, NULL);
	ut.ut_tv.tv_sec = tv.tv_sec;
	ut.ut_tv.tv_usec = tv.tv_usec;
	ut.ut_type = USER_PROCESS;
	ut.ut_pid = cxt->pid;
	if (cxt->hostname) {
		str2memcpy(ut.ut_host, cxt->hostname, sizeof(ut.ut_host));
		if (*cxt->hostaddress)
			memcpy(&ut.ut_addr_v6, cxt->hostaddress,
			       sizeof(ut.ut_addr_v6));
	}

	pututxline(&ut);
	endutxent();

	updwtmpx(_PATH_WTMP, &ut);
}
Пример #15
0
int
main (int argc, char **argv)
{
#if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE)
	int		utmp;
#endif
#ifndef USE_UTMPX
	int		wtmp;
#endif
	time_t		current_time;
#ifdef USE_UTMP
	struct utmp	utmp_entry;
#endif
#ifdef USE_UTMPX
	struct utmpx	utmpx_entry;
#endif
	char *		line = NULL;

	program_name = argv[0];
	while (*++argv && **argv == '-') {
		switch (*++*argv) {
		case 'w':
			wtmp_file = getstring (&argv, &wflag);
			if (!strcmp (wtmp_file, "none"))
				wtmp_none = 1;
#if defined(USE_UTMPX) && defined(HAVE_UPDWTMPX)
			else
				wtmpx_file = wtmp_file;
#endif
			break;
		case 'u':
			utmp_file = getstring (&argv, &uflag);
			if (!strcmp (utmp_file, "none"))
				utmp_none = 1;
#if defined(USE_UTMPX) && defined(HAVE_UTMPXNAME)
			else
				utmpx_file = utmp_file;
#endif
			break;
#ifdef USE_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':
#if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE)
			slot_number = atoi (getstring (&argv, &sflag));
#endif
			break;
		case 'x':
			xservers_file = getstring (&argv, &xflag);
			break;
		case 'a':
			aflag++;
			break;
		case 'd':
			dflag++;
			break;
		case 'V':
			printf("%s\n", PACKAGE_STRING);
			exit (0);
		default:
			fprintf (stderr, "%s: unrecognized option '%s'\n",
				 program_name, argv[0]);
			usage (1);
		}
	}
	user_name = *argv++;
	if (user_name == NULL) {
		fprintf (stderr, "%s: missing required user-name argument\n",
			 program_name);
		usage (1);
	}
	if (*argv != NULL) {
		fprintf (stderr, "%s: unrecognized argument '%s'\n",
			 program_name, argv[0]);
		usage (1);
	}
	/*
	 * complain if neither aflag nor dflag are set,
	 * or if both are set.
	 */
	if (!(aflag ^ dflag)) {
		fprintf (stderr, "%s: must specify exactly one of -a or -d\n",
			 program_name);
		usage (1);
	}
	if (xflag && !lflag) {
		fprintf (stderr, "%s: must specify -l when -x is used\n",
			 program_name);
		usage (1);
	}
	/* set up default file names */
	if (!wflag) {
		wtmp_file = WTMP_FILE;
#if defined(USE_UTMPX) && defined(HAVE_UPDWTMPX)
		wtmpx_file = WTMPX_FILE;
#endif
	}
	if (!uflag) {
		utmp_file = UTMP_FILE;
#if defined(USE_UTMPX) && defined(HAVE_UTMPXNAME)
		utmpx_file = UTMPX_FILE;
#endif
	}
#ifdef USE_LASTLOG
	if (!Lflag)
		llog_file = LLOG_FILE;
#endif
#if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE)
	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 ((line = ttyname (0)) != NULL, "ttyname");
		if (strncmp(line, "/dev/", 5) == 0)
			line += 5;
	}
	time (&current_time);
#ifdef USE_UTMP
	set_utmp (&utmp_entry, line, user_name, host_name, current_time, aflag);
#endif

#ifdef USE_UTMPX
	/* need to set utmpxname() before calling set_utmpx() for
	   UtmpxIdOpen to work */
# ifdef HAVE_UTMPXNAME
	if (utmpx_file != NULL) {
		utmpxname (utmpx_file);
	}
# endif
	set_utmpx (&utmpx_entry, line, user_name,
		   host_name, current_time, aflag);
#endif

	if (!utmp_none) {
#ifdef USE_UTMPX
# ifdef HAVE_UTMPXNAME
		if (utmpx_file != NULL)
# endif
		{
			setutxent ();
			(void) getutxid (&utmpx_entry);
			pututxline (&utmpx_entry);
			endutxent ();
		}
#endif
#ifdef USE_UTMP
# ifdef HAVE_PUTUTLINE
		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
#endif /* USE_UTMP */
	}
	if (!wtmp_none) {
#ifdef USE_UTMPX
# ifdef HAVE_UPDWTMPX
		if (wtmpx_file != NULL) {
			updwtmpx(wtmpx_file, &utmpx_entry);
		}
# endif
#else
		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);
		}
#endif
	}
#ifdef USE_LASTLOG
	if (aflag && !llog_none) {
		int llog;
		struct passwd *pwd = getpwnam(user_name);

		sysnerr( pwd != NULL, "get user id");
		llog = open (llog_file, O_RDWR);

		if (llog != -1) {
			struct lastlog ll;

			sysnerr (lseek(llog, (long) (pwd->pw_uid*sizeof(ll)), 0)
					!= -1, "seeking lastlog entry");
			memset(&ll, 0, 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 (write (llog, (char *) &ll, sizeof (ll))
					== sizeof (ll), "write lastlog entry");
			close (llog);
		}
	}
#endif
	return 0;
}