Hi,

the proposal in

  https://marc.info/?l=openbsd-misc&m=150001966325010&w=2

made me look at newsyslog and its manually linked lists.  Here's a stab
at using TAILQs instead.

Notes:
- no attempt is made to free unused entries.
- "free(p)" below isn't enough to properly deallocate the memory used by
  an entry anyway.
- when parsing the config file, we only add an entry to the list once we
  know it is "good".

I find this more readable.  ok?


Index: newsyslog.c
===================================================================
RCS file: /d/cvs/src/usr.bin/newsyslog/newsyslog.c,v
retrieving revision 1.102
diff -u -p -r1.102 newsyslog.c
--- newsyslog.c 16 Mar 2017 10:32:01 -0000      1.102
+++ newsyslog.c 14 Jul 2017 20:14:42 -0000
@@ -79,6 +79,7 @@
 #define SENDMAIL "/usr/sbin/sendmail"
 
 #include <sys/param.h> /* DEV_BSIZE */
+#include <sys/queue.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/wait.h>
@@ -126,8 +127,9 @@ struct conf_entry {
        char    *whom;          /* Whom to notify if logfile changes */
        char    *pidfile;       /* Path to file containing pid to signal */
        char    *runcmd;        /* Command to run instead of sending a signal */
-       struct conf_entry *next; /* Linked list pointer */
+       TAILQ_ENTRY(conf_entry) next;
 };
+TAILQ_HEAD(entrylist, conf_entry);
 
 struct pidinfo {
        char    *file;
@@ -158,8 +160,7 @@ int movefile(char *, char *, uid_t, gid_
 int    stat_suffix(char *, size_t, char *, struct stat *,
            int (*)(const char *, struct stat *));
 off_t  sizefile(struct stat *);
-struct conf_entry *
-       parse_file(int *);
+void   parse_file(struct entrylist *, int *);
 time_t parse8601(char *);
 time_t parseDWM(char *);
 void   child_killer(int);
@@ -175,7 +176,8 @@ void        usage(void);
 int
 main(int argc, char **argv)
 {
-       struct conf_entry *p, *q, *x, *y;
+       struct entrylist config, runlist;
+       struct conf_entry *p, *q, *tmp;
        struct pidinfo *pidlist, *pl;
        int status, listlen;
        char **av;
@@ -187,30 +189,28 @@ main(int argc, char **argv)
        if (needroot && getuid() && geteuid())
                errx(1, "You must be root.");
 
-       p = parse_file(&listlen);
-       if (argc > 0) {
+       TAILQ_INIT(&config);
+       TAILQ_INIT(&runlist);
+
+       parse_file(&config, &listlen);
+       if (argc == 0)
+               TAILQ_CONCAT(&runlist, &config, next);
+       else {
                /* Only rotate specified files. */
-               x = y = NULL;
                listlen = 0;
                for (av = argv; *av; av++) {
-                       for (q = p; q; q = q->next)
+                       TAILQ_FOREACH_SAFE(q, &config, next, tmp)
                                if (strcmp(*av, q->log) == 0) {
-                                       if (x == NULL)
-                                               x = y = q;
-                                       else {
-                                               y->next = q;
-                                               y = q;
-                                       }
+                                       TAILQ_REMOVE(&config, q, next);
+                                       TAILQ_INSERT_TAIL(&runlist, q, next);
                                        listlen++;
                                        break;
                                }
                        if (q == NULL)
                                warnx("%s: %s not found", conf, *av);
                }
-               if (x == NULL)
+               if (TAILQ_EMPTY(&runlist))
                        errx(1, "%s: no specified log files", conf);
-               y->next = NULL;
-               p = x;
        }
 
        pidlist = calloc(listlen + 1, sizeof(struct pidinfo));
@@ -220,11 +220,12 @@ main(int argc, char **argv)
        signal(SIGCHLD, child_killer);
 
        /* Step 1, rotate all log files */
-       for (q = p; q; q = q->next)
+       TAILQ_FOREACH(q, &runlist, next)
                do_entry(q);
 
        /* Step 2, make a list of unique pid files */
-       for (q = p, pl = pidlist; q; ) {
+       pl = pidlist;
+       TAILQ_FOREACH(q, &runlist, next) {
                if (q->flags & CE_ROTATED) {
                        struct pidinfo *pltmp;
 
@@ -247,7 +248,6 @@ main(int argc, char **argv)
                                pl++;
                        }
                }
-               q = q->next;
        }
 
        /* Step 3, send a signal or run a command */
@@ -263,13 +263,11 @@ main(int argc, char **argv)
                sleep(5);
 
        /* Step 4, compress the log.0 file if configured to do so and free */
-       while (p) {
+       TAILQ_FOREACH_SAFE(p, &runlist, next, tmp) {
                if ((p->flags & CE_COMPACT) && (p->flags & CE_ROTATED) &&
                    p->numlogs > 0)
                        compress_log(p);
-               q = p;
-               p = p->next;
-               free(q);
+               free(p);
        }
 
        /* Wait for children to finish, then exit */
@@ -464,14 +462,14 @@ usage(void)
 }
 
 /*
- * Parse a configuration file and return a linked list of all the logs
+ * Parse a configuration file and build a linked list of all the logs
  * to process
  */
-struct conf_entry *
-parse_file(int *nentries)
+void
+parse_file(struct entrylist *list, int *nentries)
 {
        char line[BUFSIZ], *parse, *q, *errline, *group, *tmp, *ep;
-       struct conf_entry *working = NULL, *first = NULL;
+       struct conf_entry *working;
        struct passwd *pwd;
        struct group *grp;
        struct stat sb;
@@ -492,18 +490,9 @@ parse_file(int *nentries)
                errline = strdup(tmp);
                if (errline == NULL)
                        err(1, "strdup");
-               (*nentries)++;
-               if (!first) {
-                       working = malloc(sizeof(struct conf_entry));
-                       if (working == NULL)
-                               err(1, "malloc");
-                       first = working;
-               } else {
-                       working->next = malloc(sizeof(struct conf_entry));
-                       if (working->next == NULL)
-                               err(1, "malloc");
-                       working = working->next;
-               }
+               working = calloc(1, sizeof(*working));
+               if (working == NULL)
+                       err(1, "calloc");
 
                q = parse = missing_field(sob(line), errline, lineno);
                *(parse = son(line)) = '\0';
@@ -722,11 +711,10 @@ parse_file(int *nentries)
                                errx(1, "%s:%d: pathname too long: %s",
                                    conf, lineno, working->log);
                }
+               TAILQ_INSERT_TAIL(list, working, next);
+               (*nentries)++;
        }
-       if (working)
-               working->next = NULL;
        (void)fclose(f);
-       return (first);
 }
 
 char *


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to