#!/usr/bin/perl -w # -*- perl -*- # # mail2msg.pl # # Author: Heiko Teichmeier # Mail: heiko.teichmeier@tei-lin-net.de # Web: www.tei-lin-net.de # Date: 2002-10-13 # Version: 0.1.1 # License: GPL # # => By using parts from the following script and author: #===================================================================+ # smsmail.pl # # Author: Daniel.Stenberg@haxx.nu # Date: 2000-mar-17 # Version: 0.1 # License: Free, keep it free, but keep my name when you modify it! #===================================================================+ # # Dieses Perl-Script soll Mails an verschiedene Dienste weitergeben. # Zur Zeit ist ein SMS-Dienst (yaps auf Linux) und Winpopup konfiguriert. # Das Script extrahiert "To:", "From:", "Replyto:", "Subject:" und # den Inhalt des "Bodys" aus der Mail und übergibt diese an das # Unterprogramm "do_send_message". # Je nachdem unter welchem Namen das Script aufgerufen wird (über # verschiedene Symlinks auf dieses Programm realisieren # [ln -s /usr/local/bin/mail2msg.pl /usr/local/bin/mail2sms_in_to.pl]), # führt das Unterprogramm unterschiedliche Operationen durch und benutzt # die Variablen unterschiedlich. # An dieser Stelle ist auch die Möglichkeit gegeben eigene Services zu # definieren. Solltet Ihr noch andere Möglichkeiten finden, für welche # Services dieses Script verwendbar ist bitte ich um Nachricht und # Übersendung des Codes (bzw. Link auf die URL, unter der ich es mir # ansehen kann). # Nun viel Spaß beim Benutzen und ergänzen dieses Perl-Programms. # use strict; # Globale (überall verfübare) Variablen setzen use vars qw($YAPS_BIN $MAILER $SCR_NAME $WINPOPUP_SUBJ $WINPOPUP_TO $SMS_SUBJ $SMS_TO $WERBUNG $CUT $CREAT_ERR_MSG $ERR_REPLY $PROG_ABS); my ($state,$replyto,$from,$to,$subject,$msg,$mail_msg); my ($lines,$max_msg_len,$max_lines,$line_len,$max_line_len); my (%mail,$key,$w_str,$work_str,$arr_body,$mail_ptr,@in); my ($err_txt,$service,$mail_domain); my ($err_from,$err_to,$err_subj,$err_msg,$err_reply,$err_max_lines,$i); # +------------------------------------------+ # | Programmvariablen festlegen | # +------------------------------------------+ # #+====== Globale Variablen ============================== #| ### Programmnamen für verschiedene Aufgaben festlegen # (dann entsprechenden symlink setzen) $SMS_SUBJ = "mail2sms_in_subj.pl"; # Nachricht von Mail an SMS-Programm # Tel.-Nr. im "Subject:" $SMS_TO = "mail2sms_in_to.pl"; # Nachricht von Mail an SMS-Programm # Tel.-Nr. im "To:" $WINPOPUP_SUBJ = "mail2winpop_in_subj.pl"; # Nachricht von Mail an Winpopup # user-name im "Subject:" $WINPOPUP_TO = "mail2winpop_in_to.pl"; # Nachricht von Mail an Winpopup # user-name im "To:" $mail_domain = "teichmeier-gc.de"; $YAPS_BIN = "/usr/bin/yaps"; # Pfad und Name des SMS-Programms $MAILER = "/usr/sbin/sendmail -t"; # Befehl für Mail versenden # [-t]: sendmail liest "To:" und "From:" # aus dem Mail-Header $PROG_ABS = "mail2msg\@".$mail_domain; # Absender der Benachrichtigung festlegen # # ==> Änderungen nur bis hierher nötig #======================================================== # hier noch etwas Werbung $WERBUNG = "*powered by \nhttp://www.tei-lin-net.de/\n"; ### Abtrennzeichen festlegen (wird bei abgeschnittenem, weil zu langem Body angehängt) $CUT = ""; ### soll Fehler-mail erstellt werden $CREAT_ERR_MSG = 1; ### Abfragen des Scriptnamens -> unter verschiedenen Namen # (per symbolischen Link) zu verschiedenen Aufgaben verwendbar $SCR_NAME = $0; # den Programm-Name vom letzten "/" bis Zeilenende extrahieren $SCR_NAME =~ s/(.*\/)(.+)$/$2/; #| #+====== Ende Globale Variablen ========================= ###-> Maximale Länge der Nachricht die in diesem Script erstellt wird $max_msg_len = 95; $arr_body = 0; ###-> Zähler für Zeilen-Anzahl der Mail, am Ende nicht mehr ### als 40 Zeilen zulassen $lines = 0; $max_lines = 40; ###-> Zähler für Zeilen-Länge, nicht mehr als 256 zulassen $line_len = 0; $max_line_len = 256; # #+------------------------------------------+ ###### Hauptroutine ###### # $state = 0; # hier weiß ich nicht genau wozu benötigt? $i = 0; while() { # -> Beim Einlesen Länge der Zeilen auf "$max_line_len" begrenzen $work_str = substr($_, 0, $max_line_len); # zählen der Schleifendurchläufe (Zeilen) $i++; if(0 == $state) { # Wenn nicht "$arr_body" gesetzt ist, dann ... if (!$arr_body) { # ... sind wir noch im Header -> extrahieren der interessierenden # Variablen if($work_str =~ /^Subject: (.*)/) { $state = 1; $subject = $1; } elsif($work_str =~ /^From:.*[^a-zA-Z0-9.](([a-zA-Z0-9.\-]+)@([a-zA-Z0-9.\-]+))/) { # we extract the email address only $from = $1; } elsif($work_str =~ /^To:.*[^a-zA-Z0-9.](([a-zA-Z0-9.\-]+)@([a-zA-Z0-9.\-]+))/) { # we extract the email address only $to = $1; } elsif($work_str =~ /^Reply-To:.*[^a-zA-Z0-9.](([a-zA-Z0-9.]+)@([a-zA-Z0-9.]+))/) { $replyto = $1; } # wenn Leerzeile gefunden -> "$arr_body" setzen -> # Verzweigung zum Einlesen des Bodys elsif($work_str =~ /^$/) { $arr_body = 1; } } #-> sonst, einlesen des Bodys in "$msg" else { # max. 1 Leerzeichen erlauben, sonst ausfiltern dieser $work_str =~ s/[\s]+/ /g; $msg .= $work_str; } } else { if($work_str =~ /^[ \t]+(.*)/) { $subject .= $1; } else { $state = 0; # back to nothing } } # wenn "$max_lines" erreicht - abbrechen! if ($i>=$max_lines) { $err_max_lines = 1; last; } } # Versuch des Abfangens von undefinierten Variablen if (!$msg) { $err_msg = 1; } else { # "$mail_msg" auf "$max_msg_len" kürzen und "$cut" anfügen if (length $msg > $max_msg_len) { $msg = substr($msg, 0, ($max_msg_len - (length $CUT))); $msg .= $CUT; } } if (!$from) { $err_from = 1; } if (!$to) { $err_to = 1; } if (!$subject) { $err_subj = 1; } if (!$msg) { $err_msg = 1; } if (!$replyto) { $err_reply = 1; } ### Den Rest des Scripts nur ausführen wenn Absender angegeben # unless ($err_from) { ### ich benötige nur die Angaben "$from", "$subj", "$msg", "$to" für dieses # Script, # deshalb auch beim Hash %mail die nicht benötigten Variablen deaktivieren # !!! auch beim Einlese-Block in den verwendeten Subroutinen !!! # Variablen dem Hash "%mail" zuweisen $mail{"from"} = "$from"; unless ($err_to) { $mail{"to"} = "$to"; } unless ($err_subj) { $mail{"subject"} = "$subject"; } unless ($err_msg) { $mail{"msg"} = "$msg"; } unless ($err_reply) { $mail{"replyto"} = "$replyto"; } # Eine Referenz auf den Hash %mail in $mail_ptr verpacken $mail_ptr = \%mail; # ###### Ende der Hauptroutine ###### do_send_msg($mail_ptr,$err_to,$err_subj,$err_msg,$err_reply,$err_max_lines); } ############################################################## # # ====> ab hier Subroutinen # ################################# ## # ############################################################## sub do_send_msg { ############################################################## # Versand einer SMS-Nachricht -> Tel-Nr im "Subject: " #================================================= # [] my ($sub_txt,$body_txt,$recv,$send_response,$signatur); my @in = @_; my $mail_ptr = $in[0]; my $service = "MAIL-TO-MESSAGE"; my $err_to = $in[1]; my $err_subj = $in[2]; my $err_msg = $in[3]; my $err_reply = $in[4]; my $err_max_lines = $in[5]; # Derefereinzieren des Hash %mail my %mail = %{$mail_ptr}; my $from = $mail{"from"}; my $to = $mail{"to"}; my $subject = $mail{"subject"}; my $msg = $mail{"msg"}; my $replyto = $mail{"replyto"}; # Nur weiter, wenn diese Fehler nicht auftreten unless ($err_to || $err_subj || $err_msg || $err_max_lines) { $send_response = 1; ### Verzweigung je nachdem unter welchem Namen das Programm aufgerufen wurde # # -> hier Einbindung weiterer Dienste möglich # ##### # => MAIL-to-SMS, Nr. im Subject, To: # if ($SCR_NAME eq $SMS_SUBJ) { $service = "MAIL-TO-SMS"; # Prüfung ob im "Subject:" auch nur Zahlen stehen if ($subject =~ /^([0-9]+)/) { $recv = $1; ### jetzt wird die Nachricht an den entsprechenden Dienst gesendet # $send_response = system ("$YAPS_BIN '$recv' '(Von: $from) $msg'"); } else { $err_subj = 1; err_msg_out($from,$service,$msg,$recv,$err_to,$err_subj,$err_msg,$err_reply); } } ##### # => MAIL-to-SMS, Nr. im To:, (To: <0177777777@sms.your-domain.de>) # elsif ($SCR_NAME eq $SMS_TO) { $service = "MAIL-TO-SMS"; # Prüfung ob im "To:" eine Mail-Adresse mit ausschließlich Zahlen # vor dem "@" steht if ($to =~ /^([0-9]+)@([a-zA-Z0-9.\-]+)/) { $recv = $1; ### jetzt wird die Nachricht an den entsprechenden Dienst gesendet # $send_response = system ("$YAPS_BIN '$recv' '(Von: $from) $msg'"); } else { $err_to = 1; err_msg_out($from,$service,$msg,$recv,$err_to,$err_subj,$err_msg,$err_reply); } } ##### !!! Noch nicht getestet, nur Beispiel für andere Möglichkeiten !!! # # => MAIL-to-WINPOPUP, Net-Bios-Name der "Empfänger-Maschine" im To:, # (To: ) # elsif ($SCR_NAME eq $WINPOPUP_SUBJ) { $service = "MAIL-TO-WINPOPUP"; $recv = $subject; ### jetzt wird die Nachricht an den entsprechenden Dienst gesendet # $send_response = system ("echo 'Von: $from\n====\n\n$msg' | /usr/bin/smbclient -M '$recv' -U $service >/dev/null 2>&1"); } ##### !!! Noch nicht getestet, nur Beispiel für andere Möglichkeiten !!! # # => MAIL-to-WINPOPUP, Net-Bios-Name der "Empfänger-Maschine" im To:, # (To: ) # elsif ($SCR_NAME eq $WINPOPUP_TO) { $service = "MAIL-TO-WINPOPUP"; if ($to =~ /^([a-zA-Z0-9_]*)@([a-zA-Z0-9.\-]+)/) { $recv = $1; ### jetzt wird die Nachricht an den entsprechenden Dienst gesendet # $send_response = system ("echo 'Von: $from\n====\nSubj: $subject\n=====\n$msg' | /usr/bin/smbclient -M '$recv' -U $service >/dev/null 2>&1"); } else { $err_to = 1; err_msg_out($from,$service,$msg,$recv,$err_to,$err_subj,$err_msg,$err_reply); } } $signatur = "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n $service - Mailer\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n$WERBUNG"; # Wenn Versand fehlgeschlagen (Rückgabe = 1) Fehlermail erstellen if ($send_response) { err_msg_out($from,$service,$msg,$recv,$err_to,$err_subj,$err_msg,$err_reply); } else { # Versenden einer Benachrichtigungsmail an Absender die "Unable to invoke mailer for response\n" unless open (OUT, "|$MAILER"); print OUT "From: $PROG_ABS\n"; print OUT "To: $from\n"; print OUT "Subject: $service-Nachricht an $recv gesendet\n"; print OUT "X-Mailer: mail2msg.pl - a universal mail-to-message Script\n"; print OUT "X-Mailer: by Heiko Teichmeier [www.tei-lin-net.de]\n"; print OUT "X-Mailer: (Parts from Daniel Stenberg)\n"; print OUT "\n"; # header/body separator print OUT "Ihre $service-Nachricht:\n"; print OUT "========================\n"; print OUT "$msg\n\n"; print OUT "An:\n"; print OUT "===\n"; print OUT "$recv\n\n"; print OUT "wurde soeben gesendet!\n"; print OUT "$signatur\n"; close (OUT); } } # Fehler-Mail an Absender else { err_msg_out($from,$service,$msg,$recv,$err_to,$err_subj,$err_msg,$err_reply); } } # ### Ende von "do_send_msg" ### ##################################################### sub err_msg_out { ### Ausgabe einer "Fehler-mail" an "$From" ###### my ($err_txt,$err_txt_1,$signatur,$err_subject); my @in = @_; my $from = $in[0]; my $service = $in[1]; my $msg = $in[2]; my $recv = $in[3]; my $err_to = $in[4]; my $err_subj = $in[5]; my $err_msg = $in[6]; my $err_reply = $in[7]; if ($CREAT_ERR_MSG) { if ($err_to || $err_subj || $err_msg) { $err_subject = "Mail-to-Message - Fehler"; $err_txt = "konnte nicht gesendet werden!"; if ($err_to) { $err_txt_1 = "\nKeine (oder fehlerhafte) Angabe im \"To:\" !!!\n"; } if ($err_subj) { $err_txt_1 .= "\nKeine (oder fehlerhafte) Angabe im \"Subject:\" !!!\n"; } if ($err_max_lines) { $err_txt_1 .= "\nZu viele Zeilen im \"Header:\" !!!\n"; } elsif ($err_msg) { $err_txt_1 .= "\nKein Text im \"Body:\" !!!\n"; } } else { $err_subject = "$service Nachricht an $recv - Fehler"; $err_txt = ":"; $err_txt_1 = "$msg\n\nAn:\n===\n$recv\n\n... Versand fehlgeschlagen!"; } # Fußzeile der Mail $signatur = "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n $service - Mailer\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n$WERBUNG"; # Versenden einer Benachrichtigungsmail an Absender die "Unable to invoke mailer for response\n" unless open (OUT, "|$MAILER"); print OUT "From: $PROG_ABS\n"; print OUT "To: $from\n"; print OUT "Subject: $err_subject\n"; print OUT "X-Mailer: mail2msg.pl - a universal mail-to-message Script\n"; print OUT "X-Mailer: by Heiko Teichmeier [www.tei-lin-net.de]\n"; print OUT "X-Mailer: (Parts from Daniel Stenberg)\n"; print OUT "\n"; print OUT "Ihre $service-Nachricht $err_txt\n"; print OUT "================================================\n"; print OUT "$err_txt_1\n\n"; print OUT "$signatur\n"; close (OUT); } exit 0; } # ### Ende sub err_msg_out ###