/[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.3 - (hide annotations) (download)
Thu Jul 25 01:43:40 2002 UTC (8 years, 1 month ago) by erik
Branch: MAIN
Changes since 1.2: +5 -4 lines
File MIME type: text/plain
02/22/01
1 erik 1.1 #!/usr/local/bin/taintperl
2    
3     # $Id: mailback.pl,v 1.3 2002/07/25 01:43:40 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 erik 1.3 # Copyright (C) 1995-2001 Erik C. Thauvin. All rights reserved.
17 erik 1.1 #
18 erik 1.3 # Date: 02/22/01
19 erik 1.1 #
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 erik 1.2 if ( /$host/i )
348 erik 1.1 {
349     return 1;
350     }
351     }
352     return 0;
353     }
354    
355     #
356     # Ensure that the proper environment variables are defined
357     #
358     if (!defined($ENV{REQUEST_METHOD}) || $ENV{REQUEST_METHOD} ne "POST")
359     {
360     &error("This script should be referenced with a METHOD of POST. If you "
361     . "don't understand this, see the <a href=\"http://www.ncsa.uiuc.edu/SDG"
362     . "/Software/Mosaic/Docs/fill-out-forms/overview.html\">forms overview"
363     . "</a>.\n<p>\n<p>\nThank you.");
364     }
365    
366     #
367     # More environment variables
368     #
369     if (!defined($ENV{CONTENT_TYPE}) || $ENV{CONTENT_TYPE} ne "application/x-www-form-urlencoded")
370     {
371     &error("This script can only be used to decode form results.");
372     }
373    
374     #
375     # Read in the message based on the CONTENT_LENGTH in the header.
376     # If no CONTENT_LENGTH, complain about the error.
377     #
378     if (defined($ENV{CONTENT_LENGTH}) && $ENV{CONTENT_LENGTH} != 0)
379     {
380     $bytes = read(STDIN, $all, $ENV{CONTENT_LENGTH});
381     foreach $pair (split("&", $all))
382     {
383     ($key, $val) = split("=", $pair);
384     $val =~ tr/+/ /;
385     $val =~ s/%(..)/pack("c", hex($1))/eg;
386     # $val =~ s/\n/\n /g;
387    
388     if (defined($posted{$key}))
389     {
390     $posted{$key} = "$posted{$key}\n$val";
391     }
392     else
393     {
394     $posted{$key} = $val;
395     push(@keylist, $key) if ( $key ne "mailitto" &&
396     $key ne "errorsto" &&
397     $key ne "namefrom" &&
398     $key ne "mailfrom" &&
399     $key ne "subject" &&
400     $key ne "bcc" &&
401     $key ne "showreport" &&
402     $key ne "returnurl" &&
403     $key ne "returntext" &&
404     $key ne "returngraphic" &&
405     $key ne "skipRSLlink" &&
406     $key ne "returnmsg" &&
407     $key ne "returntitle" &&
408     $key ne "returnpage" &&
409     $key ne "subtag" &&
410     $key ne "bodytags" &&
411     $key ne "base" &&
412     $key ne "nozeros" &&
413     $key ne "noblanks" &&
414     $key ne "senderinfo" &&
415     $key ne "notags" );
416     }
417     }
418     }
419     else
420     {
421     &error("This script, the URL, or the fields given in the form returned "
422     . "an error. Please notify the creator of this page.\n<p>\n<p>\n"
423     . "Thank you.");
424     }
425    
426     #
427     # Check that each of the four required fields are entered properly
428     # Make sure user has entered "mailitto" , "mailfrom", "namefrom"
429     # and "subject"
430     #
431     ### To: ###
432     if (!defined($posted{mailitto}) || !&isvalidhost($posted{mailitto}))
433     {
434     &notenoughinfo("The creator of the form you are using failed to provide "
435     . "a valid e-mail address. Please try again later, or send "
436     . "mail to the person who created this form.<p>");
437     }
438    
439     ### From ###
440     if (!defined($posted{namefrom}) || $posted{namefrom} =~ /^\s*$/)
441     {
442     &notenoughinfo("Please provide your first and/or last name to help the "
443     . "reader of this message identify you.<p>");
444     }
445     else
446     {
447     $posted{namefrom} =~ s/^\s*//;
448     $posted{namefrom} =~ s/\s*$//;
449     }
450    
451     ### From: ###
452     if (!defined($posted{mailfrom}) ||
453     $posted{mailfrom} !~ /^[-._%!*\/+0-9A-Za-z]+@[-0-9A-Za-z.]+\.[A-Za-z][A-Za-z]+$/)
454     {
455     &notenoughinfo("Please provide a full internet mail address so the reader "
456     . "of this message may reply to you.<p>");
457     }
458     else
459     {
460     $posted{mailfrom} =~ s/^\s*//;
461     $posted{mailfrom} =~ s/\s*$//;
462     }
463    
464     ### Subject: ###
465     if (!defined($posted{subject}) || $posted{subject} =~ /^\s*$/)
466     {
467     &notenoughinfo("Please provide a subject to give the reader of this "
468     . "message some clue as to its content.<p>");
469     }
470     else
471     {
472     $posted{subject} =~ s/^\s*//;
473     $posted{subject} =~ s/\s*$//;
474     }
475    
476     #
477     # As long as those four fields are non-empty, and in a valid format, send it
478     #
479     if ($infoerr > 0)
480     {
481     &printfooter;
482     exit 1;
483     }
484     else
485     {
486     #
487     # Connect to the mail server
488     #
489     local($sockaddr, $addr) = ("Snc4x8");
490     local($mailagent) = 'sendmail';
491    
492     if ($trysmtp)
493     {
494     $addr = pack($sockaddr, 2, $mailport, &getaddress($mailserv));
495    
496     if (socket(SOCK, 2, 1, 6))
497     {
498     if (connect(SOCK, $addr))
499     {
500     select(SOCK); $| = 1;
501     select(STDOUT); $| = 1;
502    
503 erik 1.3 if (&getresultcode == 220)
504 erik 1.1 {
505     $mailagent = 'smtp';
506     }
507     }
508     }
509     }
510    
511     #
512     # Send mail message
513     #
514     if ($mailagent eq 'sendmail')
515     {
516     close(SOCK);
517     open(SOCK, "| /usr/lib/sendmail -t");
518     }
519     else
520     {
521     print SOCK "HELO mailback$eol";
522     do { &mailerror(1200); } if (&getresultcode != 250);
523    
524     print SOCK "RSET$eol";
525     do { &mailerror(1300); } if (&getresultcode != 250);
526    
527     print SOCK "MAIL FROM:<>$eol";
528     do { &mailerror(1400); } if (&getresultcode != 250);
529    
530     print SOCK "RCPT TO:<$posted{mailitto}>$eol";
531     do { &mailerror(1500); } if (&getresultcode != 250);
532    
533     if (defined($posted{bcc}))
534     {
535     print SOCK "RCPT TO:<$posted{mailfrom}>$eol";
536     do { &mailerror(1500); } if (&getresultcode != 250);
537     }
538    
539     print SOCK "DATA$eol";
540     do { &mailerror(1600); } if (&getresultcode != 354);
541     }
542    
543     print SOCK "From: $posted{mailfrom} ($posted{namefrom})$eol"
544     . "To: $posted{mailitto}$eol";
545    
546     if (defined($posted{bcc}))
547     {
548     print SOCK "Bcc: $posted{mailfrom}$eol";
549     }
550    
551     if (defined($posted{$posted{subtag}}))
552     {
553     print SOCK "Subject: $posted{subject} ($posted{$posted{subtag}})$eol";
554     }
555     else
556     {
557     print SOCK "Subject: $posted{subject}$eol";
558     }
559    
560     if (defined($ENV{REMOTE_ADDRESS})) { print SOCK "X-Remote-Address: $ENV{REMOTE_ADDRESS}$eol"; }
561     if (defined($ENV{REMOTE_HOST})) { print SOCK "X-Remote-Host: $ENV{REMOTE_HOST}$eol"; }
562     if (defined($ENV{REMOTE_IDENT})) { print SOCK "X-Remote-Ident: $ENV{REMOTE_IDENT}$eol"; }
563     if (defined($ENV{REMOTE_USER})) { print SOCK "X-Remote-User: $ENV{REMOTE_USER}$eol"; }
564     if (defined($ENV{HTTP_REFERER})) { print SOCK "X-URL: $ENV{HTTP_REFERER}$eol"; }
565 erik 1.3
566     print SOCK "X-Mailback-Agent: $mailagent$eol";
567 erik 1.1
568     if (defined($posted{senderinfo}))
569     {
570     if (defined($posted{notags}))
571     {
572     print SOCK "$eol$posted{namefrom}$eol"
573     . "$eol$posted{mailfrom}$eol";
574     }
575     else
576     {
577 erik 1.2 print SOCK "$eol--- Sender's Name ---$eol$posted{namefrom}$eol"
578     . "$eol--- Sender's Email Address ---$eol$posted{mailfrom}$eol";
579 erik 1.1 }
580     }
581    
582     foreach $key (@keylist)
583     {
584     $keyval = $posted{$key};
585    
586     if (!(defined($posted{noblanks}) && (length($keyval) == 0)))
587     {
588     $keyval =~ s/\012\.\015/\012\.\.\015/g;
589     $keyval =~ s/\012\.$/\012\.\./;
590    
591     if (!(defined($posted{nozeros}) && ($keyval eq "0")))
592     {
593     if (defined($posted{notags}))
594     {
595     print SOCK "$eol$keyval$eol";
596     }
597     else
598     {
599     print SOCK "$eol--- $key ---$eol$keyval$eol";
600     }
601     }
602     }
603     }
604    
605     print SOCK ".$eol";
606    
607     if ($mailagent eq 'smtp')
608     {
609     do { &mailerror(1700); } if (&getresultcode != 250);
610    
611     print SOCK "QUIT$eol";
612     }
613    
614     close(SOCK);
615     }
616    
617    
618     #
619     # If "returnpage" is defined...
620     #
621     if (defined($posted{returnpage}))
622     {
623     print "Location: $posted{returnpage}$eol$eol";
624     }
625     #
626     # If "showreport" is defined then show the mail report and have a link
627     # to return back to some page
628     #
629     elsif (defined($posted{showreport}))
630     {
631     &printheader("Mail Status Report");
632     print "<h1><hr><font size=5>Mail Status Report</font><hr></h1>\n\n<p>\n"
633     . "<b>From:</b> $posted{mailfrom} ($posted{namefrom})\n<br>\n"
634     . "<b>Sent To:</b> <a href=\"mailto:$posted{mailitto}\">"
635     . "$posted{mailitto}</a><br>\n";
636    
637     if (defined($posted{$posted{subtag}}))
638     {
639     print "<b>Subject:</b> $posted{subject} ($posted{$posted{subtag}})$eol";
640     }
641     else
642     {
643     print "<b>Subject:</b> $posted{subject}$eol";
644     }
645    
646     print "<blockquote>\n<pre>";
647    
648     foreach $key (@keylist)
649     {
650     $keyval = $posted{$key};
651    
652     if (!(defined($posted{noblanks}) && (length($keyval) == 0)))
653     {
654     $keyval =~ s/\&/\&amp\;/g;
655     $keyval =~ s/\</\&lt\;/g;
656     $keyval =~ s/\>/\&gt\;/g;
657    
658     if (!(defined($posted{nozeros}) && ($keyval eq "0")))
659     {
660     if (defined($posted{notags}))
661     {
662     print "$keyval\n";
663     }
664     else
665     {
666     print "$key: $keyval\n";
667     }
668     }
669     }
670     }
671     print "</pre></blockquote><h2>Thank You!</h2>\n";
672     &printfooter;
673     }
674     #
675     # If "showreport" is not defined then just show a message
676     # of confirmation and have a link to another page
677     #
678     else
679     {
680     if (defined($posted{returntitle}))
681     {
682     &printheader($posted{returntitle});
683     print "<h1><hr><font size=5>$posted{returntitle}</font><hr></h1>\n<p>\n";
684     }
685     else
686     {
687     &printheader("Mail Confirmation");
688     print "<h1><hr><font size=5>Mail Confirmation</font><hr></h1>\n<p>\n";
689     }
690    
691     if (defined($posted{returnmsg}))
692     {
693     print $posted{returnmsg};
694     }
695     else
696     {
697     print "<blockquote>\nYour message was sent to <b><a href=\"mailto:$posted{mailitto}\">"
698     . "$posted{mailitto}</a></b>\n</blockquote>\n<h2>Thank You!</h2>\n";
699     }
700     print "\n<p>\n";
701     &printfooter;
702     }
703     exit 0;

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