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
218 y seguir los pasos que se le indiquen a continuación.
219 De no ejecutar apropiadamente la instalación, no se garantiza el correcto
220 funcionamiento de los componentes.
224 Comandos Desarrollados
241 Procesa los archivos que se encuentran en el directorio
243 $PATH_ANTIFRAUDE/$DATADIR/aprocesar
247 $PATH_ANTIFRAUDE/$DATADIR/enproce
264 El afimonio genera una salida al archivo
268 la cual contiene información sobre la ejecución del programa.
271 Si un archivo es válido, se añade una línea con el siguiente formato:
274 $fecha $USER afimonio: "Se detecta archivo de llamadas $file"
277 Si el archivo tuviera un nombre inválido, la línea seria la siguiente:
280 $fecha $USER afimonio: "Se rechaza el archivo $file"
290 fecha actual con formato Día-Mes-Año-Hora:Minuto.
297 nombre de usuario que ejecuto el script.
304 nombre del archivo que se procesó.
307 Ejemplos de invocación
308 \layout Subsubsection
315 Corre el programa en primer plano.
316 \layout Subsubsection
323 Corre el programa en segundo plano, evitando que se cierre al morir el padre
324 desasociándolo de la terminal.
325 La salida del programa queda en el archivo
329 a menos que se redirija a otro archivo.
340 BASE_DIR=$HOME/.antifraude
345 # uso las funciones de util.sh
349 "$HOME/.antifraude/util.sh"
353 "$HOME/.antifraude/conf/afimonio.conf"
357 "$HOME/.antifraude/conf/antifraude.conf"
362 # Es llamada por los trap para deslockear el afimonio
377 # filtra el nombre del archivo pasado por parametro sacandole
380 # todos los caracteres que no sean numeros
386 date=`echo $1 | cut -d "." -f 1`
389 central=`echo $1 | cut -d "." -f 2`
392 validar_solo_numeros "$date"
395 if [ "$?" -ne 0 ]; then
407 validar_rango "$mes" "1" "12"
410 if [ "$?" -ne 0 ]; then
422 validar_rango "$dia" "1" "31"
425 if [ "$?" -ne 0 ]; then
437 validar_rango "$hora" "0" "23"
440 if [ "$?" -ne 0 ]; then
452 validar_rango "$min" "0" "59"
455 if [ "$?" -ne 0 ]; then
464 validar_solo_numeros "$central"
467 if [ "$?" -ne 0 ]; then
482 #--------------------MAIN SCRIPT----------------------
485 # Recupero las rutas a todos los directorios y archivos
488 # que necesito del antifraude
491 DATADIR=$ANTI_DATADIR
494 SOURCEDIR=$DATADIR/aprocesar/
497 ACEPTDIR=$DATADIR/enproceso/
500 REJECTDIR=$DATADIR/rechazadas/
512 LOGNAME=$AFIM_LOGFILE
515 LOGFILE=$LOGDIR/$LOGNAME
518 # Capturo señales para salir bien (liberando el lock)
530 lock "afimonio" || die "No se puede correr, hay otra
535 instancia corriendo o no se puede crear el lock file!"
538 # Comienza el ciclo infinito que mueve los archivos
547 for file in `ls $SOURCEDIR` ; do
556 if [ "$?" -eq 0 ]; then
559 mv "$SOURCEDIR$file" "$ACEPTDIR"
562 fecha=$(date +%d/%m/%Y-%H:%M)
565 echo "$fecha $USER afimonio:
572 "archivo de llamadas $file
580 mv "$SOURCEDIR$file" "$REJECTDIR"
583 fecha=$(date +%d/%m/%Y-%H:%M)
586 echo "$fecha $USER afimonio:
601 clean_log "$LOGFILE" "$AFIM_LOGSIZE"
607 # me fijo si el antifraude esta corriendo y si no lo esta
613 if [ -n $files ] && ! is_lock "antifraude.pl"; then
616 $BINDIR/antifraude.pl &
640 Procesa los archivos de llamadas que encuentre en el momento de invocación
643 $PATH_ANTIFRAUDE/$DATADIR/enproceso
652 será quien alimentará al
658 con dichos archivos, no obstante se lo puede alimentar con archivos de
659 llamadas en forma manual, situándolos en el directorio anteriormente descripto.
662 Este comando, en el momento de invocacion genera y guarda internamente un
663 listado de los archivos de llamadas presences en el directorio
667 , ordenándolos por fecha (establecida en el nombre del archivo) en forma
669 Dado que utiliza durante toda su ejecución esta lista interna, el
675 puede alimentar al directorio
679 con nuevos archivos mientras el
685 corre, pero los mismos no serán tenidos en cuenta (esto es, procesados),
686 hasta la próxima invocación del comando.
696 En este archivo se guarda información del procesamiento de los registros,
697 advertencias provocados por registros no validos y alarmas emitidas por
698 registros que cumplen con un umbral.
705 En este archivo se guarda información de las alarmas provocadas por registros
706 en los archivos de llamadas, que hayan cumplido un umbral determinado del
714 Ejemplos de invocación
715 \layout Subsubsection
722 El programa procesa las llamadas
726 como indica el enunciado en primer plano.
727 \layout Subsubsection
735 \layout Subsubsection
742 Ídem anterior pero procesa en segundo plano.
754 if ( -e "$ENV{'HOME'}/.antifraude/lock/antifraude.pid" ) {
757 # Lock file encontrado
778 unlink ("$ENV{'HOME'}/.antifraude/lock/antifraude.pid");
790 local $lfile = "$ENV{'HOME'}/.antifraude/lock/antifraude.pid";
793 open(LOCKFILE,">>$lfile");
814 # Comparador de fecha para los archivos de llamada
820 ($year1,$mon1,$day1,$hr1,$min1) =
823 $a =~ /([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/;
826 ($year2,$mon2,$day2,$hr2,$min2) =
829 $b =~ /([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/;
838 if ($year1 > $year2) { return 1; }
841 elsif ($year1 < $year2) { return -1; }
847 if ($mon1 > $mon2) { return 1; }
850 elsif ($mon1 < $mon2) { return -1; }
853 # Calculo minutos de lo restante
856 $totalmin1 = ($day1 * 24 * 60) + ($hr1 * 60) + $min1;
859 $totalmin2 = ($day2 * 24 * 60) + ($hr2 * 60) + $min2;
862 if ($totalmin1 > $totalmin2) { return 1; }
865 elsif ($totalmin1 < $totalmin2) { return -1; }
874 # Devuelve un listado de archivos de llamada y ordenado por fecha ASC
880 # Obtengo listado de archivos de llamadas y lo ordeno por fecha
883 opendir($DIR,"$CONFDATA{datadir}/enproceso")
886 or die 'Could not open dir';
889 # Valido solo fisicamente, lo logico ya valido afimonio..
892 @files = grep {/[0-9]{12}
897 && -f "$CONFDATA{datadir}/enproceso/$_"} readdir($DIR);
900 @sortedfiles = sort byDate @files;
912 # Levanta una variable del archivo AFINSTAL.CONF
918 $CONFIGFILE = shift(@_);
921 my $linenumber = shift(@_);
927 or die "No se pudo abrir el archivo $CONFIGFILE";
930 do { $line = <CONFIGFILE> } until $.
940 ($confvar = $line) =~ s/"(.*)"$/$1/;
943 $confvar =~ s/^.*=//;
952 # Agrega un log entry al logfile del antifraude.pl
958 my $logentry = shift(@_);
961 my $consoleout = shift(@_);
964 my $log = "$CONFDATA{logdir}/$CONFDATA{logfile}";
967 # Fetch date and Format it
970 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
996 $year += 1900; ++$mon;
999 $user = "$ENV{USER}";
1002 $commonstring = "$mday/$mon/$year-$hour:$min $user antifraude:";
1008 open(LOGFILE,">>$log")
1011 or die "No se pudo abrir el archivo de log";
1017 print LOGFILE "$commonstring
1026 $filesize = tell(LOGFILE);
1032 # Chequeo el logsize y su lo supero me quedo con 100 lineas
1035 if ($filesize > $CONFDATA{logsize})
1041 open(LOGFILE,"+<$log");
1044 do ($line = <LOGFILE>) until $.
1048 truncate(LOGFILE,tell(LOGFILE));
1057 if ($consoleout) { print("$logentry
1068 my $callreg = shift(@_);
1071 my $numreg = shift(@_);
1074 logEntry("El siguiente registro de llamada tiene format ".
1082 print("Warning: El registro de llamada $numreg tiene ".
1099 local(*callfields) = $_[0];
1102 my $callsfile = $_[1];
1105 my $matchedUmbral = 0;
1111 while (($i <= $#UMBRALES) && ($matchedUmbral == 0)) {
1114 $umbral = $UMBRALES[$i];
1120 ($regid,$phoneline,$oridest,$type,$state)
1123 = split(';',$umbral);
1126 if (($state eq 'A') && ($callfields[0] == $phoneline)
1129 && ($callfields[4] eq $type)) {
1132 # Si es Saliente y coincide el Destino con el
1135 # Ori/Dest del umbral
1141 && ($callfields[5] eq $oridest)) {
1144 $matchedUmbral = $regid;
1153 && ($callfields[6] eq $oridest)) {
1156 $matchedUmbral = $regid;
1171 # Si se matcheo un umbral, grabo una alarma y aviso por consola
1174 if ($matchedUmbral > 0) {
1177 # Obtengo algunos datos
1180 ($central = $callsfile) =~ s/^.*
1185 $user = "$ENV{USER}";
1188 # Fetch date and Format it
1191 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
1197 $year += 1900; ++$mon;
1225 $user = "$ENV{USER}";
1228 $date = "${year}${mon}${mday}";
1231 $time = "${hour}${min}${sec}";
1234 # Preparo el registro de alarma
1237 $alarmEntry = "$callfields[7];$central;$callfields[0];".
1240 "$callfields[1];$regid;$callfields[2];".
1243 "$callfields[3];$user;$date;$time";
1246 # Grabamos el registro en el archivo de alarmas
1249 $alarmlog = "$CONFDATA{datadir}/alarmas/alarmas.txt";
1252 open(ALARMFILE,">>$alarmlog")
1255 or die 'No se pudo abrir el archivo de alarmas';
1258 seek(ALARMFILE,0,2);
1261 print ALARMFILE "$alarmEntry
1269 # Logeo por consola y logfile que hubo una alarma
1272 logEntry("Alarma: Se ha matcheado el registro procesado"
1275 ." con el umbral nro $matchedUmbral",1);
1284 # --------- MAIN CODE -------- #
1290 if (is_lock()) { exit 1; }
1296 # Defino some GLOBALS
1299 $CONFDIR = "$ENV{'HOME'}/.antifraude";
1302 $CONFDATA{logdir} = getConfVar("$CONFDIR/conf/antifraude.conf",2);
1305 $CONFDATA{logfile} = getConfVar("$CONFDIR/conf/antifraude.conf",3);
1308 $CONFDATA{logsize} = getConfVar("$CONFDIR/conf/antifraude.conf",4);
1311 $CONFDATA{datadir} = getConfVar("$CONFDIR/conf/antifraude.conf",5);
1314 # Cargo los UMBRALES en memoria
1317 open(PARAMFILE,"$CONFDIR/umbrales.param") or die "No se pudo abrir el "
1320 ."archivo de umbrales";
1323 @UMBRALES = <PARAMFILE>;
1329 # Proceso los archivos de llamadas
1332 @archivos = getCallFiles();
1335 FILE: foreach $filename (@archivos) {
1341 $CALLFILE = "$CONFDATA{datadir}/enproceso/$filename";
1344 logEntry("Inicio proceso de: $filename",1);
1350 or ((warn "No se pudo abrir archivo $filename"),next FILE);
1353 REG: foreach $callreg (<CALLFILE>) {
1356 logEntry("Procesando Reg: $regnum | Archivo: $filename",1);
1362 $fieldcount = split(';',$callreg);
1368 # Si no tengo 8 campos exactamente, invalido
1371 if ($fieldcount != 8)
1377 badCall($callreg,$regnum);
1386 # Si la linea no es un numero, invalido
1398 if (!($fields[0] =~ /^
1406 badCall($callreg,$regnum);
1415 # Si tipo llamada ! E|S o no se informa Origen
1418 # o Destino, invalido
1421 if (($fields[4] ne 'E') && ($fields[4] ne 'S')) {
1424 badCall($callreg,$regnum); next REG;
1430 if (($fields[4] eq 'E') && ($fields[6] eq "")) {
1433 badCall($callreg,$regnum); next REG;
1439 if (($fields[4] eq 'S') && ($fields[5] eq "")) {
1442 badCall($callreg,$regnum); next REG;
1448 # Ya pase todas las validaciones, ahora busco si
1454 checkUmbrales(*fields,$filename);
1457 } continue { ++$regnum }
1463 # La muevo al directorio de procesadas
1466 rename $CALLFILE,"$CONFDATA{datadir}/procesadas/$filename";
1469 logEntry("Fin proceso de: $filename",1);
1493 El comando utiliza los archivos
1504 \layout Subsubsection
1513 de ser solicitado por el usuario, ya sea por la alta o baja de un umbral.
1516 Ejemplos de invocación
1517 \layout Subsubsection
1524 Realiza lo pedido en el enunciado.
1544 BASE_DIR="$HOME/.antifraude"
1553 "$BASE_DIR/conf/aficonf.conf"
1568 LOGNAME=$AFIC_LOGFILE
1571 LOGFILE=$LOGDIR/$LOGNAME
1576 #Valida que exista el pais
1582 # $1 = Descripcion a buscar
1585 # $2 = Variable donde guardar el código del Pais
1588 # en caso de existir
1594 EXISTE=`cat "$BASE_DIR/oridesti.txt"
1599 | egrep "^[A-Z]*;$1" | cut -d ';' -f 1`;
1602 if [ "$EXISTE" != "" ] ; then
1605 #Exite!, debo gaurdar el código
1625 poner_estado_umbral () {
1634 FECHA=`date +"%Y%m%d"`
1637 HORA=`date +"%H%M%S"`
1643 if [ "$ESTADO" != "A" ] && [ "$ESTADO" != "I" ]
1657 (;[^;]*;[^;]*;[^;]*;
1670 1I;$USER;$FECHA;$HORA/"
1675 "$BASE_DIR/umbrales.param"`
1678 echo "$SALIDA" > "$BASE_DIR/umbrales.param"
1681 put_log "$LOGFILE" "aficonf"
1686 "Se ha cambiado el estado de umbral $ID a $ESTADO"
1720 preguntar "Su opción" "123" $1
1731 EXISTE=`cat "$BASE_DIR/umbrales.param" | egrep "$1"`;
1734 if [ "$EXISTE" == "" ] ; then
1746 #Ya existe un umbral!
1758 buscar_id_umbral () {
1761 ID=`cat "$BASE_DIR/umbrales.id"`;
1770 echo "$ID" > "$BASE_DIR/umbrales.id"
1782 while [ $DONE == 0 ] ; do
1785 leer "Número de línea" "" LINEA
1791 if ! validar_solo_numeros "$LINEA" ; then
1794 echo "EL NUMERO TE LINEA SOLO DEBE"
1811 if [ "$LINEA" == "" ] ; then
1823 preguntar "Tipo de llamada" "ES" TIPO
1832 while [ $DONE == 0 ] ; do
1835 leer "Pais (descripción)" "" PAIS
1838 if ! existe_pais "$PAIS" CODIGO ; then
1841 echo "No existe el país de descrición '$PAIS'"
1853 if [ "$PAIS" == "" ] ; then
1865 echo "El código de '$PAIS' es '$CODIGO'"
1871 # Verifico que el umbral no exista
1874 FECHA=`date +"%Y%m%d"`
1877 HORA=`date +"%H%M%S"`
1880 UMBRAL="$LINEA;$PAIS;$TIPO;A;*;*;*"
1883 if existe_umbral "$UMBRAL" ; then
1886 echo "Ya existe un umbral con los datos ingresados."
1892 put_log "$LOGFILE" "aficonf"
1897 "Se trató de insertar un umbral repetido ($UMBRAL)"
1920 UMBRAL="$ID;$LINEA;$PAIS;$TIPO;A;$USER;$FECHA;$HORA"
1926 echo "$UMBRAL" >> "$BASE_DIR/umbrales.param"
1932 echo "El Umbral fue grabado con éxito"
1943 "aficonf" "Se inserto un nuevo umbral ($UMBRAL)"
1960 while [ $DONE == 0 ] ; do
1963 leer "Número de línea" "" LINEA
1969 if ! validar_solo_numeros "$LINEA" ; then
1972 echo "EL NUMERO TE LINEA SOLO DEBE"
1989 if [ "$LINEA" == "" ] ; then
2001 DATOS=`cat "$BASE_DIR/umbrales.param"
2006 | grep "[0-9]*;$LINEA;[A-Z]*;[E,S];A"`
2009 if [ "$DATOS" == "" ] ; then
2015 echo "No se han encontrado Umbrales activos"
2020 "para la linea $LINEA."
2023 echo "Abortando ..."
2029 put_log "$LOGFILE" "aficonf"
2034 "No se han encontrado umbrales para la línea $LINEA"
2048 printf "%3s %2s %1s %1s %10s%8s %6s
2055 "ID" "Ciudad" "Tipo" "Estado" "Usuario" "Fecha" "Hora"
2061 for i in $DATOS ; do
2064 ID=`echo "$i" | cut -d ';' -f 1`
2067 CIUDAD=`echo "$i" | cut -d ';' -f 3`
2070 TIPO=`echo "$i" | cut -d ';' -f 4`
2073 ESTADO=`echo "$i" | cut -d ';' -f 5`
2076 USUARIO=`echo "$i" | cut -d ';' -f 6`
2079 FECHA=`echo "$i" | cut -d ';' -f 7`
2082 HORA=`echo "$i" | cut -d ';' -f 8`
2090 "%3s %2s %1s %1s %10s %8s %6s
2097 "$ID" "$CIUDAD" "$TIPO" "$ESTADO" "$USUARIO"
2105 OPCIONES="$OPCIONES $ID"
2111 preguntar "Cual desea borrar (-1 para salir)" "$OPCIONES" OPT
2114 if [ "$OPT" = "-1" ] ; then
2123 echo "Borrando el registro $OPT ..."
2126 poner_estado_umbral "$OPT" "I"
2129 put_log "$LOGFILE" "aficonf"
2134 "No se ha eliminado elumbral de ID $OPT" "$AFIC_LOGSIZE"
2143 echo "El Umbral fue eliminado con éxito"
2154 # No permito correr 2 instancias de AFICONF
2157 if is_lock "aficonf" ; then
2163 echo "Aficonf está corriendo actualmente."
2169 put_log "$LOGFILE" "aficonf"
2174 "Se ha intentado ejecutar aficonf cuando este estaba corriendo"
2198 while [ "$OPT" != "3" ] ; do
2228 Auxiliar, escrito en bash.
2231 Sería equivalente a una biblioteca compartida, no es exactamente un comando
2232 que se pueda ejecutar directamente sino que se incluye desde otros comandos.
2235 Justificación de su uso
2238 Es un archivo con varias funciones generales, sirve para no duplicar código
2239 común entre los varios scripts de bash.
2245 Al ser de propósito general, no tiene ningún archivo de input específico,
2246 aunque hay funciones que utilizan archivos, no se describen aquí sino en
2247 los comandos que usan este archivo.
2259 Al no ser un comando ejecutable, no aplica.
2268 Ejemplos de invocación
2283 # Los scrips que incluyan deben definir BASE_DIR
2286 # antes de incluirme!
2291 LOCK_DIR="$BASE_DIR/lock"
2294 # Lee del teclado un valor
2303 # $1 = Leyeda a mostrar de pregunta
2306 # $2 = Valor default por si el usuario no ingresa nada
2309 # $3 = Variable donde guardar el valor ingresado (o el default)
2324 read -p "$MSG [$DEFAULT] : " ALGO
2327 # Si el usuario no ingresa nada
2330 # nos quedamos con el valor default
2333 if [ ! -z "$ALGO" ] ; then
2353 # Realiza una pregunta al usuario
2362 # $1 = Leyeda a mostrar de preguntar
2365 # $2 = string con las opciones validas
2368 # $3 = Variable donde guardar el valor ingresado
2371 # $4 = Valor por defecto si se apreta ENTER
2392 read -p "$PREGUNTA [$OPCIONES]: " RTA
2395 # Si me pasaron un default y la respuesta es vacía
2398 if [ -n "$DEFAULT" -a -z "$RTA" ]; then
2413 # Escapeo el caracter '-' por '
2418 RTA=$(echo $RTA | sed "s/
2429 IS_OK=`echo "$OPCIONES" | grep "$RTA"`
2432 if [ ! -z "$IS_OK" ] && [ ! -z "$RTA" ] ; then
2452 validar_solo_numeros () {
2455 TEST=`echo "$1" | sed "s/[0-9]*//g"`
2458 if [ "$TEST" == "" ] ; then
2461 #Ok, son solo numeros
2470 # ups, hay algo que no es un numero
2481 # Crea un archivo de lock para un script
2484 # Devuelve: 0 si ok, 1 si ya esta lockeado, 2 si no pudo crear lock.
2487 # Uso: lock programa
2493 # si ya esta loqueado, no lo vuelvo a crear
2496 is_lock "$1" && return 1
2499 # Si no puedo escribir en el dir de lock, da error
2502 [ -w "$LOCK_DIR" ] || return 2
2505 echo $$ > "$LOCK_DIR/$1.pid"
2516 # Desbloquea el script
2519 # Uso: unlock programa
2525 rm -rf "$LOCK_DIR/$1.pid"
2534 # Consulta si un script esta lockeado
2537 # Uso: is_lock programa
2543 if [ -e "$LOCK_DIR/$1.pid" ] ; then
2546 # Lock file encontrado!
2566 # Obtiene el pid de un programa lockeado
2569 # Uso: lock_pid programa
2578 is_lock "$1" && cat "$LOCK_DIR/$1.pid"
2586 # Verifica que un valor este entre otros 2
2589 # $1 pertecezca a [$2,$3]
2592 # $1 Numero a validar
2604 if [ "$1" -ge "$2" ] && [ "$1" -le "$3" ]; then
2624 # Muestra mensaje y sale con código de error
2627 # Uso: die mensaje [código de error = 1]
2647 # Imprime mensaje por salida de error
2650 # Uso: perr mensajes
2667 # Pone un MSG en el log
2673 # $1 = Archivo del log
2682 # $4 = Tamaño maximo
2688 fecha=$(date +%d/%m/%Y-%H:%M)
2691 echo "$fecha $USER $2:
2706 # Trunca un archivo de log si pasa el tamaño máximo.
2709 # Uso: clean_log log_filename max_log_size_bytes
2727 tmp=`dirname "$LOGFILE"`"/`basename $0`.$$.temp"
2730 # Verifico que el logfile no se pase del tamaño maximo
2733 tam=`stat -c '%s' "$LOGFILE"`
2736 # Si se paso del maximo dejo las ultimas 100 lineas
2739 if [ "$tam" -ge "$LOGSIZE" ]; then
2742 tail -n 100 "$LOGFILE" > "$tmp"
2745 mv "$tmp" "$LOGFILE"
2760 Auxiliar, escrito en
2767 Justificación de su uso
2776 en segundo plano, desasociado de la terminal.
2782 Ninguno, toma los datos necesarios por la entrada estándar, aunque es común
2783 redireccionarle el archivo
2788 De la entrada estándar toma los códigos de origen y destino.
2789 Cada código debe encontrarse en una línea y al comienzo de ésta.
2790 Sólo toma los 2 primeros caracteres, e ignora el resto de la línea (para
2791 compatibilidad con el archivo oridesti.txt).
2801 (especificada por el usuario) de archivos con nombre y formato de
2805 en el directorio actual.
2806 Tanto el nombre como la cantidad de líneas y su contenido es generado aleatoria
2807 mente (respetando el formato mencionado y con valores racionales).
2813 La invocación es al estilo SysV, tomando como parámetro la acción a realizar,
2841 está corriendo o no.
2847 Al comienzo del script, abajo de
2851 , se pueden cambiar algunas variables:
2854 WAIT Cantidad de segundos a esperar para que arranque o se detenga
2860 antes de asumir un error.
2863 DAEMON Nombre del programa a ejecutar.
2864 Este programa es lo suficientemente genérico como para correr cualquier
2869 , por eso se provee una variable de configuración para cambiar el comando
2873 Ejemplos de invocación
2874 \layout Subsubsection
2878 ./afimonio_daemon.sh start
2888 \layout Subsubsection
2892 ./afimonio_daemon.sh stop
2902 \layout Subsubsection
2906 ./afimonio_daemon.sh status
2915 está corriendo lo indica con un mensaje y muestra su PID.
2916 Si no está corriendo da otro mensaje indicándolo.
2917 \layout Subsubsection
2921 ./afimonio_daemon.sh
2924 Da un mensaje de ayuda.
2946 # --------------- SCRIPT ---------------------
2949 BASE_DIR="$HOME/.antifraude"
2953 "$BASE_DIR/conf/$DAEMON.conf"
2965 perr "Parámetros válidos : start, stop, status"
2979 echo -n "Iniciando demonio '$DAEMON' en modo daemon "
2982 if is_lock "$DAEMON"; then
2988 perr "$DAEMON ya está corriendo"
2993 "(PID=`lock_pid $DAEMON`)."
3002 nohup "$AFIM_BINDIR/$DAEMON" > /dev/null &
3005 for i in `seq $WAIT`; do
3008 if is_lock "$DAEMON"; then
3011 echo " OK! (PID=`lock_pid $DAEMON`)"
3029 # Tardó más de 5 segundos en arrancar, algo anda mal...
3035 perr "$DAEMON tardó más de $WAIT segundos en arrancar,"
3041 "probablemente haya algún problema."
3053 echo -n "Parando el demonio '$DAEMON' "
3056 if ! is_lock "$DAEMON"; then
3062 perr "$DAEMON no esta corriendo."
3071 kill `lock_pid $DAEMON`
3074 for i in `seq $WAIT`; do
3077 if ! is_lock "$DAEMON"; then
3098 # Tardó más de 5 segundos en parar, algo anda mal...
3104 perr "$DAEMON tardó más de $WAIT segundos en parar,"
3109 "probablemente haya algún problema."
3121 if is_lock "$DAEMON"; then
3124 echo "$DAEMON está corriendo actualmente"
3129 "(PID=`lock_pid $DAEMON`)."
3135 echo "$DAEMON no está corriendo."
3156 Auxiliar, escrito en
3163 Justificación de su uso
3166 Sirve para realizar lotes de prueba con gran cantidad de entradas y variaciones
3167 de forma rápida y cómoda.
3173 Ninguno, toma los datos necesarios por la entrada estándar, aunque es común
3174 redireccionarle el archivo
3179 De la entrada estándar toma los códigos de origen y destino.
3180 Cada código debe encontrarse en una línea y al comienzo de ésta.
3181 Sólo toma los 2 primeros caracteres, e ignora el resto de la línea (para
3182 compatibilidad con el archivo oridesti.txt).
3192 (especificada por el usuario) de archivos con nombre y formato de
3196 en el directorio actual.
3197 Tanto el nombre como la cantidad de líneas y su contenido es generado aleatoria
3198 mente (respetando el formato mencionado y con valores racionales).
3204 El comando toma 3 parámetros
3211 ./callgen [cant_archivos [min_lineas [max_lineas]]]
3215 \begin_inset Tabular
3216 <lyxtabular version="3" rows="4" columns="3">
3218 <column alignment="center" valignment="top" leftline="true" width="0">
3219 <column alignment="center" valignment="top" leftline="true" width="0">
3220 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
3221 <row topline="true" bottomline="true">
3222 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3232 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3242 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3253 <row topline="true">
3254 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3262 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3267 Cantidad de archivos a generar
3270 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3279 <row topline="true">
3280 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3288 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3293 Mínima cantidad de lineas en un archivo
3296 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3305 <row topline="true" bottomline="true">
3306 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3314 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3319 Máxima cantidad de lineas en un archivo
3322 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3341 Pueden cambiarse los valores por defecto editando el código fuente del comando,
3342 en la sección de configuración que se encuentra al comienzo del mismo.
3343 También puede cambiarse el mínimo y máximo año (por defecto 1999 y 2004)
3344 y el mínimo y máximo código de central (por defecto 0000 y 9999).
3347 Ejemplos de invocación
3348 \layout Subsubsection
3357 Se escriben por entrada estándar los códigos de origen/destino, se presiona
3364 para cerrar el descriptor de archivo de la entrada estándar y se generan
3365 10 archivos con entre 1000 y 5000 líneas cada uno.
3366 \layout Subsubsection
3370 ./callgen 2 < oridesti.txt
3375 Genera 2 archivos con entre 1000 y 5000 líneas cada uno tomando los códigos
3376 de origen/destino del archivo
3381 \layout Subsubsection
3385 ./callgen 5 10 < oridesti.txt
3390 Genera 5 archivos con entre 10 y 5000 líneas cada uno tomando los códigos
3391 de origen/destino del archivo
3396 \layout Subsubsection
3400 ./callgen 50 10 50 < oridesti.txt
3405 Genera 50 archivos con entre 10 y 50 líneas cada uno tomando los códigos
3406 de origen/destino del archivo
3422 # Generador aleatorio de archivos de llamadas
3428 # Leandro Lucarella - dom oct 17 18:37:05 ART 2004
3434 # Bajo licencia GPL.
3443 # ./callgen [cant_archivos [min_lineas [max_lineas]]]
3449 # cant_archivos Cantidad de archivos a generar.
3452 # min_lines Mínima cantidad de líneas que puede tener un archivo.
3455 # max_lines Máxima cantidad de líneas que puede tener un archivo.
3461 # Por la entrada estándar debe recibir los códigos de países para
3464 # origen y/o destino.
3465 Toma los dos primeros caracteres por línea como
3468 # un código, ignorando el resto, de manera que se puede hacer:
3471 # cat oridesti.txt | ./gencall
3500 #{{{ Variables globales
3503 our @codes; # Códigos de origen/destino
3516 #{{{ load_codes() - Obtiene códigos de origen/destino de la entrada
3531 push(@codes, substr($_, 0, 2)) while (<STDIN>);
3542 #{{{ get_rnd_code() - Obtiene un códigos de origen/destino al azar
3545 # Uso: get_rnd_code()
3557 return $codes[rnd($cant-1)];
3568 #{{{ rnd() - Genera números aleatorios
3571 # Uso: rnd(MAX) - genera número de 0 a MAX (inclusive)
3574 # rnd(MIN, MAX) - genera número de MIN a MAX (inclusive)
3580 # Nota: respeta el tamaño del campo más chico, es decir, si se usa
3583 # rnd 01 250, el número siempre tendrá al menos 2 dígitos
3586 # rellenados con ceros, como 04, 28, 123, 08, etc
3595 my ($ini, $fin) = @_;
3613 return sprintf('%0'.length($ini).'d', $ini + rand()
3616 * ($fin - $ini + 1));
3627 #{{{ Tipos de campos
3630 sub aaaa() { return rnd($MIN_ANIO, $MAX_ANIO); } # año
3633 sub mm() { return rnd("01", 12); } # mes
3636 sub dd() { return rnd("01", 28); } # día
3639 sub hh() { return rnd("00", 23); } # hora
3642 sub MM() { return rnd("00", 59); } # minutos
3645 # código de central telefónica
3648 sub DDDD() { return rnd($MIN_COD, $MAX_COD); }
3651 # caracter aleatorio
3654 sub char() { return chr(rnd(65, 90)); }
3662 #{{{ line() - Genera una línea del archivo
3671 my $f_linea = rnd(100000, 99999999);
3674 my $f_minutos = rnd(1, 150);
3677 my $f_fecha = aaaa().mm().dd();
3680 my $f_hora = dd().hh().MM();
3683 my ($f_tipo, $f_orig, $f_dest) = ('', '', '');
3695 $f_orig = get_rnd_code();
3710 $f_dest = get_rnd_code();
3716 my $f_prest = char().char().char().char().char().
3719 char().char().char().char();
3722 return "$f_linea;$f_minutos;$f_fecha;$f_hora;".
3725 "$f_tipo;$f_dest;$f_orig;$f_prest";
3736 #{{{ gen() - Genera un archivo con entre MIN y MAX llamadas
3739 # Uso: gen(MIN, MAX)
3748 my ($ini, $fin) = @_;
3751 my $file = aaaa().mm().dd().hh().MM().'.'.DDDD();
3754 # Mientras exista uno, buscamos un nuevo nombre.
3757 $file = aaaa().mm().dd().hh().MM().'.'.DDDD()
3766 or die("No puedo abrir el archivo $file!
3771 for (my $i = rnd($ini, $fin); $i > 0; --$i)
3804 my $cant = $ARGV[0] ? $ARGV[0] : $CANT_ARCHS;
3810 for (my $i = 0; $i < $cant; ++$i)
3816 gen($ARGV[1] ? $ARGV[1] : $MIN_LINEAS,
3819 $ARGV[2] ? $ARGV[2] : $MAX_LINEAS);
3830 # vim: set fdm=marker ts=4 sw=4 :
3836 Archivos del Enunciado
3844 Los archivos de log generados por los distintos comandos, presentan todos
3845 la misma estructura de registro que se detalla a continuación:
3847 YYYYMMDD-hhmm $usuario $comando: ¨$Mensaje¨
3855 En este archivo se tienen los origenes y destinos en base a los cuales hemos
3856 generados los archivos de llamada y los umbrales.
3860 \begin_inset Float table
3869 Estructura de oridesti.txt
3873 \begin_inset Tabular
3874 <lyxtabular version="3" rows="2" columns="2">
3876 <column alignment="center" valignment="top" leftline="true" width="0">
3877 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
3878 <row topline="true" bottomline="true">
3879 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3887 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3896 <row topline="true" bottomline="true">
3897 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3905 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3929 Este archivo posee los umbrales de llamadas de los cuales se valdra el antifraud
3930 e.pl para emitir o no alarmas durante el proceso de los archivos de llamadas.
3934 \begin_inset Float table
3943 Estructura de umbrales.param
3947 \begin_inset Tabular
3948 <lyxtabular version="3" rows="8" columns="2">
3950 <column alignment="center" valignment="top" leftline="true" width="0">
3951 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
3952 <row topline="true" bottomline="true">
3953 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3961 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3966 N caracteres, número secuencial >= 1
3970 <row topline="true">
3971 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3979 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3984 N caracteres, Numérico
3988 <row topline="true">
3989 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3997 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4002 2 caracteres, valores posibles segun oridesti.txt
4006 <row topline="true">
4007 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4015 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4020 1 caracter, E = Entrante, S = Salida
4024 <row topline="true">
4025 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4033 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4038 1 caracter, A = Activo, I = Inactivo
4042 <row topline="true">
4043 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4051 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4056 N caracteres = login del user que graba el reg
4060 <row topline="true">
4061 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4069 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4074 8 caracteres, formato aaaammdd
4078 <row topline="true" bottomline="true">
4079 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4087 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4092 6 caracteres, formato hhmmss, hora actual
4108 <archivo de llamada>
4111 Estos archivos son los que el antifraude procesará en busca de matchs contra
4116 \begin_inset Float table
4125 Estructura de un archivo de llamadas
4129 \begin_inset Tabular
4130 <lyxtabular version="3" rows="8" columns="2">
4132 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4133 <column alignment="center" valignment="top" rightline="true" width="0">
4134 <row topline="true" bottomline="true">
4135 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4143 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4148 N caracteres, Numérico
4152 <row topline="true">
4153 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4161 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4166 N caracteres, Numérico
4170 <row topline="true">
4171 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4179 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4184 8 caracteres, formato aaaammdd
4188 <row topline="true">
4189 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4197 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4202 6 caracteres, formato hhmmss
4206 <row topline="true">
4207 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4215 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4220 1 carácter, E = Entrante, S = Salida
4224 <row topline="true">
4225 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4233 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4238 2 caracteres, solo informado en llamadas salientes
4242 <row topline="true">
4243 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4251 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4256 2 caracteres, solo informado en llamadas entrantes
4260 <row topline="true">
4261 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4269 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4293 En este archivo el antifraude irá dejando registro de las alarmas emitidas
4294 en base a registros que han tenido un match contra los umbrales.
4298 \begin_inset Float table
4307 Estructura de alarmas.txt
4311 \begin_inset Tabular
4312 <lyxtabular version="3" rows="10" columns="2">
4314 <column alignment="center" valignment="top" leftline="true" width="0">
4315 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4316 <row topline="true" bottomline="true">
4317 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4325 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4330 N caracteres, campo 'Prestadora', archivo de llamadas
4334 <row topline="true">
4335 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4343 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4348 4 caracteres, obtenido a partir del archivo de llamadas
4352 <row topline="true">
4353 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4361 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4366 N caracteres, campo 'Numero de Linea' , archivo de llamadas
4370 <row topline="true">
4371 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4379 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4384 N caracteres, campo 'Cant de Minutos', archivo de llamadas
4388 <row topline="true">
4389 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4397 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4402 N caracteres, campo 'Id de registro', umbrales.param
4406 <row topline="true">
4407 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4415 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4420 8 caracteres, campo 'Fecha de llamada', archivo de llamadas
4424 <row topline="true">
4425 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4433 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4438 6 caracteres, campo 'Hora de llamada', archivo de llamadas
4442 <row topline="true">
4443 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4451 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4456 N caracteres, siempre login del usuario que graba el reg
4460 <row topline="true">
4461 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4469 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4474 8 caracteres, formato aaaammdd, fecha actual
4478 <row topline="true" bottomline="true">
4479 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4487 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4492 6 caracteres formato hhmmss, hora actual
4514 El archivo de configuración
4516 ~/.antifraude/conf/afimonio.conf
4518 almacena las rutas a los directorios necesarios para la ejecución del script
4523 y la ruta, nombre, y tamaño máximo del archivo de log.
4532 El archivo de configuración
4534 ~/.antifraude/conf/antifraude.conf
4536 almacena las rutas a los directorios necesarios para la ejecución del script
4541 y la ruta, nombre, y tamaño máximo del archivo de log.
4550 El archivo de configuración
4552 ~/.antifraude/conf/aficonf.conf
4554 almacena las rutas a los directorios necesarios para la ejecución del script
4559 y la ruta, nombre, y tamaño máximo del archivo de log.
4563 Estos archivos fueron creados para que los diferentes scripts tengan un
4564 lugar común donde buscar esa información para salvar el problema comentado
4566 \begin_inset LatexCommand \vref{sec:Problemas-relevantes}
4580 Para probar el comportamiento del sistema, se preparo un set de prueba distribui
4585 , situado en el directorio
4589 , del paquete de instalación.
4590 El set de prueba se copia automáticamente en el momento en que se instale
4597 , dejando el escenario listo para procesarlos en el momento en que sea arrancado
4605 o bien ejecutando el
4614 Este set de prueba consta de
4618 , que se detallan a continuación:
4621 14 archivos de llamadas generados con el
4627 , con entre 1000 y 5000 registros cada uno, y fecha en el rango año 1999
4631 1 archivo de llamadas con registros válidos y otros no válidos.
4634 1 archivo con nombre válido según el formato YYYYMMDDhhmm.nnnn, pero con
4635 contenido inválido, el cual es rechazado por
4644 1 archivo con nombre no válido rechazado en instancia previa por
4653 Se describen en la siguiente tabla, los archivos y registros que disparan
4654 alarmas o tienen close matches contra los 25 umbrales distribuidos en el
4655 paquete de instalación, vía el umbrales.param:
4659 \begin_inset Float table
4668 Archivos y Registros que disparan alarmas
4672 \begin_inset Tabular
4673 <lyxtabular version="3" rows="24" columns="3">
4675 <column alignment="center" valignment="top" leftline="true" width="0">
4676 <column alignment="center" valignment="top" leftline="true" width="0">
4677 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4678 <row topline="true" bottomline="true">
4679 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4689 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4700 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4711 <row topline="true">
4712 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4720 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4728 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4737 <row topline="true">
4738 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4746 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4754 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4763 <row topline="true">
4764 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4772 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4780 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4789 <row topline="true">
4790 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4798 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4806 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4815 <row topline="true">
4816 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4824 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4832 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4841 <row topline="true">
4842 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4850 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4858 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4867 <row topline="true">
4868 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4876 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4884 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4893 <row topline="true">
4894 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4902 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4910 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4919 <row topline="true">
4920 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4928 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4936 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4945 <row topline="true">
4946 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4954 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4962 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4971 <row topline="true">
4972 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4980 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4988 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4997 <row topline="true">
4998 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5006 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5014 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5023 <row topline="true">
5024 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5032 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5040 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5049 <row topline="true">
5050 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5058 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5066 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5075 <row topline="true">
5076 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5084 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5092 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5101 <row topline="true">
5102 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5110 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5118 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5127 <row topline="true">
5128 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5136 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5144 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5153 <row topline="true">
5154 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5162 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5170 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5179 <row topline="true">
5180 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5188 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5196 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5205 <row topline="true">
5206 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5214 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5222 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5227 21 (umbral inactivo => no emite alarma)
5231 <row topline="true">
5232 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5240 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5248 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5253 Close match umbral 22, difiere tipo de llamada
5257 <row topline="true">
5258 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5266 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5274 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5283 <row topline="true" bottomline="true">
5284 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5292 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5300 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5305 25 (umbral inactivo => no emite alarma)
5317 \layout Subsubsection
5326 Posee registros no válidos detallados a continuación.
5327 Los registros se contabilizan de 0 a N (Línea 1 = Reg 0)
5330 Registro\SpecialChar ~
5340 Registro\SpecialChar ~
5350 Registro\SpecialChar ~
5355 Posee un tipo de llamada
5362 Registro\SpecialChar ~
5367 El número de línea (campo1) no es numérico, es un string
5372 Registro\SpecialChar ~
5377 Tiene cantidad de campos insuficiente (siete)
5380 Estos registros emitirán errores plasmados en el
5385 Para verificar esto, realizar una búsqueda en el log, sobre el nombre del
5386 archivo, y ubicarse en el sector donde se indica el comienzo del procesamiento
5389 Inicio proceso de: 199908220733.4515
5392 \layout Subsubsection
5401 Es un archivo de texto el cual pasa el control de Afimonio, pero luego sus
5402 lineas son descartadas por antifraude y dicho error emitido en el antifraude.log
5403 \layout Subsubsection
5412 El nombre del archivo no es conforme al formato de nombre estipulado en
5413 el TP y el mismo es rechazado de antemano por
5425 Esto deberia ser una hoja aparte que solo diga 1.6 Apéndice A) y las hojas
5426 posteriores son las páginas 3 en adelante del PDF oficial de la catedra,
5427 sacando la parte de archivos.
5428 3-15 más precisamente es lo que iria.