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