X-Git-Url: https://git.llucax.com/z.facultad/75.08/llamadas.git/blobdiff_plain/f7c3d7b7c9700df05b6174535056b857452eecc8..8924bf6b7d40b1b543706926d806e4104db61393:/doc/Informe7508.lyx?ds=sidebyside diff --git a/doc/Informe7508.lyx b/doc/Informe7508.lyx index 22a71dd..ff754b8 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 @@ -84,6 +84,20 @@ Aficonf utiliza n La opción Borrar es ofrecida requiriendo un número de ID a borrar dependiendo de los resultados de la búsqueda, y dando una opción (-1) para cancelar la acción. +\layout Itemize + +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 Section @@ -121,10 +135,93 @@ root \layout Section Instalación -\layout Comment +\layout Standard + +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 + +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 +antifraude +\series default + debe correr el script +\series bold +afinstal +\series default +: +\layout LyX-Code + +./afinstal +\layout Standard -Copiar del README cuando este terminado y extenderlo un poco si se considera - necesario. +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 Section Comandos Desarrollados @@ -236,200 +333,2470 @@ nohup.out \layout Subsubsection Código Fuente -\layout Comment +\layout LyX-Code -Copy Paste cuando este cerrado. -\layout Subsection +#!/bin/bash +\layout LyX-Code -ANTIFRAUDE -\layout Subsubsection +\layout LyX-Code -Tipo de comando -\layout Standard +BASE_DIR=$HOME/.antifraude +\layout LyX-Code -Solicitado. -\layout Subsubsection +\layout LyX-Code -Archivos de Input -\layout Standard +# uso las funciones de util.sh +\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 -\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 Subsubsection + "$HOME/.antifraude/util.sh" +\layout LyX-Code -Archivos de Output -\layout Description +. + "$HOME/.antifraude/conf/afimonio.conf" +\layout LyX-Code +. + "$HOME/.antifraude/conf/antifraude.conf" +\layout LyX-Code -\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 +\layout LyX-Code +# Es llamada por los trap para deslockear el afimonio +\layout LyX-Code -\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 Subsubsection +finalize() { +\layout LyX-Code -Ejemplos de invocación -\layout Paragraph + unlock "afimonio" +\layout LyX-Code + exit 0 +\layout LyX-Code -\family typewriter -./antifraude.pl -\layout Standard +} +\layout LyX-Code -El programa procesa las llamadas -\family typewriter -enproceso -\family default - como indica el enunciado en primer plano. -\layout Paragraph +# filtra el nombre del archivo pasado por parametro sacandole +\layout LyX-Code +# todos los caracteres que no sean numeros +\layout LyX-Code -\family typewriter -perl antifraude.pl -\layout Standard +checkfilename(){ +\layout LyX-Code -Ídem anterior. -\layout Paragraph + date=`echo $1 | cut -d "." -f 1` +\layout LyX-Code -./antifraude.pl & -\layout Standard + central=`echo $1 | cut -d "." -f 2` +\layout LyX-Code -Ídem anterior pero procesa en segundo plano. -\layout Subsubsection + validar_solo_numeros "$date" +\layout LyX-Code -Código Fuente -\layout Comment + if [ "$?" -ne 0 ]; then +\layout LyX-Code -Copy Paste cuando este cerrado. -\layout Subsection + return 1 +\layout LyX-Code -AFICONF -\layout Subsubsection + fi +\layout LyX-Code -Tipo de comando -\layout Standard + mes=${date:4:2} +\layout LyX-Code -Solicitado. -\layout Subsubsection + validar_rango "$mes" "1" "12" +\layout LyX-Code -Archivos de Input -\layout Standard + if [ "$?" -ne 0 ]; then +\layout LyX-Code -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 + return 1 +\layout LyX-Code -Archivos de Output -\layout Standard + fi +\layout LyX-Code -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 Subsubsection + dia=${date:6:2} +\layout LyX-Code -Ejemplos de invocación -\layout Paragraph + validar_rango "$dia" "1" "31" +\layout LyX-Code + if [ "$?" -ne 0 ]; then +\layout LyX-Code -\family typewriter -./aficonf -\layout Standard + return 1 +\layout LyX-Code -Realiza lo pedido en el enunciado. -\layout Subsubsection + fi +\layout LyX-Code -Código Fuente -\layout Standard + hora=${date:8:2} +\layout LyX-Code -Copy Paste cuando este cerrado. -\layout Subsection + validar_rango "$hora" "0" "23" +\layout LyX-Code -CALLGEN -\layout Subsubsection + if [ "$?" -ne 0 ]; then +\layout LyX-Code -Tipo de comando -\layout Standard + return 1 +\layout LyX-Code -Auxiliar, escrito en -\family typewriter -perl -\family default -. -\layout Subsubsection + fi +\layout LyX-Code -Justificación de su uso -\layout Standard + min=${date:10:2} +\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 + validar_rango "$min" "0" "59" +\layout LyX-Code -Archivos de Input -\layout Standard + if [ "$?" -ne 0 ]; then +\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 + return 1 +\layout LyX-Code -Archivos de Output -\layout Standard + fi +\layout LyX-Code -Crea una cantidad -\family typewriter -N -\family default - (especificada por el usuario) de archivos con nombre y formato de + 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 Subsection + +ANTIFRAUDE +\layout Subsubsection + +Tipo de comando +\layout Standard + +Solicitado. +\layout Subsubsection + +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 Subsubsection + +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 Subsubsection + +Ejemplos de invocación +\layout Paragraph + + +\family typewriter +./antifraude.pl +\layout Standard + +El programa procesa las llamadas +\family typewriter +enproceso +\family default + como indica el enunciado en primer plano. +\layout Paragraph + + +\family typewriter +perl antifraude.pl +\layout Standard + +Ídem anterior. +\layout Paragraph + + +\family typewriter +./antifraude.pl & +\layout Standard + +Ídem anterior pero procesa en segundo plano. +\layout Subsubsection + +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 Subsection + +AFICONF +\layout Subsubsection + +Tipo de comando +\layout Standard + +Solicitado. +\layout Subsubsection + +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 Subsubsection + +Ejemplos de invocación +\layout Paragraph + + +\family typewriter +./aficonf +\layout Standard + +Realiza lo pedido en el enunciado. +\layout Subsubsection + +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 Subsection + +UTIL +\layout Subsubsection + +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 Subsubsection + +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 Subsubsection + +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 Subsubsection + +Archivos de Output +\layout Standard + +Ídem anterior. +\layout Subsubsection + +Parámetros +\layout Standard + +Al no ser un comando ejecutable, no aplica. +\layout Subsubsection + +Opciones +\layout Standard + +Ídem anterior. +\layout Subsubsection + +Ejemplos de invocación +\layout Standard + +Ídem anterior. +\layout Subsubsection + +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 Subsection + +CALLGEN +\layout Subsubsection + +Tipo de comando +\layout Standard + +Auxiliar, escrito en +\family typewriter +perl +\family default +. +\layout Subsubsection + +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 Subsubsection + +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 Subsubsection + +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 @@ -438,37 +2805,1120 @@ Archivo de Llamadas mente (respetando el formato mencionado y con valores racionales). \layout Subsubsection -Parámetros +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 Subsubsection + +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 Subsubsection + +Ejemplos de invocación +\layout Paragraph + + +\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 Paragraph + + +\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 Paragraph + + +\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 Paragraph + + +\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 Subsubsection + +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 Section + +Archivos +\layout Subsection + +Archivos del Enunciado +\layout Subsubsection + + +\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 Subsubsection + + +\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 Subsubsection + + +\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 Subsubsection + + +\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 -El comando toma 3 parámetros -\series bold -opcionales -\series default -: -\layout LyX-Code +6 caracteres, formato hhmmss +\end_inset + + + + +\begin_inset Text -./callgen [cant_archivos [min_lineas [max_lineas]]] -\layout LyX-Code +\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 Subsubsection + + +\family typewriter +alarmas.txt +\layout Standard + +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 - + - @@ -476,19 +3926,25 @@ Par \layout Standard +Prestadora +\end_inset + + +\begin_inset Text -\series bold -Parámetro +\layout Standard + +N caracteres, campo 'Prestadora', archivo de llamadas \end_inset + + \begin_inset Text \layout Standard - -\series bold -Descripción +Central Telefónica \end_inset @@ -496,9 +3952,7 @@ Descripci \layout Standard - -\series bold -Default +4 caracteres, obtenido a partir del archivo de llamadas \end_inset @@ -508,15 +3962,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 @@ -524,7 +3988,7 @@ Cantidad de archivos a generar \layout Standard -10 +N caracteres, campo 'Cant de Minutos', archivo de llamadas \end_inset @@ -534,41 +3998,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_linaes +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 @@ -576,107 +4042,72 @@ M \layout Standard -5000 +6 caracteres, campo 'Hora de llamada', archivo de llamadas \end_inset - - -\end_inset + + +\begin_inset Text +\layout Standard +Usuario \end_inset - - -\layout LyX-Code + + +\begin_inset Text \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 Subsubsection - -Ejemplos de invocación -\layout Paragraph - - -\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 Paragraph - - -\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 Paragraph +N caracteres, siempre login del usuario que graba el reg +\end_inset + + + + +\begin_inset Text +\layout Standard -\family typewriter -./callgen 5 10 < oridesti.txt -\layout Paragraph +Fecha +\end_inset + + +\begin_inset Text +\layout Standard -\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 Paragraph +8 caracteres, formato aaaammdd, fecha actual +\end_inset + + + + +\begin_inset Text +\layout Standard -\family typewriter -./callgen 50 10 50 < oridesti.txt -\layout Paragraph +Hora +\end_inset + + +\begin_inset Text +\layout Standard -\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 Subsubsection +6 caracteres formato hhmmss, hora actual +\end_inset + + + -Código Fuente -\layout Comment +\end_inset -Copy Paste cuando este cerrado. -\layout Section -Archivos -\layout Subsection +\end_inset -Archivos del Enunciado -\layout Comment -Por cada uno se debe poner nombre y detallar su estructura interna. \layout Subsection Archivos Auxiliares @@ -829,8 +4260,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