masqmail

view src/peopen.c @ 378:5781ba87df95

Removed ident. This had been discussed on the mailing list in Oct 2011. Ident is hardly useful in typical setups for masqmail. Probably Oliver had used it in his setup; that would make sense. Now, I know of nobody who needs it.
author markus schnalke <meillo@marmaro.de>
date Sat, 14 Jan 2012 21:36:58 +0100
parents b27f66555ba8
children
line source
1 /*
2 ** This a snippet I found in sourceforge. I just changed the identing
3 ** style to my own and deleted the main function. -- oku
4 ** The functions destroy_argv() and create_argv() were added by oku.
5 */
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sysexits.h>
15 #include "peopen.h"
16 #include "masqmail.h"
18 /*
19 ** static void
20 ** destroy_argv(char **arr)
21 ** {
22 ** char *p = arr[0];
23 ** int i = 0;
24 **
25 ** while (p) {
26 ** free(p);
27 ** p = arr[i++];
28 ** }
29 ** free(arr);
30 ** }
31 */
33 static char**
34 create_argv(const char *cmd, int count)
35 {
36 char buf[strlen(cmd) + 1];
37 char **arr, *q;
38 const char *p;
39 int i = 0;
41 arr = (char **) g_malloc(sizeof(char *) * count);
43 p = cmd;
44 while (*p && i < (count - 1)) {
45 while (*p && isspace(*p))
46 p++;
47 q = buf;
48 while (*p && !isspace(*p))
49 *q++ = *p++;
50 *q = '\0';
51 arr[i++] = strdup(buf);
52 while (*p && isspace(*p))
53 p++;
54 }
55 arr[i] = NULL;
57 return arr;
58 }
60 FILE*
61 peidopen(const char *command, const char *type, char *const envp[],
62 int *ret_pid, uid_t uid, gid_t gid)
63 {
64 enum { Read, Write } mode;
65 int pipe_fd[2];
66 pid_t pid;
68 if (command == NULL || type == NULL) {
69 errno = EINVAL;
70 return NULL;
71 }
73 if (strcmp(type, "r")) {
74 if (strcmp(type, "w")) {
75 errno = EINVAL;
76 return NULL;
77 } else
78 mode = Write;
79 } else
80 mode = Read;
82 if (pipe(pipe_fd) == -1)
83 return NULL;
85 switch (pid = fork()) {
86 case 0: /* child thread */
88 {
89 int i, max_fd = sysconf(_SC_OPEN_MAX);
91 if (max_fd <= 0)
92 max_fd = 64;
93 for (i = 0; i < max_fd; i++)
94 if ((i != pipe_fd[0]) && (i != pipe_fd[1]))
95 close(i);
96 }
97 if (close(pipe_fd[mode == Read ? 0 : 1]) != -1 &&
98 dup2(pipe_fd[mode == Read ? 1 : 0],
99 mode == Read ? STDOUT_FILENO : STDIN_FILENO) != -1) {
100 /* char *argv [] = { "/bin/sh", "-c", (char*) command, NULL }; */
101 char **argv = create_argv(command, 10);
102 int ret;
104 if (uid != (uid_t) - 1) {
105 if ((ret = seteuid(0)) != 0) {
106 exit(EX_NOPERM);
107 }
108 }
109 if (gid != (gid_t) - 1) {
110 if ((ret = setgid(gid)) != 0) {
111 exit(EX_NOPERM);
112 }
113 }
114 if (uid != (uid_t) - 1) {
115 if ((ret = setuid(uid)) != 0) {
116 exit(EX_NOPERM);
117 }
118 }
119 execve(*argv, argv, envp);
120 }
122 _exit(errno);
124 default: /* parent thread */
125 *ret_pid = pid;
126 close(pipe_fd[mode == Read ? 1 : 0]);
127 return fdopen(pipe_fd[mode == Read ? 0 : 1], type);
129 case -1:
130 close(pipe_fd[0]);
131 close(pipe_fd[1]);
132 return NULL;
133 }
134 }
136 FILE*
137 peopen(const char *command, const char *type, char *const envp[], int *ret_pid)
138 {
139 return peidopen(command, type, envp, ret_pid, -1, -1);
140 }