[0001]
[0002]
[0003]
[0004]
[0005]
[0006]
[0007]
[0008]
[0009]
[0010]
[0011]
[0012]
[0013]
[0014]
[0015]
[0016]
[0017]
[0018]
[0019]
[0020]
[0021]
[0022]
[0023]
[0024]
[0025]
[0026]
[0027]
[0028]
[0029]
[0030]
[0031]
[0032]
[0033]
[0034]
[0035]
[0036]
[0037]
[0038]
[0039]
[0040]
[0041]
[0042]
[0043]
[0044]
[0045]
[0046]
[0047]
[0048]
[0049]
[0050]
[0051]
[0052]
[0053]
[0054]
[0055]
[0056]
[0057]
[0058]
[0059]
[0060]
[0061]
[0062]
[0063]
[0064]
[0065]
[0066]
[0067]
[0068]
[0069]
[0070]
[0071]
[0072]
[0073]
[0074]
[0075]
[0076]
[0077]
[0078]
[0079]
[0080]
[0081]
[0082]
[0083]
[0084]
[0085]
[0086]
[0087]
[0088]
[0089]
[0090]
[0091]
[0092]
[0093]
[0094]
[0095]
[0096]
[0097]
[0098]
[0099]
[0100]
[0101]
[0102]
[0103]
[0104]
[0105]
[0106]
[0107]
[0108]
[0109]
[0110]
[0111]
[0112]
[0113]
[0114]
[0115]
[0116]
[0117]
[0118]
[0119]
[0120]
[0121]
[0122]
[0123]
[0124]
[0125]
[0126]
[0127]
[0128]
[0129]
[0130]
[0131]
[0132]
[0133]
[0134]
[0135]
[0136]
[0137]
[0138]
[0139]
[0140]
[0141]
[0142]
[0143]
[0144]
[0145]
[0146]
[0147]
[0148]
[0149]
[0150]
[0151]
[0152]
[0153]
[0154]
[0155]
[0156]
[0157]
[0158]
[0159]
[0160]
[0161]
[0162]
[0163]
[0164]
[0165]
[0166]
[0167]
[0168]
[0169]
[0170]
[0171]
[0172]
[0173]
[0174]
[0175]
[0176]
[0177]
[0178]
[0179]
[0180]
[0181]
[0182]
[0183]
[0184]
[0185]
[0186]
[0187]
[0188]
[0189]
[0190]
[0191]
[0192]
[0193]
[0194]
[0195]
[0196]
[0197]
[0198]
[0199]
[0200]
[0201]
[0202]
[0203]
[0204]
[0205]
[0206]
[0207]
[0208]
[0209]
[0210]
[0211]
[0212]
[0213]
[0214]
[0215]
[0216]
[0217]
[0218]
[0219]
[0220]
[0221]
[0222]
[0223]
[0224]
[0225]
[0226]
[0227]
[0228]
[0229]
[0230]
[0231]
[0232]
[0233]
[0234]
[0235]
[0236]
[0237]
[0238]
[0239]
[0240]
[0241]
[0242]
[0243]
[0244]
[0245]
[0246]
[0247]
[0248]
[0249]
[0250]
[0251]
[0252]
[0253]
[0254]
[0255]
[0256]
[0257]
[0258]
[0259]
[0260]
[0261]
[0262]
[0263]
[0264]
[0265]
[0266]
[0267]
[0268]
[0269]
[0270]
[0271]
[0272]
[0273]
[0274]
[0275]
[0276]
[0277]
[0278]
[0279]
[0280]
[0281]
[0282]
[0283]
[0284]
[0285]
[0286]
[0287]
[0288]
[0289]
[0290]
[0291]
[0292]
[0293]
[0294]
[0295]
[0296]
[0297]
[0298]
[0299]
[0300]
[0301]
[0302]
[0303]
[0304]
[0305]
[0306]
[0307]
[0308]
[0309]
[0310]
[0311]
[0312]
[0313]
[0314]
[0315]
[0316]
[0317]
[0318]
[0319]
[0320]
[0321]
[0322]
[0323]
[0324]
[0325]
[0326]
[0327]
[0328]
[0329]
[0330]
[0331]
[0332]
[0333]
[0334]
[0335]
[0336]
[0337]
[0338]
[0339]
[0340]
[0341]
[0342]
[0343]
[0344]
[0345]
[0346]
[0347]
[0348]
[0349]
[0350]
[0351]
[0352]
[0353]
[0354]
[0355]
[0356]
[0357]
[0358]
[0359]
[0360]
[0361]
[0362]
[0363]
[0364]
[0365]
[0366]
[0367]
[0368]
[0369]
[0370]
[0371]
[0372]
[0373]
[0374]
[0375]
[0376]
[0377]
[0378]
[0379]
[0380]
[0381]
[0382]
[0383]
[0384]
[0385]
[0386]
[0387]
[0388]
[0389]
[0390]
[0391]
[0392]
[0393]
[0394]
[0395]
[0396]
[0397]
[0398]
[0399]
[0400]
[0401]
[0402]
[0403]
[0404]
[0405]
[0406]
[0407]
[0408]
[0409]
[0410]
[0411]
[0412]
[0413]
[0414]
[0415]
[0416]
[0417]
[0418]
[0419]
[0420]
[0421]
[0422]
[0423]
[0424]
[0425]
[0426]
[0427]
[0428]
[0429]
[0430]
[0431]
[0432]
[0433]
[0434]
[0435]
[0436]
[0437]
[0438]
[0439]
[0440]
[0441]
[0442]
[0443]
[0444]
[0445]
[0446]
[0447]
[0448]
[0449]
[0450]
[0451]
[0452]
[0453]
[0454]
[0455]
[0456]
[0457]
[0458]
[0459]
[0460]
[0461]
[0462]
[0463]
[0464]
[0465]
[0466]
[0467]
[0468]
[0469]
[0470]
[0471]
[0472]
[0473]
[0474]
[0475]
[0476]
[0477]
[0478]
[0479]
[0480]
[0481]
[0482]
[0483]
[0484]
[0485]
[0486]
[0487]
[0488]
[0489]
[0490]
[0491]
[0492]
[0493]
[0494]
[0495]
[0496]
[0497]
[0498]
[0499]
[0500]
[0501]
[0502]
[0503]
[0504]
[0505]
[0506]
[0507]
[0508]
[0509]
[0510]
[0511]
[0512]
[0513]
[0514]
[0515]
[0516]
[0517]
[0518]
[0519]
[0520]
[0521]
[0522]
[0523]
[0524]
[0525]
[0526]
[0527]
[0528]
[0529]
[0530]
[0531]
[0532]
[0533]
/*
**++
**  FACILITY:  WWW CGI Scripts
**
**  MODULE DESCRIPTION:
**
**      This mails the contents of a FORM POSTed to the URL invoking ths
**	program.  The url embeds the mail address as follows:
**
**	http://www.acornsw.com/htbin/cgi-mailto.exe/mailaddress
**
**	For for mail to local user's, the user's web directory must
**	contain the file .www_mailable before the script will deliver
**	mail to that account.
**
**  AUTHORS:
**
**      Dick Munroe
**	Acorn Software, Inc.
**	179 Great Rd.
**	Acton, Ma. 01720
**
**	(508) 266-9800
**	fax:  266-9707
**	
**	munroe@acornsw.com
**
**      David Jones
**	Ohio State University
**
**  CREATION DATE:  04-Dec-94
**
**  DESIGN ISSUES:
**
**      {@tbs@}
**
**  [@optional module tags@]...
**
**  MODIFICATION HISTORY:
**
**      0.000 Dick Munroe 04-Dec-94
**	    Initial Version Created.
**
**	0.001 David Jones 10-Dec-1994
**	    Added check for .www_mailable to web directory.
**	    
**	0.002 David Jones 6-Feb-1995
**	    Convert extra path info to subject line for mail message.
**	    Include REMOTE_ADDRESS info in mail message.
**
**	0.003 David Jones 28-Feb-1995
**	    Remove FROM_LINE from send_attribute call.
**
**	0.004 David Jones 16-May-1995
**	    Use new cgi_translate_path routine to verify .www_mailable.
**
**      0.005 D. Jones 21-Jun-1995
**	   Delete extra '\r's in cgi_printf() calls ('\n's are automatically
**	   converted to "\r\n" already.
**	[@tbs@]...
**--
*/

