x400_mssend.c
1 /*
2  * Copyright (c) 2003-2013, Isode Limited, London, England.
3  * All rights reserved.
4  *
5  * Acquisition and use of this software and related materials for any
6  * purpose requires a written licence agreement from Isode Limited,
7  * or a written licence from an organisation licenced by Isode Limited
8  * to grant such a licence.
9  */
10 
11 /*
12  * @VERSION@
13  * Simple example program for submitting a message via a message store.
14  */
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #ifndef _WIN32
22 #include <unistd.h>
23 #endif
24 #include <fcntl.h>
25 #include <errno.h>
26 
27 #include <x400_msapi.h>
28 #include <seclabel_api.h> /* For security labels */
29 #include "example.h"
30 #include "ms_example.h"
31 #include "time.h"
32 
33 
34 static char *optstr = "u371m:d:p:w:M:D:P:W:o:O:r:l:R:y:C:iaqsAvf:kK:B:";
35 
36 /* These are the data items used to construct the message for submission */
37 static char *default_recip = "/CN=P7User1/O=attlee/PRMD=TestPRMD/ADMD=TestADMD/C=GB/";
38 char *recip;
39 static const char text[] = "First line\r\nSecond line\r\n";
40 static char *binary_data;
41 
42 static char *fwd_subject = "Forwarded message subject";
43 
44 static int add_binary_attachment (
45  struct X400msMessage *mp,
46  char * filename_to_send
47 );
48 static int add_fwd_bp (
49  struct X400msMessage *mp,
50  char *recip_orn,
51  char *recip_dn
52 ) ;
53 static int add_ftbp(
54  struct X400msMessage *mp
55 );
56 static void usage(void) ;
57 
58 
59 int main (
60  int argc,
61  char **argv
62 )
63 {
64  char buffer[BUFSIZ];
65  char pa[BUFSIZ];
66  char orn[BUFSIZ];
67  char tmp[BUFSIZ];
68  int status;
69  struct X400msSession *sp;
70  struct X400msMessage *mp;
71  struct X400Recipient *rp;
72  int contype;
73  char *def_oraddr;
74  char *def_dn;
75  char *def_pa;
76 
77  if (get_args(argc, argv, optstr)) {
78  usage();
79  exit(-1);
80  }
81 
82  printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
83  contype = ic_fgetc(x400_contype, stdin);
84  if (contype != 10)
85  ic_fgetc(x400_contype, stdin);
86 
87  if ( contype < '0' || '2' < contype )
88  contype = x400_contype;
89  else
90  contype -= '0';
91 
92  if (contype == 0) {
93  def_oraddr = x400_ms_user_addr;
94  def_dn = x400_ms_user_dn;
95  def_pa = x400_ms_presentation_address;
96  } else {
97  def_oraddr = x400_mta_user_addr;
98  def_dn = x400_mta_user_dn;
99  def_pa = x400_mta_presentation_address;
100  }
101 
102  printf("Your ORAddress [%s] > ", def_oraddr);
103  ic_fgets (orn, sizeof orn, stdin);
104 
105  if ( (strlen(orn) > 0) && (orn[strlen(orn)-1] == '\n') )
106  orn[strlen(orn)-1] = '\0';
107 
108  if (orn[0] == '\0')
109  strcpy(orn, def_oraddr);
110 
111  /* Prompt for password; note: reflected. */
112  printf ("Password [%s]: ",
113  contype == 0 ? x400_p7_password : x400_p3_password);
114  if ( ic_fgets (buffer, sizeof buffer, stdin) == NULL )
115  exit (1);
116 
117  if ((strlen(buffer) > 0) && (buffer[strlen(buffer)-1] == '\n') )
118  buffer[strlen(buffer)-1] = '\0';
119  if (buffer[0] == '\0')
120  strcpy(buffer, contype == 0 ? x400_p7_password : x400_p3_password);
121 
122  /* Presentation Address */
123  printf("Presentation Address [%s] > ", def_pa);
124  ic_fgets (pa, sizeof pa, stdin);
125 
126  if ( (strlen(pa) > 0) && (pa[strlen(pa)-1] == '\n'))
127  pa[strlen(pa)-1] = '\0';
128 
129  if (pa[0] == '\0')
130  strcpy(pa, def_pa);
131 
132  if (talking_to_marben_ms)
134 
135  /* we've got what we need - now open an API session */
136  status = X400msOpen (contype, orn, def_dn, buffer, pa, NULL, &sp);
137  if ( status != X400_E_NOERROR ) {
138  fprintf (stderr, "Error in Open: %s\n", X400msError (status));
139  exit (status);
140  }
141 
142  if (talking_to_marben_ms)
144 
145  /* setup logging */
146  X400msSetStrDefault(sp, X400_S_LOG_CONFIGURATION_FILE, "x400api.xml", 0);
147 
148  /* Turn on generation of extended-subject heading extension */
150 
151  /* Turn on error on duplicate string attribute setting */
153 
154  /* Configure the character sets to be used for Teletex syntax fields
155  (X400_S_FREE_FORM_NAME, X400_T_TELETEX, X400_S_SUBJECT). If not
156  explicitly configured, the default set of 102, 103, 106, 107
157  will be assumed. The string below adds Cyrillic (8859-5) into the list. */
158  X400msSetStrDefault(sp, X400_S_TELETEX_CHARSETS, "102 103 106 107 144", -1);
159 
160  /* Configure the character sets to be used for Graphic string syntax fields
161  (X400_S_FTBP_APPLICATION_REFERENCE_STR, X400_S_FTBP_CONTENT_DESCRIPTION,
162  X400_S_FTBP_FILENAME). If not explicitly configured, a default of
163  character set 6 (US-ASCII) will be assumed.
164  The string below adds Cyrillic (8859-5) into the list. */
166 
167  if (x400_default_recipient != NULL)
168  recip = x400_default_recipient;
169  else
170  recip = default_recip;
171 
172  printf("Message recipient [%s]: ", recip);
173  ic_fgets (tmp, sizeof tmp, stdin);
174 
175  if ( (strlen(tmp) > 0) && (tmp[strlen(tmp)-1] == '\n') )
176  tmp[strlen(tmp)-1] = '\0';
177  if (strlen(tmp) != 0)
178  recip = strdup(tmp);
179 
180  printf("Subject [%s]: ", subject);
181  ic_fgets (tmp, sizeof tmp, stdin);
182 
183  if ( (strlen(tmp) > 0) && (tmp[strlen(tmp)-1] == '\n') )
184  tmp[strlen(tmp)-1] = '\0';
185  if (strlen(tmp) != 0)
186  subject = strdup(tmp);
187 
188  status = X400msMsgNew (sp, X400_MSG_MESSAGE, &mp);
189  if ( status != X400_E_NOERROR ) {
190  fprintf (stderr, "x400msMsgNew returned error: %s\n", X400msError (status));
191  exit (status);
192  }
193 
194  status = X400msRecipNew (mp, X400_RECIP_STANDARD, &rp);
195  if ( status != X400_E_NOERROR ) {
196  fprintf (stderr, "x400msRecipNew returned error: %s\n", X400msError (status));
197  exit (status);
198  }
199 
200  status = X400msRecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
201  if ( status != X400_E_NOERROR ) {
202  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
203  exit (status);
204  }
205 
206  status = X400msRecipAddStrParam (rp, X400_S_DIRECTORY_NAME, "CN=recipient;c=gb", -1);
207  if ( status != X400_E_NOERROR ) {
208  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
209  exit (status);
210  }
211 
212  status = X400msMsgAddStrParam (mp, X400_S_OR_ADDRESS, orn, -1);
213  if ( status != X400_E_NOERROR ) {
214  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
215  exit (status);
216  }
217 
218  status = X400msMsgAddStrParam (mp, X400_S_DIRECTORY_NAME, "CN=originator;c=gb", -1);
219  if ( status != X400_E_NOERROR ) {
220  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
221  exit (status);
222  }
223 
224  /* Ask for delivery reports */
225  printf("delivery report request %d ( 1 - No, 2 - Yes)\n", x400_dr_req);
226  status = X400msRecipAddIntParam (rp, X400_N_REPORT_REQUEST, x400_dr_req);
227  if ( status != X400_E_NOERROR ) {
228  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
229  exit (status);
230  }
231 
232  /* Ask for read receipts */
233  printf("read notification request %d ( 1 - RN, 2 - NRN, 4 - return of IPM with NRN )\n", x400_rn_req);
234  status = X400msRecipAddIntParam (rp, X400_N_NOTIFICATION_REQUEST, x400_rn_req);
235  if ( status != X400_E_NOERROR ) {
236  fprintf (stderr, "x400msRecipAddIntParam returned error: %s\n", X400msError (status));
237  exit (status);
238  }
239 
240  if (1) {
241  char *contid = "ContID00001";
242 
243  /* Content identifier so we can correlate with submission result */
244  status = X400msMsgAddStrParam(mp, X400_S_CONTENT_IDENTIFIER, contid, -1);
245  if ( status != X400_E_NOERROR ) {
246  fprintf (stderr, "X400msMsgAddIntParam %d returned error: %s\n",
248  exit (status);
249  }
250  }
251 
252  /* content return request on report - 0 = no */
254  if ( status != X400_E_NOERROR ) {
255  fprintf (stderr, "X400msMsgAddIntParam %d returned error: %s\n",
257  exit (status);
258  }
259 
260  /* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
261  printf("message priority is %d ( 0 - normal, 1 - non-urgent, 2 - urgent)\n",
262  x400_default_priority);
263  status = X400msMsgAddIntParam (mp, X400_N_PRIORITY, x400_default_priority);
264  if ( status != X400_E_NOERROR ) return (status);
265 
266  /* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
267  printf("military message priority is %d ( 0 - low, 1 - high)\n",
268  x400_default_priority);
270  if ( status != X400_E_NOERROR ) return (status);
271 
272  /* subject */
273  {
274  time_t t;
275  time(&t);
276  char tmp_buffer[255];
277  // NB strip newline from ctime result
278  snprintf(tmp_buffer, 244, "%s '%s' '%.19s'",
279  subject, get_x400_pty_str_from_4406(x400_default_priority), ctime(&t));
280  printf("Subject is '%s'\n", tmp_buffer);
281  status = X400msMsgAddStrParam (mp, X400_S_SUBJECT, tmp_buffer, -1);
282  if ( status != X400_E_NOERROR ) {
283  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n",
284  X400msError (status));
285  exit (status);
286  }
287  }
288 
289  /* content type */
290  status = X400msMsgAddStrParam (mp, X400_S_EXTERNAL_CONTENT_TYPE, "1.3.26.0.4406.0.4.1", -1);
291  if ( status != X400_E_NOERROR ) {
292  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
293  exit (status);
294  }
295  /* 8859-1 attachment */
296  status = X400msMsgAddStrParam (mp, X400_T_ISO8859_1, text, -1);
297  if ( status != X400_E_NOERROR ) {
298  fprintf (stderr, "x400ms returned error: %s\n", X400msError (status));
299  exit (status);
300  }
301 
302  /* now an IA5 body part using the bodypart func */
303  status = X400msMsgAddAttachment (mp, X400_T_IA5TEXT, text, strlen(text));
304  if ( status != X400_E_NOERROR ) {
305  printf("failed to add X400_T_IA5TEXT BP\n");
306  return (status);
307  }
308 
309  /* or a Binary body part using the bodypart func */
310  if (filename_to_send != NULL) {
311  status = add_binary_attachment (mp, filename_to_send);
312  if ( status != X400_E_NOERROR ) {
313  printf("failed to add X400_T_BINARY BP\n");
314  return (status);
315  }
316  status = add_fwd_bp (mp, orn, def_dn);
317  if ( status != X400_E_NOERROR ) {
318  printf("failed to add forwarded BP\n");
319  return (status);
320  }
321  } else {
322  printf("no binary file set - not sending X400_T_BINARY\n");
323  printf("no binary file set - not sending forwarded BP\n");
324  }
325 
326  /* File Transfer Body Part using the bodypart func */
327  status = add_ftbp(mp);
328  if ( status != X400_E_NOERROR ) {
329  printf("failed to add X400_T_BINARY BP\n");
330  return (status);
331  }
332 
333 
334 #ifdef USE_SEC_LABEL
335  {
336 #define XML_BUFSIZE 1024
337 #define STRING_BUFSIZE 1024
338 
339  const char* xml_filename = "seclabel.xml";
340  char xml_content[XML_BUFSIZE];
341  char str_content[STRING_BUFSIZE];
342  int str_len = STRING_BUFSIZE;
343  FILE *fd = NULL;
344 
345  /* Read in the security label XML file */
346  fd = fopen(xml_filename,"r");
347  if(fd == NULL) {
348  fprintf(stderr,"Failed to open %s : %s\n",
349  xml_filename,strerror(errno));
350  }
351 
352  fread(&xml_content,XML_BUFSIZE,1,fd);
353 
354  fclose(fd);
355 
356  status = SecLabelInit("Example program");
357  if (status != SECLABEL_E_NOERROR) {
358  fprintf(stderr, "SecLabelInit returned error %d\n", status);
359  exit(1);
360  }
361 
362  /* Use SecLabelParse to turn the XML into an octet string */
363  status = SecLabelParse(xml_content,
364  str_content,
365  STRING_BUFSIZE,
366  &str_len);
367 
368  if (status != SECLABEL_E_NOERROR) {
369  fprintf(stderr, "SecLabelParse returned error %d\n", status);
370  exit(1);
371  }
372 
373  /* Add the octet string to the message pointer */
375  str_content,str_len);
376  if ( status != X400_E_NOERROR ) {
377  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
378  exit (status);
379  }
380 
381  }
382 #endif
383 
384  status = X400msMsgSend (mp);
385  if ( status != X400_E_NOERROR ) {
386  fprintf (stderr, "x400msMsgSend returned error: %s\n", X400msError (status));
387 
388  if (status == X400_E_RECIPIENT_ERROR) {
389  int n = 1;
390  struct X400Recipient *irp;
391  int ss = X400_E_NOERROR;
392 
393  while (ss == X400_E_NOERROR) {
394  ss = X400msRecipGet(mp, X400_RECIP_INVALID, n, &irp);
395  if (ss == X400_E_NOERROR) {
396  char buf[1024];
397  size_t retlen;
398  int s;
399 
400  fprintf(stderr, "A recipient with ");
401 
402  s = X400msRecipGetStrParam(irp, X400_S_OR_ADDRESS, buf, 1024, &retlen);
403  if (s == X400_E_NOERROR) {
404  buf[retlen] = '\0';
405  fprintf (stderr, "ORAddress %s ", buf);
406  }
407 
408  s = X400msRecipGetStrParam(irp, X400_S_DIRECTORY_NAME, buf, 1024, &retlen);
409  if (s == X400_E_NOERROR) {
410  buf[retlen] = '\0';
411  fprintf (stderr, " and DN %s", buf);
412  }
413  fprintf (stderr, " was rejected\n");
414  n++;
415  }
416  }
417  }
418 
419  } else {
420  char buf[1024];
421  size_t retlen;
422  char *databuf = buf;
423 
424  printf("Message submitted successfully\n");
425 
426  status = X400msMsgGetStrParam(mp, X400_S_MESSAGE_IDENTIFIER, buf, 1024, &retlen);
427  if (status != X400_E_NOERROR) {
428  fprintf(stderr, "No MessageId present from submission result: error %d\n", status);
429  } else {
430  buf [retlen] = '\0';
431  printf("MessageId from Submission Result = %s\n", buf);
432  }
433 
434  status = X400msMsgGetStrParam(mp, X400_S_MESSAGE_SUBMISSION_TIME, buf, 1024, &retlen);
435  if (status != X400_E_NOERROR) {
436  fprintf(stderr, "No MessageSubmissionTime present from submission result: error %d\n", status);
437  } else {
438  buf [retlen] = '\0';
439  printf("MessageSubmissionTime from Submission Result = %s\n", buf);
440  }
441 
442  status = X400msMsgGetStrParam(mp, X400_S_CONTENT_IDENTIFIER, buf, 1024, &retlen);
443  if (status != X400_E_NOERROR) {
444  fprintf(stderr, "No ContentIdentifier present from submission result: error %d\n", status);
445  } else {
446  buf [retlen] = '\0';
447  printf("ContentIdentifier from Submission Result = %s\n", buf);
448  }
449 
450  /* Get binary representation and store to file */
451 
452  /* First pass to find out how big it needs to be */
453  status = X400msMsgGetRaw(sp, mp, databuf, 0, &retlen);
454  if (status != X400_E_NOSPACE) {
455  fprintf(stderr, "Failed to get raw message length: error %d\n", status);
456  } else {
457  struct X400msMessage *newmsg;
458  int newtype;
459 
460  databuf = (char *)malloc(retlen);
461  printf("Data buffer length required = %d\n", (int)retlen);
462  status = X400msMsgGetRaw(sp, mp, databuf, retlen, &retlen);
463  if (status != X400_E_NOERROR) {
464  fprintf(stderr, "Failed to get raw message: error %d\n", status);
465  } else {
466  /* Dump to file */
467  FILE *fd = fopen("message.dump", "w");
468  if (fd == NULL) {
469  fprintf(stderr, "Failed to open file message.dump\n");
470  } else {
471  if (fwrite(databuf, 1, retlen, fd) < retlen) {
472  fprintf(stderr, "Failed to write message to file message.dump\n");
473  } else {
474  fprintf(stdout, "Dumped message to file message.dump\n");
475  }
476  fclose(fd);
477  }
478  }
479 
480  /* And try to reconstruct message from bytes */
481  status = X400msMsgFromRaw(sp, databuf, retlen, &newmsg, &newtype);
482  if (status != X400_E_NOERROR) {
483  fprintf(stderr, "Failed to create message from bytes: error %d\n", status);
484  }
485 
486  free(databuf);
487  }
488  }
489 
490  status = X400msMsgDelete (mp, 0);
491  if ( status != X400_E_NOERROR ) {
492  fprintf (stderr, "x400msMsgDelete returned error: %s\n", X400msError (status));
493  exit (status);
494  }
495 
496  mp = NULL;
497  rp = NULL;
498 
499  status = X400msClose (sp);
500  exit (status);
501  /* NOTREACHED */
502 }
503 
504 static int add_binary_attachment (
505  struct X400msMessage *mp,
506  char * filename
507 )
508 {
509  int fd;
510  int file_size;
511  struct stat buf;
512  int fs=0;
513  int status;
514 
515  printf("sending file %s\n", filename);
516  if ((fd = open (filename_to_send, O_RDONLY)) == -1) {
517  printf("Failed to open content file %s: ", filename);
518  return X400_E_BADPARAM;
519  }
520 
521 
522  if (fstat(fd, &buf) != 0) {
523  close(fd);
524  printf("Can't fstat file %s %d", filename, errno);
525  return X400_E_BADPARAM;
526  }
527 
528  file_size = buf.st_size;
529  printf("Content file size = %d\n", file_size);
530 
531  binary_data = (char *) malloc(file_size);
532  if ( binary_data == NULL )
533  return X400_E_NOMEMORY;
534 
535  if ((fs = read(fd, binary_data, file_size) ) == -1) {
536  printf("Cannot read from binary file %d\n", errno);
537  return (X400_E_SYSERROR);
538  }
539  close(fd);
540 
541  status = X400msMsgAddAttachment (mp, X400_T_BINARY, binary_data, fs);
542  if ( status != X400_E_NOERROR ) {
543  printf("failed to add X400_T_BINARY BP\n");
544  return (status);
545  }
546  return (status);
547 }
548 
549 static int add_fwd_bp (
550  struct X400msMessage *mp,
551  char *orig_orn,
552  char *orig_dn
553 )
554 {
555  struct X400Message *x400_mp;
556  struct X400Recipient *rp;
557  int status;
558  int num_atts = 0;
559 
560  printf("sending fwd bp \n");
561 
562  status = X400MsgNew (X400_MSG_MESSAGE, &x400_mp);
563  if ( status != X400_E_NOERROR ) {
564  fprintf (stderr, "x400MsgNew returned error: %s\n", X400msError (status));
565  exit (status);
566  }
567 
569  "090909090909Z", (size_t)-1);
570  if ( status != X400_E_NOERROR ) {
571  fprintf (stderr, "x400MsgAddStrParam returned error: %s\n", X400msError (status));
572  exit (status);
573  }
574 
576  "090909090909Z", (size_t)-1);
577  if ( status != X400_E_NOERROR ) {
578  fprintf (stderr, "x400MsgAddStrParam returned error: %s\n", X400msError (status));
579  exit (status);
580  }
581 
582  /* envelope originator OR address */
583  status = X400MsgAddStrParam (x400_mp, X400_S_OR_ADDRESS, orig_orn, (size_t)-1);
584  if ( status != X400_E_NOERROR ) {
585  fprintf (stderr, "x400MsgAddStrParam returned error: %s\n", X400msError (status));
586  exit (status);
587  }
588  status = X400MsgAddStrParam (x400_mp, X400_S_DIRECTORY_NAME, orig_dn, (size_t)-1);
589  if ( status != X400_E_NOERROR ) {
590  fprintf (stderr, "x400MsgAddStrParam returned error: %s\n", X400msError (status));
591  exit (status);
592  }
593 
594  /* add originator into headers */
595  status = X400RecipNew (X400_ORIGINATOR, &rp);
596  if ( status != X400_E_NOERROR ) {
597  fprintf (stderr, "x400RecipNew returned error: %s\n", X400msError (status));
598  exit (status);
599  }
600 
601  /* put in OR Address part of OR Name */
602  status = X400RecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
603  if ( status != X400_E_NOERROR ) {
604  fprintf (stderr, "x400RecipAddStrParam returned error: %s\n", X400msError (status));
605  exit (status);
606  }
607 
608  /* put in DN part of OR Name */
609  status = X400RecipAddStrParam (rp, X400_S_DIRECTORY_NAME, orig_dn, -1);
610  if ( status != X400_E_NOERROR ) {
611  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
612  exit (status);
613  }
614 
615  /* put originator into message */
616  status = X400MsgAddRecip (x400_mp, X400_ORIGINATOR, rp);
617  if ( status != X400_E_NOERROR ) {
618  fprintf (stderr, "X400MsgAddRecip returned error: %s\n", X400msError (status));
619  exit (status);
620  }
621  printf("Put %s in as originator\n", orig_orn);
622 
623  /* add a recipient */
624  status = X400RecipNew (X400_RECIP_STANDARD, &rp);
625  if ( status != X400_E_NOERROR ) {
626  fprintf (stderr, "x400RecipNew returned error: %s\n", X400msError (status));
627  exit (status);
628  }
629 
630  status = X400RecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
631  if ( status != X400_E_NOERROR ) {
632  fprintf (stderr, "x400RecipAddStrParam returned error: %s\n", X400msError (status));
633  exit (status);
634  }
635 
636  status = X400RecipAddStrParam (rp, X400_S_DIRECTORY_NAME, "CN=recipient;c=gb", -1);
637  if ( status != X400_E_NOERROR ) {
638  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
639  exit (status);
640  }
641 
642  status = X400MsgAddRecip (x400_mp, X400_RECIP_STANDARD, rp);
643  if ( status != X400_E_NOERROR ) {
644  fprintf (stderr, "X400MsgAddRecip returned error: %s\n", X400msError (status));
645  exit (status);
646  }
647  printf("Put %s in as reipient\n", recip);
648 
649 
650  /* Add 2nd recipient */
651  status = X400RecipNew (X400_RECIP_STANDARD, &rp);
652  if ( status != X400_E_NOERROR ) {
653  fprintf (stderr, "x400RecipNew returned error: %s\n", X400msError (status));
654  exit (status);
655  }
656 
657  status = X400RecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
658  if ( status != X400_E_NOERROR ) {
659  fprintf (stderr, "x400RecipAddStrParam returned error: %s\n", X400msError (status));
660  exit (status);
661  }
662 
663  status = X400RecipAddStrParam (rp, X400_S_DIRECTORY_NAME, "CN=second recipient;c=gb", -1);
664  if ( status != X400_E_NOERROR ) {
665  fprintf (stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError (status));
666  exit (status);
667  }
668 
669 
670  /* put recipient into message */
671  status = X400MsgAddRecip (x400_mp, X400_RECIP_STANDARD, rp);
672  if ( status != X400_E_NOERROR ) {
673  fprintf (stderr, "X400MsgAddRecip returned error: %s\n", X400msError (status));
674  exit (status);
675  }
676  printf("Put %s in as reipient\n", recip);
677 
678 
679  /* envelope */
680 
681  /* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
682  printf("message priority is %d ( 0 - normal, 1 - non-urgent, 2 - urgent)\n",
683  x400_default_priority);
684  status = X400MsgAddIntParam (x400_mp, X400_N_PRIORITY, x400_default_priority);
685  if ( status != X400_E_NOERROR ) return (status);
686 
687  /* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
688  printf("military message priority is %d ( 0 - low, 1 - high)\n",
689  x400_default_priority);
690  status = X400MsgAddIntParam (x400_mp, X400_N_MMTS_PRIORITY_QUALIFIER, 1);
691  if ( status != X400_E_NOERROR ) return (status);
692 
693  /* content */
694  /* subject */
695  status = X400MsgAddStrParam (x400_mp, X400_S_SUBJECT, fwd_subject, (size_t)-1);
696  if ( status != X400_E_NOERROR ) {
697  fprintf (stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError (status));
698  exit (status);
699  }
700 
701  /* now an IA5 body part using the bodypart func */
702  status = X400MsgAddAttachment (x400_mp, X400_T_IA5TEXT, text, strlen(text));
703  if ( status != X400_E_NOERROR ) {
704  printf("failed to add X400_T_IA5TEXT BP\n");
705  return (status);
706  }
707  num_atts++;
708 
709  /* 8859-1 attachment */
710  status = X400MsgAddStrParam (x400_mp, X400_T_ISO8859_1, text, (size_t)-1);
711  if ( status != X400_E_NOERROR ) {
712  fprintf (stderr, "x400ms returned error: %s\n", X400msError (status));
713  exit (status);
714  }
715  num_atts++;
716 
717  status = X400MsgAddIntParam (x400_mp, X400_N_NUM_ATTACHMENTS, num_atts);
718  if (status != X400_E_NOERROR )
719  return (status);
720 
721  status = X400msMsgAddMessageBody (mp, x400_mp);
722  if (status != X400_E_NOERROR ) {
723  fprintf (stderr, "X400msMsgAddMessageBody returned error: %s\n", X400msError (status));
724  return (status);
725  }
726 
727  return X400_E_NOERROR;
728 }
729 
730 
731 static int add_ftbp(
732  struct X400msMessage *mp
733 )
734 {
735  FILE *fp = NULL;
736  int fs=0;
737  char *binary_data;
738  int status;
739  struct X400Bodypart *bp;
740 
741  /* Add FTBP using the bodypart func */
742  if (filename_to_send == NULL) {
743  printf("no file set - not sending X400_T_FTBP\n");
744  return X400_E_NOERROR;
745  }
746  fp = fopen(filename_to_send, "rb");
747  if (fp == (FILE *)NULL) {
748  printf("Cannot open binary file\n");
749  return (X400_E_SYSERROR);
750  }
751  binary_data = (char *) malloc(bin_bp_size);
752  if ( binary_data == NULL )
753  return X400_E_NOMEMORY;
754  if ((fs = fread (binary_data, sizeof(char),
755  bin_bp_size/sizeof(char), fp) ) == -1) {
756  printf("Cannot read from binary file\n");
757  free (binary_data);
758  fclose(fp);
759  return (X400_E_SYSERROR);
760  }
761  fclose(fp);
762  if (fs < bin_bp_size) {
763  printf("Cannot read %d bytes from binary file (got %d)\n",
764  bin_bp_size, fs);
765  free (binary_data);
766  return (X400_E_SYSERROR);
767  }
768 
770  X400BodypartAddStrParam(bp, X400_S_BODY_DATA, binary_data, fs);
772  "Test FTBP File", -1);
773  /* NB this value should have the filename, but not the full path */
774  /* And on Windows backslashes must be escaped with a second backslash */
775  X400BodypartAddStrParam(bp, X400_S_FTBP_FILENAME, filename_to_send, -1);
777  "20230801060101.0Z", -1);
779  "20230801060202.0Z", -1);
781  status = X400msMsgAddBodypart(mp, bp);
782  free (binary_data);
783 
784  if ( status != X400_E_NOERROR ) {
785  printf("failed to add X400_T_FTBP BP\n");
786  return (status);
787  }
788  printf("Sent %d bytes as X400_T_FTBP BP\n", fs);
789  return X400_E_NOERROR;
790 }
791 
792 static void usage(void) {
793  printf("usage: %s\n", optstr);
794  printf("\t where:\n");
795  printf("\t -u : Don't prompt to override defaults \n");
796  printf("\t -3 : Use P3 connection \n");
797  printf("\t -7 : Use P7 connection \n");
798  printf("\t -1 : Use Marben-compatibility mode for P7 connection \n");
799  printf("\t -m : OR Address in P7 bind arg \n");
800  printf("\t -d : DN in P7 bind arg \n");
801  printf("\t -p : Presentation Address of P7 Store \n");
802  printf("\t -w : P7 password of P7 user \n");
803  printf("\t -M : OR Address in P3 bind arg \n");
804  printf("\t -D : DN in P3 bind arg \n");
805  printf("\t -P : Presentation Address of P3 server\n");
806  printf("\t -W : P3 password of P3 user \n");
807  printf("\t -o : Originator \n");
808  printf("\t -O : Originator Return Address \n");
809  printf("\t -r : Recipient\n");
810  printf("\t -l : Logline\n");
811  printf("\t -R : Report setting: 0=none, 1=-ve, 2=+ve\n");
812  printf("\t -y : Military Priority \n");
813  printf("\t\t 0 - deferred, 1 - routine, 2 - priority \n");
814  printf("\t\t 3 - immediate, 4 - flash, 5 - override \n");
815  printf("\t -C : Content Type (2/22/772/OID) \n");
816  printf("\t -i : Implicit conversion prohibited = TRUE \n");
817  printf("\t -a : Alternate Recipient Prohibited = TRUE \n");
818  printf("\t -q : Content Return Request = TRUE \n");
819  printf("\t -s : Disclosure of Recipient = FALSE \n");
820  printf("\t -A : Recipient Reassignment Prohibited = FALSE \n");
821  printf("\t -v : Conversion with Loss Prohibited = FALSE \n");
822  printf("\t -f : Filename to transfer as binary bp\n");
823  printf("\t -k : Request Delivery Report\n");
824  printf("\t -K : Request Read Notification ( 1 - RN, 2 - NRN, 4 - return of IPM with NRN )\n");
825  printf("\t -B : Set alternative subject line \n");
826  return;
827 }
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
int X400BodypartNew(int type, struct X400Bodypart **bpp)
Create a new body part object.
int X400msMsgSend(struct X400msMessage *mp)
Send message object.
#define X400_N_CONTENT_RETURN_REQUEST
Definition: x400_att.h:436
#define X400_S_BODY_DATA
Definition: x400_att.h:1170
int X400msMsgAddAttachment(struct X400msMessage *mp, int type, const char *string, size_t length)
Add attachment to the message.
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_GRAPHIC_CHARSETS
Definition: x400_att.h:1144
#define X400_S_FTBP_CONTENT_DESCRIPTION
Definition: x400_att.h:1200
int X400MsgAddIntParam(struct X400Message *mp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400msSetStrDefault(struct X400msSession *sp, int paramtype, const char *value, size_t length)
Set a default string parameter value in a session.
int X400msMsgAddBodypart(struct X400msMessage *mp, struct X400Bodypart *bp)
#define X400_N_NUM_ATTACHMENTS
Definition: x400_att.h:796
#define X400_S_SECURITY_LABEL
Definition: x400_att.h:1348
int X400BodypartAddIntParam(struct X400Bodypart *bp, int paramtype, int value)
Add integer-valued parameter to the body part.
int X400msClose(struct X400msSession *sp)
Close a X400 Session.
#define X400_E_RECIPIENT_ERROR
Definition: x400_att.h:157
int X400msMsgAddIntParam(struct X400msMessage *mp, int paramtype, int value)
Add integer-valued parameter to the message.
#define X400_T_BINARY
Definition: x400_att.h:825
int X400msRecipAddIntParam(struct X400Recipient *rp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400msRecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
#define X400_S_DIRECTORY_NAME
Definition: x400_att.h:397
#define X400_N_PRIORITY
Definition: x400_att.h:422
int X400MsgAddRecip(struct X400Message *mp, int reciptype, struct X400Recipient *recip)
Add a recipient object to the message.
int X400RecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the recipient.
#define X400_S_MESSAGE_DELIVERY_TIME
Definition: x400_att.h:442
#define X400_ORIGINATOR
Definition: x400_att.h:305
int X400msRecipNew(struct X400msMessage *mp, int type, struct X400Recipient **rpp)
Add new recipient to a message.
#define X400_T_ISO8859_1
Definition: x400_att.h:809
int X400RecipNew(int type, struct X400Recipient **rpp)
Create a new recipient object.
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_S_FTBP_CREATION_DATE
Definition: x400_att.h:1206
#define X400_S_FTBP_MODIFICATION_DATE
Definition: x400_att.h:1209
#define X400_RECIP_STANDARD
Definition: x400_att.h:341
#define X400_N_MMTS_PRIORITY_QUALIFIER
Definition: x400_att.h:473
int X400msMsgNew(struct X400msSession *sp, int type, struct X400msMessage **mpp)
Creates new message.
#define X400_N_USE_EXTENDED_SUBJECT
Definition: x400_att.h:1276
#define X400_S_CONTENT_IDENTIFIER
Definition: x400_att.h:414
#define X400_S_MESSAGE_IDENTIFIER
Definition: x400_att.h:405
#define X400_E_NOERROR
Definition: x400_att.h:46
#define X400_N_REPORT_REQUEST
Definition: x400_att.h:654
int X400msMsgFromRaw(struct X400msSession *sp, char *buffer, size_t buflen, struct X400msMessage **mpp, int *typep)
Reconstruct a message from a binary representation.
int X400msRecipGet(struct X400msMessage *mp, int type, int number, struct X400Recipient **rpp)
Get recipient object from message.
int X400msRecipGetStrParam(struct X400Recipient *rp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the recipient object.
#define X400_S_EXTERNAL_CONTENT_TYPE
Definition: x400_att.h:447
X400 MA/MS (P3/P7) Interface.
#define X400_N_FTBP_OBJECT_SIZE
Definition: x400_att.h:1215
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 X400MsgAddStrParam(struct X400Message *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400msMsgAddMessageBody(struct X400msMessage *mp, struct X400Message *mbp)
#define X400_E_BADPARAM
Definition: x400_att.h:55
int X400MsgAddAttachment(struct X400Message *mp, int type, const char *string, size_t length)
Add an attachment to the message.
int X400msSetIntDefault(struct X400msSession *sp, int paramtype, int value)
Set a default integer parameter value in a session.
#define X400_S_FTBP_FILENAME
Definition: x400_att.h:1203
#define X400_T_FTBP
Definition: x400_att.h:834
#define X400_S_SUBJECT
Definition: x400_att.h:723
#define X400_RECIP_INVALID
Definition: x400_att.h:338
#define X400_N_NOTIFICATION_REQUEST
Definition: x400_att.h:676
int X400MsgNew(int type, struct X400Message **mpp)
Creates new message.
#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.
#define X400_N_ERROR_DUPLICATE_ATTRIBUTE
Definition: x400_att.h:1283
int X400msMsgAddStrParam(struct X400msMessage *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400BodypartAddStrParam(struct X400Bodypart *bp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the body part.
#define X400_MSG_MESSAGE
Definition: x400_att.h:29
#define X400_E_NOMEMORY
Definition: x400_att.h:52
#define X400_E_SYSERROR
Definition: x400_att.h:49
#define X400_E_NOSPACE
Definition: x400_att.h:112
#define X400_S_OR_ADDRESS
Definition: x400_att.h:349
int X400msMsgDelete(struct X400msMessage *mp, int retain)
Delete message object.
#define X400_S_TELETEX_CHARSETS
Definition: x400_att.h:1151