Directory sotto controllo con Perl

folder_locked.png
Navigando per CPAN, l’imponente archivio dei moduli Perl, mentre cercavo delle funzioni per smanettare con i permessi sui file, mi sono imbattuto nel modulo File::Monitor, che permette di monitorare file e directory in cerca (o in attesa) di cambiamenti di qualsiasi tipo.
Capirete che questo genere di funzionalità puà rivelarsi molto utile qualora si volesse monitorare lo stato di una directory importante a cui nessuno dovrebbe apportare modifiche, come ad esempio le directory di installazione del vostro sito internet, le directory contenenti informazioni sugli utenti che dovrebbero essere modificate solo dall’amministratore di sistema o dal sistema stesso ecc.. .
Questo modulo offre una classe principale File::Monitor, a cui assegnare diversi elementi da controllare e grazie ad un sistema di gestione degli eventi, ad ogni occorrenza di un determinato tipo di evento, potrete eseguire una specifica serie di istruzioni (contenute in subroutine).
Ecco la lista gerarchizzata dei possibili tipi di evento:

change

created

deleted

metadata

time

mtime

ctime

perms

uid

gid

mode

size

directory

files_created

files_deleted

Ogni volta che File::Monitor rileva un cambiamento in uno dei suoi “bersagli”, incapsula le informazioni a riguardo in un oggetto di tipo Delta, da cui poi possiamo estrarle con dei semplici metodi.

Ecco un semplice esempio di come monitorare una directory in modo superficiale, senza controllare nel dettaglio i cambiamenti apportati ai files, naturalmente.

Questo esempio è molto esemplificato e se voleste scrivere uno script che controlli ogni aspetto dei vostri files, dovreste aggiungere istruzioni per ogni tipo di evento.

use File::Monitor;sub getDate() {

#Funzione che restituisce la data nel formato: gg/mm/aaaa--hh-mm-ss;

 	@time = localtime();

#è necessario aggiungere 1900 perchè localtime contiene il numero di anni passati dal 1900

 	$time[5] = $time[5]+1900;

#è necessario aggiungere 1 al mese perchè localtime conta i mesi a aprtire da 0

 	$time[4] = $time[4]+1;

 	return $time[3]."/".$time[4]."/".$time[5]."--".$time[2].":".$time[1].":".$time[0];

}

sub DIRchanged() {

#Ecco cosa facciamo quando la directory cambia

                open(FH,">>/tmp/dirMonitor.log") || die "ERRORE!!\t Impossibile aprire il log!!\n";

 	print "Data: ".&getDate()."\t";

 	print "ATTENZIONE!! La directory $DIR ha subito delle modifiche!!\n";

 	print FH "Data: ".&getDate()."\t";

 	print FH "ATTENZIONE!! La directory $DIR ha subito delle modifiche!!\n";

 	close(FH);

            }

#Oggetto fondamentale

my $monitor = File::Monitor->new();

#Prendiamo la directory da controllare, che è passata argomento