#if defined(__ALPHA)
#pragma nomember_alignment
#endif

/** MGD **/
#if defined(__ia64)
#pragma nomember_alignment
#endif

/*
**
**  INCLUDE FILES
**
*/

#include <stdio.h>
#include <stat.h>
#include <prvdef.h>

#include "cgi-mailto.h"
#include "cgilib.h"
/* #include "utl-itemlist.h" */
struct ItemList { short int length, code; char *buffer; long returnLength; };

#include <descrip.h>
#include <jpidef.h>
#include <lib$routines.h>
#include <maildef.h>
#include <ssdef.h>
#include <stdlib.h>
#include <str$routines.h>
#include <string.h>
#include <stsdef.h>

static char*				getField(char*) ;
static void				getFieldNameAndValue(char*,char**,char**) ;
static char*				getRepeatedFieldValue(char*) ;
static void				htmlStrcpy(char*, char*) ;
extern unsigned long			mail$send_begin() ;
extern unsigned long			mail$send_add_attribute() ;
extern unsigned long			mail$send_add_address() ;
extern unsigned long			mail$send_add_bodypart() ;
extern unsigned long			mail$send_message() ;
extern unsigned long			mail$send_end() ;

int main ( int argc, char **argv )
{
    char				buffer[1024] ;
    char				*content_data;
    int					content_length;
    char				*cp ;
    int					i, sys$setprv() ;
    struct ItemList			itemList[10] ;
    struct ItemList			nullItemList = {0, 0, 0, 0} ;
    unsigned long			sendContext = 0 ;
    long				privs[2], priv_mask[2];
    int					status;
    char				*to ;
    char				*subject, *raddr;
    struct dsc$descriptor_d		xxxDesc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0};

    priv_mask[0] = PRV$M_SYSPRV;
    priv_mask[1] = 0;
    status = sys$setprv ( 0, priv_mask, 0, privs );
    if ( (status&1) == 0 ){ fprintf(stderr,"setprv error: %d\n", status ); }
    fprintf(stderr,"Priv mask: %x, previous privs: %x\n", priv_mask[0],
	privs[0] );
