--- a/toys/pending/syslogd.c	2015-10-20 10:25:21.000000000 +0530
+++ b/toys/pending/syslogd.c	2015-10-20 10:42:47.000000000 +0530
@@ -1,18 +1,18 @@
 /* syslogd.c - a system logging utility.
  *
+ * Copyright 2015 Sameer Prakash Pradhan <sameer.p.pradhan@gmail.com>
  * Copyright 2013 Madhur Verma <mad.flexi@gmail.com>
- * Copyright 2013 Kyungwan Han <asura321@gmail.com>
  *
  * No Standard
 
-USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1s#<0=200m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT))
+USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1B#<0>99=0s#<0=200m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT))
 
 config SYSLOGD
   bool "syslogd"
-  default n
+  default y
   help
   usage: syslogd  [-a socket] [-O logfile] [-f config file] [-m interval]
-                  [-p socket] [-s SIZE] [-b N] [-R HOST] [-l N] [-nSLKD]
+                  [-p socket] [-s SIZE] [-b N] [-B N] [-R HOST] [-l N] [-nSLKD]
 
   System logging utility
 
@@ -27,11 +27,11 @@
   -L      Log locally and via network (default is network only if -R)"
   -s SIZE Max size (KB) before rotation (default:200KB, 0=off)
   -b N    rotated logs to keep (default:1, max=99, 0=purge)
+  -B N    Set number of logs to keep logs in memory buffer before write (default:0, max=99, 0=purge)
   -K      Log to kernel printk buffer (use dmesg to read it)
   -l N    Log only messages more urgent than prio(default:8 max:8 min:1)
   -D      Drop duplicates
 */
-
 #define FOR_syslogd
 #define SYSLOG_NAMES
 #include "toys.h"
@@ -51,17 +51,12 @@
   uint32_t facility[8];
   uint8_t level[LOG_NFACILITIES];
   int logfd;
-  struct sockaddr_in saddr;
+  struct sockaddr_storage saddr;
 };
 
 GLOBALS(
-  char *socket;
-  char *config_file;
-  char *unix_socket;
-  char *logfile;
-  long interval;
-  long rot_size;
-  long rot_count;
+  char *socket, *config_file, *unix_socket, *logfile; 
+  long interval, rot_size, buf_count, rot_count;
   char *remote_log;
   long log_prio;
 
@@ -70,6 +65,11 @@
   int sigfd[2];
 )
 
+typedef struct logbuffer_s {
+  int len;
+  char buf[1024];
+} logbuffer_t;
+
 // Lookup numerical code from name
 // Also used in logger
 int logger_lookup(int where, char *key)
@@ -85,7 +85,7 @@
 //search the given name and return its value
 static char *dec(int val, CODE *clist, char *buf)
 {
-  for (; clist->c_name; clist++) 
+  for (; clist->c_name; clist++)
     if (val == clist->c_val) return clist->c_name;
   sprintf(buf, "%u", val);
 
@@ -94,7 +94,7 @@
 
 /*
  * recurses the logfile list and resolves config
- * for evry file and updates facilty and log level bits.
+ * for every file and updates facility and log level bits.
  */
 static int resolve_config(struct logfile *file, char *config)
 {
@@ -104,7 +104,7 @@
     char *fac = tk, *lvl;
     int i = 0;
     unsigned facval = 0;
-    uint8_t set, levval, bits = 0;
+    uint8_t levval, bits = 0;
 
     tk = strchr(fac, '.');
     if (!tk) return -1;
@@ -140,8 +140,6 @@
       if (bits & 8) levval = ~levval;
     }
 
-    for (i = 0, set = levval; set; set >>= 1, i++)
-      if (set & 0x1) file->facility[i] |= ~facval;
     for (i = 0; i < LOG_NFACILITIES; facval >>= 1, i++)
       if (facval & 0x1) file->level[i] |= ~levval;
   }
