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.
11 #include <lib-lib/lib-lib.h>
14 #include "mutt_signal.h"
16 #include <imap/imap.h> /* for imap_wait_keepalive EEEEK */
18 /* Extract the real name from /etc/passwd's GECOS field.
19 * When set, honor the regular expression in rx,
20 * otherwise assume that the GECOS field is a comma-separated list.
21 * Replace "&" by a capitalized version of the user's login name.
23 ssize_t mutt_gecos_name(char *dst, ssize_t n, struct passwd *pw, rx_t *rx)
35 regmatch_t pat_match[1];
37 if (regexec(rx->rx, pw->pw_gecos, 1, pat_match, 0)) {
41 p = pw->pw_gecos + pat_match[0].rm_so;
42 end = pw->pw_gecos + pat_match[0].rm_eo;
45 end = m_strchrnul(pw->pw_gecos, ',');
49 const char *q = m_strchrnul(p, '&');
51 len += m_strncpy(dst + len, n - len, p, MIN(end, q) - p);
54 if (!p[-1] || p >= end)
58 len += m_strcpy(dst + len, n - len, pw->pw_name);
64 int _mutt_system(const char *cmd, int flags)
68 struct sigaction oldtstp;
69 struct sigaction oldcont;
73 if (m_strisempty(cmd))
76 /* must ignore SIGINT and SIGQUIT */
77 mutt_block_signals_system();
79 /* also don't want to be stopped right now */
80 if (flags & M_DETACH_PROCESS) {
82 sigaddset(&set, SIGTSTP);
83 sigprocmask(SIG_BLOCK, &set, NULL);
85 act.sa_handler = SIG_DFL;
86 /* we want to restart the waitpid() below */
88 act.sa_flags = SA_RESTART;
90 sigemptyset(&act.sa_mask);
91 sigaction(SIGTSTP, &act, &oldtstp);
92 sigaction(SIGCONT, &act, &oldcont);
99 if (flags & M_DETACH_PROCESS) {
100 /* give up controlling terminal */
107 nb_fds = getdtablesize();
108 for (fd = 0; fd < nb_fds; fd++) {
112 act.sa_handler = SIG_DFL;
113 sigaction(SIGCHLD, &act, NULL);
124 /* reset signals for the child; not really needed, but... */
125 mutt_unblock_signals_system(0);
126 act.sa_handler = SIG_DFL;
128 sigemptyset(&act.sa_mask);
129 sigaction(SIGTERM, &act, NULL);
130 sigaction(SIGTSTP, &act, NULL);
131 sigaction(SIGCONT, &act, NULL);
133 execl("/bin/sh", "sh", "-c", cmd, NULL);
134 _exit(127); /* execl error */
137 rc = imap_wait_keepalive(pid);
140 sigaction(SIGCONT, &oldcont, NULL);
141 sigaction(SIGTSTP, &oldtstp, NULL);
143 /* reset SIGINT, SIGQUIT and SIGCHLD */
144 mutt_unblock_signals_system(1);
145 if (flags & M_DETACH_PROCESS) {
146 sigprocmask (SIG_UNBLOCK, &set, NULL);
149 return (pid > 0 && WIFEXITED(rc)) ? WEXITSTATUS(rc) : -1;
152 int getdnsdomainname(char *s, ssize_t n)
157 if ((f = fopen("/etc/resolv.conf", "r")) == NULL)
160 while (fgets(tmp, sizeof(tmp), f)) {
161 const char *p = skipspaces(tmp);
163 if (m_strncmp("domain", p, 6) && m_strncmp("search", p, 6))
175 trailing_dot = q[-1] == '.';
176 if (!trailing_dot || q > p + 1) {
177 m_strncpy(s, n, p, q - trailing_dot - p);