examples/x400_mssend.c

This is an example program which submits a message either indirectly via the P7 Message Store or directly to the MTA's P3 responder.

/*
* Copyright (c) 2003-2026, Isode Limited, London, England.
* All rights reserved.
*
* Acquisition and use of this software and related materials for any
* purpose requires a written licence agreement from Isode Limited,
* or a written licence from an organisation licenced by Isode Limited
* to grant such a licence.
*/
/*
* @VERSION@
* Simple example program for submitting a message via a message store.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include "example.h"
#include "ms_example.h"
#include "time.h"
#include <errno.h>
#include <fcntl.h>
#include <seclabel_api.h> /* For security labels */
#include <x400_msapi.h>
static char *optstr = "u371m:d:p:w:M:D:P:W:o:O:r:l:R:y:C:iaqsAvf:kK:B:";
/* These are the data items used to construct the message for submission */
static char *default_recip = "/CN=P7User1/O=attlee/PRMD=TestPRMD/ADMD=TestADMD/C=GB/";
char *recip;
static const char text[] = "First line\r\nSecond line\r\n";
static char *binary_data;
static char *fwd_subject = "Forwarded message subject";
static int add_binary_attachment(struct X400msMessage *mp, char *filename_to_send);
static int add_fwd_bp(struct X400msMessage *mp, char *recip_orn, char *recip_dn);
static int add_ftbp(struct X400msMessage *mp);
static void usage(void);
int main(int argc, char **argv) {
char creds[BUFSIZ];
char pa[BUFSIZ];
char orn[BUFSIZ];
char tmp[BUFSIZ];
int status;
struct X400msSession *sp;
struct X400msMessage *mp;
struct X400Recipient *rp;
int contype;
char *def_oraddr;
char *def_dn;
char *def_pa;
if (get_args(argc, argv, optstr)) {
usage();
exit(-1);
}
printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
contype = ic_fgetc(x400_contype, stdin);
if (contype != 10) {
ic_fgetc(x400_contype, stdin);
}
if (contype < '0' || '2' < contype) {
contype = x400_contype;
}
else {
contype -= '0';
}
if (contype == 0) {
def_oraddr = x400_ms_user_addr;
def_dn = x400_ms_user_dn;
def_pa = x400_ms_presentation_address;
}
else {
def_oraddr = x400_mta_user_addr;
def_dn = x400_mta_user_dn;
def_pa = x400_mta_presentation_address;
}
printf("Your ORAddress [%s] > ", def_oraddr);
ic_fgets(orn, sizeof orn, stdin);
if ((strlen(orn) > 0) && (orn[strlen(orn) - 1] == '\n')) {
orn[strlen(orn) - 1] = '\0';
}
if (orn[0] == '\0') {
strcpy(orn, def_oraddr);
}
// Prompt for password; note: reflected.
printf("Password [%s]: ", contype == 0 ? x400_p7_password : x400_p3_password);
if (ic_fgets(creds, sizeof(creds), stdin) == NULL) {
exit(1);
}
if ((strlen(creds) > 0) && (creds[strlen(creds) - 1] == '\n')) {
creds[strlen(creds) - 1] = '\0';
}
if (creds[0] == '\0') {
strcpy(creds, contype == 0 ? x400_p7_password : x400_p3_password);
}
// Presentation Address.
printf("Presentation Address [%s] > ", def_pa);
ic_fgets(pa, sizeof pa, stdin);
if ((strlen(pa) > 0) && (pa[strlen(pa) - 1] == '\n')) {
pa[strlen(pa) - 1] = '\0';
}
if (pa[0] == '\0') {
strcpy(pa, def_pa);
}
if (talking_to_marben_ms) {
}
/*
By default (an industry norm) the simple bind response password (mtaPassword) for the MTA is never checked.
We can force this checking by setting the mtaPassword parameter when building the simple authentication credentials.
If we tokenise the credentials and the mtaPassword is NULL or empty, we skip the test, and just accept whatever is returned.
Example 1:
char* creds = X400msBuildCredentials(0, pass, "MTAPassword", NULL, NULL, NULL, NULL, NULL);
and passing creds as the credentials argument to X400msOpen() will check if the returned password matches "MTAPassword".
Example 2:
char* creds = X400msBuildCredentials(0, pass, NULL, NULL, NULL, NULL, NULL, NULL);
and passing creds as the credentials argument to X400msOpen(), or just passing the plain pass as the credentials argument to x400_ms_open() will skip the test.
The creds pointer must be freed in both cases.
*/
// We've got what we need - now open an API session.
status = X400msOpen(contype, orn, def_dn, creds, pa, NULL, &sp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "Error in Open: %s\n", X400msError(status));
exit(status);
}
if (talking_to_marben_ms) {
}
/* setup logging */
/* Turn on generation of extended-subject heading extension */
/* Turn on error on duplicate string attribute setting */
/* Configure the character sets to be used for Teletex syntax fields
(X400_S_FREE_FORM_NAME, X400_T_TELETEX, X400_S_SUBJECT). If not
explicitly configured, the default set of 102, 103, 106, 107
will be assumed. The string below adds Cyrillic (8859-5) into the list. */
X400msSetStrDefault(sp, X400_S_TELETEX_CHARSETS, "102 103 106 107 144", -1);
/* Configure the character sets to be used for Graphic string syntax fields
(X400_S_FTBP_APPLICATION_REFERENCE_STR, X400_S_FTBP_CONTENT_DESCRIPTION,
X400_S_FTBP_FILENAME). If not explicitly configured, a default of
character set 6 (US-ASCII) will be assumed.
The string below adds Cyrillic (8859-5) into the list. */
if (x400_default_recipient != NULL) {
recip = x400_default_recipient;
}
else {
recip = default_recip;
}
printf("Message recipient [%s]: ", recip);
ic_fgets(tmp, sizeof tmp, stdin);
if ((strlen(tmp) > 0) && (tmp[strlen(tmp) - 1] == '\n')) {
tmp[strlen(tmp) - 1] = '\0';
}
if (strlen(tmp) != 0) {
recip = strdup(tmp);
}
printf("Subject [%s]: ", subject);
ic_fgets(tmp, sizeof tmp, stdin);
if ((strlen(tmp) > 0) && (tmp[strlen(tmp) - 1] == '\n')) {
tmp[strlen(tmp) - 1] = '\0';
}
if (strlen(tmp) != 0) {
subject = strdup(tmp);
}
status = X400msMsgNew(sp, X400_MSG_MESSAGE, &mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msRecipNew(mp, X400_RECIP_STANDARD, &rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msRecipAddStrParam(rp, X400_S_OR_ADDRESS, recip, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msRecipAddStrParam(rp, X400_S_DIRECTORY_NAME, "CN=recipient;c=gb", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msMsgAddStrParam(mp, X400_S_OR_ADDRESS, orn, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400msMsgAddStrParam(mp, X400_S_DIRECTORY_NAME, "CN=originator;c=gb", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* Ask for delivery reports */
printf("delivery report request %d ( 1 - No, 2 - Yes)\n", x400_dr_req);
status = X400msRecipAddIntParam(rp, X400_N_REPORT_REQUEST, x400_dr_req);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* Ask for read receipts */
printf("read notification request %d ( 1 - RN, 2 - NRN, 4 - return of IPM with NRN )\n", x400_rn_req);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddIntParam returned error: %s\n", X400msError(status));
exit(status);
}
if (1) {
char *contid = "ContID00001";
/* Content identifier so we can correlate with submission result */
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400msMsgAddIntParam %d returned error: %s\n", X400_S_CONTENT_IDENTIFIER, X400msError(status));
exit(status);
}
}
/* content return request on report - 0 = no */
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400msMsgAddIntParam %d returned error: %s\n", X400_N_CONTENT_RETURN_REQUEST, X400msError(status));
exit(status);
}
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
printf("message priority is %d ( 0 - normal, 1 - non-urgent, 2 - urgent)\n", x400_default_priority);
status = X400msMsgAddIntParam(mp, X400_N_PRIORITY, x400_default_priority);
if (status != X400_E_NOERROR) {
return (status);
}
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
printf("military message priority is %d ( 0 - low, 1 - high)\n", x400_default_priority);
if (status != X400_E_NOERROR) {
return (status);
}
/* subject */
{
time_t t;
time(&t);
char tmp_buffer[255];
// NB strip newline from ctime result
snprintf(tmp_buffer, 244, "%s '%s' '%.19s'", subject, get_x400_pty_str_from_4406(x400_default_priority), ctime(&t));
printf("Subject is '%s'\n", tmp_buffer);
status = X400msMsgAddStrParam(mp, X400_S_SUBJECT, tmp_buffer, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
}
status = add_sec_label(mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "Failed to add Security Label: %s\n", X400msError(status));
return (status);
}
else {
fprintf(stderr, "added Security Label\n");
}
/* content type */
status = X400msMsgAddStrParam(mp, X400_S_EXTERNAL_CONTENT_TYPE, "1.3.26.0.4406.0.4.1", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* 8859-1 attachment */
status = X400msMsgAddStrParam(mp, X400_T_ISO8859_1, text, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400ms returned error: %s\n", X400msError(status));
exit(status);
}
/* now an IA5 body part using the bodypart func */
status = X400msMsgAddAttachment(mp, X400_T_IA5TEXT, text, strlen(text));
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_IA5TEXT BP\n");
return (status);
}
/* or a Binary body part using the bodypart func */
if (filename_to_send != NULL) {
status = add_binary_attachment(mp, filename_to_send);
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_BINARY BP\n");
return (status);
}
status = add_fwd_bp(mp, orn, def_dn);
if (status != X400_E_NOERROR) {
printf("failed to add forwarded BP\n");
return (status);
}
}
else {
printf("no binary file set - not sending X400_T_BINARY\n");
printf("no binary file set - not sending forwarded BP\n");
}
/* File Transfer Body Part using the bodypart func */
status = add_ftbp(mp);
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_BINARY BP\n");
return (status);
}
#ifdef USE_SEC_LABEL
{
#define XML_BUFSIZE 1024
#define STRING_BUFSIZE 1024
const char *xml_filename = "seclabel.xml";
char xml_content[XML_BUFSIZE];
char str_content[STRING_BUFSIZE];
int str_len = STRING_BUFSIZE;
FILE *fd = NULL;
/* Read in the security label XML file */
fd = fopen(xml_filename, "r");
if (fd == NULL) {
fprintf(stderr, "Failed to open %s : %s\n", xml_filename, strerror(errno));
}
fread(&xml_content, XML_BUFSIZE, 1, fd);
fclose(fd);
status = SecLabelInit("Example program");
if (status != SECLABEL_E_NOERROR) {
fprintf(stderr, "SecLabelInit returned error %d\n", status);
exit(1);
}
/* Use SecLabelParse to turn the XML into an octet string */
status = SecLabelParse(xml_content, str_content, STRING_BUFSIZE, &str_len);
if (status != SECLABEL_E_NOERROR) {
fprintf(stderr, "SecLabelParse returned error %d\n", status);
exit(1);
}
/* Add the octet string to the message pointer */
status = X400msMsgAddStrParam(mp, X400_S_SECURITY_LABEL, str_content, str_len);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
}
#endif
status = X400msMsgSend(mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgSend returned error: %s\n", X400msError(status));
if (status == X400_E_RECIPIENT_ERROR) {
int n = 1;
struct X400Recipient *irp;
int ss = X400_E_NOERROR;
while (ss == X400_E_NOERROR) {
ss = X400msRecipGet(mp, X400_RECIP_INVALID, n, &irp);
if (ss == X400_E_NOERROR) {
char buf[1024];
size_t retlen;
int s;
fprintf(stderr, "A recipient with ");
s = X400msRecipGetStrParam(irp, X400_S_OR_ADDRESS, buf, 1024, &retlen);
if (s == X400_E_NOERROR) {
buf[retlen] = '\0';
fprintf(stderr, "ORAddress %s ", buf);
}
s = X400msRecipGetStrParam(irp, X400_S_DIRECTORY_NAME, buf, 1024, &retlen);
if (s == X400_E_NOERROR) {
buf[retlen] = '\0';
fprintf(stderr, " and DN %s", buf);
}
fprintf(stderr, " was rejected\n");
n++;
}
}
}
}
else {
char buf[1024];
size_t retlen;
char *databuf = buf;
printf("Message submitted successfully\n");
status = X400msMsgGetStrParam(mp, X400_S_MESSAGE_IDENTIFIER, buf, 1024, &retlen);
if (status != X400_E_NOERROR) {
fprintf(stderr, "No MessageId present from submission result: error %d\n", status);
}
else {
buf[retlen] = '\0';
printf("MessageId from Submission Result = %s\n", buf);
}
status = X400msMsgGetStrParam(mp, X400_S_MESSAGE_SUBMISSION_TIME, buf, 1024, &retlen);
if (status != X400_E_NOERROR) {
fprintf(stderr, "No MessageSubmissionTime present from submission result: error %d\n", status);
}
else {
buf[retlen] = '\0';
printf("MessageSubmissionTime from Submission Result = %s\n", buf);
}
status = X400msMsgGetStrParam(mp, X400_S_CONTENT_IDENTIFIER, buf, 1024, &retlen);
if (status != X400_E_NOERROR) {
fprintf(stderr, "No ContentIdentifier present from submission result: error %d\n", status);
}
else {
buf[retlen] = '\0';
printf("ContentIdentifier from Submission Result = %s\n", buf);
}
/* Get binary representation and store to file */
/* First pass to find out how big it needs to be */
status = X400msMsgGetRaw(sp, mp, databuf, 0, &retlen);
if (status != X400_E_NOSPACE) {
fprintf(stderr, "Failed to get raw message length: error %d\n", status);
}
else {
struct X400msMessage *newmsg;
int newtype;
databuf = (char *)malloc(retlen);
printf("Data buffer length required = %d\n", (int)retlen);
status = X400msMsgGetRaw(sp, mp, databuf, retlen, &retlen);
if (status != X400_E_NOERROR) {
fprintf(stderr, "Failed to get raw message: error %d\n", status);
}
else {
/* Dump to file */
FILE *fd = fopen("message.dump", "w");
if (fd == NULL) {
fprintf(stderr, "Failed to open file message.dump\n");
}
else {
if (fwrite(databuf, 1, retlen, fd) < retlen) {
fprintf(stderr, "Failed to write message to file message.dump\n");
}
else {
fprintf(stdout, "Dumped message to file message.dump\n");
}
fclose(fd);
}
}
/* And try to reconstruct message from bytes */
status = X400msMsgFromRaw(sp, databuf, retlen, &newmsg, &newtype);
if (status != X400_E_NOERROR) {
fprintf(stderr, "Failed to create message from bytes: error %d\n", status);
}
free(databuf);
}
}
status = X400msMsgDelete(mp, 0);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgDelete returned error: %s\n", X400msError(status));
exit(status);
}
mp = NULL;
rp = NULL;
status = X400msClose(sp);
exit(status);
/* NOTREACHED */
}
static int add_binary_attachment(struct X400msMessage *mp, char *filename) {
int fd;
int file_size;
struct stat buf;
int fs = 0;
int status;
printf("sending file %s\n", filename);
if ((fd = open(filename_to_send, O_RDONLY)) == -1) {
printf("Failed to open content file %s: ", filename);
}
if (fstat(fd, &buf) != 0) {
close(fd);
printf("Can't fstat file %s %d", filename, errno);
}
file_size = buf.st_size;
printf("Content file size = %d\n", file_size);
binary_data = (char *)malloc(file_size);
if (binary_data == NULL) {
}
if ((fs = read(fd, binary_data, file_size)) == -1) {
printf("Cannot read from binary file %d\n", errno);
return (X400_E_SYSERROR);
}
close(fd);
status = X400msMsgAddAttachment(mp, X400_T_BINARY, binary_data, fs);
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_BINARY BP\n");
return (status);
}
return (status);
}
static int add_fwd_bp(struct X400msMessage *mp, char *orig_orn, char *orig_dn) {
struct X400Message *x400_mp;
struct X400Recipient *rp;
int status;
int num_atts = 0;
printf("sending fwd bp \n");
status = X400MsgNew(X400_MSG_MESSAGE, &x400_mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400MsgAddStrParam(x400_mp, X400_S_MESSAGE_DELIVERY_TIME, "090909090909Z", (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400MsgAddStrParam(x400_mp, X400_S_MESSAGE_SUBMISSION_TIME, "090909090909Z", (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* envelope originator OR address */
status = X400MsgAddStrParam(x400_mp, X400_S_OR_ADDRESS, orig_orn, (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400MsgAddStrParam(x400_mp, X400_S_DIRECTORY_NAME, orig_dn, (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400MsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* add originator into headers */
status = X400RecipNew(X400_ORIGINATOR, &rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipNew returned error: %s\n", X400msError(status));
exit(status);
}
/* put in OR Address part of OR Name */
status = X400RecipAddStrParam(rp, X400_S_OR_ADDRESS, recip, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* put in DN part of OR Name */
status = X400RecipAddStrParam(rp, X400_S_DIRECTORY_NAME, orig_dn, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* put originator into message */
status = X400MsgAddRecip(x400_mp, X400_ORIGINATOR, rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400MsgAddRecip returned error: %s\n", X400msError(status));
exit(status);
}
printf("Put %s in as originator\n", orig_orn);
/* add a recipient */
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400RecipAddStrParam(rp, X400_S_OR_ADDRESS, recip, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400RecipAddStrParam(rp, X400_S_DIRECTORY_NAME, "CN=recipient;c=gb", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400MsgAddRecip(x400_mp, X400_RECIP_STANDARD, rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400MsgAddRecip returned error: %s\n", X400msError(status));
exit(status);
}
printf("Put %s in as reipient\n", recip);
/* Add 2nd recipient */
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipNew returned error: %s\n", X400msError(status));
exit(status);
}
status = X400RecipAddStrParam(rp, X400_S_OR_ADDRESS, recip, -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400RecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
status = X400RecipAddStrParam(rp, X400_S_DIRECTORY_NAME, "CN=second recipient;c=gb", -1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msRecipAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* put recipient into message */
status = X400MsgAddRecip(x400_mp, X400_RECIP_STANDARD, rp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400MsgAddRecip returned error: %s\n", X400msError(status));
exit(status);
}
printf("Put %s in as reipient\n", recip);
/* envelope */
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
printf("message priority is %d ( 0 - normal, 1 - non-urgent, 2 - urgent)\n", x400_default_priority);
status = X400MsgAddIntParam(x400_mp, X400_N_PRIORITY, x400_default_priority);
if (status != X400_E_NOERROR) {
return (status);
}
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
printf("military message priority is %d ( 0 - low, 1 - high)\n", x400_default_priority);
if (status != X400_E_NOERROR) {
return (status);
}
/* content */
/* subject */
status = X400MsgAddStrParam(x400_mp, X400_S_SUBJECT, fwd_subject, (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400msMsgAddStrParam returned error: %s\n", X400msError(status));
exit(status);
}
/* now an IA5 body part using the bodypart func */
status = X400MsgAddAttachment(x400_mp, X400_T_IA5TEXT, text, strlen(text));
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_IA5TEXT BP\n");
return (status);
}
num_atts++;
/* 8859-1 attachment */
status = X400MsgAddStrParam(x400_mp, X400_T_ISO8859_1, text, (size_t)-1);
if (status != X400_E_NOERROR) {
fprintf(stderr, "x400ms returned error: %s\n", X400msError(status));
exit(status);
}
num_atts++;
status = X400MsgAddIntParam(x400_mp, X400_N_NUM_ATTACHMENTS, num_atts);
if (status != X400_E_NOERROR) {
return (status);
}
status = X400msMsgAddMessageBody(mp, x400_mp);
if (status != X400_E_NOERROR) {
fprintf(stderr, "X400msMsgAddMessageBody returned error: %s\n", X400msError(status));
return (status);
}
}
static int add_ftbp(struct X400msMessage *mp) {
FILE *fp = NULL;
int fs = 0;
char *binary_data;
int status;
struct X400Bodypart *bp;
/* Add FTBP using the bodypart func */
if (filename_to_send == NULL) {
printf("no file set - not sending X400_T_FTBP\n");
}
fp = fopen(filename_to_send, "rb");
if (fp == (FILE *)NULL) {
printf("Cannot open binary file\n");
return (X400_E_SYSERROR);
}
binary_data = (char *)malloc(bin_bp_size);
if (binary_data == NULL) {
}
if ((fs = fread(binary_data, sizeof(char), bin_bp_size / sizeof(char), fp)) == -1) {
printf("Cannot read from binary file\n");
free(binary_data);
fclose(fp);
return (X400_E_SYSERROR);
}
fclose(fp);
if (fs < bin_bp_size) {
printf("Cannot read %d bytes from binary file (got %d)\n", bin_bp_size, fs);
free(binary_data);
return (X400_E_SYSERROR);
}
/* NB this value should have the filename, but not the full path */
/* And on Windows backslashes must be escaped with a second backslash */
X400BodypartAddStrParam(bp, X400_S_FTBP_FILENAME, filename_to_send, -1);
X400BodypartAddStrParam(bp, X400_S_FTBP_CREATION_DATE, "20230801060101.0Z", -1);
status = X400msMsgAddBodypart(mp, bp);
free(binary_data);
if (status != X400_E_NOERROR) {
printf("failed to add X400_T_FTBP BP\n");
return (status);
}
printf("Sent %d bytes as X400_T_FTBP BP\n", fs);
}
static void usage(void) {
printf("usage: %s\n", optstr);
printf("\t where:\n");
printf("\t -u : Don't prompt to override defaults \n");
printf("\t -3 : Use P3 connection \n");
printf("\t -7 : Use P7 connection \n");
printf("\t -1 : Use Marben-compatibility mode for P7 connection \n");
printf("\t -m : OR Address in P7 bind arg \n");
printf("\t -d : DN in P7 bind arg \n");
printf("\t -p : Presentation Address of P7 Store \n");
printf("\t -w : P7 password of P7 user \n");
printf("\t -M : OR Address in P3 bind arg \n");
printf("\t -D : DN in P3 bind arg \n");
printf("\t -P : Presentation Address of P3 server\n");
printf("\t -W : P3 password of P3 user \n");
printf("\t -o : Originator \n");
printf("\t -O : Originator Return Address \n");
printf("\t -r : Recipient\n");
printf("\t -l : Logline\n");
printf("\t -R : Report setting: 0=none, 1=-ve, 2=+ve\n");
printf("\t -y : Military Priority \n");
printf("\t\t 0 - deferred, 1 - routine, 2 - priority \n");
printf("\t\t 3 - immediate, 4 - flash, 5 - override \n");
printf("\t -C : Content Type (2/22/772/OID) \n");
printf("\t -i : Implicit conversion prohibited = TRUE \n");
printf("\t -a : Alternate Recipient Prohibited = TRUE \n");
printf("\t -q : Content Return Request = TRUE \n");
printf("\t -s : Disclosure of Recipient = FALSE \n");
printf("\t -A : Recipient Reassignment Prohibited = FALSE \n");
printf("\t -v : Conversion with Loss Prohibited = FALSE \n");
printf("\t -f : Filename to transfer as binary bp\n");
printf("\t -k : Request Delivery Report\n");
printf("\t -K : Request Read Notification ( 1 - RN, 2 - NRN, 4 - return of IPM with NRN )\n");
printf("\t -B : Set alternative subject line \n");
return;
}
int X400RecipNew(int type, struct X400Recipient **rpp)
Create a new recipient object.
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.
int X400MsgAddIntParam(struct X400Message *mp, int paramtype, int value)
Add integer-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.
int X400BodypartAddIntParam(struct X400Bodypart *bp, int paramtype, int value)
Add integer-valued parameter to the body part.
int X400MsgNew(int type, struct X400Message **mpp)
Creates new message.
int X400MsgAddAttachment(struct X400Message *mp, int type, const char *string, size_t length)
Add an attachment to the message.
int X400MsgAddStrParam(struct X400Message *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400BodypartNew(int type, struct X400Bodypart **bpp)
Create a new body part object.
int X400msMsgAddStrParam(struct X400msMessage *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
int X400msMsgFromRaw(struct X400msSession *sp, char *buffer, size_t buflen, struct X400msMessage **mpp, int *typep)
Reconstruct a message from a binary representation.
int X400msMsgAddBodypart(struct X400msMessage *mp, struct X400Bodypart *bp)
int X400msRecipGet(struct X400msMessage *mp, int type, int number, struct X400Recipient **rpp)
Get recipient object from message.
int X400msRecipAddIntParam(struct X400Recipient *rp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400msMsgAddIntParam(struct X400msMessage *mp, int paramtype, int value)
Add integer-valued parameter to the message.
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 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 X400msRecipGetStrParam(struct X400Recipient *rp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the recipient object.
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.
int X400msRecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
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 X400msMsgAddMessageBody(struct X400msMessage *mp, struct X400Message *mbp)
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.
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 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_DIRECTORY_NAME
Definition x400_att.h:397
#define X400_S_OR_ADDRESS
Definition x400_att.h:349
#define X400_N_FTBP_OBJECT_SIZE
Definition x400_att.h:1239
#define X400_S_FTBP_FILENAME
Definition x400_att.h:1227
#define X400_S_BODY_DATA
Definition x400_att.h:1194
#define X400_S_FTBP_MODIFICATION_DATE
Definition x400_att.h:1233
#define X400_S_FTBP_CREATION_DATE
Definition x400_att.h:1230
#define X400_S_FTBP_CONTENT_DESCRIPTION
Definition x400_att.h:1224
#define X400_S_SUBJECT
Definition x400_att.h:749
#define X400_T_BINARY
Definition x400_att.h:851
#define X400_T_IA5TEXT
Definition x400_att.h:825
#define X400_N_NUM_ATTACHMENTS
Definition x400_att.h:822
#define X400_T_ISO8859_1
Definition x400_att.h:835
#define X400_T_FTBP
Definition x400_att.h:860
#define X400_S_GRAPHIC_CHARSETS
Definition x400_att.h:1168
#define X400_S_TELETEX_CHARSETS
Definition x400_att.h:1175
#define X400_S_LOG_CONFIGURATION_FILE
Definition x400_att.h:1116
#define X400_N_PRIORITY
Definition x400_att.h:433
#define X400_S_MESSAGE_DELIVERY_TIME
Definition x400_att.h:451
#define X400_N_MMTS_PRIORITY_QUALIFIER
Definition x400_att.h:482
#define X400_S_CONTENT_IDENTIFIER
Definition x400_att.h:425
#define X400_N_CONTENT_RETURN_REQUEST
Definition x400_att.h:445
#define X400_S_MESSAGE_SUBMISSION_TIME
Definition x400_att.h:448
#define X400_S_EXTERNAL_CONTENT_TYPE
Definition x400_att.h:456
#define X400_S_MESSAGE_IDENTIFIER
Definition x400_att.h:416
#define X400_S_SECURITY_LABEL
Definition x400_att.h:1370
#define X400_E_BADPARAM
Definition x400_att.h:55
#define X400_E_SYSERROR
Definition x400_att.h:49
#define X400_E_RECIPIENT_ERROR
Definition x400_att.h:157
#define X400_E_NOMEMORY
Definition x400_att.h:52
#define X400_E_NOERROR
Definition x400_att.h:46
#define X400_E_NOSPACE
Definition x400_att.h:112
#define X400_N_ERROR_DUPLICATE_ATTRIBUTE
Definition x400_att.h:1306
#define X400_N_STRICT_P7_1988
Definition x400_att.h:1293
#define X400_N_USE_EXTENDED_SUBJECT
Definition x400_att.h:1299
#define X400_MSG_MESSAGE
Definition x400_att.h:29
#define X400_N_REPORT_REQUEST
Definition x400_att.h:680
#define X400_N_NOTIFICATION_REQUEST
Definition x400_att.h:702
#define X400_RECIP_STANDARD
Definition x400_att.h:341
#define X400_ORIGINATOR
Definition x400_att.h:305
#define X400_RECIP_INVALID
Definition x400_att.h:338
X400 MA/MS (P3/P7) Interface.

All rights reserved © 2002 - 2024 Isode Ltd.