Postfix3.3.1
post_mail.c
[詳解]
1 /*++
2 /* NAME
3 /* post_mail 3
4 /* SUMMARY
5 /* convenient mail posting interface
6 /* SYNOPSIS
7 /* #include <post_mail.h>
8 /*
9 /* VSTREAM *post_mail_fopen(sender, recipient, source_class, trace_flags,
10 /* utf8_flags, queue_id)
11 /* const char *sender;
12 /* const char *recipient;
13 /* int source_class;
14 /* int trace_flags;
15 /* int utf8_flags;
16 /* VSTRING *queue_id;
17 /*
18 /* VSTREAM *post_mail_fopen_nowait(sender, recipient, source_class,
19 /* trace_flags, utf8_flags, queue_id)
20 /* const char *sender;
21 /* const char *recipient;
22 /* int source_class;
23 /* int trace_flags;
24 /* int utf8_flags;
25 /* VSTRING *queue_id;
26 /*
27 /* void post_mail_fopen_async(sender, recipient, source_class,
28 /* trace_flags, utf8_flags,
29 /* queue_id, notify, context)
30 /* const char *sender;
31 /* const char *recipient;
32 /* int source_class;
33 /* int trace_flags;
34 /* int utf8_flags;
35 /* VSTRING *queue_id;
36 /* void (*notify)(VSTREAM *stream, void *context);
37 /* void *context;
38 /*
39 /* int post_mail_fprintf(stream, format, ...)
40 /* VSTREAM *stream;
41 /* const char *format;
42 /*
43 /* int post_mail_fputs(stream, str)
44 /* VSTREAM *stream;
45 /* const char *str;
46 /*
47 /* int post_mail_buffer(stream, buf, len)
48 /* VSTREAM *stream;
49 /* const char *buffer;
50 /*
51 /* int POST_MAIL_BUFFER(stream, buf)
52 /* VSTREAM *stream;
53 /* VSTRING *buffer;
54 /*
55 /* int post_mail_fclose(stream)
56 /* VSTREAM *STREAM;
57 /*
58 /* void post_mail_fclose_async(stream, notify, context)
59 /* VSTREAM *stream;
60 /* void (*notify)(int status, void *context);
61 /* void *context;
62 /* DESCRIPTION
63 /* This module provides a convenient interface for the most
64 /* common case of sending one message to one recipient. It
65 /* allows the application to concentrate on message content,
66 /* without having to worry about queue file structure details.
67 /*
68 /* post_mail_fopen() opens a connection to the cleanup service
69 /* and waits until the service is available, does some option
70 /* negotiation, generates message envelope records, and generates
71 /* Received: and Date: message headers. The result is a stream
72 /* handle that can be used for sending message records.
73 /*
74 /* post_mail_fopen_nowait() tries to contact the cleanup service
75 /* only once, and does not wait until the cleanup service is
76 /* available. Otherwise it is identical to post_mail_fopen().
77 /*
78 /* post_mail_fopen_async() contacts the cleanup service and
79 /* invokes the caller-specified notify routine, with the
80 /* open stream and the caller-specified context when the
81 /* service responds, or with a null stream and the caller-specified
82 /* context when the request could not be completed. It is the
83 /* responsibility of the application to close an open stream.
84 /*
85 /* post_mail_fprintf() formats message content (header or body)
86 /* and sends it to the cleanup service.
87 /*
88 /* post_mail_fputs() sends pre-formatted content (header or body)
89 /* to the cleanup service.
90 /*
91 /* post_mail_buffer() sends a pre-formatted buffer to the
92 /* cleanup service.
93 /*
94 /* POST_MAIL_BUFFER() is a wrapper for post_mail_buffer() that
95 /* evaluates its buffer argument more than once.
96 /*
97 /* post_mail_fclose() completes the posting of a message.
98 /*
99 /* post_mail_fclose_async() completes the posting of a message
100 /* and upon completion invokes the caller-specified notify
101 /* routine, with the cleanup status and caller-specified context
102 /* as arguments.
103 /*
104 /* Arguments:
105 /* .IP sender
106 /* The sender envelope address. It is up to the application
107 /* to produce From: headers.
108 /* .IP recipient
109 /* The recipient envelope address. It is up to the application
110 /* to produce To: headers.
111 /* .IP source_class
112 /* The message source class, as defined in \fB<mail_proto.h>\fR.
113 /* Depending on the setting of the internal_mail_source_classes
114 /* and smtputf8_autodetect_classes parameters, the message
115 /* will or won't be subject to content inspection or SMTPUTF8
116 /* autodetection.
117 /* .IP trace_flags
118 /* Message tracing flags as specified in \fB<deliver_request.h>\fR.
119 /* .IP utf8_flags
120 /* Flags defined in <smtputf8.h>. Flags other than
121 /* SMTPUTF8_FLAG_REQUESTED are ignored.
122 /* .IP queue_id
123 /* Null pointer, or pointer to buffer that receives the queue
124 /* ID of the new message.
125 /* .IP stream
126 /* A stream opened by mail_post_fopen().
127 /* .IP notify
128 /* Application call-back routine.
129 /* .IP context
130 /* Application call-back context.
131 /* DIAGNOSTICS
132 /* post_mail_fopen_nowait() returns a null pointer when the
133 /* cleanup service is not available immediately.
134 /*
135 /* post_mail_fopen_async() returns a null pointer when the
136 /* attempt to contact the cleanup service fails immediately.
137 /*
138 /* post_mail_fprintf(), post_mail_fputs() post_mail_fclose(),
139 /* and post_mail_buffer() return the binary OR of the error
140 /* status codes defined in \fI<cleanup_user.h>\fR.
141 /*
142 /* Fatal errors: cleanup initial handshake errors. This means
143 /* the client and server speak incompatible protocols.
144 /* SEE ALSO
145 /* cleanup_user(3h) cleanup options and results
146 /* cleanup_strerror(3) translate results to text
147 /* cleanup(8) cleanup service
148 /* LICENSE
149 /* .ad
150 /* .fi
151 /* The Secure Mailer license must be distributed with this software.
152 /* AUTHOR(S)
153 /* Wietse Venema
154 /* IBM T.J. Watson Research
155 /* P.O. Box 704
156 /* Yorktown Heights, NY 10598, USA
157 /*
158 /* Wietse Venema
159 /* Google, Inc.
160 /* 111 8th Avenue
161 /* New York, NY 10011, USA
162 /*--*/
163 
164 /* System library. */
165 
166 #include <sys_defs.h>
167 #include <sys/time.h>
168 #include <stdlib.h> /* 44BSD stdarg.h uses abort() */
169 #include <stdarg.h>
170 #include <string.h>
171 
172 /* Utility library. */
173 
174 #include <msg.h>
175 #include <vstream.h>
176 #include <vstring.h>
177 #include <mymalloc.h>
178 #include <events.h>
179 
180 /* Global library. */
181 
182 #include <mail_params.h>
183 #include <record.h>
184 #include <rec_type.h>
185 #include <mail_proto.h>
186 #include <cleanup_user.h>
187 #include <post_mail.h>
188 #include <mail_date.h>
189 
190  /*
191  * Call-back state for asynchronous connection requests.
192  */
193 typedef struct {
194  char *sender;
195  char *recipient;
200  void *context;
204 
205  /*
206  * Call-back state for asynchronous close requests.
207  */
208 typedef struct {
209  int status;
212  void *context;
214 
215 /* post_mail_init - initial negotiations */
216 
217 static void post_mail_init(VSTREAM *stream, const char *sender,
218  const char *recipient,
219  int source_class, int trace_flags,
220  int utf8_flags, VSTRING *queue_id)
221 {
222  VSTRING *id = queue_id ? queue_id : vstring_alloc(100);
223  struct timeval now;
224  const char *date;
225  int cleanup_flags =
227  | smtputf8_autodetect(source_class)
228  | ((utf8_flags & SMTPUTF8_FLAG_REQUESTED) ? CLEANUP_FLAG_SMTPUTF8 : 0);
229 
230  GETTIMEOFDAY(&now);
231  date = mail_date(now.tv_sec);
232 
233  /*
234  * XXX Don't flush buffers while sending the initial message records.
235  * That would cause deadlock between verify(8) and cleanup(8) servers.
236  */
239 
240  /*
241  * Negotiate with the cleanup service. Give up if we can't agree.
242  */
243  if (attr_scan(stream, ATTR_FLAG_STRICT,
245  ATTR_TYPE_END) != 1
246  || attr_print(stream, ATTR_FLAG_NONE,
247  SEND_ATTR_INT(MAIL_ATTR_FLAGS, cleanup_flags),
248  ATTR_TYPE_END) != 0)
249  msg_fatal("unable to contact the %s service", var_cleanup_service);
250 
251  /*
252  * Generate a minimal envelope section. The cleanup service will add a
253  * size record.
254  */
256  REC_TYPE_TIME_ARG(now));
257  rec_fprintf(stream, REC_TYPE_ATTR, "%s=%s",
259  rec_fprintf(stream, REC_TYPE_ATTR, "%s=%d",
260  MAIL_ATTR_TRACE_FLAGS, trace_flags);
261  rec_fputs(stream, REC_TYPE_FROM, sender);
262  rec_fputs(stream, REC_TYPE_RCPT, recipient);
263  rec_fputs(stream, REC_TYPE_MESG, "");
264 
265  /*
266  * Do the Received: and Date: header lines. This allows us to shave a few
267  * cycles by using the expensive date conversion result for both.
268  */
269  post_mail_fprintf(stream, "Received: by %s (%s)",
271  post_mail_fprintf(stream, "\tid %s; %s", vstring_str(id), date);
272  post_mail_fprintf(stream, "Date: %s", date);
273  if (queue_id == 0)
274  vstring_free(id);
275 }
276 
277 /* post_mail_fopen - prepare for posting a message */
278 
279 VSTREAM *post_mail_fopen(const char *sender, const char *recipient,
280  int source_class, int trace_flags,
281  int utf8_flags, VSTRING *queue_id)
282 {
283  VSTREAM *stream;
284 
286  post_mail_init(stream, sender, recipient, source_class, trace_flags,
287  utf8_flags, queue_id);
288  return (stream);
289 }
290 
291 /* post_mail_fopen_nowait - prepare for posting a message */
292 
293 VSTREAM *post_mail_fopen_nowait(const char *sender, const char *recipient,
294  int source_class, int trace_flags,
295  int utf8_flags, VSTRING *queue_id)
296 {
297  VSTREAM *stream;
298 
300  BLOCKING)) != 0)
301  post_mail_init(stream, sender, recipient, source_class, trace_flags,
302  utf8_flags, queue_id);
303  else
304  msg_warn("connect to %s/%s: %m",
306  return (stream);
307 }
308 
309 /* post_mail_open_event - handle asynchronous connection events */
310 
311 static void post_mail_open_event(int event, void *context)
312 {
313  POST_MAIL_STATE *state = (POST_MAIL_STATE *) context;
314  const char *myname = "post_mail_open_event";
315 
316  switch (event) {
317 
318  /*
319  * Initial server reply. Stop the watchdog timer, disable further
320  * read events that end up calling this function, and notify the
321  * requestor.
322  */
323  case EVENT_READ:
324  if (msg_verbose)
325  msg_info("%s: read event", myname);
326  event_cancel_timer(post_mail_open_event, context);
329  post_mail_init(state->stream, state->sender,
330  state->recipient, state->source_class,
331  state->trace_flags, state->utf8_flags,
332  state->queue_id);
333  myfree(state->sender);
334  myfree(state->recipient);
335  state->notify(state->stream, state->context);
336  myfree((void *) state);
337  return;
338 
339  /*
340  * No connection or no initial reply within a conservative time
341  * limit. The system is broken and we give up.
342  */
343  case EVENT_TIME:
344  if (state->stream) {
345  msg_warn("timeout connecting to service: %s", var_cleanup_service);
347  vstream_fclose(state->stream);
348  } else {
349  msg_warn("connect to service: %s: %m", var_cleanup_service);
350  }
351  myfree(state->sender);
352  myfree(state->recipient);
353  state->notify((VSTREAM *) 0, state->context);
354  myfree((void *) state);
355  return;
356 
357  /*
358  * Some exception.
359  */
360  case EVENT_XCPT:
361  msg_warn("error connecting to service: %s", var_cleanup_service);
362  event_cancel_timer(post_mail_open_event, context);
364  vstream_fclose(state->stream);
365  myfree(state->sender);
366  myfree(state->recipient);
367  state->notify((VSTREAM *) 0, state->context);
368  myfree((void *) state);
369  return;
370 
371  /*
372  * Broken software or hardware.
373  */
374  default:
375  msg_panic("%s: unknown event type %d", myname, event);
376  }
377 }
378 
379 /* post_mail_fopen_async - prepare for posting a message */
380 
381 void post_mail_fopen_async(const char *sender, const char *recipient,
382  int source_class, int trace_flags,
383  int utf8_flags, VSTRING *queue_id,
384  void (*notify) (VSTREAM *, void *),
385  void *context)
386 {
387  VSTREAM *stream;
388  POST_MAIL_STATE *state;
389 
391  state = (POST_MAIL_STATE *) mymalloc(sizeof(*state));
392  state->sender = mystrdup(sender);
393  state->recipient = mystrdup(recipient);
394  state->source_class = source_class;
395  state->trace_flags = trace_flags;
396  state->utf8_flags = utf8_flags;
397  state->notify = notify;
398  state->context = context;
399  state->stream = stream;
400  state->queue_id = queue_id;
401 
402  /*
403  * To keep interfaces as simple as possible we report all errors via the
404  * same interface as all successes.
405  */
406  if (stream != 0) {
407  event_enable_read(vstream_fileno(stream), post_mail_open_event,
408  (void *) state);
409  event_request_timer(post_mail_open_event, (void *) state,
411  } else {
412  event_request_timer(post_mail_open_event, (void *) state, 0);
413  }
414 }
415 
416 /* post_mail_fprintf - format and send message content */
417 
418 int post_mail_fprintf(VSTREAM *cleanup, const char *format,...)
419 {
420  int status;
421  va_list ap;
422 
423  va_start(ap, format);
424  status = rec_vfprintf(cleanup, REC_TYPE_NORM, format, ap);
425  va_end(ap);
426  return (status != REC_TYPE_NORM ? CLEANUP_STAT_WRITE : 0);
427 }
428 
429 /* post_mail_buffer - send pre-formatted buffer */
430 
431 int post_mail_buffer(VSTREAM *cleanup, const char *buf, int len)
432 {
433  return (rec_put(cleanup, REC_TYPE_NORM, buf, len) != REC_TYPE_NORM ?
434  CLEANUP_STAT_WRITE : 0);
435 }
436 
437 /* post_mail_fputs - send pre-formatted message content */
438 
439 int post_mail_fputs(VSTREAM *cleanup, const char *str)
440 {
441  ssize_t len = str ? strlen(str) : 0;
442 
443  return (rec_put(cleanup, REC_TYPE_NORM, str, len) != REC_TYPE_NORM ?
444  CLEANUP_STAT_WRITE : 0);
445 }
446 
447 /* post_mail_fclose - finish posting of message */
448 
450 {
451  int status = 0;
452 
453  /*
454  * Send the message end marker only when there were no errors.
455  */
456  if (vstream_ferror(cleanup) != 0) {
457  status = CLEANUP_STAT_WRITE;
458  } else {
459  rec_fputs(cleanup, REC_TYPE_XTRA, "");
460  rec_fputs(cleanup, REC_TYPE_END, "");
461  if (vstream_fflush(cleanup)
462  || attr_scan(cleanup, ATTR_FLAG_MISSING,
464  ATTR_TYPE_END) != 1)
465  status = CLEANUP_STAT_WRITE;
466  }
467  (void) vstream_fclose(cleanup);
468  return (status);
469 }
470 
471 /* post_mail_fclose_event - event handler */
472 
473 static void post_mail_fclose_event(int event, void *context)
474 {
475  POST_MAIL_FCLOSE_STATE *state = (POST_MAIL_FCLOSE_STATE *) context;
476  int status = state->status;
477 
478  switch (event) {
479 
480  /*
481  * Final server reply. Pick up the completion status.
482  */
483  case EVENT_READ:
484  if (status == 0) {
485  if (vstream_ferror(state->stream) != 0
488  ATTR_TYPE_END) != 1)
489  status = CLEANUP_STAT_WRITE;
490  }
491  break;
492 
493  /*
494  * No response or error.
495  */
496  default:
497  msg_warn("error talking to service: %s", var_cleanup_service);
498  status = CLEANUP_STAT_WRITE;
499  break;
500  }
501 
502  /*
503  * Stop the watchdog timer, and disable further read events that end up
504  * calling this function.
505  */
506  event_cancel_timer(post_mail_fclose_event, context);
508 
509  /*
510  * Notify the requestor and clean up.
511  */
512  state->notify(status, state->context);
513  (void) vstream_fclose(state->stream);
514  myfree((void *) state);
515 }
516 
517 /* post_mail_fclose_async - finish posting of message */
518 
520  void (*notify) (int status, void *context),
521  void *context)
522 {
523  POST_MAIL_FCLOSE_STATE *state;
524  int status = 0;
525 
526 
527  /*
528  * Send the message end marker only when there were no errors.
529  */
530  if (vstream_ferror(stream) != 0) {
531  status = CLEANUP_STAT_WRITE;
532  } else {
533  rec_fputs(stream, REC_TYPE_XTRA, "");
534  rec_fputs(stream, REC_TYPE_END, "");
535  if (vstream_fflush(stream))
536  status = CLEANUP_STAT_WRITE;
537  }
538 
539  /*
540  * Bundle up the suspended state.
541  */
542  state = (POST_MAIL_FCLOSE_STATE *) mymalloc(sizeof(*state));
543  state->status = status;
544  state->stream = stream;
545  state->notify = notify;
546  state->context = context;
547 
548  /*
549  * To keep interfaces as simple as possible we report all errors via the
550  * same interface as all successes.
551  */
552  if (status == 0) {
553  event_enable_read(vstream_fileno(stream), post_mail_fclose_event,
554  (void *) state);
555  event_request_timer(post_mail_fclose_event, (void *) state,
557  } else {
558  event_request_timer(post_mail_fclose_event, (void *) state, 0);
559  }
560 }
int msg_verbose
Definition: msg.c:177
void event_enable_read(int fd, EVENT_NOTIFY_RDWR_FN callback, void *context)
Definition: events.c:729
char * var_mail_name
Definition: mail_params.c:230
#define ATTR_FLAG_NONE
Definition: attr.h:98
void myfree(void *ptr)
Definition: mymalloc.c:207
int rec_vfprintf(VSTREAM *stream, int type, const char *format, va_list ap)
Definition: record.c:374
VSTREAM * mail_connect_wait(const char *class, const char *name)
Definition: mail_connect.c:108
int post_mail_fprintf(VSTREAM *cleanup, const char *format,...)
Definition: post_mail.c:418
#define MAIL_ATTR_TRACE_FLAGS
Definition: mail_proto.h:149
char * mystrdup(const char *str)
Definition: mymalloc.c:225
#define CLEANUP_FLAG_SMTPUTF8
Definition: cleanup_user.h:26
char * var_cleanup_service
Definition: mail_params.c:302
int smtputf8_autodetect(int class)
Definition: smtputf8.c:67
const char * mail_date(time_t when)
Definition: mail_date.c:54
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define vstring_str(vp)
Definition: vstring.h:71
VSTREAM * mail_connect(const char *class, const char *name, int block_mode)
Definition: mail_connect.c:79
#define ATTR_FLAG_MISSING
Definition: attr.h:99
#define VSTREAM_CTL_END
Definition: vstream.h:135
void * context
Definition: post_mail.c:200
#define EVENT_XCPT
Definition: events.h:42
#define RECV_ATTR_INT(name, val)
Definition: attr.h:71
#define ATTR_TYPE_END
Definition: attr.h:39
#define REC_TYPE_FROM
Definition: rec_type.h:43
#define REC_TYPE_END
Definition: rec_type.h:77
#define MAIL_ATTR_ORG_LOCAL
Definition: mail_proto.h:229
#define SMTPUTF8_FLAG_REQUESTED
Definition: smtputf8.h:97
void post_mail_fclose_async(VSTREAM *stream, void(*notify)(int status, void *context), void *context)
Definition: post_mail.c:519
#define MAIL_CLASS_PUBLIC
Definition: mail_proto.h:95
VSTREAM * post_mail_fopen(const char *sender, const char *recipient, int source_class, int trace_flags, int utf8_flags, VSTRING *queue_id)
Definition: post_mail.c:279
#define attr_print
Definition: attr.h:109
#define MAIL_ATTR_LOG_ORIGIN
Definition: mail_proto.h:212
#define ATTR_TYPE_INT
Definition: attr.h:40
VSTREAM * stream
Definition: post_mail.c:201
VSTREAM * post_mail_fopen_nowait(const char *sender, const char *recipient, int source_class, int trace_flags, int utf8_flags, VSTRING *queue_id)
Definition: post_mail.c:293
#define VSTREAM_CTL_BUFSIZE
Definition: vstream.h:149
int vstream_fclose(VSTREAM *stream)
Definition: vstream.c:1268
#define REC_TYPE_TIME_FORMAT
Definition: rec_type.h:148
#define REC_TYPE_RCPT
Definition: rec_type.h:45
int rec_fputs(VSTREAM *stream, int type, const char *str)
Definition: record.c:404
#define REC_TYPE_MESG
Definition: rec_type.h:56
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
int post_mail_fclose(VSTREAM *cleanup)
Definition: post_mail.c:449
POST_MAIL_FCLOSE_NOTIFY notify
Definition: post_mail.c:211
#define EVENT_READ
Definition: events.h:40
#define MAIL_ATTR_STATUS
Definition: mail_proto.h:126
#define SEND_ATTR_INT(name, val)
Definition: attr.h:63
int rec_put(VSTREAM *stream, int type, const char *data, ssize_t len)
Definition: record.c:194
char * recipient
Definition: post_mail.c:195
POST_MAIL_NOTIFY notify
Definition: post_mail.c:199
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
int post_mail_fputs(VSTREAM *cleanup, const char *str)
Definition: post_mail.c:439
#define CLEANUP_FLAG_MASK_INTERNAL
Definition: cleanup_user.h:40
#define VSTREAM_BUFSIZE
Definition: vstream.h:92
void(* POST_MAIL_FCLOSE_NOTIFY)(int, void *)
Definition: post_mail.h:39
int post_mail_buffer(VSTREAM *cleanup, const char *buf, int len)
Definition: post_mail.c:431
#define EVENT_TIME
Definition: events.h:43
#define NON_BLOCKING
Definition: iostuff.h:49
VSTRING * queue_id
Definition: post_mail.c:202
int non_blocking(int, int)
Definition: non_blocking.c:55
void post_mail_fopen_async(const char *sender, const char *recipient, int source_class, int trace_flags, int utf8_flags, VSTRING *queue_id, void(*notify)(VSTREAM *, void *), void *context)
Definition: post_mail.c:381
#define REC_TYPE_XTRA
Definition: rec_type.h:62
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
time_t event_request_timer(EVENT_NOTIFY_TIME_FN callback, void *context, int delay)
Definition: events.c:894
#define REC_TYPE_ATTR
Definition: rec_type.h:49
#define vstream_fileno(vp)
Definition: vstream.h:115
int var_daemon_timeout
Definition: mail_params.c:284
#define REC_TYPE_NORM
Definition: rec_type.h:59
#define REC_TYPE_TIME
Definition: rec_type.h:38
#define CLEANUP_STAT_WRITE
Definition: cleanup_user.h:58
#define MAIL_ATTR_QUEUEID
Definition: mail_proto.h:130
char * var_myhostname
Definition: mail_params.c:223
void vstream_control(VSTREAM *stream, int name,...)
Definition: vstream.c:1372
void event_disable_readwrite(int fd)
Definition: events.c:839
#define attr_scan
Definition: attr.h:111
#define vstream_ferror(vp)
Definition: vstream.h:120
#define BLOCKING
Definition: iostuff.h:48
int rec_fprintf(VSTREAM *stream, int type, const char *format,...)
Definition: record.c:391
int event_cancel_timer(EVENT_NOTIFY_TIME_FN callback, void *context)
Definition: events.c:965
#define MAIL_ATTR_FLAGS
Definition: mail_proto.h:128
#define REC_TYPE_TIME_ARG(tv)
Definition: rec_type.h:149
void(* POST_MAIL_NOTIFY)(VSTREAM *, void *)
Definition: post_mail.h:31
int int_filt_flags(int class)
Definition: int_filt.c:56
#define RECV_ATTR_STR(name, val)
Definition: attr.h:72
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
#define ATTR_FLAG_STRICT
Definition: attr.h:103
void msg_info(const char *fmt,...)
Definition: msg.c:199