#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 ); }
|