+ fi
+\layout LyX-Code
+
+ dia=${date:6:2}
+\layout LyX-Code
+
+ validar_rango "$dia" "1" "31"
+\layout LyX-Code
+
+ if [ "$?" -ne 0 ]; then
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ hora=${date:8:2}
+\layout LyX-Code
+
+ validar_rango "$hora" "0" "23"
+\layout LyX-Code
+
+ if [ "$?" -ne 0 ]; then
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ min=${date:10:2}
+\layout LyX-Code
+
+ validar_rango "$min" "0" "59"
+\layout LyX-Code
+
+ if [ "$?" -ne 0 ]; then
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ validar_solo_numeros "$central"
+\layout LyX-Code
+
+ if [ "$?" -ne 0 ]; then
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+#--------------------MAIN SCRIPT----------------------
+\layout LyX-Code
+
+# Recupero las rutas a todos los directorios y archivos
+\layout LyX-Code
+
+# que necesito del antifraude
+\layout LyX-Code
+
+DATADIR=$ANTI_DATADIR
+\layout LyX-Code
+
+SOURCEDIR=$DATADIR/aprocesar/
+\layout LyX-Code
+
+ACEPTDIR=$DATADIR/enproceso/
+\layout LyX-Code
+
+REJECTDIR=$DATADIR/rechazadas/
+\layout LyX-Code
+
+BINDIR=$ANTI_BINDIR
+\layout LyX-Code
+
+# Del afimonio
+\layout LyX-Code
+
+LOGDIR=$AFIM_LOGDIR
+\layout LyX-Code
+
+LOGNAME=$AFIM_LOGFILE
+\layout LyX-Code
+
+LOGFILE=$LOGDIR/$LOGNAME
+\layout LyX-Code
+
+# Capturo señales para salir bien (liberando el lock)
+\layout LyX-Code
+
+trap "finalize" INT
+\layout LyX-Code
+
+trap "finalize" TERM
+\layout LyX-Code
+
+# Me lockeo
+\layout LyX-Code
+
+lock "afimonio" || die "No se puede correr, hay otra
+\backslash
+
+\layout LyX-Code
+
+instancia corriendo o no se puede crear el lock file!"
+\layout LyX-Code
+
+# Comienza el ciclo infinito que mueve los archivos
+\layout LyX-Code
+
+while true; do
+\layout LyX-Code
+
+ files=
+\layout LyX-Code
+
+ for file in `ls $SOURCEDIR` ; do
+\layout LyX-Code
+
+ files=1
+\layout LyX-Code
+
+ checkfilename $file
+\layout LyX-Code
+
+ if [ "$?" -eq 0 ]; then
+\layout LyX-Code
+
+ mv "$SOURCEDIR$file" "$ACEPTDIR"
+\layout LyX-Code
+
+ fecha=$(date +%d/%m/%Y-%H:%M)
+\layout LyX-Code
+
+ echo "$fecha $USER afimonio:
+\backslash
+"Se detecta "
+\backslash
+
+\layout LyX-Code
+
+ "archivo de llamadas $file
+\backslash
+"" >> $LOGFILE
+\layout LyX-Code
+
+ else
+\layout LyX-Code
+
+ mv "$SOURCEDIR$file" "$REJECTDIR"
+\layout LyX-Code
+
+ fecha=$(date +%d/%m/%Y-%H:%M)
+\layout LyX-Code
+
+ echo "$fecha $USER afimonio:
+\backslash
+"Se rechaza "
+\backslash
+
+\layout LyX-Code
+
+ "el archivo $file
+\backslash
+"" >> $LOGFILE
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ clean_log "$LOGFILE" "$AFIM_LOGSIZE"
+\layout LyX-Code
+
+ done #for
+\layout LyX-Code
+
+ # me fijo si el antifraude esta corriendo y si no lo esta
+\layout LyX-Code
+
+ # lo arranco
+\layout LyX-Code
+
+ if [ -n $files ] && ! is_lock "antifraude.pl"; then
+\layout LyX-Code
+
+ $BINDIR/antifraude.pl &
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ sleep 5
+\layout LyX-Code
+
+done #while
+\layout Section
+
+ANTIFRAUDE.PL
+\layout Subsection
+
+Tipo de comando
+\layout Standard
+
+Solicitado.
+\layout Subsection
+
+Archivos de Input
+\layout Standard
+
+Procesa los archivos de llamadas que encuentre en el momento de invocación
+ en el directorio
+\family typewriter
+$PATH_ANTIFRAUDE/$DATADIR/enproceso
+\family default
+.
+ El demonio
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+ será quien alimentará al
+\family typewriter
+\series bold
+antifraude
+\family default
+\series default
+ con dichos archivos, no obstante se lo puede alimentar con archivos de
+ llamadas en forma manual, situándolos en el directorio anteriormente descripto.
+\layout Standard
+
+Este comando, en el momento de invocacion genera y guarda internamente un
+ listado de los archivos de llamadas presences en el directorio
+\family typewriter
+/enproceso
+\family default
+, ordenándolos por fecha (establecida en el nombre del archivo) en forma
+ ascendente.
+ Dado que utiliza durante toda su ejecución esta lista interna, el
+\family typewriter
+\series bold
+Afimonio
+\family default
+\series default
+ puede alimentar al directorio
+\family typewriter
+/enproceso
+\family default
+ con nuevos archivos mientras el
+\family typewriter
+\series bold
+Antifraude
+\family default
+\series default
+ corre, pero los mismos no serán tenidos en cuenta (esto es, procesados),
+ hasta la próxima invocación del comando.
+\layout Subsection
+
+Archivos de Output
+\layout Description
+
+
+\family typewriter
+Antifraude.log
+\family default
+ En este archivo se guarda información del procesamiento de los registros,
+ advertencias provocados por registros no validos y alarmas emitidas por
+ registros que cumplen con un umbral.
+\layout Description
+
+
+\family typewriter
+Alarmas.txt
+\family default
+ En este archivo se guarda información de las alarmas provocadas por registros
+ en los archivos de llamadas, que hayan cumplido un umbral determinado del
+ archivo
+\family typewriter
+umbrales.param
+\family default
+.
+\layout Subsection
+
+Ejemplos de invocación
+\layout Subsubsection
+
+
+\family typewriter
+./antifraude.pl
+\layout Standard
+
+El programa procesa las llamadas
+\family typewriter
+enproceso
+\family default
+ como indica el enunciado en primer plano.
+\layout Subsubsection
+
+
+\family typewriter
+perl antifraude.pl
+\layout Standard
+
+Ídem anterior.
+\layout Subsubsection
+
+
+\family typewriter
+./antifraude.pl &
+\layout Standard
+
+Ídem anterior pero procesa en segundo plano.
+\layout Subsection
+
+Código Fuente
+\layout LyX-Code
+
+#!/usr/bin/perl
+\layout LyX-Code
+
+sub is_lock {
+\layout LyX-Code
+
+ if ( -e "$ENV{'HOME'}/.antifraude/lock/antifraude.pid" ) {
+\layout LyX-Code
+
+ # Lock file encontrado
+\layout LyX-Code
+
+ return 1;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ # No hay lock file!
+\layout LyX-Code
+
+ return 0;
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+sub unlock {
+\layout LyX-Code
+
+ unlink ("$ENV{'HOME'}/.antifraude/lock/antifraude.pid");
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+sub lock {
+\layout LyX-Code
+
+ if (!is_lock()) {
+\layout LyX-Code
+
+ local $lfile = "$ENV{'HOME'}/.antifraude/lock/antifraude.pid";
+\layout LyX-Code
+
+ open(LOCKFILE,">>$lfile");
+\layout LyX-Code
+
+ print LOCKFILE $$;
+\layout LyX-Code
+
+ close(LOCKFILE);
+\layout LyX-Code
+
+ return 1;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ return 0;
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+# Comparador de fecha para los archivos de llamada
+\layout LyX-Code
+
+sub byDate {
+\layout LyX-Code
+
+ ($year1,$mon1,$day1,$hr1,$min1) =
+\layout LyX-Code
+
+ $a =~ /([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/;
+\layout LyX-Code
+
+ ($year2,$mon2,$day2,$hr2,$min2) =
+\layout LyX-Code
+
+ $b =~ /([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/;
+\layout LyX-Code
+
+
+\layout LyX-Code
+
+ # Descarto por año
+\layout LyX-Code
+
+ if ($year1 > $year2) { return 1; }
+\layout LyX-Code
+
+ elsif ($year1 < $year2) { return -1; }
+\layout LyX-Code
+
+ # Descarto por mes
+\layout LyX-Code
+
+ if ($mon1 > $mon2) { return 1; }
+\layout LyX-Code
+
+ elsif ($mon1 < $mon2) { return -1; }
+\layout LyX-Code
+
+ # Calculo minutos de lo restante
+\layout LyX-Code
+
+ $totalmin1 = ($day1 * 24 * 60) + ($hr1 * 60) + $min1;
+\layout LyX-Code
+
+ $totalmin2 = ($day2 * 24 * 60) + ($hr2 * 60) + $min2;
+\layout LyX-Code
+
+ if ($totalmin1 > $totalmin2) { return 1; }
+\layout LyX-Code
+
+ elsif ($totalmin1 < $totalmin2) { return -1; }
+\layout LyX-Code
+
+ else { return 0; }
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+# Devuelve un listado de archivos de llamada y ordenado por fecha ASC
+\layout LyX-Code
+
+sub getCallFiles {
+\layout LyX-Code
+
+ # Obtengo listado de archivos de llamadas y lo ordeno por fecha
+\layout LyX-Code
+
+ opendir($DIR,"$CONFDATA{datadir}/enproceso")
+\layout LyX-Code
+
+ or die 'Could not open dir';
+\layout LyX-Code
+
+ # Valido solo fisicamente, lo logico ya valido afimonio..
+\layout LyX-Code
+
+ @files = grep {/[0-9]{12}
+\backslash
+.[0-9]{4}$/
+\layout LyX-Code
+
+ && -f "$CONFDATA{datadir}/enproceso/$_"} readdir($DIR);
+\layout LyX-Code
+
+ @sortedfiles = sort byDate @files;
+\layout LyX-Code
+
+ closedir($DIR);
+\layout LyX-Code
+
+ return @sortedfiles;
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+# Levanta una variable del archivo AFINSTAL.CONF
+\layout LyX-Code
+
+sub getConfVar {
+\layout LyX-Code
+
+ $CONFIGFILE = shift(@_);
+\layout LyX-Code
+
+ my $linenumber = shift(@_);
+\layout LyX-Code
+
+ open(CONFIGFILE)
+\layout LyX-Code
+
+ or die "No se pudo abrir el archivo $CONFIGFILE";
+\layout LyX-Code
+
+ do { $line = <CONFIGFILE> } until $.
+ == $linenumber;
+\layout LyX-Code
+
+ close(CONFIGFILE);
+\layout LyX-Code
+
+ chop($line);
+\layout LyX-Code
+
+ ($confvar = $line) =~ s/"(.*)"$/$1/;
+\layout LyX-Code
+
+ $confvar =~ s/^.*=//;
+\layout LyX-Code
+
+ return $confvar;
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+# Agrega un log entry al logfile del antifraude.pl
+\layout LyX-Code
+
+sub logEntry {
+\layout LyX-Code
+
+ my $logentry = shift(@_);
+\layout LyX-Code
+
+ my $consoleout = shift(@_);
+\layout LyX-Code
+
+ my $log = "$CONFDATA{logdir}/$CONFDATA{logfile}";
+\layout LyX-Code
+
+ # Fetch date and Format it
+\layout LyX-Code
+
+ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
+\layout LyX-Code
+
+ = localtime(time);
+\layout LyX-Code
+
+ $mon =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $mday =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $hour =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $min =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $year += 1900; ++$mon;
+\layout LyX-Code
+
+ $user = "$ENV{USER}";
+\layout LyX-Code
+
+ $commonstring = "$mday/$mon/$year-$hour:$min $user antifraude:";
+\layout LyX-Code
+
+ # Append to log
+\layout LyX-Code
+
+ open(LOGFILE,">>$log")
+\layout LyX-Code
+
+ or die "No se pudo abrir el archivo de log";
+\layout LyX-Code
+
+ seek(LOGFILE,0,2);
+\layout LyX-Code
+
+ print LOGFILE "$commonstring
+\backslash
+"$logentry
+\backslash
+"
+\backslash
+n";
+\layout LyX-Code
+
+ $filesize = tell(LOGFILE);
+\layout LyX-Code
+
+ close(LOGFILE);
+\layout LyX-Code
+
+ # Chequeo el logsize y su lo supero me quedo con 100 lineas
+\layout LyX-Code
+
+ if ($filesize > $CONFDATA{logsize})
+\layout LyX-Code
+
+ {
+\layout LyX-Code
+
+ open(LOGFILE,"+<$log");
+\layout LyX-Code
+
+ do ($line = <LOGFILE>) until $.
+ == 100;
+\layout LyX-Code
+
+ truncate(LOGFILE,tell(LOGFILE));
+\layout LyX-Code
+
+ close(LOGFILE);
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ if ($consoleout) { print("$logentry
+\backslash
+n"); }
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+sub badCall {
+\layout LyX-Code
+
+ my $callreg = shift(@_);
+\layout LyX-Code
+
+ my $numreg = shift(@_);
+\layout LyX-Code
+
+ logEntry("El siguiente registro de llamada tiene format ".
+\layout LyX-Code
+
+ "o invalido
+\backslash
+n$callreg",0);
+\layout LyX-Code
+
+ print("Warning: El registro de llamada $numreg tiene ".
+\layout LyX-Code
+
+ "formato invalido
+\backslash
+n");
+\layout LyX-Code
+
+
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+sub checkUmbrales {
+\layout LyX-Code
+
+ local(*callfields) = $_[0];
+\layout LyX-Code
+
+ my $callsfile = $_[1];
+\layout LyX-Code
+
+ my $matchedUmbral = 0;
+\layout LyX-Code
+
+ my $i = 0;
+\layout LyX-Code
+
+ while (($i <= $#UMBRALES) && ($matchedUmbral == 0)) {
+\layout LyX-Code
+
+ $umbral = $UMBRALES[$i];
+\layout LyX-Code
+
+ chomp($umbral);
+\layout LyX-Code
+
+ ($regid,$phoneline,$oridest,$type,$state)
+\layout LyX-Code
+
+ = split(';',$umbral);
+\layout LyX-Code
+
+ if (($state eq 'A') && ($callfields[0] == $phoneline)
+\layout LyX-Code
+
+ && ($callfields[4] eq $type)) {
+\layout LyX-Code
+
+ # Si es Saliente y coincide el Destino con el
+\layout LyX-Code
+
+ # Ori/Dest del umbral
+\layout LyX-Code
+
+ if (($type eq 'S')
+\layout LyX-Code
+
+ && ($callfields[5] eq $oridest)) {
+\layout LyX-Code
+
+ $matchedUmbral = $regid;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ if (($type eq 'E')
+\layout LyX-Code
+
+ && ($callfields[6] eq $oridest)) {
+\layout LyX-Code
+
+ $matchedUmbral = $regid;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ ++$i;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ # Si se matcheo un umbral, grabo una alarma y aviso por consola
+\layout LyX-Code
+
+ if ($matchedUmbral > 0) {
+\layout LyX-Code
+
+ # Obtengo algunos datos
+\layout LyX-Code
+
+ ($central = $callsfile) =~ s/^.*
+\backslash
+.//;
+\layout LyX-Code
+
+ $user = "$ENV{USER}";
+\layout LyX-Code
+
+ # Fetch date and Format it
+\layout LyX-Code
+
+ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
+\layout LyX-Code
+
+ = localtime(time);
+\layout LyX-Code
+
+ $year += 1900; ++$mon;
+\layout LyX-Code
+
+ $mon =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $mday =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $hour =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $min =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $sec =~ s/^(
+\backslash
+d)$/0$1/;
+\layout LyX-Code
+
+ $user = "$ENV{USER}";
+\layout LyX-Code
+
+ $date = "${year}${mon}${mday}";
+\layout LyX-Code
+
+ $time = "${hour}${min}${sec}";
+\layout LyX-Code
+
+ # Preparo el registro de alarma
+\layout LyX-Code
+
+ $alarmEntry = "$callfields[7];$central;$callfields[0];".
+\layout LyX-Code
+
+ "$callfields[1];$regid;$callfields[2];".
+\layout LyX-Code
+
+ "$callfields[3];$user;$date;$time";
+\layout LyX-Code
+
+ # Grabamos el registro en el archivo de alarmas
+\layout LyX-Code
+
+ $alarmlog = "$CONFDATA{datadir}/alarmas/alarmas.txt";
+\layout LyX-Code
+
+ open(ALARMFILE,">>$alarmlog")
+\layout LyX-Code
+
+ or die 'No se pudo abrir el archivo de alarmas';
+\layout LyX-Code
+
+ seek(ALARMFILE,0,2);
+\layout LyX-Code
+
+ print ALARMFILE "$alarmEntry
+\backslash
+n";
+\layout LyX-Code
+
+ close(ALARMFILE);
+\layout LyX-Code
+
+ # Logeo por consola y logfile que hubo una alarma
+\layout LyX-Code
+
+ logEntry("Alarma: Se ha matcheado el registro procesado"
+\layout LyX-Code
+
+ ." con el umbral nro $matchedUmbral",1);
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+# --------- MAIN CODE -------- #
+\layout LyX-Code
+
+# File locking..
+\layout LyX-Code
+
+if (is_lock()) { exit 1; }
+\layout LyX-Code
+
+lock();
+\layout LyX-Code
+
+# Defino some GLOBALS
+\layout LyX-Code
+
+$CONFDIR = "$ENV{'HOME'}/.antifraude";
+\layout LyX-Code
+
+$CONFDATA{logdir} = getConfVar("$CONFDIR/conf/antifraude.conf",2);
+\layout LyX-Code
+
+$CONFDATA{logfile} = getConfVar("$CONFDIR/conf/antifraude.conf",3);
+\layout LyX-Code
+
+$CONFDATA{logsize} = getConfVar("$CONFDIR/conf/antifraude.conf",4);
+\layout LyX-Code
+
+$CONFDATA{datadir} = getConfVar("$CONFDIR/conf/antifraude.conf",5);
+\layout LyX-Code
+
+# Cargo los UMBRALES en memoria
+\layout LyX-Code
+
+open(PARAMFILE,"$CONFDIR/umbrales.param") or die "No se pudo abrir el "
+\layout LyX-Code
+
+ ."archivo de umbrales";
+\layout LyX-Code
+
+@UMBRALES = <PARAMFILE>;
+\layout LyX-Code
+
+close(PARAMFILE);
+\layout LyX-Code
+
+# Proceso los archivos de llamadas
+\layout LyX-Code
+
+@archivos = getCallFiles();
+\layout LyX-Code
+
+FILE: foreach $filename (@archivos) {
+\layout LyX-Code
+
+ $regnum = 0;
+\layout LyX-Code
+
+ $CALLFILE = "$CONFDATA{datadir}/enproceso/$filename";
+\layout LyX-Code
+
+ logEntry("Inicio proceso de: $filename",1);
+\layout LyX-Code
+
+ open(CALLFILE)
+\layout LyX-Code
+
+ or ((warn "No se pudo abrir archivo $filename"),next FILE);
+\layout LyX-Code
+
+ REG: foreach $callreg (<CALLFILE>) {
+\layout LyX-Code
+
+ logEntry("Procesando Reg: $regnum | Archivo: $filename",1);
+\layout LyX-Code
+
+ chomp($callreg);
+\layout LyX-Code
+
+ $fieldcount = split(';',$callreg);
+\layout LyX-Code
+
+ @fields = @_;
+\layout LyX-Code
+
+ # Si no tengo 8 campos exactamente, invalido
+\layout LyX-Code
+
+ if ($fieldcount != 8)
+\layout LyX-Code
+
+ {
+\layout LyX-Code
+
+ badCall($callreg,$regnum);
+\layout LyX-Code
+
+ next REG;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ # Si la linea no es un numero, invalido
+\layout LyX-Code
+
+ $fields[0] =~ s/^
+\backslash
+s*(
+\backslash
+w*)
+\backslash
+s*$/$1/;
+\layout LyX-Code
+
+ if (!($fields[0] =~ /^
+\backslash
+d+$/))
+\layout LyX-Code
+
+ {
+\layout LyX-Code
+
+ badCall($callreg,$regnum);
+\layout LyX-Code
+
+ next REG;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ # Si tipo llamada ! E|S o no se informa Origen
+\layout LyX-Code
+
+ # o Destino, invalido
+\layout LyX-Code
+
+ if (($fields[4] ne 'E') && ($fields[4] ne 'S')) {
+\layout LyX-Code
+
+ badCall($callreg,$regnum); next REG;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ if (($fields[4] eq 'E') && ($fields[6] eq "")) {
+\layout LyX-Code
+
+ badCall($callreg,$regnum); next REG;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ if (($fields[4] eq 'S') && ($fields[5] eq "")) {
+\layout LyX-Code
+
+ badCall($callreg,$regnum); next REG;
+\layout LyX-Code
+
+ }
+\layout LyX-Code
+
+ # Ya pase todas las validaciones, ahora busco si
+\layout LyX-Code
+
+ # exite un umbral
+\layout LyX-Code
+
+ checkUmbrales(*fields,$filename);
+\layout LyX-Code
+
+ } continue { ++$regnum }
+\layout LyX-Code
+
+ close(CALLFILE);
+\layout LyX-Code
+
+ # La muevo al directorio de procesadas
+\layout LyX-Code
+
+ rename $CALLFILE,"$CONFDATA{datadir}/procesadas/$filename";
+\layout LyX-Code
+
+ logEntry("Fin proceso de: $filename",1);
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+# Unlocking
+\layout LyX-Code
+
+unlock();
+\layout Section
+
+AFICONF
+\layout Subsection
+
+Tipo de comando
+\layout Standard
+
+Solicitado.
+\layout Subsection
+
+Archivos de Input
+\layout Standard
+
+El comando utiliza los archivos
+\family typewriter
+umbrales.param
+\family default
+ y
+\family typewriter
+oridesti.txt
+\family default
+ situados en
+\family typewriter
+~$HOME/.antifraude/
+\layout Subsubsection
+
+Archivos de Output
+\layout Standard
+
+Solo escribe en
+\family typewriter
+umbrales.param
+\family default
+ de ser solicitado por el usuario, ya sea por la alta o baja de un umbral.
+\layout Subsection
+
+Ejemplos de invocación
+\layout Subsubsection
+
+
+\family typewriter
+./aficonf
+\layout Standard
+
+Realiza lo pedido en el enunciado.
+\layout Subsection
+
+Código Fuente
+\layout LyX-Code
+
+#!/bin/sh
+\layout LyX-Code
+
+#
+\layout LyX-Code
+
+# Configurador
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Cargo config
+\layout LyX-Code
+
+BASE_DIR="$HOME/.antifraude"
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Cargo config
+\layout LyX-Code
+
+.
+ "$BASE_DIR/conf/aficonf.conf"
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Cargo utilidades
+\layout LyX-Code
+
+.
+ "$BASE_DIR/util.sh"
+\layout LyX-Code
+
+LOGDIR=$AFIC_LOGDIR
+\layout LyX-Code
+
+LOGNAME=$AFIC_LOGFILE
+\layout LyX-Code
+
+LOGFILE=$LOGDIR/$LOGNAME
+\layout LyX-Code
+
+\layout LyX-Code
+
+#Valida que exista el pais
+\layout LyX-Code
+
+# Parámetros :
+\layout LyX-Code
+
+# $1 = Descripcion a buscar
+\layout LyX-Code
+
+# $2 = Variable donde guardar el código del Pais
+\layout LyX-Code
+
+# en caso de existir
+\layout LyX-Code
+
+existe_pais () {
+\layout LyX-Code
+
+ EXISTE=`cat "$BASE_DIR/oridesti.txt"
+\backslash
+
+\layout LyX-Code
+
+ | egrep "^[A-Z]*;$1" | cut -d ';' -f 1`;
+\layout LyX-Code
+
+ if [ "$EXISTE" != "" ] ; then
+\layout LyX-Code
+
+ #Exite!, debo gaurdar el código
+\layout LyX-Code
+
+ eval "$2=$EXISTE"
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+poner_estado_umbral () {
+\layout LyX-Code
+
+ ID=$1
+\layout LyX-Code
+
+ ESTADO=$2
+\layout LyX-Code
+
+ FECHA=`date +"%Y%m%d"`
+\layout LyX-Code
+
+ HORA=`date +"%H%M%S"`
+\layout LyX-Code
+
+
+\layout LyX-Code
+
+ if [ "$ESTADO" != "A" ] && [ "$ESTADO" != "I" ]
+\layout LyX-Code
+
+ then
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ SALIDA=`sed "s/^$ID
+\backslash
+(;[^;]*;[^;]*;[^;]*;
+\backslash
+)[^;]*
+\backslash
+(;"
+\backslash
+
+\layout LyX-Code
+
+"[^;]*;[^;]*;[^;]*
+\backslash
+)$/$ID
+\backslash
+1I;$USER;$FECHA;$HORA/"
+\backslash
+
+\layout LyX-Code
+
+ "$BASE_DIR/umbrales.param"`
+\layout LyX-Code
+
+ echo "$SALIDA" > "$BASE_DIR/umbrales.param"
+\layout LyX-Code
+
+ put_log "$LOGFILE" "aficonf"
+\backslash
+
+\layout LyX-Code
+
+ "Se ha cambiado el estado de umbral $ID a $ESTADO"
+\backslash
+
+\layout LyX-Code
+
+ "$AFIC_LOGSIZE"
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+menu () {
+\layout LyX-Code
+
+ echo "AFICONF"
+\layout LyX-Code
+
+ echo "======="
+\layout LyX-Code
+
+ echo
+\layout LyX-Code
+
+ echo " 1) Alta"
+\layout LyX-Code
+
+ echo " 2) Buscar"
+\layout LyX-Code
+
+ echo " 3) Salir"
+\layout LyX-Code
+
+ preguntar "Su opción" "123" $1
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+existe_umbral () {
+\layout LyX-Code
+
+ EXISTE=`cat "$BASE_DIR/umbrales.param" | egrep "$1"`;
+\layout LyX-Code
+
+ if [ "$EXISTE" == "" ] ; then
+\layout LyX-Code
+
+ #No existe
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ #Ya existe un umbral!
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+
+\layout LyX-Code
+
+buscar_id_umbral () {
+\layout LyX-Code
+
+ ID=`cat "$BASE_DIR/umbrales.id"`;
+\layout LyX-Code
+
+ eval "$1=$ID"
+\layout LyX-Code
+
+ let ID=$ID+1
+\layout LyX-Code
+
+ echo "$ID" > "$BASE_DIR/umbrales.id"
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+case_altas () {
+\layout LyX-Code
+
+ DONE=0
+\layout LyX-Code
+
+ while [ $DONE == 0 ] ; do
+\layout LyX-Code
+
+ leer "Número de línea" "" LINEA
+\layout LyX-Code
+
+ #TODO Valido
+\layout LyX-Code
+
+ if ! validar_solo_numeros "$LINEA" ; then
+\layout LyX-Code
+
+ echo "EL NUMERO TE LINEA SOLO DEBE"
+\backslash
+
+\layout LyX-Code
+
+ "TENER DIGITOS"
+\layout LyX-Code
+
+ else
+\layout LyX-Code
+
+ DONE=1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ if [ "$LINEA" == "" ] ; then
+\layout LyX-Code
+
+ DONE=0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ done
+\layout LyX-Code
+
+ preguntar "Tipo de llamada" "ES" TIPO
+\layout LyX-Code
+
+ DONE=0
+\layout LyX-Code
+
+ CODIGO=''
+\layout LyX-Code
+
+ while [ $DONE == 0 ] ; do
+\layout LyX-Code
+
+ leer "Pais (descripción)" "" PAIS
+\layout LyX-Code
+
+ if ! existe_pais "$PAIS" CODIGO ; then
+\layout LyX-Code
+
+ echo "No existe el país de descrición '$PAIS'"
+\layout LyX-Code
+
+ else
+\layout LyX-Code
+
+ DONE=1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ if [ "$PAIS" == "" ] ; then
+\layout LyX-Code
+
+ DONE=0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ done
+\layout LyX-Code
+
+ echo "El código de '$PAIS' es '$CODIGO'"
+\layout LyX-Code
+
+ PAIS=$CODIGO
+\layout LyX-Code
+
+ # Verifico que el umbral no exista
+\layout LyX-Code
+
+ FECHA=`date +"%Y%m%d"`
+\layout LyX-Code
+
+ HORA=`date +"%H%M%S"`
+\layout LyX-Code
+
+ UMBRAL="$LINEA;$PAIS;$TIPO;A;*;*;*"
+\layout LyX-Code
+
+ if existe_umbral "$UMBRAL" ; then
+\layout LyX-Code
+
+ echo "Ya existe un umbral con los datos ingresados."
+\layout LyX-Code
+
+ echo "Abortando..."
+\layout LyX-Code
+
+ put_log "$LOGFILE" "aficonf"
+\backslash
+
+\layout LyX-Code
+
+ "Se trató de insertar un umbral repetido ($UMBRAL)"
+\backslash
+
+\layout LyX-Code
+
+ "$AFIC_LOGSIZE"
+\layout LyX-Code
+
+ return
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+
+\layout LyX-Code
+
+ # Genero el umbral
+\layout LyX-Code
+
+ buscar_id_umbral ID
+\layout LyX-Code
+
+ UMBRAL="$ID;$LINEA;$PAIS;$TIPO;A;$USER;$FECHA;$HORA"
+\layout LyX-Code
+
+ # Lo guardo
+\layout LyX-Code
+
+ echo "$UMBRAL" >> "$BASE_DIR/umbrales.param"
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+ echo "El Umbral fue grabado con éxito"
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+ put_log "$LOGFILE"
+\backslash
+
+\layout LyX-Code
+
+ "aficonf" "Se inserto un nuevo umbral ($UMBRAL)"
+\backslash
+
+\layout LyX-Code
+
+ "$AFIC_LOGSIZE"
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+case_buscar () {
+\layout LyX-Code
+
+ DONE=0
+\layout LyX-Code
+
+ while [ $DONE == 0 ] ; do
+\layout LyX-Code
+
+ leer "Número de línea" "" LINEA
+\layout LyX-Code
+
+ #TODO Valido
+\layout LyX-Code
+
+ if ! validar_solo_numeros "$LINEA" ; then
+\layout LyX-Code
+
+ echo "EL NUMERO TE LINEA SOLO DEBE"
+\backslash
+
+\layout LyX-Code
+
+ "TENER DIGITOS"
+\layout LyX-Code
+
+ else
+\layout LyX-Code
+
+ DONE=1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ if [ "$LINEA" == "" ] ; then
+\layout LyX-Code
+
+ DONE=0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ done
+\layout LyX-Code
+
+ DATOS=`cat "$BASE_DIR/umbrales.param"
+\backslash
+
+\layout LyX-Code
+
+ | grep "[0-9]*;$LINEA;[A-Z]*;[E,S];A"`
+\layout LyX-Code
+
+ if [ "$DATOS" == "" ] ; then
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+ echo "No se han encontrado Umbrales activos"
+\backslash
+
+\layout LyX-Code
+
+ "para la linea $LINEA."
+\layout LyX-Code
+
+ echo "Abortando ..."
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+ put_log "$LOGFILE" "aficonf"
+\backslash
+
+\layout LyX-Code
+
+ "No se han encontrado umbrales para la línea $LINEA"
+\backslash
+
+\layout LyX-Code
+
+ "$AFIC_LOGSIZE"
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ printf "%3s %2s %1s %1s %10s%8s %6s
+\backslash
+n"
+\backslash
+
+\layout LyX-Code
+
+ "ID" "Ciudad" "Tipo" "Estado" "Usuario" "Fecha" "Hora"
+\layout LyX-Code
+
+ OPCIONES="-1"
+\layout LyX-Code
+
+ for i in $DATOS ; do
+\layout LyX-Code
+
+ ID=`echo "$i" | cut -d ';' -f 1`
+\layout LyX-Code
+
+ CIUDAD=`echo "$i" | cut -d ';' -f 3`
+\layout LyX-Code
+
+ TIPO=`echo "$i" | cut -d ';' -f 4`
+\layout LyX-Code
+
+ ESTADO=`echo "$i" | cut -d ';' -f 5`
+\layout LyX-Code
+
+ USUARIO=`echo "$i" | cut -d ';' -f 6`
+\layout LyX-Code
+
+ FECHA=`echo "$i" | cut -d ';' -f 7`
+\layout LyX-Code
+
+ HORA=`echo "$i" | cut -d ';' -f 8`
+\layout LyX-Code
+
+ printf
+\backslash
+
+\layout LyX-Code
+
+"%3s %2s %1s %1s %10s %8s %6s
+\backslash
+n"
+\backslash
+
+\layout LyX-Code
+
+ "$ID" "$CIUDAD" "$TIPO" "$ESTADO" "$USUARIO"
+\backslash
+
+\layout LyX-Code
+
+ "$FECHA" "$HORA"
+\layout LyX-Code
+
+ OPCIONES="$OPCIONES $ID"
+\layout LyX-Code
+
+ done
+\layout LyX-Code
+
+ preguntar "Cual desea borrar (-1 para salir)" "$OPCIONES" OPT
+\layout LyX-Code
+
+ if [ "$OPT" = "-1" ] ; then
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ echo "Borrando el registro $OPT ..."
+\layout LyX-Code
+
+ poner_estado_umbral "$OPT" "I"
+\layout LyX-Code
+
+ put_log "$LOGFILE" "aficonf"
+\backslash
+
+\layout LyX-Code
+
+ "No se ha eliminado elumbral de ID $OPT" "$AFIC_LOGSIZE"
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+ echo "El Umbral fue eliminado con éxito"
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# No permito correr 2 instancias de AFICONF
+\layout LyX-Code
+
+if is_lock "aficonf" ; then
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+ echo "Aficonf está corriendo actualmente."
+\layout LyX-Code
+
+ echo ""
+\layout LyX-Code
+
+ put_log "$LOGFILE" "aficonf"
+\backslash
+
+\layout LyX-Code
+
+ "Se ha intentado ejecutar aficonf cuando este estaba corriendo"
+
+\backslash
+
+\layout LyX-Code
+
+ "$AFIC_LOGSIZE"
+\layout LyX-Code
+
+ exit 1
+\layout LyX-Code
+
+fi
+\layout LyX-Code
+
+lock "aficonf"
+\layout LyX-Code
+
+# Loop Principal
+\layout LyX-Code
+
+OPT="0"
+\layout LyX-Code
+
+while [ "$OPT" != "3" ] ; do
+\layout LyX-Code
+
+ menu OPT
+\layout LyX-Code
+
+ case $OPT in
+\layout LyX-Code
+
+ "1") case_altas ;;
+\layout LyX-Code
+
+ "2") case_buscar ;;
+\layout LyX-Code
+
+ esac
+\layout LyX-Code
+
+done
+\layout LyX-Code
+
+unlock "aficonf"
+\layout Section
+
+UTIL.SH
+\layout Subsection
+
+Tipo de comando
+\layout Standard
+
+Auxiliar, escrito en bash.
+\layout Standard
+
+Sería equivalente a una biblioteca compartida, no es exactamente un comando
+ que se pueda ejecutar directamente sino que se incluye desde otros comandos.
+\layout Subsection
+
+Justificación de su uso
+\layout Standard
+
+Es un archivo con varias funciones generales, sirve para no duplicar código
+ común entre los varios scripts de bash.
+\layout Subsection
+
+Archivos de Input
+\layout Standard
+
+Al ser de propósito general, no tiene ningún archivo de input específico,
+ aunque hay funciones que utilizan archivos, no se describen aquí sino en
+ los comandos que usan este archivo.
+\layout Subsection
+
+Archivos de Output
+\layout Standard
+
+Ídem anterior.
+\layout Subsection
+
+Parámetros
+\layout Standard
+
+Al no ser un comando ejecutable, no aplica.
+\layout Subsection
+
+Opciones
+\layout Standard
+
+Ídem anterior.
+\layout Subsection
+
+Ejemplos de invocación
+\layout Standard
+
+Ídem anterior.
+\layout Subsection
+
+Código fuente
+\layout LyX-Code
+
+#/bin/bash
+\layout LyX-Code
+
+#
+\layout LyX-Code
+
+# Los scrips que incluyan deben definir BASE_DIR
+\layout LyX-Code
+
+# antes de incluirme!
+\layout LyX-Code
+
+\layout LyX-Code
+
+LOCK_DIR="$BASE_DIR/lock"
+\layout LyX-Code
+
+# Lee del teclado un valor
+\layout LyX-Code
+
+#
+\layout LyX-Code
+
+# parámetros :
+\layout LyX-Code
+
+# $1 = Leyeda a mostrar de pregunta
+\layout LyX-Code
+
+# $2 = Valor default por si el usuario no ingresa nada
+\layout LyX-Code
+
+# $3 = Variable donde guardar el valor ingresado (o el default)
+\layout LyX-Code
+
+#
+\layout LyX-Code
+
+leer () {
+\layout LyX-Code
+
+ MSG=$1
+\layout LyX-Code
+
+ DEFAULT=$2
+\layout LyX-Code
+
+ read -p "$MSG [$DEFAULT] : " ALGO
+\layout LyX-Code
+
+ # Si el usuario no ingresa nada
+\layout LyX-Code
+
+ # nos quedamos con el valor default
+\layout LyX-Code
+
+ if [ ! -z "$ALGO" ] ; then
+\layout LyX-Code
+
+ eval "$3=$ALGO"
+\layout LyX-Code
+
+ else
+\layout LyX-Code
+
+ eval "$3=$DEFAULT"
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Realiza una pregunta al usuario
+\layout LyX-Code
+
+#
+\layout LyX-Code
+
+# parámetros :
+\layout LyX-Code
+
+# $1 = Leyeda a mostrar de preguntar
+\layout LyX-Code
+
+# $2 = string con las opciones validas
+\layout LyX-Code
+
+# $3 = Variable donde guardar el valor ingresado
+\layout LyX-Code
+
+# $4 = Valor por defecto si se apreta ENTER
+\layout LyX-Code
+
+#
+\layout LyX-Code
+
+preguntar () {
+\layout LyX-Code
+
+ PREGUNTA="$1"
+\layout LyX-Code
+
+ OPCIONES="$2"
+\layout LyX-Code
+
+ DEFAULT="$4"
+\layout LyX-Code
+
+ while true; do
+\layout LyX-Code
+
+ read -p "$PREGUNTA [$OPCIONES]: " RTA
+\layout LyX-Code
+
+ # Si me pasaron un default y la respuesta es vacía
+\layout LyX-Code
+
+ if [ -n "$DEFAULT" -a -z "$RTA" ]; then
+\layout LyX-Code
+
+ # devuelvo default
+\layout LyX-Code
+
+ RTA="$DEFAULT"
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ # Escapeo el caracter '-' por '
+\backslash
+-'
+\layout LyX-Code
+
+ RTA=$(echo $RTA | sed "s/
+\backslash
+-/
+\backslash
+
+\backslash
+
+\backslash
+-/")
+\layout LyX-Code
+
+ IS_OK=`echo "$OPCIONES" | grep "$RTA"`
+\layout LyX-Code
+
+ if [ ! -z "$IS_OK" ] && [ ! -z "$RTA" ] ; then
+\layout LyX-Code
+
+ eval "$3=$RTA"
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ done
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+validar_solo_numeros () {
+\layout LyX-Code
+
+ TEST=`echo "$1" | sed "s/[0-9]*//g"`
+\layout LyX-Code
+
+ if [ "$TEST" == "" ] ; then
+\layout LyX-Code
+
+ #Ok, son solo numeros
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ # ups, hay algo que no es un numero
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Crea un archivo de lock para un script
+\layout LyX-Code
+
+# Devuelve: 0 si ok, 1 si ya esta lockeado, 2 si no pudo crear lock.
+\layout LyX-Code
+
+# Uso: lock programa
+\layout LyX-Code
+
+lock () {
+\layout LyX-Code
+
+ # si ya esta loqueado, no lo vuelvo a crear
+\layout LyX-Code
+
+ is_lock "$1" && return 1
+\layout LyX-Code
+
+ # Si no puedo escribir en el dir de lock, da error
+\layout LyX-Code
+
+ [ -w "$LOCK_DIR" ] || return 2
+\layout LyX-Code
+
+ echo $$ > "$LOCK_DIR/$1.pid"
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Desbloquea el script
+\layout LyX-Code
+
+# Uso: unlock programa
+\layout LyX-Code
+
+unlock () {
+\layout LyX-Code
+
+ rm -rf "$LOCK_DIR/$1.pid"
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+
+\layout LyX-Code
+
+# Consulta si un script esta lockeado
+\layout LyX-Code
+
+# Uso: is_lock programa
+\layout LyX-Code
+
+is_lock () {
+\layout LyX-Code
+
+ if [ -e "$LOCK_DIR/$1.pid" ] ; then
+\layout LyX-Code
+
+ # Lock file encontrado!
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ # No hay lock file!
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Obtiene el pid de un programa lockeado
+\layout LyX-Code
+
+# Uso: lock_pid programa
+\layout LyX-Code
+
+lock_pid()
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+ is_lock "$1" && cat "$LOCK_DIR/$1.pid"
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Verifica que un valor este entre otros 2
+\layout LyX-Code
+
+# $1 pertecezca a [$2,$3]
+\layout LyX-Code
+
+# $1 Numero a validar
+\layout LyX-Code
+
+# $2 Cota inferior
+\layout LyX-Code
+
+# $3 Cota superior
+\layout LyX-Code
+
+validar_rango(){
+\layout LyX-Code
+
+ if [ "$1" -ge "$2" ] && [ "$1" -le "$3" ]; then
+\layout LyX-Code
+
+ return 0
+\layout LyX-Code
+
+ else
+\layout LyX-Code
+
+ return 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Muestra mensaje y sale con código de error
+\layout LyX-Code
+
+# Uso: die mensaje [código de error = 1]
+\layout LyX-Code
+
+die()
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+ echo "$1" >&2
+\layout LyX-Code
+
+ exit ${2:-1}
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Imprime mensaje por salida de error
+\layout LyX-Code
+
+# Uso: perr mensajes
+\layout LyX-Code
+
+perr()
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+ echo $@ >&2
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Pone un MSG en el log
+\layout LyX-Code
+
+# Parametros :
+\layout LyX-Code
+
+# $1 = Archivo del log
+\layout LyX-Code
+
+# $2 = Comando
+\layout LyX-Code
+
+# $3 = Mensaje
+\layout LyX-Code
+
+# $4 = Tamaño maximo
+\layout LyX-Code
+
+put_log() {
+\layout LyX-Code
+
+ fecha=$(date +%d/%m/%Y-%H:%M)
+\layout LyX-Code
+
+ echo "$fecha $USER $2:
+\backslash
+"$3
+\backslash
+"" >> $1
+\layout LyX-Code
+
+ clean_log "$1" "$4"
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Trunca un archivo de log si pasa el tamaño máximo.
+\layout LyX-Code
+
+# Uso: clean_log log_filename max_log_size_bytes
+\layout LyX-Code
+
+clean_log()
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+ LOGFILE="$1"
+\layout LyX-Code
+
+ LOGSIZE="$2"
+\layout LyX-Code
+
+ # Archivo temporal
+\layout LyX-Code
+
+ tmp=`dirname "$LOGFILE"`"/`basename $0`.$$.temp"
+\layout LyX-Code
+
+ # Verifico que el logfile no se pase del tamaño maximo
+\layout LyX-Code
+
+ tam=`stat -c '%s' "$LOGFILE"`
+\layout LyX-Code
+
+ # Si se paso del maximo dejo las ultimas 100 lineas
+\layout LyX-Code
+
+ if [ "$tam" -ge "$LOGSIZE" ]; then
+\layout LyX-Code
+
+ tail -n 100 "$LOGFILE" > "$tmp"
+\layout LyX-Code
+
+ mv "$tmp" "$LOGFILE"
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+}
+\layout Section
+
+
+\begin_inset LatexCommand \label{sec:AFIMONIO_DAEMON.SH}
+
+\end_inset
+
+AFIMONIO_DAEMON.SH
+\layout Subsection
+
+Tipo de comando
+\layout Standard
+
+Auxiliar, escrito en
+\family typewriter
+bash
+\family default
+.
+\layout Subsection
+
+Justificación de su uso
+\layout Standard
+
+Sirve para correr
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+ en segundo plano, desasociado de la terminal.
+\layout Subsection
+
+Archivos de Input
+\layout Standard
+
+Ninguno, toma los datos necesarios por la entrada estándar, aunque es común
+ redireccionarle el archivo
+\family typewriter
+oridesti.txt
+\family default
+.
+ De la entrada estándar toma los códigos de origen y destino.
+ Cada código debe encontrarse en una línea y al comienzo de ésta.
+ Sólo toma los 2 primeros caracteres, e ignora el resto de la línea (para
+ compatibilidad con el archivo oridesti.txt).
+\layout Subsection
+
+Archivos de Output
+\layout Standard
+
+Crea una cantidad
+\family typewriter
+N
+\family default
+ (especificada por el usuario) de archivos con nombre y formato de
+\emph on
+Archivo de Llamadas
+\emph default
+ en el directorio actual.
+ Tanto el nombre como la cantidad de líneas y su contenido es generado aleatoria
+mente (respetando el formato mencionado y con valores racionales).
+\layout Subsection
+
+Parámetros
+\layout Standard
+
+La invocación es al estilo SysV, tomando como parámetro la acción a realizar,
+ que puede ser:
+\layout Description
+
+start Arranca el
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+.
+\layout Description
+
+stop Detiene el
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+.
+\layout Description
+
+status Indica si
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+ está corriendo o no.
+\layout Subsection
+
+Opciones
+\layout Standard
+
+Al comienzo del script, abajo de
+\family typewriter
+Configuración
+\family default
+, se pueden cambiar algunas variables:
+\layout Description
+
+WAIT Cantidad de segundos a esperar para que arranque o se detenga
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+ antes de asumir un error.
+\layout Description
+
+DAEMON Nombre del programa a ejecutar.
+ Este programa es lo suficientemente genérico como para correr cualquier
+ comando en modo
+\emph on
+daemon
+\emph default
+, por eso se provee una variable de configuración para cambiar el comando
+ a ejecutar.
+\layout Subsection
+
+Ejemplos de invocación
+\layout Subsubsection
+
+
+\family typewriter
+./afimonio_daemon.sh start
+\layout Standard
+
+Arranca el
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+.
+\layout Subsubsection
+
+
+\family typewriter
+./afimonio_daemon.sh stop
+\layout Standard
+
+Detiene el
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+.
+\layout Subsubsection
+
+
+\family typewriter
+./afimonio_daemon.sh status
+\layout Standard
+
+Si
+\family typewriter
+\series bold
+afimonio
+\family default
+\series default
+ está corriendo lo indica con un mensaje y muestra su PID.
+ Si no está corriendo da otro mensaje indicándolo.
+\layout Subsubsection
+
+
+\family typewriter
+./afimonio_daemon.sh
+\layout Standard
+
+Da un mensaje de ayuda.
+\layout Subsection
+
+Código Fuente
+\layout LyX-Code
+
+#!/bin/bash
+\layout LyX-Code
+
+\layout LyX-Code
+
+# Configuración
+\layout LyX-Code
+
+WAIT=10
+\layout LyX-Code
+
+DAEMON=afimonio
+\layout LyX-Code
+
+\layout LyX-Code
+
+# --------------- SCRIPT ---------------------
+\layout LyX-Code
+
+BASE_DIR="$HOME/.antifraude"
+\layout LyX-Code
+
+.
+ "$BASE_DIR/conf/$DAEMON.conf"
+\layout LyX-Code
+
+.
+ "$BASE_DIR/util.sh"
+\layout LyX-Code
+
+\layout LyX-Code
+
+ayuda () {
+\layout LyX-Code
+
+ perr "Parámetros válidos : start, stop, status"
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+case "$1" in
+\layout LyX-Code
+
+ "start")
+\layout LyX-Code
+
+ echo -n "Iniciando demonio '$DAEMON' en modo daemon "
+\layout LyX-Code
+
+ if is_lock "$DAEMON"; then
+\layout LyX-Code
+
+ echo " ERROR!"
+\layout LyX-Code
+
+ perr "$DAEMON ya está corriendo"
+\backslash
+
+\layout LyX-Code
+
+ "(PID=`lock_pid $DAEMON`)."
+\layout LyX-Code
+
+ exit 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ nohup "$AFIM_BINDIR/$DAEMON" > /dev/null &
+\layout LyX-Code
+
+ for i in `seq $WAIT`; do
+\layout LyX-Code
+
+ if is_lock "$DAEMON"; then
+\layout LyX-Code
+
+ echo " OK! (PID=`lock_pid $DAEMON`)"
+\layout LyX-Code
+
+ exit 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ echo -n '.'
+\layout LyX-Code
+
+ sleep 1;
+\layout LyX-Code
+
+ done
+\layout LyX-Code
+
+ # Tardó más de 5 segundos en arrancar, algo anda mal...
+\layout LyX-Code
+
+ echo "ERROR!"
+\layout LyX-Code
+
+ perr "$DAEMON tardó más de $WAIT segundos en arrancar,"
+
+\backslash
+
+\layout LyX-Code
+
+ "probablemente haya algún problema."
+\layout LyX-Code
+
+ exit 1
+\layout LyX-Code
+
+ ;;
+\layout LyX-Code
+
+ "stop")
+\layout LyX-Code
+
+ echo -n "Parando el demonio '$DAEMON' "
+\layout LyX-Code
+
+ if ! is_lock "$DAEMON"; then
+\layout LyX-Code
+
+ echo " ERROR!"
+\layout LyX-Code
+
+ perr "$DAEMON no esta corriendo."
+\layout LyX-Code
+
+ exit 1
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ kill `lock_pid $DAEMON`
+\layout LyX-Code
+
+ for i in `seq $WAIT`; do
+\layout LyX-Code
+
+ if ! is_lock "$DAEMON"; then
+\layout LyX-Code
+
+ echo " OK!"
+\layout LyX-Code
+
+ exit 0
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ echo -n '.'
+\layout LyX-Code
+
+ sleep 1;
+\layout LyX-Code
+
+ done
+\layout LyX-Code
+
+ # Tardó más de 5 segundos en parar, algo anda mal...
+\layout LyX-Code
+
+ echo "ERROR!"
+\layout LyX-Code
+
+ perr "$DAEMON tardó más de $WAIT segundos en parar,"
+\backslash
+
+\layout LyX-Code
+
+ "probablemente haya algún problema."
+\layout LyX-Code
+
+ exit 1
+\layout LyX-Code
+
+ ;;
+\layout LyX-Code
+
+ "status")
+\layout LyX-Code
+
+ if is_lock "$DAEMON"; then
+\layout LyX-Code
+
+ echo "$DAEMON está corriendo actualmente"
+\backslash
+
+\layout LyX-Code
+
+ "(PID=`lock_pid $DAEMON`)."
+\layout LyX-Code
+
+ else
+\layout LyX-Code
+
+ echo "$DAEMON no está corriendo."
+\layout LyX-Code
+
+ fi
+\layout LyX-Code
+
+ ;;
+\layout LyX-Code
+
+ *) ayuda ;;
+\layout LyX-Code
+
+esac
+\layout Section
+
+CALLGEN
+\layout Subsection
+
+Tipo de comando
+\layout Standard
+
+Auxiliar, escrito en
+\family typewriter
+perl