examples/x400_mtsend_rep.c
This is an example program which transfers a report into the MTA.
/* Copyright (c) 2004-2024, 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 transferring a report into the MTA
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <x400_mtapi.h>
#include "example.h"
/* local functions */
static int send_report (
int drtype
);
static int add_recips_positive(
struct X400mtMessage *mp
);
static int add_recips_negative(
struct X400mtMessage *mp
);
static int build_env(
struct X400mtMessage *mp
);
static int add_env_recip_info(
struct X400Recipient *rp
);
static void usage(void);
static int rno = 1;
static int do_redi_hist(
struct X400Recipient *rp
);
static int do_redi_hist_env(
struct X400mtMessage *msg
);
static void do_origandl(
struct X400mtMessage *msg
);
/* These are the data items used */
/* The O/R addresses used are intended to be compatible with those
* used in the quick install scripts mktailor.tcl, and createmhs.tcl.
* Change this value to the name of your host. */
#define HOSTNAME "dhcp-164"
static char *optstr = "uo:O:r:g:G:c:l:R:y:C:iaqsAv";
/* this value is used for the originator of the message */
static const char orig_s[] = "/S=x400test-orig/OU="HOSTNAME"/O=GatewayMTA/PRMD=TestPRMD/ADMD=TestADMD/C=GB/";
static const char *orig = orig_s;
/* default recipients */
static const char recip_s[] = "/S=x400test-recip2/OU="HOSTNAME"/O=GatewayMTA/PRMD=TestPRMD/ADMD=TestADMD/C=GB/";
static const char *recip = recip_s;
/* default envelope integer values */
static int def_content_type = 2;
static int def_bool = 0;
static int def_priority = 2;
/* default envelope string values */
static const char msg_id[] = "/PRMD=TestPRMD/ADMD=TestADMD/C=GB/;"HOSTNAME".2810401-030924.140212";
static const char content_id[] = "030924.140212";
static const char content_corr[] = "CONTENT-CORROLATOR";
static const char latest_del_time[] = "120927120000Z";
int main(
int argc,
char **argv
)
{
int drtype;
orig = strdup(x400_default_gw_originator);
recip = strdup(x400_default_gw_recipient);
if (get_args(argc, argv, optstr)) {
usage();
exit(-1);
}
if (x400_channel == NULL) {
printf("You must specify an X.400 channel\n");
usage();
exit(-1);
}
printf("Delivery Report type (0 = Positive, 1 = Negative): ");
drtype = ic_fgetc(x400_contype, stdin);
if ((drtype != '0') && (drtype != '1'))
exit(1);
drtype -= '0';
return send_report(drtype);
}
static int send_report (
int drtype
)
{
int status;
struct X400mtSession *sp;
struct X400mtMessage *mp;
if (x400_channel == NULL) {
fprintf (stderr, "No x400_channel value set in x400tailor file");
exit(1);
}
/* open a new session */
status = X400mtOpen (x400_channel, &sp);
exit (status);
}
/* start preparing a new report */
/* Should report all errors as above */
if ( status != X400_E_NOERROR ) exit (status);
/* setup originator using a single string */
if ( status != X400_E_NOERROR ) exit (status);
/* add various envelope and header recipients into the report */
if (drtype == 0)
status = add_recips_positive(mp);
else
status = add_recips_negative(mp);
if ( status != X400_E_NOERROR ) exit (status);
#define ADD_TRACE_INFO 1
#ifdef ADD_TRACE_INFO
{
struct X400TraceInfo *info1; /*Will contain all trace information */
if (status !=X400_E_NOERROR) {
fprintf(stderr,"Failed to allocate new trace info object \n");
exit(status);
}
status = X400TraceInfoAddStrParam (info1,
"/PRMD=wibble/ADMD=TestADMD/C=GB/",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_GLOBAL_DOMAIN_ID to trace info\n");
exit(status);
}
status = X400TraceInfoAddStrParam (info1,
"071121125704Z",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DSI_ARRIVAL_TIME to trace info\n");
exit(status);
}
/*Add optional*/
status = X400TraceInfoAddStrParam (info1,
"/PRMD=atmpdom/ADMD=TestADMD/C=GB/",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DSI_ATTEMPTED_DOMAIN to trace info\n");
exit(status);
}
/*Add optional*/
status = X400TraceInfoAddStrParam (info1,
"071122125704Z",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DSI_AA_DEF_TIME to trace info\n");
exit(status);
}
}
#endif
/* build rest of the report envelope */
status = build_env(mp);
if ( status != X400_E_NOERROR ) exit (status);
/* send the report */
status = X400mtMsgSend (mp);
if ( status != X400_E_NOERROR ) {
fprintf (stderr, "Error in MsgSend: %s\n", X400mtError (status));
exit (status);
}
/* delete the message structure */
status = X400mtMsgDelete (mp);
if ( status != X400_E_NOERROR ) exit (status);
mp = NULL;
/* close the API session */
}
static int add_recips_positive(
struct X400mtMessage *mp
)
{
struct X400Recipient *rp;
int status;
/* add new recipient to the report envelope */
/* give recip an address */
/* add other values to recip */
status = add_env_recip_info (rp);
/* add new recipient to the report content */
/* give recip an address */
status = X400mtRecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
/* add other values to recip */
status = add_env_recip_info (rp);
/* add the arrival time for this recipient */
if ( status != X400_E_NOERROR ) {
fprintf (stderr, "X400mtMsgAddStrParam returned error: %s\n", X400mtError (status));
return (status);
}
/* add the delivery time for this recipient (positive dr) */
if ( status != X400_E_NOERROR ) {
fprintf (stderr, "X400mtMsgAddStrParam returned error: %s\n", X400mtError (status));
return (status);
}
/* add the CEIT for this recipient */
if ( status != X400_E_NOERROR ) {
fprintf (stderr, "X400mtMsgAddStrParam returned error: %s\n", X400mtError (status));
return (status);
}
#define USE_REDIRECTION_HISTORY 1
#ifdef USE_REDIRECTION_HISTORY
/* Add redirection history for this recipient (8.3.1.1.1.5)*/
do_redi_hist(rp);
#endif
return X400_E_NOERROR;
}
static int add_recips_negative(
struct X400mtMessage *mp
)
{
struct X400Recipient *rp;
int status;
/* add new recipient to the report envelope */
status = X400mtRecipNew (mp, X400_RECIP_ENVELOPE, &rp);
/* give recip an address */
status = X400mtRecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
/* add other values to recip */
status = add_env_recip_info (rp);
/* add new recipient to the report content */
status = X400mtRecipNew (mp, X400_RECIP_REPORT, &rp);
/* give recip an address */
status = X400mtRecipAddStrParam (rp, X400_S_OR_ADDRESS, recip, -1);
/* add other values to recip */
status = add_env_recip_info (rp);
/* add the arrival time for this recipient */
if ( status != X400_E_NOERROR ) {
fprintf (stderr, "X400mtMsgAddStrParam returned error: %s\n", X400mtError (status));
return (status);
}
/* add the supplementary info for this recipient (negative dr) */
if ( status != X400_E_NOERROR ) {
fprintf (stderr, "X400mtMsgAddStrParam returned error: %s\n", X400mtError (status));
return (status);
}
/* add the non-delivery reason for this recipient (negative dr) */
if ( status != X400_E_NOERROR ) {
fprintf (stderr, "X400mtMsgAddIntParam returned error: %s\n", X400mtError (status));
return (status);
}
/* add the non-delivery diagnostic for this recipient (negative dr) */
if ( status != X400_E_NOERROR ) {
fprintf (stderr, "X400mtMsgAddIntParam returned error: %s\n", X400mtError (status));
return (status);
}
return X400_E_NOERROR;
}
static int build_env(
struct X400mtMessage *mp
)
{
int status;
/* Envelope Attributes */
/* Content Type: 2 or 22 */
/* X400_N_CONTENT_LENGTH is probe only */
/* Priority: 0 - normal, 1 - non-urgent, 2 - urgent */
/* Disclosure of recipients: 0 - no, 1 - yes */
/* Implicit conversion prohibited: 0 - no, 1 - yes */
/* Alternate recipient allowed: 0 - no, 1 - yes */
/* Content return request: 0 - no, 1 - yes */
/* hmm - 1 is headers - what does that do in X.400 ? */
/* Recipient reassignment prohibited: 0 - no, 1 - yes */
/* Distribution List expansion prohibited: 0 - no, 1 - yes */
/* Conversion with loss prohibited: 0 - no, 1 - yes */
/* string params */
/* Message Identifier. In RFC 2156 String form */
/* Content correlator */
/* Content Identifier */
/* Subject Identifier, the Message Identifier of the original message */
/*
* X400_S_ORIGINAL_ENCODED_INFORMATION_TYPES
* X400_S_MESSAGE_SUBMISSION_TIME
* X400_S_MESSAGE_DELIVERY_TIME
* are read only, so don't add them
*/
/* Latest Delivery Time: UTCTime format YYMMDDHHMMSS<zone> */
#ifdef USE_REDIRECTION_HISTORY
/*Add redirection history for the envelope (8.3.1.2.1.5) */
do_redi_hist_env(mp);
#endif
do_origandl(mp);
/* all OK */
return X400_E_NOERROR;
}
static int add_env_recip_info(
struct X400Recipient *rp
)
{
int status;
/* add attributes to recipient in envelope */
rno++;
return X400_E_NOERROR;
}
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 -o : Originator \n");
printf("\t -O : Originator Return Address \n");
printf("\t -r : Recipient\n");
printf("\t -c : X.400 passive channel\n");
printf("\t -l : Logline\n");
printf("\t -R : Reports (0 - never, 1 - always, 2 - always NDR \n");
printf("\t -y : Priority (0 - normal, 1 - non-urgent, 2 - urgent \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");
return;
}
static int do_redi_hist(
struct X400Recipient *rp
)
{
struct X400RediHist *hist1;
struct X400RediHist *hist2;
int status;
status = X400RediHistNew(rp,&hist1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,"Failed to allocate new trace info object \n");
exit(status);
}
/* Add Redirection History time */
status = X400RediHistAddStrParam (hist1,
"071121125704Z",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_REDIRECTION_TIME to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddStrParam (hist1,
"/cn=redihist/prmd=TestPRMD/admd=TestPRMD/C=gb",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_OR_ADDRESS to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddStrParam (hist1,
"CN=redihist,c=GB",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DIRECTORY_NAME to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddIntParam(hist1,
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_N_REDIRECTION_REASON to trace info\n");
exit(status);
}
/*hist2*/
status = X400RediHistNew(rp,&hist2);
if (status !=X400_E_NOERROR) {
fprintf(stderr,"Failed to allocate new trace info object \n");
exit(status);
}
/* Add Redirection History time */
status = X400RediHistAddStrParam (hist2,
"071121125714Z",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_REDIRECTION_TIME to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddStrParam (hist2,
"/cn=redihist2/prmd=TestPRMD/admd=TestPRMD/C=gb",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_OR_ADDRESS to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddStrParam (hist2,
"CN=redihist2,c=GB",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DIRECTORY_NAME to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddIntParam(hist2,
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_N_REDIRECTION_REASON to "
"Redirection Hist\n");
exit(status);
}
return X400_E_NOERROR;
}
static int do_redi_hist_env(
struct X400mtMessage *msg
)
{
struct X400RediHist *hist1;
struct X400RediHist *hist2;
int status;
status = X400mtRediHistNewEnv(msg,&hist1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,"Failed to allocate new trace info object \n");
exit(status);
}
/* Add Redirection History time */
status = X400RediHistAddStrParam (hist1,
"071121125704Z",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_REDIRECTION_TIME to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddStrParam (hist1,
"/cn=redihist/prmd=TestPRMD/admd=TestPRMD/C=gb",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_OR_ADDRESS to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddStrParam (hist1,
"CN=redihist,c=GB",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DIRECTORY_NAME to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddIntParam(hist1,
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_N_REDIRECTION_REASON to trace info\n");
exit(status);
}
/*hist2*/
status = X400mtRediHistNewEnv(msg,&hist2);
if (status !=X400_E_NOERROR) {
fprintf(stderr,"Failed to allocate new trace info object \n");
exit(status);
}
/* Add Redirection History time */
status = X400RediHistAddStrParam (hist2,
"071121125714Z",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_REDIRECTION_TIME to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddStrParam (hist2,
"/cn=redihist2/prmd=TestPRMD/admd=TestPRMD/C=gb",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_OR_ADDRESS to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddStrParam (hist2,
"CN=redihist2,c=GB",
-1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DIRECTORY_NAME to Redirection Hist\n");
exit(status);
}
status = X400RediHistAddIntParam(hist2,
if (status !=X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_N_REDIRECTION_REASON to "
"Redirection Hist\n");
exit(status);
}
return X400_E_NOERROR;
}
static void do_origandl(
struct X400mtMessage *msg
)
{
struct X400ORandDL *or_and_dl1;
struct X400ORandDL *or_and_dl2;
const char *origin_or_address = "/cn=origandlorig/prmd=TestPRMD/admd=TestPRMD/C=gb/";
const char *origin_dn_address = "CN=origandlorig,c=GB";
int status;
status = X400mtORandDLNew(msg,&or_and_dl1);
if (status !=X400_E_NOERROR) {
fprintf(stderr,"Failed to allocate new OR Address and DL "
"expansion object \n");
exit(status);
}
/* Add Origin or expansion time */
status = X400ORandDLAddStrParam (or_and_dl1,
"071121125704Z",
-1);
if (status != X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_ORIG_OR_EXAP_TIME "
"to X400ORandDL\n");
exit(status);
}
/* originator or dl_name */
/* Add Origin or expansion time */
status = X400ORandDLAddStrParam (or_and_dl1,
origin_or_address,
-1);
if (status != X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_OR_ADDRESS "
"to X400ORandDL\n");
exit(status);
}
status = X400ORandDLAddStrParam (or_and_dl1,
origin_dn_address,
-1);
if (status != X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DIRECTORY_NAME "
"to X400ORandDL\n");
exit(status);
}
status = X400mtORandDLNew(msg,&or_and_dl2);
if (status !=X400_E_NOERROR) {
fprintf(stderr,"Failed to allocate new OR Address and DL "
"expansion object \n");
exit(status);
}
/* Add Origin or expansion time */
status = X400ORandDLAddStrParam (or_and_dl2,
"091121125704Z",
-1);
if (status != X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_ORIG_OR_EXAP_TIME "
"to X400ORandDL\n");
exit(status);
}
/* originator or dl_name */
/* Add Origin or expansion time */
status = X400ORandDLAddStrParam (or_and_dl2,
origin_or_address,
-1);
if (status != X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_OR_ADDRESS "
"to X400ORandDL\n");
exit(status);
}
status = X400ORandDLAddStrParam (or_and_dl2,
origin_dn_address,
-1);
if (status != X400_E_NOERROR) {
fprintf(stderr,
"Failed to add X400_S_DIRECTORY_NAME "
"to X400ORandDL\n");
exit(status);
}
}
#define X400_N_RECIPIENT_REASSIGNMENT_PROHIBITED
Definition: x400_att.h:455
#define X400_S_CONTENT_CORRELATOR_IA5_STRING
Definition: x400_att.h:517
X400COMMON_CDECL int X400RediHistAddIntParam(struct X400RediHist *hist, int paramtype, int value)
Set an integer value in a Redirection History object.
X400COMMON_CDECL int X400ORandDLAddStrParam(struct X400ORandDL *or_and_dl, int type, const char *value, size_t length)
Add string parameter for a Originator and DL Expansion History object.
#define X400_N_CONVERSION_WITH_LOSS_PROHIBITED
Definition: x400_att.h:461
#define X400_S_CONVERTED_ENCODED_INFORMATION_TYPES
Definition: x400_att.h:694
int X400mtRediHistNewEnv(struct X400mtMessage *msg, struct X400RediHist **hist)
Create a new Redirection History object for a message envelope this is represented by 8....
int X400mtRecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
X.400 Gateway Interface.
int X400mtOpen(const char *credentials, struct X400mtSession **spp)
Open a session to the MTA.
X400COMMON_CDECL int X400RediHistNew(struct X400Recipient *recip, struct X400RediHist **hist)
Create a new Redirection History object.
int X400mtRecipNew(struct X400mtMessage *mp, int type, struct X400Recipient **rpp)
Add new recipient to a message.
int X400mtMsgAddStrParam(struct X400mtMessage *mp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the message.
#define X400_N_IMPLICIT_CONVERSION_PROHIBITED
Definition: x400_att.h:430
int X400mtMsgAddIntParam(struct X400mtMessage *mp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400mtRecipAddIntParam(struct X400Recipient *rp, int paramtype, int value)
Add integer-valued parameter to the message.
int X400mtMsgNew(struct X400mtSession *sp, int type, struct X400mtMessage **mpp)
Creates new message.
X400COMMON_CDECL int X400TraceInfoAddStrParam(struct X400TraceInfo *info, int paramtype, const char *value, size_t length)
Add string-valued parameter to the X400TraceInfo object.
#define X400_N_ALTERNATE_RECIPIENT_ALLOWED
Definition: x400_att.h:433
X400COMMON_CDECL int X400RediHistAddStrParam(struct X400RediHist *hist, int paramtype, const char *value, size_t length)
Add string-valued parameter to the X400RediHist object.
int X400mtORandDLNew(struct X400mtMessage *msg, struct X400ORandDL **or_and_dl)
Create new Originator and DL expansion history object.
int X400mtTraceInfoNew(struct X400mtMessage *mp, struct X400TraceInfo **info, int type)
Create a new Trace Info object for a message object.