Sponsored Content
Full Discussion: Last time logged in
Top Forums Shell Programming and Scripting Last time logged in Post 302115566 by jim mcnamara on Wednesday 25th of April 2007 02:06:36 PM
Old 04-25-2007
Old C code to check /var/adm/wtmp - like the last command. It may compile/run on your box if the /var/adm/wtmp exists and it's not /var/adm/wtmpx - a different format.

Code:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <utmp.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>

/* error macro */
#define ck(x) if ((x)==NULL) \
{barf("Memory/File error");}

/* limits */
#define USER_NAME_LEN 8
#define MAX_USERS 2000

/* array of usernames and times */
typedef struct
{
	char user[12];
	time_t logtime;
} ulog_t;
ulog_t array[MAX_USERS]={ {0x0}, 0 };

/* exit point for errors */
void barf(const char *msg)
{
	perror(msg);
	exit(EXIT_FAILURE);	
}

/* return size of file in bytes */
size_t filesize(const int fd)
{
	struct stat st;

	if(fstat(fd, &st) == (-1) )	
		barf("Cannot stat file");			

	return st.st_size;
}
/* return time_t seconds for ndays in the past */
time_t days_ago(const time_t ndays)
{
	time_t then=0;

    errno=0;
    then=time(NULL);
	if(then == (time_t)-1 && errno)	
		barf("");		
	then-=(86400 * ndays);
			
	return then;
}

/* map the utmp file into memory */
void *mappit(FILE *u, size_t ulen)
{
	void *addr=mmap((void *)0, ulen, PROT_READ, MAP_PRIVATE, fileno(u),0);

	if (addr==MAP_FAILED)
		barf("mmap failed");		
	
	return addr;
}
/* unmap file */
int unmappit(void *addr, size_t len)
{
	if( munmap(addr,len)==(-1))
		return 1;
		
	return 0;	
}
/* find user in array, change time or (if not found) add to array */
void find(const struct utmp *src, int *cnt)
{
	int i=0;
	int found=0;
	int limit=*cnt;	
	char tmp[10]={0x0};

	snprintf(tmp, USER_NAME_LEN+1, "%s",src->ut_user);
	if(strlen(tmp)> 0 )
	{
		for(i=0; !found && i < limit; i++)
		{
			if(strncmp(tmp, array[i].user, USER_NAME_LEN)==0)
			{
				found=1;
				if(src->ut_time > array[i].logtime)
					array[i].logtime=src->ut_time;					
			}
		}		
		if(found==0)
		{
			memcpy(array[limit].user, tmp, USER_NAME_LEN);			
			array[limit].logtime=src->ut_time;			
			limit++;
		}			
		*cnt=limit;
    }
}

void setup_array(const void *addr, int *arrlen, const size_t ulen)
{
	
	int i=0;
	int max=ulen/sizeof(struct utmp);
	int cnt=0;
	const struct utmp *f=(const struct utmp *)addr;

	for(i=0; i<max; i++, f++)
	{
		if(f->ut_type==USER_PROCESS && strlen(f->ut_user))
		{
			find(f, &cnt);
		}
	}
	*arrlen=cnt;
}
int between(const time_t ckval, const time_t low, const time_t high)
{
	int retval=(ckval >= low && ckval <= high);
	return retval;
}

int search(const time_t low_limit, const time_t high_limit, int arrlen)
{
	int i=0;
	char tmp[80]={0x0};
	time_t lt=0;
	ulog_t *p=array;

	for(i=0; i < arrlen; i++, p++)
	{
		if( (high_limit && between(p->logtime, low_limit, high_limit)) ||
			(!high_limit && p->logtime < low_limit) )
		{
			lt=p->logtime;
			strftime(tmp, sizeof(tmp), "%c", localtime(&lt));
			printf("%s: last login %s\n", p->user, tmp);
		}
	}
	
	return 0;
}

/*************************
* 
* search for the last time each one logged on
* if logon in time range prt it
***************************/

int process(FILE *u, const time_t low_limit, const time_t high_limit)
{
	int retval=0;
	size_t ulen=filesize(fileno(u));
	int arrlen=0;
	void *addr=mappit(u, ulen);

	setup_array(addr, &arrlen, ulen);
	retval=search(low_limit, high_limit, arrlen);
	retval|=unmappit(addr, ulen);
    
	return retval;
}



