#!/usr/bin/perl -Tw

#++
# Based on <URL:http://www.wiley.com/legacy/compbooks/stein/text/upload.txt>
#
# Source code to accompany 
#   _Official Guide to Programming with CGI.pm: The Standard for Building Web Scripts_
#   by Lincoln Stein
#   (c) 1998 by Lincoln Stein
#  Published by John Wiley & Sons, Inc.  (ISBN 0-471-24744-8)
#--

use diagnostics;
use CGI qw(:standard);
use CGI::Carp 'fatalsToBrowser';
use strict;
$| = 1;

html_start();
if (param) {
    print_results();
} else {
    print_form();
}
html_end();


# - - - - - subroutines - - - - - -

sub print_results {
    my $length;
    my $file = param('upload');
    if (!$file) {
	print "<p>No file uploaded.</p>";
	return;
    }

    print '<h4>Proof that we have the file</h4>';
    print '<dl>';
    print ' <dt>File name</dt>',"<dd>$file</dd>";

    print ' <dt>File MIME type</dt>';
    my $type = uploadInfo($file)->{'Content-Type'}; #uploadInfo() is in CGI.pm
    if ($type) {
	print " <dd><kbd>$type</kbd></dd>";
    } else {
	print " <dd>unknown</dd>";
    }

    while (<$file>) {
	$length += length($_);
    }
    print ' <dt>File length</dt>',"<dd>$length</dd>";
    print '</dl>';

    print '<h4>In the CGI perl program</h4>';
    print ' <dl>';
    print '  <dt>File name</dt>';
    print '   <dd><code>$file = param("<var>upload</var>")</code></dd>';

    print '  <dt>File MIME type</dt>';
    print '   <dd><code>uploadInfo($file)->{"Content-Type"}</code></dd>';
    print '   <dd><code>uploadInfo()</code> is part of <kbd>CGI.pm</kbd></dd>';

    print '  <dt>File length</dt>';
    print '  <dd>using <code>while (&lt;$file&gt;)</code> for example</dd>';
    print '  <dd>the key is to use the filename in a file context</dd>';
    print ' </dl>';


    print '<hr />';

    print '<h3>What else was passed in the header</h3>';
    print ' <dl>';
    my $fileinfo = uploadInfo($file);
    foreach (keys %{$fileinfo}) {
	print "    <dt>$_</dt> <dd>$$fileinfo{$_}</dd>";
    }
    print '  </dl>';

    $\="\n";
    print '<h4>In the CGI program</h4>';
    print '<pre>';
    print '# uploadInfo returns a reference to a hash';
    print '# $fileinfo is the reference to that hash';
    print 'my $fileinfo = uploadInfo($file);';
    print '<br />';

    print 'print "  &lt;dl&gt;";';
    print 'foreach (keys %{$fileinfo}) {';
    print '   # $$fileinfo is that hash, not a reference to it';
    print '   print "    &lt;dt&gt;$_&lt;/dt&gt; &lt;dd&gt;$$fileinfo{$_}&lt;/dd&gt;";';
    print '}';
    print 'print "  &lt;/dl&gt;";';
    print '</pre>';


    print '<h5>On the Server...</h5>';
    print '<pre>';
    print 'print "&lt;p&gt;"';
    print 'print " On the server, the file is stored in "';
    print 'print " `&lt;kbd&gt;<code>tmpFileName($file);</code>&lt;/kbd&gt;\'?"';
    print 'print "&lt;p&gt;"';
    print '</pre>';
    print '<p>On the server, the file is stored in <kbd>`', tmpFileName($file), '\'</kbd>?</p>';
   # open(FILE, tmpFileName($file));
   # print '<pre>+++';
   # while(<FILE>) {print};
   # print '---</pre>';
   # printf "<p>file permissions are %04o</p>\n", ((stat tmpFileName($file))[2]) & 07777;

}# print_results()


sub html_start {
    print header;
    print << 'EOHTML';
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>
    File Upload Form Example for Dal CS 4173 : Web-centric Computing
  </title>
  <meta name="ROBOTS" content="NOINDEX" />
  <meta name="ROBOTS" content="NOFOLLOW" />
  <link rel="stylesheet" type="text/css" 
        href="/~jamie/course/CS/4173/CS4173.css" />
  <style type="text/css">
    .example  { border: thin black solid; }
    .browser  { border: thin black dashed; }
  </style>
 </head>
 <body>
  <h1>
   <a href="http://www.cs.dal.ca/~jamie/course/CS/4173/"
      name="top"
      title="course homepage (Dalhousie CS 4173: Web-centric Computing)"
      >Web-centric Computing</a>
  </h1>
  <h2>
   <a href="/~jamie/course/CS/4173/examples/list.html"
      >Example Code</a>
  </h2>

  <h3><a href="/~jamie/course/CS/4173/examples/list.html#forms"
         >Forms</a>: File Upload</h3>
EOHTML
;
}# html_start()


sub print_form {
    print << 'EOHTML'
<pre class="example">
 &lt;form method="<strong>post</strong>"  
       <strong>enctype="multipart/form-data"</strong>
       <strong>accept=</strong>"text/plain"
       action="http://users.cs.dal.ca/~jamie/cgi-bin/4173/form/upload.cgi"&gt;
  &lt;p&gt;
   &lt;input type="file"   name="upload" size="60" /&gt;
   &lt;br />
   &lt;input type="submit" name="submit" value="upload file" /&gt;
  &lt;/p&gt;
 &lt;/form&gt;
</pre>

    <form method="post"  
          enctype="multipart/form-data"
          accept="text/plain"
          action="http://users.cs.dal.ca/~jamie/cgi-bin/4173/form/upload.cgi">
     <p>
        <input type="file" 
               name="upload"
               size="60" />
        <br />
        <input type="submit" name=".submit" value="upload file" />
     </p>
    </form>

  <p class="note">Note that</p>
  <ul class="note">
   <li>The <code>enctype</code> attribute must be <code>multipart/form-data</code>
       to tell the server that there are multiple sections in the input.
       <ul>
        <li>Normally there is just one part.</li>
        <li>With file upload, the file is sent in a second section.</li>
      </ul>
   </li>
   <li>The form must be submitted with <code>method="post"</code> since
       there are two sections to the input, and <code>method="get"</code>
       can only do one.
   </li>
   <li>The <code>accept</code> attribute may be used to limit which types
       of files can be sent.
       <ul><li>Not all browsers bother to check this.</li></ul>
   </li>
  </ul>

EOHTML
    ;
}# print_form()

sub html_end {
print << 'EOHTML'
  <hr title="end of document proper" />

  <h6 title="document identification information">
   <kbd>http://www.cs.dal.ca/~jamie/cgi-bin/4173/form/upload.cgi</kbd>
  </h6>
   <dl style="display : compact">
     <dt>Version:</dt> <dd>30 October 2001</dd>
     <dt>Author:</dt>
     <dd><a title="prof's homepage"
            href="/~jamie/"
            >J. Blustein</a> <kbd>&lt;jamie@cs.dal.ca&gt;</kbd></dd>
   </dl>
   <p>
    <a href="http://validator.w3.org/check/referer"><img
       src="/%7ejamie/image/vxhtml10.gif"
       alt="Valid XHTML 1.0!" height="31" width="88" /></a>
   </p>
   <p>
    [<a href="#top"
        >Jump to top</a>&nbsp;|
     <a href="/~jamie/course/CS/4173/examples/CGI/forms/file-upload.pl.source"
        >View source code</a>]
   </p>
 </body>
</html>
EOHTML
;
}# html_end()
