Table des matières
HardLinks
introduction
Il est très fréquent d'envoyer un mail à plusieurs destinataires. L'exemple le plus flagrant est l'utilisation de liste de diffusion ou de discutions. L'idée est d'éviter de stocker le mail autant de fois que le nombre de destinataire.
La solution est d'utiliser les liens physiques des disques durs.
Histoire de comprendre : un fichier est stocké sur le disque. Pour retrouver ce fichier, le système utilise un pointeur appelé inode. À cette inode on peut lui affecter un nom (chemin + nom du fichier). Et comme c'est pas trop mal fait, il est possible d'affecter plusieurs noms à la même inode. C'est un lien physique.
La seul contrainte, c'est l'obligation d'utiliser la même partition. Les liens physiques entre les partitions ne fonctionnent pas .
mise en œuvre
Dovecot dans la version 1.2 permet d'utiliser les liens physiques. Mais il est obligatoire de scripter un deliver pour que dovecot utilise les liens physiques.
voici le script delivery.pl
#!/usr/bin/perl use Sys::Syslog; # all except setlogsock(), or: $ID_mail_interne = rand(10000000); #il faut mettre le repertoire spool sur la meme partition que celle des boites mails #il faut aussi mettre les doits d'ecriture a l'utilisateur dovecot #il faut aussi mettre les droits d'ecriture sur les log $Spool="/var/mail/spool-tmp"; $Mail="$Spool/$ID_mail_interne"; $Debug="no"; openlog($program, 'cons,pid', 'user')|| exit 75 ; if (! -e $Spool) { mkdir $Spool||syslog('crit', '%s', "Failed to create the directory $Spool")&& exit 75 ; } open(TMPMAIL, ">$Mail")|| syslog('crit', '%s', "Failed to open file: $Mail")&& exit 75 ; foreach $Recepient (@ARGV){ if ($Recepient =~ /^-/) { syslog('crit', '%s', "command distribute.pl don\'t accept $Recepient "); exit 75; } if ($Debug eq yes){ syslog('crit',%s, "les destinataires sont $Recepient"); } } #on recupere le mail et on le stocke dans le spool while ($STDIN = <STDIN>) { print TMPMAIL $STDIN; if ($STDIN =~ /Message-Id/i ) { syslog('info', '%s', "$ID_mail_interne => $STDIN"); } } close (TMPMAIL); #ensuite pour chaque destinatire on envoie le mail foreach $Recepient (@ARGV){ if (/^-/) { syslog('crit', '%s', "command distribute.pl don't accept any arguments with the - "); exit 75; } if ($Debug eq yes){ syslog('crit',%s, "$Recepient $Mail"); } open DELIVER, "/usr/lib/dovecot/deliver -c /etc/dovecot/dovecot.conf -p $Mail -d $Recepient 2>&1 |"; @msgDELIVER=<DELIVER>; close DELIVER; if ( $? != 0 ) { print "command failed: $!\n"; syslog('crit', '%s', "the $ID_mail_interne are not delivred to $Recepient"); syslog('crit', '%s', "the command /usr/lib/dovecot/deliver said"); for $lineDeliver (@msgDELIVER){ syslog('crit', '%s', " $lineDeliver"); } exit 75; } else { printf "command exited with value %d", $? >> 8; syslog('info', '%s', "the $Mail are delivred to $Recepient"); unlink($Mail)|| syslog('crit', '%s', "cannot delete this file $Mail"); exit 0; } } closelog();
ensuite pour pouvoir l'utiliser, vous le copiez dans /usr/local/bin/
cp delivry.pl /usr/local/sbin/
puis dans le master.cf vous modifiez la ligne :
# Dovecot LDA dovecot unix - n n - - pipe flags=DRhu user=utilisateurmail:utilisateurmail argv=/usr/lib/dovecot/deliver -d $recipient
en
# Dovecot LDA dovecot unix - n n - - pipe user=utilisateurmail:utilisateurmail argv=/usr/local/sbin/delivery.pl ${user}
Et voila dovecot qui delivre les mails avec des liens en dur.