masqmail
view src/peopen.c @ 421:f37384470855
Changed lockdir to /var/lock/masqmail; Create lockdir and piddir on startup.
Moved the lockdir out of the spool dir. (When /var/lock is a ramdisk
we do well to have the lock files there.) Added the new configure option
--with-lockdir to change that location. Nontheless, if we run_as_user,
then lock files are always stored in the spool dir directly.
Instead of installing the lockdir and piddir at installation time, we
create them on startup time now if they are missing. This is necessary
if lockdir or piddir are a tmpfs.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Wed, 30 May 2012 09:38:38 +0200 |
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 }