@@ -237,40 +235,52 @@
 static void open_logfiles(void)
 {
   struct logfile *tfd;
+  int ret, rep;
 
   for (tfd = TT.lfiles; tfd; tfd = tfd->next) {
-    char *p, *tmpfile;
+    char *p, *tmpfile, *addr;
     long port = 514;
 
     if (*tfd->filename == '@') { // network
-      struct addrinfo *info, rp;
+      struct addrinfo *info, rp, *res = 0;
+
+      addr = tmpfile = xstrdup(tfd->filename + 1);
+      /*search for ':' in the given address.
+       Number of occurrence decide whether ipv4 or ipv6.
+       find the port number as per number of ':' */
+      for (rep=0; addr[rep]; addr[rep]==':' ? rep++ : *addr++);
+      p = ((rep == 1) ? strchr : strrchr)(tmpfile, ':');
+      if (!p) error_exit("Bad IP %s", tmpfile);
+      *p = '\0';
+      port = atolx_range(++p, 0, 65535);
 
-      tmpfile = xstrdup(tfd->filename + 1);
-      if ((p = strchr(tmpfile, ':'))) {
-        char *endptr;
-
-        *p = '\0';
-        port = strtol(++p, &endptr, 10);
-        if (*endptr || endptr == p || port < 0 || port > 65535)
-          error_exit("bad port in %s", tfd->filename);
-      }
       memset(&rp, 0, sizeof(rp));
-      rp.ai_family = AF_INET;
-      rp.ai_socktype = SOCK_DGRAM;
-      rp.ai_protocol = IPPROTO_UDP;
-
-      if (getaddrinfo(tmpfile, NULL, &rp, &info) || !info) 
-        perror_exit("BAD ADDRESS: can't find : %s ", tmpfile);
-      ((struct sockaddr_in*)info->ai_addr)->sin_port = htons(port);
-      memcpy(&tfd->saddr, info->ai_addr, info->ai_addrlen);
+      ret = getaddrinfo(tmpfile, NULL, &rp, &info);
+      if (!ret) {
+        for (res = info; res; res = res->ai_next)
+          if ((res->ai_family == AF_INET) || (res->ai_family == AF_INET6)) {
+            memcpy(&tfd->saddr, res->ai_addr, res->ai_addrlen);
+            break;
+          }
+      }
+      if (!res)
+        error_exit("BAD ADDRESS: can't find : %s ", tmpfile);
+
+      if (((struct sockaddr*)&tfd->saddr)->sa_family == AF_INET) 
+        ((struct sockaddr_in*)&tfd->saddr)->sin_port = htons(port);
+      else ((struct sockaddr_in6*)&tfd->saddr)->sin6_port = htons(port);
+
       freeaddrinfo(info);
 
-      tfd->logfd = xsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+      tfd->logfd = xsocket(((struct sockaddr*)&tfd->saddr)->sa_family,
+                             SOCK_DGRAM, IPPROTO_UDP);
       free(tmpfile);
-    } else tfd->logfd = open(tfd->filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
+    }
+    else tfd->logfd = open(tfd->filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
+
     if (tfd->logfd < 0) {
       tfd->filename = "/dev/console";
-      tfd->logfd = open(tfd->filename, O_APPEND);
+      tfd->logfd = xopen(tfd->filename, O_APPEND);
     }
   }
 }
@@ -278,7 +288,9 @@
 //write to file with rotation
 static int write_rotate(struct logfile *tf, int len)
 {
-  int size, isreg;
+  static int buf_idx = 0;
+  static logbuffer_t buffer[100];
+  int size, isreg, idx;
   struct stat statf;
   isreg = (!fstat(tf->logfd, &statf) && S_ISREG(statf.st_mode));
   size = statf.st_size;
@@ -305,7 +317,22 @@
           return -1;
         }
       }
-      ftruncate(tf->logfd, 0);
+      if (ftruncate(tf->logfd, 0)) perror_msg("can't truncate:%d", tf->filename);
+    }
+  }
+  if (TT.buf_count && (toys.optflags & FLAG_B)) {
+    if (buf_idx < TT.buf_count) {
+        memcpy(buffer[buf_idx].buf, toybuf, len);
+        buffer[buf_idx].buf[len + 1] = '\0';
+        buffer[buf_idx].len = len;
+        buf_idx++;
+        return len;
+    } else {
+      for (idx = 0; idx < TT.buf_count; idx++) {
+         if (write(tf->logfd, buffer[idx].buf, buffer[idx].len) < 0)
+             perror_msg("Cant write %s", buffer[idx].buf);
+      }
+      buf_idx = 0;
     }
   }
   return write(tf->logfd, toybuf, len);
@@ -362,9 +389,11 @@
       if (!((tf->facility[lvl] & (1 << fac)) || (tf->level[fac] & (1<<lvl)))) {
         int wlen, isNetwork = *tf->filename == '@';
         if (isNetwork)
-          wlen = sendto(tf->logfd, omsg, olen, 0, (struct sockaddr*)&tf->saddr, sizeof(tf->saddr));
+          wlen = sendto(tf->logfd, omsg, olen, 0, (struct sockaddr*)&tf->saddr,
+                        sizeof(tf->saddr));
         else wlen = write_rotate(tf, len);
-        if (wlen < 0) perror_msg("write failed file : %s ", tf->filename + isNetwork);
+        if (wlen < 0)
+          perror_msg("write failed file : %s ", tf->filename + isNetwork);
       }
     }
   }
@@ -474,7 +503,7 @@
   if (parse_config_file() == -1) goto clean_and_exit;
   open_logfiles();
   if (!(toys.optflags & FLAG_n)) {
-    daemon(0, 0);
+    if (daemon(0, 0)) error_exit("daemonize");
     //don't daemonize again if SIGHUP received.
     toys.optflags |= FLAG_n;
   }
