L'idée est de permettre un transfert de fichier de la part de quelqu'un ne disposant pas d'agent logiciel permettant d'envoyer des emails avec pièce jointe ou alors pour ceux qui sont incappables de s'en servir. A partir d'une page web on utilise un formulaire avec un champ de type fichier, le fichier est récupéré par le script perl présenté ici puis il est envoyé par email comme attachement mime.
pour réaliser ces tâches, nous allons avoir recours à quelques modules perl contenus dans la distribution standard.
#!/usr/bin/perl # All by HAbeTT # Up2me use CGI; use MIME::Base64;
CGI permet de récupérer les données du formulaire et MIME::Base64 sera utiliser pour encoder la pièce jointe. On commence par débuter la page html de sortie.
print <<frag; Content-type: text/html <html> <head> </head> <body> frag
On initie ensuite la récupération des données cgi avec un message d'erreur si le formulaire ne contient pas les données attendues.
$query = new CGI;
unless ($query->param('fichier')) {
print "<font color=\"#ff0000\">Erreur, fichier non spécifié.<p>";
print "</body></html>";
exit(0);
}
Maintenant on récupère le fichier uploadé, nom puis données.
$file = $query->param('fichier');
$data = "";
while ($size = read($file,$daa,1024)) {
$data.=$daa;
}
Les données sont ensuite encodées en base64 alors que le nom du fichier est retraité pour exclure les données relatives à son chemin d'accès qui sont à présent inutiles :
$encodata = encode_base64($data); $file =~ s/\\/\//g; $file = substr($file, rindex($file, "/")+1);
Bien qu'en pratique un boundary fixe puisse être utilisé pour délimiter les différentes parties du message, nous allons inclure une séquence pour en produire un aléatoirement à chaque éxécution du script. Cela doit être une chaine de caractères ascii 7 bits alphanumériques. Les tirets (-) sont recomandés car ils sont garantis de ne pas apparaitre dans des données en base 64.
$bound = int(rand(1000))."--".int(rand(1000))."--".int(rand(1000));
On ouvre à présent une pipe en direction de sendmail (vérifiez qu'il est placé au même endroit sur votre serveur). On utilise le paramètre t qui permet de définir origine et destination en une seule fois dans le message.
open (SENDMAIL, "|/usr/lib/sendmail -t"); print SENDMAIL <<End; From: robot\@habett.org To: habett\@habett.org Subject: Envoi de fichier $file X-Mailer: Up2Me by HAbeTT MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="$bound" MIME format mail and base64 data $bound Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit $file is attached $bound Content-Type: text/plain; name="$file" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="$file" $encodata $bound ok End
Vous pouvez noter au passage que pour simplifier, l'attachement à été défini comme Content-Type: text/plain sur 8 bit ce qui conviendra à toutes les données mais qui aurai pu être plus précis. On aurait pu inclure une phase de détermination du type Mime des données uploadées en fonction de l'extension du fichier.
Reste à conclure la page html de contrôle.
print <<frag; message bien envoyé avec le fichier <b>$file</b> joint. <p> merci </body> </html> frag exit(0);