#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <ctype.h>
#include <pwd.h> #include <sys/types.h> #include <dirent.h>
#include <sys/stat.h> #include <unistd.h> #include <time.h> extern int errno; typedef signed char bool_t;
#if !defined ( FALSE ) #define FALSE 0 #endif
#if !defined ( TRUE ) #define TRUE 1 #endif
#define GU_LINE_BUFFER_LEN 1024 #define GU_FILE_NAME_LEN 81
#define START_TIME_STR_LEN 16 #define DIFF_TIME_STR_LEN 12 #define RUN_TIME_STR_LEN 12 #define GU_DEBUG
#if defined GU_DEBUG
#define GU_ASSERT(A) \
if (A) { \
} else { \
GU_logAssertion( __FILE__, __LINE__ ); \
}
#else
#define GU_ASSERT(A)
#endif
static FILE *SpfLog = (FILE *) NULL; static char *SszLog = "message.log";
typedef struct UserStatTag {
int pid;
char szName[GU_FILE_NAME_LEN];
char state;
int ppid;
int pgrp;
int sid;
int terminal;
int pgid;
unsigned long flags;
unsigned long min_flt;
unsigned long cmin_flt;
unsigned long maj_flt;
unsigned long cmaj_flt;
long utime;
long stime;
long cutime;
long cstime;
long counter;
long priority;
unsigned long timeout;
unsigned long it_real_value;
long start_time;
unsigned size;
unsigned rss;
unsigned rlim;
unsigned long start_code;
unsigned long end_code;
unsigned long start_stack;
unsigned long st_ptr;
unsigned long ip_ptr;
unsigned long signal;
unsigned long blocked;
unsigned long sv_ignored;
unsigned long sv_handle;
unsigned long addr_kernel;
} UserStatStruct;
void
GU_exit(int nLevel)
{
exit(nLevel);
}
static void
openLogFile(void)
{
SpfLog = fopen(SszLog, "w");
if (!SpfLog) {
fprintf(stderr, "%s(%d): Could not open %s for message logging!\n",
__FILE__, __LINE__, SszLog);
GU_exit(-1);
}
setvbuf(SpfLog, NULL, 0, _IONBF);
}
static void
closeLogFile(void)
{
fclose(SpfLog);
SpfLog = (FILE *) NULL;
}
int
GU_logError(FILE * pf, char *szFmt,...)
{
va_list vargPtr;
va_start(vargPtr, szFmt);
if (!SpfLog) {
openLogFile();
}
if (pf) {
vfprintf(pf, szFmt, vargPtr);
}
vfprintf(SpfLog, szFmt, vargPtr);
va_end(vargPtr); return (0); }
void
GU_logAssertion(char *szFile, int nLine)
{
fprintf(stderr, "%s(%d): Assertion failed!\n", szFile, nLine);
exit(-99);
}
static int parseTimeLong ( char *timeStr, time_t timeVal, char *timeFormat ) { int returnCode = 0; /* Return code from strftime */ struct tm *tm = (struct tm *)NULL; /* Time struct, used as temp space */
memset( timeStr, '\0', DIFF_TIME_STR_LEN );
tm = localtime( &timeVal );
returnCode = strftime( timeStr,
START_TIME_STR_LEN - 4,
timeFormat,
tm );
return( returnCode ); } static char * getRunTime ( time_t timeVal ) { static char timeStr[ RUN_TIME_STR_LEN ]; time_t seconds = (time_t)0; time_t minutes = (time_t)0; time_t hours = (time_t)0; time_t days = (time_t)0;
memset( timeStr, '\0', RUN_TIME_STR_LEN );
/* If to be reported as ... */
if ( timeVal < (time_t)60 ) {
sprintf( timeStr, "%ld s", timeVal );
} else if ( timeVal < (time_t)3600 ) {
minutes = timeVal / (time_t)60;
seconds = timeVal % (time_t)60;
sprintf( timeStr, "%ld:%ld m", minutes, seconds );
} else if ( timeVal < (time_t)86400 ) {
hours = timeVal / (time_t)3600;
minutes = ( timeVal % (time_t)3600 ) / (time_t)60;
seconds = ( timeVal % (time_t)3600 ) % (time_t)60;
sprintf( timeStr, "%ld:%ld h", hours, minutes );
} else {
days = timeVal / (time_t)86400;
hours = ( timeVal % (time_t)86400 ) / (time_t)3600;
sprintf( timeStr, "%ld:%ld d", days, hours );
}
return( timeStr ); } /* **************** Start of stuff **************************** */ int main ( int argc, char *argv[] ) { FILE *pf = (FILE *)NULL; struct passwd *pwdUser = (struct passwd *)NULL; struct passwd *pwdCurr = (struct passwd *)NULL;
char *pszProc = (char *)NULL; char *pszUser = (char *)NULL; DIR *pDir = (DIR *)NULL; struct dirent *pEnt = (struct dirent *)NULL; char szFileName[GU_FILE_NAME_LEN]; int iRC = 0; uid_t uidUser; struct stat ss; UserStatStruct sus; time_t ttStart = 0; time_t ttCur = 0; time_t ttMidNight = 0; time_t ttElapsed = 0; time_t ttBoot = 0; char szLine[GU_LINE_BUFFER_LEN]; char szBuf[GU_LINE_BUFFER_LEN]; int iReadIn; char *psz = (char *)NULL; char szStartTime[ START_TIME_STR_LEN ]; char szRunTime[ DIFF_TIME_STR_LEN ];
char *pszStartFormat = (char *)NULL; char *pszRunFormat = (char *)NULL; char *pszCurrUser = (char *)NULL; int i; int j; int k; struct tm *ptm = (struct tm *)NULL; struct tm tm;
ttCur = time( (time_t *)NULL ); ptm = localtime( &ttCur ); tm = *ptm; tm.tm_sec = 0; tm.tm_min = 0; tm.tm_hour = 0; ttMidNight = mktime( &tm );
/* printf( "%ld %ld\n", ttCur, ttMidNight ); */
if ( argc == 2 || argc == 3 ) {
pszProc = argv[1];
if ( argc == 3 ) {
pszUser = argv[2];
pwdUser = getpwnam( pszUser );
if ( pwdUser ) {
GU_logError( NULL, "%s has uid %d\n",
pwdUser->pw_name, pwdUser->pw_uid );
uidUser = pwdUser->pw_uid;
} else {
GU_logError( stderr, "%s has no account\n", pszUser );
GU_exit( -1 );
}
}
} else {
GU_logError( stderr, "%s <base name> [<user>]\n", argv[0] );
GU_exit( -1 );
}
/*
* Get the boot time!
*/
sprintf( szFileName, "%s/stat", pszProc );
pf = fopen( szFileName, "r" );
if ( !pf ) {
GU_logError( stderr, "%s(%d): Could not open %s for reading.\n",
__FILE__, __LINE__, szFileName );
exit( -1 );
}
iReadIn = 0;
while (fgets(szLine, GU_LINE_BUFFER_LEN, pf)) {
if ( feof( pf ) ) {
break;
}
strcpy( szBuf, szLine );
iReadIn++;
psz = strtok(szLine, " ");
if ( !psz ) {
continue;
}
if ( !strcmp( psz, "btime" ) ) {
psz = strtok(NULL, "\n");
if ( !psz ) {
continue;
}
ttBoot = atol( psz );
break;
}
}
GU_logError( NULL, "Current time is %ld\nBoot Time is %ld\n",
ttCur, ttBoot );
fclose( pf ); pf = (FILE *)NULL;
pDir = opendir( pszProc );
if ( !pDir ) {
GU_logError( stderr, "%s does not exist!\n", pszProc );
GU_exit( -1 );
}
GU_logError( stdout, "%8s %5s %5s %5s %s %3s %12s %12s %5s %s %s\n",
"User", "pid", "uid", "pgrp", "F", "pri", "start", "elapsed",
"ppid", "pwd", "command line" );
while ( 1 ) {
pEnt = readdir( pDir );
if ( !pEnt ) {
break;
}
if ( !isdigit( pEnt->d_name[0] ) ) {
continue;
}
GU_logError( NULL, "%s current entry\n", pEnt->d_name );
sprintf( szFileName, "%s/%s/stat", pszProc, pEnt->d_name );
iRC = stat( szFileName, &ss );
if ( iRC ) {
GU_logError( stderr, "Could not access %s -- %s\n",
szFileName, strerror( errno ) );
continue;
}
if ( pszUser && ss.st_uid != uidUser ) {
continue;
} else if ( pszUser ) {
pszCurrUser = pszUser;
} else {
pwdCurr = getpwuid( ss.st_uid );
if ( pwdCurr ) {
pszCurrUser = pwdCurr->pw_name;
} else {
GU_logError( stderr, "%s has no account\n", pszUser );
continue;
}
}
GU_logError( NULL, "UID = %d\n", ss.st_uid );
pf = fopen( szFileName, "r" );
if ( !pf ) {
GU_logError( stderr, "PID has expired: %s\n", szFileName );
continue;
}
fscanf( pf, "%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu"
"%ld %ld %ld %ld %ld %ld %lu %lu %ld %u %u %u"
"%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
&sus.pid, sus.szName, &sus.state, &sus.ppid, &sus.pgrp,
&sus.sid, &sus.terminal, &sus.pgid, &sus.flags,
&sus.min_flt, &sus.cmin_flt, &sus.maj_flt, &sus.cmaj_flt,
&sus.utime, &sus.stime, &sus.cutime, &sus.cstime,
&sus.counter, &sus.priority, &sus.timeout,
&sus.it_real_value, &sus.start_time, &sus.size,
&sus.rss, &sus.rlim, &sus.start_code, &sus.end_code,
&sus.start_stack, &sus.st_ptr, &sus.ip_ptr, &sus.signal,
&sus.blocked, &sus.sv_ignored, &sus.sv_handle,
&sus.addr_kernel );
GU_logError( NULL, "%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu"
"%ld %ld %ld %ld %ld %ld %lu %lu %ld %u %u %u"
"%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
sus.pid, sus.szName, sus.state, sus.ppid, sus.pgrp,
sus.sid, sus.terminal, sus.pgid, sus.flags,
sus.min_flt, sus.cmin_flt, sus.maj_flt, sus.cmaj_flt,
sus.utime, sus.stime, sus.cutime, sus.cstime,
sus.counter, sus.priority, sus.timeout,
sus.it_real_value, sus.start_time, sus.size,
sus.rss, sus.rlim, sus.start_code, sus.end_code,
sus.start_stack, sus.st_ptr, sus.ip_ptr, sus.signal,
sus.blocked, sus.sv_ignored, sus.sv_handle,
sus.addr_kernel );
fclose( pf );
pf = (FILE *)NULL;
ttStart = ttBoot + sus.start_time / 100;
ttElapsed = ttCur - ttStart;
if ( ttStart < ttMidNight ) {
pszRunFormat = "%b %d";
pszStartFormat = "%b %d";
} else {
if ( ttElapsed < ( 60 * 60 ) ) {
pszRunFormat = "%M:%S";
pszStartFormat = "%r";
} else if ( ttElapsed < ( 24 * 60 * 60 ) ) {
pszRunFormat = "%H:%M:%S";
pszStartFormat = "%r";
} else {
pszRunFormat = "%b %d";
pszStartFormat = "%b %d";
}
}
/* Get the time the process was kicked off */
parseTimeLong( szStartTime, ttStart, pszStartFormat );
/* Get the time the proc ran */
#if defined ( NOT_NOW )
parseTimeLong( szRunTime, ttElapsed, pszRunFormat );
#else
strcpy( szRunTime, getRunTime( ttElapsed ) );
#endif
/* username pid uid gid state nice start time elasped time parent pid fullpath command line args */
GU_logError( stdout,
"%8s %5d %5d %5d %c %3d %12s %12s %5d",
pszCurrUser, sus.pid, uidUser,
sus.pgrp, sus.state, sus.priority, szStartTime, szRunTime,
sus.ppid );
sprintf( szFileName, "%s/%s/environ", pszProc, pEnt->d_name ); pf = fopen( szFileName, "r" ); if ( !pf ) { GU_logError( stdout, "\n" ); continue; }
memset( szLine, '\0', GU_LINE_BUFFER_LEN );
psz = fgets(szLine, GU_LINE_BUFFER_LEN, pf);
if ( !psz ) {
GU_logError( NULL,
"Could not get data from %s -- %d -- %d\n",
szFileName,
ferror( pf ), feof( pf ) );
}
for ( i = 0; i < GU_LINE_BUFFER_LEN; i = k ) {
for ( k = i + 1; k < GU_LINE_BUFFER_LEN; k++ ) {
if ( szLine[k] == '=' ) {
szLine[k] = '\0';
j = k + 1;
} else if ( szLine[k] == '\0' ) {
k++;
break;
}
}
if ( !strcmp( &szLine[i], "PWD" ) ) {
GU_logError( stdout, " %s", &szLine[j] );
break;
}
}
fclose( pf );
pf = (FILE *)NULL;
sprintf( szFileName, "%s/%s/cmdline", pszProc, pEnt->d_name ); pf = fopen( szFileName, "r" ); if ( !pf ) { GU_logError( stdout, "\n" ); continue; }
memset( szLine, '\0', GU_LINE_BUFFER_LEN );
psz = fgets(szLine, GU_LINE_BUFFER_LEN, pf);
if ( !psz ) {
GU_logError( NULL,
"Could not get data from %s -- %d -- %d\n",
szFileName,
ferror( pf ), feof( pf ) );
}
for ( i = 0; i < GU_LINE_BUFFER_LEN; i++ ) {
if ( szLine[i] == '\0' ) {
szLine[i] = ' ';
}
}
for ( i--; i > 0; i-- ) {
if ( szLine[i] != ' ' ) {
break;
} else {
szLine[i] = '\0';
}
}
GU_logError( stdout, " %s", szLine );
fclose( pf );
pf = (FILE *)NULL;
GU_logError( stdout, "\n" ); }
closedir( pDir );
closeLogFile(); return ( 0 ); }
|