Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / master / mail_flow.c
blob6d70b76bde3f820b6687a3f1b1c9194a691372b0
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* mail_flow 3
6 /* SUMMARY
7 /* global mail flow control
8 /* SYNOPSIS
9 /* #include <mail_flow.h>
11 /* ssize_t mail_flow_get(count)
12 /* ssize_t count;
14 /* ssize_t mail_flow_put(count)
15 /* ssize_t count;
17 /* ssize_t mail_flow_count()
18 /* DESCRIPTION
19 /* This module implements a simple flow control mechanism that
20 /* is based on tokens that are consumed by mail receiving processes
21 /* and that are produced by mail sending processes.
23 /* mail_flow_get() attempts to read specified number of tokens. The
24 /* result is > 0 for success, < 0 for failure. In the latter case,
25 /* the process is expected to slow down a little.
27 /* mail_flow_put() produces the specified number of tokens. The
28 /* token producing process is expected to produce new tokens
29 /* whenever it falls idle and no more tokens are available.
31 /* mail_flow_count() returns the number of available tokens.
32 /* BUGS
33 /* The producer needs to wake up periodically to ensure that
34 /* tokens are not lost due to leakage.
35 /* LICENSE
36 /* .ad
37 /* .fi
38 /* The Secure Mailer license must be distributed with this software.
39 /* AUTHOR(S)
40 /* Wietse Venema
41 /* IBM T.J. Watson Research
42 /* P.O. Box 704
43 /* Yorktown Heights, NY 10598, USA
44 /*--*/
46 /* System library. */
48 #include <sys_defs.h>
49 #include <sys/stat.h>
50 #include <unistd.h>
51 #include <stdlib.h>
52 #include <string.h>
54 /* Utility library. */
56 #include <msg.h>
57 #include <iostuff.h>
59 /* Global library. */
61 #include <mail_flow.h>
63 /* Master library. */
65 #include <master_proto.h>
67 #define BUFFER_SIZE 1024
69 /* mail_flow_get - read N tokens */
71 ssize_t mail_flow_get(ssize_t len)
73 const char *myname = "mail_flow_get";
74 char buf[BUFFER_SIZE];
75 struct stat st;
76 ssize_t count;
77 ssize_t n = 0;
80 * Sanity check.
82 if (len <= 0)
83 msg_panic("%s: bad length %ld", myname, (long) len);
86 * Silence some wild claims.
88 if (fstat(MASTER_FLOW_WRITE, &st) < 0)
89 msg_fatal("fstat flow pipe write descriptor: %m");
92 * Read and discard N bytes. XXX AIX read() can return 0 when an open
93 * pipe is empty.
95 for (count = len; count > 0; count -= n)
96 if ((n = read(MASTER_FLOW_READ, buf, count > BUFFER_SIZE ?
97 BUFFER_SIZE : count)) <= 0)
98 return (-1);
99 if (msg_verbose)
100 msg_info("%s: %ld %ld", myname, (long) len, (long) (len - count));
101 return (len - count);
104 /* mail_flow_put - put N tokens */
106 ssize_t mail_flow_put(ssize_t len)
108 const char *myname = "mail_flow_put";
109 char buf[BUFFER_SIZE];
110 ssize_t count;
111 ssize_t n = 0;
114 * Sanity check.
116 if (len <= 0)
117 msg_panic("%s: bad length %ld", myname, (long) len);
120 * Write or discard N bytes.
122 memset(buf, 0, len > BUFFER_SIZE ? BUFFER_SIZE : len);
124 for (count = len; count > 0; count -= n)
125 if ((n = write(MASTER_FLOW_WRITE, buf, count > BUFFER_SIZE ?
126 BUFFER_SIZE : count)) < 0)
127 return (-1);
128 if (msg_verbose)
129 msg_info("%s: %ld %ld", myname, (long) len, (long) (len - count));
130 return (len - count);
133 /* mail_flow_count - return number of available tokens */
135 ssize_t mail_flow_count(void)
137 const char *myname = "mail_flow_count";
138 ssize_t count;
140 if ((count = peekfd(MASTER_FLOW_READ)) < 0)
141 msg_warn("%s: %m", myname);
142 return (count);