Initial C daemon

it works... not optimized... at least it compiles...
This commit is contained in:
RLF
2024-01-10 01:51:11 -05:00
parent 2ad2e0b128
commit d7e9bb2b0d
3 changed files with 999 additions and 0 deletions

View File

@@ -0,0 +1,261 @@
/*
* UNO Monitor Daemon
* Kidacro <kidacro@archamedis.net>
*
* gather_stats.c - retrieves stats from system
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/sysinfo.h>
#include <sys/vfs.h>
#define MAX_ENTRIES 10
// from monitor_daemon.c
void send_stats();
// local function prototypes
void get_stats();
char *trim(char *str);
static void get_cpu_load();
static void get_cpu_temp();
static void get_free_mem();
static void get_free_space();
// external vars (monitor_daemon.c)
extern const char *cpu_temp_file;
extern const char *cpu_fanspeed_file;
extern char *drive_free_space[MAX_ENTRIES];
extern int drive_free_space_count;
extern FILE *log_stream;
extern int debug;
extern int line_length;
extern int line_count;
// stats vars
// TODO: make the character sizes dynamic based on line_length
// src/gather_stats.c:43:6: error: variably modified freespace at file scope <-- damn C
// so we have to make a concession and either #define a max or.... no clue... go back to PHP?
char cpuload[4]; // line 1
char cputemp[6]; // line 1
char freemem[6]; // line 1
char freespace[16]; // line 2
// sysinfo vars
int sysinfo(struct sysinfo *info);
// proto:
// struct sysinfo {
// long uptime; /* Seconds since boot */
// unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
// unsigned long totalram; /* Total usable main memory size */
// unsigned long freeram; /* Available memory size */
// unsigned long sharedram; /* Amount of shared memory */
// unsigned long bufferram; /* Memory used by buffers */
// unsigned long totalswap; /* Total swap space size */
// unsigned long freeswap; /* swap space still available */
// unsigned short procs; /* Number of current processes */
// unsigned long totalhigh; /* Total high memory size */
// unsigned long freehigh; /* Available high memory size */
// unsigned int mem_unit; /* Memory unit size in bytes */
// char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
//};
// trims end of strings
char *trim(char *str)
{
size_t len = 0;
char *frontp = str;
char *endp = NULL;
if( str == NULL ) { return NULL; }
if( str[0] == '\0' ) { return str; }
len = strlen(str);
endp = str + len;
/* Move the front and back pointers to address the first non-whitespace
* characters from each end.
*/
while(isspace((unsigned char) *frontp)) { ++frontp; }
if(endp != frontp) {
while(isspace((unsigned char) *(--endp)) && endp != frontp) {}
}
if(frontp != str && endp == frontp) {
*str = '\0';
}
else if(str + len - 1 != endp) {
*(endp + 1) = '\0';
}
/* Shift the string so that it starts at str so that if it's dynamically
* allocated, we can still free it on the returned pointer. Note the reuse
* of endp to mean the front of the string buffer now.
*/
endp = str;
if(frontp != str) {
while(*frontp) { *endp++ = *frontp++; }
*endp = '\0';
}
return str;
}
// get stats (retreive, combine, and send stats)
// TODO: force trunication for each line to line_length
// no reason to hardcode '24' below when we know the exact line_length
void get_stats()
{
char line_1[24], line_2[24], line_3[24];
get_cpu_load();
get_cpu_temp();
get_free_mem();
get_free_space();
snprintf(line_1,sizeof(line_1),"#1%s%% %sC %sM@",cpuload,cputemp,freemem);
snprintf(line_2,sizeof(line_2),"#2%s@",trim(freespace));
snprintf(line_3,sizeof(line_3),"#3%s@",cpuload);
send_stats(line_1,line_2,line_3);
return;
}
static void get_cpu_load()
{
//static unsigned int lastTotalUser, lastTotalUserLow, lastTotalSys, lastTotalIdle;
static unsigned long long lastTotalUser, lastTotalUserLow, lastTotalSys, lastTotalIdle;
float percent;
static float lastPercent;
int intPercent, read_result = 0;
FILE* file;
unsigned long long totalUser, totalUserLow, totalSys, totalIdle, total;
file = fopen("/proc/stat", "r");
read_result = fscanf(file, "cpu %llu %llu %llu %llu", &totalUser, &totalUserLow, &totalSys, &totalIdle);
fclose(file);
// if result cannot be read, set to 0
if(read_result < 0) {
snprintf(&*cpuload, sizeof(0), "%d", 0);
return;
}
// we dont have a good value, use old value
if(totalUser < lastTotalUser || totalUserLow < lastTotalUserLow ||
totalSys < lastTotalSys || totalIdle < lastTotalIdle)
{
//percent = -1.0;
percent = lastPercent;
}
// we have a good value, save it and process it
else
{
total = (totalUser - lastTotalUser) + (totalUserLow - lastTotalUserLow) + (totalSys - lastTotalSys);
percent = total * 100;
total += (totalIdle - lastTotalIdle);
percent /= total;
lastPercent = percent;
}
lastTotalUser = totalUser;
lastTotalUserLow = totalUserLow;
lastTotalSys = totalSys;
lastTotalIdle = totalIdle;
intPercent = percent;
snprintf(&*cpuload, sizeof(intPercent), "%d", intPercent);
return;
}
static void get_cpu_temp()
{
FILE* ptr;
char str[10];
// opening file in readonly mode
ptr = fopen(&*cpu_temp_file, "r");
if(NULL == ptr) {
fprintf(log_stream,"File %s can't be opened!\n",cpu_temp_file);
return;
}
while(fgets(str, 10, ptr) != NULL) {
if(debug) {
fprintf(log_stream,"Raw CPU temp: %s\n", str);
}
}
/*
1 decimal place
char a = str[0];
char b = str[1];
char c = str[2];
snprintf(&*cputemp,6,"%c%c.%c",a,b,c);*/
// no decimals
char a = str[0];
char b = str[1];
snprintf(&*cputemp,6,"%c%c",a,b);
fclose(ptr);
return;
}
static void get_free_mem()
{
struct sysinfo info;
int myfreemem;
if(sysinfo(&info) < 0) {
return;
}
if(debug) {
fprintf(log_stream,"RAW free mem: %ld\n",info.freeram);
}
myfreemem = info.freeram / 1024 / 1024;
snprintf(&*freemem,sizeof(freemem),"%d",myfreemem);
return;
}
static void get_free_space()
{
struct statfs info;
int n = 0;
char *mydrive;
char myfree_string[line_length];
long unsigned int mytmpfree;
for(n = 0; n < drive_free_space_count; n++) {
mydrive = drive_free_space[n];
statfs(mydrive, &info);
mytmpfree = ((info.f_bavail*4) / 1024 / 1024) + 1;
snprintf(myfree_string,line_length,"%ldG ",mytmpfree);
strcat(freespace,myfree_string);
if(debug) {
fprintf(log_stream, "My Drive: %s\n"
" block size : %ld,"
" total data blocks : %ld,"
" free blocks for root: %ld,"
" free blocks for user: %ld,"
" free space in G: %ld\n\n",
mydrive, info.f_bsize, info.f_blocks, info.f_bfree, info.f_bavail, mytmpfree);
}
}
return;
}