Newsgroup: it.comp.lang.perl
Titolo: Reindirizzare Output System

Ho un problema.
Devo aprire una system per chiamare il sendmail. Mi serve per
verificare la correttezza degli indirizzi di posta elettronica.
Non riesco a reindirizzare l'output a /dev/null, o qualsiasi altro
file temporaneo.
La system ha la sisntassi
@args = ("/usr/lib/sendmail", "-bv", "$addr");
system @args;
se io aggiungo in fondo, come arogmento, il ">/dev/null 2>&1"
questo viene passato al programma vero e proprio, e non viene
interpretato come un reindirizzamento.
Se, invece, lo metto nel primo argomento, il perl controlla l'esistenza
dell'eseguibile ("/usr/lib/sendmail >/dev/null...  non esiste!) e mi
esce
con errore.
Grazie in anticipo per la cortese attenzione.

 system @args;

Non sono sicuro che si possa fare semplicemente con system(LIST), perche'
stai esplicitamente bypassando le funzioni della shell sottostante, per cui
ti risparmi sia l'espansione delle wildcard e delle variabili, sia tutte le
funzionalita' di redirezione.
Se devi controllare STDERR e STDOUT, forse ti conviene provare con
open() o con una system(SCALAR) (guarda perlfaq8).
Tra l'altro, a meno che tu non abbia gia' controllato il contenuto di $addr,
la chiamata 
 
  @args = ("/usr/lib/sendmail", "-bv", "$addr");
  system @args;
mi sembra altrettanto pericolosa di
  system("/usr/lib/sendmail -bv $addr");
 
perche' stai interpolando $addr in una stringa, esponendoti a problemi se
$addr contiene cose strane.
Per stare un pochino piu' sicuro, dovrebbe essere
  @args = ("/usr/lib/sendmail", "-bv", $addr );
  system @args;                    #   ^^^^^  Senza virgolette
Su questo non ci metto la mano sul fuoco, ma di solito dicono sia bene non
mettere tra virgolette delle variabili inutilmente.
Maurizio
-- 
Maurizio M. Munafo' / 
mmmu...@netscape.net
"Consider Phlebas, who was once handsome and tall as you" (T.S.Eliot)


Ti credo sulla parola, anche se, sinceramente non capisco la differenza.
Comunque (grazie per l'indicazione perlfaq8 ho risolto cosě)
# Sub che controlla la validita' di
# un indirizzo
sub check_addr {
  my ($address) = @_;
  `/usr/lib/sendmail -bv $address 1>$log 2>&1`;
  return $?;
}
E come puoi ven vedere nella stringa destinata alla shell ci sono
delle variabili del perl che vengono correttamente espanse. :P
Ciao.

 delle variabili del perl che vengono correttamente espanse. :P
 Beh. Lo stesso risultato dovevi ottenerlo con
 
  system "/usr/lib/sendmail -bv $address 1>$log 2>&1";
 
 In effetti, usare i backtick `` in un contesto vuoto non e' molto fine.
 I backtick servono proprio perche' ti ritornano l'output del comando (cosa
 che system non fa).



Ok. Spero che questa sia la buona!
# Sub che controlla la validita' di
# un indirizzo
sub check_addr {
  my ($address) = @_;
  return 1 if $address =~ tr/|; //;
  return system "/usr/lib/sendmail -bv $address 1>>$log 2>&1";
}

 }
Scusa, ma tu torni 1 se la roba NON funziona e 0 se funziona?
Mi sembra un po' contorto...
Tra l'altro... non sono sicuro che | e ; non possano essere permessi in un
indirizzo di mail.


 indirizzo di mail.
Beh... inzomma... io ritorno il valore di uscita della sendmail.
Solitamente in tutte le funzioni 0 č andata bene ed !0 č il codice
di errore della funzione.
Sono programmatore C da parecchi anni, e lě č tutto cosě.
Non č contorto, anzi, č standard.
Ho provato a cercare nella RFC 822 a riguardo, ma non ho trovato niente.
Io e-mail con pipe e puntievirgola non ne ho mai vista.
Poi ho provato ad aggiungere un utente (Solaris 2.6) e non mi accetta
nel nome ne la pipe ne il puntoevirgola....
Quindi non rimangono che gli alias, ma se tu metti in un alias una pipe
questa
viene interpretata come pipe vera e propria... per eseguire i programmi.
Quindi ho dedotto, anche se non l'ho letto da nessuna parte, che non
sono accettati.
CIAO.

 Non è contorto, anzi, è standard.