/*
   first argument req'd: # days
   read from /var/adm/wtmp - (file used by last)
   print all users with last logins < low_limit or with
         last logins between low_limit and high_limit when 
         high_limit is non-zero
*/
int main(int argc, char **argv)
{
	int retval=0;
	const time_t low_limit= (argc>1) ? days_ago(atoi(argv[1])): 0;
	const time_t high_limit=(argc>2) ? days_ago(atoi(argv[2])): 0;
	FILE *u=fopen("/var/adm/wtmp", "r");

 	ck(u);
	if ( low_limit > 0 && (high_limit==0 || high_limit >= low_limit))
		retval=process(u, low_limit, high_limit);
	else
	{
		fprintf(stderr,
			"Bad parameters.\n\tONE required: <number days ago>\n\tOptional: <most recent day>\n");
		fprintf(stderr,"     usage: utmp 10 5\n");	
		retval=1;
	}
    
	return retval;
}

 

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

Finding last time users logged in

I would like to find out the last time all users have logged in or out. I tried the last command, but it could not find the wtmp file in /var/adm (I searched in othe directories also). This is an AIX rs6000 4.2.1 system. We are moving our applications from this system to an AIX 5.2 system and I... (11 Replies)
Discussion started by: jyoung
11 Replies

2. Shell Programming and Scripting

How can one know how much time user logged?

Hello, i know who command gives you the time when particular user logged in. And subtracting today's date and time from the one found in who we can get how much time user logged in. But this can get very much clumsy as we can't subtract date directly in unix . Is there any other way or command... (4 Replies)
Discussion started by: salman4u
4 Replies

3. UNIX for Dummies Questions & Answers

How many time have user logged last X days?

Hi all.. I was trying to do a little shell script, that would list users and their login times, lets say like last 5 days. But I couldnt figure out how to count users login times from previous days. Any tips? Funny that nobody has do this kinda script before, or atleast I couldnt find on... (2 Replies)
Discussion started by: Kimmo_
2 Replies

4. UNIX for Dummies Questions & Answers

How to do a login time and date list of users never logged on?

Hello, I'm trying to do a list of user that never connected to a couple of servers. I want to do a diff between the servers lists, and print out only the users that never has logged on each server. Here my first step : SERVER01: # finger `egrep -v -e "^\s*#" /etc/passwd | awk '{ print $1 }' |... (4 Replies)
Discussion started by: gogol_bordello
4 Replies

5. UNIX for Dummies Questions & Answers

Finding users logged on time and space useage

I need to find what users are currently logged onto the system that is easy just a simple who | awk '{ print $1 }' (thats all I need for the part), but I also need to find how long they have been logged on and the total amount of file space they are using. Thanks in advance, I have been looking... (3 Replies)
Discussion started by: mauler123
3 Replies

6. UNIX Desktop Questions & Answers

Shell script to display user logged in within given time

how can i know which users have logged in at specified given start and end time in 24 hour format? (3 Replies)
Discussion started by: meherzad4u
3 Replies

7. Shell Programming and Scripting

Shell script to display user logged last week and time connected

Hello all, I want to display all the user logged last week and know the time tnat they are connected. I have been looking for a solution in the Forum, but I didn't find. Thanks in advance (4 Replies)
Discussion started by: ahernandez
4 Replies

8. UNIX for Dummies Questions & Answers

Script to determine logged in time

Hi all So I am thinking my inability to cope with math is bogging me down here so Im asking for help. I want to determine how long a user has been logged on for by using the date and who commands to determine the time they have been logge don. My problem is that I keep getting the wrong... (2 Replies)
Discussion started by: losingit
2 Replies

9. Homework & Coursework Questions

Sort current logged in users by log in time (supposedly to be very easy but I'm missing something)

1. The problem statement, all variables and given/known data: Show all users who are currently logged in, sorted from earliest to latest log in time. The log in time includes the month, day, and time. 2. Relevant commands, code, scripts, algorithms: finger, who, sort, pipe, head, tail, ... (8 Replies)
Discussion started by: vtmd
8 Replies

10. Shell Programming and Scripting

• Write a shell script that upon invocation shows the time and date and lists all the logged-in user

help me (1 Reply)
Discussion started by: sonu pandey
1 Replies
All times are GMT -4. The time now is 07:57 AM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy