reimplement mutt_gecos_name.
[apps/madmutt.git] / lib-sys / unix.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4  * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org>
5  *
6  * This file is part of mutt-ng, see http://www.muttng.org/.
7  * It's licensed under the GNU General Public License,
8  * please see the file GPL in the top level source directory.
9  */
10
11 #include <stdlib.h>
12
13 #include <lib-lib/macros.h>
14 #include <lib-lib/mem.h>
15 #include <lib-lib/str.h>
16
17 #include "unix.h"
18
19 /* Extract the real name from /etc/passwd's GECOS field.
20  * When set, honor the regular expression in rx,
21  * otherwise assume that the GECOS field is a comma-separated list.
22  * Replace "&" by a capitalized version of the user's login name.
23  */
24 ssize_t mutt_gecos_name(char *dst, ssize_t n, struct passwd *pw, rx_t *rx)
25 {
26     const char *p, *end;
27     ssize_t len;
28
29     *dst = '\0';
30     len  = 0;
31
32     if (!pw->pw_gecos)
33         return 0;
34
35     if (rx) {
36         regmatch_t pat_match[1];
37
38         if (regexec(rx->rx, pw->pw_gecos, 1, pat_match, 0)) {
39             return 0;
40         }
41
42         p   = pw->pw_gecos + pat_match[0].rm_so;
43         end = pw->pw_gecos + pat_match[0].rm_so;
44     } else {
45         p   = pw->pw_gecos;
46         end = m_strchrnul(pw->pw_gecos, ',');
47     }
48
49     for (;;) {
50         const char *q = MIN(end, m_strchrnul(p, '&'));
51
52         len += m_strncpy(dst + len, n - len, p, q - p);
53         p = q + 1;
54
55         if (!p[-1] || p >= end)
56             break;
57
58         /* p[0] == '&' */
59         len += m_strcpy(dst + len, n - len, pw->pw_name);
60     }
61
62     return len;
63 }