/* 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 #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.9" extern char *optarg; extern int optind, opterr, optopt; 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]; /* Paranoia, reallly big buffer. */ char feildname[12]; if ((fd=fopen(PROC_MEMINFO, "r"))==NULL) return(0); while (!feof(fd)) { fgets(buffer, sizeof(buffer), fd); sscanf(buffer,"%11s%lu",feildname,&value); if (strcmp(feildname,searchfor)==0) results+=(value*1024); } fclose(fd); return(results); } #endif int main(int argc, char *argv[]) { float percentram, percentswap, percentbuffer, percentused, percentfree; float ramfree, ramtotal, swapfree, swaptotal, doloop=0, cachedbuffer, totaltotal; char realbarchart[BARLEN+HEADERLEN+1], swapbarchart[BARLEN+HEADERLEN+1], totalbarchart[BARLEN+HEADERLEN+1]; int i, dototals=0, doold=0, linestoup=2; unsigned long meminfo_cached, divisor=1024; #ifndef HAVE_LIBSTATGRAB struct sysinfo sinfo; meminfo_cached=get_meminfo("Cached:"); #else sg_mem_stats *mem_stats=NULL; sg_swap_stats *swap_stats=NULL; struct systeminfo_st { 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 */ } sinfo; 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 #endif #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) { if (i=='?') { printf("usage: %s [-b|-k|-m] [-o] [-t] [-s delay] [-V]\n",argv[0]); return(1); } switch(i) { case 's' : doloop=atof(optarg); break; #endif 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; #ifdef NO_GETOPT 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); } } } #else } } #endif while(1) { #ifndef HAVE_LIBSTATGRAB sysinfo(&sinfo); #else if(((mem_stats=sg_get_mem_stats()) == NULL) || (swap_stats=sg_get_swap_stats()) == NULL) { printf("Couldn't get memory information, exiting.\n"); return(-1); } meminfo_cached=mem_stats->cache; sinfo.totalram=mem_stats->total; sinfo.freeram=mem_stats->free; sinfo.sharedram=0; sinfo.bufferram=0; sinfo.totalswap=swap_stats->total; sinfo.freeswap=swap_stats->free; #endif ramtotal=sinfo.totalram; cachedbuffer=sinfo.bufferram+meminfo_cached; ramfree=sinfo.freeram; swapfree=sinfo.freeswap; swaptotal=sinfo.totalswap; totaltotal=(sinfo.totalram+sinfo.totalswap); percentram=(float) ((ramfree / ramtotal)*100); percentbuffer=(float) ((cachedbuffer/ramtotal)*100); percentfree=(float) (((sinfo.freeram+sinfo.freeswap+meminfo_cached+sinfo.bufferram)/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",(sinfo.totalram/divisor), (sinfo.totalram-sinfo.freeram)/divisor, (sinfo.freeram/divisor), (sinfo.sharedram/divisor), (sinfo.bufferram/divisor), (((unsigned long) cachedbuffer)/divisor)); printf("Swap: %12lu %10lu %10lu\n",(sinfo.totalswap/divisor), ((sinfo.totalswap-sinfo.freeswap)/divisor), (sinfo.freeswap/divisor)); if (dototals) printf("Total: %11lu = (%8lu (used) + %8lu (free))\n",(long) totaltotal/divisor,(((long) totaltotal)-((sinfo.freeram+sinfo.freeswap)))/divisor,(sinfo.freeram+sinfo.freeswap+((unsigned long) cachedbuffer))/divisor); } if (doloop==0) { return(0); } else { usleep(doloop*1000000); printf("\033[%iA",linestoup); } } return(0); }