Advertisement
Guest User

climbo

a guest
Jul 25th, 2009
358
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 8.05 KB | None | 0 0
  1. #!/usr/bin/perl -T
  2.  
  3. ##################################################################
  4. # contador.cgi      CONTADOR DE ACCESOS
  5. #
  6. # (c) Ivan Nieto Perez
  7. # Este CGI puede descargarse de El Codigo:
  8. # http://www.elcodigo.com
  9. #
  10. # Puede usarse libremente y modificarse siempre que se conserve
  11. # esta cabecera intacta
  12. #
  13. ##################################################################
  14. #
  15. # Contador de visitas a una pagina que se invoca desde una etiqueta <img>
  16. # Sintaxis:
  17. # <img src="/ruta_cgis/contador.pl?pagina=mi_pagina.html">
  18. #
  19. # Ejemplo:
  20. # <img src="/cgi-bin/contador.pl?pagina=index.html">
  21. #
  22. # Este CGI debe tener permisos chmod 755, y el fichero con la
  23. # cuenta chmod 666 o 777
  24. #
  25. ##################################################################
  26. #
  27. # Codigos de error:
  28. #   1   Error abriendo fichero para lectura ($FicheroCuenta)
  29. #   2   Error abriendo fichero para escritura ($FicheroCuenta)
  30. #   3   Este CGI no puede ser invocado directamente en la barra de direcciones del navegador
  31. #   4   Faltan parámetros en la llamada al CGI
  32. #   5   Este CGI no puede ejecutarse desde este dominio o pagina
  33. #   6   Hay caracteres no permitidos en el nombre del fichero ($FicheroCuenta)
  34. #
  35. ##################################################################
  36.  
  37. # CONFIGURACION
  38.  
  39. # Ruta fisica y nombre fichero de cuentas
  40. $FicheroCuenta = '/var/www/htdocs/contador.txt';
  41.  
  42. # Dominio desde el que se puede ejecutar, separados por comas
  43. $DOMINIOS_VALIDOS = "www.elcodigo.com,www.elcodigo.com,elcodigo.com,elcodigo.net";
  44.  
  45. #formato digitos
  46. $digitos_por_bmp = 6;   # numero minimo de digitos en un bipmap
  47. $flagAltura = 0;    # si a 1, los digitos seran de 16 pixels de alto, para dejar espacio para el borde
  48. $flagNegativo = 0;  # a 1, los digitos son blancos sobre fondo negro, a 0 negros sobre fondo blanco
  49.              
  50. # FIN CONFIGURACION, NO TOCAR NADA A PARTIR DE AQUI (SALVO QUE SE SEPA LO QUE SE HACE)
  51.  
  52. # VARIABLES GLOBALES
  53.  
  54. # Contador
  55. my $cuenta = '';
  56.  
  57. # Mapa de bits de cada digito
  58. # Cada digito es 8 pixels de ancho x 10 de alto
  59. # @digitos_negativo son blanco sobre fondo negro, @digitos son negro sobre fondo blanco
  60. @digitos_negativo = ("c3 99 99 99 99 99 99 99 99 c3",  # 0
  61.                      "cf c7 cf cf cf cf cf cf cf c7",  # 1
  62.                      "c3 99 9f 9f cf e7 f3 f9 f9 81",  # 2
  63.                      "c3 99 9f 9f c7 9f 9f 9f 99 c3",  # 3
  64.                      "cf cf c7 c7 cb cb cd 81 cf 87",  # 4
  65.                      "81 f9 f9 f9 c1 9f 9f 9f 99 c3",  # 5
  66.                      "c7 f3 f9 f9 c1 99 99 99 99 c3",  # 6
  67.                      "81 99 9f 9f cf cf e7 e7 f3 f3",  # 7
  68.                      "c3 99 99 99 c3 99 99 99 99 c3",  # 8
  69.                      "c3 99 99 99 99 83 9f 9f cf e3"); # 9
  70.    
  71. @digitos = ("3c 66 66 66 66 66 66 66 66 3c",  # 0
  72.             "30 38 30 30 30 30 30 30 30 30",  # 1
  73.             "3c 66 60 60 30 18 0c 06 06 7e",  # 2
  74.             "3c 66 60 60 38 60 60 60 66 3c",  # 3
  75.             "30 30 38 38 34 34 32 7e 30 78",  # 4
  76.             "7e 06 06 06 3e 60 60 60 66 3c",  # 5
  77.             "38 0c 06 06 3e 66 66 66 66 3c",  # 6
  78.             "7e 66 60 60 30 30 18 18 0c 0c",  # 7
  79.             "3c 66 66 66 3c 66 66 66 66 3c",  # 8
  80.             "3c 66 66 66 66 7c 60 60 30 1c"); # 9
  81.  
  82. # FIN VARIABLES GLOBALES
  83.  
  84. # Comprueba dominio valido
  85.    &comprueba_dominio;
  86.    
  87. # Lee query string
  88.    &lee_querystr;
  89.  
  90. # Comprueba que se ha introducido el parametro necesario
  91.    if ( $INFO{'pagina'} eq '' ) { die('Falta parametro nombre pagina.'); }
  92.  
  93. # Incremento de la cuenta del fichero
  94.    &incrementaContador;
  95.  
  96. # Obtencion imagenes
  97.    &generaMapaBits;
  98.  
  99. # Salida  
  100.    &escribeMapaBits;
  101.  
  102.    exit(0);
  103.  
  104. ##################################################################
  105. sub escribeMapaBits {
  106.    print ("Content-type: image/x-xbitmap\n");
  107.    print "Pragma: no-cache\n";
  108.    print "Expires: now\n\n";
  109.    
  110.    if ($flagAltura) {
  111.       printf ("#define count_width %d\n#define count_height 16\n",
  112.               $len*8);
  113.    }
  114.    else {
  115.       printf ("#define count_width %d\n#define count_height 10\n",
  116.               $len*8);
  117.    }
  118.    printf STDOUT "static char count_bits[] = {\n";
  119.    for($i = 0; $i < ($#bytes + 1); $i++) {
  120.       print("0x$bytes[$i]");
  121.       if ($i != $#bytes) {
  122.          print(",");
  123.          if (($i+1) % 7 == 0) {
  124.             print("\n");
  125.          }
  126.       }
  127.    }
  128.    print("};\n");
  129. }
  130.  
  131. ##################################################################
  132. # generaMapaBits() - $cuenta        numero a mostrar
  133. #                    $digitos_por_bmp   minimo numero de digitos a mostrar
  134. #                    $flagAltura    a 1 si digitos de 16 pixels alto
  135. #                    $flagNegativo  a 1 si negativo (blanco sobre negro)
  136. sub generaMapaBits {
  137.    @bytes = ();
  138.    $len = length($cuenta) > $digitos_por_bmp ? length($cuenta) : $digitos_por_bmp;
  139.    $formattedCount = sprintf("%0${len}d",$cuenta);
  140.    if ($flagAltura) {
  141.       for ($i = 0; $i < $len*3; $i++ ) {
  142.          if ($flagNegativo) {
  143.             push(@bytes,"ff");
  144.          }
  145.          else {
  146.             push(@bytes,"00");
  147.          }
  148.       }
  149.    }
  150.    for ($y=0; $y < 10; $y++) {
  151.        for ($x=0; $x < $len; $x++) {
  152.            $digit = substr($formattedCount,$x,1);
  153.            if ($flagNegativo) {
  154.                $byte = substr(@digitos_negativo[$digit],$y*3,2);
  155.            }
  156.            else {
  157.                $byte = substr(@digitos[$digit],$y*3,2);
  158.            }
  159.            push(@bytes,$byte);
  160.        }
  161.    }
  162.    if ($flagAltura) {
  163.       for ($i = 0; $i < $len*3; $i++ ) {
  164.          if ($flagNegativo) {
  165.             push(@bytes,"ff");
  166.          }
  167.          else {
  168.             push(@bytes,"00");
  169.          }
  170.       }
  171.    }
  172. }
  173.  
  174. ###############################################################################
  175. # $INFO{'pagina'} = nombre de la pagina cuyos accesos se desea contabilizar
  176. sub incrementaContador {
  177.  
  178.    $pagina = $INFO{'pagina'};
  179.  
  180.    $encontrados = 0;
  181.    $cuenta = 1;
  182.    
  183.    open(COUNT,"$FicheroCuenta") || die("Imposible abrir $FicheroCuenta.");
  184.    &lock;      
  185.    @lineas = <COUNT>;
  186.    &unlock;        
  187.    close(COUNT);  
  188.    
  189.    # Espera aleatoria para accesos concurrentes
  190.    srand(time ^ $$);
  191.  
  192.    # Contador especial para permitir contar en cualquier pagina
  193.    open (FILE, ">$FicheroCuenta") || die("Imposible abrir $FicheroCuenta.");
  194.    &lock;      
  195.  
  196.    foreach $linea (@lineas) {  
  197.       my ($temppagina, $tempcuenta, $crlf) = split(/;/, $linea);
  198.       if ( $temppagina eq $pagina ) {
  199.          $cuenta = $tempcuenta + 1;
  200.          print FILE "$pagina;$cuenta;\n";
  201.       } else {
  202.          print FILE "$linea";
  203.       }
  204.    }
  205.  
  206.    # Primer acceso a la pagina
  207.    if ($cuenta eq '') {
  208.       print FILE "$pagina;1;\n";
  209.    }
  210.  
  211.    &unlock;  
  212.    close (FILE);
  213. }
  214.  
  215.  
  216.  
  217. ###############################################################################
  218. sub lee_querystr {
  219.  
  220.     @vars = split(/&/, $ENV{QUERY_STRING});
  221.     foreach $var (@vars) {
  222.             ($v,$i) = split(/=/, $var);
  223.             $v =~ tr/+/ /;
  224.             $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  225.             $i =~ tr/+/ /;
  226.             $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  227.             $i =~ s/<!--(.|\n)*-->//g;
  228.             $INFO{$v} = $i;
  229.     }
  230. }
  231.  
  232.  
  233. ##################################################################
  234. sub lock {
  235.   local($file)=@_;
  236.   flock($file, $LOCK_EX);
  237. }
  238.  
  239.  
  240. ##################################################################
  241. sub unlock {
  242.   local($file)=@_;
  243.   flock($file, $LOCK_UN);
  244. }
  245.  
  246.  
  247. ##################################################################
  248. sub comprueba_dominio {
  249.  
  250.   # Obtencion de la pagina desde la que se llama al CGI
  251.   $pagina = $ENV{'HTTP_REFERER'};
  252.   if ( $pagina eq '' ) { die('Referrer no presente.'); }
  253.   ($http, $dominioypagina) = split(/\/\//,$pagina); # Separa por //
  254.   ($dominio, @resto) = split(/\//, $dominioypagina);    # Separa por /
  255.  
  256.   # Comprobacion de dominio
  257.   my $domvalido = 0;
  258.   my $valido = 0;
  259.   (@dominios_validos) = split(/,/, $DOMINIOS_VALIDOS);  # Lista de dominios validos
  260.   foreach $dom (@dominios_validos) {
  261.      if ( $dominio eq $dom ) { $domvalido = 1; }
  262.   }
  263.  
  264.   if ( $domvalido != 1 ) {
  265.      die('Dominio no valido.');
  266.   }
  267. }
  268.  
  269.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement