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

All rights reserved © 2002 - 2024 Isode Ltd.