#!/usr/bin/perl # subscribe.cgi - web-to-email gateway with many possible recipients, # based on "roles" defined in a text file # copyright (c) 2002 Prescient Code Solutions. All rights reserved. # Please do not redistribute without permission. # contact daniel@coder.com #use strict; require 'cgi-lib.pl'; # configuration my $formfile = 'newsletter-form.html'; my $outputURL = 'http://flgbtqc.quaker.org/newsletter/thanks.html'; my $databasefile = "subscriptions/download.csv"; my $roleDB = '../email-roles.txt'; my $rolename = 'Newsletter_subscriptions'; my $sendmail = '/usr/sbin/sendmail'; my $debug = 0; print &header if $debug; sub error { my $message = shift; print &header; print "Error: $message\n

Please use the \"back\" button on your browser and try again."; exit; } # three lazy fixes for CGI.pm -> cgi-lib sub header { &PrintHeader; } sub param { my $var = shift; return $in{$var}; } sub referer { return $ENV{'HTTP_REFERER'}; } sub remote_host { return $ENV{'REMOTE_HOST'} || lookup($ENV{'REMOTE_ADDR'}) || 'localhost'; } sub lookup { my $ip = shift; return $ip unless $ip=~/\d+\.\d+\.\d+\.\d+/; return $CACHE{$ip} if exists $CACHE{$ip}; my @h = eval <<'END'; alarm(TIMEOUT); my @i = gethostbyaddr(pack('C4',split('\.',$ip)),2); alarm(0); @i; END $CACHE{$ip} = $h[0]; return $CACHE{$ip} || $ip; } sub redirect { my $url = shift; return "Status: 302 Moved\nLocation: $url$pic\n\n"; } &error("Can't find your sendmail: $sendmail") unless (-f $sendmail); &error("Can't execute your sendmail: $sendmail") unless (-e $sendmail); # parse role file into $role{$rolename} and @rolelist # file has format: open(FILE, "<$roleDB") or &error("Couldn't read role file '$roleDB'"); my @roles = ; my %role; my @rolelist; my $line; foreach $line (@roles) { next if (($line =~ /^\s*\#/) or ($line =~ /^\s*$/)); chomp $line; $line =~ s/^(\s+)//; # strip leading space my ($rolename, $rolevalue) = split /\s+/, $line, 2; unless ($rolename =~ /^\w+$/) { &error("Role name '$rolename' is invalid in file '$roleDB'"); } unless ($rolevalue =~ /\w+@\w*/) { &error("Role value '$rolevalue' for role '$rolename' isn't an email address."); } push @rolelist, $rolename; $role{$rolename} = $rolevalue; print "$rolename = $rolevalue\n" if ($debug); } my %in; &ReadParse; unless (param('email')) { # parse feedback-form, replace tag (REFERER) # print feedback-form and exit. open(FORMFILE, "<$formfile") or &error("Couldn't read feedback-form '$formfile'"); my $formcontents; { local $/=undef; $formcontents = ; } my $referer = referer() || 'Unknown'; $formcontents =~ s///; print header(); print $formcontents; exit; } # feedback form has been submitted, because 'message' and 'role' are filled in. # process contents, send email, and redirect browser to $outputURL; &error("No role specified in inputs") unless ($rolename); &error("Invalid role specified: ".$rolename) unless ($role{$rolename}); $roleaddress = $role{$rolename}; &error("No email address was found.") unless (param('email')); &error("Your email address '".param('email')."' seems to be invalid.") unless param('email') =~ /^.+@\w+\.\w+/; &error("Your email address didn't match the copy for verification.") unless (param('email') eq param('email2')); &error("New subscription or change in subscription?") unless param('new'); &error("Do you want to receive the print version?") unless param('print'); &error("Your name or title appears to be blank.") unless (param('sendername')); foreach (qw(phone street city state zip country)) { &error("Your $_ appears to be blank.") unless (param($_)); } # &error("got " .param('url'). param('message')); # but first, silently squelch if they've come here for spammy purposes if (param('url') eq 'Unknown' && param('message') =~ m{http://}) { print redirect($outputURL); exit; } my $send_email = "yes"; my $send_print = "yes"; $send_email = "no" if (param('print') eq 'only'); $send_print = "no" if (param('print') eq 'no'); my $sender = param('email'); my $sendername = param('sendername'); my $subject = "Newsletter Subscription Update"; my $org = param('org'); my $new = param('new'); my $streetdisp = $street = param('street'); my $street2 = param('street2') || ''; if ($street2) { $streetdisp .= "\n$street2"; } my $city = param('city'); my $state = param('state'); my $zip = param('zip') || 'None'; my $country = param('country'); my $phone = param('phone') || 'None'; my $message = param('message'); my $url = param('url') || 'Unknown'; my $host = remote_host() || 'Unknown'; # if $roleaddress has more than one address, mangle to turn , into >,< $roleaddress=~ s/,\s*/>, From: $sendername <$sender> Subject: FLGBTQC Website: $subject New?: $new Send Print?: $send_print Send Email?: $send_email Zip: $zip Org: $org Phone: $phone $name $streetdisp $city, $state $zip $country $message ----------------------------------------------------- Webpage: $url Sender's IP: $host "; my $mailexec = "$sendmail -f$sender -t"; open(MAIL,"|$mailexec") || &error("Couldn't open mail program using '$mailexec'"); print MAIL $email; #print &header . $email; my $dataline = qq{"$sendername","$org","$street","$street2","$city","$state","$zip","$country","$phone","$sender","$send_print","$send_email","$new"\n}; open(DATABASE,">>$databasefile") || &error("Couldn't open database file"); print DATABASE "$dataline"; print redirect($outputURL);