Quizzer

 view release on metacpan or  search on metacpan

exercises/compile-tcsh/tcsh-6.10.00/tc.who.c  view on Meta::CPAN

 * when doing pointer-chase searches.
 */
void
initwatch()
{
    whohead.who_next = &whotail;
    whotail.who_prev = &whohead;
    stlast = 1;
#ifdef WHODEBUG
    debugwholist(NULL, NULL);
#endif /* WHODEBUG */
}

void
resetwatch()
{
    watch_period = 0;
    stlast = 0;
}

/*
 * Karl Kleinpaste, 26 Jan 1984.
 * Watch /etc/utmp for login/logout changes.
 */
void
watch_login(force)
    int force;
{
    int     utmpfd, comp = -1, alldone;
    int	    firsttime = stlast == 1;
#ifdef BSDSIGS
    sigmask_t omask;
#endif				/* BSDSIGS */
    struct utmp utmp;
    struct who *wp, *wpnew;
    struct varent *v;
    Char  **vp = NULL;
    time_t  t, interval = MAILINTVL;
    struct stat sta;
#if defined(UTHOST) && defined(_SEQUENT_)
    char   *host, *ut_find_host();
#endif
#ifdef WINNT_NATIVE
    static int ncbs_posted = 0;
    USE(utmp);
    USE(utmpfd);
    USE(sta);
    USE(wpnew);
#endif /* WINNT_NATIVE */

    /* stop SIGINT, lest our login list get trashed. */
#ifdef BSDSIGS
    omask = sigblock(sigmask(SIGINT));
#else
    (void) sighold(SIGINT);
#endif

    v = adrof(STRwatch);
    if (v == NULL && !force) {
#ifdef BSDSIGS
	(void) sigsetmask(omask);
#else
	(void) sigrelse(SIGINT);
#endif
	return;			/* no names to watch */
    }
    if (!force) {
	trim(vp = v->vec);
	if (blklen(vp) % 2)		/* odd # args: 1st == # minutes. */
	    interval = (number(*vp)) ? (getn(*vp++) * 60) : MAILINTVL;
    }
    else
	interval = 0;
	
    (void) time(&t);
#ifdef WINNT_NATIVE
	/*
	 * Since NCB_ASTATs take time, start em async at least 90 secs
	 * before we are due -amol 6/5/97
	 */
	if (!ncbs_posted) {
	    unsigned long tdiff = t - watch_period;
	    if (!watch_period || ((tdiff  > 0) && (tdiff > (interval - 90)))) {
		start_ncbs(vp);
 		ncbs_posted = 1;
	    }
	}
#endif /* WINNT_NATIVE */
    if (t - watch_period < interval) {
#ifdef BSDSIGS
	(void) sigsetmask(omask);
#else
	(void) sigrelse(SIGINT);
#endif
	return;			/* not long enough yet... */
    }
    watch_period = t;
#ifdef WINNT_NATIVE
    ncbs_posted = 0;
#else /* !WINNT_NATIVE */

    /*
     * From: Michael Schroeder <mlschroe@immd4.informatik.uni-erlangen.de>
     * Don't open utmp all the time, stat it first...
     */
    if (stat(_PATH_UTMP, &sta)) {
	if (!force)
	    xprintf(CGETS(26, 1,
			  "cannot stat %s.  Please \"unset watch\".\n"),
		    _PATH_UTMP);
# ifdef BSDSIGS
	(void) sigsetmask(omask);
# else
	(void) sigrelse(SIGINT);
# endif
	return;
    }
    if (stlast == sta.st_mtime) {
# ifdef BSDSIGS
	(void) sigsetmask(omask);
# else
	(void) sigrelse(SIGINT);
# endif
	return;
    }
    stlast = sta.st_mtime;
    if ((utmpfd = open(_PATH_UTMP, O_RDONLY)) < 0) {
	if (!force)
	    xprintf(CGETS(26, 2,
			  "%s cannot be opened.  Please \"unset watch\".\n"),
		    _PATH_UTMP);
# ifdef BSDSIGS
	(void) sigsetmask(omask);
# else
	(void) sigrelse(SIGINT);
# endif
	return;
    }

    /*
     * xterm clears the entire utmp entry - mark everyone on the status list
     * OFFLINE or we won't notice X "logouts"
     */
    for (wp = whohead.who_next; wp->who_next != NULL; wp = wp->who_next) {
	wp->who_status = OFFLINE;
	wp->who_time = 0;
    }

    /*
     * Read in the utmp file, sort the entries, and update existing entries or
     * add new entries to the status list.
     */
    while (read(utmpfd, (char *) &utmp, sizeof utmp) == sizeof utmp) {

# ifdef DEAD_PROCESS
#  ifndef IRIS4D
	if (utmp.ut_type != USER_PROCESS)
	    continue;
#  else
	/* Why is that? Cause the utmp file is always corrupted??? */
	if (utmp.ut_type != USER_PROCESS && utmp.ut_type != DEAD_PROCESS)
	    continue;
#  endif /* IRIS4D */
# endif /* DEAD_PROCESS */

	if (utmp.ut_name[0] == '\0' && utmp.ut_line[0] == '\0')
	    continue;	/* completely void entry */
# ifdef DEAD_PROCESS
	if (utmp.ut_type == DEAD_PROCESS && utmp.ut_line[0] == '\0')
	    continue;
# endif /* DEAD_PROCESS */
	wp = whohead.who_next;
	while (wp->who_next && (comp = strncmp(wp->who_tty, utmp.ut_line, UTLINLEN)) < 0)
	    wp = wp->who_next;/* find that tty! */

	if (wp->who_next && comp == 0) {	/* found the tty... */
# ifdef DEAD_PROCESS
	    if (utmp.ut_type == DEAD_PROCESS) {
		wp->who_time = utmp.ut_time;
		wp->who_status = OFFLINE;
	    }
	    else
# endif /* DEAD_PROCESS */
	    if (utmp.ut_name[0] == '\0') {
		wp->who_time = utmp.ut_time;
		wp->who_status = OFFLINE;
	    }
	    else if (strncmp(utmp.ut_name, wp->who_name, UTNAMLEN) == 0) {
		/* someone is logged in */ 
		wp->who_time = utmp.ut_time;
		wp->who_status = 0;	/* same guy */
	    }
	    else {

exercises/compile-tcsh/tcsh-6.10.00/tc.who.c  view on Meta::CPAN

    }
    (void) close(utmpfd);
# if defined(UTHOST) && defined(_SEQUENT_)
    endutent();
# endif
#endif /* !WINNT_NATIVE */

    if (force || vp == NULL)
	return;

    /*
     * The state of all logins is now known, so we can search the user's list
     * of watchables to print the interesting ones.
     */
    for (alldone = 0; !alldone && *vp != NULL && **vp != '\0' &&
	 *(vp + 1) != NULL && **(vp + 1) != '\0';
	 vp += 2) {		/* args used in pairs... */

	if (eq(*vp, STRany) && eq(*(vp + 1), STRany))
	    alldone = 1;

	for (wp = whohead.who_next; wp->who_next != NULL; wp = wp->who_next) {
	    if (wp->who_status & ANNOUNCE ||
		(!eq(STRany, vp[0]) &&
		 !Gmatch(str2short(wp->who_name), vp[0]) &&
		 !Gmatch(str2short(wp->who_new),  vp[0])) ||
		(!Gmatch(str2short(wp->who_tty),  vp[1]) &&
		 !eq(STRany, vp[1])))
		continue;	/* entry doesn't qualify */
	    /* already printed or not right one to print */


	    if (wp->who_time == 0)/* utmp entry was cleared */
		wp->who_time = watch_period;

	    if ((wp->who_status & OFFLINE) &&
		(wp->who_name[0] != '\0')) {
		if (!firsttime)
		    print_who(wp);
		wp->who_name[0] = '\0';
		wp->who_status |= ANNOUNCE;
		continue;
	    }
	    if (wp->who_status & ONLINE) {
		if (!firsttime)
		    print_who(wp);
		(void) strcpy(wp->who_name, wp->who_new);
		wp->who_status |= ANNOUNCE;
		continue;
	    }
	    if (wp->who_status & CHANGED) {
		if (!firsttime)
		    print_who(wp);
		(void) strcpy(wp->who_name, wp->who_new);
		wp->who_status |= ANNOUNCE;
		continue;
	    }
	}
    }
#ifdef BSDSIGS
    (void) sigsetmask(omask);
#else
    (void) sigrelse(SIGINT);
#endif
}

#ifdef WHODEBUG
static void
debugwholist(new, wp)
    register struct who *new, *wp;
{
    register struct who *a;

    a = whohead.who_next;
    while (a->who_next != NULL) {
	xprintf("%s/%s -> ", a->who_name, a->who_tty);
	a = a->who_next;
    }
    xprintf("TAIL\n");
    if (a != &whotail) {
	xprintf(CGETS(26, 3, "BUG! last element is not whotail!\n"));
	abort();
    }
    a = whotail.who_prev;
    xprintf(CGETS(26, 4, "backward: "));
    while (a->who_prev != NULL) {
	xprintf("%s/%s -> ", a->who_name, a->who_tty);
	a = a->who_prev;
    }
    xprintf("HEAD\n");
    if (a != &whohead) {
	xprintf(CGETS(26, 5, "BUG! first element is not whohead!\n"));
	abort();
    }
    if (new)
	xprintf(CGETS(26, 6, "new: %s/%s\n"), new->who_name, new->who_tty);
    if (wp)
	xprintf("wp: %s/%s\n", wp->who_name, wp->who_tty);
}
#endif /* WHODEBUG */


static void
print_who(wp)
    struct who *wp;
{
#ifdef UTHOST
    Char   *cp = str2short(CGETS(26, 7, "%n has %a %l from %m."));
#else
    Char   *cp = str2short(CGETS(26, 8, "%n has %a %l."));
#endif /* UTHOST */
    struct varent *vp = adrof(STRwho);
    Char buf[BUFSIZE];

    if (vp && vp->vec[0])
	cp = vp->vec[0];

    tprintf(FMT_WHO, buf, cp, BUFSIZE, NULL, wp->who_time, (ptr_t) wp);
    for (cp = buf; *cp;)
	xputchar(*cp++);
    xputchar('\n');



( run in 1.651 second using v1.01-cache-2.11-cpan-364913b4093 )