x400_mslist.c
1 /* Copyright (c) 2005-2010, 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  * Simple example program for listing the contents of an X.400 Message Store mailbox.
15  */
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 
20 #include <x400_msapi.h>
21 #include "example.h"
22 #include "ms_example.h"
23 
24 static void usage(void);
25 
26 static int fetch_and_print_msg (struct X400msSession *sp,
27  int seqnum);
28 
29 static char *optstr = "371um:p:d:w:t:znT:S:h:V:I";
30 
31 int main (
32  int argc,
33  char **argv
34 )
35 {
36  char buffer[BUFSIZ];
37  char pa[BUFSIZ];
38  char orn[BUFSIZ];
39  int status;
40  struct X400msSession *sp;
41  int contype;
42  char *def_oraddr;
43  char *def_dn;
44  char *def_pa;
45  int i;
46  struct X400msListResult *lr;
47 
48  /* Magic value as this parameter can be used for entry status
49  * this value results in either 'any' or 'new' being used.
50  */
51  bin_bp_size = 10000;
52 
53  if (get_args(argc, argv, optstr)) {
54  usage();
55  exit(-1);
56  }
57 
58  printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
59  contype = ic_fgetc(x400_contype, stdin);
60  if (contype != 10)
61  ic_fgetc(x400_contype, stdin);
62 
63  if ( contype < '0' || '2' < contype )
64  contype = x400_contype;
65  else
66  contype -= '0';
67 
68  if (contype == 0) {
69  def_oraddr = x400_ms_user_addr;
70  def_dn = x400_ms_user_dn;
71  def_pa = x400_ms_presentation_address;
72  } else {
73  def_oraddr = x400_mta_user_addr;
74  def_dn = x400_mta_user_dn;
75  def_pa = x400_mta_presentation_address;
76  }
77 
78  printf("Your ORAddress [%s] > ", def_oraddr);
79  ic_fgets (orn, sizeof orn, stdin);
80 
81  if ( orn[strlen(orn)-1] == '\n' )
82  orn[strlen(orn)-1] = '\0';
83 
84  if (orn[0] == '\0')
85  strcpy(orn, def_oraddr);
86 
87  /* Prompt for password; note: reflected. */
88  printf ("Password [%s]: ",
89  contype == 0 ? x400_p7_password : x400_p3_password);
90  if ( ic_fgets (buffer, sizeof buffer, stdin) == NULL )
91  exit (1);
92 
93  if (buffer[strlen(buffer)-1] == '\n' )
94  buffer[strlen(buffer)-1] = '\0';
95  if (buffer[0] == '\0')
96  strcpy(buffer, contype == 0 ? x400_p7_password : x400_p3_password);
97 
98  printf("Presentation Address [%s] > ", def_pa);
99  ic_fgets (pa, sizeof pa, stdin);
100 
101  if ( pa[strlen(pa)-1] == '\n' )
102  pa[strlen(pa)-1] = '\0';
103 
104  if (pa[0] == '\0')
105  strcpy(pa, def_pa);
106 
107 
108  if (talking_to_marben_ms)
110 
111  status = X400msOpen (contype, orn, def_dn, buffer, pa, NULL, &sp);
112  if ( status != X400_E_NOERROR ) {
113  fprintf (stderr, "Error in Open: %s\n", X400msError (status));
114  exit (status);
115  }
116 
117  if (talking_to_marben_ms)
119 
120  /* setup logging from $(ETCDIR)x400api.xml or $(SHAREDIR)x400api.xml */
121  X400msSetStrDefault(sp, X400_S_LOG_CONFIGURATION_FILE, "x400api.xml", -1);
122 
123  for (i = 0; attrs[i] != NULL; i++) {
124  X400msSetStrDefault(sp, X400_S_LIST_ATTR + i, attrs[i], -1);
125  }
126 
127  /* Now list messages, since we have a P7 connection */
128 
129  /* List messages since a specific time and date - 20/01/2005, 12:05:06
130  in this case. Specify NULL string instead to list all of them */
131 
132  status = X400msListExAuxPriBefore(sp, since_time, until_time,
133  (submitted_messages == 1) ?
136  (bin_bp_size == 10000) ?
137  (new_messages == 1) ? 0 : -1 :
138  bin_bp_size,
139  priority,
140  &lr);
141  if (status != X400_E_NOERROR) {
142  fprintf (stderr, "X400msList returned status: %s\n",
143  X400msError (status));
144  exit(1);
145  }
146 
147  i = 1;
148 
149  printf("\nGot a list result\n");
150 
151  /* Traverse list result, extracting information about each message */
152  while (status == X400_E_NOERROR) {
153  int n;
154  int seqnum;
155  int substat;
156  char buf[1024];
157  size_t len;
158 
159  /* Get sequence number */
161  &seqnum);
162  if (status == X400_E_NOERROR)
163  printf("\nSequence number = %d\n", seqnum);
164  else if (status == X400_E_NO_MORE_RESULTS)
165  break;
166 
167  /* Get type of entry */
168  substat = X400msListGetStrParam(lr,
170  i,
171  buf,
172  1024,
173  &len);
174 
175  if (substat == X400_E_NOERROR) {
176  printf("Object type = %s\n", buf);
177  } else {
178  printf("No object type present \n");
179  }
180 
181  /* Get Subject field, if any */
182  substat = X400msListGetStrParam(lr,
184  i,
185  buf,
186  1024,
187  &len);
188 
189  if (substat == X400_E_NOERROR) {
190  printf("Subject = %s\n", buf);
191  } else {
192  printf("No subject present \n");
193  }
194 
195  /* Get sender address */
196  substat = X400msListGetStrParam(lr,
198  i,
199  buf,
200  1024,
201  &len);
202 
203  if (substat == X400_E_NOERROR) {
204  printf("Sender = %s\n", buf);
205  } else {
206  printf("No sender present \n");
207  }
208 
209  substat = X400msListGetStrParam(lr,
211  i,
212  buf,
213  1024,
214  &len);
215 
216  if (substat == X400_E_NOERROR) {
217  printf("Msg Id = %s\n", buf);
218  } else {
219  printf("No Msg Id present \n");
220  }
221 
222  substat = X400msListGetStrParam(lr,
224  i,
225  buf,
226  1024,
227  &len);
228 
229  if (substat == X400_E_NOERROR) {
230  printf("Subject Id = %s\n", buf);
231  } else {
232  printf("No Subject Id present \n");
233  }
234 
235  /* Priority */
236  substat = X400msListGetIntParam(lr, X400_N_PRIORITY, i, &n);
237  if (substat == X400_E_NOERROR) {
238  printf("Priority = %d\n", n);
239  } else {
240  printf("No priority present \n");
241  }
242 
243  /* Length */
245  &n);
246  if (substat == X400_E_NOERROR) {
247  printf("Content length = %d\n", n);
248  } else {
249  printf("No content length present \n");
250  }
251 
253  buf, 1024, &len);
254  if (substat == X400_E_NOERROR) {
255  printf("Content type = %s\n", buf);
256  } else {
257  printf("No content type present \n");
258  }
259 
260  /* Entry status */
262  &n);
263  if (substat == X400_E_NOERROR) {
264  if ( n == X400_MS_ENTRY_STATUS_NEW ) {
265  printf("MS entry status = %d, (New message)\n", n);
266  } else if ( n == X400_MS_ENTRY_STATUS_LISTED ) {
267  printf("MS entry status = %d, (Message listed)\n", n);
268  } else if ( n == X400_MS_ENTRY_STATUS_FETCHED ) {
269  printf("MS entry status = %d, (Message fetched)\n", n);
270  } else {
271  printf("MS entry status = %d, (Unknown status)\n", n);
272  }
273  } else {
274  printf("No entry status present \n");
275  }
276 
277  if (gen_ipn == 1) {
278  // Fetch and print by sequence number
279  fetch_and_print_msg(sp, seqnum);
280  }
281 
282  i++;
283  }
284 
285  X400msListFree(lr);
286 
287  printf("The list result contained %d entries\n", i-1);
288 
289  status = X400msClose (sp);
290  return (status);
291 }
292 
293 static int fetch_and_print_msg (struct X400msSession *sp,
294  int seqnum)
295 {
296  int type;
297  int seqn;
298  int status;
299  struct X400msMessage *mp;
300  char c;
301  size_t retlen;
302  char *buf = NULL;
303  char *databuf = &c;
304 
305  printf("Getting message\n");
306  status = X400msMsgGet(sp, seqnum, &mp, &type, &seqn);
307  switch (status) {
308  case X400_E_NOERROR:
309  fprintf(stderr, "MsgGet successfully got message; type = %d\n", type);
310  break;
311  default :
312  fprintf(stderr, "Error from MsgGet: %s\n", X400msError(status));
313  /* tidily close the session */
314  status = X400msClose(sp);
315  exit(status);
316  break;
317  }
318 
319  status = print_msg(mp, type);
320  if (status != X400_E_NOERROR) {
321  (void) X400msMsgDelete(mp, 0);
322  X400msClose(sp);
323  exit(status);
324  }
325 
326  /* Get binary representation and store to file */
327 
328  /* First pass to find out how big it needs to be */
329  status = X400msMsgGetRaw(sp, mp, databuf, 0, &retlen);
330  if (status != X400_E_NOSPACE) {
331  fprintf(stderr, "Failed to get raw message length: error %d\n", status);
332  } else {
333  struct X400msMessage *newmsg;
334  int newtype;
335 
336  databuf = buf = (char *)malloc(retlen);
337  printf("Data buffer length required = %d\n", (int)retlen);
338  status = X400msMsgGetRaw(sp, mp, databuf, retlen, &retlen);
339  if (status != X400_E_NOERROR) {
340  fprintf(stderr, "Failed to get raw message: error %d\n", status);
341  } else {
342  /* Dump to file */
343  FILE *fd = fopen("message.dump", "w");
344  if (fd == NULL) {
345  fprintf(stderr, "Failed to open file message.dump\n");
346  } else {
347  if (fwrite(databuf, 1, retlen, fd) < retlen) {
348  fprintf(stderr, "Failed to write message to file message.dump\n");
349  } else {
350  fprintf(stdout, "Dumped message to file message.dump\n");
351  }
352  fclose(fd);
353  }
354  }
355 
356  /* And try to reconstruct message from bytes */
357  status = X400msMsgFromRaw(sp, databuf, retlen, &newmsg, &newtype);
358  if (status != X400_E_NOERROR) {
359  fprintf(stderr, "Failed to create message from bytes: error %d\n", status);
360  }
361 
362  printf("************************** Printing cached message ************************\n");
363  print_msg(newmsg, newtype);
364  if (buf != NULL)
365  free(buf);
366 
367  X400msMsgDelete(newmsg, 0);
368  }
369 
370  /* Deletes message in message store as well as internal copy */
371  printf("\n+++ got message - deleting it and returning+++\n");
372  status = X400msMsgDelete(mp, 0);
373 
374  return status;
375 }
376 
377 
378 
379 static void usage(void) {
380  printf("usage: %s\n", optstr);
381  printf("\t where:\n");
382  printf("\t -u : Don't prompt to override defaults \n");
383  printf("\t -m : OR Address in P7 bind arg \n");
384  printf("\t -p : Presentation Address of P7 Store \n");
385  printf("\t -d : DN in P7 bind arg \n");
386  printf("\t -w : P7 password of P7 user \n");
387  printf("\t -z : List submitted messages\n");
388  printf("\t -n : List messages with status 'new' only\n");
389  printf("\t -T : List messages with delivery time after <UTCTime>\n");
390  printf("\t -V : List messages with delivery time before <UTCTime>\n");
391  printf("\t -S : Specify ms-entry-status value for list operation\n");
392  printf("\t -h : Specify priority value for list operation\n");
393  printf("\t -I : Fetch and delete listed messages\n");
394  return;
395 }
396 
#define X400_S_EXTERNAL_CONTENT_TYPE
Definition: x400_att.h:447
#define X400_E_NO_MORE_RESULTS
Definition: x400_att.h:214
#define X400_S_LOG_CONFIGURATION_FILE
Definition: x400_att.h:1091
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_SUBJECT_IDENTIFIER
Definition: x400_att.h:1038
int X400msListExAuxPriBefore(struct X400msSession *sp, char *since_time, char *before_time, int entryclass, int entrystatus, int priority, struct X400msListResult **lrp)
List messages in the P7 Message Store, specifying entryclass, entrystatus and priority, with before time.
#define X400_N_CONTENT_LENGTH
Definition: x400_att.h:411
void X400msSetConfigRequest(int val)
Disable and enable configuration requests in MS Bind operations.
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_STRICT_P7_1988
Definition: x400_att.h:1268
const char * X400msError(int error)
Obtain a string describing the meaning of the given error code.
int X400msClose(struct X400msSession *sp)
Close a X400 Session.
void X400msListFree(struct X400msListResult *lr)
Free the memory occupied by a ListResult.
#define X400_N_MS_ENTRY_STATUS
Definition: x400_att.h:1228
#define X400_S_OBJECTTYPE
Definition: x400_att.h:470
#define X400_E_NOERROR
Definition: x400_att.h:46
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_S_MESSAGE_IDENTIFIER
Definition: x400_att.h:405
#define X400_N_MS_SEQUENCE_NUMBER
Definition: x400_att.h:1231
int X400msMsgFromRaw(struct X400msSession *sp, char *buffer, size_t buflen, struct X400msMessage **mpp, int *typep)
Reconstruct a message from a binary representation.
#define X400_MS_ENTRY_STATUS_NEW
Definition: x400_att.h:1293
X400 MA/MS (P3/P7) Interface.
#define MS_ENTRY_CLASS_STORED_MESSAGES
Definition: x400_msapi.h:313
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...
#define X400_N_PRIORITY
Definition: x400_att.h:422
int X400msSetIntDefault(struct X400msSession *sp, int paramtype, int value)
Set a default integer 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.
#define X400_MS_ENTRY_STATUS_LISTED
Definition: x400_att.h:1296
#define X400_S_SUBJECT
Definition: x400_att.h:722
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.
#define MS_ENTRY_CLASS_SUBMITTED_MESSAGES
Definition: x400_msapi.h:316
#define X400_E_NOSPACE
Definition: x400_att.h:112
#define X400_S_LIST_ATTR
Definition: x400_att.h:1157
#define X400_MS_ENTRY_STATUS_FETCHED
Definition: x400_att.h:1299
int X400msMsgDelete(struct X400msMessage *mp, int retain)
Delete message object.