Beh. Il mio era in commento personalissimo.
La mia idea e' che una funzione che si chiama check_address() debba tornarne
un valore vero se l'indirizzo esiste e un valore falso altrimenti, per
usarla direttamente in un if
 if (check_address('
pi...@pluto.it
'))
  {
    print "Complimenti! L'indirizzo esiste.\n";
  }
 else
  {
    print "Peccato! L'indirizzo non esiste.\n";
  }
Con il tuo approccio, bisogna ricorrere al controintuitivo (IMHO)
 unless (check_address(....))
  {
  }
 
oppure all'esplicito
 if (check_address(...) == 0)
  {
  }
Il fatto che in C si faccia in un certo modo non depone a suo favore :)
E poi stai programmando in Perl: Get the Perl Thinking! :)
Infine, se anche ti servisse il codice di errore, lo poi o gestire dentro
check_address() o recuperare all'esterno tramite $?, e mantenere cosi' la
logica booleana nel valore di ritorno della tua funzione.
Saluti


 logica booleana nel valore di ritorno della tua funzione.
Forse cosě sarei veramente contorto :P
Potrei, per concludere la diatriba, chiamare la mia funzione check_address
check_if_the_address_is_wrong
Ciao.

On 29 Jun 1999 09:22:46 GMT, 
mmmu...@netscape.net
 (Maurizio M.
Munafo`) wrote:
| Tra l'altro... non sono sicuro che | e ; non possano essere permessi in un
| indirizzo di mail.
secondo me conviene troncare allo spazio.
$_=(split(/ /,$_,2))[1];
oha

 wrote:
:> Tra l'altro... non sono sicuro che | e ; non possano essere permessi in un
:> indirizzo di mail.
: Ho provato a cercare nella RFC 822 a riguardo, ma non ho trovato niente.
: Io e-mail con pipe e puntievirgola non ne ho mai vista.
Tanto per citare qualche amenita`: in "Mastering Regular Expression"
viene presentata una re per validare un indirizzo di email.
E` lunga 6598 caratteri!
Gli indirizzi di email sono tra le cose piu` cattive al mondo :-)
-- 
Nando Santagata: Telemastica & infornatica
Key fingerprint = C2 D9 C0 8E D5 B7 04 97  AF E8 3F 3E AF 4E 7F 9E
finger nando (at) mail (dot) ipers (dot) net   for my PGP public key
Home: 
http://www.ipers.net/~nandos

 Gli indirizzi di email sono tra le cose piu` cattive al mondo :-)
Infatti. Stavo per suggerirla, ma in effetti e' un po' un'esagerazione :)


 $_=(split(/ /,$_,2))[1];
Cioe' prendi tutto quello che c'e' DOPO il primo spazio? Sicuro che non
fosse quello che c'e' prima?
Comunque e' un'istruzione inutilmente complicata
 ($_) = split;
e' piu' che sufficiente per prendere tutto quello che c'e' prima del primo
spazio.
Comuqnue lo spazio e' un carattere permesso, se chiuso tra virgolette.
Pare che a sinistra dell'@ sia permesso praticamente tutto!
Infatti, ho definito sul mio sistema un alias "Mr. Munafo" corrispondente al
mio account e sono riuscito senza problemi a mandare un mail a
  "Mr. Munafo"@
xxxx.xxxx.it
Con le virgolette, il punto, lo spazio e tutto quanto!
Vorrai mica negarmi il privilegio di avere un tale indirizzo di e-mail?
Di fatto, non esiste una regola semplice per validare indirizzi di e-mail.
Gli indirizzi di e-mail possono perfino contenere commenti.
Ho provato il programmino di Mastering Regular Expression per validare gli
e-mail.
Mi dice che "Mr;ls * @@@Munafo"@
pippo.it
 e' sintatticamente valido!
Qualsiasi cosa che sta prima dell'@ tra doppie virgolette e' valida.
Quindi, non e' possibile, in modo semplice, decidere quali caratteri debbano
stare in un indirizzo di e-mail e quali no!
Se torniamo al problema originario, tutto questa questione del velidare
l'indirizzo diventa, parzialmente, risolvibile se invece di usare la
system(SCALAR) si usasse una system(LIST).


 system(SCALAR) si usasse una system(LIST).
Ok, ma come fare il reindirizzamento?
PLZ, Example.
Ciao.

 Ciao.


 }
Mi sembrava che fosse possibile redirigere ragionevolmente STDOUT e STDERR
per uno script e poi farli tornare ai vecchi valori!
Traendo ispirazione dalla descrizione di open() in perlfunc (e quindi anche
in Programming Perl)...
sub check_addr {
  my $address = shift;
  open(SAVEOUT, ">&STDOUT");
  open(SAVEERR, ">&STDERR");
 
  open(STDOUT, ">$log") || die "Can't redirect stdout";
  open(STDERR, ">&STDOUT") || die "Can't dup stdout";
 
  system("/usr/lib/sendmail","-bv",$address);
  close(STDOUT);
  close(STDERR);
  open(STDOUT, ">&SAVEOUT");
  open(STDERR, ">&SAVEERR");
  return $?;
}
Naturalmente e' un po' un overkill :) Pero' riesci a fare la chiamata a
system senza dover passare per la shell e doverti preoccupare di
metacaratteri strani in $address.
Tra l'altro, se $address e' 
 
  "
pi...@pluto.it
; ls *"
(senza le virgolette)
il mio sendmail dice che l'indirizzo e' deliverable e torna stato 0 ! 
Apparentemente, qualsiasi cosa che non e' un indirizzo locale (per cui
l'utente non esiste), mi da stato 0 e indirizzo deliverable.
A questo punto mi chiedo a cosa ti serva tutta questa baraonda. Credo
proprio che -bv serva a sendmail solo per validare utenti LOCALI
Per validare utenti remoti, a parte mandargli effettivamente un e-mail e
richiedere una risposta esplicita, c'e' solo il protocollo di VRFY di SMNP,
che pero' non e' supportato da tutti.
Morale: se devi verificare che gli utenti ti abbiano dato un e-mail valido,
l'unico modo e' mandare un mail a quell'indirizzo per chiedere conferma! 


 l'unico modo e' mandare un mail a quell'indirizzo per chiedere conferma!
Bah, qualche controllo lo fa', anche se devo ammettere che sono controllo
poco poco efficenti. Forse controlla che ci sia @ e basta.
Sigh.
Ma vedi, non posso farmi spedire indietro l'e-mail, visto che č una cosa
pubblicitaria, la gente se ne infischia di iscriversi, figuriamoci, poi, di
mandarmi una reply.
Dovrei cercare un programma (o implementarlo) che si connette al
server alla porta 25, fa il suo HELO, MAIL, RCPT e guarda se l'RCPT
verso l'utente č andato a buon fine.
Il problema perň č l'host, infatti 
pi...@tin.it
 non č
l'utente pippo all'host 
tin.it
, ma all'host 
mail.tin.it
. Io non so come faccia
il sendmail a trovare l'host giusto dato quello mozzo. Forse č uno standard
aggiungere mail?
Boh.
Comunque adesso non ho tempo per farlo e rimane cosě.
Grazie per i consigli, Ciao.

 mandarmi una reply.
Allora tu gli mandi l'email e basta.
Se torna indietro un errore cancelli l'utente! Cavoli loro.
E' inutile complicarsi la vita.
Poi ci sapebbe la possibilita' che io mi iscriva mettendo l'indirizzo di
e-mail di un altro. L'indirizzo esiste e tu mandi le informazioni all'altro,
che non le vuole e si incazza: come fai?
Devi comunque mettere qualche disclaimer tipo: "questo indirizzo e' stato
registrato da tizio per questo servizio: se l'hai ricevuto senza averlo
richiesto, fai questo, questo e quest'altro"
Mi sa che piu' cerchi di analizzare il problema piu' magagne ci trovi :(


 Mi sa che piu' cerchi di analizzare il problema piu' magagne ci trovi :(
Grazie a te.
Ciao.

ftp://uiarchive.uiuc.edu/pub/lang/perl/CPAN/authors/Tom_Christiansen/scripts/ckaddr.gz

Boh.
Facile chiede il record MX al Name Server di quel dominio e dopo di
che contatta quel sistema sulla porta 25.
Quel sistema o detiene la casella di posta oppure sa a quale altro
sistema inoltrare il messaggio.
--------------------------------------------
 Voster semper Voster
         .And.
Ogni idea esposta rispecchia la mia personale opinione
 e non e' in alcun modo correlata con lo CSELT S.p.A.

 wrote:
:>Ma vedi, non posso farmi spedire indietro l'e-mail, visto che è una cosa
:>pubblicitaria, la gente se ne infischia di iscriversi, figuriamoci, poi, di
:>mandarmi una reply.
: Non so se risponderti, visto lo scopo per cui lo fai...
: N.B. questo viene anche dalle circa 60 E-Mail pubblicitarie che mi
: tocca cancellare al giorno... 
Giusto, salvate Internet, non rispondetegli.
