/[cvs]/cgi/mailback/mailback.pl

Contents of /cgi/mailback/mailback.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download)
Thu Jul 25 01:41:21 2002 UTC (8 years, 1 month ago) by erik
Branch: MAIN
Changes since 1.1: +5 -5 lines
File MIME type: text/plain
02/26/99
1 #!/usr/local/bin/taintperl
2
3 # $Id: mailback.pl,v 1.2 2002/07/25 01:41:21 erik Exp $
4 #
5 # Author: Erik C. Thauvin <erik@skytouch.com>
6 #
7 # Thanks to David Walker <dwalker@eskimo.com> and Robert Dinse
8 # <nanook@eskimo.com> for the great suggestions.
9 #
10 # This script will mail the content of any HTML form to its author.
11 #
12 # Based on "mailback.pl" by Phillip Moore <phil@erc.msstate.edu>
13 # Source available at http://www.erc.msstate.edu/~phil/src/mailback.pl
14 #
15 # Also based on "sendmail-cgi.pl" by Erik C. Thauvin <erik@skytouch.com>
16 # Copyright (C) 1995-99 Erik C. Thauvin. All rights reserved.
17 #
18 # Date: 02/26/99
19 #
20 # Usage: You must reference this script in your HTML forms with
21 # the method=POST option. Options are passed inside the
22 # the document with the input tag, as follows:
23 #
24 # <input name="variable-name" type="input-type" value="default-value">
25 #
26 # The variable-name represents parameters for this script.
27 # The following are reserved names used by the script and
28 # must be specified in your HTML documents/forms:
29 #
30 # mailitto (req) - Full internet mail address of mail recipient.
31 # This MUST be your email address on Eskimo.
32 #
33 # namefrom (req) - Name of the person the submission is from.
34 #
35 # mailfrom (req) - Email address of the person the submission
36 # is from.
37 #
38 # subject (req) - Subject of the email message.
39 #
40 # bcc - If defined, sends a blind carbon copy of the
41 # mail message to the person submitting the form.
42 #
43 # showreport - If defined, a mail status report is shown upon
44 # submission; otherwise a generic confirmation
45 # message is displayed.
46 #
47 # returngraphic - Inline image to be displayed at the bottom of
48 # the mail confirmation/status report.
49 #
50 # returntext - If "retrungraphic" is defined, the text is used
51 # as an alternate to the "returngraphic" for non-
52 # graphical browsers, such as lynx.
53 # If "returngraphic" is not defined, the text is
54 # displayed instead of the image.
55 #
56 # returnurl - The URL of "returngraphic" and/or "returntext".
57 # If not defined, the URL of the previous page is
58 # used.
59 #
60 # returnmsg - The actual confirmation message. If not defined,
61 # a generic message is used.
62 #
63 # returntitle - The confirmation message's title. If not defined,
64 # "Mail Confirmation" is used.
65 #
66 # returnpage - The URL of a custom "Mail Confirmation" page.
67 # Overrides "showreport", "returntext", "returnurl",
68 # "returngraphic", "returnmsg" and "returntitle".
69 #
70 # subtag - The name of one of the form's input tag. If valid,
71 # the tag's value will be affixed to the subject of
72 # the mail.
73 #
74 # bodytags - The HTML elements to be included in the <body> tag
75 # of the confirmation/error messages. Example:
76 #
77 # ... value="bgcolor=#FFFFFF vlink=#008000" ...
78 #
79 # base - The URL to be used in the <base> HTML tag of the
80 # confirmation/error messages.
81 #
82 # nozeros - Suppresses input tags whose values are 0.
83 #
84 # noblanks - Suppresses input tags whose values are blank.
85 #
86 # notags - Suppresses input tags from email message.
87 #
88 # senderinfo - Includes "namefrom" and "mailfrom" in the body
89 # of the email message.
90 #
91 # The ones with (req) are required but may be written into the HTML
92 # form so that users cannot change them. For example:
93 #
94 # <HTML>
95 # <TITLE>Mailback Sample Form</TITLE>
96 # <BODY>
97 # <FORM ACTION="http:/cgi-bin/mailback" METHOD="POST">
98 # <INPUT TYPE="HIDDEN" NAME="mailitto" VALUE="johndoe@eskimo.com">
99 # <INPUT TYPE="HIDDEN" NAME="returnurl" VALUE="/~johndoe/mypage.html">
100 # <INPUT TYPE="HIDDEN" NAME="returntext" VALUE="Back to my Home Page.">
101 # <INPUT TYPE="HIDDEN" NAME="notags">
102 # <INPUT TYPE="HIDDEN" NAME="showreport">
103 # Your Name: <INPUT TYPE="TEXT" NAME="namefrom" SIZE=35><BR>
104 # Your Email Address: <INPUT TYPE="TEXT" NAME="mailfrom" SIZE=35><BR>
105 # Subject: <INPUT TYPE="TEXT" NAME="subject" SIZE=35><P>
106 # Your Message:<BR>
107 # <TEXTAREA NAME="message" ROWS="10" COLS="60"></TEXTAREA><P>
108 # <INPUT TYPE="RESET" VALUE="Clear Form">
109 # <INPUT TYPE="SUBMIT" VALUE="Send Mail">
110 # </FORM>
111 # </BODY>
112 # </HTML>
113 #
114 # This software is provided "as is" without express or implied warranties.
115 #
116 # Permission is granted to use, copy, modify and distribute this software,
117 # provided this disclaimer and copyright are preserved on all copies. This
118 # software may not, however, be sold or distributed for profit, or included
119 # with other software which is sold or distributed for profit, without the
120 # permission of the author.
121 #
122
123 $ENV{'PATH'} = '/bin:/usr/bin:/usr/lib';
124 $ENV{'IFS'} = '';
125
126
127 #
128 # Mail server address & port
129 #
130 $mailserv = 'mail.eskimo.com';
131 $mailport = 25;
132
133
134 #
135 # CRLF
136 #
137 $eol = "\015\012";
138
139
140 #
141 # Try SMTP?
142 #
143 $trysmtp = 0;
144
145
146 #
147 # Valid mail server hosts
148 #
149 @validhosts = ( 'eskimo.com', 'skytouch.com' );
150
151
152 #
153 # Print text/html error message
154 #
155 sub error
156 {
157 local($msg) = @_;
158
159 &printheader('Error');
160 print "<h1><hr><font size=5>Error</font><hr></h1>\n<blockquote>\n$msg\n</blockquote>\n<p>\n";
161 &printfooter;
162 exit 1;
163 }
164
165
166 #
167 # Return error if mail could not be sent
168 #
169 sub mailerror
170 {
171 close(SOCK);
172 &error("An timeout error (ID=@_) occurred while sending mail. Please try "
173 . "again later or <a href=\"mailto:$posted{mailitto}\">notify</a> "
174 . "the creator of this page.\n<p>\n<p>\nThank you.");
175 }
176
177
178 #
179 # Print detailed text/html error message
180 #
181 sub notenoughinfo
182 {
183 local($msg) = @_;
184
185 if ($infoerr == 0)
186 {
187 &printheader("Error");
188 print "<h1><hr><font size=5>Error</font><hr></h1>\n"
189 . "<h2>Not Enough Information:</h2>"
190 . "<blockquote>\n$msg\n</blockquote>\n";
191 }
192 else
193 {
194 print "<h3>And</h3>\n<blockquote>\n$msg\n</blockquote>\n";
195 }
196 $infoerr++;
197 }
198
199
200 #
201 # Print html header
202 #
203 sub printheader
204 {
205 local($title) = @_;
206
207 print "Content-Type: text/html$eol$eol"
208 . "<html>\n<head>\n";
209
210 if (defined($posted{base}))
211 {
212 print "<base href=\"$posted{base}\">\n";
213 }
214
215 print "<title>$title</title>\n";
216
217 if (defined($posted{bodytags}))
218 {
219 print "</head>\n<body $posted{bodytags}>\n";
220 }
221 else
222 {
223 print "</head>\n<body bgcolor=#ffffff>\n";
224 }
225 }
226
227
228 #
229 # Print html footer
230 #
231 sub printfooter
232 {
233 if (!defined($posted{skipRSLlink}))
234 {
235 print "<a href=\"http://www.skytouch.com/\"><img align=\"right\" alt=\"Designed by...\" src=\"http://www.skytouch.com/images/skytouch-mini.gif\" border=\"0\"></a>";
236 }
237 else
238 {
239 print "<a href=\"#\" onmouseover=\"window.status = 'Designed by SkyTouch Communications'; return(true);\"><img align=\"right\" alt=\"Designed by SkyTouch Communications\" src=\"http://www.skytouch.com/images/skytouch-mini.gif\"></a>";
240 }
241
242 print "<hr>\n";
243
244 if (defined($posted{returnurl}))
245 {
246 if (defined($posted{returngraphic}) && defined($posted{returntext}))
247 {
248 print "<a href=\"$posted{returnurl}\"><img src=\"$posted{returngraphic}\" alt=\"$posted{returntext}\"></a>\n";
249 }
250 elsif (defined($posted{returngraphic}))
251 {
252 print "<a href=\"$posted{returnurl}\"><img src=\"$posted{returngraphic}\"></a>\n";
253 }
254 elsif (defined($posted{returntext}))
255 {
256 print "<a href=\"$posted{returnurl}\">$posted{returntext}</a>\n";
257 }
258 else
259 {
260 print "Follow this <a href=\"$posted{returnurl}\">link</a> to continue.\n";
261 }
262 }
263 else
264 {
265 print "Back to the <a href=\"$ENV{HTTP_REFERER}\">previous</a> page.\n";
266 }
267
268 print "</body>\n</html>";
269 }
270
271
272 #
273 # Get mail server result code
274 #
275 sub getresultcode
276 {
277 local($buff, $resultcode, $bits) = "";
278 local($timeout, $nbr) = 0;
279
280 vec($bits, fileno(SOCK), 1) = 1;
281 LOOP: {
282 if ($timeout <= 2)
283 {
284 ($nfound, $bits) = select($bits, undef, undef, 3);
285 if ($nfound)
286 {
287 $nbr = sysread(SOCK, $buff, 1024);
288 if ($nbr > 0)
289 {
290 if (length($resultcode) < 3)
291 {
292 $resultcode .= substr($buff, 0, 3);
293 if ($resultcode == 220)
294 {
295 $timeout++;
296 redo LOOP;
297 }
298 }
299 if (substr($buff, -1, 1) ne "\012")
300 {
301 $timeout++;
302 redo LOOP;
303 }
304 }
305 }
306 else
307 {
308 $timeout++;
309 redo LOOP;
310 }
311 }
312 else
313 {
314 if ($resultcode != 220)
315 {
316 $resultcode = 554;
317 }
318 }
319 }
320 return $resultcode;
321 }
322
323
324 #
325 # Get host address
326 #
327 sub getaddress
328 {
329 local($host) = @_;
330 local(@addrs);
331
332 @addrs = gethostbyname($host);
333 return(unpack("C4", $addrs[4]));
334 }
335
336
337 #
338 # Verify mail host validity
339 #
340 sub isvalidhost
341 {
342 local($email) = @_;
343 local($name, $host) = split('@', $email);
344
345 foreach (@validhosts)
346 {
347 if ( /$host/i )
348 {
349 return 1;
350 }
351 }
352 return 0;
353 }
354
355
356 #
357 # Ensure that the proper environment variables are defined
358 #
359 if (!defined($ENV{REQUEST_METHOD}) || $ENV{REQUEST_METHOD} ne "POST")
360 {
361 &error("This script should be referenced with a METHOD of POST. If you "
362 . "don't understand this, see the <a href=\"http://www.ncsa.uiuc.edu/SDG"
363 . "/Software/Mosaic/Docs/fill-out-forms/overview.html\">forms overview"
364 . "</a>.\n<p>\n<p>\nThank you.");
365 }
366
367 #
368 # More environment variables
369 #
370 if (!defined($ENV{CONTENT_TYPE}) || $ENV{CONTENT_TYPE} ne "application/x-www-form-urlencoded")
371 {
372 &error("This script can only be used to decode form results.");
373 }
374
375 #
376 # Read in the message based on the CONTENT_LENGTH in the header.
377 # If no CONTENT_LENGTH, complain about the error.
378 #
379 if (defined($ENV{CONTENT_LENGTH}) && $ENV{CONTENT_LENGTH} != 0)
380 {
381 $bytes = read(STDIN, $all, $ENV{CONTENT_LENGTH});
382 foreach $pair (split("&", $all))
383 {
384 ($key, $val) = split("=", $pair);
385 $val =~ tr/+/ /;
386 $val =~ s/%(..)/pack("c", hex($1))/eg;
387 # $val =~ s/\n/\n /g;
388
389 if (defined($posted{$key}))
390 {
391 $posted{$key} = "$posted{$key}\n$val";
392 }
393 else
394 {
395 $posted{$key} = $val;
396 push(@keylist, $key) if ( $key ne "mailitto" &&
397 $key ne "errorsto" &&
398 $key ne "namefrom" &&
399 $key ne "mailfrom" &&
400 $key ne "subject" &&
401 $key ne "bcc" &&
402 $key ne "showreport" &&
403 $key ne "returnurl" &&
404 $key ne "returntext" &&
405 $key ne "returngraphic" &&
406 $key ne "skipRSLlink" &&
407 $key ne "returnmsg" &&
408 $key ne "returntitle" &&
409 $key ne "returnpage" &&
410 $key ne "subtag" &&
411 $key ne "bodytags" &&
412 $key ne "base" &&
413 $key ne "nozeros" &&
414 $key ne "noblanks" &&
415 $key ne "senderinfo" &&
416 $key ne "notags" );
417 }
418 }
419 }
420 else
421 {
422 &error("This script, the URL, or the fields given in the form returned "
423 . "an error. Please notify the creator of this page.\n<p>\n<p>\n"
424 . "Thank you.");
425 }
426
427 #
428 # Check that each of the four required fields are entered properly
429 # Make sure user has entered "mailitto" , "mailfrom", "namefrom"
430 # and "subject"
431 #
432 ### To: ###
433 if (!defined($posted{mailitto}) || !&isvalidhost($posted{mailitto}))
434 {
435 &notenoughinfo("The creator of the form you are using failed to provide "
436 . "a valid e-mail address. Please try again later, or send "
437 . "mail to the person who created this form.<p>");
438 }
439
440 ### From ###
441 if (!defined($posted{namefrom}) || $posted{namefrom} =~ /^\s*$/)
442 {
443 &notenoughinfo("Please provide your first and/or last name to help the "
444 . "reader of this message identify you.<p>");
445 }
446 else
447 {
448 $posted{namefrom} =~ s/^\s*//;
449 $posted{namefrom} =~ s/\s*$//;
450 }
451
452 ### From: ###
453 if (!defined($posted{mailfrom}) ||
454 $posted{mailfrom} !~ /^[-._%!*\/+0-9A-Za-z]+@[-0-9A-Za-z.]+\.[A-Za-z][A-Za-z]+$/)
455 {
456 &notenoughinfo("Please provide a full internet mail address so the reader "
457 . "of this message may reply to you.<p>");
458 }
459 else
460 {
461 $posted{mailfrom} =~ s/^\s*//;
462 $posted{mailfrom} =~ s/\s*$//;
463 }
464
465 ### Subject: ###
466 if (!defined($posted{subject}) || $posted{subject} =~ /^\s*$/)
467 {
468 &notenoughinfo("Please provide a subject to give the reader of this "
469 . "message some clue as to its content.<p>");
470 }
471 else
472 {
473 $posted{subject} =~ s/^\s*//;
474 $posted{subject} =~ s/\s*$//;
475 }
476
477 #
478 # As long as those four fields are non-empty, and in a valid format, send it
479 #
480 if ($infoerr > 0)
481 {
482 &printfooter;
483 exit 1;
484 }
485 else
486 {
487 #
488 # Connect to the mail server
489 #
490 local($sockaddr, $addr) = ("Snc4x8");
491 local($mailagent) = 'sendmail';
492
493 if ($trysmtp)
494 {
495 $addr = pack($sockaddr, 2, $mailport, &getaddress($mailserv));
496
497 if (socket(SOCK, 2, 1, 6))
498 {
499 if (connect(SOCK, $addr))
500 {
501 select(SOCK); $| = 1;
502 select(STDOUT); $| = 1;
503
504 if (&getresultcode != 220)
505 {
506 $mailagent = 'smtp';
507 }
508 }
509 }
510 }
511
512 #
513 # Send mail message
514 #
515 if ($mailagent eq 'sendmail')
516 {
517 close(SOCK);
518 open(SOCK, "| /usr/lib/sendmail -t");
519 }
520 else
521 {
522 print SOCK "HELO mailback$eol";
523 do { &mailerror(1200); } if (&getresultcode != 250);
524
525 print SOCK "RSET$eol";
526 do { &mailerror(1300); } if (&getresultcode != 250);
527
528 print SOCK "MAIL FROM:<>$eol";
529 do { &mailerror(1400); } if (&getresultcode != 250);
530
531 print SOCK "RCPT TO:<$posted{mailitto}>$eol";
532 do { &mailerror(1500); } if (&getresultcode != 250);
533
534 if (defined($posted{bcc}))
535 {
536 print SOCK "RCPT TO:<$posted{mailfrom}>$eol";
537 do { &mailerror(1500); } if (&getresultcode != 250);
538 }
539
540 print SOCK "DATA$eol";
541 do { &mailerror(1600); } if (&getresultcode != 354);
542 }
543
544 print SOCK "From: $posted{mailfrom} ($posted{namefrom})$eol"
545 . "To: $posted{mailitto}$eol";
546
547 if (defined($posted{bcc}))
548 {
549 print SOCK "Bcc: $posted{mailfrom}$eol";
550 }
551
552 if (defined($posted{$posted{subtag}}))
553 {
554 print SOCK "Subject: $posted{subject} ($posted{$posted{subtag}})$eol";
555 }
556 else
557 {
558 print SOCK "Subject: $posted{subject}$eol";
559 }
560
561 if (defined($ENV{REMOTE_ADDRESS})) { print SOCK "X-Remote-Address: $ENV{REMOTE_ADDRESS}$eol"; }
562 if (defined($ENV{REMOTE_HOST})) { print SOCK "X-Remote-Host: $ENV{REMOTE_HOST}$eol"; }
563 if (defined($ENV{REMOTE_IDENT})) { print SOCK "X-Remote-Ident: $ENV{REMOTE_IDENT}$eol"; }
564 if (defined($ENV{REMOTE_USER})) { print SOCK "X-Remote-User: $ENV{REMOTE_USER}$eol"; }
565 if (defined($ENV{HTTP_REFERER})) { print SOCK "X-URL: $ENV{HTTP_REFERER}$eol"; }
566
567 if (defined($posted{senderinfo}))
568 {
569 if (defined($posted{notags}))
570 {
571 print SOCK "$eol$posted{namefrom}$eol"
572 . "$eol$posted{mailfrom}$eol";
573 }
574 else
575 {
576 print SOCK "$eol--- Sender's Name ---$eol$posted{namefrom}$eol"
577 . "$eol--- Sender's Email Address ---$eol$posted{mailfrom}$eol";
578 }
579 }
580
581 foreach $key (@keylist)
582 {
583 $keyval = $posted{$key};
584
585 if (!(defined($posted{noblanks}) && (length($keyval) == 0)))
586 {
587 $keyval =~ s/\012\.\015/\012\.\.\015/g;
588 $keyval =~ s/\012\.$/\012\.\./;
589
590 if (!(defined($posted{nozeros}) && ($keyval eq "0")))
591 {
592 if (defined($posted{notags}))
593 {
594 print SOCK "$eol$keyval$eol";
595 }
596 else
597 {
598 print SOCK "$eol--- $key ---$eol$keyval$eol";
599 }
600 }
601 }
602 }
603
604 print SOCK ".$eol";
605
606 if ($mailagent eq 'smtp')
607 {
608 do { &mailerror(1700); } if (&getresultcode != 250);
609
610 print SOCK "QUIT$eol";
611 }
612
613 close(SOCK);
614 }
615
616
617 #
618 # If "returnpage" is defined...
619 #
620 if (defined($posted{returnpage}))
621 {
622 print "Location: $posted{returnpage}$eol$eol";
623 }
624 #
625 # If "showreport" is defined then show the mail report and have a link
626 # to return back to some page
627 #
628 elsif (defined($posted{showreport}))
629 {
630 &printheader("Mail Status Report");
631 print "<h1><hr><font size=5>Mail Status Report</font><hr></h1>\n\n<p>\n"
632 . "<b>From:</b> $posted{mailfrom} ($posted{namefrom})\n<br>\n"
633 . "<b>Sent To:</b> <a href=\"mailto:$posted{mailitto}\">"
634 . "$posted{mailitto}</a><br>\n";
635
636 if (defined($posted{$posted{subtag}}))
637 {
638 print "<b>Subject:</b> $posted{subject} ($posted{$posted{subtag}})$eol";
639 }
640 else
641 {
642 print "<b>Subject:</b> $posted{subject}$eol";
643 }
644
645 print "<blockquote>\n<pre>";
646
647 foreach $key (@keylist)
648 {
649 $keyval = $posted{$key};
650
651 if (!(defined($posted{noblanks}) && (length($keyval) == 0)))
652 {
653 $keyval =~ s/\&/\&amp\;/g;
654 $keyval =~ s/\</\&lt\;/g;
655 $keyval =~ s/\>/\&gt\;/g;
656
657 if (!(defined($posted{nozeros}) && ($keyval eq "0")))
658 {
659 if (defined($posted{notags}))
660 {
661 print "$keyval\n";
662 }
663 else
664 {
665 print "$key: $keyval\n";
666 }
667 }
668 }
669 }
670 print "</pre></blockquote><h2>Thank You!</h2>\n";
671 &printfooter;
672 }
673 #
674 # If "showreport" is not defined then just show a message
675 # of confirmation and have a link to another page
676 #
677 else
678 {
679 if (defined($posted{returntitle}))
680 {
681 &printheader($posted{returntitle});
682 print "<h1><hr><font size=5>$posted{returntitle}</font><hr></h1>\n<p>\n";
683 }
684 else
685 {
686 &printheader("Mail Confirmation");
687 print "<h1><hr><font size=5>Mail Confirmation</font><hr></h1>\n<p>\n";
688 }
689
690 if (defined($posted{returnmsg}))
691 {
692 print $posted{returnmsg};
693 }
694 else
695 {
696 print "<blockquote>\nYour message was sent to <b><a href=\"mailto:$posted{mailitto}\">"
697 . "$posted{mailitto}</a></b>\n</blockquote>\n<h2>Thank You!</h2>\n";
698 }
699 print "\n<p>\n";
700 &printfooter;
701 }
702 exit 0;

Mail
ViewVC Help
cvs.thauvin.net
svn.thauvin.net
Powered by ViewVC 1.2-dev