Passer un mail à un programme java via procmail

Ducktale

Grand Maître
#1
Hello !

Mon problème est à cheval entre l'utilisation de Linux et la programmation.

Sous procmail, je cherche à passer les mails entrants sur mon serveur SMTP et devant être délivrés localement dans un programme Java.

J'ai essayer de piper le mail directement au programme, mais il n'en veut pas des masses.

[cpp]:o:
|/usr/lib/java/bin/java MonPackage.MaClasse[/cpp]
Cela ne me donne rien dans le args[0] de mon main.


Une idée pour arriver à lui faire passer le mail entier comme chaine de caractère dans args[0] ?

Merci !
 

bebRito

Grand Maître
#2
Salut,

Je ne connais pas procmail mais par contre, pour passer un argument à un main java, il n'y a qu'une solution (à ma connaissance), c'est d'utiliser:[cpp]java MaClass.class argument1[/cpp]ou[cpp]java -jar MonAppli.jar argument1[/cpp]

Quelle est la sortie de la commande avant ton pipe ?

L'idée serait peut être de ranger le contenu de cette commande dans un fichier et de passer ce fichier en paramètre du java.
Il y a plein de solution, je pense.

Détaille un peu plus les infos d'entrées.
 

zeb

Modérateur
#3
Salut Ducktale :hello:

Le pipe (|) permet de rediriger les entrées/sorties standards, autrement dit, les fichiers de descripteurs 0 et 1. Il faut donc par cette méthode, lire l'entrée standard dans ta classe.

Si tu veux passer un paramètre à ta classe, c'est à la suite, sur la ligne de commande, comme te le montre bebRito.

Tu veux mettre tout le contenu de tel fichier en argument ?
Voilà :[fixed]$> monprogramme "$( cat monfichier )"[/fixed]

C'est ce que tu cherchais ?

EDIT: Arff, pas compris que tu présentais ton fichier .procmailrc Je regarde et reviens à toi.
 

Ducktale

Grand Maître
#4
Merci à vous deux.

Le problème est justement l'interfaçage avec procmail.

zeb, qu'est ce que le :o: que tu insères dans ton deuxième exemple ?
 

Ducktale

Grand Maître
#5
OK, je comprends mieux :d

Oui, c'est mon fichier .procmailrc
Le pipe est censé être un stdin, selon la doc procmail.
 

zeb

Modérateur
#6
Oki, alors il faut soit modifier ta classe pour lire les données sur l'entrée standard (stdin) plutôt que sur la ligne de commande, soit intercaler un autre programme entre procmail et ta classe.

La première solution est la plus élégante. Pour échanger des données de façon standard, procmail les écrit sur la sortie standard (stdout), tandis que ta classe les lit sur entrée standard (stdin). Bref, c'est standard :D

La seconde est facile à mettre en oeuvre, avec un petit script, qui va lire son entrée standard, et mettre le tout dans le premier argument de ta classe, mais c'est vraiment moche :

Code:
#!/bin/bash

# // Création d'un fichier temporaire
typeset TMPFILE
while true ; do
	TMPFILE=/tmp/mail.$RANDOM
	[ ! -f $TMPFILE ] && {
  	> $TMPFILE && break
  	exit 2
	}	
done

# // Lecture sur l'entrée standard, écriture dans le fichier temporaire
while read LINE ; do
  echo "$LINE" >> $TMPFILE
done

# // Traitement Java
/usr/lib/java/bin/java MonPackage.MaClasse "$( cat $TMPFILE )"

# // Suppression du fichier temporaire. Un trap serait plus propre
rm -fr $TMPFILE
 

Ducktale

Grand Maître
#7

hmmm .... Merci pour ta recherche ! Je ne suis pas sûr de comprendre la moitié de ce que tu racontes, mais on va essayer de voir ça :d

Pour la première solution, je ne vois pas comment mon programme Java peut lire sur l'entrée standard ? J'ai bien sûr la possibilité de modifier ma classe si nécessaire. Comment sait-elle quand le mail commence à arriver sur l'entrée standard, comment sait-elle quand le mail est terminé, qu'un autre mail arrive, etc ? Doit-on exécuter le programme Java en tant que démon dans ce cas ?

