#!/usr/local/bin/perl # afm.cgi - Any Form Mailer v1.0 # (c)1998 Bernhard Tischler # # # This script may be used and modified free of charge by anyone so # long as all copyright notices remain intact. If you think, that you # have made a real improvement to this script, than email me. # # Selling the code for this program without prior written consent is # expressly forbidden. In other words, please ask first before you # try and make money of my program. # # Obtain permission before redistributing this software over the # Internet or in any other medium. In all cases copyright and header # must remain intact. # # Script setup: # ------------- # # Change the first line of this file, if necessary. Either # '#!/usr/local/bin/perl' or '#!/usr/bin/perl' should work on any unix # system. # Change the configuration part below as described below. # Upload this file as ASCII to your cgi-bin and chmod it to 755, if # you have a unix server. # ( owner: [x]read [x]write [x]execute # group: [x]read [ ]write [x]execute # everyone: [x]read [ ]write [x]execute ) # # Form setup: # ----------- # # Required fields: # #
# # The first line is the location of the mail script. The second line is the alias # of the recipient as specified in %alias (see cofiguration below). # # All other fields are optional, but i guess it would be a good idea to include # some. :) # # Configuration fields: # # - linkURL # This will be used for a link on the confirmation page. Default is # your base directory /. Example: # # # - linkName # This will be used as name for the link specified above. Default is 'home'. # Example: # # - e-mail: # The email address of your visitor. This will appear in the 'From' field of the # messages header. Example: # # - name # The realname of your visitor. This will appear in the 'From' field of the # messages header. Example: # # - subject # The subject of the message. This will appear in the 'Subject' field of the # messages header. Example: # # - required # Specifies required fields. The script will only send mail, if all # required fields are filled out. Example: # # # - bgcolor # Specifies the background color of the confirmation and error pages. # Default value is white. Example: # # # - color # Specifies the font color of the confirmation and error pages. # Default value is black. Example: # # # - face # Specifies the font face used for the confirmation and error pages. # Default value is Arial. Example: # # # - title # Specifies the title of the confirmation page. Default value is # 'message sent'. Example: # # # - redirect # Use it, if you want to use your own confirmation page. Example: # # # All other form fields will get mailed to you. You can include as many # as you like. Example: # your homepage: # will get mailed as # [ hp: ] # .... <--- here comes the users input # # Don't forget to close the form tag with
. # # c-ya ... bernd ###################################### # Configuration # # Uncomment the next four lines, if you don't have access # to a sendmail program like 'sendmail' or 'qmail-inject' # and change $smtp_server to your SMTP server and $LOCALHOST # to the name of your computer. # use Socket; # $LOCALHOST = 'localhost'; # $smtp_server = 'mail.server.com'; # $smtp_port = 25; # Uncomment and change the next line to your sendmail program, # if you have one. If you don't have one specify a smtp_host above. # $sendmail = "/usr/sbin/sendmail -t"; # Choose an alias for every recipient and enter it as shown # (Format: 'alias" => 'name@server.com'). # The alias has to be in the form field # . %alias = ( 'test' => 'webmaster@server.com', 'you' => 'you@your.server.com', 'someone' => 'someone@somewhere.com' ); ####################################### # No need to change anything below this line ... # %config = ( 'e-mail' => '', 'subject' => 'Form Feedback', 'name' => '', 'bgcolor' => 'white', 'redirect' => '', 'title' => 'message sent', 'required' => '', 'face' => 'Arial', 'to' => '', 'color' => 'black', 'linkURL' => '/', 'linkName' => 'home' ); &parse_form; if( $alias{$in{'to'}} ) { $in{'to'} = $alias{$in{'to'}} } else { &unknown_user } &check_required; &parse_config; &build_message; &send_message; &return_html; exit; sub return_html { if( $config{'redirect'} ) { print "Location: $config{'redirect'}\n\n"; exit; } print <<"__STOP__"; Content-Type: text/html $config{'title'}

$config{'title'}


The following message has been sent to $config{'to'}:

$msg

[ $config{'linkName'} ]

