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>
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.
17 #include <lib-lib/macros.h>
18 #include <lib-lib/mem.h>
19 #include <lib-lib/str.h>
20 #include <lib-lib/file.h>
23 #include "mutt_signal.h"
25 #include <imap/imap.h> /* for imap_wait_keepalive EEEEK */
27 /* Extract the real name from /etc/passwd's GECOS field.
28 * When set, honor the regular expression in rx,
29 * otherwise assume that the GECOS field is a comma-separated list.
30 * Replace "&" by a capitalized version of the user's login name.
32 ssize_t mutt_gecos_name(char *dst, ssize_t n, struct passwd *pw, regex_t *rx)
44 regmatch_t pat_match[1];
46 if (regexec(rx, pw->pw_gecos, 1, pat_match, 0)) {
50 p = pw->pw_gecos + pat_match[0].rm_so;
51 end = pw->pw_gecos + pat_match[0].rm_so;
54 end = m_strchrnul(pw->pw_gecos, ',');
58 const char *q = MIN(end, m_strchrnul(p, '&'));
60 len += m_strncpy(dst + len, n - len, p, q - p);
63 if (!p[-1] || p >= end)
67 len += m_strcpy(dst + len, n - len, pw->pw_name);
73 int _mutt_system(const char *cmd, int flags)
77 struct sigaction oldtstp;
78 struct sigaction oldcont;
82 if (m_strisempty(cmd))
85 /* must ignore SIGINT and SIGQUIT */
86 mutt_block_signals_system();
88 /* also don't want to be stopped right now */
89 if (flags & M_DETACH_PROCESS) {
91 sigaddset(&set, SIGTSTP);
92 sigprocmask(SIG_BLOCK, &set, NULL);
94 act.sa_handler = SIG_DFL;
95 /* we want to restart the waitpid() below */
97 act.sa_flags = SA_RESTART;
99 sigemptyset(&act.sa_mask);
100 sigaction(SIGTSTP, &act, &oldtstp);
101 sigaction(SIGCONT, &act, &oldcont);
108 if (flags & M_DETACH_PROCESS) {
109 /* give up controlling terminal */
116 nb_fds = getdtablesize();
117 for (fd = 0; fd < nb_fds; fd++) {
121 act.sa_handler = SIG_DFL;
122 sigaction(SIGCHLD, &act, NULL);
133 /* reset signals for the child; not really needed, but... */
134 mutt_unblock_signals_system(0);
135 act.sa_handler = SIG_DFL;
137 sigemptyset(&act.sa_mask);
138 sigaction(SIGTERM, &act, NULL);
139 sigaction(SIGTSTP, &act, NULL);
140 sigaction(SIGCONT, &act, NULL);
142 execl("/bin/sh", "sh", "-c", cmd, NULL);
143 _exit(127); /* execl error */
146 rc = imap_wait_keepalive(pid);
149 sigaction(SIGCONT, &oldcont, NULL);
150 sigaction(SIGTSTP, &oldtstp, NULL);
152 /* reset SIGINT, SIGQUIT and SIGCHLD */
153 mutt_unblock_signals_system(1);
154 if (flags & M_DETACH_PROCESS) {
155 sigprocmask (SIG_UNBLOCK, &set, NULL);
158 return (pid > 0 && WIFEXITED(rc)) ? WEXITSTATUS(rc) : -1;
161 int getdnsdomainname(char *s, ssize_t n)
166 if ((f = fopen("/etc/resolv.conf", "r")) == NULL)
169 while (fgets(tmp, sizeof(tmp), f)) {
170 const char *p = skipspaces(tmp);
172 if (m_strncmp("domain", p, 6) && m_strncmp("search", p, 6))
184 trailing_dot = q[-1] == '.';
185 if (!trailing_dot || q > p + 1) {
186 m_strncpy(s, n, p, q - trailing_dot - p);