/* Search utmp for the local user */ int find_user (char *name, char *tty) { STRUCT_UTMP *utmpbuf, *uptr; size_t utmp_count; int status; struct stat statb; char ftty[sizeof (PATH_DEV) + sizeof (uptr->ut_line)]; time_t last_time = 0; int notty; notty = (*tty == '\0'); status = NOT_HERE; strcpy (ftty, PATH_DEV); read_utmp (PATH_UTMP, &utmp_count, &utmpbuf, READ_UTMP_USER_PROCESS | READ_UTMP_CHECK_PIDS); for (uptr = utmpbuf; uptr < utmpbuf + utmp_count; uptr++) { if (!strncmp (UT_USER (uptr), name, sizeof (UT_USER (uptr)))) { if (notty) { /* no particular tty was requested */ strncpy (ftty + sizeof (PATH_DEV) - 1, uptr->ut_line, sizeof (ftty) - sizeof (PATH_DEV) - 1); ftty[sizeof (ftty) - 1] = 0; if (stat (ftty, &statb) == 0) { if (!(statb.st_mode & S_IWGRP)) { if (status != SUCCESS) status = PERMISSION_DENIED; continue; } if (statb.st_atime > last_time) { last_time = statb.st_atime; strcpy (tty, uptr->ut_line); status = SUCCESS; } continue; } } if (!strcmp (uptr->ut_line, tty)) { status = SUCCESS; break; } } } free (utmpbuf); return status; }
char * extract_trimmed_name (const STRUCT_UTMP *ut) { char *p, *trimmed_name; trimmed_name = xmalloc (sizeof (UT_USER (ut)) + 1); strncpy (trimmed_name, UT_USER (ut), sizeof (UT_USER (ut))); /* Append a trailing NUL. Some systems pad names shorter than the maximum with spaces, others pad with NULs. Remove any trailing spaces. */ trimmed_name[sizeof (UT_USER (ut))] = '\0'; for (p = trimmed_name + strlen (trimmed_name); trimmed_name < p && p[-1] == ' '; *--p = '\0') continue; return trimmed_name; }
void wtmpxrawdump (const char *wtmpfile, const char *user) { STRUCT_UTMP *utp; struct in_addr addr; char *addr_string, *time_string; if (access (wtmpfile, R_OK)) die (errno, "cannot access the file"); /* Ignore the return value for now. Solaris' utmpname returns 1 upon success -- which is contrary to what the GNU libc version does. In addition, older GNU libc versions are actually void. */ UTMP_NAME_FUNCTION (wtmpfile); SET_UTMP_ENT (); while ((utp = GET_UTMP_ENT ()) != NULL) { if (user && strncmp (UT_USER (utp), user, sizeof (UT_USER (utp)))) continue; /* FIXME: missing support for IPv6 */ #ifdef HAVE_UTP_UT_ADDR_V6 addr.s_addr = utp->ut_addr_v6[0]; #endif addr_string = inet_ntoa (addr); time_string = timetostr (UT_TIME_MEMBER (utp)); switch (utp->ut_type) { default: /* Note: also catch EMPTY/UT_UNKNOWN values */ printf ("%-9s", "NONE"); break; #ifdef RUN_LVL /* Undefined on AIX if _ALL_SOURCE is false */ case RUN_LVL: printf ("%-9s", "RUNLEVEL"); break; #endif case BOOT_TIME: printf ("%-9s", "REBOOT"); break; case OLD_TIME: case NEW_TIME: /* FIXME */ break; case INIT_PROCESS: printf ("%-9s", "INIT"); break; case LOGIN_PROCESS: printf ("%-9s", "LOGIN"); break; case USER_PROCESS: printf ("%-9.*s", sizeof (UT_USER (utp)), UT_USER (utp)); break; case DEAD_PROCESS: printf ("%-9s", "DEAD"); break; #ifdef ACCOUNTING /* Undefined on AIX if _ALL_SOURCE is false */ case ACCOUNTING: printf ("%-9s", "ACCOUNT"); break; #endif } /* pid */ UT_PID (utp) ? printf ("[%05d]", UT_PID (utp)) : printf ("[%5s]", "-"); /* line id host addr date&time */ printf (" [%-12.*s] [%-4.*s] [%-19.*s] [%-15.15s] [%-19.19s]\n", sizeof (utp->ut_line), utp->ut_line, sizeof (utp->ut_id), utp->ut_id, sizeof (utp->ut_host), utp->ut_host, addr_string, time_string); } END_UTMP_ENT (); }