--- /dev/null
+#! /usr/bin/perl
+use CGI;
+use POSIX;
+use strict;
+use File::Temp;
+
+$ENV{"HOME"} = "/home/cassarossa/itk/sesse/sesse-pdf/";
+
+my $cgi = CGI->new;
+my $filename = $cgi->param('input');
+my $file = $cgi->upload('input');
+
+# It kind of sucks that we just can't get the temporary file name from
+# CGI.pm, but OK, here goes :-)
+
+my $pdf_filename = join('', (0..9, 'A'..'Z', 'a'..'z')[
+ rand 62, rand 62, rand 62, rand 62, rand 62,
+ rand 62, rand 62, rand 62, rand 62, rand 62
+]) . '.pdf';
+
+my $pdfopts = "";
+my $psopts = "/setdistillerparams { } /def";
+my $outname;
+
+if ($cgi->param('preset') eq 'screen') {
+ $pdfopts = "-dPDFSETTINGS=/screen";
+} elsif ($cgi->param('preset') eq 'ebook') {
+ $pdfopts = "-dPDFSETTINGS=/ebook";
+} elsif ($cgi->param('preset') eq 'printer') {
+ $pdfopts = "-dPDFSETTINGS=/printer";
+} elsif ($cgi->param('preset') eq 'prepress') {
+ $pdfopts = "-dPDFSETTINGS=/prepress";
+} elsif ($cgi->param('preset') eq 'default') {
+ $psopts = "";
+}
+
+if ($filename =~ /(.*)\.(?:e?ps|pdf)$/i) {
+ $outname = "$1.pdf";
+
+ # Yay, just a round through GhostScript
+ open PIPE, "| gs $pdfopts -dCompatbilityLevel=1.4 -dNOPAUSE -dPATCH -sDEVICE=pdfwrite -dSAFER -sOutputFile=output/$pdf_filename -c '.setpdfwrite $psopts' -f - >&2"
+ or die "gs: $!";
+
+ my ($buf, $ret);
+ while ($ret = read($file, $buf, 1024)) {
+ print PIPE $buf;
+ }
+ close PIPE;
+} elsif ($filename =~ /(.*)\.(bmp|png|jpe?g|xpm)$/i) {
+ $outname = "$1.pdf";
+
+ # Run through ImageMagick first of all, then gs
+ open PIPE, "| convert $2:- ps:- | gs $pdfopts -dCompatbilityLevel=1.4 -dNOPAUSE -dPATCH -sDEVICE=pdfwrite -dSAFER -sOutputFile=output/$pdf_filename -c '.setpdfwrite $psopts' -f - >&2"
+ or die "convert: $!";
+
+ my ($buf, $ret);
+ while ($ret = read($file, $buf, 1024)) {
+ print PIPE $buf;
+ }
+ close PIPE;
+} elsif ($filename =~ /(.*)\.txt$/i) {
+ $outname = "$1.pdf";
+
+ # Use mpage
+ open PIPE, "| mpage -da -1 - | gs $pdfopts -dCompatbilityLevel=1.4 -dNOPAUSE -dPATCH -sDEVICE=pdfwrite -dSAFER -sOutputFile=output/$pdf_filename -c '.setpdfwrite $psopts' -f - >&2"
+ or die "convert: $!";
+
+ my ($buf, $ret);
+ while ($ret = read($file, $buf, 1024)) {
+ print PIPE $buf;
+ }
+ close PIPE;
+} elsif ($filename =~ /(.*)\.(doc|xls|ppt)$/i) {
+ $outname = "$1.pdf";
+ my $ext = $2;
+
+ # Oh my, OpenOffice
+ open DOC, ">output/$pdf_filename.$ext"
+ or die "output/$pdf_filename.$ext: $!";
+ my ($buf, $ret);
+ while ($ret = read($file, $buf, 1024)) {
+ print DOC $buf;
+ }
+ close DOC;
+
+ # Create PostScript from OOo :-)
+ system("/usr/lib/openoffice/program/soffice -display :25 -headless -pt pdf /home/cassarossa/itk/sesse/public_html/pdf/output/$pdf_filename.$ext");
+
+ system("gs $pdfopts -dCompatbilityLevel=1.4 -dNOPAUSE -dPATCH -sDEVICE=pdfwrite -dSAFER -sOutputFile=output/$pdf_filename -c '.setpdfwrite $psopts' -f - < output/$pdf_filename.pdf >&2");
+} elsif ($filename =~ /(.*)\.(c|cc|cpp|cs|h|py|rb|pl|diff|patch|js|php[1-5]?|hs|f|f90|java|css|sql|l|y|s?ml|sh|awk|m|v)$/i) {
+ $outname = "$1.pdf";
+ my $ext = $2;
+
+ open DOC, ">output/$pdf_filename.$ext"
+ or die "output/$pdf_filename.$ext: $!";
+ my ($buf, $ret);
+ while ($ret = read($file, $buf, 1024)) {
+ print DOC $buf;
+ }
+ close DOC;
+
+ (my $sanitized_filename = $filename) =~ tr/a-zA-Z0-9./_/c;
+
+ # This is just perverse :-P
+ system("vim -Z -R +\"set printheader=\%<$sanitized_filename\%h\%m\%=Page\\ \%N\" +\"ha >/home/cassarossa/itk/sesse/public_html/pdf/output/$pdf_filename.ps\" +:q output/$pdf_filename.$ext");
+
+ system("gs $pdfopts -dCompatbilityLevel=1.4 -dNOPAUSE -dPATCH -sDEVICE=pdfwrite -dSAFER -sOutputFile=output/$pdf_filename -c '.setpdfwrite $psopts' -f - < output/$pdf_filename.ps >&2");
+} else {
+ print <<"EOF";
+Content-type: text/html
+
+<html><head><title>Error</title></head>
+<body><h1>Error</h1>
+<p>You sent an unknown file type.</p>
+</body></html>
+EOF
+ exit;
+}
+
+my $size = -s "output/$pdf_filename";
+
+print "Content-type: application/pdf\n";
+print "Content-disposition: attachment; filename=\"$outname\"\n"; # FIXME: XSS problems?
+print "Content-length: $size\n\n";
+
+system("cat output/$pdf_filename"); # yuck?
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE
+ html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>PDF converter : sesse.net</title>
+ <meta name="description" content="Easily and freely create PDFs -- no strings attached" />
+ <link rel="stylesheet" href="http://www.sesse.net/sesse.css" type="text/css" />
+ <link rev="made" href="mailto:sgunderson@bigfoot.com" />
+ <meta name="MSSmartTagsPreventParsing" content="TRUE" />
+ </head>
+ <body>
+ <h1>PDF converter</h1>
+
+ <div class="boxes">
+ <div class="info">
+ <h2>Last updated</h2>
+ <p id="lastupdated">August 5th, 2005</p>
+ </div>
+
+ <div class="nav">
+ <p><a href="sitemap.html">Site map</a> :
+ <a href="index.html">Home</a> :
+ <a href="search.html">Search</a><br />
+ <span class="copy">© 2005 <a href="mailto:sgunderson@bigfoot.com">Steinar H. Gunderson</a>.</span></p>
+ </div>
+ </div>
+
+ <form method="post" action="createpdf.pl" enctype="multipart/form-data">
+ <table>
+ <tr>
+ <th>File:</th>
+ <td><input type="file" name="input" /></td>
+ </tr>
+ <tr>
+ <th>PDF preset:</th>
+ <td>
+ <select name="preset">
+ <option value="default">Default</option>
+ <option value="screen">Screen (72dpi, no embedded fonts)</option>
+ <option value="ebook">eBook (150dpi)</option>
+ <option value="printer">Printer (300dpi)</option>
+ <option value="prepress">Prepress (300dpi, better JPEG quality)</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <th colspan="2">
+ <input type="submit" value="Make PDF" />
+ </th>
+ </tr>
+ </table>
+ </form>
+
+ <p>This is an “anything to PDF” converter, not unlike what you get
+ from <a href="http://createpdf.adobe.com/">Adobe's PDF Online service</a>,
+ but completely free and running entirely on free software. It is also
+ completely without any kind of warranty or uptime guarantees -- I'll
+ try to do my best keeping it up, but in case people start dumping
+ multi-gigabyte jobs etc. on it regularily I might just not be able to
+ do that. Please be nice :-)</p>
+
+ <p>Note that there is minimal security involved; if I feel like it, I
+ might even take a look at what people are processing. Do not submit
+ any sensitive data!</p>
+
+ <p>The converter is currently based on <a href="http://www.ghostscript.com/">GPL
+ GhostScript</a> 8.01 (yes, a bit old); everything is pushed through it in one form or the
+ other (if only for image recompression etc.). The PDF presets match
+ exactly those in GhostScript itself -- see the
+ <a href="http://www.cs.wisc.edu/~ghost/doc/cvs/Ps2pdf.htm#Options">table
+ of options</a> for more details. (Note that anything except “default”
+ will override whatever input parameters there are in the input PostScript
+ file.)</p>
+
+ <p>The converter can currently handle the following formats, autodetected
+ by file extension <em>only</em>:</p>
+
+ <ul>
+ <li>PostScript (.ps) and Encapsulated PostScript (.pdf), via GS directly</li>
+ <li>Plain text (.txt), via mpage</li>
+ <li>BMP (.bmp), PNG (.png), JPEG (.jpg/.jpeg), XPM (.xpm), via <a href="http://www.imagemagick.com">ImageMagick</a>
+ (somewhat odd image placement for now due to bugs in Debian sarge's
+ version of ImageMagick).</li>
+ <li>Microsoft Word (.doc), Excel (.xls) and PowerPoint (.ppt), via
+ <a href="http://www.openoffice.org">OpenOffice.org</a> (could be
+ slightly sketchy at times, let me know if it's broken).</li>
+ <li>Lots of different programming-related formats (.c, .pl, .js, etc.),
+ via <a href="http://www.vim.org/">Vim</a>.</li>
+ </ul>
+
+ <p>If somebody knows a good way of getting a Gecko-based browser to
+ convert from an URL or HTML file to PostScript (on the command line),
+ please let me know; I'd guess HTML would be the most-wanted format
+ missing. :-)</p>
+ </body>
+</html>
+