Pour la deuxième solution, j'en avais eu l'idée, même si je n'étais pas arrivé à un truc aussi abouti que ce que tu me proposes. Cependant je trouve ça tiré par les cheveux, et assez moche en fait. :p Mais je garde en effet sous le coude au cas où.

Dans les deux cas, j'ai peur que ça me cause des problèmes dans le cas de l'arrivée de plusieurs mails, et donc du lancement concurrent du script.

Merci en tout cas ...
 

bebRito

Grand Maître
#8
Pour lire l'entrée standard en Java, il y a la classe System :
[cpp]System.in.read();[/cpp]
Tout comme pour écrire sur la sortie standard:[cpp]System.out.println("TOTO");[/cpp]

[strike]Je suppose qu'il faut utiliser le code retour pour savoir comment ca s'est passé.[/strike]

Tant que tu as une info sur l'entrée tu la lis.
Après, pour les différents mails, il faut certainement analyser ce qu'il se passe sur la stdout.

Quelles sont infos que procmail envoie ?
 

Ducktale

Grand Maître
#9
Pas trop d'idées. :d

Procmail est appelé à chaque mail reçu. Il me semble qu'il y a un système de lock à chaque mail, mais je ne suis pas certain de son fonctionnement détaillé.

Selon la doc procmail, quand j'écris le caractère | (pipe) dans le .procmailrc, il passe le mail au programme qui suit via stdin.

Mes compétences en la matière s'arrêtent là :d Je ne vois même pas comment faire pour être certain que c'est bien mon mail qui est dans le stdin quand ça passe par sendmail, ni qu'il est lancé mail par mail, ni ce qui se passe entre deux mails qui se suivent ...
 

bebRito

Grand Maître
#10
Je n'ai pas assez de compétences sur le sujet, procmail en particulier.

Plutôt que de faire un pipe, peux-tu rediriger vers un fichier pour voir ce qui est envoyé ?
 

zeb

Modérateur
#11
Yuhuuu, il n'est pas programmeur, le maître Yoda !!!

On oublie cette histoire de passer le contenu du message par la ligne de commande. C'est TRES moche, et ce n'est pas comme ça qu'il faut faire.

Non, il faut que ta classe lise sur son entrée.

Alors, 1°, pas de problème pour savoir si c'est le bon mail ou pas. Si tu reçois plusieurs mails en même temps, procmail lancera plusieurs fois ton programme en même temps, avec chacun des mails en entrée d'une des instances de ton programme.



2° Comment qu'on fait pour savoir quand ça commence ?
Ben en fait, ton programme n'est lancé que quand ça commence, donc ça commence quand ça commence.

3° Comment qu'on fait pour savoir quand ça finit ?
Le in.read va lire une ligne sur l'entrée standard et retourner le nombre de caractères lus. A la fin, c'est-à-dire quand il n'y a plus rien à lire, read renvoie -1. Donc, si tu mets ta lecture dans une boucle while avec comme condition de sortie un -1 sur le code de retour de read, tu devrais avoir la solution à ton problème.

Pour plus de renseignements, repose ta question en programmation, à la lumière de ces quelques explications.
 

Ducktale

Grand Maître
#12

Ah ça non :d
Je connais les principes généraux, je sais instancier deux trois trucs, écrire une ou deux bricoles de script, mais ça s'arrête là :d



J'ai trouvé à la lumière de tes explications quelques liens détaillant quelques exemples de lecture sur le stdin, je vais essayer de me pencher de ce côté là, en faisant quelques tests.

Merci infiniment pour le schéma et les explications en tout cas. :merci:
 

bebRito

Grand Maître
#13
Il est au top ce zeb !! :D
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Membres en ligne
Aucun membre en ligne actuellement.
Derniers messages publiés
Statistiques globales
Discussions
871 650
Messages
8 139 582
Membres
1 582 331
Dernier membre
navywilliamsusa
Partager cette page
Haut