reimplement mutt_gecos_name.
[apps/madmutt.git] / lib-sys / unix.c
diff --git a/lib-sys/unix.c b/lib-sys/unix.c
new file mode 100644 (file)
index 0000000..372ff06
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright notice from original mutt:
+ * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
+ * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org>
+ *
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
+
+#include <stdlib.h>
+
+#include <lib-lib/macros.h>
+#include <lib-lib/mem.h>
+#include <lib-lib/str.h>
+
+#include "unix.h"
+
+/* Extract the real name from /etc/passwd's GECOS field.
+ * When set, honor the regular expression in rx,
+ * otherwise assume that the GECOS field is a comma-separated list.
+ * Replace "&" by a capitalized version of the user's login name.
+ */
+ssize_t mutt_gecos_name(char *dst, ssize_t n, struct passwd *pw, rx_t *rx)
+{
+    const char *p, *end;
+    ssize_t len;
+
+    *dst = '\0';
+    len  = 0;
+
+    if (!pw->pw_gecos)
+        return 0;
+
+    if (rx) {
+        regmatch_t pat_match[1];
+
+        if (regexec(rx->rx, pw->pw_gecos, 1, pat_match, 0)) {
+            return 0;
+        }
+
+        p   = pw->pw_gecos + pat_match[0].rm_so;
+        end = pw->pw_gecos + pat_match[0].rm_so;
+    } else {
+        p   = pw->pw_gecos;
+        end = m_strchrnul(pw->pw_gecos, ',');
+    }
+
+    for (;;) {
+        const char *q = MIN(end, m_strchrnul(p, '&'));
+
+        len += m_strncpy(dst + len, n - len, p, q - p);
+        p = q + 1;
+
+        if (!p[-1] || p >= end)
+            break;
+
+        /* p[0] == '&' */
+        len += m_strcpy(dst + len, n - len, pw->pw_name);
+    }
+
+    return len;
+}