unless (-d $ARGV[0]) { die("ERRORE:\t La directory da monitorare specificata, non esiste!!\n\n")

$DIR = $ARGV[0];

$monitor->watch( {

        name        => $DIR,

        recurse     => 1,

        files       => 0

    } );

#Il primo scan on rileva cambiamenti ma raccoglie le informazioni sui files

$monitor->scan();

#Per ogni cambiamento, esegue i controlli che vogliamo

foreach my $change ($monitor->scan()) {

if ($change->is_event('changed')) {

&DIRchanged();

}

}

Per prima cosa ho incluso la libreria Monitor, poi ho definito due subroutine:
getDate(): formatta la data corrente in modo approfondito fino ai secondi
DIRchanged(): risponde all’evento changed modificando un file di log ed emettendo il segnale di allarme allo Standard Output

Creo l’oggetto monitor, e poi controllo che esista la directory da controllare passata come argomento da riga di comando, altrimenti termina con un messaggio di errore.

Il metodo watch(), assegna la directory da controllare e setta i flag che ne definiscono il comportamento:
recurse: Se settato a true e il flag base è una directory, scansiona ricorsivamente tutto l’albero directory sottostante alla directory specificata
files: Se settato a true e il flag base è una directory, scansiona tutti i file e directory sottostanti alla directory specificata, ma non ricorsivamente

In questo modo però solamente i nomi dei files e delle directory vengono controllati, per approfondire il controllo dobbiamo lavorare con i Delta Objects.

A questo punto, lanciamo il primo scan, che non rileva cambiamenti dei files in quanto stiamo facendo il primo controllo ed il monitor non ha ancora nessuna informazione a riguardo, ma si tratta della fase di acquisizione delle informazioni su di essi.

Tutti gli scan successivi restituiscono un oggetto di tipo Delta, su cui effettueremo i nostri test.

Annunci

Perl ed il modulo Term::ReadLine

Vi siete mai chiesti come implementare un prompt dei comandi per le vostre applicazioni? Perl vi fornisce un modulo perfetto allo scopo, che in poche righe di codice (12 nel caso del nostro esempio) vi permette di configurare un terminale con tanto di storico dei comandi inseriti.
Buttiamoci subito nell’ analisi del codice:

##############Config########################
 my $PROMPTSTRING = '%PSH% >>>';
 my $PROMPTNAME = 'term';
 ##############Main########################
 use Term::ReadLine;
 my $term = new Term::ReadLine $PROMPTNAME;
 my $out = $term->OUT || \*STDOUT;
 while (defined($_ = $term->readline($PROMPTSTRING))) {
  my $result = eval($_);
  warn $@ if $@;
  chop($result);
  print $result, "\n" unless $@;
  $term->addhistory($_) if /\s/;
}

Le prime due istruzioni, impostano il messaggio che visualizzeremo nel prompt ed il nome del terminale, mentre la terza include il modulo perl che fornisce tutte le subroutines necessarie (si trova facilmente il deb nei repository Debian), non c’è bisogno che vi ricordi che senza quel modulo non funziona una mazza vero?.

Dopo l’inclusione del modulo inizia la parte interessante:
Creiamo l’oggetto Term::ReadLine ed impostiamo come output, la variabile $out, che conterrà l’output del prompt stesso e quello emesso dallo standard output.

Il ciclo while tiene vivo il terminale, salvando il comando immesso dall’utente nella variabile $_; quindi ad ogni ciclo, viene valutata la stringa $_ come se fosse una istruzione perl e viene eseguita come sottoprogramma (tutto questo grazie alla funzione eval() ).
Infine visualizziamo l’output oppure gli eventuali messaggi di errore per poi aggiungere il nostro comando alla history.

Per maggiori informazioni vi rimando a:

Prima release seria per eMule Log Checker

elalogo.png

Ho terminato la prima release seria di emule Log Checker (o Analyzer non fa differenza XD), in cui ho implementato alcune opzioni da riga di comando , l’opzione di help ed un mitico File README!!! 😀

È disponibile un archivio zip contenente lo script e la documentazione, basta cliccare sul link download

P.S. In caso decidiate di scaricare il file, vi sarei davvero grato se lasciaste un commento all’articolo di presentazione presente al sito bubbledev.altervista.org, giusto per rendermi conto del numero di downloads e per ricevere feedback da voi (potete anche utilizzare la mail)

eMule Log Analyzer

elalogo.png

Ciao a tutti! non pubblico articoli ormai da qualche giorno… sono stato parecchio impegnato XD….tanto per farvi un esempio, oggi è inziata l’università (matricola di ingegneria informatica)!!!!

Ma basta parlare di me…. ecco la novità: ho cominciato a scrivere un tool che potrebbe servire a molti di voi: un analizzatore dei log di eMule, che ,pensate un po, ho chiamato eMule Log analyzer :P.

Il funzionamente è molto semplice: una volta editato il file per definire la versione del client in uso (il default è aMule, utilizzata dal sottoscritto) vi basta eseguire in un interprete Perl lo scriptino e vedrete magicamente comparire la lista degli ultimi download registrati dal Logfile di eMule!.
Per il momento ho inserito pochissime opzioni da riga di comando e soprattutto, le opzioni sono ancora pochissime, diciamo che in questi giorni non avrò il tempo di annoiarmi 😉

Attenzione: Ci tengo a ribadire che è una versione mooolto giovane, mancano molte feature e potrebbero esserci bug, in definitiva il codice potrebbe cambiare di parecchio…. mi impegnerò anche a commentare il codice tranquilli!!!

Se avete consigli o idee per migliorare lo script, postate! 😉

Potete scaricare lo script Qui

Aggiorno Debian e diventa muto…. AIUTO!!

Sono il felice possessore di un antiquato ma scattante (grazie Kernel Linux) PC, dotato di un vecchio Celeron Coppermine a 500 Mhz, due HD da 9GB, 512MB di RAM una scheda ATI FireGL 8000 che non sono mai riuscito a configurare con i driver FGLRX da quando ho lasciato OpenSuse (forse per colpa del monito LCD) e UDITE UDITE una Sound Blaster 16 su bus ISA….. ed è proprio lei l’oggetto dell’articolo…
Da un po di tempo…..da quando uso la mia amata, amatissima, ma che dico…. amaterrima DEBIAN, i driver alsa non no vogliono sapere di caricarsi all’avvio… niente di che… un ALSACONF mette tutto in ordine, ma stranamente il comando ALSACTL non salva la configurazione come dovuto… così ad ogni avvio mi ritrovo a dover lanciare il Pallosissimo alsaconf…. ma cè di più: Da quando sono passato a SID il comando update-modules è deprecato, di conseguenza, nonstante l’alsaconf, la mia SB16 è muta (niente punkrock per il povero fatmatt).
Per ovviare al problema ho deciso di caricare manualmente i moduli necessari al funzionamento dell’audio nella mia Debian. Per facilitare la procedura ho operato in questo modo:
Ho creato un file di testo ALSA_MODULES.txt contenente la lista dei moduli da caricare (uno per ogni riga), dopodichè ho scritto il seguente script Perl:

#!/usr/bin/perl   

open(F,"<".$ARGV[0]) || die "Unable to open module list at : $ARGV[0]"; 
my @l = ; 
foreach $module (@l) { 
	system("modprobe $module"); 
}

L’ho salvato come modprober.pl, così mi basta aprire il terminale e digitare da root (perchè modprobe richiede i provilegi di amministratore) :

perl modprobe.pl ALSA_MODULES.txt

In questo modo (che comunque non è il miglior modo per risolvere il problema, ma solo una scappatoia) si risparmia parecchio tempo 😉