I noticed that barM.c obtained from here
dwm.suckless.org/dwmstatus/barM.c was using fixed buffers without
concern for the length of said buffer creating the possibility of a
buffer overflow.

I have also declared global variables and functions static because
there is only one file. This may lead to slightly better generated
code.

I have also made the program loop in order to eliminate the bash loop.
There is no advantage to looping in bash.

Finally I have made slight improvements to some of the comments.
--- barM.c
+++ barM.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014,2015 levi0x0
+ * Copyright (C) 2014,2015 levi0x0 with enhancements by ProgrammerNerd
  * 
  * barM (bar_monitor or BarMonitor) is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -10,7 +10,7 @@
  *
  *  Read main() to configure your new status Bar.
  *
- *  compile: gcc -o barM barM.c -lX11
+ *  compile: gcc -o barM barM.c -O2 -s -lX11
  *  
  *  mv barM /usr/local/bin/
  */
@@ -25,36 +25,23 @@
 /*
  *  Put this in your .xinitrc file: 
  *
- *      while true;do 
- *              $(barM)
- *      done &
+ *  barM&
  *  
  */
 
-#define VERSION "0.11"
+#define VERSION "0.12"
 #define TIME_FORMAT "(%H:%M) (%d-%m-%Y)"
 #define MAXSTR  1024
 
-static char status[MAXSTR];
 
-/*append here your commands*/
-char *commands[] = {"uname",
+/*Append here your commands.*/
+static const char *const commands[] = {"uname",
                     "free -mh | awk 'NR==2{print $3\"/\"$2}'"
 };
 
-/* will append the buffer to status*/
-void sprint(char *format, ...) {
-        va_list li;
-        static char s[MAXSTR];
-        va_start(li, format);
-        vsprintf(s, format, li);
-        va_end(li);
 
-        strcat(status, s);
-}
-
-/* returen the date*/
-char * date(void) {
+/* Returns the date*/
+static char * date(void) {
         static char date[MAXSTR];
 
         time_t now = time(0);
@@ -64,8 +51,10 @@
 }
 
 
-/* open a pipe for a new coomand and return the output*/
-char * spawn(char *c) {
+/* Opens a pipe for a new command and return the output.*/
+#define xstr(s) str(s)
+#define str(s) #s
+static char * spawn(const char *c) {
         FILE *proc;
         static char buffer[MAXSTR];
 
@@ -74,14 +63,14 @@
                 exit(1);;
         }
 
-        fscanf(proc, "%[^\n]", buffer);
+        fscanf(proc, "%"xstr(MAXSTR)"[^\n]", buffer);
         pclose(proc);
 
         return buffer;
 }
 
 
-void XSetRoot(char *name) {
+static void XSetRoot(const char *name) {
         Display *display;
 
         if (( display = XOpenDisplay(0x0)) == NULL ) {
@@ -95,17 +84,23 @@
         XCloseDisplay(display);
 }
 
-int main(int argc, char **argv) { 
-        int i = 0;
-        for(i = 0; commands[i]; i++ ) {
-                sprint("(%s) ", spawn(commands[i]));
+int main(int argc, char **argv) {
+        char status[MAXSTR];
+        for(;;){
+                int left=sizeof(status),i;
+                char*sta=status;
+                for(i = 0; i<sizeof(commands)/sizeof(commands[0]); ++i ) {
+                        int ret=snprintf(sta,left,"(%s) ", spawn(commands[i]));
+                        sta+=ret;
+                        left-=ret;
+                        if(sta>=(status+MAXSTR))/*When snprintf has to resort to truncating a string it will return the length as if it were not truncated.*/
+                                goto skipDate;
+                }
+                strncpy(sta,date(),left);
+skipDate:
+                status[MAXSTR-1]=0;
+                XSetRoot(status);
+                sleep(1);
         }
-
-        sprint("%s", date());
-        XSetRoot(status);
-
-        /* sleep by default you dont need to add it to your bash*/
-        sleep(1);
-
         return 0;
 }

Reply via email to