7 /* global mail flow control
9 /* #include <mail_flow.h>
11 /* ssize_t mail_flow_get(count)
14 /* ssize_t mail_flow_put(count)
17 /* ssize_t mail_flow_count()
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.
33 /* The producer needs to wake up periodically to ensure that
34 /* tokens are not lost due to leakage.
38 /* The Secure Mailer license must be distributed with this software.
41 /* IBM T.J. Watson Research
43 /* Yorktown Heights, NY 10598, USA
54 /* Utility library. */
61 #include <mail_flow.h>
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
];
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
95 for (count
= len
; count
> 0; count
-= n
)
96 if ((n
= read(MASTER_FLOW_READ
, buf
, count
> BUFFER_SIZE
?
97 BUFFER_SIZE
: count
)) <= 0)
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
];
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)
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";
140 if ((count
= peekfd(MASTER_FLOW_READ
)) < 0)
141 msg_warn("%s: %m", myname
);