#define ENABLE_SYSPRV if (priv_mask[0]&privs[0]) sys$setprv(1,priv_mask,0,0);
#define DISABLE_SYSPRV if (priv_mask[0]&privs[0]) sys$setprv(0,priv_mask,0,0);

    status = cgi_init_env ( argc, argv );

    to = cgi_info( ("PATH_INFO") ) ;			/* PATH_INFO is of the form /mailaddress				*/
    to++ ;						/* Advance past the /							*/
    if (strchr (to, '@') != NULL)
    {
    	sprintf (buffer, TO_ADDRESS, to) ;
	subject = "";
	to = buffer ;					/* The address is one on a distant machine, so set up the mail		*/
							/* transport.								*/
    } else {
	/* Verify that user has enabled recieving mail */
	int xlate_len;
	stat_t s_buf;
	char control_doc[400], translation[800];
	subject = strchr ( to, '/' );
	if ( subject ) {
	    int k;
	    *subject++ = '\0';
	    for ( k = 0; subject[k]; k++ ) 
		if (subject[k] == '/') subject[k] = ' ';
	} else subject = "";

	sprintf ( control_doc, "(GET)/~%s/.www_mailable", to );
	status = cgi_translate_path ( control_doc, 1, translation,
		sizeof(translation)-1, &xlate_len );
	translation[xlate_len] = '\0';
	if ( (status&1) && (xlate_len > 0) ) {
	    /* If we can't stat file, treat as translation failure */
	    if ( stat ( translation, &s_buf ) < 0 ) xlate_len = 0;
	}
	if ( xlate_len == 0 ) {
	    cgi_begin_output ( 1 );
	    cgi_printf("content-type: text/plain\n\n");	/* CGI header */
	    cgi_printf ( 
		"Cannot send MAIL to %s, no .www_mailable file present\n",
			to );
	    cgi_printf ( "in user's web directory\n" );
	    cgi_printf ( "(%s)",  translation[0] ? translation : control_doc );
	    return 1;
	}
    }
    cgi_begin_output ( 1 );
    cgi_printf("content-type: text/plain\n\n");	/* CGI header */
    cgi_printf("Sending form data as MAIL to: %s\n",to);
    
    content_length = atoi(cgi_info ("CONTENT_LENGTH"));
    if (content_length == 0)
    {
	cgi_printf("Send failed: No data in CONTENT_LENGTH\n") ;
	return 1;
    }

    content_data = (char *) malloc(sizeof(char)*(content_length+1));
    status = cgi_read(content_data, content_length);
    if (status == 0)
    {
	cgi_printf("Send failed: No data from cgi_read\n") ;
	return 1;
    }
    content_data[content_length] = '\0';

    ENABLE_SYSPRV
    status =
	mail$send_begin (
	    &sendContext,
	    &nullItemList,
	    &nullItemList) ;				/* Set up to construct the mail context.				 */
    DISABLE_SYSPRV
    if (!$VMS_STATUS_SUCCESS(status))
    {
	cgi_printf("Send failed: MAIL$SEND_BEGIN returned %%X%0X\n",status) ;
	return 1 ;
    } ;

    /*
    ** Now build up the attributes of the message.  
    */

    status = JPI$_USERNAME ;
    lib$getjpi (&status, 0, 0, 0, &xxxDesc,0) ;
    str$trim (&xxxDesc, &xxxDesc) ;

    i = -1 ;
    itemList[++i].length =		strlen(to) ;
    itemList[i].code =			MAIL$_SEND_TO_LINE ;
    itemList[i].buffer =		to ;
    itemList[i].returnLength =	0 ;
