diff options
Diffstat (limited to 'scripts/multipart')
-rw-r--r-- | scripts/multipart/Makefile | 35 | ||||
-rw-r--r-- | scripts/multipart/README | 24 | ||||
-rw-r--r-- | scripts/multipart/mailcap | 1 | ||||
-rw-r--r-- | scripts/multipart/multipart.cgi | 272 | ||||
-rw-r--r-- | scripts/multipart/multipart.cgi.in | 272 |
5 files changed, 604 insertions, 0 deletions
diff --git a/scripts/multipart/Makefile b/scripts/multipart/Makefile new file mode 100644 index 0000000..8f77b16 --- /dev/null +++ b/scripts/multipart/Makefile @@ -0,0 +1,35 @@ + +prefix = /usr/local +bindir = $(prefix)/bin +libdir = $(prefix)/lib +distdir = ./distfiles + +W3M_LIBDIR = $(libdir)/w3m + +INSTALL = install -c +INSTALL_SCRIPT = $(INSTALL) -m 755 + +PERL = /usr/local/bin/perl +NKF = /usr/local/bin/nkf + +all: multipart.cgi + +multipart.cgi: multipart.cgi.in Makefile + sed -e 's%@PERL@%$(PERL)%g' \ + -e 's%@NKF@%$(NKF)%g' \ + multipart.cgi.in > multipart.cgi + chmod +x multipart.cgi + +install: multipart.cgi + $(INSTALL_SCRIPT) multipart.cgi $(W3M_LIBDIR) + +dist: all + @-rm -fr $(distdir)/multipart + mkdir -p $(distdir)/multipart + cp Makefile README multipart.cgi multipart.cgi.in \ + $(distdir)/multipart + ( cd $(distdir); \ + tar -cf - multipart | GZIP='' gzip ) \ + > $(distdir)/multipart.tar.gz + -rm -fr $(distdir)/multipart + diff --git a/scripts/multipart/README b/scripts/multipart/README new file mode 100644 index 0000000..54df29a --- /dev/null +++ b/scripts/multipart/README @@ -0,0 +1,24 @@ + +Content-Type: multipart/* を扱う local-CGI + + Content-Type: multipart/* なファイルを扱うための local-CGI です。 + 主に mailx などでメールを PAGER="w3m -m" で読む場合を想定しています。 + +インストール + + * make install + 必要なら PERL, NKF, W3M_LIBDIR を設定してください。 + + * mailcap を ~/.w3m/mailcap にマージ + multipart.cgi のパスに注意 + + * w3m の Option Setting Panel で、 + 『保存時に Content-Transfer-Encoding をデコードする』を ON + 添付ファイルの保存時に便利です。 + +必要なもの + + * NKF モジュールまたは nkf + 文字コード変換や MIME ヘッダのデコードにを使ってます。 + 気にいらなければ変えてください。 + diff --git a/scripts/multipart/mailcap b/scripts/multipart/mailcap new file mode 100644 index 0000000..323ee20 --- /dev/null +++ b/scripts/multipart/mailcap @@ -0,0 +1 @@ +multipart/*; /usr/local/lib/w3m/multipart.cgi %s %{boundary}; htmloutput diff --git a/scripts/multipart/multipart.cgi b/scripts/multipart/multipart.cgi new file mode 100644 index 0000000..e7c71e5 --- /dev/null +++ b/scripts/multipart/multipart.cgi @@ -0,0 +1,272 @@ +#!/usr/local/bin/perl + +if ($use_NKF = eval "use NKF;") { + $CONV = "-e"; + $MIME_DECODE = "-m -e"; +} else { +# $CONV = "w3m -dump -e"; + $CONV = "/usr/local/bin/nkf -e"; + $MIME_DECODE = "/usr/local/bin/nkf -m -e"; +} +$MIME_TYPE = "$ENV{'HOME'}/.mime.types"; + +if (defined($ENV{'QUERY_STRING'})) { + for (split('&', $ENV{'QUERY_STRING'})) { + s/^([^=]*)=//; + $v{$1} = $_; + } + $file = &form_decode($v{'file'}); + $boundary = &form_decode($v{'boundary'}); +} else { + $file = $ARGV[0]; + if (@ARGV >= 2) { + $boundary = $ARGV[1]; + } + $CGI = "file:///\$LIB/multipart.cgi?file=" . &html_quote($file); +} + +open(F, $file); +$end = 0; +$mbody = ''; +if (defined($boundary)) { + while(<F>) { + s/\r?\n$//; + ($_ eq "--$boundary") && last; + ($_ eq "--$boundary--") && ($end = 1, last); + $mbody .= "$_\n"; + } +} else { + while(<F>) { + s/\r?\n$//; + if (s/^\-\-//) { + $boundary = $_; + last; + } + $mbody .= "$_\n"; + } +} +$CGI .= "&boundary=" . &html_quote($boundary); + +if (defined($v{'count'})) { + $count = 0; + while($count < $v{'count'}) { + while(<F>) { + s/\r?\n$//; + ($_ eq "--$boundary") && last; + } + eof(F) && exit; + $count++; + } + + %header = (); + $hbody = ''; + while(<F>) { + /^\s*$/ && last; + $x = $_; + s/\r?\n$//; + if (/=\?/) { + $_ = &decode($_, $MIME_DECODE); + } + if (s/^(\S+)\s*:\s*//) { + $hbody .= "$&$_\n"; + $p = $1; + $p =~ tr/A-Z/a-z/; + $header{$p} = $_; + } elsif (s/^\s+//) { + chop $hbody; + $hbody .= "$_\n"; + $header{$p} .= $_; + } + } + $type = $header{"content-type"}; + $dispos = $header{"content-disposition"}; + if ($type =~ /application\/octet-stream/) { + if ($type =~ /type\=gzip/) { + print "Content-Encoding: x-gzip\n"; + } + if ($type =~ /name=\"?([^\"]+)\"?/ || + $dispos =~ /filename=\"?([^\"]+)\"?/) { + $type = &guess_type($1); + if ($type) { + print "Content-Type: $type; name=\"$1\"\n"; + } else { + print "Content-Type: text/plain; name=\"$1\"\n"; + } + } + } + print $hbody; + print "\n"; + while(<F>) { + $x = $_; + s/\r?\n$//; + ($_ eq "--$boundary") && last; + if ($_ eq "--$boundary--") { + last; + } + print $x; + } + close(F); + exit; +} + +if ($mbody =~ /\S/) { + $_ = $mbody; + s/\&/\&/g; + s/\</\</g; + s/\>/\>/g; + print "<pre>\n"; + print $_; + print "</pre>\n"; +} + +$count = 0; +while(! $end) { + %header = (); + $hbody = ''; + while(<F>) { + /^\s*$/ && last; + s/\r?\n$//; + if (/=\?/) { + $_ = &decode($_, $MIME_DECODE); + } + if (s/^(\S+)\s*:\s*//) { + $hbody .= "$&$_\n"; + $p = $1; + $p =~ tr/A-Z/a-z/; + $header{$p} = $_; + } elsif (s/^\s+//) { + chop $hbody; + $hbody .= "$_\n"; + $header{$p} .= $_; + } + } + $type = $header{"content-type"}; + $dispos = $header{"content-disposition"}; + if ((! $type || $type =~ /^text\/plain/i) && + (! $dispos || $dispos =~ /^inline/i)) { + $plain = 1; + } else { + $plain = 0; + } + $body = ''; + while(<F>) { + s/\r?\n$//; + ($_ eq "--$boundary") && last; + if ($_ eq "--$boundary--") { + $end = 1; + last; + } + if ($plain) { + $body .= "$_\n"; + } + } + $| = 1; + print "<hr>\n"; + { + $_ = $hbody; + s/\&/\&/g; + s/\</\</g; + s/\>/\>/g; + print "<pre>\n"; + print $_; + if ($type =~ /name=\"?([^\"]+)\"?/ || + $dispos =~ /filename=\"?([^\"]+)\"?/) { + $name = $1; + } else { + $name = "[Content]"; + } + print "\n<a href=\"$CGI&count=$count\">", &html_quote($name), "</a>"; + print "\n\n</pre>\n"; + } + if ($plain) { + $body = &decode($body, $CONV); + $_ = $body; + s/\&/\&/g; + s/\</\</g; + s/\>/\>/g; + print "<pre>\n"; + print $_; + print "</pre>\n"; + } + eof(F) && last; + $count++; +} +close(F); + +sub decode { +if ($use_NKF) { + local($body, $opt) = @_; + return nkf($opt, $body); +} + local($body, @cmd) = @_; + local($_); + + $| = 1; + pipe(R, W2); + pipe(R2, W); + if (! fork()) { + close(F); + close(R); + close(W); + open(STDIN, "<&R2"); + open(STDOUT, ">&W2"); + exec @cmd; + die; + } + close(R2); + close(W2); + print W $body; + close(W); + $body = ''; + while(<R>) { + $body .= $_; + } + close(R); + return $body; +} + +sub html_quote { + local($_) = @_; + local(%QUOTE) = ( + '<', '<', + '>', '>', + '&', '&', + '"', '"', + ); + s/[<>&"]/$QUOTE{$&}/g; + return $_; +} + +sub form_decode { + local($_) = @_; + s/\+/ /g; + s/%([\da-f][\da-f])/pack('c', hex($1))/egi; + return $_; +} + +sub guess_type { + local($_) = @_; + + /\.(\w+)$/ || next; + $_ = $1; + tr/A-Z/a-z/; + %mime_type = &load_mime_type($MIME_TYPE); + $mime_type{$_}; +} + +sub load_mime_type { + local($file) = @_; + local(%m, $a, @b, $_); + + open(M, $file) || return (); + while(<M>) { + /^#/ && next; + chop; + (($a, @b) = split(" ")) >= 2 || next; + for(@b) { + $m{$_} = $a; + } + } + close(M); + return %m; +} diff --git a/scripts/multipart/multipart.cgi.in b/scripts/multipart/multipart.cgi.in new file mode 100644 index 0000000..be4e6a0 --- /dev/null +++ b/scripts/multipart/multipart.cgi.in @@ -0,0 +1,272 @@ +#!@PERL@ + +if ($use_NKF = eval "use NKF;") { + $CONV = "-e"; + $MIME_DECODE = "-m -e"; +} else { +# $CONV = "w3m -dump -e"; + $CONV = "@NKF@ -e"; + $MIME_DECODE = "@NKF@ -m -e"; +} +$MIME_TYPE = "$ENV{'HOME'}/.mime.types"; + +if (defined($ENV{'QUERY_STRING'})) { + for (split('&', $ENV{'QUERY_STRING'})) { + s/^([^=]*)=//; + $v{$1} = $_; + } + $file = &form_decode($v{'file'}); + $boundary = &form_decode($v{'boundary'}); +} else { + $file = $ARGV[0]; + if (@ARGV >= 2) { + $boundary = $ARGV[1]; + } + $CGI = "file:///\$LIB/multipart.cgi?file=" . &html_quote($file); +} + +open(F, $file); +$end = 0; +$mbody = ''; +if (defined($boundary)) { + while(<F>) { + s/\r?\n$//; + ($_ eq "--$boundary") && last; + ($_ eq "--$boundary--") && ($end = 1, last); + $mbody .= "$_\n"; + } +} else { + while(<F>) { + s/\r?\n$//; + if (s/^\-\-//) { + $boundary = $_; + last; + } + $mbody .= "$_\n"; + } +} +$CGI .= "&boundary=" . &html_quote($boundary); + +if (defined($v{'count'})) { + $count = 0; + while($count < $v{'count'}) { + while(<F>) { + s/\r?\n$//; + ($_ eq "--$boundary") && last; + } + eof(F) && exit; + $count++; + } + + %header = (); + $hbody = ''; + while(<F>) { + /^\s*$/ && last; + $x = $_; + s/\r?\n$//; + if (/=\?/) { + $_ = &decode($_, $MIME_DECODE); + } + if (s/^(\S+)\s*:\s*//) { + $hbody .= "$&$_\n"; + $p = $1; + $p =~ tr/A-Z/a-z/; + $header{$p} = $_; + } elsif (s/^\s+//) { + chop $hbody; + $hbody .= "$_\n"; + $header{$p} .= $_; + } + } + $type = $header{"content-type"}; + $dispos = $header{"content-disposition"}; + if ($type =~ /application\/octet-stream/) { + if ($type =~ /type\=gzip/) { + print "Content-Encoding: x-gzip\n"; + } + if ($type =~ /name=\"?([^\"]+)\"?/ || + $dispos =~ /filename=\"?([^\"]+)\"?/) { + $type = &guess_type($1); + if ($type) { + print "Content-Type: $type; name=\"$1\"\n"; + } else { + print "Content-Type: text/plain; name=\"$1\"\n"; + } + } + } + print $hbody; + print "\n"; + while(<F>) { + $x = $_; + s/\r?\n$//; + ($_ eq "--$boundary") && last; + if ($_ eq "--$boundary--") { + last; + } + print $x; + } + close(F); + exit; +} + +if ($mbody =~ /\S/) { + $_ = $mbody; + s/\&/\&/g; + s/\</\</g; + s/\>/\>/g; + print "<pre>\n"; + print $_; + print "</pre>\n"; +} + +$count = 0; +while(! $end) { + %header = (); + $hbody = ''; + while(<F>) { + /^\s*$/ && last; + s/\r?\n$//; + if (/=\?/) { + $_ = &decode($_, $MIME_DECODE); + } + if (s/^(\S+)\s*:\s*//) { + $hbody .= "$&$_\n"; + $p = $1; + $p =~ tr/A-Z/a-z/; + $header{$p} = $_; + } elsif (s/^\s+//) { + chop $hbody; + $hbody .= "$_\n"; + $header{$p} .= $_; + } + } + $type = $header{"content-type"}; + $dispos = $header{"content-disposition"}; + if ((! $type || $type =~ /^text\/plain/i) && + (! $dispos || $dispos =~ /^inline/i)) { + $plain = 1; + } else { + $plain = 0; + } + $body = ''; + while(<F>) { + s/\r?\n$//; + ($_ eq "--$boundary") && last; + if ($_ eq "--$boundary--") { + $end = 1; + last; + } + if ($plain) { + $body .= "$_\n"; + } + } + $| = 1; + print "<hr>\n"; + { + $_ = $hbody; + s/\&/\&/g; + s/\</\</g; + s/\>/\>/g; + print "<pre>\n"; + print $_; + if ($type =~ /name=\"?([^\"]+)\"?/ || + $dispos =~ /filename=\"?([^\"]+)\"?/) { + $name = $1; + } else { + $name = "[Content]"; + } + print "\n<a href=\"$CGI&count=$count\">", &html_quote($name), "</a>"; + print "\n\n</pre>\n"; + } + if ($plain) { + $body = &decode($body, $CONV); + $_ = $body; + s/\&/\&/g; + s/\</\</g; + s/\>/\>/g; + print "<pre>\n"; + print $_; + print "</pre>\n"; + } + eof(F) && last; + $count++; +} +close(F); + +sub decode { +if ($use_NKF) { + local($body, $opt) = @_; + return nkf($opt, $body); +} + local($body, @cmd) = @_; + local($_); + + $| = 1; + pipe(R, W2); + pipe(R2, W); + if (! fork()) { + close(F); + close(R); + close(W); + open(STDIN, "<&R2"); + open(STDOUT, ">&W2"); + exec @cmd; + die; + } + close(R2); + close(W2); + print W $body; + close(W); + $body = ''; + while(<R>) { + $body .= $_; + } + close(R); + return $body; +} + +sub html_quote { + local($_) = @_; + local(%QUOTE) = ( + '<', '<', + '>', '>', + '&', '&', + '"', '"', + ); + s/[<>&"]/$QUOTE{$&}/g; + return $_; +} + +sub form_decode { + local($_) = @_; + s/\+/ /g; + s/%([\da-f][\da-f])/pack('c', hex($1))/egi; + return $_; +} + +sub guess_type { + local($_) = @_; + + /\.(\w+)$/ || next; + $_ = $1; + tr/A-Z/a-z/; + %mime_type = &load_mime_type($MIME_TYPE); + $mime_type{$_}; +} + +sub load_mime_type { + local($file) = @_; + local(%m, $a, @b, $_); + + open(M, $file) || return (); + while(<M>) { + /^#/ && next; + chop; + (($a, @b) = split(" ")) >= 2 || next; + for(@b) { + $m{$_} = $a; + } + } + close(M); + return %m; +} |