#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
#endif
#ifdef USE_SMTPAUTH
#include <auth-client.h>
#endif
#include <libesmtp.h>
#include "const-c.inc"
typedef smtp_session_t Net__ESMTP__Session;
typedef smtp_message_t Net__ESMTP__Message;
typedef smtp_recipient_t Net__ESMTP__Recipient;
typedef smtp_etrn_node_t Net__ESMTP__EtrnNode;
typedef enum header_option Net__ESMTP__HeaderOption;
typedef enum rfc2822_timeouts Net__ESMTP__RFC822Timeouts;
typedef HV * Net__ESMTP__Status;
#ifdef _auth_client_h
typedef auth_context_t Net__ESMTP__Auth;
#else
typedef void * Net__ESMTP__Auth;
#endif
void
callback_eventcb (smtp_session_t session, int event_no, void *arg, ...)
{
va_list ap;
smtp_message_t message;
smtp_recipient_t recipient;
char *text;
int intarg, *intptr, count;
long longarg;
SV *svfunc = NULL;
SV *svuser_data = NULL;
SV **sv, *svobj, *rvobj, *svobjarg;
HV *hvarray;
dSP ;
if (!arg || !SvROK((SV *)arg))
return;
ENTER ;
SAVETMPS;
hvarray = (HV *)(SvRV((SV *)arg));
intptr = NULL;
sv = hv_fetch(hvarray, "func", 4, FALSE);
if (sv == (SV**)NULL)
croak("callback_enum_eventcb: Internal error fetching func ...\n") ;
svfunc = *sv;
sv = hv_fetch(hvarray, "user_data", 9, FALSE);
if (sv == (SV**)NULL)
croak("callback_enum_eventcb: Internal error fetching user_data ...\n") ;
svuser_data = *sv;
svobj = sv_newmortal ();
rvobj = sv_setref_pv (svobj, "Net::ESMTP::Session", session);
PUSHMARK(sp);
XPUSHs(rvobj);
XPUSHs(sv_2mortal(newSViv(event_no)));
XPUSHs(sv_mortalcopy(svuser_data));
va_start (ap, arg);
/* Protocol progress */
switch (event_no) {
case SMTP_EV_CONNECT: /* <empty arg list> */
break;
case SMTP_EV_MAILSTATUS: /* char* message->reverse_path_mailbox, message */
text = va_arg (ap, char *);
message = va_arg (ap, smtp_message_t);
XPUSHs(sv_2mortal(newSVpvn(text, strlen(text))));
svobjarg = sv_newmortal();
XPUSHs(sv_setref_pv (svobjarg, "Net::ESMTP::Message", message));
break;
case SMTP_EV_RCPTSTATUS: /* char* session->rsp_recipient->mailbox, session->rsp_recipient */
text = va_arg (ap, char *);
recipient = va_arg (ap, smtp_recipient_t);
XPUSHs(sv_2mortal(newSVpvn(text, strlen(text))));
svobjarg = sv_newmortal();
XPUSHs(sv_setref_pv (svobjarg, "Net::ESMTP::Recipient", recipient));
break;
case SMTP_EV_MESSAGEDATA: /* session->current_message, int len */
message = va_arg (ap, smtp_message_t);
intarg = va_arg (ap, int);
svobjarg = sv_newmortal();
XPUSHs(sv_setref_pv (svobjarg, "Net::ESMTP::Message", message));
XPUSHs(sv_2mortal(newSViv(intarg)));
break;
case SMTP_EV_MESSAGESENT: /* session->current_message */
message = va_arg (ap, smtp_message_t);
svobjarg = sv_newmortal();
XPUSHs(sv_setref_pv (svobjarg, "Net::ESMTP::Message", message));
break;
case SMTP_EV_DISCONNECT: /* <empty arg list> */
break;
/* Protocol extension progress */
case SMTP_EV_ETRNSTATUS: /* int node->option, char* node->domain */
intarg = va_arg (ap, int);
text = va_arg (ap, char *);
XPUSHs(sv_2mortal(newSViv(intarg)));
XPUSHs(sv_2mortal(newSVpvn(text, strlen(text))));
break;
/* Required extensions */
case SMTP_EV_EXTNA_DSN: /* int &quit_now */
intptr = va_arg (ap, int *);
case SMTP_EV_EXTNA_8BITMIME: /* <empty arg list> */
break;
case SMTP_EV_EXTNA_STARTTLS: /* NULL (protocol.c) */
break;
case SMTP_EV_EXTNA_ETRN: /* int &quit_now */
case SMTP_EV_EXTNA_CHUNKING: /* int &quit_now */
intptr = va_arg (ap, int *);
break;
case SMTP_EV_EXTNA_BINARYMIME: /* <empty arg list> */
break;
/* Extensions specific events */
case SMTP_EV_DELIVERBY_EXPIRED: /* long session->min_by_time - by_time, int &adjust */
longarg = va_arg (ap, long);
intptr = va_arg (ap, int *);
XPUSHs(sv_2mortal(newSVnv(longarg)));
break;
/* STARTTLS */
case SMTP_EV_WEAK_CIPHER: /* int bits, int &ok */
intarg = va_arg (ap, int);
intptr = va_arg (ap, int *);
XPUSHs(sv_2mortal(newSViv(intarg)));
break;
case SMTP_EV_STARTTLS_OK: /* SSL* ssl, SSL_get_cipher (ssl), SSL_get_cipher_bits (ssl, NULL) */
/* UNSUPPORTED */
break;
case SMTP_EV_INVALID_PEER_CERTIFICATE: /* long vfy_result, int &ok */
longarg = va_arg (ap, long);
intptr = va_arg (ap, int *);
XPUSHs(sv_2mortal(newSVnv(longarg)));
break;
case SMTP_EV_NO_PEER_CERTIFICATE: /* int &ok */
case SMTP_EV_WRONG_PEER_CERTIFICATE: /* int &ok */
intptr = va_arg (ap, int *);
break;
case SMTP_EV_NO_CLIENT_CERTIFICATE: /* int &ok */
intptr = va_arg (ap, int *);
break;
case SMTP_EV_UNUSABLE_CLIENT_CERTIFICATE: /* <empty arg list> */
break;
case SMTP_EV_UNUSABLE_CA_LIST: /* <empty arg list> */
break;
}
va_end (ap);
PUTBACK ;
SPAGAIN ;
if (svfunc) {
if (intptr != NULL) {
count = perl_call_sv(svfunc, G_SCALAR);
if (count > 0)
*intptr = POPi;
} else {
perl_call_sv(svfunc, G_DISCARD);
}
}
PUTBACK ;
FREETMPS ;
LEAVE ;
}
void
callback_enum_messagecb (smtp_message_t message, void *arg)
{
SV *svfunc = NULL;
SV *svuser_data = NULL;
SV **sv, *svobj, *rvobj;
HV *hvarray;
dSP ;
if (!arg || !SvROK((SV *)arg))
return;
hvarray = (HV *)(SvRV((SV *)arg));
sv = hv_fetch(hvarray, "func", 4, FALSE);
if (sv == (SV**)NULL)
croak("callback_enum_messagecb: Internal error fetching func ...\n") ;
svfunc = *sv;
sv = hv_fetch(hvarray, "user_data", 9, FALSE);
if (sv == (SV**)NULL)
croak("callback_enum_messagecb: Internal error fetching user_data ...\n") ;
svuser_data = *sv;
svobj = sv_newmortal ();
rvobj = sv_setref_pv (svobj, "Net::ESMTP::Message", message);
PUSHMARK(sp);
XPUSHs(rvobj);
XPUSHs(sv_mortalcopy(svuser_data));
PUTBACK ;
if (svfunc)
perl_call_sv(svfunc, G_DISCARD);
}
void
callback_enum_recipientcb (smtp_recipient_t recipient,
const char *mailbox, void *arg)
{
SV *svfunc = NULL;
SV *svuser_data = NULL;
SV **sv, *svobj, *rvobj;
HV *hvarray;
dSP ;
if (!arg || !SvROK((SV *)arg))
return;
hvarray = (HV *)(SvRV((SV *)arg));
sv = hv_fetch(hvarray, "func", 4, FALSE);
if (sv == (SV**)NULL)
croak("callback_enum_recipientcb: Internal error fetching func ...\n") ;
svfunc = *sv;
sv = hv_fetch(hvarray, "user_data", 9, FALSE);
if (sv == (SV**)NULL)
croak("callback_enum_recipientcb: Internal error fetching user_data ...\n") ;
svuser_data = *sv;
svobj = sv_newmortal ();
rvobj = sv_setref_pv (svobj, "Net::ESMTP::Recipient", recipient);
PUSHMARK(sp);
XPUSHs(rvobj);
XPUSHs(sv_2mortal(newSVpvn(mailbox, strlen(mailbox))));
XPUSHs(sv_mortalcopy(svuser_data));
PUTBACK ;
if (svfunc)
perl_call_sv(svfunc, G_DISCARD);
}
void
callback_enum_nodecb (smtp_etrn_node_t node,
int option, const char *domain, void *arg)
{
SV *svfunc = NULL;
SV *svuser_data = NULL;
SV **sv, *svobj, *rvobj;
HV *hvarray;
dSP ;
if (!arg || !SvROK((SV *)arg))
return;
hvarray = (HV *)(SvRV((SV *)arg));
sv = hv_fetch(hvarray, "func", 4, FALSE);
if (sv == (SV**)NULL)
croak("callback_enum_nodecb: Internal error fetching func ...\n") ;
svfunc = *sv;
sv = hv_fetch(hvarray, "user_data", 9, FALSE);
if (sv == (SV**)NULL)
croak("callback_enum_nodecb: Internal error fetching user_data ...\n") ;
svuser_data = *sv;
svobj = sv_newmortal ();
rvobj = sv_setref_pv (svobj, "Net::ESMTP::ETRNNode", node);
PUSHMARK(sp);
XPUSHs(rvobj);
XPUSHs(sv_2mortal(newSViv(option)));
XPUSHs(sv_2mortal(newSVpvn(domain, strlen(domain))));
XPUSHs(sv_mortalcopy(svuser_data));
PUTBACK ;
if (svfunc)
perl_call_sv(svfunc, G_DISCARD);
}
void
callback_monitorcb (const char *buf, int buflen, int writing, void *arg)
{
SV *svfunc = NULL;
SV *svuser_data = NULL;
SV **sv;
HV *hvarray;
dSP ;
if (!arg || !SvROK((SV *)arg))
return;
hvarray = (HV *)(SvRV((SV *)arg));
sv = hv_fetch(hvarray, "func", 4, FALSE);
if (sv == (SV**)NULL)
croak("callback_monitorcb: Internal error fetching func ...\n") ;
svfunc = *sv;
sv = hv_fetch(hvarray, "user_data", 9, FALSE);
if (sv == (SV**)NULL)
croak("callback_monitorcb: Internal error fetching user_data ...\n") ;
svuser_data = *sv;
PUSHMARK(sp);
XPUSHs(sv_2mortal(newSVpvn(buf, buflen)));
XPUSHs(sv_2mortal(newSViv(writing)));
XPUSHs(sv_mortalcopy(svuser_data));
PUTBACK ;
if (svfunc)
perl_call_sv(svfunc, G_DISCARD);
}
/* I am not sure that callback_auth_interactcb works,
* since perl can free the result strings before C library would use it */
#ifdef _auth_client_h
int
callback_auth_interactcb (auth_client_request_t request,
char **result, int fields, void *arg)
{
SV *svfunc = NULL;
SV *svuser_data = NULL;
SV **sv, *rvobj;
HV *hvarray;
HV *hvrequest;
AV *avreq;
int i, ret = 1;
dSP ;
int count = 0;
I32 ax;
ENTER ;
SAVETMPS;
if (!arg || !SvROK((SV *)arg))
return 0;
hvarray = (HV *)(SvRV((SV *)arg));
sv = hv_fetch(hvarray, "func", 4, FALSE);
if (sv == (SV**)NULL)
croak("callback_auth_interactcb: Internal error fetching func ...\n") ;
svfunc = *sv;
sv = hv_fetch(hvarray, "user_data", 9, FALSE);
if (sv == (SV**)NULL)
croak("callback_auth_interactcb: Internal error fetching user_data ...\n") ;
svuser_data = *sv;
avreq = (AV *)sv_2mortal((SV *)newAV()); /* array of requests */
for (i=0; i<fields; ++i) {
hvrequest = (HV *)sv_2mortal((SV *)newHV());
hv_store(hvrequest, "name", 4, newSVpvn(request[i].name, strlen(request[i].name)), 0);
hv_store(hvrequest, "flags", 5, newSViv(request[i].flags), 0);
hv_store(hvrequest, "prompt", 6, newSVpvn(request[i].prompt, strlen(request[i].prompt)), 0);
hv_store(hvrequest, "size", 4, newSViv(request[i].size), 0);
av_push(avreq, newRV((SV *)hvrequest));
}
rvobj = newRV((SV *)avreq);
PUSHMARK(sp);
XPUSHs(rvobj);
XPUSHs(sv_mortalcopy(svuser_data));
PUTBACK ;
if (svfunc)
count = perl_call_sv(svfunc, G_ARRAY);
SPAGAIN ;
SP -= count ; /* we can use ST(i) */
ax = (SP - PL_stack_base) + 1 ;
for (i=0; i<count; i++) {
SV *svstr = sv_mortalcopy(ST(i));
result[i] = (char *) SvPV_nolen(svstr);
}
/* fail if there are no result or less items than requested */
if (count < fields)
ret = 0;
PUTBACK ;
FREETMPS ;
LEAVE ;
return ret;
}
#endif
/* returns a length of the password, not the command status */
int
callback_starttls_set_password (char *buf, int buflen, int rwflag, void *arg)
{
int ret = 0;
SV *svfunc = NULL;
SV *svuser_data = NULL;
SV **sv;
HV *hvarray;
dSP ;
int count = 0;
ENTER ;
SAVETMPS;
if (!arg || !SvROK((SV *)arg))
return 0;
hvarray = (HV *)(SvRV((SV *)arg));
sv = hv_fetch(hvarray, "func", 4, FALSE);
if (sv == (SV**)NULL)
croak("callback_starttls_set_password: Internal error fetching func ...\n") ;
svfunc = *sv;
sv = hv_fetch(hvarray, "user_data", 9, FALSE);
if (sv == (SV**)NULL)
croak("callback_starttls_set_password: Internal error fetching user_data ...\n") ;
svuser_data = *sv;
PUSHMARK(sp);
XPUSHs(sv_2mortal(newSViv(rwflag)));
XPUSHs(sv_mortalcopy(svuser_data));
PUTBACK ;
if (svfunc)
count = perl_call_sv(svfunc, G_SCALAR);
SPAGAIN ;
if (count) {
STRLEN n_a;
char *text = POPpx;
int len = n_a;
if (len + 1 > buflen || len == 0 || !text)
ret = 0;
else
strcpy (buf, text);
ret = len; /* return length of the returned password string */
} else {
ret = 0;
}
PUTBACK ;
FREETMPS ;
LEAVE ;
return ret;
}
const char *
callback_messagecb (void **buf, int *len, void *arg)
{
SV *svfunc = NULL;
SV *svuser_data = NULL;
SV **sv;
HV *hvarray;
dSP ;
int count = 0;
ENTER ;
SAVETMPS;
if (!arg || !SvROK((SV *)arg))
return NULL;
hvarray = (HV *)(SvRV((SV *)arg));
sv = hv_fetch(hvarray, "func", 4, FALSE);
if (sv == (SV**)NULL)
croak("callback_messagecb: Internal error fetching func ...\n") ;
svfunc = *sv;
sv = hv_fetch(hvarray, "user_data", 9, FALSE);
if (sv == (SV**)NULL)
croak("callback_messagecb: Internal error fetching user_data ...\n") ;
svuser_data = *sv;
PUSHMARK(sp);
/* len is NULL at the begining */
if (len == NULL) {
XPUSHs(&PL_sv_undef);
} else {
XPUSHs(sv_2mortal(newSViv(*len)));
}
XPUSHs(sv_mortalcopy(svuser_data));
PUTBACK ;
if (svfunc) {
if (len == NULL) {
perl_call_sv(svfunc, G_DISCARD);
} else {
count = perl_call_sv(svfunc, G_SCALAR);
}
}
SPAGAIN ;
if (count > 0) {
STRLEN n_a;
char *text = POPpx;
if (n_a <= 0 || !text)
*len = 0;
else {
*buf = realloc (*buf, n_a);
strncpy (*buf, text, n_a);
*len = n_a;
}
}
PUTBACK ;
FREETMPS ;
LEAVE ;
if (len == NULL)
return NULL;
else
return *buf;
}
MODULE = Net::ESMTP PACKAGE = Net::ESMTP
PROTOTYPES: ENABLE
INCLUDE: const-xs.inc
BOOT:
#ifdef _auth_client_h
auth_client_init();
#endif
SV *
smtp_version ()
PREINIT:
char buf[256];
CODE:
if (!smtp_version (buf, 255, 0))
XSRETURN_UNDEF;
RETVAL = newSVpv (buf, 1);
OUTPUT:
RETVAL
MODULE = Net::ESMTP PACKAGE = Net::ESMTP PREFIX = smtp_
int
smtp_starttls_set_password_cb(callback, svdata = 0)
SV * callback
SV * svdata
PREINIT:
HV * rh;
CODE:
rh = (HV *)sv_2mortal((SV *)newHV());
hv_store(rh, "user_data", 9, newSVsv(svdata), 0);
hv_store(rh, "func", 4, newSVsv(callback), 0);
RETVAL = smtp_starttls_set_password_cb (callback_starttls_set_password, newRV((SV *)rh));
OUTPUT:
RETVAL
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::Session PREFIX = smtp_
Net::ESMTP::Session
smtp_new (Class = "Net::ESMTP::Session")
const char * Class
CODE:
RETVAL = smtp_create_session ();
OUTPUT:
RETVAL
void
DESTROY (session)
Net::ESMTP::Session session
CODE:
#ifdef _auth_client_h
smtp_auth_set_context (session, NULL);
#endif
smtp_destroy_session (session);
Net::ESMTP::Message
smtp_add_message (session)
Net::ESMTP::Session session
int
smtp_set_server (session, hostport)
Net::ESMTP::Session session
const char * hostport
int
smtp_set_hostname (session, hostname)
Net::ESMTP::Session session
const char * hostname
int
smtp_start_session (session)
Net::ESMTP::Session session
#
# application data (void *)
#
void *
smtp_set_application_data (session, data)
Net::ESMTP::Session session
void * data
void *
smtp_get_application_data (session)
Net::ESMTP::Session session
int
smtp_option_require_all_recipients (session, state)
Net::ESMTP::Session session
int state
#ifdef _auth_client_h
int
smtp_auth_set_context (session, context)
Net::ESMTP::Session session
Net::ESMTP::Auth context
#endif
long
smtp_set_timeout (session, which, value)
Net::ESMTP::Session session
int which
long value
int
smtp_set_eventcb (session, callback, svdata = 0)
Net::ESMTP::Session session
SV * callback
SV * svdata
PREINIT:
HV * rh;
CODE:
rh = (HV *)sv_2mortal((SV *)newHV());
hv_store(rh, "user_data", 9, newSVsv(svdata), 0);
hv_store(rh, "func", 4, newSVsv(callback), 0);
RETVAL = smtp_set_eventcb (session, callback_eventcb, newRV((SV *)rh));
OUTPUT:
RETVAL
int
smtp_set_monitorcb (session, callback, svdata = 0, headers = 0)
Net::ESMTP::Session session
SV * callback
SV * svdata
int headers
PREINIT:
HV * rh;
CODE:
rh = (HV *)sv_2mortal((SV *)newHV());
hv_store(rh, "user_data", 9, newSVsv(svdata), 0);
hv_store(rh, "func", 4, newSVsv(callback), 0);
RETVAL = smtp_set_monitorcb (session, callback_monitorcb, newRV((SV *)rh), headers);
OUTPUT:
RETVAL
## RFC 1985. Remote Message Queue Starting (ETRN)
Net::ESMTP::EtrnNode
smtp_etrn_add_node (session, option, node)
Net::ESMTP::Session session
int option
const char * node
int
smtp_etrn_enumerate_nodes (session, callback, svdata = 0)
Net::ESMTP::Session session
SV * callback
SV * svdata
PREINIT:
HV * rh;
CODE:
rh = (HV *)sv_2mortal((SV *)newHV());
hv_store(rh, "user_data", 9, newSVsv(svdata), 0);
hv_store(rh, "func", 4, newSVsv(callback), 0);
RETVAL = smtp_etrn_enumerate_nodes (session, callback_enum_nodecb, newRV((SV *)rh));
OUTPUT:
RETVAL
int
smtp_enumerate_messages (session, callback, svdata = 0)
Net::ESMTP::Session session
SV * callback
SV * svdata
PREINIT:
HV * rh;
CODE:
rh = (HV *)sv_2mortal((SV *)newHV());
hv_store(rh, "user_data", 9, newSVsv(svdata), 0);
hv_store(rh, "func", 4, newSVsv(callback), 0);
RETVAL = smtp_enumerate_messages (session, callback_enum_messagecb, newRV((SV *)rh));
OUTPUT:
RETVAL
## RFC 3207. SMTP Starttls extension.
int
smtp_starttls_enable (session, how = Starttls_ENABLED)
Net::ESMTP::Session session
int how
int
smtp_starttls_set_ctx (session, ctx)
Net::ESMTP::Session session
void * ctx
CODE:
#ifdef USE_OPENSSL
RETVAL = smtp_starttls_set_ctx (session, ctx);
#else
RETVAL = 0;
#endif
OUTPUT:
RETVAL
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::Message PREFIX = smtp_
int
smtp_set_reverse_path (message, mailbox)
Net::ESMTP::Message message
const char * mailbox
int
smtp_set_header (message, header, ...)
Net::ESMTP::Message message
const char * header
CODE:
RETVAL = -1;
if (!header || strlen(header) <= 2) {
XSRETURN(0);
}
// set_date
if (!strncasecmp(header, "Date", 4)) {
if (items == 3)
RETVAL = smtp_set_header (message, header, SvNV(ST(2)));
}
/* Omit special cases, since they are the same to the application */
/*
else
// set_from phrase, mailbox (many values are allowed)
if (!strncasecmp(header, "Disposition-Notification-To", 27) ||
!strncasecmp(header, "From", 4)) {
if (items == 4)
RETVAL = smtp_set_header (message, header, SvPV(ST(2),0), SvPV(ST(3),0));
}
else
// set_string_null
if (!strncasecmp(header, "Message-Id", 10)) {
if (items == 3)
RETVAL = smtp_set_header (message, header, SvPV(ST(2),0));
}
else
// set_sender phrase, mailbox (one value is allowed)
if (!strncasecmp(header, "Sender", 6)) {
if (items == 4)
RETVAL = smtp_set_header (message, header, SvPV(ST(2),0), SvPV(ST(3),0));
}
else
// set_to phrase, mailbox
if (!strncasecmp(header, "To", 2)) {
if (items == 4)
RETVAL = smtp_set_header (message, header, SvPV(ST(2),0), SvPV(ST(3),0));
}
else
// set_cc phrase, mailbox
if (!strncasecmp(header, "Cc", 2) ||
!strncasecmp(header, "Bcc", 3) ||
!strncasecmp(header, "Reply-To", 8)) {
if (items == 4)
RETVAL = smtp_set_header (message, header, SvPV(ST(2),0), SvPV(ST(3),0));
}
*/
else
{
if (items == 3)
RETVAL = smtp_set_header (message, header, SvPV_nolen(ST(2)));
else
if (items == 4)
RETVAL = smtp_set_header (message, header, SvPV_nolen(ST(2)), SvPV_nolen(ST(3)));
}
if (RETVAL == -1) {
RETVAL = 0;
warn ("Wrong number of arguments for header '%s'", header);
}
OUTPUT:
RETVAL
int
smtp_set_header_option (message, header, option, ...)
Net::ESMTP::Message message
const char * header
Net::ESMTP::HeaderOption option
CODE:
if (items == 3) {
RETVAL = smtp_set_header_option (message, header, option);
} else if (items == 4) {
RETVAL = smtp_set_header_option (message, header, option, SvIV(ST(3)));
} else {
croak("Usage: Net::ESMTP::Message::set_header_option(message, header, option[, value])");
}
OUTPUT:
RETVAL
int
smtp_set_resent_headers (message, onoff)
Net::ESMTP::Message message
int onoff
int
smtp_set_messagecb (message, callback, svdata = 0)
Net::ESMTP::Message message
SV * callback
SV * svdata
PREINIT:
HV * rh;
CODE:
rh = (HV *)sv_2mortal((SV *)newHV());
hv_store(rh, "user_data", 9, newSVsv(svdata), 0);
hv_store(rh, "func", 4, newSVsv(callback), 0);
RETVAL = smtp_set_messagecb (message, callback_messagecb, newRV((SV *)rh));
OUTPUT:
RETVAL
#
# Standard callbacks for reading the message from the application.
#
int
smtp_set_message_fp (message, fp)
Net::ESMTP::Message message
FILE * fp
int
smtp_set_message_str (message, str)
Net::ESMTP::Message message
char * str
#
# Net::ESMTP::Status
#
Net::ESMTP::Status
smtp_message_transfer_status (message)
Net::ESMTP::Message message
PREINIT:
HV *hv;
const smtp_status_t *stat;
CODE:
stat = smtp_message_transfer_status (message);
if (!stat)
XSRETURN_UNDEF;
hv = (HV *)sv_2mortal((SV *)newHV());
if (!hv)
XSRETURN_UNDEF;
hv_store(hv, "code", 4 ,newSViv(stat->code) , 0);
hv_store(hv, "text", 4 ,newSVpvn(stat->text, strlen(stat->text)) , 0);
hv_store(hv, "enh_class", 9 ,newSViv(stat->enh_class) , 0);
hv_store(hv, "enh_subject",11 ,newSViv(stat->enh_subject) , 0);
hv_store(hv, "enh_detail", 10 ,newSViv(stat->enh_detail) , 0);
RETVAL = hv;
OUTPUT:
RETVAL
Net::ESMTP::Status
smtp_reverse_path_status (message)
Net::ESMTP::Message message
PREINIT:
HV *hv;
const smtp_status_t *stat;
CODE:
stat = smtp_reverse_path_status (message);
if (!stat)
XSRETURN_UNDEF;
hv = (HV *)sv_2mortal((SV *)newHV());
if (!hv)
XSRETURN_UNDEF;
hv_store(hv, "code", 4 ,newSViv(stat->code) , 0);
hv_store(hv, "text", 4 ,newSVpvn(stat->text, strlen(stat->text)) , 0);
hv_store(hv, "enh_class", 9 ,newSViv(stat->enh_class) , 0);
hv_store(hv, "enh_subject",11 ,newSViv(stat->enh_subject) , 0);
hv_store(hv, "enh_detail", 10 ,newSViv(stat->enh_detail) , 0);
RETVAL = hv;
OUTPUT:
RETVAL
int
smtp_message_reset_status (message)
Net::ESMTP::Message message
## RFC 1891. Delivery Status Notification (DSN)
int
smtp_dsn_set_ret (message, flags)
Net::ESMTP::Message message
int flags
int
smtp_dsn_set_envid (message, envid)
Net::ESMTP::Message message
const char * envid
## RFC 1870. SMTP Size extension.
int
smtp_size_set_estimate (message, size)
Net::ESMTP::Message message
unsigned long size
## RFC 1652. 8bit-MIME Transport
int
smtp_8bitmime_set_body (message, body)
Net::ESMTP::Message message
int body
## RFC 2852. Deliver By
int
smtp_deliverby_set_mode (message, time, mode, trace)
Net::ESMTP::Message message
long time
int mode
int trace
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::Message PREFIX = smtp_message_
#
# application data (void *)
#
void *
smtp_message_set_application_data (message, data)
Net::ESMTP::Message message
void * data
void *
smtp_message_get_application_data (message)
Net::ESMTP::Message message
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::Message PREFIX = smtp_
Net::ESMTP::Recipient
smtp_add_recipient (message, mailbox)
Net::ESMTP::Message message
const char * mailbox
int
smtp_enumerate_recipients (message, callback, svdata = 0)
Net::ESMTP::Message message
SV * callback
SV * svdata
PREINIT:
HV * rh;
CODE:
rh = (HV *)sv_2mortal((SV *)newHV());
hv_store(rh, "user_data", 9, newSVsv(svdata), 0);
hv_store(rh, "func", 4, newSVsv(callback), 0);
RETVAL = smtp_enumerate_recipients (message, callback_enum_recipientcb, newRV((SV *)rh));
OUTPUT:
RETVAL
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::Recipient PREFIX = smtp_
Net::ESMTP::Status
smtp_recipient_status (recipient)
Net::ESMTP::Recipient recipient
PREINIT:
HV *hv;
const smtp_status_t *stat;
CODE:
stat = smtp_recipient_status (recipient);
if (!stat)
XSRETURN_UNDEF;
hv = (HV *)sv_2mortal((SV *)newHV());
if (!hv)
XSRETURN_UNDEF;
hv_store(hv, "code", 4 ,newSViv(stat->code) , 0);
hv_store(hv, "text", 4 ,newSVpvn(stat->text, strlen(stat->text)) , 0);
hv_store(hv, "enh_class", 9 ,newSViv(stat->enh_class) , 0);
hv_store(hv, "enh_subject",11 ,newSViv(stat->enh_subject) , 0);
hv_store(hv, "enh_detail", 10 ,newSViv(stat->enh_detail) , 0);
RETVAL = hv;
OUTPUT:
RETVAL
int
smtp_recipient_check_complete (recipient)
Net::ESMTP::Recipient recipient
int
smtp_recipient_reset_status (recipient)
Net::ESMTP::Recipient recipient
## RFC 1891. Delivery Status Notification (DSN)
int
smtp_dsn_set_notify (recipient, notify)
Net::ESMTP::Recipient recipient
int notify
int
smtp_dsn_set_orcpt (recipient, address_type, address)
Net::ESMTP::Recipient recipient
const char * address_type
const char * address
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::Recipient PREFIX = smtp_recipient_
#
# application data (void *)
#
void *
smtp_recipient_set_application_data (recipient, data)
Net::ESMTP::Recipient recipient
void * data
void *
smtp_recipient_get_application_data (recipient)
Net::ESMTP::Recipient recipient
MODULE = Net::ESMTP PACKAGE = Net::ESMTP
int
smtp_errno ()
SV *
smtp_strerror (error)
int error
PREINIT:
char buf[256];
char *ret;
CODE:
if ((ret = smtp_strerror (error, buf, 255)) == NULL)
XSRETURN_UNDEF;
RETVAL = newSVpv (ret, 0);
OUTPUT:
RETVAL
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::EtrnNode PREFIX = smtp_
## RFC 1985. Remote Message Queue Starting (ETRN)
Net::ESMTP::Status
smtp_etrn_node_status (node)
Net::ESMTP::EtrnNode node
PREINIT:
HV *hv;
const smtp_status_t *stat;
CODE:
stat = smtp_etrn_node_status (node);
if (!stat)
XSRETURN_UNDEF;
hv = (HV *)sv_2mortal((SV *)newHV());
if (!hv)
XSRETURN_UNDEF;
hv_store(hv, "code", 4 ,newSViv(stat->code) , 0);
hv_store(hv, "text", 4 ,newSVpvn(stat->text, strlen(stat->text)) , 0);
hv_store(hv, "enh_class", 9 ,newSViv(stat->enh_class) , 0);
hv_store(hv, "enh_subject",11 ,newSViv(stat->enh_subject) , 0);
hv_store(hv, "enh_detail", 10 ,newSViv(stat->enh_detail) , 0);
RETVAL = hv;
OUTPUT:
RETVAL
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::EtrnNode PREFIX = smtp_etrn_
void *
smtp_etrn_set_application_data (node, data)
Net::ESMTP::EtrnNode node
void * data
void *
smtp_etrn_get_application_data (node)
Net::ESMTP::EtrnNode node
MODULE = Net::ESMTP PACKAGE = Net::ESMTP::Auth PREFIX = auth_
Net::ESMTP::Auth
auth_new (Class = "Net::ESMTP::Auth")
const char * Class
CODE:
#ifdef _auth_client_h
RETVAL = auth_create_context ();
#else
RETVAL = &PL_sv_undef;
#endif
OUTPUT:
RETVAL
void
DESTROY (context)
Net::ESMTP::Auth context
CODE:
#ifdef _auth_client_h
auth_destroy_context (context);
#endif
#ifdef _auth_client_h
int
auth_set_mechanism_flags (context, set, clear)
Net::ESMTP::Auth context
unsigned int set
unsigned int clear
int
auth_set_mechanism_ssf (context, min_ssf)
Net::ESMTP::Auth context
int min_ssf
int
auth_set_interact_cb (context, callback, svdata = 0)
Net::ESMTP::Auth context
SV * callback
SV * svdata
PREINIT:
HV * rh;
CODE:
rh = (HV *)sv_2mortal((SV *)newHV());
hv_store(rh, "user_data", 9, newSVsv(svdata), 0);
hv_store(rh, "func", 4, newSVsv(callback), 0);
RETVAL = auth_set_interact_cb (context, callback_auth_interactcb, newRV((SV *)rh));
OUTPUT:
RETVAL
int
auth_client_enabled(context)
Net::ESMTP::Auth context
int
auth_set_mechanism(context, name)
Net::ESMTP::Auth context
const char * name
const char *
auth_mechanism_name (context)
Net::ESMTP::Auth context
SV *
auth_response(context, challenge)
Net::ESMTP::Auth context
const char * challenge
PREINIT:
const char * text;
int len;
CODE:
text = auth_response(context, challenge, &len);
RETVAL = newSVpvn (text, len);
OUTPUT:
RETVAL
int
auth_get_ssf(context)
Net::ESMTP::Auth context
SV *
auth_encode(context, svsrc)
Net::ESMTP::Auth context
SV * svsrc
PREINIT:
char *dstbuf;
char *srcbuf;
int dstlen;
STRLEN srclen;
CODE:
srcbuf = SvPV(svsrc, srclen);
auth_encode(&dstbuf, &dstlen, srcbuf, srclen, (void *)context);
if (dstlen > 0) {
RETVAL = newSVpvn (dstbuf, dstlen);
} else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV *
auth_decode(context, svsrc)
Net::ESMTP::Auth context
SV * svsrc
PREINIT:
char *dstbuf;
char *srcbuf;
int dstlen;
STRLEN srclen;
CODE:
srcbuf = SvPV(svsrc, srclen);
auth_decode(&dstbuf, &dstlen, srcbuf, srclen, (void *)context);
if (dstlen > 0) {
RETVAL = newSVpvn (dstbuf, dstlen);
} else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int
auth_set_external_id (context, identity)
Net::ESMTP::Auth context
const char * identity
#endif