1 /* 2 A colorful `free' clone with graphs and such. 3 4 -- Roy Keene [200819992000] rkeene@suspend.net 5 6 Bug 230819992230: freecolor segfaults if swapping is off. (fixed, 7 reported by shammack@goldinc.com). 8 Warn 260919991600: Warning about returning a local variable fixed ( 9 Jakob Erikson <jakov@quicknet.se>). 10 Annoy 270819990700: Made the code for the "-o" option neater. 11 Bug 270819990700: Fixed support for unknown options 12 (Rene <renec@zorro.pangea.ca) 13 Annoy 270819990800: Fixed display of buffed and cached memmory. 14 (Rene <renec@zorro.pangea.ca) 15 Annoy 270819991030: Fixed the ugly bargraph(), now its less ugly, but 16 but still not very good. 17 Annoy 270819992100: Fixed the (less) ugly bargraph(), now it doesnt look 18 so bad. 19 Feature 161019991640: Added Total Free/Total Used to "-t" option. 20 21 */ 22 /* 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following condition 26 * is met: 27 * 1. Redistributions of source code must retain the following disclaimer, 28 * and this list of conditions. 29 * 30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 32 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 33 * JUHA PIRKOLA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 */ 42 43 44 #include <linux/kernel.h> 45 #include <sys/sysinfo.h> 46 #include <linux/sys.h> 47 #include <string.h> 48 #include <unistd.h> 49 #include <stdlib.h> 50 #include <stdio.h> 51 #ifndef NO_GETOPT 52 #include <getopt.h> 53 #endif 54 #define BARLEN 35 55 #define HEADERLEN 14 56 #define VERSION "0.7.1" 57 #ifndef PROC_MEMINFO 58 #define PROC_MEMINFO "/proc/meminfo" 59 #endif 60 61 extern char *optarg; 62 extern int optind, opterr, optopt; 63 64 void bargraph(float percent, float secondper, char marks[BARLEN+HEADERLEN],int usefull) { 65 char percentone[BARLEN], percenttwo[BARLEN], remain[BARLEN]; 66 unsigned int numberofmarks, numofmarkstwo, remainnum; 67 numberofmarks=(int) ((float) (BARLEN*(percent/100))); 68 if (!usefull) numofmarkstwo=(int) ((float) (BARLEN*(secondper/100))); else numofmarkstwo=(BARLEN-numberofmarks); 69 remainnum=BARLEN-(numberofmarks+numofmarkstwo); 70 memset(percentone, '#', numberofmarks); 71 memset(percenttwo, '%', numofmarkstwo); 72 memset(remain, '.', remainnum); 73 percentone[numberofmarks]=0; 74 percenttwo[numofmarkstwo]=0; 75 remain[remainnum]=0; 76 sprintf(marks,"%s\033[1;31m%s\033[1;37m%s",percentone, percenttwo, remain); 77 return; 78 } 79 80 /* 81 Extracted alot from sysinfo.c (part of the procps package?) by 82 Michael K. Johnson <johnsonm@redhat.com> 83 */ 84 unsigned long get_meminfo(char searchfor[12]) { 85 FILE *fd; 86 unsigned long value=0, results=0; 87 char buffer[256]; /* Paranoia, reallly big buffer. */ 88 char feildname[12]; 89 if ((fd=fopen(PROC_MEMINFO, "r"))==NULL) return(0); 90 while (!feof(fd)) { 91 fgets(buffer, sizeof(buffer), fd); 92 sscanf(buffer,"%11s%lu",feildname,&value); 93 if (strcmp(feildname,searchfor)==0) results+=(value*1024); 94 } 95 fclose(fd); 96 return(results); 97 } 98 99 int main(int argc, char *argv[]) { 100 float percentram, percentswap, percentbuffer, percentused, percentfree; 101 float ramfree, ramtotal, swapfree, swaptotal, doloop=0, cachedbuffer, totaltotal; 102 struct sysinfo sinfo; 103 char realbarchart[BARLEN+HEADERLEN], swapbarchart[BARLEN+HEADERLEN], totalbarchart[BARLEN+HEADERLEN]; 104 int i, divisor=1024, dototals=0, doold=0, linestoup=2; 105 #ifdef NO_GETOPT 106 for (i=1;i<argc;i++) { 107 if (argv[i][0]=='-') { 108 switch(argv[i][1]) { 109 case 's' : 110 if (argc>(i+1)) { doloop=atof(argv[i+1]); i++; } 111 break; 112 #else 113 while ((i=getopt(argc, argv, "obkmVs:t")) != -1) { 114 if (i=='?') { printf("usage: %s [-b|-k|-m] [-o] [-t] [-s delay] [-V]\n",argv[0]); return(1); } 115 switch(i) { 116 case 's' : 117 doloop=atof(optarg); 118 break; 119 #endif 120 case 'b' : divisor=1; break; 121 case 'k' : divisor=1024; break; 122 case 'm' : divisor=1048576; break; 123 case 'V' : printf("freecolor version %s\n", VERSION); return(0); 124 case 't' : dototals=1; linestoup++; break; 125 case 'o' : doold=1; linestoup++; break; 126 #ifdef NO_GETOPT 127 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); 128 } 129 } 130 } 131 #else 132 } 133 } 134 #endif 135 while(1) { 136 sysinfo(&sinfo); 137 ramtotal=sinfo.totalram; 138 cachedbuffer=sinfo.bufferram+get_meminfo("Cached:"); 139 ramfree=sinfo.freeram; 140 swapfree=sinfo.freeswap; 141 swaptotal=sinfo.totalswap; 142 totaltotal=(sinfo.totalram+sinfo.totalswap); 143 percentram=(float) ((ramfree / ramtotal)*100); 144 percentbuffer=(float) ((cachedbuffer/ramtotal)*100); 145 percentfree=(float) (((sinfo.freeram+sinfo.freeswap+get_meminfo("Cached:")+sinfo.bufferram)/totaltotal)*100); 146 percentused=(int) (100-((int) percentfree)); 147 if (!(swaptotal==0)) { percentswap=(float) ((swapfree/swaptotal)*100); } else { percentswap=0; } 148 bargraph(percentswap,0,swapbarchart,0); 149 bargraph(percentram,percentbuffer,realbarchart,0); 150 bargraph((int) percentfree,(int) percentused,totalbarchart,1); 151 if (!doold) { 152 printf("Physical : \033[1;30m[\033[1;32m%s\033[1;30m]\033[1;37m %i\033[0;31m%%\033[0m\t(%i/%i)\n", realbarchart ,(int) (percentram+percentbuffer), (int) (ramfree+cachedbuffer)/divisor, (int) ramtotal/divisor); 153 printf("Swap : \033[1;30m[\033[1;32m%s\033[1;30m]\033[1;37m %i\033[0;31m%%\033[0m\t(%i/%i)\n",swapbarchart ,(int) percentswap,(int) swapfree/divisor, (int) swaptotal/divisor); 154 if (dototals) 155 printf("Total : \033[1;30m[\033[1;32m%s\033[1;30m]\033[1;37m \033[0m(%i=%i+%i)\n", totalbarchart, (int) (sinfo.totalram+sinfo.totalswap)/divisor,(int) ((sinfo.freeram+sinfo.freeswap)/divisor), (int) ((totaltotal-((sinfo.freeram+sinfo.freeswap+cachedbuffer)))/divisor)); 156 } else { 157 printf(" total used free shared buffers cached\n"); 158 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)); 159 printf("Swap: %12lu %10lu %10lu\n",(sinfo.totalswap/divisor), ((sinfo.totalswap-sinfo.freeswap)/divisor), (sinfo.freeswap/divisor)); 160 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); 161 } 162 if (doloop==0) { return(0); } else { usleep(doloop*1000000); printf("\033[%iA",linestoup); } 163 } 164 return(0); 165 } |