home *** CD-ROM | disk | FTP | other *** search
- /*
- * Uptime
- *
- * This file is public domain.
- *
- * Author: Petri Nordlund <petrin@megabaud.fi>
- *
- * $Id: uptime.c 1.5 1995/10/05 12:31:31 petrin Exp petrin $
- *
- */
-
- /*
- * This is a fairly complete uptime-program. The sourcecode comes from Executive
- * uptime-client, it's just modified to support SysInfo.library. This program
- * can be compiled for multiuser.library support to show the number of users
- * currently logged in. This requires multiuser.library include-files and
- * a stub-library if you are using GCC. See GCC:geninline/README.glue for
- * information about how to generate the stub-library.
- */
-
- #include "defs.h"
- #include <proto/SysInfo.h>
- #include <libraries/SysInfo.h>
-
- /* PROTOTYPES */
- #ifdef USE_MULTIUSER
- static void AddUser(ULONG user, UWORD *uids, ULONG *nusers);
- ULONG CountTasks(void);
- #endif
- static void MyExit(void);
- static void GetTime(void);
- static void Users(void);
- static void LoadAverages(void);
- static void Uptime(void);
-
-
- /* EXTERNAL VARIABLES */
- extern struct ExecBase *SysBase;
-
-
- /* VARIABLES */
- #ifdef USE_MULTIUSER
- struct muBase *muBase = NULL;
- #endif
- struct SysInfo *si = NULL;
- struct Library *SysInfoBase = NULL;
-
-
- int
- main(int argc, char **argv)
- {
- /* MyExit will be called when we exit */
- atexit(MyExit);
-
- if(!(SysInfoBase = OpenLibrary(SYSINFONAME, SYSINFOVERSION)))
- {
- puts("Can't open SysInfo.library.");
- exit(RETURN_FAIL);
- }
-
- /* Initialize SysInfo.library, this will make the connection to the
- * server-process and allocate the SysInfo-structure. */
- if(!(si = InitSysInfo()))
- {
- puts("Couldn't initialize SysInfo.");
- exit(RETURN_FAIL);
- }
-
- #ifdef USE_MULTIUSER
- /* If this fails, we'll just output `1 user' */
- muBase = (struct muBase *) OpenLibrary(MULTIUSERNAME,MULTIUSERVERSION);
- #endif
-
- GetTime();
- printf(", ");
- Uptime();
- printf(", ");
- Users();
- printf(", ");
- LoadAverages();
- printf("\n");
-
- return(RETURN_OK);
- }
-
-
- /*
- * Exit. Free everything.
- */
- static void
- MyExit(void)
- {
- #ifdef USE_MULTIUSER
- if(muBase)
- CloseLibrary((struct Library *) muBase);
- #endif
-
- /* Free SysInfo.library */
- if(si)
- FreeSysInfo(si);
-
- if(SysInfoBase)
- CloseLibrary(SysInfoBase);
- }
-
-
- /*
- * Print system time
- */
- static void
- GetTime(void)
- {
- struct DateTime dtime;
- char timestr[LEN_DATSTRING+1];
-
- DateStamp(&dtime.dat_Stamp);
-
- dtime.dat_Format = FORMAT_DOS;
- dtime.dat_Flags = 0;
- dtime.dat_StrDay = NULL;
- dtime.dat_StrDate = NULL;
- dtime.dat_StrTime = timestr;
-
- DateToStr(&dtime);
-
- printf(timestr);
- }
-
-
- /*
- * Print number of users (from Multiuser if available)
- */
- static void
- Users(void)
- {
- ULONG nusers = 1;
-
- #ifdef USE_MULTIUSER
- if(muBase)
- {
- ULONG numtasks;
- UWORD *uids;
-
- Forbid();
-
- /* Count the number of tasks currently in system */
- numtasks = CountTasks();
-
- /* Allocate memory for each task */
- if(uids=AllocVec(numtasks*sizeof(UWORD),MEMF_CLEAR|MEMF_PUBLIC))
- {
- struct Task *task;
-
- /* Find out how many different uids there are */
-
- nusers = 0;
- AddUser(muGetTaskOwner(FindTask(NULL)), uids, &nusers);
- for(task = (struct Task *)SysBase->TaskReady.lh_Head;
- task->tc_Node.ln_Succ;
- task = (struct Task *)task->tc_Node.ln_Succ)
- AddUser(muGetTaskOwner(task), uids, &nusers);
- for(task = (struct Task *)SysBase->TaskWait.lh_Head;
- task->tc_Node.ln_Succ;
- task = (struct Task *)task->tc_Node.ln_Succ)
- AddUser(muGetTaskOwner(task), uids, &nusers);
- FreeVec(uids);
- }
-
- Permit();
- }
- #endif
-
- if((nusers>1) || (nusers==0))
- printf("%d users", nusers);
- else
- printf("%d user",nusers);
- }
-
-
- #ifdef USE_MULTIUSER
- static void
- AddUser(ULONG user, UWORD *uids, ULONG *nusers)
- {
- UWORD uid;
- BOOL found = FALSE;
- ULONG i;
-
- if(user)
- {
- uid = user>>16;
- for(i=0; !found && (i<*nusers); i++)
- found = (uids[i] == uid);
- if(!found)
- uids[(*nusers)++] = uid;
- }
- }
-
- static ULONG
- CountTasks(void)
- {
- ULONG i = 1;
- struct Task *task;
-
- for (task = (struct Task *)SysBase->TaskReady.lh_Head;
- task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
- i++;
- for (task = (struct Task *)SysBase->TaskWait.lh_Head;
- task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
- i++;
- return(i);
- }
- #endif
-
-
- /*
- * Print uptime. We use RAM:-disk creation time.
- */
- static void
- Uptime(void)
- {
- LONG boottime;
- LONG currenttime;
- struct DateTime dtime;
- BPTR lock;
- struct InfoData *infodata;
- struct DeviceList *ramdevice;
-
- /*
- * InfoData-structure must be long word aligned. By allocating it this way,
- * we can make sure it is aligned properly. GCC has a bug in it's aligned-
- * attribute <sigh> so it's not possible to just use: struct InfoData infodata.
- */
-
- if(!(infodata=AllocMem(sizeof(struct InfoData),MEMF_ANY)))
- return;
-
- if(lock = Lock("RAM:", SHARED_LOCK))
- {
- if((Info(lock, infodata)) == DOSTRUE)
- {
- ramdevice = BADDR(infodata->id_VolumeNode);
-
- boottime = SMult32(ramdevice->dl_VolumeDate.ds_Days, 86400) +
- SMult32(ramdevice->dl_VolumeDate.ds_Minute, 60) +
- SDivMod32(ramdevice->dl_VolumeDate.ds_Tick, TICKS_PER_SECOND);
-
- DateStamp(&dtime.dat_Stamp);
-
- currenttime = SMult32(dtime.dat_Stamp.ds_Days, 86400) +
- SMult32(dtime.dat_Stamp.ds_Minute, 60) +
- SDivMod32(dtime.dat_Stamp.ds_Tick, TICKS_PER_SECOND);
-
- currenttime -= boottime;
-
- if(currenttime > 0)
- {
- ULONG days, hrs, mins, hrs_tmp;
-
- /* Calculate days, hours and minutes */
- days = currenttime/86400;
- hrs_tmp = hrs = currenttime%86400;
- hrs = hrs/3600;
- mins = (hrs_tmp%3600) / 60;
-
- if(days || hrs || mins)
- printf("up ");
-
- if(days > 0)
- {
- if(days>1)
- printf("%d days ", days);
- else
- printf("%d day ", days);
- }
- if(hrs > 0)
- printf("%d:%02d", hrs, mins);
- else
- {
- if((mins>1) || (mins==0))
- printf("%d mins", mins);
- else
- printf("%d min", mins);
- }
- }
- }
- UnLock(lock);
- }
-
- FreeMem(infodata, sizeof(struct InfoData));
- }
-
-
- /*
- * Print load averages
- */
- static void
- LoadAverages(void)
- {
- struct SI_LoadAverage load; /* This will be filled by GetLoadAverage() */
-
- GetLoadAverage(si, &load); /* Ask SysInfo.library for current load averages */
-
- printf("load:");
-
- switch(si->loadavg_type)
- {
- case LOADAVG_FIXEDPNT:
-
- /* Convert fixed point values to floating point values */
-
- if(si->loadavg_time1)
- printf(" %.2f",(float) load.lavg_fixed.load1 / (float) si->fscale);
- else
- printf(" N/A");
-
- if(si->loadavg_time2)
- printf(" %.2f",(float) load.lavg_fixed.load2 / (float) si->fscale);
- else
- printf(" N/A");
-
- if(si->loadavg_time3)
- printf(" %.2f",(float) load.lavg_fixed.load3 / (float) si->fscale);
- else
- printf(" N/A");
-
- break;
- default:
- /* Load average is not supported */
- printf("-");
- }
- }
-