1 /*
2 * Copyright (c) 2020 Proofpoint, Inc. and its suppliers.
3 * All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11 #include <sm/gen.h>
12
13 #if _FFR_DMTRIGGER && _FFR_NOTIFY < 2
14 #include <sm/conf.h> /* FDSET_CAST */
15 #include <sm/fdset.h>
16 #include <sm/assert.h>
17 #include <sm/notify.h>
18 #include "notify.h"
19 #include <sm/time.h>
20 #include <sm/string.h>
21
22 #include <sys/types.h>
23 #include <signal.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <stdbool.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <string.h> /* for memset() */
31
32 static int Notifypipe[2];
33 #define NotifyRDpipe Notifypipe[0]
34 #define NotifyWRpipe Notifypipe[1]
35
36 #define CLOSEFD(fd) do { \
37 if ((fd) != -1) { \
38 (void) close(fd); \
39 fd = - 1; \
40 } \
41 } while (0) \
42
43
44 /*
45 ** SM_NOTIFY_INIT -- initialize notify system
46 **
47 ** Parameters:
48 ** flags -- ignored
49 **
50 ** Returns:
51 ** 0: success
52 ** <0: -errno
53 */
54
55 int
sm_notify_init(flags)56 sm_notify_init(flags)
57 int flags;
58 {
59 if (pipe(Notifypipe) < 0)
60 return -errno;
61 return 0;
62 }
63
64 /*
65 ** SM_NOTIFY_START -- start notify system
66 **
67 ** Parameters:
68 ** owner -- owner.
69 ** flags -- currently ignored.
70 **
71 ** Returns:
72 ** 0: success
73 ** <0: -errno
74 */
75
76 int
sm_notify_start(owner,flags)77 sm_notify_start(owner, flags)
78 bool owner;
79 int flags;
80 {
81 int r;
82
83 r = 0;
84 if (owner)
85 CLOSEFD(NotifyWRpipe);
86 else
87 CLOSEFD(NotifyRDpipe);
88 return r;
89 }
90
91 /*
92 ** SM_NOTIFY_STOP -- stop notify system
93 **
94 ** Parameters:
95 ** owner -- owner.
96 ** flags -- currently ignored.
97 **
98 ** Returns:
99 ** 0: success
100 ** <0: -errno
101 */
102
103 int
sm_notify_stop(owner,flags)104 sm_notify_stop(owner, flags)
105 bool owner;
106 int flags;
107 {
108 if (owner)
109 CLOSEFD(NotifyRDpipe);
110 else
111 CLOSEFD(NotifyWRpipe);
112 return 0;
113 }
114
115 /*
116 ** SM_NOTIFY_SND -- send notification
117 **
118 ** Parameters:
119 ** buf -- where to write data
120 ** buflen -- len of buffer
121 **
122 ** Returns:
123 ** 0: success
124 ** <0: -errno
125 */
126
127 int
sm_notify_snd(buf,buflen)128 sm_notify_snd(buf, buflen)
129 char *buf;
130 size_t buflen;
131 {
132 int r;
133 int save_errno;
134 size_t len;
135 char netstr[MAX_NETSTR];
136
137 SM_REQUIRE(buf != NULL);
138 SM_REQUIRE(buflen > 0);
139 if (NotifyWRpipe < 0)
140 return -EINVAL;
141 if (buflen >= MAX_NETSTR - 7)
142 return -E2BIG; /* XXX "TOO LARGE"? */
143
144 len = sm_snprintf(netstr, sizeof(netstr), "%04d:%s,", (int)buflen, buf);
145 r = write(NotifyWRpipe, netstr, len);
146 save_errno = errno;
147 SM_DBG((stderr, "pid=%ld, write=%d, fd=%d, e=%d\n", (long)getpid(), r, NotifyWRpipe, save_errno));
148 return r >= 0 ? 0 : -save_errno;
149 }
150
151 /*
152 ** SM_NOTIFY_RCV -- receive notification
153 **
154 ** Parameters:
155 ** buf -- where to write data
156 ** buflen -- len of buffer
157 ** tmo -- timeout (micro seconds)
158 **
159 ** Returns:
160 ** 0: EOF (XXX need to provide info about client)
161 ** >0: length of received data
162 ** <0: -errno
163 */
164
165 int
sm_notify_rcv(buf,buflen,tmo)166 sm_notify_rcv(buf, buflen, tmo)
167 char *buf;
168 size_t buflen;
169 long tmo;
170 {
171 int r, len;
172 int save_errno;
173 fd_set readfds;
174 struct timeval timeout, *tval;
175
176 SM_REQUIRE(buf != NULL);
177 SM_REQUIRE(buflen > NETSTRPRE + 2);
178 if (NotifyRDpipe < 0)
179 return -EINVAL;
180 FD_ZERO(&readfds);
181 SM_FD_SET(NotifyRDpipe, &readfds);
182 SM_MICROS2TVAL(tmo, tval, timeout);
183
184 do {
185 r = select(NotifyRDpipe + 1, FDSET_CAST &readfds, NULL, NULL, tval);
186 save_errno = errno;
187 SM_DBG((stderr, "pid=%ld, select=%d, fd=%d, e=%d\n", (long)getpid(), r, NotifyRDpipe, save_errno));
188 } while (r < 0 && save_errno == EINTR);
189
190 RDNETSTR(r, NotifyRDpipe, (void)0);
191 }
192 #endif /* _FFR_DMTRIGGER && _FFR_NOTIFY < 2 */
193