[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++ ; } } }