#ifdef DONT_NEED_SYSPRV
    itemList[++i].length =		xxxDesc.dsc$w_length ;
    itemList[i].code =			MAIL$_SEND_FROM_LINE ;
    itemList[i].buffer =	        xxxDesc.dsc$a_pointer ;
    itemList[i].returnLength =	0 ;
#endif
    itemList[++i].length =		strlen(subject);
    itemList[i].code =			MAIL$_SEND_SUBJECT ;
    itemList[i].buffer =		subject;
    itemList[i].returnLength =	0 ;
    itemList[++i].length =		0 ;
    itemList[i].code =			0 ;

    ENABLE_SYSPRV
    status =
	mail$send_add_attribute (
	    &sendContext,
	    &itemList,
	    &nullItemList) ;				/* Add the the message header.						 */
    if (!$VMS_STATUS_SUCCESS(status))
    {
	cgi_printf("Send failed: MAIL$SEND_ADD_ATTRIBUTE returned %%X%0X\n",status) ;
	return 1 ;
    } ;

    i = -1 ;
    itemList[++i].length =		strlen(to) ;
    itemList[i].code =			MAIL$_SEND_USERNAME ;
    itemList[i].buffer =		to ;
    itemList[i].returnLength =	0 ;
    itemList[++i] = nullItemList ;			/* The itemlist describes an address of a receipient.			 */

    status =
	mail$send_add_address (
	    &sendContext,
	    &itemList,
	    &nullItemList) ;				/* Add the sender of the message to the list of receipients.		 */
    if (!$VMS_STATUS_SUCCESS(status))
    {
	cgi_printf("Send failed: MAIL$SEND_ADD_ADDRESS returned %%X%0X\n",status) ;
	return 1 ;
    } ;

    /*
    ** Include address of sender.
    */
    raddr = cgi_info ( "REMOTE_ADDR" );
    if ( raddr ) {
	sprintf ( buffer, "REMOTE_ADDRESS: %s", raddr );
        i = -1 ;
        itemList[++i].length =	strlen(buffer) ;
        itemList[i].code =		MAIL$_SEND_RECORD ;
        itemList[i].buffer =	buffer ;
        itemList[i].returnLength =	0 ;
        itemList[++i] = nullItemList ;		/* The itemlist describes the body of the message.			 */
	    
        status = mail$send_add_bodypart (&sendContext, &itemList, &nullItemList) ;
							/* Add the body to the message.						 */
        if (!$VMS_STATUS_SUCCESS(status))
        {
	    cgi_printf("Send failed: MAIL$SEND_ADD_BODYPART returned %%X%0X\n",status) ;
	    return 1 ;
        } ;
    }
    /*
    ** The content data is of the form:
    **
    **	fieldName=fielddata[&fieldName=fielddata...]
    */
    
    for (cp = getField(content_data); cp; cp = getField(NULL))
    {
	char				*field ;
	int				j = 0 ;
	int				multiline = 0 ;
	char				*name ;
	char				*value ;

#ifdef DEBUG
	printf ("%s\n", cp) ;
	printf ("%d\n", strlen(cp)) ;
#endif
	getFieldNameAndValue(cp, &name, &value) ;

#ifdef DEBUG
	printf ("%p\n", name) ;
	printf ("%s\n", name) ;
	printf ("%d\n", strlen(name)) ;
	printf ("%p\n", value) ;
	printf ("%s\n", value) ;
	printf ("%d\n", strlen(value)) ;
#endif
	htmlStrcpy(name, name) ;
#ifdef DEBUG
	printf ("%s\n", name) ;
	printf ("%d\n", strlen(name)) ;
#endif
	htmlStrcpy(value, value) ;
#ifdef DEBUG
	printf ("%s\n", value) ;
	printf ("%d\n", strlen(value)) ;
#endif
	multiline = ((strchr(value,'\n')) && (strlen(name) > 8)) ;
#ifdef DEBUG
	printf ("multiline = %d\n", multiline) ;
#endif
	if (!multiline)
	{
	    multiline = ((strlen(name) > 8) && ((strlen(name) + strlen(value) + 2) > 80)) ;
#ifdef DEBUG
	    printf ("multiline = %d\n", multiline) ;
#endif
	}
	
	for (field = getRepeatedFieldValue(value);  field;  field = getRepeatedFieldValue(NULL))
	{
	    if (j == 0)
	    {
		if (multiline)
		{
		    j = 8 ;
		    sprintf (buffer, "%s:", name) ;

#ifdef DEBUG
		    printf("%s\n", buffer) ;
#endif
		    i = -1 ;
		    itemList[++i].length =	strlen(buffer) ;
		    itemList[i].code =		MAIL$_SEND_RECORD ;
		    itemList[i].buffer =	buffer ;
		    itemList[i].returnLength =	0 ;
		    itemList[++i] = nullItemList ;
		    
		    status = mail$send_add_bodypart (&sendContext, &itemList, &nullItemList) ;
		
		    if (!$VMS_STATUS_SUCCESS(status))
		    {
			cgi_printf("Send failed: MAIL$SEND_ADD_BODYPART returned %%X%0X\n",status) ;
			return 1 ;
		    } ;
		    
		    sprintf (buffer, "%*c%s", j, ' ', field) ;
		}
		else
		{
		    j = strlen(name) + 2 ;
		    sprintf (buffer, "%s: %s", name, field) ;
		}
	    }
	    else
	    {
		sprintf (buffer, "%*c%s", j, ' ', field) ;
	    }
	    
#ifdef DEBUG
	    printf("%s\n", buffer) ;
#endif
	    i = -1 ;
	    itemList[++i].length =	strlen(buffer) ;
	    itemList[i].code =		MAIL$_SEND_RECORD ;
	    itemList[i].buffer =	buffer ;
	    itemList[i].returnLength =	0 ;
	    itemList[++i] = nullItemList ;		/* The itemlist describes the body of the message.			 */
	    
	    status = mail$send_add_bodypart (&sendContext, &itemList, &nullItemList) ;
							/* Add the body to the message.						 */
	    if (!$VMS_STATUS_SUCCESS(status))
	    {
		cgi_printf("Send failed: MAIL$SEND_ADD_BODYPART returned %%X%0X\n",status) ;
		return 1 ;
	    } ;
	}
    }

    status =
	mail$send_message (
	    &sendContext,
	    &nullItemList,
	    &nullItemList) ;				/* Send the message.							 */
    if (!$VMS_STATUS_SUCCESS(status))
    {
	cgi_printf("Send failed: MAIL$SEND_MESSAGE returned %%X%0X\n",status) ;
	return 1 ;
    } ;
	 
    status =
	mail$send_end (
	    &sendContext,
	    &nullItemList,
	    &nullItemList) ;	    			/* Set up to construct the mail context.				 */
    DISABLE_SYSPRV
    if (!$VMS_STATUS_SUCCESS(status))
    {
	cgi_printf("Send failed: MAIL$SEND_END returned %%X%0X\n",status) ;
	return 1 ;
    } ;

    str$free1_dx (&xxxDesc) ;

    cgi_printf("Send Succeeded: submitted form data mailed\n") ;
    return 1;
}
•
char* getField (
    char* field)
{
    static char				*cp = NULL ;
    char				*next ;
    char				*xxx ;
    
    if (field)
    {
    	cp = field ;
    }

    if (!cp)
    {
	return cp ;
    }

    next = strchr(cp, '&') ;
    if (next)
    {
	*next++ = 0 ;
    } ;
    
    xxx = cp ;
    cp = next ;
    return xxx ;
}
•
void getFieldNameAndValue (
    char* field,
    char** name,
    char** value)
{
    char				*cp ;
    
    if (!field)
    {
	*name = NULL ;
	*value = NULL ;
	return ;
    }

    *name = field ;
    cp = strchr(field, '=') ;
    if (!cp)
    {
	*name = NULL ;
	*value = NULL ;
	return ;
    }
    *cp++ = 0 ;
    *value = cp ;
    return ;
}
•
char* getRepeatedFieldValue (
    char* field)
{
    static char				*cp = NULL ;
    char				*next ;
    char				*xxx ;
    
    if (field)
    {
    	cp = field ;
    }

    if (!cp)
    {
	return cp ;
    }

    next = strchr(cp, '\n') ;
    if (next)
    {
	*next++ = 0 ;
    } ;
    
    xxx = cp ;
    cp = next ;
    return xxx ;
}
•
void htmlStrcpy (
    char *out,
    char *in)
{
    int					i ;
    for (i = strlen(in);  i >= 0;  i--)
    {
    	if (*in == '%')
	{
	    int				xxx ;

	    sscanf (&in[1], "%02x", &xxx) ;
	    *out++ = (char) xxx ;
	    i -= 2 ;
	    in += 3 ;
	}
	else if ( *in == '+' ) {
	    *out++ = ' ';
	    in++;
	}
	else
	{
	    *out++ = *in++ ;
	}
    }
}