x400_msasync.c
1 /* Copyright (c) 2005-2009, Isode Limited, London, England.
2  * All rights reserved.
3  *
4  * Acquisition and use of this software and related materials for any
5  * purpose requires a written licence agreement from Isode Limited,
6  * or a written licence from an organisation licenced by Isode Limited
7  * to grant such a licence.
8  *
9  */
10 
11 /*
12  *
13  * @VERSION@
14  */
15 
16 #include <stdio.h>
17 
18 #ifdef _WIN32
19 
20 int main(int argc, char **argv)
21 {
22  fprintf(stderr, "This example is not available on Windows\n");
23  exit(1);
24 }
25 
26 #else
27 
28 static void usage(void) ;
29 
30 #include <string.h>
31 #include <errno.h>
32 
33 #if defined (__hpux)
34 #include <sys/types.h>
35 #else
36 #include <sys/select.h>
37 #endif
38 #include <signal.h>
39 #include <sys/time.h>
40 #include <x400_msapi.h>
41 #include <x400_ms_async.h>
42 #include "example.h"
43 
44 /* Define IC_ATTRIBUTE
45  * For gcc/g++ this becomes __attribute__ and is used for the printf type
46  * format checking.
47  * Defined to be empty for other compilers
48  */
49 
50 #if defined(__GNUC__) || defined (__GNUG__)
51 #define IC_ATTRIBUTE(x) __attribute__ (x)
52 #else
53 #define IC_ATTRIBUTE(x)
54 #endif
55 
56 /* To annotate function parameters which are known not to be used
57  * Not in gcc/g++ prior to v4 (I think)
58  */
59 #if (defined(__GNUG__) && __GNUG__ >= 4) || (!defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 3)
60 # define ARGNOTUSED IC_ATTRIBUTE((unused))
61 #else
62 # define ARGNOTUSED
63 #endif
64 
65 static void connection_established(struct X400msSession *session,
66  int status,
67  int num_messages_waiting);
68 
69 static void connection_lost(struct X400msSession *session,
70  int reason_code,
71  char *diagnostic);
72 
73 static void submission_complete(struct X400msSession *session,
74  struct X400msMessage *message,
75  int errorcode);
76 
77 static void fetch_complete(struct X400msSession *session,
78  struct X400msMessage *message,
79  int type,
80  int seq,
81  int errorcode);
82 
83 static void delete_complete(struct X400msSession *session,
84  int seqnum,
85  int errorcode);
86 
87 static void wait_complete(struct X400msSession *session,
88  int num_messages_waiting,
89  int errorcode);
90 
91 static void list_complete(struct X400msSession *session,
92  struct X400msListResult *listres,
93  int errorcode);
94 
95 static void register_complete(struct X400msSession *session,
96  int errorcode);
97 
98 static void alert_event(struct X400msSession *session);
99 
100 static void event_loop(void);
101 
102 static int manage_callback(struct X400msSession *session,
103  int fd,
104  int eventmask);
105 
106 static int unmanage_callback(struct X400msSession *session,
107  int fd,
108  int eventmask);
109 
111  char *oraddr;
112  char *psw;
113  char *pa;
114  int fd;
115  int eventmask;
116  struct X400msSession *sp;
117 };
118 
119 #define MAX_SESSIONS 10
120 
121 struct SessionTable st[MAX_SESSIONS + 1];
122 static int dosubmit = 1;
123 int millisecs = 10000;
124 int numcons = 1;
125 int nummsgs = 9999999;
126 static char *optstr = "u371m:p:w:l:sc:o:";
127 int contype;
128 
129 static void usage(void) {
130  printf("usage: %s\n", optstr);
131  printf("\t where:\n");
132  printf("\t -u : Don't prompt to override defaults \n");
133  printf("\t -3 : P3 connection \n");
134  printf("\t -7 : P7 connection \n");
135  printf("\t -m : OR Address in P7 bind arg \n");
136  printf("\t -p : Presentation Address of P7 Store \n");
137  printf("\t -w : P7 password of P7 user \n");
138  printf("\t -s : Don't do submission\n");
139  printf("\t -l : Sleep time (milliseconds)\n");
140  printf("\t -c : Num associations\n");
141  printf("\t -o : Exit after retrieving n messages\n");
142  return;
143 }
144 
145 
146 int main(int argc, char **argv)
147 {
148  int i;
149  int status;
150  char *def_oraddr;
151  char *def_pa;
152  char buffer[BUFSIZ];
153  char pa[BUFSIZ];
154  char ora[BUFSIZ];
155 
156  x400_default_alternate_recipient_allowed = 1;
157  x400_channel = "1";
158  x400_default_originator = "1000000";
159 
160  for (i = 0; i <= MAX_SESSIONS; i++)
161  st[i].oraddr = NULL;
162 
163  if (get_args(argc, argv, optstr)) {
164  usage();
165  exit(-1);
166  }
167 
168  def_oraddr = x400_ms_user_addr;
169  def_pa = x400_ms_presentation_address;
170  if (x400_logline != NULL)
171  millisecs = atoi(x400_logline);
172 
173  dosubmit = x400_default_disclosure_of_recipients;
174  numcons = atoi(x400_channel);
175  nummsgs = atoi(x400_default_originator);
176 
177  printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
178  contype = ic_fgetc(x400_contype, stdin);
179  if (contype != 10)
180  ic_fgetc(x400_contype, stdin);
181 
182  if ( contype < '0' || '2' < contype )
183  contype = x400_contype;
184  else
185  contype -= '0';
186 
187  for (i = 0; i < numcons; i++) {
188  printf("ORAddress [%s] > ", def_oraddr);
189  ic_fgets (ora, sizeof ora, stdin);
190 
191  if ( ora[strlen(ora)-1] == '\n' )
192  ora[strlen(ora)-1] = '\0';
193 
194  if (ora[0] == '\0')
195  strcpy(ora, def_oraddr);
196 
197  /* Prompt for password; note: reflected. */
198  printf ("Password [%s]: ",
199  contype == 0 ? x400_p7_password : x400_p3_password);
200  if ( ic_fgets (buffer, sizeof buffer, stdin) == NULL )
201  exit (1);
202 
203  if (buffer[strlen(buffer)-1] == '\n' )
204  buffer[strlen(buffer)-1] = '\0';
205  if (buffer[0] == '\0')
206  strcpy(buffer, contype == 0 ? x400_p7_password : x400_p3_password);
207 
208  printf("Presentation Address [%s] > ", def_pa);
209  ic_fgets (pa, sizeof pa, stdin);
210 
211  if ( pa[strlen(pa)-1] == '\n' )
212  pa[strlen(pa)-1] = '\0';
213 
214  if (pa[0] == '\0')
215  strcpy(pa, def_pa);
216 
217  st[i].oraddr = strdup(ora);
218  st[i].psw = strdup(buffer);
219  st[i].pa = strdup(pa);
220  }
221 
222 
223  if (talking_to_marben_ms)
225 
226  /* Open our connections */
227  for (i = 0; (st[i].oraddr != NULL) && (i < numcons); i++) {
228  status = X400msOpenAsync (contype,
229  st[i].oraddr, NULL, st[i].psw,
230  st[i].pa, NULL,
231  connection_established,
232  connection_lost,
233  submission_complete,
234  fetch_complete,
235  delete_complete,
236  wait_complete,
237  list_complete,
238  register_complete,
239  alert_event,
240  manage_callback,
241  unmanage_callback,
242  &(st[i].sp));
243 
244  if (status != X400_E_WAIT_WRITE) {
245  fprintf (stderr, "Error in Open for %s: %s\n",
246  st[i].oraddr, X400msError (status));
247  } else {
248  printf ("Sent off connection request for session %p\n",
249  st[i].sp);
250  X400msSetStrDefault(st[i].sp,
252  "x400api.xml", 0);
253 
254  if (talking_to_marben_ms)
256 
257  st[i].fd = X400msGetHandle(st[i].sp);
258  }
259  }
260 
261  event_loop();
262 
263  return 0;
264 }
265 
266 
267 static int unmanage_callback(struct X400msSession *session,
268  int fd ARGNOTUSED,
269  int eventmask)
270 {
271  int i;
272 
273  printf("unmanage_callback, session = %p, mask = %d\n", session, eventmask);
274 
275  for (i = 0; st[i].oraddr != NULL; i++) {
276  if (st[i].sp == session) {
277  st[i].eventmask &= ~eventmask;
278  return 0;
279  }
280  }
281  return -1;
282 }
283 
284 static int manage_callback(struct X400msSession *session,
285  int fd,
286  int eventmask)
287 {
288  int i;
289 
290  printf("manage_callback, session = %p, fd = %d, eventmask = %d\n",
291  session, fd, eventmask);
292 
293  for (i = 0; st[i].oraddr != NULL; i++) {
294  if (st[i].sp == session) {
295  st[i].eventmask |= eventmask;
296  return 0;
297  }
298  }
299  return -1;
300 }
301 
302 
303 static void send_messages(void)
304 {
305  int status;
306  int i;
307  struct X400msMessage *mp;
308  struct X400Recipient *rp;
309  char buf[1024];
310  char contid[1024];
311  static int num = 0;
312  char *s;
313 
314  for (i = 0; st[i].oraddr != NULL; i++) {
315  if (st[i].fd != -1) {
316 
317  status = X400msMsgNew (st[i].sp,
318  X400_MSG_MESSAGE, &mp);
319  if ( status != X400_E_NOERROR ) {
320  fprintf (stderr, "x400msMsgNew returned error: %s\n",
321  X400msError (status));
322  exit (status);
323  }
324 
325  status = X400msRecipNew (mp, X400_RECIP_STANDARD, &rp);
326  if ( status != X400_E_NOERROR ) {
327  fprintf (stderr, "x400msRecipNew returned error: %s\n",
328  X400msError (status));
329  exit (status);
330  }
331 
333  st[i].oraddr, -1);
334  if ( status != X400_E_NOERROR ) {
335  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n",
336  X400msError (status));
337  exit (status);
338  }
339 
340  sprintf(buf, "Subject for session %p", st[i].sp);
341  status = X400msMsgAddStrParam (mp, X400_S_SUBJECT,
342  buf, -1);
343  if ( status != X400_E_NOERROR ) {
344  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
345  X400msError (status));
346  exit (status);
347  }
348 
349  status = X400msMsgAddStrParam (mp, X400_T_IA5TEXT, "body text", -1);
350  if ( status != X400_E_NOERROR ) {
351  fprintf (stderr, "x400ms returned error: %s\n",
352  X400msError (status));
353  exit (status);
354  }
355 #define BINSIZE 6000000
356  s = (char*)malloc(BINSIZE);
357  memset(s,0,BINSIZE);
358  X400msMsgAddAttachment(mp, X400_T_BINARY, s, BINSIZE);
359  free(s);
360 
361  sprintf(contid, "CONTID%d", num);
362  num++;
363 
364  /* Content identifier so we can correlate with submission result */
365  status = X400msMsgAddStrParam(mp, X400_S_CONTENT_IDENTIFIER, contid, -1);
366  if ( status != X400_E_NOERROR ) {
367  fprintf (stderr, "X400msMsgAddIntParam %d returned error: %s\n",
369  exit (status);
370  }
371 
372  printf("Sending message from & to %s\n", st[i].oraddr);
373  status = X400msMsgSend(mp);
374 
375  if ((status != X400_E_WAIT_READ) &&
376  (status != X400_E_WAIT_READ_WRITE)) {
377  fprintf (stderr, "Error sending message: %d\n", status);
378  }
379 
380  X400msMsgDelete(mp, 0);
381  }
382  }
383 }
384 
385 
386 static void connection_established(struct X400msSession *session,
387  int status,
388  int alert)
389 {
390  int retval;
391  int count;
392 
393  if (status == X400_E_NOERROR) {
394  printf("Connection established for session %p, alert = %d\n",
395  session, alert);
396 
397  if (contype == 0) {
398 #ifdef notdef
399  printf("Sending Register request\n");
400  retval = X400msRegisterAutoAction (session, X400_AUTO_ALERT,
401  9, NULL);
402  if ((retval != X400_E_WAIT_READ) &&
403  (retval != X400_E_WAIT_READ_WRITE))
404  fprintf(stderr,
405  "Failed to issue Register for session %p, err = %d\n",
406  session, retval);
407  printf("Registered AutoAlert autoaction (id = 9) OK\n");
408 
409  printf("Sending Deregister request\n");
410  retval = X400msDeregisterAutoAction (session,
411  X400_AUTO_ALERT, 5);
412  if ((retval != X400_E_WAIT_READ) &&
413  (retval != X400_E_WAIT_READ_WRITE))
414  fprintf(stderr,
415  "Failed to issue Deregister for session %p, err = %d\n",
416  session, retval);
417  printf("Deegistered AutoAlert autoaction (id = 5) OK\n");
418 #endif
419  printf("Sending List request\n");
420  retval = X400msList(session, NULL, NULL);
421  if ((retval != X400_E_WAIT_READ) &&
422  (retval != X400_E_WAIT_READ_WRITE))
423  fprintf(stderr,
424  "Failed to issue List for session %p, err = %d\n",
425  session, retval);
426  } else {
427  /* If P3 connection, we just need to wait until we get invoked */
428  retval = X400msWait(session, 0, &count);
429 
430  if ((retval != X400_E_WAIT_READ) &&
431  (retval != X400_E_WAIT_READ_WRITE))
432  fprintf(stderr,
433  "Failed to issue Wait for session %p, err = %d\n",
434  session, retval);
435  }
436  } else {
437  int i;
438 
439  fprintf(stderr, "Connection failed for session %p\n", session);
440  for (i = 0; st[i].oraddr != NULL; i++) {
441  if (st[i].sp == session) {
442  st[i].fd = -1;
443  break;
444  }
445  }
446  }
447 }
448 
449 static void connection_lost(struct X400msSession *session ARGNOTUSED,
450  int reason_code,
451  char *diagnostic)
452 {
453  fprintf(stderr, "Connection lost callback, reason = %d, diag = %s\n",
454  reason_code, (diagnostic == NULL) ? "NULL" : diagnostic);
455 }
456 
457 static void submission_complete(struct X400msSession *session ARGNOTUSED,
458  struct X400msMessage *message,
459  int errorcode)
460 {
461  if (errorcode == X400_E_NOERROR) {
462  char buf[1024];
463  size_t len;
464  int status;
465 
466  memset(buf,0,1024);
468  buf, 1024, &len) == X400_E_NOERROR)
469  printf("Submission successful, identifier = %s\n", buf);
470  else
471  fprintf(stderr,"Submission successful but failed to get ID\n");
472 
473  status = X400msMsgGetStrParam(message, X400_S_MESSAGE_SUBMISSION_TIME, buf, 1024, &len);
474  if (status != X400_E_NOERROR) {
475  fprintf(stderr, "No MessageSubmissionTime present from submission result: error %d\n", status);
476  } else {
477  buf [len] = '\0';
478  printf("MessageSubmissionTime from Submission Result = %s\n", buf);
479  }
480 
481  status = X400msMsgGetStrParam(message, X400_S_CONTENT_IDENTIFIER, buf, 1024, &len);
482  if (status != X400_E_NOERROR) {
483  fprintf(stderr, "No ContentIdentifier present from submission result: error %d\n", status);
484  } else {
485  buf [len] = '\0';
486  printf("ContentIdentifier from Submission Result = %s\n", buf);
487  }
488 
489  X400msMsgDelete (message, 0);
490  } else {
491  fprintf(stderr, "Submission failed, errorcode = %d\n", errorcode);
492  }
493 
494 }
495 
496 
497 static void list_complete(struct X400msSession *session,
498  struct X400msListResult *lr,
499  int errorcode)
500 {
501  int i = 1;
502  int status = X400_E_NOERROR;
503 
504  printf("list_complete, errorcode = %d\n", errorcode);
505 
506  if (errorcode == X400_E_NOERROR) {
507  /* Traverse list result, extracting information about each message */
508  while (status == X400_E_NOERROR) {
509  int seqnum = 0;
510  char buf[1024];
511  char *type;
512  char *subj;
513  char *sender;
514  size_t len;
515  int length;
516  int pri;
517  int entry_status;
518  char *msgid;
519  char *subjid;
520 
521  type = NULL;
522  subj = NULL;
523  sender = NULL;
524  msgid = NULL;
525  subjid = NULL;
526  length = -1;
527  pri = -1;
528  entry_status = -1;
529 
530  /* Get sequence number */
532  i, &seqnum)) == X400_E_NO_MORE_RESULTS)
533  break;
534 
535  if (X400msListGetStrParam(lr,
537  i,
538  buf,
539  1024,
540  &len) == X400_E_NOERROR)
541  type = strdup(buf);
542 
543  if (X400msListGetStrParam(lr,
545  i,
546  buf,
547  1024,
548  &len) == X400_E_NOERROR)
549  subj = strdup(buf);
550 
551  if (X400msListGetStrParam(lr,
553  i,
554  buf,
555  1024,
556  &len) == X400_E_NOERROR)
557  sender = strdup(buf);
558 
559  if (X400msListGetStrParam(lr,
561  i,
562  buf,
563  1024,
564  &len) == X400_E_NOERROR)
565  msgid = strdup(buf);
566 
567  if (X400msListGetStrParam(lr,
569  i,
570  buf,
571  1024,
572  &len) == X400_E_NOERROR)
573  subjid = strdup(buf);
574 
576 
578 
579  /* Entry status */
581  &entry_status);
582 
583  printf("S=%d, P=%d, len=%d, stat=%d, type=%s, subj=%s, orig=%s, msgid=%s, subjid=%s\n",
584  seqnum, pri, length, entry_status,
585  (type == NULL) ? "NULL" : type,
586  (subj == NULL) ? "NULL": subj,
587  (sender == NULL) ? "NULL" : sender,
588  (msgid == NULL) ? "NULL" : msgid,
589  (subjid == NULL) ? "NULL" : subjid);
590  i++;
591  if (sender != NULL)
592  free(sender);
593  if (subj != NULL)
594  free(subj);
595  if (type != NULL)
596  free(type);
597  if (msgid != NULL)
598  free(msgid);
599  if (subjid != NULL)
600  free(subjid);
601 
602  if (seqnum != 0) {
603  int retval;
604 
605  /* Ask for the whole message */
606  printf("Session %p, issing MsgGet\n", session);
607  retval = X400msMsgGet (session, seqnum,
608  NULL, NULL, NULL);
609  if ((retval != X400_E_WAIT_READ) &&
610  (retval != X400_E_WAIT_READ_WRITE)) {
611  fprintf(stderr, "MsgGet failed !\n");
612  exit(1);
613  }
614  }
615  }
616  X400msListFree(lr);
617  } else {
618  fprintf(stderr,"List failed, errorcode = %d\n", errorcode);
619  }
620 }
621 
622 
623 static void fetch_complete(struct X400msSession *session,
624  struct X400msMessage *message,
625  int type,
626  int seqno,
627  int errorcode)
628 {
629  printf("Fetch complete callback, session=%p, seqno=%d, type=%d, errorcode = %d\n",
630  session, seqno, type, errorcode);
631 
632  if (errorcode == X400_E_NOERROR) {
633  char buf[1024];
634  size_t len;
635  int retval;
636  char buffer[30000];
637  int status;
638  size_t length;
639 
641  buffer, sizeof buffer, &length);
642  if (status == X400_E_NOERROR)
643  printf("Read raw content into file %s\n", buffer);
644  else
645  fprintf(stderr,"Failed to read raw content into file, error %d\n", status);
646 
647  status = X400msMsgGetStrParam (message, X400_S_CONTENT_STRING,
648  buffer, sizeof buffer , &length);
649  if (status == X400_E_NOERROR)
650  printf("Read raw content into buffer, length = %ld\n", (long)length);
651  else
652  fprintf(stderr,"Failed to read raw content into buffer, error %d\n", status);
653 
654  memset(buf,0,1024);
656  buf, 1024, &len) == X400_E_NOERROR)
657  printf("Object type = %s\n", buf);
658 
659  memset(buf,0,1024);
660  if (X400msMsgGetStrParam (message, X400_S_SUBJECT,
661  buf, 1024, &len) == X400_E_NOERROR)
662  printf("Subject = %s\n", buf);
663 
664  if (contype != 0) {
665  retval = X400msMsgGetFinish (message, X400_E_NOERROR, 0);
666  if (retval != X400_E_NOERROR)
667  fprintf(stderr, "MsgGetFinish failed !\n");
668  }
669 
670  /* Now delete it */
671  retval = X400msMsgDelete (message, 0);
672  if ((retval != X400_E_NOERROR) &&
673  (retval != X400_E_WAIT_READ) && (retval != X400_E_WAIT_READ_WRITE))
674  fprintf(stderr, "MsgDelete failed !\n");
675  else
676  printf("Session %p, issued MsgDelete for %d\n", session, seqno );
677 #ifdef notdef
678  /* Ask for the next one */
679  retval = X400msMsgGet (session, 0, NULL, NULL, NULL);
680  fprintf(stderr, "MsgGet failed !\n");
681  if ((retval != X400_E_WAIT_READ) && (retval != X400_E_WAIT_READ_WRITE))
682  else
683  printf("Session %p, issued MsgGet\n", session);
684 #endif
685  } else
686  fprintf(stderr, "Fetch failed, errcode = %d\n",errorcode);
687 
688 }
689 
690 static void delete_complete(struct X400msSession *session,
691  int seqnum,
692  int errorcode)
693 {
694  if (errorcode == X400_E_NOERROR) {
695  printf("Session %p, - delete complete callback for seqnum %d\n",
696  session, seqnum);
697  } else {
698  fprintf(stderr, "******* SESSION %p, - DELETE FAILED %d **********\n",
699  session, errorcode);
700  }
701 }
702 
703 static void register_complete(struct X400msSession *session,
704  int errorcode)
705 {
706  if (errorcode == X400_E_NOERROR) {
707  printf("Session %p, - register complete callback\n",
708  session);
709  } else {
710  fprintf(stderr, "******* SESSION %p, - REGISTER FAILED %d **********\n",
711  session, errorcode);
712  }
713 }
714 
715 static void wait_complete(struct X400msSession *session,
716  int num_messages_waiting,
717  int errorcode)
718 {
719  printf("Wait complete callback, errorcode = %d, num = %d\n",
720  errorcode, num_messages_waiting);
721 
722  if (num_messages_waiting > 0) {
723  int retval;
724 
725  /* Get first available message */
726  printf("Session %p, issuing MsgGet OK\n", session);
727  retval = X400msMsgGet (session, 0, NULL, NULL, NULL);
728  if ((retval != X400_E_WAIT_READ) && (retval != X400_E_WAIT_READ_WRITE))
729  fprintf(stderr, "MsgGet failed !\n");
730  }
731 }
732 
733 static void alert_event(struct X400msSession *session)
734 {
735  int retval;
736 
737  printf("Got an alert !\n");
738 
739  printf("Issuing List op for session %p\n", session);
740  retval = X400msList(session, NULL, NULL);
741  if ((retval != X400_E_WAIT_READ) && (retval != X400_E_WAIT_READ_WRITE))
742  fprintf(stderr, "Failed to issue List op for session %p, error %d\n",
743  session, retval);
744 }
745 
746 
747 static void event_loop()
748 {
749  fd_set rfds, wfds, efds;
750  struct timeval timeout, *tp;
751  int n;
752  int i;
753 
754  while (1) {
755  int num_fds = 0;
756 
757  FD_ZERO (&rfds);
758  FD_ZERO (&efds);
759  FD_ZERO (&wfds);
760 
761  for (i = 0; st[i].oraddr != NULL; i++) {
762  if (st[i].fd != -1) {
763 
764  printf("Expecting ");
765  if (st[i].eventmask & X400_EVENT_READ) {
766  printf("read ");
767  FD_SET(st[i].fd, &rfds);
768  }
769 
770  if (st[i].eventmask & X400_EVENT_WRITE) {
771  printf("write ");
772  FD_SET(st[i].fd, &wfds);
773  }
774 
775  if (st[i].eventmask & X400_EVENT_ERROR) {
776  printf("error ");
777  FD_SET(st[i].fd, &efds);
778  }
779  printf("on fd %d\n", st[i].fd);
780  }
781 
782  if (st[i].fd > num_fds)
783  num_fds = st[i].fd;
784  }
785 
786  if ( millisecs >= 0 ) {
787  timeout.tv_sec = millisecs / 1000;
788  timeout.tv_usec = (millisecs % 1000) *1000;
789  tp = &timeout;
790  } else {
791  tp = 0;
792  }
793  //printf("num fds = %d\n", num_fds);
794  n = select (num_fds + 1, &rfds, &wfds, &efds, tp);
795 
796  if (n < 0) {
797  fprintf(stderr, "select returned %d: errno = %d\n", n, errno);
798  exit(1);
799  }
800  else if (n == 0) {
801  if (nummsgs < 0) {
802  printf("Exiting now\n");
803  for (i = 0; st[i].oraddr != NULL; i++)
804  if (st[i].fd != -1)
805  X400msClose(st[i].sp);
806  exit(0);
807  } else
808  nummsgs--;
809 
810  printf(">>>>> Timeout\n");
811 
812  if (contype == 0) {
813  for (i = 0; st[i].oraddr != NULL; i++) {
814  int retval;
815 
816  if (st[i].fd != -1) {
817  printf("Issuing List for session %p\n", st[i].sp);
818  retval = X400msList(st[i].sp, NULL, NULL);
819  if ((retval != X400_E_WAIT_READ) &&
820  (retval != X400_E_WAIT_READ_WRITE))
821  fprintf(stderr,
822  "Failed to issue List for session %p, err = %d\n",
823  st[i].sp, retval);
824  }
825  }
826  }
827 
828  if (dosubmit == 1)
829  /* Submit some new message */
830  send_messages();
831 
832  } else {
833  X400msProcessEvent(num_fds + 1, &rfds, &wfds, &efds);
834  }
835  }
836 }
837 
838 #endif
int X400msProcessEvent(int num_fds, fd_set *read_fds, fd_set *write_fds, fd_set *error_fds)
Process outstanding read, write and error events on the specified set of file descriptors....
void X400msSetConfigRequest(int val)
Disable and enable configuration requests in MS Bind operations.
#define X400_N_STRICT_P7_1988
Definition: x400_att.h:1269
#define X400_S_LOG_CONFIGURATION_FILE
Definition: x400_att.h:1092
#define X400_EVENT_READ
Definition: x400_msapi.h:297
#define X400_E_WAIT_READ
Definition: x400_att.h:220
#define X400_S_OBJECTTYPE
Definition: x400_att.h:470
int X400msMsgSend(struct X400msMessage *mp)
Send message object.
#define X400_AUTO_ALERT
Definition: x400_att.h:1334
#define X400_N_MS_ENTRY_STATUS
Definition: x400_att.h:1229
int X400msMsgAddAttachment(struct X400msMessage *mp, int type, const char *string, size_t length)
Add attachment to the message.
#define X400_S_CONTENT_STRING
Definition: x400_att.h:767
int X400msSetStrDefault(struct X400msSession *sp, int paramtype, const char *value, size_t length)
Set a default string parameter value in a session.
int X400msListGetIntParam(struct X400msListResult *lr, int paramtype, int number, int *valp)
Get an integer attribute value from an element of a ListResult.
int X400msOpenAsync(int type, const char *oraddr, const char *dirname, const char *credentials, const char *pa, const char *ret_psw, X400msConnEstablishedCb *conupcb, X400msConnDroppedCb *condowncb, X400msMsgSubmittedCb *msgsubcb, X400msMsgFetchedCb *msgfetchcb, X400msMsgDeletedCb *msgdelcb, X400msMsgWaitingCb *msgwaitcb, X400msListCb *listcb, X400msRegisterCb *registercb, X400msAlertCb *alertcb, X400msManageCb *managecb, X400msManageCb *unmanagecb, struct X400msSession **spp)
Initiate an asynchronous opening of a session to a Message Store (P7)
#define X400_E_NO_MORE_RESULTS
Definition: x400_att.h:214
int X400msClose(struct X400msSession *sp)
Close a X400 Session.
#define X400_T_BINARY
Definition: x400_att.h:825
#define X400_E_WAIT_WRITE
Definition: x400_att.h:217
int X400msDeregisterAutoAction(struct X400msSession *sp, int type, int id)
Deregister an autoaction from the Message Store.
void X400msListFree(struct X400msListResult *lr)
Free the memory occupied by a ListResult.
int X400msRecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400msMsgGet(struct X400msSession *sp, int number, struct X400msMessage **mpp, int *typep, int *seqp)
Get message object for transfer out from MS or MTA via P3.
#define X400_N_PRIORITY
Definition: x400_att.h:422
int X400msRecipNew(struct X400msMessage *mp, int type, struct X400Recipient **rpp)
Add new recipient to a message.
const char * X400msError(int error)
Obtain a string describing the meaning of the given error code.
#define X400_T_IA5TEXT
Definition: x400_att.h:799
#define X400_E_WAIT_READ_WRITE
Definition: x400_att.h:223
#define X400_RECIP_STANDARD
Definition: x400_att.h:341
int X400msMsgNew(struct X400msSession *sp, int type, struct X400msMessage **mpp)
Creates new message.
#define X400_S_CONTENT_FILENAME
Definition: x400_att.h:772
#define X400_S_CONTENT_IDENTIFIER
Definition: x400_att.h:414
int X400msList(struct X400msSession *sp, char *since_time, struct X400msListResult **lrp)
List messages in the P7 Message Store.
int X400msWait(struct X400msSession *sp, int seconds, int *count)
Wait for messages to be ready to be read.
#define X400_S_MESSAGE_IDENTIFIER
Definition: x400_att.h:405
#define X400_N_MS_SEQUENCE_NUMBER
Definition: x400_att.h:1232
#define X400_E_NOERROR
Definition: x400_att.h:46
#define X400_EVENT_WRITE
Definition: x400_msapi.h:300
#define X400_S_SUBJECT_IDENTIFIER
Definition: x400_att.h:1039
X400 MA/MS (P3/P7) Interface.
#define X400_N_CONTENT_LENGTH
Definition: x400_att.h:411
X400 MS (P7) Interface asynchronous event handler.
#define X400_EVENT_ERROR
Definition: x400_msapi.h:303
int X400msSetIntDefault(struct X400msSession *sp, int paramtype, int value)
Set a default integer parameter value in a session.
#define X400_S_SUBJECT
Definition: x400_att.h:723
#define X400_S_MESSAGE_SUBMISSION_TIME
Definition: x400_att.h:439
int X400msMsgGetStrParam(struct X400msMessage *mp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the message object.
int X400msListGetStrParam(struct X400msListResult *lr, int paramtype, int number, char *buffer, size_t buflen, size_t *paramlenp)
Get a string attribute value from an element of a ListResult.
int X400msMsgAddStrParam(struct X400msMessage *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400msMsgGetFinish(struct X400msMessage *mp, int errnum, int problem)
Generate delivery result or error for a message.
int X400msRegisterAutoAction(struct X400msSession *sp, int type, int id, struct X400msAutoActionParameter *aa_param)
Register an autoaction with the Message Store.
#define X400_MSG_MESSAGE
Definition: x400_att.h:29
int X400msGetHandle(struct X400msSession *session)
Get a handle suitable for use in a call to select()
#define X400_S_OR_ADDRESS
Definition: x400_att.h:349
int X400msMsgDelete(struct X400msMessage *mp, int retain)
Delete message object.