|
Packit |
f574b8 |
#! /usr/bin/perl -w
|
|
Packit |
f574b8 |
# Some scripts for handling mailto URLs within lynx via an interactive form
|
|
Packit |
f574b8 |
#
|
|
Packit |
f574b8 |
# Warning: this is a quick demo, to show what kinds of things are possible
|
|
Packit |
f574b8 |
# by hooking some external commands into lynx. Use at your own risk.
|
|
Packit |
f574b8 |
#
|
|
Packit |
f574b8 |
# Requirements:
|
|
Packit |
f574b8 |
#
|
|
Packit |
f574b8 |
# - Perl and CGI.pm.
|
|
Packit |
f574b8 |
# - A "sendmail" command for actually sending mail (if you need some
|
|
Packit |
f574b8 |
# other interface, change the code below in sub sendit appropriately).
|
|
Packit |
f574b8 |
# - Lynx compiled with support for lynxcgi, that means EXEC_CGI must have
|
|
Packit |
f574b8 |
# been defined at compilation, usually done with
|
|
Packit |
f574b8 |
# ./configure --enable-cgi-links
|
|
Packit |
f574b8 |
# - Lynx must have support for CERN-style rules as of 2.8.3, which must
|
|
Packit |
f574b8 |
# not have been disabled at compilation (it is enabled by default).
|
|
Packit |
f574b8 |
#
|
|
Packit |
f574b8 |
# Instructions:
|
|
Packit |
f574b8 |
# (This is for people without lynxcgi experience; if you are already
|
|
Packit |
f574b8 |
# use lynxcgi, you don't have to follow everything literally, use
|
|
Packit |
f574b8 |
# common sense for picking appropriate file locations in your situation.)
|
|
Packit |
f574b8 |
#
|
|
Packit |
f574b8 |
# - Make a subdirectory 'lynxcgi' under you home directory, i.e.
|
|
Packit |
f574b8 |
# mkdir ~/lynxcgi
|
|
Packit |
f574b8 |
# - Put this three script file mailto-form.pl there and make it
|
|
Packit |
f574b8 |
# executable. For example,
|
|
Packit |
f574b8 |
# cp mailto-form.pl ~/lynxcgi
|
|
Packit |
f574b8 |
# chmod a+x ~/lynxcgi/mailto-form.pl
|
|
Packit |
f574b8 |
# - Edit mailto-form.pl (THIS FILE), there are some strings that
|
|
Packit |
f574b8 |
# that need to be changed, see ### Configurable variables ###
|
|
Packit |
f574b8 |
# below.
|
|
Packit |
f574b8 |
# - Allow lynx to execute lynxcgi files in that directory, for example,
|
|
Packit |
f574b8 |
# put in your lynx.cfg file:
|
|
Packit |
f574b8 |
# TRUSTED_LYNXCGI:<tab>/home/myhomedir/lynxcgi/mailto-form.pl
|
|
Packit |
f574b8 |
# where <tab> is a real TAB character and you have to put the real
|
|
Packit |
f574b8 |
# location of your directory in place of "myhomedir", of course.
|
|
Packit |
f574b8 |
# The '~' abbreviation cannot be used.
|
|
Packit |
f574b8 |
# You could also just enable execution of all lynxcgi scripts, by
|
|
Packit |
f574b8 |
# not having any TRUSTED_LYNXCGI options in lynx.cfg at all, but
|
|
Packit |
f574b8 |
# that can't be recommended.
|
|
Packit |
f574b8 |
# - Tell lynx to actually use the lynxcgi scripts for mailto URLs.
|
|
Packit |
f574b8 |
# There are two variants:
|
|
Packit |
f574b8 |
# a) Redirect "mailto"
|
|
Packit |
f574b8 |
# Requires patched lynx, currently not yet in the developent code.
|
|
Packit |
f574b8 |
# Use the following two lines in the file that is configured as
|
|
Packit |
f574b8 |
# RULESFILE in lynxcfg:
|
|
Packit |
f574b8 |
# PermitRedirection mailto:*
|
|
Packit |
f574b8 |
# Redirect mailto:* lynxcgi:/home/myhomedir/lynxcgi/mailto-form.pl?from=myname@myhost&to=*
|
|
Packit |
f574b8 |
# You can also put them directly in lynx.cfg, prefixing each with
|
|
Packit |
f574b8 |
# "RULE:". Replace ""myhomedir", "myname", and "myhost" with your
|
|
Packit |
f574b8 |
# correct values, of course.
|
|
Packit |
f574b8 |
# b) Redirect "xmailto"
|
|
Packit |
f574b8 |
# Requires defining a fake proxy before starting lynx, like
|
|
Packit |
f574b8 |
# export xmailto_proxy=dummy # or for csh: setenv xmailto_proxy dummy
|
|
Packit |
f574b8 |
# Requires that you change "mailto" to "xmailto" each time you want
|
|
Packit |
f574b8 |
# to activate a mailto link. This can be done conveniently with
|
|
Packit |
f574b8 |
# a few keys: 'E', ^A, 'x', Enter.
|
|
Packit |
f574b8 |
# Use the following two lines in the file that is configured as
|
|
Packit |
f574b8 |
# RULESFILE in lynxcfg:
|
|
Packit |
f574b8 |
# PermitRedirection xmailto:*
|
|
Packit |
f574b8 |
# Redirect xmailto:* lynxcgi:/home/myhomedir/lynxcgi/mailto-form.pl?from=myname@myhost&to=*
|
|
Packit |
f574b8 |
# You can also put them directly in lynx.cfg, prefixing each with
|
|
Packit |
f574b8 |
# "RULE:". Replace ""myhomedir", "myname", and "myhost" with your
|
|
Packit |
f574b8 |
# correct values, of course.
|
|
Packit |
f574b8 |
#
|
|
Packit |
f574b8 |
# Limitations:
|
|
Packit |
f574b8 |
#
|
|
Packit |
f574b8 |
# - Only applies to mailto URLs that appear as links or are entered at
|
|
Packit |
f574b8 |
# a 'g'oto prompt. Does not apply to other ways of sending mail, like
|
|
Packit |
f574b8 |
# the 'c' (COMMENT) key, mailto as a FORM action, or mailing a file
|
|
Packit |
f574b8 |
# from the 'P'rinting Options screen.
|
|
Packit |
f574b8 |
# - Nothing is done for charset labelling, content-transfer-encoding
|
|
Packit |
f574b8 |
# of non-ASCII characters, and other MIME niceties.
|
|
Packit |
f574b8 |
#
|
|
Packit |
f574b8 |
# Klaus Weide 20000712
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
########################################################################
|
|
Packit |
f574b8 |
########## Configurable variables ######################################
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
$SENDMAIL = '/usr/sbin/sendmail';
|
|
Packit |
f574b8 |
# The location of your sendmail binary
|
|
Packit |
f574b8 |
$SELFURL = 'lynxcgi:/home/lynxdev/lynxcgi/mailto-form.pl';
|
|
Packit |
f574b8 |
# Where this script lives in URL space
|
|
Packit |
f574b8 |
$SEND_TOKEN = '/vJhOp6eQ';
|
|
Packit |
f574b8 |
# When found in the PATH_INFO part of the URL,
|
|
Packit |
f574b8 |
# this causes the script to actually send mail
|
|
Packit |
f574b8 |
# by calling $SENDMAIL instead of just throwing
|
|
Packit |
f574b8 |
# up a form. CHANGE IT! And don't tell anyone!
|
|
Packit |
f574b8 |
# Treat it like a password.
|
|
Packit |
f574b8 |
# Must start with '/', probably should have only
|
|
Packit |
f574b8 |
# alphanumeric ASCII characters.
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
## Also, make sure the first line of this script points
|
|
Packit |
f574b8 |
## to your PERL binary
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
########## Nothing else to change - I hope #############################
|
|
Packit |
f574b8 |
########################################################################
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
use CGI;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
$|=1;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
### Upcase first character
|
|
Packit |
f574b8 |
##sub ucfirst {
|
|
Packit |
f574b8 |
## s/^./\U$1/;
|
|
Packit |
f574b8 |
##}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
# If there are multiple occurrences of the same thing, how to join them
|
|
Packit |
f574b8 |
# into one string
|
|
Packit |
f574b8 |
%joiner = (from => ', ',
|
|
Packit |
f574b8 |
to => ', ',
|
|
Packit |
f574b8 |
cc => ', ',
|
|
Packit |
f574b8 |
subject => '; ',
|
|
Packit |
f574b8 |
body => "\n\n"
|
|
Packit |
f574b8 |
);
|
|
Packit |
f574b8 |
sub joiner {
|
|
Packit |
f574b8 |
my ($key) = @_;
|
|
Packit |
f574b8 |
if ($joiner{$key}) {
|
|
Packit |
f574b8 |
$joiner{$key};
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
" ";
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
# Here we check whether this script is called for actual sending, rather
|
|
Packit |
f574b8 |
# than form generation. If so, all the rest is handled by sub sendit, below.
|
|
Packit |
f574b8 |
$pathinfo = $ENV{'PATH_INFO'};
|
|
Packit |
f574b8 |
if (defined($pathinfo) && $pathinfo eq $SEND_TOKEN) {
|
|
Packit |
f574b8 |
$q = new CGI;
|
|
Packit |
f574b8 |
print $q->header('text/plain');
|
|
Packit |
f574b8 |
sendit();
|
|
Packit |
f574b8 |
exit;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
$method = $ENV{'REQUEST_METHOD'};
|
|
Packit |
f574b8 |
$querystring = $ENV{'QUERY_STRING'};
|
|
Packit |
f574b8 |
if ($querystring) {
|
|
Packit |
f574b8 |
if ($method && $method eq "POST" && $ENV{'CONTENT_LENGTH'}) {
|
|
Packit |
f574b8 |
$querystring =~ s/((^|\&)to=[^?&]*)\?/$1&/;
|
|
Packit |
f574b8 |
$q0 = new CGI;
|
|
Packit |
f574b8 |
$q = new CGI($querystring);
|
|
Packit |
f574b8 |
@fields = $q0->param();
|
|
Packit |
f574b8 |
foreach $key (@fields) {
|
|
Packit |
f574b8 |
@vals = $q0->param($key);
|
|
Packit |
f574b8 |
# print "Content-type: text/html\n\n";
|
|
Packit |
f574b8 |
# print "Appending $key to \$q...\n";
|
|
Packit |
f574b8 |
$q->append($key, @vals);
|
|
Packit |
f574b8 |
# print "Current Values in \$q0\n";
|
|
Packit |
f574b8 |
# print $q0->dump;
|
|
Packit |
f574b8 |
# print "Current Values in \$q\n";
|
|
Packit |
f574b8 |
# print $q->dump;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
$querystring =~ s/((^|\&)to=[^?&]*)\?/$1&/;
|
|
Packit |
f574b8 |
$q = new CGI($querystring);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
$q = new CGI;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
print $q->header;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
$long_title = $ENV{'QUERY_STRING'};
|
|
Packit |
f574b8 |
$long_title =~ s/^from=([^&]*)\&to=//;
|
|
Packit |
f574b8 |
$long_title = "someone" unless $long_title;
|
|
Packit |
f574b8 |
$long_title = "Compose mail for $long_title";
|
|
Packit |
f574b8 |
if (length($long_title) > 72) {
|
|
Packit |
f574b8 |
$title = substr($long_title,0,72) . "...";
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
$title = $long_title;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
$long_title =~ s/&/&/g;
|
|
Packit |
f574b8 |
$long_title =~ s/</</g;
|
|
Packit |
f574b8 |
print
|
|
Packit |
f574b8 |
$q->start_html($title), "\n",
|
|
Packit |
f574b8 |
$q->h1($long_title), "\n",
|
|
Packit |
f574b8 |
$q->start_form(-method=>'POST', -action => $SELFURL . $SEND_TOKEN), "\n";
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
print "\n";
|
|
Packit |
f574b8 |
@fields = $q->param();
|
|
Packit |
f574b8 |
foreach $key (@fields) {
|
|
Packit |
f574b8 |
@vals = $q->param($key);
|
|
Packit |
f574b8 |
if (scalar(@vals) != 1) {
|
|
Packit |
f574b8 |
print "multiple values " . scalar(@vals) ." for $key!\n";
|
|
Packit |
f574b8 |
$q->param($key, join (joiner($key), @vals));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
foreach $key (@fields) {
|
|
Packit |
f574b8 |
$_ = lc($key);
|
|
Packit |
f574b8 |
if ($_ ne $key) {
|
|
Packit |
f574b8 |
print "noncanonical case for $key!\n";
|
|
Packit |
f574b8 |
$val=$q->param($key);
|
|
Packit |
f574b8 |
$q->delete($key);
|
|
Packit |
f574b8 |
if (!$q->param($_)) {
|
|
Packit |
f574b8 |
$q->param($_, $val);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
$q->param($_, $q->param($_) . joiner($_) . "$val");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
foreach $key ('from', 'to', 'cc', 'subject') {
|
|
Packit |
f574b8 |
print $q->Tr,
|
|
Packit |
f574b8 |
$q->td(ucfirst($key) . ":"),
|
|
Packit |
f574b8 |
$q->td($q->textfield(-name=>$key,
|
|
Packit |
f574b8 |
-size=>60,
|
|
Packit |
f574b8 |
-default=>$q->param($key))), "\n";
|
|
Packit |
f574b8 |
$q->delete($key);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
# Also pass on any unrecognized header fields that were specified.
|
|
Packit |
f574b8 |
# This may not be a good idea for general use!
|
|
Packit |
f574b8 |
# At least some dangerous header fields may have to be suppressed.
|
|
Packit |
f574b8 |
@keys = $q->param();
|
|
Packit |
f574b8 |
if (scalar(@keys) > (($q->param('body')) ? 1 : 0)) {
|
|
Packit |
f574b8 |
print "Additional headers:\n";
|
|
Packit |
f574b8 |
foreach $key ($q->param()) {
|
|
Packit |
f574b8 |
if ($key ne 'body') {
|
|
Packit |
f574b8 |
print $q->Tr,
|
|
Packit |
f574b8 |
$q->td(ucfirst($key) . ":"),
|
|
Packit |
f574b8 |
$q->td($q->textfield(-name=>$key,
|
|
Packit |
f574b8 |
-size=>60,
|
|
Packit |
f574b8 |
-default=>$q->param($key))), "\n";
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
print "\n";
|
|
Packit |
f574b8 |
print $q->textarea(-name=>'body',
|
|
Packit |
f574b8 |
-default=>$q->param('body')), "\n";
|
|
Packit |
f574b8 |
print "\n\n ", "\n",
|
|
Packit |
f574b8 |
$q->submit(-value=>"Send the message"), "\n",
|
|
Packit |
f574b8 |
$q->endform, "\n";
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
print "\n";
|
|
Packit |
f574b8 |
exit;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
# This is for header field values.
|
|
Packit |
f574b8 |
sub sanitize_field_value {
|
|
Packit |
f574b8 |
my($val) = @_;
|
|
Packit |
f574b8 |
$val =~ s/\0/./g;
|
|
Packit |
f574b8 |
$val =~ s/\r\n/\n/g;
|
|
Packit |
f574b8 |
$val =~ s/\r/\n/g;
|
|
Packit |
f574b8 |
$val =~ s/\n*$//g;
|
|
Packit |
f574b8 |
$val =~ s/\n+/\n/g;
|
|
Packit |
f574b8 |
$val =~ s/\n(\S)/\n\t$1/g;
|
|
Packit |
f574b8 |
$val;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
sub sendit {
|
|
Packit |
f574b8 |
open (MAIL, "| $SENDMAIL -t -oi -v") || die ("$0: Can't run sendmail: $!\n");
|
|
Packit |
f574b8 |
@fields = $q->param();
|
|
Packit |
f574b8 |
foreach $key (@fields) {
|
|
Packit |
f574b8 |
@vals = $q->param($key);
|
|
Packit |
f574b8 |
if (scalar(@vals) != 1) {
|
|
Packit |
f574b8 |
print "multiple values " . scalar(@vals) ." for $key!\n";
|
|
Packit |
f574b8 |
$q->param($key, join (joiner($key), @vals));
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
foreach $key (@fields) {
|
|
Packit |
f574b8 |
if ($key ne 'body') {
|
|
Packit |
f574b8 |
if ($key =~ /[^A-Za-z0-9_-]/) {
|
|
Packit |
f574b8 |
print "$0: Ignoring malformed header field named '$key'!\n";
|
|
Packit |
f574b8 |
next;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
print MAIL ucfirst($key) . ": " .
|
|
Packit |
f574b8 |
sanitize_field_value($q->param($key)) . "\n"
|
|
Packit |
f574b8 |
or die ("$0: Feeding header to sendmail failed: $!\n");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
print MAIL "\n"
|
|
Packit |
f574b8 |
or die ("$0: Ending header for sendmail failed: $!\n");
|
|
Packit |
f574b8 |
print MAIL $q->param('body'), "\n"
|
|
Packit |
f574b8 |
or die ("$0: Feeding body to sendmail failed: $!\n");
|
|
Packit |
f574b8 |
close(MAIL)
|
|
Packit |
f574b8 |
or warn $! ? "Error closing pipe to sendmail: $!"
|
|
Packit |
f574b8 |
: ($? & 127) ? ("Sendmail killed by signal " . ($? & 127) .
|
|
Packit |
f574b8 |
($? & 127) ? ", core dumped" : "")
|
|
Packit |
f574b8 |
: "Return value " . ($? >> 8) . " from sendmail";
|
|
Packit |
f574b8 |
}
|