/* A colorful `free' clone with graphs and such. -- Roy Keene [200819992000] rkeene@suspend.net Bug 230819992230: freecolor segfaults if swapping is off. (fixed, reported by shammack@goldinc.com). Warn 260919991600: Warning about returning a local variable fixed ( Jakob Erikson ). Annoy 270819990700: Made the code for the "-o" option neater. Bug 270819990700: Fixed support for unknown options (Rene #include #ifndef PROC_MEMINFO #define PROC_MEMINFO "/proc/meminfo" #endif #else #include #endif #include #include #include #include #ifndef NO_GETOPT #include #endif #define BARLEN 35 #define HEADERLEN 14 #define VERSION "0.8.10" extern char *optarg; extern int optind, opterr, optopt; struct freecolor_meminfo { 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 cachedram; /* Memory used for I/O cache */ unsigned long totalswap; /* Total swap space size */ unsigned long freeswap; /* swap space still available */ }; void bargraph(float percent, float secondper, char marks[BARLEN + HEADERLEN + 1], int usefull) { char percentone[BARLEN + 1], percenttwo[BARLEN + 1], remain[BARLEN + 1]; unsigned int numberofmarks, numofmarkstwo, remainnum; numberofmarks=(int) ((float) (BARLEN * (percent / 100))); if (!usefull) { numofmarkstwo = (int) ((float) (BARLEN * (secondper / 100))); } else { numofmarkstwo = (BARLEN - numberofmarks); } remainnum = BARLEN - (numberofmarks + numofmarkstwo); memset(percentone, '#', numberofmarks); memset(percenttwo, '%', numofmarkstwo); memset(remain, '.', remainnum); percentone[numberofmarks] = 0; percenttwo[numofmarkstwo] = 0; remain[remainnum] = 0; snprintf(marks, BARLEN + HEADERLEN + 1, "%s\033[1;31m%s\033[1;37m%s", percentone, percenttwo, remain); return; } #ifndef HAVE_LIBSTATGRAB /* Extracted alot from sysinfo.c (part of the procps package?) by Michael K. Johnson */ unsigned long get_meminfo(char searchfor[12]) { FILE *fd; unsigned long value = 0, results = 0; char buffer[256]; char fieldname[12]; fd = fopen(PROC_MEMINFO, "r"); if (fd == NULL) { return(0); } while (!feof(fd)) { fgets(buffer, sizeof(buffer), fd); sscanf(buffer,"%11s%lu",fieldname,&value); if (strcmp(fieldname, searchfor) == 0) { results+=(value*1024); } } fclose(fd); return(results); } int get_all_meminfo(struct freecolor_meminfo *retval) { struct sysinfo sinfo; unsigned long meminfo_cached; meminfo_cached = get_meminfo("Cached:"); sysinfo(&sinfo); retval->totalram = sinfo.totalram; retval->freeram = sinfo.freeram; retval->sharedram = sinfo.sharedram; retval->bufferram = sinfo.bufferram; retval->totalswap = sinfo.totalswap; retval->freeswap = sinfo.freeswap; retval->cachedram = meminfo_cached; return(0); } #else int get_all_meminfo(struct freecolor_meminfo *retval) { static int init_called = 0; sg_mem_stats *mem_stats; sg_swap_stats *swap_stats; if (init_called == 0) { init_called = 1; sg_init(); #ifdef HAVE_STATGRAB_DROP_PRIVILEGES /* Drop setuid/setgid privileges. */ if (sg_drop_privileges() != 0) { perror("Error. Failed to drop privileges"); return(-1); } #endif } mem_stats = sg_get_mem_stats(); swap_stats = sg_get_swap_stats(); if (mem_stats == NULL || swap_stats == NULL) { return(-1); } retval->totalram = mem_stats->total; retval->freeram = mem_stats->free; retval->cachedram = mem_stats->cache; retval->sharedram = 0; retval->bufferram = 0; retval->totalswap = swap_stats->total; retval->freeswap = swap_stats->free; return(0); } #endif int main(int argc, char **argv) { struct freecolor_meminfo sinfo; unsigned long cachedbuffer, divisor; float percentram, percentswap, percentbuffer, percentused, percentfree; float ramfree, ramtotal, swapfree, swaptotal, doloop, totaltotal; char realbarchart[BARLEN +HEADERLEN + 1], swapbarchart[BARLEN + HEADERLEN + 1], totalbarchart[BARLEN + HEADERLEN + 1]; int i, dototals, doold, linestoup; int gam_ret; /* Set defaults */ divisor = 1024; doold = 0; linestoup = 2; dototals = 0; doloop = 0; /* Get arguments */ #ifdef NO_GETOPT for (i=1;i (i+1)) { doloop=atof(argv[i+1]); i++; } break; #else while ((i=getopt(argc, argv, "obkmVs:t")) != -1) { switch(i) { case 's' : doloop=atof(optarg); break; #endif /* NO_GETOPT */ case 'b' : divisor=1; break; case 'k' : divisor=1024; break; case 'm' : divisor=1048576; break; case 'V' : printf("freecolor version %s\n", VERSION); return(0); case 't' : dototals=1; linestoup++; break; case 'o' : doold=1; linestoup++; break; case '?' : printf("usage: %s [-b|-k|-m] [-o] [-t] [-s delay] [-V]\n",argv[0]); return(1); default : printf("%s: illegal option -- %c\n",argv[0],argv[i][1]); printf("usage: %s [-b|-k|-m] [-t] [-s delay] [-V]\n",argv[0]); return(1); } } /* Display information */ while(1) { gam_ret = get_all_meminfo(&sinfo); if (gam_ret < 0) { fprintf(stderr, "Error getting memory information.\n"); return(1); } ramtotal = sinfo.totalram; ramfree = sinfo.freeram; swapfree = sinfo.freeswap; swaptotal = sinfo.totalswap; totaltotal = sinfo.totalram + sinfo.totalswap; cachedbuffer = sinfo.bufferram + sinfo.cachedram; percentram = (float) ((ramfree / ramtotal) * 100); percentbuffer = (float) ((cachedbuffer / ramtotal) * 100); percentfree = (float) (((sinfo.freeram + sinfo.freeswap + cachedbuffer) / totaltotal) * 100); percentused = (int) (100 - ((int) percentfree)); if (swaptotal!=0) { percentswap = (float) (( swapfree / swaptotal) * 100); } else { percentswap = 0; } bargraph(percentswap, 0, swapbarchart, 0); bargraph(percentram, percentbuffer, realbarchart, 0); bargraph((int) percentfree,(int) percentused, totalbarchart,1); if (!doold) { printf("Physical : \033[1;30m[\033[1;32m%s\033[1;30m]\033[1;37m %i\033[0;31m%%\033[0m\t(%lu/%lu)\n", realbarchart, (int) (percentram + percentbuffer), (unsigned long) (ramfree + cachedbuffer) / divisor, (unsigned long) ramtotal/divisor ); printf("Swap : \033[1;30m[\033[1;32m%s\033[1;30m]\033[1;37m %i\033[0;31m%%\033[0m\t(%lu/%lu)\n", swapbarchart, (int) percentswap, (unsigned long) swapfree / divisor, (unsigned long) swaptotal/divisor ); if (dototals) { printf("Total : \033[1;30m[\033[1;32m%s\033[1;30m]\033[1;37m \033[0m(%lu=%lu+%lu)\n", totalbarchart, (unsigned long) (sinfo.totalram + sinfo.totalswap) / divisor, (unsigned long) ((sinfo.freeram + sinfo.freeswap) / divisor), (unsigned long) ((totaltotal - ((sinfo.freeram + sinfo.freeswap + cachedbuffer))) / divisor) ); } } else { printf(" total used free shared buffers cached\n"); printf("Mem: %12lu %10lu %10lu %10lu %10lu %10lu\n", (unsigned long) (sinfo.totalram / divisor), (unsigned long) ((sinfo.totalram - sinfo.freeram) / divisor), (unsigned long) (sinfo.freeram / divisor), (unsigned long) (sinfo.sharedram / divisor), (unsigned long) (sinfo.bufferram / divisor), (unsigned long) (cachedbuffer / divisor) ); printf("Swap: %12lu %10lu %10lu\n", (unsigned long) (sinfo.totalswap / divisor), (unsigned long) ((sinfo.totalswap - sinfo.freeswap) / divisor), (unsigned long) (sinfo.freeswap / divisor) ); if (dototals) { printf("Total: %11lu = (%8lu (used) + %8lu (free))\n", (unsigned long) (totaltotal / divisor), (((long) totaltotal) - ((sinfo.freeram+sinfo.freeswap))) / divisor, (sinfo.freeram+sinfo.freeswap+((unsigned long) cachedbuffer)) / divisor ); } } if (doloop==0) { break; } usleep(doloop*1000000); printf("\033[%iA",linestoup); } return(0); }