x400_msrcv.c
1/* Copyright (c) 2003-2014, 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 * Simple example program for receiving a message from a store.
14 */
15#include <stdio.h>
16#include <stdlib.h>
17#ifndef _WIN32
18#include <unistd.h>
19#endif
20#include <x400_msapi.h>
21#include <amhs_att.h>
22#include <seclabel_api.h> /* For security labels */
23#include "example.h"
24#include "ms_example.h"
25
26static char *optstr = "u371m:d:p:w:M:D:P:W:";
27
28static void usage(void);
29
30static int get_msg (
31 struct X400msSession *sp
32);
33
37int
38main(
39 int argc,
40 char **argv)
41{
42 char buffer[BUFSIZ];
43 char pa[BUFSIZ];
44 char orn[BUFSIZ];
45 int status;
46 int nummsg;
47 int nummsg_ready;
48 struct X400msSession *sp;
49 int contype;
50 char *def_oraddr;
51 char *def_dn;
52 char *def_pa;
53 /* period to pass into X400msWait() */
54 int ms_timeout_period = 10;
55 /* number of timeouts from X400msWait() before exiting */
56 # define NUM_MSWAIT_TIMEOUTS 10
57 int max_timeouts = NUM_MSWAIT_TIMEOUTS;
58
59 /* setup logging from $(ETCDIR)x400api.xml or $(SHAREDIR)x400api.xml */
60 status = X400InitializeLogging(argv[0], "x400api.xml");
61 if (status != X400_E_NOERROR) {
62 fprintf(stderr, "Failed to initialize logging, %s\n", X400msError(status));
63 } else {
64 printf("Initialized logging from file x400api.xml\n");
65 }
66
67 if (get_args(argc, argv, optstr)) {
68 usage();
69 exit(-1);
70 }
71
72 printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
73 contype = ic_fgetc(x400_contype, stdin);
74 if (contype != 10)
75 ic_fgetc(x400_contype, stdin);
76
77 if ( contype < '0' || '2' < contype )
78 contype = x400_contype;
79 else
80 contype -= '0';
81
82 if (contype == 0) {
83 def_oraddr = x400_ms_user_addr;
84 def_dn = x400_ms_user_dn;
85 def_pa = x400_ms_presentation_address;
86 }
87 else {
88 def_oraddr = x400_mta_user_addr;
89 def_dn = x400_mta_user_dn;
90 def_pa = x400_mta_presentation_address;
91 }
92
93 printf("Your ORAddress [%s] > ", def_oraddr);
94 ic_fgets(orn, sizeof orn, stdin);
95
96 if (orn[strlen(orn) - 1] == '\n')
97 orn[strlen(orn) - 1] = '\0';
98
99 if (orn[0] == '\0')
100 strcpy(orn, def_oraddr);
101
102 /* Prompt for password; note: reflected. */
103 printf("Password [%s]: ",
104 contype == 0 ? x400_p7_password : x400_p3_password);
105 if (ic_fgets(buffer, sizeof buffer, stdin) == NULL)
106 exit(1);
107
108 if (buffer[strlen(buffer) - 1] == '\n')
109 buffer[strlen(buffer) - 1] = '\0';
110 if (buffer[0] == '\0')
111 strcpy(buffer, contype == 0 ? x400_p7_password : x400_p3_password);
112
113 printf("Presentation Address [%s] > ", def_pa);
114 ic_fgets(pa, sizeof pa, stdin);
115
116 if (pa[strlen(pa) - 1] == '\n')
117 pa[strlen(pa) - 1] = '\0';
118
119 if (pa[0] == '\0')
120 strcpy(pa, def_pa);
121
122 if (talking_to_marben_ms)
124
125 status = X400msOpen(contype, orn, def_dn, buffer, pa, &nummsg, &sp);
126 if (status != X400_E_NOERROR) {
127 fprintf(stderr, "Error in Open: %s\n", X400msError(status));
128 exit(status);
129 }
130
131 if (talking_to_marben_ms)
133
134#ifdef USING_ALERTS
135 /* If we register the alert auto-action, we will get an alert indication
136 when a message is delivered. So there is no need to poll at
137 short intervals within X400ms_Wait - we can do a slow background
138 poll and rely on the Alert indication to wake the code up instead */
140#endif
141
142#ifdef WANT_SESSION_SPECIFIC_LOGGING
143 /* setup logging from $(ETCDIR)x400api.xml or $(SHAREDIR)x400api.xml */
145#endif
146
148
149 if (contype == 0) {
150#ifdef WANT_AUTOFORWARDING
151 struct X400msAutoActionParameter *aa_param;
152
153 /* Register an Autoforwarding Autoaction. */
154 aa_param = X400msNewAutoActionParameter();
155
156 /* Add mandatory things to AutoAction parameter for auto-forwarding:
157 i.e. recipient address */
158 X400RecipNew(0, &rp);
159
161 strlen(def_oraddr));
162
164
167 "AF contentid", -1);
168
170
173 1);
174
177 1);
178
181 1);
182
184
187 "This message was autoforwarded",
188 -1);
189
192 "This is a cover note", -1);
193
196 "AutoForwarded:", -1);
197
199 4, aa_param);
200 if (status != X400_E_NOERROR) {
201 fprintf(stderr,
202 "Error in RegisterAutoAction: %s\n", X400msError(status));
203 /* tidily close the session */
204 (void) X400msClose(sp);
205 exit(status);
206 }
207 printf("Registered AutoForwarding autoaction (id = 4) OK\n");
209#endif
210
211#ifdef USING_ALERTS
212 /* No parameter needed for Alert autoaction - we do not support
213 configuration of requested-attributes in this API yet. */
214 status = X400msRegisterAutoAction(sp, X400_AUTO_ALERT, 9, NULL);
215 if (status != X400_E_NOERROR) {
216 fprintf(stderr, "Error in RegisterAutoAction: %s\n",
217 X400msError(status));
218 /* tidily close the session */
219 (void) X400msClose(sp);
220 exit(status);
221 }
222 printf("Registered AutoAlert autoaction (id = 9) OK\n");
223#endif
224
225 /* Just test the register and deregister functions */
226 status = X400msRegisterAutoAction(sp, X400_AUTO_ALERT, 10, NULL);
227 if (status != X400_E_NOERROR) {
228 fprintf(stderr, "Error in RegisterAutoAction: %s\n",
229 X400msError(status));
230 /* tidily close the session */
231 (void) X400msClose(sp);
232 exit(status);
233 }
234 printf("Registered AutoAlert autoaction (id = 10) OK\n");
235
236 /* Lets do a deregistration of the action we just registered */
238 if (status != X400_E_NOERROR) {
239 fprintf(stderr, "Error in DeregisterAutoAction: %s\n",
240 X400msError(status));
241 /* tidily close the session */
242 (void) X400msClose(sp);
243 exit(status);
244 }
245 printf("Deregistered AutoAlert autoaction (id = 10) OK\n");
246 }
247
248 ms_timeout_period = 20;
249
250 if (nummsg == 0) {
251 if (ms_timeout_period == 0) {
252 printf ("\n\nno messages - looping in msWait(%d) .....\n",
253 ms_timeout_period);
254 } else {
255 printf ("\n\nno messages - calling msWait(%d) .....\n",
256 ms_timeout_period);
257 }
258 } else {
259 printf("%d messages waiting\n", nummsg);
260 }
261
262 while (1) {
263 /* Using P3
264 * - if ms_timeout_period > 0, wait once then break
265 * - if ms_timeout_period == 0, loop through NUM_MSWAIT_TIMEOUTS
266 * times, then break.
267 */
268 status = X400msWait(sp, ms_timeout_period, &nummsg_ready);
269 if (status == X400_E_NOERROR) {
270 printf("====== Getting next msg ======= (%d)\n", nummsg_ready);
271 (void) get_msg(sp);
272 max_timeouts = NUM_MSWAIT_TIMEOUTS;
273 } else {
274 if (status != X400_E_TIMED_OUT) {
275 /* tidily close the session */
276 fprintf(stderr, "X400msWait returned error: %s\n",
277 X400msError(status));
278 status = X400msClose(sp);
279 exit(status);
280 }
281 /* printf("X400msWait returned timeout\n"); */
282 sleep(1);
283 if (max_timeouts-- == 0)
284 break;
285 }
286 if (ms_timeout_period != 0)
287 break;
288 }
289
290 status = X400msClose(sp);
291 return(status);
292}
293
294static int get_msg (
295 struct X400msSession *sp
296)
297{
298 int type;
299 int seqn;
300 int status;
301 struct X400msMessage *mp;
302 char c;
303 size_t retlen;
304 char *buf = NULL;
305 char *databuf = &c;
306
307 printf("Getting message\n");
308 status = X400msMsgGet(sp, 0, &mp, &type, &seqn);
309 switch (status) {
310 case X400_E_NOERROR:
311 fprintf(stderr, "MsgGet successfully got message\n");
312 break;
313 default :
314 fprintf(stderr, "Error from MsgGet: %s\n", X400msError(status));
315 /* tidily close the session */
316 status = X400msClose(sp);
317 exit(status);
318 break;
319 }
320
321 status = print_msg(mp, type);
322 if (status != X400_E_NOERROR) {
323 (void) X400msMsgDelete(mp, 0);
324 X400msClose(sp);
325 exit(status);
326 }
327
328 /* Get binary representation and store to file */
329
330 /* First pass to find out how big it needs to be */
331 status = X400msMsgGetRaw(sp, mp, databuf, 0, &retlen);
332 if (status != X400_E_NOSPACE) {
333 fprintf(stderr, "Failed to get raw message length: error %d\n", status);
334 } else {
335 struct X400msMessage *newmsg;
336 int newtype;
337
338 databuf = buf = (char *)malloc(retlen);
339 printf("Data buffer length required = %d\n", (int)retlen);
340 status = X400msMsgGetRaw(sp, mp, databuf, retlen, &retlen);
341 if (status != X400_E_NOERROR) {
342 fprintf(stderr, "Failed to get raw message: error %d\n", status);
343 } else {
344 /* Dump to file */
345 FILE *fd = fopen("message.dump", "w");
346 if (fd == NULL) {
347 fprintf(stderr, "Failed to open file message.dump\n");
348 } else {
349 if (fwrite(databuf, 1, retlen, fd) < retlen) {
350 fprintf(stderr, "Failed to write message to file message.dump\n");
351 } else {
352 fprintf(stdout, "Dumped message to file message.dump\n");
353 }
354 fclose(fd);
355 }
356 }
357
358 /* And try to reconstruct message from bytes */
359 status = X400msMsgFromRaw(sp, databuf, retlen, &newmsg, &newtype);
360 if (status != X400_E_NOERROR) {
361 fprintf(stderr, "Failed to create message from bytes: error %d\n", status);
362 }
363
364 printf("************************** Printing cached message ************************\n");
365 print_msg(newmsg, newtype);
366 if (buf != NULL)
367 free(buf);
368
369 X400msMsgDelete(newmsg, 0);
370 }
371
372 /* Deletes message in message store as well as internal copy */
373 printf("\n+++ got message - deleting it and returning+++\n");
374 status = X400msMsgDelete(mp, 0);
375
376 return status;
377}
378
379
380
381static void usage(void) {
382 printf("usage: %s\n", optstr);
383 printf("\t where:\n");
384 printf("\t -u : Don't prompt to override defaults \n");
385 printf("\t -3 : Use P3 connection \n");
386 printf("\t -7 : Use P7 connection \n");
387 printf("\t -m : OR Address in P7 bind arg \n");
388 printf("\t -d : DN in P7 bind arg \n");
389 printf("\t -p : Presentation Address of P7 Store \n");
390 printf("\t -w : P7 password of P7 user \n");
391 printf("\t -M : OR Address in P3 bind arg \n");
392 printf("\t -D : DN in P3 bind arg \n");
393 printf("\t -P : Presentation Address of P3 server\n");
394 printf("\t -W : P3 password of P3 user \n");
395 return;
396}
397
AMHS Symbolic Constants.
int X400RecipNew(int type, struct X400Recipient **rpp)
Create a new recipient object.
int X400RecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the recipient.
int X400InitializeLogging(const char *myname, const char *xmlfile)
Initialize X.400 API logging. If just the name of the logging configuration file is provided,...
int X400msMsgFromRaw(struct X400msSession *sp, char *buffer, size_t buflen, struct X400msMessage **mpp, int *typep)
Reconstruct a message from a binary representation.
int X400msAutoActionParameterAddIntParam(struct X400msAutoActionParameter *aap, int paramtype, int value)
Add integer-valued parameter to the autoaction parameter.
void X400msFreeAutoActionParameter(struct X400msAutoActionParameter *aa_param)
Free an autoaction parameter.
int X400msMsgGetRaw(struct X400msSession *sp, struct X400msMessage *mp, char *buffer, size_t buflen, size_t *buflenp)
Get a binary representation of a message which can be subsequently be used to reconstruct the message...
int X400msAutoActionParameterAddRecip(struct X400msAutoActionParameter *aap, int reciptype, struct X400Recipient *recip)
Add a receipient to the autoaction parameter.
int X400msWait(struct X400msSession *sp, int seconds, int *count)
Wait for messages to be ready to be read.
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 X400msRegisterAutoAction(struct X400msSession *sp, int type, int id, struct X400msAutoActionParameter *aa_param)
Register an autoaction with the Message Store.
int X400msSetIntDefault(struct X400msSession *sp, int paramtype, int value)
Set a default integer parameter value in a session.
struct X400msAutoActionParameter * X400msNewAutoActionParameter(void)
Create a new (empty) autoaction parameter structure.
int X400msMsgDelete(struct X400msMessage *mp, int retain)
Delete message object.
int X400msAutoActionParameterAddStrParam(struct X400msAutoActionParameter *aap, int paramtype, const char *value, size_t length)
Add string-valued parameter to the autoaction parameter.
void X400msSetConfigRequest(int val)
Disable and enable configuration requests in MS Bind operations.
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.
int X400msOpen(int type, const char *oraddr, const char *dirname, const char *credentials, const char *pa, int *messages, struct X400msSession **spp)
Open a session to a Message Store (P7) or MTA (P3) in synchronous mode.
#define X400_S_OR_ADDRESS
Definition x400_att.h:349
#define X400_AUTO_ALERT
Definition x400_att.h:1356
#define X400_AUTO_FORWARDING
Definition x400_att.h:1359
#define X400_N_WAIT_INTERVAL
Definition x400_att.h:1109
#define X400_S_LOG_CONFIGURATION_FILE
Definition x400_att.h:1116
#define X400_N_OR_CANONICAL
Definition x400_att.h:1160
#define X400_N_PRIORITY
Definition x400_att.h:433
#define X400_S_CONTENT_IDENTIFIER
Definition x400_att.h:425
#define X400_N_IMPLICIT_CONVERSION_PROHIBITED
Definition x400_att.h:439
#define X400_N_CONTENT_RETURN_REQUEST
Definition x400_att.h:445
#define X400_N_DISCLOSURE
Definition x400_att.h:436
#define X400_N_ALTERNATE_RECIPIENT_ALLOWED
Definition x400_att.h:442
#define X400_E_TIMED_OUT
Definition x400_att.h:106
#define X400_E_NOERROR
Definition x400_att.h:46
#define X400_E_NOSPACE
Definition x400_att.h:112
#define X400_S_COVER_NOTE
Definition x400_att.h:1266
#define X400_N_STRICT_P7_1988
Definition x400_att.h:1293
#define X400_S_AUTO_FORWARDING_COMMENT
Definition x400_att.h:1262
#define X400_S_THIS_IPM_PREFIX
Definition x400_att.h:1269
#define X400_RECIP_STANDARD
Definition x400_att.h:341
X400 MA/MS (P3/P7) Interface.

All rights reserved © 2002 - 2024 Isode Ltd.