__STOP__ } sub missing_fields { my $err = join( ", ", @_ ); print <<"__STOP__"; Content-Type: text/html ERROR - missing fields

ERROR - missing fields


The following required fields were either
left blank or not filled out correctly:
$err
Please hit your browsers <back> button
and correct them.

__STOP__ exit; } sub unknown_user { print <<"__STOP__"; Content-Type: text/html ERROR - unknown user

ERROR - unknown user


$in{'to'} is not a registered user!

[ $config{'linkName'} ]

__STOP__ exit; } sub build_message { my $now_string = gmtime; $msg = "To: $config{'to'}\n"; $msg .= "From: $config{'e-mail'} ($config{'name'})\n"; $msg .= "Subject: $config{'subject'}\n\n"; foreach ( keys %in ) { $in{$_} =~ s/\r\n/\n/g; $msg .= " [ $_: ]\n"; $msg .= "$in{$_}\n\n"; } $msg .= "---\n"; $msg .= "This message was sent to you by $ENV{'REMOTE_ADDR'}\n"; $msg .= "on $now_string (GMT).\n"; } sub send_message { if( defined( $sendmail ) && ( -e $sendmail ) ) { open( MAIL, "| $sendmail" ) or die( "Can't open $sendmail, because: $!\n" ); print MAIL $msg; close( MAIL ); } elsif( $smtp_server && $smtp_port ) { send_smtp_mail( $config{'to'}, $config{'e-mail'}, $msg ); } else { die( "Don't know how to send mail!\nSpecify a smtp_host or a sendmail program!\n" ) } } sub check_required { return unless( $in{'required'} ); my @missing; my @required = split( /\,/, $in{'required'} ); foreach ( @required ) { if( $_ eq 'e-mail' ) { push( @missing, $_ ) unless( &check_mail( $in{$_} ) ) } elsif( !$in{$_} ) { push( @missing, $_ ) } } if( @missing ) { missing_fields( @missing ) } } sub check_mail { if( $_[0] =~ /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/ || $_[0] !~ /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/ ) { return 0; } else { return 1 } } sub parse_config { foreach ( keys %config ) { if( $in{$_} ) { $config{$_} = $in{$_}; delete $in{$_}; } } } sub parse_form { my( @pairs, $value, $name, $buffer ); if( $ENV{'REQUEST_METHOD' } eq 'GET' ) { @pairs = split( /&/, $ENV{'QUERY_STRING'} ); } elsif( $ENV{'REQUEST_METHOD'} eq 'POST' ) { read( STDIN, $buffer, $ENV{'CONTENT_LENGTH'} ); @pairs = split( /&/, $buffer ); } else { die( "unknown REQUEST_METHOD!\n" ) } foreach $pair (@pairs) { ($name, $value) = split( /=/, $pair ); $name =~ tr/+/ /; $value =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $name =~ s///g; $value =~ s///g; if( $in{$name} && $value ) { $in{$name} = "$in{$name}, $value" } else { $in{$name} = $value } } } sub send_smtp_mail { my( $to, $from, $message ) = @_; my( $iaddr, $paddr, $proto ) = undef; $iaddr = inet_aton( $smtp_server ); $paddr = sockaddr_in( $smtp_port, $iaddr ); $proto = getprotobyname( 'tcp' ); socket( SOCK, PF_INET, SOCK_STREAM, $proto ) or return 0; connect( SOCK, $paddr ) or return 0; receive_from_server( \*SOCK ) or return 0; send_to_server( \*SOCK, "HELO $LOCALHOST" ) or return 0; receive_from_server( \*SOCK ) or return 0; send_to_server( \*SOCK, "MAIL FROM: <$from>") or return 0; receive_from_server( \*SOCK ) or return 0; send_to_server( \*SOCK, "RCPT TO: <$to>" ) or return 0; receive_from_server( \*SOCK ) or return 0; send_to_server( \*SOCK, "DATA" ) or return 0; receive_from_server( \*SOCK ) or return 0; send_to_server( \*SOCK, "$message\n." ) or return 0; receive_from_server( \*SOCK ) or return 0; send_to_server( \*SOCK, "QUIT" ) or return 0; receive_from_server( \*SOCK ) or return 0; close( SOCK ) or return 0; return 1; } sub send_to_server { my( $socket ) = shift; my( $message ) = shift; send( $socket, "$message\n", 0 ) or return 0; return 1; } sub receive_from_server { my( $socket ) = shift; my( $reply ); while( $reply = <$socket> ) { return 0 if $reply =~ /^5/; last if $reply =~ /^\d+ /; } return 1; }