1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
11 \paperpackage widemarginsa4
15 \use_numerical_citations 0
16 \paperorientation portrait
19 \paragraph_separation indent
21 \quotes_language english
25 \paperpagestyle default
29 Sistemas Operativos (75.08)
50 Leandro Lucarella (77891)
52 Ricardo Markiewicz (78226)
55 26 de Octubre del 2004
59 \begin_inset LatexCommand \tableofcontents{}
66 Hipotesis y Aclaraciones
69 El programa en su totalidad va a ser ejecutado por un único usuario, una
70 configuración diferente es posible pero queda en manos del administrador.
73 En los archivos de llamada se valida que sean números, y para validar la
74 fecha no se tiene en cuenta casos particulares como el 29, 30, 31 de febrero.
77 Todos los meses pueden tener 31 días.
80 Aficonf utiliza números para describir las acciones Nuevo y Buscar.
81 La opción Borrar es ofrecida requiriendo un número de ID a borrar dependiendo
82 de los resultados de la búsqueda, y dando una opción (-1) para cancelar
86 El instalador utiliza el archivo
90 , situado en el directorio
94 , para determinar que componentes se encuentran instalados.
95 Internamente, en base a la información de paths proporcionada por este
96 archivo, busca su los binarios realmente se encuentran en el OS, y en caso
97 contrario permite volver a reinstalarlo/s.
101 \begin_inset LatexCommand \label{sec:Problemas-relevantes}
108 Dado que los distintos componentes del sistema se pueden instalar en diferentes
109 paths dentro del OS, creamos el directorio
113 donde se almacenará información acerca de los paths en donde reside cada
114 uno de ellos y otros archivos de intercambio.
117 Así mismo, como los programas pueden ser instalados en directorios distintos,
118 toda la información compartida es guardada en
122 , para ser mas consistentes con la manera de trabajar en Unix.
123 Lo ideal hubiera sido utilizar
127 , pero como no podríamos suponer acceso de
131 preferimos directamente trabajar en el directorio del usuario.
137 Una vez descargados los fuentes (asumiremos que ha descargado el
141 ) solo debe descomprimir el archivo ejecutando el siguiente comando:
144 tar xvzf grupo12.tar.gz
147 Esto creará la siguiente estructura de directorios:
192 +---- afimonio_daemon.sh
201 +---- testcalls.tar.gz
204 Para proceder a la instalación del sistema
208 debe correr el script
215 cd grupo12/antifraude
221 y seguir los pasos que se le indiquen a continuación.
222 De no ejecutar apropiadamente la instalación, no se garantiza el correcto
223 funcionamiento de los componentes.
229 Antifraude es un sistema automatizado, que se vale de un script de bash
230 corriendo en background.
233 Para iniciar el demonio existen varios métodos posibles, pero lo recomendado
234 es utilizar la utilidad
240 , que permite iniciar el demonio (si no esta corriendo ya), detener el demonio
241 (si actualmente esta corriendo o consultar el estado actual.
247 Desde el directorio donde se instalaron los ejecutables:
250 ./afimonio_daemon.sh [start|stop|status]
254 \begin_inset LatexCommand \vref{sec:AFIMONIO_DAEMON.SH}
258 para más información.
264 Este software se distribuye bajo licencia GNU GPL versión 2.0 o superior.
265 Para más detalles lea el archivo
272 Comandos Desarrollados
289 Procesa los archivos que se encuentran en el directorio
291 $PATH_ANTIFRAUDE/$DATADIR/aprocesar
295 $PATH_ANTIFRAUDE/$DATADIR/enproce
312 El afimonio genera una salida al archivo
316 la cual contiene información sobre la ejecución del programa.
319 Si un archivo es válido, se añade una línea con el siguiente formato:
322 $fecha $USER afimonio: "Se detecta archivo de llamadas $file"
325 Si el archivo tuviera un nombre inválido, la línea seria la siguiente:
328 $fecha $USER afimonio: "Se rechaza el archivo $file"
338 fecha actual con formato Día-Mes-Año-Hora:Minuto.
345 nombre de usuario que ejecuto el script.
352 nombre del archivo que se procesó.
355 Ejemplos de invocación
356 \layout Subsubsection
363 Corre el programa en primer plano.
364 \layout Subsubsection
371 Corre el programa en segundo plano, evitando que se cierre al morir el padre
372 desasociándolo de la terminal.
373 La salida del programa queda en el archivo
377 a menos que se redirija a otro archivo.
388 BASE_DIR=$HOME/.antifraude
393 # uso las funciones de util.sh
397 "$HOME/.antifraude/util.sh"
401 "$HOME/.antifraude/conf/afimonio.conf"
405 "$HOME/.antifraude/conf/antifraude.conf"
410 # Es llamada por los trap para deslockear el afimonio
425 # filtra el nombre del archivo pasado por parametro sacandole
428 # todos los caracteres que no sean numeros
434 date=`echo $1 | cut -d "." -f 1`
437 central=`echo $1 | cut -d "." -f 2`
440 validar_solo_numeros "$date"
443 if [ "$?" -ne 0 ]; then
455 validar_rango "$mes" "1" "12"
458 if [ "$?" -ne 0 ]; then
470 validar_rango "$dia" "1" "31"
473 if [ "$?" -ne 0 ]; then
485 validar_rango "$hora" "0" "23"
488 if [ "$?" -ne 0 ]; then
500 validar_rango "$min" "0" "59"
503 if [ "$?" -ne 0 ]; then
512 validar_solo_numeros "$central"
515 if [ "$?" -ne 0 ]; then
530 #--------------------MAIN SCRIPT----------------------
533 # Recupero las rutas a todos los directorios y archivos
536 # que necesito del antifraude
539 DATADIR=$ANTI_DATADIR
542 SOURCEDIR=$DATADIR/aprocesar/
545 ACEPTDIR=$DATADIR/enproceso/
548 REJECTDIR=$DATADIR/rechazadas/
560 LOGNAME=$AFIM_LOGFILE
563 LOGFILE=$LOGDIR/$LOGNAME
566 # Capturo señales para salir bien (liberando el lock)
578 lock "afimonio" || die "No se puede correr, hay otra
583 instancia corriendo o no se puede crear el lock file!"
586 # Comienza el ciclo infinito que mueve los archivos
595 for file in `ls $SOURCEDIR` ; do
604 if [ "$?" -eq 0 ]; then
607 mv "$SOURCEDIR$file" "$ACEPTDIR"
610 fecha=$(date +%d/%m/%Y-%H:%M)
613 echo "$fecha $USER afimonio:
620 "archivo de llamadas $file
628 mv "$SOURCEDIR$file" "$REJECTDIR"
631 fecha=$(date +%d/%m/%Y-%H:%M)
634 echo "$fecha $USER afimonio:
649 clean_log "$LOGFILE" "$AFIM_LOGSIZE"
655 # me fijo si el antifraude esta corriendo y si no lo esta
661 if [ -n $files ] && ! is_lock "antifraude.pl"; then
664 $BINDIR/antifraude.pl &
688 Procesa los archivos de llamadas que encuentre en el momento de invocación
691 $PATH_ANTIFRAUDE/$DATADIR/enproceso
700 será quien alimentará al
706 con dichos archivos, no obstante se lo puede alimentar con archivos de
707 llamadas en forma manual, situándolos en el directorio anteriormente descripto.
710 Este comando, en el momento de invocacion genera y guarda internamente un
711 listado de los archivos de llamadas presences en el directorio
715 , ordenándolos por fecha (establecida en el nombre del archivo) en forma
717 Dado que utiliza durante toda su ejecución esta lista interna, el
723 puede alimentar al directorio
727 con nuevos archivos mientras el
733 corre, pero los mismos no serán tenidos en cuenta (esto es, procesados),
734 hasta la próxima invocación del comando.
744 En este archivo se guarda información del procesamiento de los registros,
745 advertencias provocados por registros no validos y alarmas emitidas por
746 registros que cumplen con un umbral.
753 En este archivo se guarda información de las alarmas provocadas por registros
754 en los archivos de llamadas, que hayan cumplido un umbral determinado del
762 Ejemplos de invocación
763 \layout Subsubsection
770 El programa procesa las llamadas
774 como indica el enunciado en primer plano.
775 \layout Subsubsection
783 \layout Subsubsection
790 Ídem anterior pero procesa en segundo plano.
802 if ( -e "$ENV{'HOME'}/.antifraude/lock/antifraude.pid" ) {
805 # Lock file encontrado
826 unlink ("$ENV{'HOME'}/.antifraude/lock/antifraude.pid");
838 local $lfile = "$ENV{'HOME'}/.antifraude/lock/antifraude.pid";
841 open(LOCKFILE,">>$lfile");
862 # Comparador de fecha para los archivos de llamada
868 ($year1,$mon1,$day1,$hr1,$min1) =
871 $a =~ /([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/;
874 ($year2,$mon2,$day2,$hr2,$min2) =
877 $b =~ /([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/;
886 if ($year1 > $year2) { return 1; }
889 elsif ($year1 < $year2) { return -1; }
895 if ($mon1 > $mon2) { return 1; }
898 elsif ($mon1 < $mon2) { return -1; }
901 # Calculo minutos de lo restante
904 $totalmin1 = ($day1 * 24 * 60) + ($hr1 * 60) + $min1;
907 $totalmin2 = ($day2 * 24 * 60) + ($hr2 * 60) + $min2;
910 if ($totalmin1 > $totalmin2) { return 1; }
913 elsif ($totalmin1 < $totalmin2) { return -1; }
922 # Devuelve un listado de archivos de llamada y ordenado por fecha ASC
928 # Obtengo listado de archivos de llamadas y lo ordeno por fecha
931 opendir($DIR,"$CONFDATA{datadir}/enproceso")
934 or die 'Could not open dir';
937 # Valido solo fisicamente, lo logico ya valido afimonio..
940 @files = grep {/[0-9]{12}
945 && -f "$CONFDATA{datadir}/enproceso/$_"} readdir($DIR);
948 @sortedfiles = sort byDate @files;
960 # Levanta una variable del archivo AFINSTAL.CONF
966 $CONFIGFILE = shift(@_);
969 my $linenumber = shift(@_);
975 or die "No se pudo abrir el archivo $CONFIGFILE";
978 do { $line = <CONFIGFILE> } until $.
988 ($confvar = $line) =~ s/"(.*)"$/$1/;
991 $confvar =~ s/^.*=//;
1000 # Agrega un log entry al logfile del antifraude.pl
1006 my $logentry = shift(@_);
1009 my $consoleout = shift(@_);
1012 my $log = "$CONFDATA{logdir}/$CONFDATA{logfile}";
1015 # Fetch date and Format it
1018 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
1044 $year += 1900; ++$mon;
1047 $user = "$ENV{USER}";
1050 $commonstring = "$mday/$mon/$year-$hour:$min $user antifraude:";
1056 open(LOGFILE,">>$log")
1059 or die "No se pudo abrir el archivo de log";
1065 print LOGFILE "$commonstring
1074 $filesize = tell(LOGFILE);
1080 # Chequeo el logsize y su lo supero me quedo con 100 lineas
1083 if ($filesize > $CONFDATA{logsize})
1089 open(LOGFILE,"+<$log");
1092 do ($line = <LOGFILE>) until $.
1096 truncate(LOGFILE,tell(LOGFILE));
1105 if ($consoleout) { print("$logentry
1116 my $callreg = shift(@_);
1119 my $numreg = shift(@_);
1122 logEntry("El siguiente registro de llamada tiene format ".
1130 print("Warning: El registro de llamada $numreg tiene ".
1147 local(*callfields) = $_[0];
1150 my $callsfile = $_[1];
1153 my $matchedUmbral = 0;
1159 while (($i <= $#UMBRALES) && ($matchedUmbral == 0)) {
1162 $umbral = $UMBRALES[$i];
1168 ($regid,$phoneline,$oridest,$type,$state)
1171 = split(';',$umbral);
1174 if (($state eq 'A') && ($callfields[0] == $phoneline)
1177 && ($callfields[4] eq $type)) {
1180 # Si es Saliente y coincide el Destino con el
1183 # Ori/Dest del umbral
1189 && ($callfields[5] eq $oridest)) {
1192 $matchedUmbral = $regid;
1201 && ($callfields[6] eq $oridest)) {
1204 $matchedUmbral = $regid;
1219 # Si se matcheo un umbral, grabo una alarma y aviso por consola
1222 if ($matchedUmbral > 0) {
1225 # Obtengo algunos datos
1228 ($central = $callsfile) =~ s/^.*
1233 $user = "$ENV{USER}";
1236 # Fetch date and Format it
1239 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
1245 $year += 1900; ++$mon;
1273 $user = "$ENV{USER}";
1276 $date = "${year}${mon}${mday}";
1279 $time = "${hour}${min}${sec}";
1282 # Preparo el registro de alarma
1285 $alarmEntry = "$callfields[7];$central;$callfields[0];".
1288 "$callfields[1];$regid;$callfields[2];".
1291 "$callfields[3];$user;$date;$time";
1294 # Grabamos el registro en el archivo de alarmas
1297 $alarmlog = "$CONFDATA{datadir}/alarmas/alarmas.txt";
1300 open(ALARMFILE,">>$alarmlog")
1303 or die 'No se pudo abrir el archivo de alarmas';
1306 seek(ALARMFILE,0,2);
1309 print ALARMFILE "$alarmEntry
1317 # Logeo por consola y logfile que hubo una alarma
1320 logEntry("Alarma: Se ha matcheado el registro procesado"
1323 ." con el umbral nro $matchedUmbral",1);
1332 # --------- MAIN CODE -------- #
1338 if (is_lock()) { exit 1; }
1344 # Defino some GLOBALS
1347 $CONFDIR = "$ENV{'HOME'}/.antifraude";
1350 $CONFDATA{logdir} = getConfVar("$CONFDIR/conf/antifraude.conf",2);
1353 $CONFDATA{logfile} = getConfVar("$CONFDIR/conf/antifraude.conf",3);
1356 $CONFDATA{logsize} = getConfVar("$CONFDIR/conf/antifraude.conf",4);
1359 $CONFDATA{datadir} = getConfVar("$CONFDIR/conf/antifraude.conf",5);
1362 # Cargo los UMBRALES en memoria
1365 open(PARAMFILE,"$CONFDIR/umbrales.param") or die "No se pudo abrir el "
1368 ."archivo de umbrales";
1371 @UMBRALES = <PARAMFILE>;
1377 # Proceso los archivos de llamadas
1380 @archivos = getCallFiles();
1383 FILE: foreach $filename (@archivos) {
1389 $CALLFILE = "$CONFDATA{datadir}/enproceso/$filename";
1392 logEntry("Inicio proceso de: $filename",1);
1398 or ((warn "No se pudo abrir archivo $filename"),next FILE);
1401 REG: foreach $callreg (<CALLFILE>) {
1404 logEntry("Procesando Reg: $regnum | Archivo: $filename",1);
1410 $fieldcount = split(';',$callreg);
1416 # Si no tengo 8 campos exactamente, invalido
1419 if ($fieldcount != 8)
1425 badCall($callreg,$regnum);
1434 # Si la linea no es un numero, invalido
1446 if (!($fields[0] =~ /^
1454 badCall($callreg,$regnum);
1463 # Si tipo llamada ! E|S o no se informa Origen
1466 # o Destino, invalido
1469 if (($fields[4] ne 'E') && ($fields[4] ne 'S')) {
1472 badCall($callreg,$regnum); next REG;
1478 if (($fields[4] eq 'E') && ($fields[6] eq "")) {
1481 badCall($callreg,$regnum); next REG;
1487 if (($fields[4] eq 'S') && ($fields[5] eq "")) {
1490 badCall($callreg,$regnum); next REG;
1496 # Ya pase todas las validaciones, ahora busco si
1502 checkUmbrales(*fields,$filename);
1505 } continue { ++$regnum }
1511 # La muevo al directorio de procesadas
1514 rename $CALLFILE,"$CONFDATA{datadir}/procesadas/$filename";
1517 logEntry("Fin proceso de: $filename",1);
1541 El comando utiliza los archivos
1552 \layout Subsubsection
1561 de ser solicitado por el usuario, ya sea por la alta o baja de un umbral.
1564 Ejemplos de invocación
1565 \layout Subsubsection
1572 Realiza lo pedido en el enunciado.
1592 BASE_DIR="$HOME/.antifraude"
1601 "$BASE_DIR/conf/aficonf.conf"
1616 LOGNAME=$AFIC_LOGFILE
1619 LOGFILE=$LOGDIR/$LOGNAME
1624 #Valida que exista el pais
1630 # $1 = Descripcion a buscar
1633 # $2 = Variable donde guardar el código del Pais
1636 # en caso de existir
1642 EXISTE=`cat "$BASE_DIR/oridesti.txt"
1647 | egrep "^[A-Z]*;$1" | cut -d ';' -f 1`;
1650 if [ "$EXISTE" != "" ] ; then
1653 #Exite!, debo gaurdar el código
1673 poner_estado_umbral () {
1682 FECHA=`date +"%Y%m%d"`
1685 HORA=`date +"%H%M%S"`
1691 if [ "$ESTADO" != "A" ] && [ "$ESTADO" != "I" ]
1705 (;[^;]*;[^;]*;[^;]*;
1718 1I;$USER;$FECHA;$HORA/"
1723 "$BASE_DIR/umbrales.param"`
1726 echo "$SALIDA" > "$BASE_DIR/umbrales.param"
1729 put_log "$LOGFILE" "aficonf"
1734 "Se ha cambiado el estado de umbral $ID a $ESTADO"
1768 preguntar "Su opción" "123" $1
1779 EXISTE=`cat "$BASE_DIR/umbrales.param" | egrep "$1"`;
1782 if [ "$EXISTE" == "" ] ; then
1794 #Ya existe un umbral!
1806 buscar_id_umbral () {
1809 ID=`cat "$BASE_DIR/umbrales.id"`;
1818 echo "$ID" > "$BASE_DIR/umbrales.id"
1830 while [ $DONE == 0 ] ; do
1833 leer "Número de línea" "" LINEA
1839 if ! validar_solo_numeros "$LINEA" ; then
1842 echo "EL NUMERO TE LINEA SOLO DEBE"
1859 if [ "$LINEA" == "" ] ; then
1871 preguntar "Tipo de llamada" "ES" TIPO
1880 while [ $DONE == 0 ] ; do
1883 leer "Pais (descripción)" "" PAIS
1886 if ! existe_pais "$PAIS" CODIGO ; then
1889 echo "No existe el país de descrición '$PAIS'"
1901 if [ "$PAIS" == "" ] ; then
1913 echo "El código de '$PAIS' es '$CODIGO'"
1919 # Verifico que el umbral no exista
1922 FECHA=`date +"%Y%m%d"`
1925 HORA=`date +"%H%M%S"`
1928 UMBRAL="$LINEA;$PAIS;$TIPO;A;*;*;*"
1931 if existe_umbral "$UMBRAL" ; then
1934 echo "Ya existe un umbral con los datos ingresados."
1940 put_log "$LOGFILE" "aficonf"
1945 "Se trató de insertar un umbral repetido ($UMBRAL)"
1968 UMBRAL="$ID;$LINEA;$PAIS;$TIPO;A;$USER;$FECHA;$HORA"
1974 echo "$UMBRAL" >> "$BASE_DIR/umbrales.param"
1980 echo "El Umbral fue grabado con éxito"
1991 "aficonf" "Se inserto un nuevo umbral ($UMBRAL)"
2008 while [ $DONE == 0 ] ; do
2011 leer "Número de línea" "" LINEA
2017 if ! validar_solo_numeros "$LINEA" ; then
2020 echo "EL NUMERO TE LINEA SOLO DEBE"
2037 if [ "$LINEA" == "" ] ; then
2049 DATOS=`cat "$BASE_DIR/umbrales.param"
2054 | grep "[0-9]*;$LINEA;[A-Z]*;[E,S];A"`
2057 if [ "$DATOS" == "" ] ; then
2063 echo "No se han encontrado Umbrales activos"
2068 "para la linea $LINEA."
2071 echo "Abortando ..."
2077 put_log "$LOGFILE" "aficonf"
2082 "No se han encontrado umbrales para la línea $LINEA"
2096 printf "%3s %2s %1s %1s %10s%8s %6s
2103 "ID" "Ciudad" "Tipo" "Estado" "Usuario" "Fecha" "Hora"
2109 for i in $DATOS ; do
2112 ID=`echo "$i" | cut -d ';' -f 1`
2115 CIUDAD=`echo "$i" | cut -d ';' -f 3`
2118 TIPO=`echo "$i" | cut -d ';' -f 4`
2121 ESTADO=`echo "$i" | cut -d ';' -f 5`
2124 USUARIO=`echo "$i" | cut -d ';' -f 6`
2127 FECHA=`echo "$i" | cut -d ';' -f 7`
2130 HORA=`echo "$i" | cut -d ';' -f 8`
2138 "%3s %2s %1s %1s %10s %8s %6s
2145 "$ID" "$CIUDAD" "$TIPO" "$ESTADO" "$USUARIO"
2153 OPCIONES="$OPCIONES $ID"
2159 preguntar "Cual desea borrar (-1 para salir)" "$OPCIONES" OPT
2162 if [ "$OPT" = "-1" ] ; then
2171 echo "Borrando el registro $OPT ..."
2174 poner_estado_umbral "$OPT" "I"
2177 put_log "$LOGFILE" "aficonf"
2182 "No se ha eliminado elumbral de ID $OPT" "$AFIC_LOGSIZE"
2191 echo "El Umbral fue eliminado con éxito"
2202 # No permito correr 2 instancias de AFICONF
2205 if is_lock "aficonf" ; then
2211 echo "Aficonf está corriendo actualmente."
2217 put_log "$LOGFILE" "aficonf"
2222 "Se ha intentado ejecutar aficonf cuando este estaba corriendo"
2246 while [ "$OPT" != "3" ] ; do
2276 Auxiliar, escrito en bash.
2279 Sería equivalente a una biblioteca compartida, no es exactamente un comando
2280 que se pueda ejecutar directamente sino que se incluye desde otros comandos.
2283 Justificación de su uso
2286 Es un archivo con varias funciones generales, sirve para no duplicar código
2287 común entre los varios scripts de bash.
2293 Al ser de propósito general, no tiene ningún archivo de input específico,
2294 aunque hay funciones que utilizan archivos, no se describen aquí sino en
2295 los comandos que usan este archivo.
2307 Al no ser un comando ejecutable, no aplica.
2316 Ejemplos de invocación
2331 # Los scrips que incluyan deben definir BASE_DIR
2334 # antes de incluirme!
2339 LOCK_DIR="$BASE_DIR/lock"
2342 # Lee del teclado un valor
2351 # $1 = Leyeda a mostrar de pregunta
2354 # $2 = Valor default por si el usuario no ingresa nada
2357 # $3 = Variable donde guardar el valor ingresado (o el default)
2372 read -p "$MSG [$DEFAULT] : " ALGO
2375 # Si el usuario no ingresa nada
2378 # nos quedamos con el valor default
2381 if [ ! -z "$ALGO" ] ; then
2401 # Realiza una pregunta al usuario
2410 # $1 = Leyeda a mostrar de preguntar
2413 # $2 = string con las opciones validas
2416 # $3 = Variable donde guardar el valor ingresado
2419 # $4 = Valor por defecto si se apreta ENTER
2440 read -p "$PREGUNTA [$OPCIONES]: " RTA
2443 # Si me pasaron un default y la respuesta es vacía
2446 if [ -n "$DEFAULT" -a -z "$RTA" ]; then
2461 # Escapeo el caracter '-' por '
2466 RTA=$(echo $RTA | sed "s/
2477 IS_OK=`echo "$OPCIONES" | grep "$RTA"`
2480 if [ ! -z "$IS_OK" ] && [ ! -z "$RTA" ] ; then
2500 validar_solo_numeros () {
2503 TEST=`echo "$1" | sed "s/[0-9]*//g"`
2506 if [ "$TEST" == "" ] ; then
2509 #Ok, son solo numeros
2518 # ups, hay algo que no es un numero
2529 # Crea un archivo de lock para un script
2532 # Devuelve: 0 si ok, 1 si ya esta lockeado, 2 si no pudo crear lock.
2535 # Uso: lock programa
2541 # si ya esta loqueado, no lo vuelvo a crear
2544 is_lock "$1" && return 1
2547 # Si no puedo escribir en el dir de lock, da error
2550 [ -w "$LOCK_DIR" ] || return 2
2553 echo $$ > "$LOCK_DIR/$1.pid"
2564 # Desbloquea el script
2567 # Uso: unlock programa
2573 rm -rf "$LOCK_DIR/$1.pid"
2582 # Consulta si un script esta lockeado
2585 # Uso: is_lock programa
2591 if [ -e "$LOCK_DIR/$1.pid" ] ; then
2594 # Lock file encontrado!
2614 # Obtiene el pid de un programa lockeado
2617 # Uso: lock_pid programa
2626 is_lock "$1" && cat "$LOCK_DIR/$1.pid"
2634 # Verifica que un valor este entre otros 2
2637 # $1 pertecezca a [$2,$3]
2640 # $1 Numero a validar
2652 if [ "$1" -ge "$2" ] && [ "$1" -le "$3" ]; then
2672 # Muestra mensaje y sale con código de error
2675 # Uso: die mensaje [código de error = 1]
2695 # Imprime mensaje por salida de error
2698 # Uso: perr mensajes
2715 # Pone un MSG en el log
2721 # $1 = Archivo del log
2730 # $4 = Tamaño maximo
2736 fecha=$(date +%d/%m/%Y-%H:%M)
2739 echo "$fecha $USER $2:
2754 # Trunca un archivo de log si pasa el tamaño máximo.
2757 # Uso: clean_log log_filename max_log_size_bytes
2775 tmp=`dirname "$LOGFILE"`"/`basename $0`.$$.temp"
2778 # Verifico que el logfile no se pase del tamaño maximo
2781 tam=`stat -c '%s' "$LOGFILE"`
2784 # Si se paso del maximo dejo las ultimas 100 lineas
2787 if [ "$tam" -ge "$LOGSIZE" ]; then
2790 tail -n 100 "$LOGFILE" > "$tmp"
2793 mv "$tmp" "$LOGFILE"
2803 \begin_inset LatexCommand \label{sec:AFIMONIO_DAEMON.SH}
2813 Auxiliar, escrito en
2820 Justificación de su uso
2829 en segundo plano, desasociado de la terminal.
2835 Ninguno, toma los datos necesarios por la entrada estándar, aunque es común
2836 redireccionarle el archivo
2841 De la entrada estándar toma los códigos de origen y destino.
2842 Cada código debe encontrarse en una línea y al comienzo de ésta.
2843 Sólo toma los 2 primeros caracteres, e ignora el resto de la línea (para
2844 compatibilidad con el archivo oridesti.txt).
2854 (especificada por el usuario) de archivos con nombre y formato de
2858 en el directorio actual.
2859 Tanto el nombre como la cantidad de líneas y su contenido es generado aleatoria
2860 mente (respetando el formato mencionado y con valores racionales).
2866 La invocación es al estilo SysV, tomando como parámetro la acción a realizar,
2894 está corriendo o no.
2900 Al comienzo del script, abajo de
2904 , se pueden cambiar algunas variables:
2907 WAIT Cantidad de segundos a esperar para que arranque o se detenga
2913 antes de asumir un error.
2916 DAEMON Nombre del programa a ejecutar.
2917 Este programa es lo suficientemente genérico como para correr cualquier
2922 , por eso se provee una variable de configuración para cambiar el comando
2926 Ejemplos de invocación
2927 \layout Subsubsection
2931 ./afimonio_daemon.sh start
2941 \layout Subsubsection
2945 ./afimonio_daemon.sh stop
2955 \layout Subsubsection
2959 ./afimonio_daemon.sh status
2968 está corriendo lo indica con un mensaje y muestra su PID.
2969 Si no está corriendo da otro mensaje indicándolo.
2970 \layout Subsubsection
2974 ./afimonio_daemon.sh
2977 Da un mensaje de ayuda.
2999 # --------------- SCRIPT ---------------------
3002 BASE_DIR="$HOME/.antifraude"
3006 "$BASE_DIR/conf/$DAEMON.conf"
3018 perr "Parámetros válidos : start, stop, status"
3032 echo -n "Iniciando demonio '$DAEMON' en modo daemon "
3035 if is_lock "$DAEMON"; then
3041 perr "$DAEMON ya está corriendo"
3046 "(PID=`lock_pid $DAEMON`)."
3055 nohup "$AFIM_BINDIR/$DAEMON" > /dev/null &
3058 for i in `seq $WAIT`; do
3061 if is_lock "$DAEMON"; then
3064 echo " OK! (PID=`lock_pid $DAEMON`)"
3082 # Tardó más de 5 segundos en arrancar, algo anda mal...
3088 perr "$DAEMON tardó más de $WAIT segundos en arrancar,"
3094 "probablemente haya algún problema."
3106 echo -n "Parando el demonio '$DAEMON' "
3109 if ! is_lock "$DAEMON"; then
3115 perr "$DAEMON no esta corriendo."
3124 kill `lock_pid $DAEMON`
3127 for i in `seq $WAIT`; do
3130 if ! is_lock "$DAEMON"; then
3151 # Tardó más de 5 segundos en parar, algo anda mal...
3157 perr "$DAEMON tardó más de $WAIT segundos en parar,"
3162 "probablemente haya algún problema."
3174 if is_lock "$DAEMON"; then
3177 echo "$DAEMON está corriendo actualmente"
3182 "(PID=`lock_pid $DAEMON`)."
3188 echo "$DAEMON no está corriendo."
3209 Auxiliar, escrito en
3216 Justificación de su uso
3219 Sirve para realizar lotes de prueba con gran cantidad de entradas y variaciones
3220 de forma rápida y cómoda.
3226 Ninguno, toma los datos necesarios por la entrada estándar, aunque es común
3227 redireccionarle el archivo
3232 De la entrada estándar toma los códigos de origen y destino.
3233 Cada código debe encontrarse en una línea y al comienzo de ésta.
3234 Sólo toma los 2 primeros caracteres, e ignora el resto de la línea (para
3235 compatibilidad con el archivo oridesti.txt).
3245 (especificada por el usuario) de archivos con nombre y formato de
3249 en el directorio actual.
3250 Tanto el nombre como la cantidad de líneas y su contenido es generado aleatoria
3251 mente (respetando el formato mencionado y con valores racionales).
3257 El comando toma 3 parámetros
3264 ./callgen [cant_archivos [min_lineas [max_lineas]]]
3268 \begin_inset Tabular
3269 <lyxtabular version="3" rows="4" columns="3">
3271 <column alignment="center" valignment="top" leftline="true" width="0">
3272 <column alignment="center" valignment="top" leftline="true" width="0">
3273 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
3274 <row topline="true" bottomline="true">
3275 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3285 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3295 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3306 <row topline="true">
3307 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3315 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3320 Cantidad de archivos a generar
3323 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3332 <row topline="true">
3333 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3341 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3346 Mínima cantidad de lineas en un archivo
3349 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3358 <row topline="true" bottomline="true">
3359 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3367 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3372 Máxima cantidad de lineas en un archivo
3375 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3394 Pueden cambiarse los valores por defecto editando el código fuente del comando,
3395 en la sección de configuración que se encuentra al comienzo del mismo.
3396 También puede cambiarse el mínimo y máximo año (por defecto 1999 y 2004)
3397 y el mínimo y máximo código de central (por defecto 0000 y 9999).
3400 Ejemplos de invocación
3401 \layout Subsubsection
3410 Se escriben por entrada estándar los códigos de origen/destino, se presiona
3417 para cerrar el descriptor de archivo de la entrada estándar y se generan
3418 10 archivos con entre 1000 y 5000 líneas cada uno.
3419 \layout Subsubsection
3423 ./callgen 2 < oridesti.txt
3428 Genera 2 archivos con entre 1000 y 5000 líneas cada uno tomando los códigos
3429 de origen/destino del archivo
3434 \layout Subsubsection
3438 ./callgen 5 10 < oridesti.txt
3443 Genera 5 archivos con entre 10 y 5000 líneas cada uno tomando los códigos
3444 de origen/destino del archivo
3449 \layout Subsubsection
3453 ./callgen 50 10 50 < oridesti.txt
3458 Genera 50 archivos con entre 10 y 50 líneas cada uno tomando los códigos
3459 de origen/destino del archivo
3475 # Generador aleatorio de archivos de llamadas
3481 # Leandro Lucarella - dom oct 17 18:37:05 ART 2004
3487 # Bajo licencia GPL.
3496 # ./callgen [cant_archivos [min_lineas [max_lineas]]]
3502 # cant_archivos Cantidad de archivos a generar.
3505 # min_lines Mínima cantidad de líneas que puede tener un archivo.
3508 # max_lines Máxima cantidad de líneas que puede tener un archivo.
3514 # Por la entrada estándar debe recibir los códigos de países para
3517 # origen y/o destino.
3518 Toma los dos primeros caracteres por línea como
3521 # un código, ignorando el resto, de manera que se puede hacer:
3524 # cat oridesti.txt | ./gencall
3553 #{{{ Variables globales
3556 our @codes; # Códigos de origen/destino
3569 #{{{ load_codes() - Obtiene códigos de origen/destino de la entrada
3584 push(@codes, substr($_, 0, 2)) while (<STDIN>);
3595 #{{{ get_rnd_code() - Obtiene un códigos de origen/destino al azar
3598 # Uso: get_rnd_code()
3610 return $codes[rnd($cant-1)];
3621 #{{{ rnd() - Genera números aleatorios
3624 # Uso: rnd(MAX) - genera número de 0 a MAX (inclusive)
3627 # rnd(MIN, MAX) - genera número de MIN a MAX (inclusive)
3633 # Nota: respeta el tamaño del campo más chico, es decir, si se usa
3636 # rnd 01 250, el número siempre tendrá al menos 2 dígitos
3639 # rellenados con ceros, como 04, 28, 123, 08, etc
3648 my ($ini, $fin) = @_;
3666 return sprintf('%0'.length($ini).'d', $ini + rand()
3669 * ($fin - $ini + 1));
3680 #{{{ Tipos de campos
3683 sub aaaa() { return rnd($MIN_ANIO, $MAX_ANIO); } # año
3686 sub mm() { return rnd("01", 12); } # mes
3689 sub dd() { return rnd("01", 28); } # día
3692 sub hh() { return rnd("00", 23); } # hora
3695 sub MM() { return rnd("00", 59); } # minutos
3698 # código de central telefónica
3701 sub DDDD() { return rnd($MIN_COD, $MAX_COD); }
3704 # caracter aleatorio
3707 sub char() { return chr(rnd(65, 90)); }
3715 #{{{ line() - Genera una línea del archivo
3724 my $f_linea = rnd(100000, 99999999);
3727 my $f_minutos = rnd(1, 150);
3730 my $f_fecha = aaaa().mm().dd();
3733 my $f_hora = dd().hh().MM();
3736 my ($f_tipo, $f_orig, $f_dest) = ('', '', '');
3748 $f_orig = get_rnd_code();
3763 $f_dest = get_rnd_code();
3769 my $f_prest = char().char().char().char().char().
3772 char().char().char().char();
3775 return "$f_linea;$f_minutos;$f_fecha;$f_hora;".
3778 "$f_tipo;$f_dest;$f_orig;$f_prest";
3789 #{{{ gen() - Genera un archivo con entre MIN y MAX llamadas
3792 # Uso: gen(MIN, MAX)
3801 my ($ini, $fin) = @_;
3804 my $file = aaaa().mm().dd().hh().MM().'.'.DDDD();
3807 # Mientras exista uno, buscamos un nuevo nombre.
3810 $file = aaaa().mm().dd().hh().MM().'.'.DDDD()
3819 or die("No puedo abrir el archivo $file!
3824 for (my $i = rnd($ini, $fin); $i > 0; --$i)
3857 my $cant = $ARGV[0] ? $ARGV[0] : $CANT_ARCHS;
3863 for (my $i = 0; $i < $cant; ++$i)
3869 gen($ARGV[1] ? $ARGV[1] : $MIN_LINEAS,
3872 $ARGV[2] ? $ARGV[2] : $MAX_LINEAS);
3883 # vim: set fdm=marker ts=4 sw=4 :
3889 Archivos del Enunciado
3897 Los archivos de log generados por los distintos comandos, presentan todos
3898 la misma estructura de registro que se detalla a continuación:
3900 YYYYMMDD-hhmm $usuario $comando: ¨$Mensaje¨
3908 En este archivo se tienen los origenes y destinos en base a los cuales hemos
3909 generados los archivos de llamada y los umbrales.
3913 \begin_inset Float table
3922 Estructura de oridesti.txt
3926 \begin_inset Tabular
3927 <lyxtabular version="3" rows="2" columns="2">
3929 <column alignment="center" valignment="top" leftline="true" width="0">
3930 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
3931 <row topline="true" bottomline="true">
3932 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3940 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3949 <row topline="true" bottomline="true">
3950 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3958 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3982 Este archivo posee los umbrales de llamadas de los cuales se valdra el antifraud
3983 e.pl para emitir o no alarmas durante el proceso de los archivos de llamadas.
3987 \begin_inset Float table
3996 Estructura de umbrales.param
4000 \begin_inset Tabular
4001 <lyxtabular version="3" rows="8" columns="2">
4003 <column alignment="center" valignment="top" leftline="true" width="0">
4004 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4005 <row topline="true" bottomline="true">
4006 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4014 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4019 N caracteres, número secuencial >= 1
4023 <row topline="true">
4024 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4032 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4037 N caracteres, Numérico
4041 <row topline="true">
4042 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4050 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4055 2 caracteres, valores posibles segun oridesti.txt
4059 <row topline="true">
4060 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4068 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4073 1 caracter, E = Entrante, S = Salida
4077 <row topline="true">
4078 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4086 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4091 1 caracter, A = Activo, I = Inactivo
4095 <row topline="true">
4096 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4104 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4109 N caracteres = login del user que graba el reg
4113 <row topline="true">
4114 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4122 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4127 8 caracteres, formato aaaammdd
4131 <row topline="true" bottomline="true">
4132 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4140 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4145 6 caracteres, formato hhmmss, hora actual
4161 <archivo de llamada>
4164 Estos archivos son los que el antifraude procesará en busca de matchs contra
4169 \begin_inset Float table
4178 Estructura de un archivo de llamadas
4182 \begin_inset Tabular
4183 <lyxtabular version="3" rows="8" columns="2">
4185 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4186 <column alignment="center" valignment="top" rightline="true" width="0">
4187 <row topline="true" bottomline="true">
4188 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4196 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4201 N caracteres, Numérico
4205 <row topline="true">
4206 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4214 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4219 N caracteres, Numérico
4223 <row topline="true">
4224 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4232 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4237 8 caracteres, formato aaaammdd
4241 <row topline="true">
4242 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4250 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4255 6 caracteres, formato hhmmss
4259 <row topline="true">
4260 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4268 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4273 1 carácter, E = Entrante, S = Salida
4277 <row topline="true">
4278 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4286 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4291 2 caracteres, solo informado en llamadas salientes
4295 <row topline="true">
4296 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4304 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4309 2 caracteres, solo informado en llamadas entrantes
4313 <row topline="true">
4314 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4322 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4346 En este archivo el antifraude irá dejando registro de las alarmas emitidas
4347 en base a registros que han tenido un match contra los umbrales.
4351 \begin_inset Float table
4360 Estructura de alarmas.txt
4364 \begin_inset Tabular
4365 <lyxtabular version="3" rows="10" columns="2">
4367 <column alignment="center" valignment="top" leftline="true" width="0">
4368 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4369 <row topline="true" bottomline="true">
4370 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4378 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4383 N caracteres, campo 'Prestadora', archivo de llamadas
4387 <row topline="true">
4388 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4396 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4401 4 caracteres, obtenido a partir del archivo de llamadas
4405 <row topline="true">
4406 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4414 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4419 N caracteres, campo 'Numero de Linea' , archivo de llamadas
4423 <row topline="true">
4424 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4432 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4437 N caracteres, campo 'Cant de Minutos', archivo de llamadas
4441 <row topline="true">
4442 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4450 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4455 N caracteres, campo 'Id de registro', umbrales.param
4459 <row topline="true">
4460 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4468 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4473 8 caracteres, campo 'Fecha de llamada', archivo de llamadas
4477 <row topline="true">
4478 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4486 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4491 6 caracteres, campo 'Hora de llamada', archivo de llamadas
4495 <row topline="true">
4496 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4504 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4509 N caracteres, siempre login del usuario que graba el reg
4513 <row topline="true">
4514 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4522 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4527 8 caracteres, formato aaaammdd, fecha actual
4531 <row topline="true" bottomline="true">
4532 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4540 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4545 6 caracteres formato hhmmss, hora actual
4567 El archivo de configuración
4569 ~/.antifraude/conf/afimonio.conf
4571 almacena las rutas a los directorios necesarios para la ejecución del script
4576 y la ruta, nombre, y tamaño máximo del archivo de log.
4585 El archivo de configuración
4587 ~/.antifraude/conf/antifraude.conf
4589 almacena las rutas a los directorios necesarios para la ejecución del script
4594 y la ruta, nombre, y tamaño máximo del archivo de log.
4603 El archivo de configuración
4605 ~/.antifraude/conf/aficonf.conf
4607 almacena las rutas a los directorios necesarios para la ejecución del script
4612 y la ruta, nombre, y tamaño máximo del archivo de log.
4616 Estos archivos fueron creados para que los diferentes scripts tengan un
4617 lugar común donde buscar esa información para salvar el problema comentado
4619 \begin_inset LatexCommand \vref{sec:Problemas-relevantes}
4633 Para probar el comportamiento del sistema, se preparo un set de prueba distribui
4638 , situado en el directorio
4642 , del paquete de instalación.
4643 El set de prueba se copia automáticamente en el momento en que se instale
4650 , dejando el escenario listo para procesarlos en el momento en que sea arrancado
4658 o bien ejecutando el
4667 Este set de prueba consta de
4671 , que se detallan a continuación:
4674 14 archivos de llamadas generados con el
4680 , con entre 1000 y 5000 registros cada uno, y fecha en el rango año 1999
4684 1 archivo de llamadas con registros válidos y otros no válidos.
4687 1 archivo con nombre válido según el formato YYYYMMDDhhmm.nnnn, pero con
4688 contenido inválido, el cual es rechazado por
4697 1 archivo con nombre no válido rechazado en instancia previa por
4706 Se describen en la siguiente tabla, los archivos y registros que disparan
4707 alarmas o tienen close matches contra los 25 umbrales distribuidos en el
4708 paquete de instalación, vía el umbrales.param:
4712 \begin_inset Float table
4721 Archivos y Registros que disparan alarmas
4725 \begin_inset Tabular
4726 <lyxtabular version="3" rows="24" columns="3">
4728 <column alignment="center" valignment="top" leftline="true" width="0">
4729 <column alignment="center" valignment="top" leftline="true" width="0">
4730 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4731 <row topline="true" bottomline="true">
4732 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4742 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4753 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4764 <row topline="true">
4765 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4773 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4781 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4790 <row topline="true">
4791 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4799 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4807 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4816 <row topline="true">
4817 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4825 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4833 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4842 <row topline="true">
4843 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4851 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4859 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4868 <row topline="true">
4869 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4877 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4885 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4894 <row topline="true">
4895 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4903 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4911 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4920 <row topline="true">
4921 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4929 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4937 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4946 <row topline="true">
4947 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4955 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4963 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4972 <row topline="true">
4973 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4981 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4989 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4998 <row topline="true">
4999 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5007 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5015 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5024 <row topline="true">
5025 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5033 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5041 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5050 <row topline="true">
5051 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5059 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5067 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5076 <row topline="true">
5077 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5085 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5093 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5102 <row topline="true">
5103 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5111 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5119 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5128 <row topline="true">
5129 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5137 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5145 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5154 <row topline="true">
5155 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5163 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5171 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5180 <row topline="true">
5181 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5189 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5197 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5206 <row topline="true">
5207 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5215 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5223 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5232 <row topline="true">
5233 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5241 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5249 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5258 <row topline="true">
5259 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5267 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5275 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5280 21 (umbral inactivo => no emite alarma)
5284 <row topline="true">
5285 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5293 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5301 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5306 Close match umbral 22, difiere tipo de llamada
5310 <row topline="true">
5311 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5319 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5327 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5336 <row topline="true" bottomline="true">
5337 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5345 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5353 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5358 25 (umbral inactivo => no emite alarma)
5370 \layout Subsubsection
5379 Posee registros no válidos detallados a continuación.
5380 Los registros se contabilizan de 0 a N (Línea 1 = Reg 0)
5383 Registro\SpecialChar ~
5393 Registro\SpecialChar ~
5403 Registro\SpecialChar ~
5408 Posee un tipo de llamada
5415 Registro\SpecialChar ~
5420 El número de línea (campo1) no es numérico, es un string
5425 Registro\SpecialChar ~
5430 Tiene cantidad de campos insuficiente (siete)
5433 Estos registros emitirán errores plasmados en el
5438 Para verificar esto, realizar una búsqueda en el log, sobre el nombre del
5439 archivo, y ubicarse en el sector donde se indica el comienzo del procesamiento
5442 Inicio proceso de: 199908220733.4515
5445 \layout Subsubsection
5454 Es un archivo de texto el cual pasa el control de Afimonio, pero luego sus
5455 lineas son descartadas por antifraude y dicho error emitido en el antifraude.log
5456 \layout Subsubsection
5465 El nombre del archivo no es conforme al formato de nombre estipulado en
5466 el TP y el mismo es rechazado de antemano por
5478 Esto deberia ser una hoja aparte que solo diga 1.6 Apéndice A) y las hojas
5479 posteriores son las páginas 3 en adelante del PDF oficial de la catedra,
5480 sacando la parte de archivos.
5481 3-15 más precisamente es lo que iria.