X-Git-Url: https://git.llucax.com/z.facultad/75.08/llamadas.git/blobdiff_plain/e5e30b07fdffd68dc708d96af58f9ffca0afbe11..ae3e2a0e180b3db5a1a3ea7c6ed9381eff395d46:/doc/Informe7508.lyx?ds=inline diff --git a/doc/Informe7508.lyx b/doc/Informe7508.lyx index 0220308..08b52c0 100644 --- a/doc/Informe7508.lyx +++ b/doc/Informe7508.lyx @@ -52,7 +52,7 @@ Leandro Lucarella (77891) Ricardo Markiewicz (78226) \layout Date -Primera Entrega, 28 de Junio del 2004 +26 de Octubre del 2004 \layout Standard @@ -63,9 +63,6 @@ Primera Entrega, 28 de Junio del 2004 \layout Chapter -Desarollo e Implementación -\layout Section - Hipotesis y Aclaraciones \layout Itemize @@ -73,7 +70,7 @@ El programa en su totalidad va a ser ejecutado por un configuración diferente es posible pero queda en manos del administrador. \layout Itemize -En los archivos de llamada se valida que sean numeros, y para validar la +En los archivos de llamada se valida que sean números, y para validar la fecha no se tiene en cuenta casos particulares como el 29, 30, 31 de febrero. \layout Itemize @@ -86,9 +83,24 @@ Aficonf utiliza n la acción. \layout Itemize -El archivo de umbrales no puede ser modificado por el usuario manualmente, - solo a travez de AFICONF -\layout Section +El instalador utiliza el archivo +\family typewriter +afinstal.conf +\family default +, situado en el directorio +\family typewriter +$PATH_INSTALADOR/conf +\family default +, para determinar que componentes se encuentran instalados. + Internamente, en base a la información de paths proporcionada por este + archivo, busca su los binarios realmente se encuentran en el OS, y en caso + contrario permite volver a reinstalarlo/s. +\layout Chapter + + +\begin_inset LatexCommand \label{sec:Problemas-relevantes} + +\end_inset Problemas relevantes \layout Itemize @@ -96,46 +108,130 @@ Problemas relevantes Dado que los distintos componentes del sistema se pueden instalar en diferentes paths dentro del OS, creamos el directorio \family typewriter -$HOME/.antifraude +~$HOME/.antifraude \family default donde se almacenará información acerca de los paths en donde reside cada - uno de ellos y otros archivos de intercambio y de rutinas comunes. + uno de ellos y otros archivos de intercambio. \layout Itemize Así mismo, como los programas pueden ser instalados en directorios distintos, - toda la información compartida (oridesti.txt y umbrales.param) es guardada - en + toda la información compartida es guardada en \family typewriter -$HOME/.antifraude +~$HOME/.antifraude \family default , para ser mas consistentes con la manera de trabajar en Unix. Lo ideal hubiera sido utilizar \family typewriter /etc/antifraude \family default -, pero como no podríamos suponer root access preferimos directamente trabajar - en el home del usuario. -\layout Section +, pero como no podríamos suponer acceso de +\emph on +root +\emph default + preferimos directamente trabajar en el directorio del usuario. +\layout Chapter Instalación \layout Standard -Copiar del README cuando este terminado y extenderlo un poco si se considera - necesario. -\layout Section - -Comandos Desarrollados -\layout Subsection +Una vez descargados los fuentes (asumiremos que ha descargado el +\family typewriter +tar.gz +\family default +) solo debe descomprimir el archivo ejecutando el siguiente comando: +\layout LyX-Code -AFIMONIO +tar xvzf grupo12.tar.gz \layout Standard +Esto creará la siguiente estructura de directorios: +\layout LyX-Code + +./ +\layout LyX-Code + + +- grupo12 +\layout LyX-Code + + | +\layout LyX-Code + + +-- README +\layout LyX-Code + + +-- COPYING +\layout LyX-Code + + +-- afinstal +\layout LyX-Code + + +-- conf +\layout LyX-Code + + +---- umbrales.param +\layout LyX-Code + + +---- umbrales.id +\layout LyX-Code + + +---- oridesti.txt +\layout LyX-Code + + +-- inst +\layout LyX-Code + + +---- afimonio +\layout LyX-Code + + +---- antifraude.pl +\layout LyX-Code + + +---- aficonf +\layout LyX-Code + + +---- afimonio_daemon.sh +\layout LyX-Code + + +---- util.sh +\layout LyX-Code + + +---- callgen +\layout LyX-Code + + +---- testcalls.tar.gz +\layout Standard +Para proceder a la instalación del sistema \series bold -Tipo de comando: +antifraude \series default - Solicitado -\layout Subsubsection + debe correr el script +\series bold +afinstal +\series default +: +\layout LyX-Code + +./afinstal +\layout Standard + +y seguir los pasos que se le indiquen a continuación. + De no ejecutar apropiadamente la instalación, no se garantiza el correcto + funcionamiento de los componentes. + +\layout Chapter + +Comandos Desarrollados +\layout Section + +AFIMONIO +\layout Subsection + +Tipo de comando +\layout Standard + +Solicitado. +\layout Subsection Archivos de Input \layout Standard @@ -160,241 +256,4062 @@ so \family default \series medium según corresponda. -\layout Subsubsection +\layout Subsection Archivos de Output \layout Standard -El afimonio genera una salida al archivo afimonio.log la cual contiene informació -n sobre la ejecución del programa. +El afimonio genera una salida al archivo +\family typewriter +afimonio.log +\family default + la cual contiene información sobre la ejecución del programa. \layout Standard Si un archivo es válido, se añade una línea con el siguiente formato: -\layout Standard +\layout LyX-Code -"$fecha $USER afimonio: "Se detecta archivo de llamadas $file" +$fecha $USER afimonio: "Se detecta archivo de llamadas $file" \layout Standard Si el archivo tuviera un nombre inválido, la línea seria la siguiente: -\layout Standard +\layout LyX-Code -"$fecha $USER afimonio:"Se rechaza el archivo $file". - +$fecha $USER afimonio: "Se rechaza el archivo $file" \layout Standard -donde -\layout Standard +donde: +\layout Description -$fecha: fecha actual con formato Día-Mes-Año-Hora:Minuto. - -\layout Standard -$USER: nombre de usuario que ejecuto el script. - +\family typewriter +$fecha +\family default + fecha actual con formato Día-Mes-Año-Hora:Minuto. +\layout Description + + +\family typewriter +$USER +\family default + nombre de usuario que ejecuto el script. +\layout Description + + +\family typewriter +$file +\family default + nombre del archivo que se procesó. +\layout Subsection + +Ejemplos de invocación +\layout Subsubsection + + +\family typewriter +./afimonio \layout Standard -$file: nombre del archivo que se procesó. - +Corre el programa en primer plano. \layout Subsubsection -Ejemplos de invocación + +\family typewriter +nohup ./afimonio & +\layout Standard + +Corre el programa en segundo plano, evitando que se cierre al morir el padre + desasociándolo de la terminal. + La salida del programa queda en el archivo +\family typewriter +nohup.out +\family default + a menos que se redirija a otro archivo. +\layout Subsection + +Código Fuente \layout LyX-Code -:afimonio/bin$> ./afimonio +#!/bin/bash \layout LyX-Code -:afimonio/bin$> nohup ./afimonio & \layout LyX-Code -:afimonio/bin$> ./afimonio_daemon.sh +BASE_DIR=$HOME/.antifraude \layout LyX-Code - afimonio_daemon.sh (start|stop|status) -\layout Subsubsection +\layout LyX-Code -Código Fuente -\layout Standard +# uso las funciones de util.sh +\layout LyX-Code -Copy Paste cuando este cerrado. -\layout Subsection +. + "$HOME/.antifraude/util.sh" +\layout LyX-Code -ANTIFRAUDE -\layout Standard +. + "$HOME/.antifraude/conf/afimonio.conf" +\layout LyX-Code +. + "$HOME/.antifraude/conf/antifraude.conf" +\layout LyX-Code -\series bold -Tipo de comando: -\series default - Solicitado -\layout Subsubsection +\layout LyX-Code -Archivos de Input -\layout Standard +# Es llamada por los trap para deslockear el afimonio +\layout LyX-Code -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 -\series bold -Afimonio -\series default - será quien alimentará al -\series bold -Antifraude -\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 Subsubsection +finalize() { +\layout LyX-Code -Archivos de Output -\layout Itemize + unlock "afimonio" +\layout LyX-Code + exit 0 +\layout LyX-Code -\series bold -Antifraude.log: -\series default - Se loguea en este archivo el procesamiento de los registros, warnings provocado -s por registros no validos y alarmas emitidas por registros que matchean - contra un umbral. -\layout Itemize +} +\layout LyX-Code +# filtra el nombre del archivo pasado por parametro sacandole +\layout LyX-Code -\series bold -Alarmas.txt: -\series default - Se loguean en este archivo las alarmas provocadas por registros en los - archivos de llamadas, que hayan matcheado un umbral determinado del archivo - umbrales.param. -\layout Subsubsection +# todos los caracteres que no sean numeros +\layout LyX-Code -Ejemplos de invocación +checkfilename(){ \layout LyX-Code -:antifraude/bin$> perl antifraude.pl + date=`echo $1 | cut -d "." -f 1` \layout LyX-Code -:antifraude/bin$> perl antifraude.pl & -\layout Subsubsection + central=`echo $1 | cut -d "." -f 2` +\layout LyX-Code -Código Fuente -\layout Standard + validar_solo_numeros "$date" +\layout LyX-Code -Copy Paste cuando este cerrado. -\layout Subsection + if [ "$?" -ne 0 ]; then +\layout LyX-Code -AFICONF -\layout Standard + return 1 +\layout LyX-Code + fi +\layout LyX-Code -\series bold -Tipo de comando: -\series default - Solicitado -\layout Subsubsection + mes=${date:4:2} +\layout LyX-Code -Archivos de Input -\layout Standard + validar_rango "$mes" "1" "12" +\layout LyX-Code -El comando utiliza los archivos umbrales.param y oridesti.txt situados en - -\family typewriter -~$HOME/.antifraude/ -\layout Subsubsection + if [ "$?" -ne 0 ]; then +\layout LyX-Code -Archivos de Output -\layout Standard + return 1 +\layout LyX-Code -Solo escribe en umbrales.param de ser solicitado por el usuario, ya sea por - la alta o baja de un umbral. -\layout Subsubsection + fi +\layout LyX-Code -Ejemplos de invocación + dia=${date:6:2} \layout LyX-Code -:aficonf/bin$> ./aficonf -\layout Subsubsection + validar_rango "$dia" "1" "31" +\layout LyX-Code -Código Fuente -\layout Standard + if [ "$?" -ne 0 ]; then +\layout LyX-Code -Copy Paste cuando este cerrado. -\layout Subsection + return 1 +\layout LyX-Code -CALLGEN -\layout Standard + fi +\layout LyX-Code + hora=${date:8:2} +\layout LyX-Code -\series bold -Tipo de comando: -\series default - Auxiliar, escrito en PERL -\layout Subsubsection + validar_rango "$hora" "0" "23" +\layout LyX-Code -Justificación de su uso -\layout Standard + if [ "$?" -ne 0 ]; then +\layout LyX-Code -Sirve para realizar lotes de prueba con gran cantidad de entradas y variaciones - de forma rápida y cómoda. -\layout Subsubsection + return 1 +\layout LyX-Code -Archivos de Input -\layout Standard + fi +\layout LyX-Code -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 Subsubsection + min=${date:10:2} +\layout LyX-Code -Archivos de Output -\layout Standard + validar_rango "$min" "0" "59" +\layout LyX-Code -Crea una cantidad N (especificada por el usuario) de archivos con nombre - y formato de Archivo de Llamadas 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 Subsubsection + if [ "$?" -ne 0 ]; then +\layout LyX-Code -Parámetros + 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 = } 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 = ) 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 = ; +\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 () { +\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 + +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 +\family default +. +\layout Subsection + +Justificación de su uso +\layout Standard + +Sirve para realizar lotes de prueba con gran cantidad de entradas y variaciones + de forma rápida y cómoda. +\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 + +El comando toma 3 parámetros +\series bold +opcionales +\series default +: +\layout LyX-Code + +./callgen [cant_archivos [min_lineas [max_lineas]]] +\layout Standard + + +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\layout Standard + + +\series bold +Parámetro +\end_inset + + +\begin_inset Text + +\layout Standard + + +\series bold +Descripción +\end_inset + + +\begin_inset Text + +\layout Standard + + +\series bold +Default +\end_inset + + + + +\begin_inset Text + +\layout Standard + +cant_archivos +\end_inset + + +\begin_inset Text + +\layout Standard + +Cantidad de archivos a generar +\end_inset + + +\begin_inset Text + +\layout Standard + +10 +\end_inset + + + + +\begin_inset Text + +\layout Standard + +min_lineas +\end_inset + + +\begin_inset Text + +\layout Standard + +Mínima cantidad de lineas en un archivo +\end_inset + + +\begin_inset Text + +\layout Standard + +1000 +\end_inset + + + + +\begin_inset Text + +\layout Standard + +max_linaes +\end_inset + + +\begin_inset Text + +\layout Standard + +Máxima cantidad de lineas en un archivo +\end_inset + + +\begin_inset Text + +\layout Standard + +5000 +\end_inset + + + + +\end_inset + + +\layout Subsection + +Opciones +\layout Standard + +Pueden cambiarse los valores por defecto editando el código fuente del comando, + en la sección de configuración que se encuentra al comienzo del mismo. + También puede cambiarse el mínimo y máximo año (por defecto 1999 y 2004) + y el mínimo y máximo código de central (por defecto 0000 y 9999). +\layout Subsection + +Ejemplos de invocación +\layout Subsubsection + + +\family typewriter +./callgen +\layout Paragraph + + +\series medium +Se escriben por entrada estándar los códigos de origen/destino, se presiona + +\family typewriter +\series default +Ctrl-D +\family default +\series medium + para cerrar el descriptor de archivo de la entrada estándar y se generan + 10 archivos con entre 1000 y 5000 líneas cada uno. +\layout Subsubsection + + +\family typewriter +./callgen 2 < oridesti.txt +\layout Paragraph + + +\series medium +Genera 2 archivos con entre 1000 y 5000 líneas cada uno tomando los códigos + de origen/destino del archivo +\family typewriter +origesti.txt +\family default +. +\layout Subsubsection + + +\family typewriter +./callgen 5 10 < oridesti.txt +\layout Paragraph + + +\series medium +Genera 5 archivos con entre 10 y 5000 líneas cada uno tomando los códigos + de origen/destino del archivo +\family typewriter +origesti.txt +\family default +. +\layout Subsubsection + + +\family typewriter +./callgen 50 10 50 < oridesti.txt +\layout Paragraph + + +\series medium +Genera 50 archivos con entre 10 y 50 líneas cada uno tomando los códigos + de origen/destino del archivo +\family typewriter +origesti.txt +\family default +. +\layout Subsection + +Código Fuente +\layout LyX-Code + +#!/usr/bin/perl -w +\layout LyX-Code + +# +\layout LyX-Code + +# Generador aleatorio de archivos de llamadas +\layout LyX-Code + +# +\layout LyX-Code + +# Leandro Lucarella - dom oct 17 18:37:05 ART 2004 +\layout LyX-Code + +# +\layout LyX-Code + +# Bajo licencia GPL. +\layout LyX-Code + +# +\layout LyX-Code + +# Uso: +\layout LyX-Code + +# ./callgen [cant_archivos [min_lineas [max_lineas]]] +\layout LyX-Code + +# +\layout LyX-Code + +# cant_archivos Cantidad de archivos a generar. +\layout LyX-Code + +# min_lines Mínima cantidad de líneas que puede tener un archivo. +\layout LyX-Code + +# max_lines Máxima cantidad de líneas que puede tener un archivo. +\layout LyX-Code + +# +\layout LyX-Code + +# Por la entrada estándar debe recibir los códigos de países para +\layout LyX-Code + +# origen y/o destino. + Toma los dos primeros caracteres por línea como +\layout LyX-Code + +# un código, ignorando el resto, de manera que se puede hacer: +\layout LyX-Code + +# cat oridesti.txt | ./gencall +\layout LyX-Code + +# Configuración +\layout LyX-Code + +$CANT_ARCHS = 10; +\layout LyX-Code + +$MIN_LINEAS = 1000; +\layout LyX-Code + +$MAX_LINEAS = 5000; +\layout LyX-Code + +$MIN_ANIO = "1999"; +\layout LyX-Code + +$MAX_ANIO = "2004"; +\layout LyX-Code + +$MIN_COD = "0000"; +\layout LyX-Code + +$MAX_COD = "9999"; +\layout LyX-Code + +\layout LyX-Code + +#{{{ Variables globales +\layout LyX-Code + +our @codes; # Códigos de origen/destino +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +#{{{ Funciones +\layout LyX-Code + +\layout LyX-Code + +#{{{ load_codes() - Obtiene códigos de origen/destino de la entrada +\layout LyX-Code + +# estándar +\layout LyX-Code + +# Uso: load_codes() +\layout LyX-Code + +sub load_codes() +\layout LyX-Code + +{ +\layout LyX-Code + + push(@codes, substr($_, 0, 2)) while (); +\layout LyX-Code + +} +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +#{{{ get_rnd_code() - Obtiene un códigos de origen/destino al azar +\layout LyX-Code + +# Uso: get_rnd_code() +\layout LyX-Code + +sub get_rnd_code() +\layout LyX-Code + +{ +\layout LyX-Code + + my $cant = @codes; +\layout LyX-Code + + return $codes[rnd($cant-1)]; +\layout LyX-Code + +} +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +#{{{ rnd() - Genera números aleatorios +\layout LyX-Code + +# Uso: rnd(MAX) - genera número de 0 a MAX (inclusive) +\layout LyX-Code + +# rnd(MIN, MAX) - genera número de MIN a MAX (inclusive) +\layout LyX-Code + +# +\layout LyX-Code + +# Nota: respeta el tamaño del campo más chico, es decir, si se usa +\layout LyX-Code + +# rnd 01 250, el número siempre tendrá al menos 2 dígitos +\layout LyX-Code + +# rellenados con ceros, como 04, 28, 123, 08, etc +\layout LyX-Code + +sub rnd($;$) +\layout LyX-Code + +{ +\layout LyX-Code + + my ($ini, $fin) = @_; +\layout LyX-Code + + if (!$fin) +\layout LyX-Code + + { +\layout LyX-Code + + $fin = $ini; +\layout LyX-Code + + $ini = 0; +\layout LyX-Code + + } +\layout LyX-Code + + return sprintf('%0'.length($ini).'d', $ini + rand() +\layout LyX-Code + + * ($fin - $ini + 1)); +\layout LyX-Code + +} +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +#{{{ Tipos de campos +\layout LyX-Code + +sub aaaa() { return rnd($MIN_ANIO, $MAX_ANIO); } # año +\layout LyX-Code + +sub mm() { return rnd("01", 12); } # mes +\layout LyX-Code + +sub dd() { return rnd("01", 28); } # día +\layout LyX-Code + +sub hh() { return rnd("00", 23); } # hora +\layout LyX-Code + +sub MM() { return rnd("00", 59); } # minutos +\layout LyX-Code + +# código de central telefónica +\layout LyX-Code + +sub DDDD() { return rnd($MIN_COD, $MAX_COD); } +\layout LyX-Code + +# caracter aleatorio +\layout LyX-Code + +sub char() { return chr(rnd(65, 90)); } +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +#{{{ line() - Genera una línea del archivo +\layout LyX-Code + +sub line() +\layout LyX-Code + +{ +\layout LyX-Code + + my $f_linea = rnd(100000, 99999999); +\layout LyX-Code + + my $f_minutos = rnd(1, 150); +\layout LyX-Code + + my $f_fecha = aaaa().mm().dd(); +\layout LyX-Code + + my $f_hora = dd().hh().MM(); +\layout LyX-Code + + my ($f_tipo, $f_orig, $f_dest) = ('', '', ''); +\layout LyX-Code + + if (rnd(1) == 1) +\layout LyX-Code + + { +\layout LyX-Code + + $f_tipo = 'E'; +\layout LyX-Code + + $f_orig = get_rnd_code(); +\layout LyX-Code + + } +\layout LyX-Code + + else +\layout LyX-Code + + { +\layout LyX-Code + + $f_tipo = 'S'; +\layout LyX-Code + + $f_dest = get_rnd_code(); +\layout LyX-Code + + } +\layout LyX-Code + + my $f_prest = char().char().char().char().char(). +\layout LyX-Code + + char().char().char().char(); +\layout LyX-Code + + return "$f_linea;$f_minutos;$f_fecha;$f_hora;". +\layout LyX-Code + + "$f_tipo;$f_dest;$f_orig;$f_prest"; +\layout LyX-Code + +} +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +#{{{ gen() - Genera un archivo con entre MIN y MAX llamadas +\layout LyX-Code + +# Uso: gen(MIN, MAX) +\layout LyX-Code + +sub gen($$) +\layout LyX-Code + +{ +\layout LyX-Code + + my ($ini, $fin) = @_; +\layout LyX-Code + + my $file = aaaa().mm().dd().hh().MM().'.'.DDDD(); +\layout LyX-Code + + # Mientras exista uno, buscamos un nuevo nombre. +\layout LyX-Code + + $file = aaaa().mm().dd().hh().MM().'.'.DDDD() +\layout LyX-Code + + while (-e $file); +\layout LyX-Code + + open(FH, ">$file") +\layout LyX-Code + + or die("No puedo abrir el archivo $file! +\backslash +n"); +\layout LyX-Code + + for (my $i = rnd($ini, $fin); $i > 0; --$i) +\layout LyX-Code + + { +\layout LyX-Code + + print FH line()." +\backslash +n"; +\layout LyX-Code + + } +\layout LyX-Code + +} +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +#{{{ Programa +\layout LyX-Code + +srand; +\layout LyX-Code + +my $cant = $ARGV[0] ? $ARGV[0] : $CANT_ARCHS; +\layout LyX-Code + +load_codes(); +\layout LyX-Code + +for (my $i = 0; $i < $cant; ++$i) +\layout LyX-Code + +{ +\layout LyX-Code + + gen($ARGV[1] ? $ARGV[1] : $MIN_LINEAS, +\layout LyX-Code + + $ARGV[2] ? $ARGV[2] : $MAX_LINEAS); +\layout LyX-Code + +} +\layout LyX-Code + +#}}} +\layout LyX-Code + +\layout LyX-Code + +# vim: set fdm=marker ts=4 sw=4 : +\layout Chapter + +Archivos +\layout Section + +Archivos del Enunciado +\layout Subsection + + +\family typewriter +.log +\layout Standard + +Los archivos de log generados por los distintos comandos, presentan todos + la misma estructura de registro que se detalla a continuación: +\family typewriter +YYYYMMDD-hhmm $usuario $comando: ¨$Mensaje¨ +\layout Subsection + + +\family typewriter +oridesti.txt +\layout Standard + +En este archivo se tienen los origenes y destinos en base a los cuales hemos + generados los archivos de llamada y los umbrales. +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Caption + + +\series bold +Estructura de oridesti.txt +\layout Standard +\align center + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + +Código +\end_inset + + +\begin_inset Text + +\layout Standard + +2 caracteres +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Descripción +\end_inset + + +\begin_inset Text + +\layout Standard + +N caracteres +\end_inset + + + + +\end_inset + + +\end_inset + + +\layout Subsection + + +\family typewriter +umbrales.param +\layout Standard + +Este archivo posee los umbrales de llamadas de los cuales se valdra el antifraud +e.pl para emitir o no alarmas durante el proceso de los archivos de llamadas. +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Caption + + +\series bold +Estructura de umbrales.param +\layout Standard +\align center + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + +Id del registro +\end_inset + + +\begin_inset Text + +\layout Standard + +N caracteres, número secuencial >= 1 +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Número de línea +\end_inset + + +\begin_inset Text + +\layout Standard + +N caracteres, Numérico +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Origen/Destino +\end_inset + + +\begin_inset Text + +\layout Standard + +2 caracteres, valores posibles segun oridesti.txt +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Tipo de llamada +\end_inset + + +\begin_inset Text + +\layout Standard + +1 caracter, E = Entrante, S = Salida +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Estado +\end_inset + + +\begin_inset Text + +\layout Standard + +1 caracter, A = Activo, I = Inactivo +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Usuario +\end_inset + + +\begin_inset Text + +\layout Standard + +N caracteres = login del user que graba el reg +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Fecha +\end_inset + + +\begin_inset Text + +\layout Standard + +8 caracteres, formato aaaammdd +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Hora +\end_inset + + +\begin_inset Text + +\layout Standard + +6 caracteres, formato hhmmss, hora actual +\end_inset + + + + +\end_inset + + +\end_inset + + +\layout Subsection + + +\family typewriter + +\layout Standard + +Estos archivos son los que el antifraude procesará en busca de matchs contra + los umbrales. +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Caption + + +\series bold +Estructura de un archivo de llamadas +\layout Standard +\align center + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + +Número de línea +\end_inset + + +\begin_inset Text + +\layout Standard + +N caracteres, Numérico +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Cantidad de Minutos +\end_inset + + +\begin_inset Text + +\layout Standard + +N caracteres, Numérico +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Fecha de Llamada +\end_inset + + +\begin_inset Text + +\layout Standard + +8 caracteres, formato aaaammdd +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Hora de Llamada +\end_inset + + +\begin_inset Text + +\layout Standard + +6 caracteres, formato hhmmss +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Tipo de Llamada +\end_inset + + +\begin_inset Text + +\layout Standard + +1 carácter, E = Entrante, S = Salida +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Destino +\end_inset + + +\begin_inset Text + +\layout Standard + +2 caracteres, solo informado en llamadas salientes +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Origen +\end_inset + + +\begin_inset Text + +\layout Standard + +2 caracteres, solo informado en llamadas entrantes +\end_inset + + + + +\begin_inset Text + +\layout Standard + +Prestadora +\end_inset + + +\begin_inset Text + +\layout Standard + +N caracteres +\end_inset + + + + +\end_inset + + +\end_inset + + +\layout Subsection + + +\family typewriter +alarmas.txt \layout Standard -El comando toma 3 parámetros -\series bold -opcionales -\series default -: -\layout LyX-Code - -./callgen [cant_archivos [min_lineas [max_lineas]]] -\layout LyX-Code +En este archivo el antifraude irá dejando registro de las alarmas emitidas + en base a registros que han tenido un match contra los umbrales. +\layout Standard \begin_inset Float table +placement H wide false -collapsed false +collapsed true \layout Caption \series bold -Parámetros del comando CALLGEN +Estructura de alarmas.txt \layout Standard \align center \begin_inset Tabular - + - @@ -402,19 +4319,25 @@ Par \layout Standard +Prestadora +\end_inset + + +\begin_inset Text + +\layout Standard -\series bold -Parámetro +N caracteres, campo 'Prestadora', archivo de llamadas \end_inset + + \begin_inset Text \layout Standard - -\series bold -Descripción +Central Telefónica \end_inset @@ -422,9 +4345,7 @@ Descripci \layout Standard - -\series bold -Default +4 caracteres, obtenido a partir del archivo de llamadas \end_inset @@ -434,15 +4355,25 @@ Default \layout Standard -cant_archivos +Número de Línea +\end_inset + + +\begin_inset Text + +\layout Standard + +N caracteres, campo 'Numero de Linea' , archivo de llamadas \end_inset + + \begin_inset Text \layout Standard -Cantidad de archivos a generar +Cantidad de minutos \end_inset @@ -450,7 +4381,7 @@ Cantidad de archivos a generar \layout Standard -10 +N caracteres, campo 'Cant de Minutos', archivo de llamadas \end_inset @@ -460,41 +4391,43 @@ Cantidad de archivos a generar \layout Standard -min_lineas +Regla Aplicada \end_inset - + \begin_inset Text \layout Standard -Mínima cantidad de lineas en un archivo +N caracteres, campo 'Id de registro', umbrales.param \end_inset - + + + \begin_inset Text \layout Standard -1000 +Fecha de llamada \end_inset - - - + \begin_inset Text \layout Standard -max_lines +8 caracteres, campo 'Fecha de llamada', archivo de llamadas \end_inset + + \begin_inset Text \layout Standard -Máxima cantidad de lineas en un archivo +Hora de llamada \end_inset @@ -502,205 +4435,124 @@ M \layout Standard -5000 +6 caracteres, campo 'Hora de llamada', archivo de llamadas \end_inset - - -\end_inset - - -\end_inset - - -\layout LyX-Code + + +\begin_inset Text \layout Standard +Usuario +\end_inset + + +\begin_inset Text -\series bold -NOTA: -\series default - Pueden cambiarse los valores por defecto editando el código fuente del - comando, en la sección de configuración que se encuentra al comienzo del - mismo. - También puede cambiarse el mínimo y máximo año (por defecto 1999 y 2004) - y el mínimo y máximo código de central (por defecto 0000 y 9999). -\layout Subsubsection - -Ejemplos de invocación -\layout Paragraph - -./callgen -\layout Paragraph - - -\series medium -Se escriben por entrada estándar los códigos de origen/destino, se presiona - Ctrl-D para cerrar el descriptor de archivo de la entrada estándar y se - generan 10 archivos con entre 1000 y 5000 líneas cada uno. -\layout Paragraph - -./callgen 2 < oridesti.txt -\layout Paragraph - - -\series medium -Genera 2 archivos con entre 1000 y 5000 líneas cada uno tomando los códigos - de origen/destino del archivo origesti.txt. -\layout Paragraph - -./callgen 5 10 < oridesti.txt -\layout Paragraph - - -\series medium -Genera 5 archivos con entre 10 y 5000 líneas cada uno tomando los códigos - de origen/destino del archivo origesti.txt. -\layout Paragraph - -./callgen 50 10 50 < oridesti.txt -\layout Paragraph - - -\series medium -Genera 50 archivos con entre 10 y 50 líneas cada uno tomando los códigos - de origen/destino del archivo origesti.txt. - -\layout Subsubsection - -Código Fuente \layout Standard -Copy Paste cuando este cerrado. -\layout Subsection +N caracteres, siempre login del usuario que graba el reg +\end_inset + + + + +\begin_inset Text -util.sh \layout Standard +Fecha +\end_inset + + +\begin_inset Text -\series bold -Tipo de comando: -\series default - Auxiliar, escrito en bash scripting -\layout Subsubsection - -Archivos de Input \layout Standard -No corresponde -\layout Subsubsection +8 caracteres, formato aaaammdd, fecha actual +\end_inset + + + + +\begin_inset Text -Archivos de Output \layout Standard -No corresponde -\layout Subsubsection - -Ejemplos de invocación -\layout Standard +Hora +\end_inset + + +\begin_inset Text -No corresponde. - El archivo es una colección de funciones comunes a los comandos. \layout Standard -El archivo contiene las siguientes funciones de uso genérico: -\layout Enumerate - -leer - Permite leer un valor desde el teclado, presentando una opción por - defecto seleccionada si el usuario ingresa una entrada nula. -\layout Enumerate - -preguntar - Realiza una pregunta al usuario dando un set de opciones válidas - y solo aceptando una respuesta del set de preguntas. -\layout Enumerate - -validar_solo_numeros - Verifica que la clave pasada contenga solo dígitos. -\layout Enumerate - -lock - Genera un archivo de lock con el PID del programa -\layout Enumerate - -unlock - Eliminar el archivo de lock de un programa -\layout Enumerate - -is_lock - Consulta si un programa está lockeado -\layout Enumerate - -lock_pid - Retorna el PID de un programa lockeado -\layout Enumerate - -validar_rango - Valida si un valor está en un rango de valores -\layout Enumerate - -die - Emite un mensaje de error y retorna al proceso padre un código de - error -\layout Enumerate +6 caracteres formato hhmmss, hora actual +\end_inset + + + -perr - Imprime un mensaje por la salida de error estandar -\layout Enumerate +\end_inset -put_log - Agrega una entrada a un archivo de log -\layout Enumerate -clean_log - Verifica el tamaño del archivo de log y lo trunca de ser necesario -\layout Subsubsection +\end_inset -Código Fuente -\layout Standard -Copy Paste cuando este cerrado. \layout Section -Archivos -\layout Subsection - -Archivos del Enunciado -\layout Standard - -[ Por cada uno se debe poner nombre y detallar su estructura interna ] -\layout Subsection - Archivos Auxiliares -\layout Subsubsection - -umbrales.id -\layout Standard +\layout Subsection -Este archivo contiene el último ID utilizado para los umbrales, a fin de - no tener que recalcularlo cada vez que se necesita crear un nuevo umbral. -\layout Subsubsection +\family typewriter afimonio.conf \layout Standard -El archivo de configuración $~/.antifraude/conf/afimonio.conf almacena las - rutas a los directorios necesarios para la ejecución del script +El archivo de configuración +\family typewriter +~/.antifraude/conf/afimonio.conf +\family default + almacena las rutas a los directorios necesarios para la ejecución del script + \family typewriter afimonio \family default y la ruta, nombre, y tamaño máximo del archivo de log. -\layout Subsubsection +\layout Subsection + +\family typewriter antifraude.conf \layout Standard -El archivo de configuración $~/.antifraude/conf/antifraude.conf almacena las - rutas a los directorios necesarios para la ejecución del script +El archivo de configuración +\family typewriter +~/.antifraude/conf/antifraude.conf +\family default + almacena las rutas a los directorios necesarios para la ejecución del script + \family typewriter antifraude.pl \family default y la ruta, nombre, y tamaño máximo del archivo de log. -\layout Subsubsection +\layout Subsection + +\family typewriter aficonf.conf \layout Standard -El archivo de configuración $~/.antifraude/conf/aficonf.conf almacena las - rutas a los directorios necesarios para la ejecución del script +El archivo de configuración +\family typewriter +~/.antifraude/conf/aficonf.conf +\family default + almacena las rutas a los directorios necesarios para la ejecución del script + \family typewriter aficonf \family default @@ -710,10 +4562,19 @@ aficonf Estos archivos fueron creados para que los diferentes scripts tengan un lugar común donde buscar esa información para salvar el problema comentado - en el punto 1.2. + en el punto +\begin_inset LatexCommand \vref{sec:Problemas-relevantes} + +\end_inset + +. \layout Subsection -Set de Prueba (testcalls.tar.gz) +Set de Prueba ( +\family typewriter +testcalls.tar.gz +\family default +) \layout Standard Para probar el comportamiento del sistema, se preparo un set de prueba distribui @@ -721,20 +4582,31 @@ do en el archivo \family typewriter testcalls.tar.gz \family default -, situado en el directorio /INST, del paquete de instalación. +, situado en el directorio +\family typewriter +/inst +\family default +, del paquete de instalación. El set de prueba se copia automáticamente en el momento en que se instale el componente +\family typewriter \series bold -ANTIFRAUDE +antifraude +\family default \series default , dejando el escenario listo para procesarlos en el momento en que sea arrancado el +\family typewriter \series bold -AFIMONIO +afimonio +\family default + \series default o bien ejecutando el +\family typewriter \series bold -ANTIFRAUDE +antifraude +\family default \series default en forma manual. \layout Standard @@ -747,21 +4619,35 @@ Este set de prueba consta de \layout Itemize 14 archivos de llamadas generados con el +\family typewriter \series bold -CALLGEN +callgen +\family default \series default , con entre 1000 y 5000 registros cada uno, y fecha en el rango año 1999 - - 2004. + a 2004. \layout Itemize -1 archivo de llamadas con registros validos y otros no validos. +1 archivo de llamadas con registros válidos y otros no válidos. \layout Itemize 1 archivo con nombre válido según el formato YYYYMMDDhhmm.nnnn, pero con - texto dentro suyo, el cual es rechazado por Antifraude. + contenido inválido, el cual es rechazado por +\family typewriter +\series bold +antifraude +\family default +\series default +. \layout Itemize -1 archivo con nombre no válido rechazado en instancia previa por el Afimonio. +1 archivo con nombre no válido rechazado en instancia previa por +\family typewriter +\series bold +afimonio +\family default +\series default +. \layout Standard Se describen en la siguiente tabla, los archivos y registros que disparan @@ -771,8 +4657,9 @@ Se describen en la siguiente tabla, los archivos y registros que disparan \begin_inset Float table +placement H wide false -collapsed false +collapsed true \layout Caption @@ -806,7 +4693,8 @@ Archivo \series bold -Linea Nro +Nro. + Línea \end_inset @@ -816,7 +4704,7 @@ Linea Nro \series bold -Matched Umbral +Umbral \end_inset @@ -1426,85 +5314,116 @@ Close match umbral 22, difiere tipo de llamada \end_inset -\layout Paragraph +\layout Subsubsection -Archivo 199908220733.4515 +Archivo +\family typewriter +199908220733.4515 \layout Paragraph \series medium -Posee registros no validos detallados a continuación. - Los registros se contabilizan de 0 a N (Linea 1 = Reg 0) -\layout Itemize +Posee registros no válidos detallados a continuación. + Los registros se contabilizan de 0 a N (Línea 1 = Reg 0) +\layout Description +Registro\SpecialChar ~ \series bold -Registro 3 +3 \series default - -> Posee un 9no campo 'Bogus' -\layout Itemize + Posee un 9no campo +\emph on +bogus +\layout Description +Registro\SpecialChar ~ \series bold -Registro 27 +27 \series default - -> Posee un 9no campo 'Bogus' -\layout Itemize + Posee un 9no campo +\emph on +bogus +\layout Description +Registro\SpecialChar ~ \series bold -Registro 31 +31 \series default - -> Posee un tipo de llamada 'W' no valida -\layout Itemize + Posee un tipo de llamada +\family typewriter +W +\family default + no valida +\layout Description +Registro\SpecialChar ~ \series bold -Registro 41 +41 \series default - -> El numero de linea (campo1) no es numerico, es un string 'ABCD' -\layout Itemize + El número de línea (campo1) no es numérico, es un string +\family typewriter +'ABCD' +\layout Description +Registro\SpecialChar ~ \series bold -Registro 52 +52 \series default - -> Tiene insuficiente cantidad de campos (siete) + Tiene cantidad de campos insuficiente (siete) \layout Standard -Estos registros emitirán errores plasmados en el antifraude.log. - Para verificar esto, realizar un search en el logfile, sobre el nombre - del archivo, y ubicarse en el sector donde se indica el comienzo del procesamie -nto del mismo con ¨ +Estos registros emitirán errores plasmados en el +\family typewriter +antifraude.log +\family default +. + Para verificar esto, realizar una búsqueda en el log, sobre el nombre del + archivo, y ubicarse en el sector donde se indica el comienzo del procesamiento + del mismo con ¨ \family typewriter Inicio proceso de: 199908220733.4515 \family default ¨. -\layout Paragraph +\layout Subsubsection -Archivo 200412010000.6666 +Archivo +\family typewriter +200412010000.6666 \layout Paragraph \series medium Es un archivo de texto el cual pasa el control de Afimonio, pero luego sus lineas son descartadas por antifraude y dicho error emitido en el antifraude.log -\layout Paragraph +\layout Subsubsection -Archivo 200223.1234 +Archivo +\family typewriter +200223.1234 \layout Paragraph \series medium El nombre del archivo no es conforme al formato de nombre estipulado en - el TP y el mismo es rechazado de antemano por Afimonio. -\layout Section + el TP y el mismo es rechazado de antemano por +\family typewriter +\series default +afimonio +\family default +\series medium +. +\layout Chapter Apéndice A -\layout Standard +\layout Comment -(Esto deberia ser una hoja aparte que solo diga 1.6 Apéndice A) y las hojas +Esto deberia ser una hoja aparte que solo diga 1.6 Apéndice A) y las hojas posteriores son las páginas 3 en adelante del PDF oficial de la catedra, sacando la parte de archivos. - 3-15 más precisamente es lo que iria). + 3-15 más precisamente es lo que iria. \the_end