xref: /freebsd/contrib/sendmail/libsm/notify.h (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1 /*
2  * Copyright (c) 2021 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 #ifndef LIBSM_NOTIFY_H
11 #define LIBSM_NOTIFY_H
12 
13 #if SM_NOTIFY_DEBUG
14 #define SM_DBG(p)	fprintf p
15 #else
16 #define SM_DBG(p)
17 #endif
18 
19 /* microseconds */
20 #define SM_MICROS 1000000L
21 
22 #define SM_MICROS2TVAL(tmo, tval, timeout) \
23 	do	\
24 	{	\
25 		if (tmo < 0)	\
26 			tval = NULL;	\
27 		else	\
28 		{	\
29 			timeout.tv_sec = (long) (tmo / SM_MICROS);	\
30 			timeout.tv_usec = tmo % SM_MICROS;	\
31 			tval = &timeout;	\
32 		}	\
33 	} while (0)
34 
35 #define MAX_NETSTR 1024
36 #define NETSTRPRE 5
37 
38 /* flow through code, be careful how to use! */
39 #define RDNETSTR(rc, fd, SM_NOTIFY_EOF)	\
40 	if ((rc) <= 0)	\
41 	{	\
42 		SM_DBG((stderr, "pid=%ld, select=%d, e=%d\n", (long)getpid(), (rc), save_errno)); \
43 		return -ETIMEDOUT;	\
44 	}	\
45 	\
46 	/* bogus... need to check again? */	\
47 	if (!FD_ISSET(fd, &readfds))	\
48 	{	\
49 		SM_DBG((stderr, "pid=%ld, fd=%d, isset=false\n", (long)getpid(), fd)); \
50 		return -ETIMEDOUT;	\
51 	}	\
52 	r = read(fd, buf, NETSTRPRE);	\
53 	if (0 == r)	\
54 	{	\
55 		SM_DBG((stderr, "pid=%ld, fd=%d, read1=EOF, e=%d\n", (long)getpid(), fd, errno));	\
56 		SM_NOTIFY_EOF;	\
57 		return r;	\
58 	}	\
59 	if (NETSTRPRE != r)	\
60 	{	\
61 		SM_DBG((stderr, "pid=%ld, fd=%d, read1=%d, e=%d\n", (long)getpid(), fd, r, errno));	\
62 		return -1;	/* ??? */	\
63 	}	\
64 	\
65 	if (sm_io_sscanf(buf, "%4u:", &len) != 1)	\
66 	{	\
67 		SM_DBG((stderr, "pid=%ld, scanf, e=%d\n", (long)getpid(), errno));	\
68 		return -EINVAL;	/* ??? */	\
69 	}	\
70 	if (len >= MAX_NETSTR)	\
71 	{	\
72 		SM_DBG((stderr, "pid=%ld, 1: len=%d\n", (long)getpid(), len));	\
73 		return -E2BIG;	/* ??? */	\
74 	}	\
75 	if (len >= buflen - 1)	\
76 	{	\
77 		SM_DBG((stderr, "pid=%ld, 2: len=%d\n", (long)getpid(), len));	\
78 		return -E2BIG;	/* ??? */	\
79 	}	\
80 	if (len <= 0)	\
81 	{	\
82 		SM_DBG((stderr, "pid=%ld, 3: len=%d\n", (long)getpid(), len));	\
83 		return -EINVAL;	/* ??? */	\
84 	}	\
85 	r = read(fd, buf, len + 1);	\
86 	save_errno = errno;	\
87 	SM_DBG((stderr, "pid=%ld, fd=%d, read=%d, len=%d, e=%d\n", (long)getpid(), fd, r, len+1, save_errno));	\
88 	if (r == 0)	\
89 	{	\
90 		SM_DBG((stderr, "pid=%ld, fd=%d, read2=%d, e=%d\n", (long)getpid(), fd, r, save_errno));	\
91 		return -1;	/* ??? */	\
92 	}	\
93 	if (r < 0)	\
94 	{	\
95 		SM_DBG((stderr, "pid=%ld, fd=%d, read3=%d, e=%d\n", (long)getpid(), fd, r, save_errno));	\
96 		return -save_errno;	\
97 	}	\
98 	if (len + 1 != r)	\
99 	{	\
100 		SM_DBG((stderr, "pid=%ld, fd=%d, read4=%d, len=%d\n", (long)getpid(), fd, r, len));	\
101 		return -1;	/* ??? */	\
102 	}	\
103 	if (buf[len] != ',')	\
104 	{	\
105 		SM_DBG((stderr, "pid=%ld, fd=%d, read5=%d, f=%d\n", (long)getpid(), fd, r, buf[len]));	\
106 		return -EINVAL;	/* ??? */	\
107 	}	\
108 	buf[len] = '\0';	\
109 	return r
110 
111 #endif /* ! LIBSM_MSG_H */
112