/*
* This program is original work by Zac Sprackett <zacs@valinux.com> .
* This program is distributed under the GNU General Public License (GPL)
* as outlined in the COPYING file.
*
* Copyright (C) 2000, Zac Sprackett, and VA Linux Systems, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*/
#include <stdio.h>
#include <sys/socket.h>
#include <signal.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <stdlib.h>
#include <sys/time.h>
#include <netdb.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <vacmclient_api.h>
int compatibility = 0;
/* Function prototypes so we don't generate errors */
void display_usage(void);
int do_uptime(void *handle, char *node);
void display_usage(void)
{
printf("Usage: ruptime -c <Nexxus> -u <Username> -p <Password> -n <Node>\n");
printf("\nOptional Flags\n");
printf(" -f used to force compatibility with uptime\n");
exit(-1);
}
int do_uptime(void *handle, char *node)
{
int rc;
char *bword;
char send_pkt[4096];
char *rcvd_pkt;
int rcvd_len;
int upminutes, uphours, updays;
int numuser = 0;
double load_avg[3];
double raw_uptime;
time_t raw_time;
struct tm *time_tm;
char buf[128];
int pos = 0;
/* Get the current time */
time(&raw_time);
time_tm = localtime(&raw_time);
pos += sprintf(buf, " %2d:%02d%s ",
time_tm->tm_hour%12 ? time_tm->tm_hour%12 : 12,
time_tm->tm_min,time_tm->tm_hour > 11 ? "pm" : "am");
/* Get the amount of uptime */
snprintf(send_pkt,sizeof(send_pkt),"SYSSTAT:UPTIME:%s",node);
api_nexxus_send_ipc(handle,send_pkt,strlen(send_pkt)+1);
while(1)
{
if((rc=api_nexxus_wait_for_data(handle,&rcvd_pkt,&rcvd_len,10))<0)
{
printf("Error reading uptime from Nexxus\n");
exit(-1);
}
if(!(bword = strtok(rcvd_pkt,":"))) /* SYSSTAT */
break;
if(!(bword = strtok(NULL,":"))) /* Job ID */
break;
if(!(bword = strtok(NULL,":"))) /* UPTIME */
break;
if (!strcmp(bword,"UPTIME"))
{
bword = strtok(NULL,":");
sscanf(bword,"%lf",&raw_uptime);
free(rcvd_pkt);
}
else if (!strcmp(bword,"JOB_STARTED"))
{
free(rcvd_pkt);
continue;
}
else if (!strcmp(bword,"JOB_COMPLETED"))
{
free(rcvd_pkt);
break;
}
else if (!strcmp(bword,"JOB_ERROR"))
{
bword = strtok(NULL,":");
printf("Error reading uptime from Nexxus (%s)\n",bword);
exit(-1);
}
else
{
printf("Unexpected Response (%s)\n",bword);
}
}
/* Convert it to a string */
updays = (int)raw_uptime / (60*60*24);
strcat (buf,"up ");
pos += 3;
if (updays)
pos += sprintf(buf + pos, "%d day%s, ", updays, (updays != 1) ? "s":"");
upminutes = (int)raw_uptime / 60;
uphours = upminutes / 60;
uphours = uphours % 24;
upminutes = upminutes % 60;
if (uphours)
pos += sprintf (buf + pos, "%2d:%02d, ", uphours, upminutes);
else
pos += sprintf (buf + pos, "%d min, ", upminutes);
/* Count the number of users */
snprintf(send_pkt,sizeof(send_pkt),"SYSSTAT:WHO:%s",node);
api_nexxus_send_ipc(handle,send_pkt,strlen(send_pkt)+1);
while(1)
{
if((rc=api_nexxus_wait_for_data(handle,&rcvd_pkt,&rcvd_len,10))<0)
{
printf("Error reading user information from Nexxus\n");
exit(-1);
}
if(!(bword = strtok(rcvd_pkt,":"))) /* SYSSTAT */
break;
if(!(bword = strtok(NULL,":"))) /* Job ID */
break;
if(!(bword = strtok(NULL,":"))) /* WHO */
break;
if (!strcmp(bword,"WHO"))
{
numuser++;
free(rcvd_pkt);
}
else if (!strcmp(bword,"JOB_STARTED"))
{
free(rcvd_pkt);
continue;
}
else if (!strcmp(bword,"JOB_COMPLETED"))
{
free(rcvd_pkt);
break;
}
else if (!strcmp(bword,"JOB_ERROR"))
{
bword = strtok(NULL,":");
printf("Error reading user information from Nexxus (%s)\n",bword);
exit(-1);
}
else
{
printf("Error reading user information from Nexxus\n");
printf("Unexpected Response (%s)\n",bword);
}
}
/* Add it to our buffer */
pos += sprintf(buf + pos, "%2d user%s, ", numuser, numuser == 1 ? "":"s");
/* Get the load average */
snprintf(send_pkt,sizeof(send_pkt),"SYSSTAT:CPU_LOAD:%s",node);
api_nexxus_send_ipc(handle,send_pkt,strlen(send_pkt)+1);
while(1)
{
if((rc=api_nexxus_wait_for_data(handle,&rcvd_pkt,&rcvd_len,10))<0)
{
printf("Error reading cpu load from nexxus\n");
exit(-1);
}
if(!(bword = strtok(rcvd_pkt,":"))) /* SYSSTAT */
break;
if(!(bword = strtok(NULL,":"))) /* Job ID */
break;
if(!(bword = strtok(NULL,":"))) /* UPTIME */
break;
if (!strcmp(bword,"CPU_LOAD"))
{
bword = strtok(NULL,":");
sscanf(bword,"%lf",&load_avg[0]);
bword = strtok(NULL,":");
sscanf(bword,"%lf",&load_avg[1]);
bword = strtok(NULL,":");
sscanf(bword,"%lf",&load_avg[2]);
free(rcvd_pkt);
}
else if (!strcmp(bword,"JOB_STARTED"))
{
free(rcvd_pkt);
continue;
}
else if (!strcmp(bword,"JOB_COMPLETED"))
{
free(rcvd_pkt);
break;
}
else if (!strcmp(bword,"JOB_ERROR"))
{
bword = strtok(NULL,":");
printf("Error reading cpu load from nexxus (%s)\n",bword);
exit(-1);
}
else
{
printf("Unexpected Response (%s)\n",bword);
}
}
pos += sprintf(buf + pos, " load average: %.2f, %.2f, %.2f",
load_avg[0], load_avg[1], load_avg[2]);
if (!compatibility)
printf(" Uptime Information for Node %s\n", node);
printf("%s\n", buf);
return(0);
}
int main(int argc, char **argv)
{
int rc;
char *nexxus = NULL;
char *username = NULL;
char *password = NULL;
char *node = NULL;
void *handle;
int rcvd_len;
char *rcvd_pkt;
/* Deal with our commandline arguments */
opterr = 0;
while ((rc = getopt(argc,argv,"c:n:p:u:f"))!=EOF)
{
if((char)rc == 'c')
nexxus = optarg;
else if((char)rc == 'n')
node = optarg;
else if((char)rc == 'p')
password = optarg;
else if((char)rc == 'u')
username = optarg;
else if((char)rc == 'f')
compatibility++;
else
display_usage();
}
if ((!nexxus)||(!username)||(!password)||(!node))
display_usage();
/* Connect to the Nexxus */
if(api_nexxus_connect(nexxus,username,password,&handle)<0)
{
printf("Unable to connect to nexxus at %s (%s)\n",
nexxus,
api_nexxus_get_error());
exit(-1);
}
/* Wait for NEXXUS_READY message */
if((rc=api_nexxus_wait_for_data(
handle,
&rcvd_pkt,
&rcvd_len,
10))<0)
{
printf("ruptime: timed out waiting for NEXXUS_READY\n");
exit(-1);
}
if(strcmp(rcvd_pkt, "NEXXUS_READY"))
{
printf("ruptime: Received unexpected data during connect (%s)\n",rcvd_pkt);
exit(-1);
}
/* Its our responsibility to free the buffer */
free(rcvd_pkt);
do_uptime(handle,node);
return(0);
} |