Archivo

Archivo para la categoría ‘General’

Creando una aplicación para Facebook (paso a paso)

Miércoles, 18 de Enero de 2012 Gaspar Fernández 2 comentarios

monitor_poesia

He decidido hacer esta guía porque Facebook anda cambiando los métodos para hacer aplicaciones y varias partes de su API. Los chicos de Facebook no paran de meter y sacar cosas y no dejan la página quieta. Después de hacer varias guías para “publicar definitivamente” en Facebook, van y cambian la forma de hacerlo.

Aunque parece que se han estabilizado, todos estos cambios han sido para llegar a la Graph API, se ha quedado bien hecha y estable, y yo creo que es posible aprender mucho de ella.

Aunque en esta guía empezaré desde el principio, desde que se crea la aplicación, paso a paso, ya que actualmente crear una aplicación vale para muchas cosas, no sólo para algo que resida dentro de Facebook sino para webs o clientes que funcionan fuera de Facebook e interactúan con la red social.

He de decir también que esta guía está hecha en Enero de 2012, por lo que si entras aquí en el futuro, puede que hayan hecho otro cambios definitivo más en Facebook.

Primer paso: Crear la App

Para ello debemos dirigirnos a https://developers.facebook.com/apps. Éste será nuestro centro de control de aplicaciones, donde podremos ver y editar los datos de éstas. Allí encontraremos en la parte superior de la página:

facebook_create_app

Pulsamos sobre Create New App, tras ello veremos un diálogo como este:

facebook_create_app_dialogEn el que en:

  • App Display Name debemos decir el nombre de nuestra aplicación, o si es una aplicación para identificarnos en una página, el nombre de la página. Es un nombre que la identifique.
  • App Namespace es el nombre que tiene nuestra aplicación en la URL de aplicaciones de Facebook. Es decir https://apps.facebook.com/AppNamespace . Dependiendo del ámbito de nuestra aplicación (si es accesible a través de Facebook.com o no) rellenaremos este campo o no.

Si continuamos, a veces la web de Facebook dará un error (comprobado el 7 de Enero de 2012), por lo que podemos volver a la página de las aplicaciones y continuar.

En la configuración de la aplicación, le damos a Edit Settings, y saldrá una pantalla así:

facebook_app_basica

Aquí podremos rellenar el Namespace (mencionado antes), el mail de contacto y el dominio donde está alojada la aplicación (muy importante, ya que si la aplicación no está en el dominio indicado, no funcionará; además de la categoría de nuestra aplicación.

Por otra parte, arriba vemos la App ID y la App Secret. La primera es el identificador de nuestra aplicación, y la segunda una clave secreta que no se debe compartir con nadie para que la aplicación pueda interactuar con Facebook, algo así como el nombre de usuario y contraseña de nuestra aplicación. (Yo lo he puesto aquí, pero en realidad lo he regenerado varias veces).

La aplicación que crearemos servirá para enlazar una página web con Facebook y poder utilizar esa información, para eso debemos rellenar el apartado App Domain (por ejemplo minutodecaos.com), con el dominio donde estén alojadas las páginas de la aplicación, si no, la aplicación no estará autorizada y, un poco más abajo Site URL con la dirección exacta donde estará alojada nuestra aplicación.

fb_website

Código fuente de la App

Es hora de crear nuestra aplicación en PHP. Lo primero que tenemos que hacer es descargarnos los archivos de la API desde esta dirección, dentro de GitHub. En principio trabajaremos en la web en modo local, por lo que creamos un directorio en nuestro disco duro (proyectos/facebook/tests/ dentro de mi home) Y descomprimimos los archivos dentro del directorio de nuestro proyecto. Aunque no es estrictamente necesario, yo lo he descomprimido dentro de lib/facebook, por lo que esos archivos estarán en $HOME/proyectos/facebook/tests/lib/facebook; y creamos el siguiente index.php (que luego subiremos al servidor junto con los ficheros de biblioteca de Facebook) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

$api_key = 'xxxxxxxxxx';
$api_sec = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

require_once('lib/facebook/facebook.php');

$facebook = new Facebook(array(  
                   'appId'  => $api_key,
                   'secret' => $api_sec,
                   'cookie' => true ,
                 ));

$sesion = $facebook->getUser();
if ($sesion)
  {
    echo "Estamos identificados en Facebook<br/>";
  }
 else
  {
    echo "No estamos identificados en Facebook ";
    $login_url = $facebook->getLoginUrl();
    echo '<a href="'.$login_url.'">Click para identificarte</a>';
  }

?>

Este código nos mostrará, la primera vez que entremos: “No estamos identificados en Facebook. Click aquí para identificarte”, eso no significa que no hayamos entrado a la página de Facebook, significa que la página web no te ha identificado como usuario y de ser autorizada, por eso hacemos click en la pantalla anterior y aparecerá lo siguiente:
fb_website1

Login automático

Si no queremos mostrar el enlace para identificarnos en la aplicación, podemos utilizar el siguiente código:

1
2
3
4
5
6
7
8
if ($sesion)
   echo "Estamos identificados en Facebook";
else
{
   $login_url = $facebook->getLoginUrl();
   header('Location: '.$login_url);
   die();
}

Mostrando datos de usuario, o cogiéndolos

En la parte de “Estamos identificados en Facebook”, podemos hacer:

1
2
3
4
5
6
7
if ($sesion)
{
   echo "Estamos identificados en Facebook<br/>";
   echo "Usuario: ".$sesion."<br/>";
   $userData = $facebook->api('/me');
   echo nl2br(print_r($userData, true));
}

Con estas líneas podemos ver información del usuario que está actualmente identificado en nuestra aplicación, y podremos utilizar los datos del array $userData:

  • ['name'] - Nombre completo del usuario
  • ['first_name'] - Nombre
  • ['last_name'] - Apellidos
  • ['link'] - Enlace a la página del usuario en Facebook
  • ['username'] - Nombre de usuario de Facebook
  • ['about'] - Frase personal
  • ['gender'] - Género
  • y mucho más que podemos ver cuando ejecutamos el ejemplo anterior

Ahora en Facebook, siempre que queramos acceder a información tanto de páginas, grupos, usuarios, etc, sólo tenemos que acceder a través de la llamada a api(’/localizacion’), con la palabra especial /me, como hemos visto para el usuario actual. Esto nos puede ayudar a identificarnos en nuestra web, sin pedir usuario, ni contraseña, a través de la Graph Api.

5 Aplicaciones que me salvan día a día

Domingo, 15 de Enero de 2012 Gaspar Fernández 3 comentarios

Son pequeñas aplicaciones sin las cuales no podría salir adelante día a día. Aunque a veces no las mime demasiado y no les haga mucho caso, deberían saber que son importantes para mí, para mi vida online y yo informático. He intentado establecer un orden, pero todas ellas son muy importantes, por lo que ocuparían todas la primera posición:

  1. Keepnote

    Es un software muy completo y ligero para tomar notas, clasificarlas y buscar dentro de ellas. De todos los que he probado es el que mejor sensación me ha dejado con respecto a su facilidad de uso, velocidad y características. Disponible en Linux, Mac y Windows

  2. KeepassX

    Es un gran programa para anotar nuestras contraseñas y anotaciones para cualquier tipo de identificación electrónica (webs, banca online, routers, etc). Puedes ordenar las contraseñas por categorías, asignarles iconos, buscarlas, etc. Es muy fácil de utilizar, y guarda la información cifrada para que nadie más que tú pueda verla. Disponible para Linux, Mac y Windows

  3. Grisbi

    Un software para organizar mi economía personal, saber cuánto dinero tengo en la cartera y en el banco, quién me debe y a quién le debo. Es muy completo y funciona en Linux, Mac y Windows.

  4. Emacs

    Llamadme friki, pero es mi editor de texto / IDE favorito para programar. Con multitud de opciones, automatizable, personalizable y todo a mano, aunque para aprender fue algo difícil en principio, una vez que sabes las cuatro cosas básicas, todo va sobre ruedas, y cada día me gusta más (excepto la opción deshacer, pero bueno, nadie es perfecto). Funciona en Linux, Mac, Windows, *BSD, Solaris y algunos más

  5. Hotot

    Un cliente para Twitter muy ligero, cómodo e intuitivo. Hay muchos clientes para microbloguear, pero con éste es con el que me siento más cómodo. Disponible para Linux, Mac, Windows y Chrome, aunque para Windows y Mac es bastante inestable aún.

En algunos de estos proyectos, y en otros más intento colaborar de diferentes formas, aunque a veces no en la medida que me gustaría, por falta de tiempo, como pasa siempre:

  • Clicks en la publicidad de sus webs oficiales
  • Perfeccionamiento de traducciones
  • Haciendo que más gente los utilice
  • Reportando bugs
  • Sugiriendo características

Y vosotros, ¿cómo colaboráis con vuestros proyectos preferidos? ¿Cuáles son esos 5 programas sin los que no podríais vivir?

Creando un menú selector de frecuencia de nuestra CPU

Lunes, 9 de Enero de 2012 Gaspar Fernández 2 comentarios

screenshot-05-01-2012-220103

A mí me gusta tener el control sobre la frecuencia de la CPU, ya sea porque muchas veces no estoy haciendo nada y lo quiero dejar al mínimo de velocidad para que se caliente menos, o porque algunas veces necesito un poco más de potencia, y otras veces lo dejo a su aire para que cambie de frecuencia solo.

El script se basa en llamadas a cpufreq-set de cpufrequtils, aunque la llamada tiene que ser con permisos de root, por lo que conviene ver antes este artículo, de todas formas, todo esto se hará paso a paso.

Requisitos

  • CPU soportada por cpufreq
  • Sudo / Gksudo
  • Cpufrequtils
  • Zenity
  • Xosd

Editando sudoers

Este script lo ejecutaremos desde nuestro usuario, pero la llamada a cpufreq-set necesita permisos especiales, por lo tanto, lo haremos con sudo. Si saltamos este paso, nos preguntará la contraseña para ejecutar los comandos, pero si no queremos que nos pregunte, debemos hacer esto.

Lo primero es ejecutar:

$ sudo visudo

Y en el archivo, debajo de la última línea sin comentario, escribimos:

mi_usuario   ALL= NOPASSWD : /usr/bin/cpufreq-set

Sustituyendo mi_usuario por el usuario que va a ejecutar el script. Si tenéis varios usuarios podéis añadirlos uno por línea, o ver el artículo mencionado antes para más opciones.

El script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash

DIALOG=zenity
CPUFREQSET=`which cpufreq-set`
OSDCAT=`which osd_cat`

XOSD_FONT="-*-luxisans-bold-*-*-*-47-*-*-*-*-*-*-*"
XOSD_OPTIONS="--pos=bottom -o -210 -A center -c green -s 2 -d 2 -f "$XOSD_FONT;
tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$
trap "rm -f $tempfile" 0 1 2 5 15

if [ -z $CPUFREQSET ]
then
    echo "cpufrequtils no está instalado"
    exit
fi

if [ -z $OSDCAT ]
then
    echo "xosd no está instalado"
    exit
fi

if [ -e "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies" ]
then
    actual=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq`
    cnt=0
    for i in `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies`
    do
    if [[ $i != $actual ]]; then
        cnt=`expr $cnt + 1`
    fi
    done
else
    echo "CPUfreq no está disponible"
    exit    
fi

simple_math()
{
    echo "scale=2; $1" | bc;
}

saca_freq()
{
    cnt=0
    for i in `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies`
      do
      if [[ $cnt == $1 ]]; then
      frq=$i
      break
      fi
      cnt=`expr $cnt + 1`
    done
    echo $frq
}

pone_freqs()
{
    cnt=0
    for j in `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies`
      do
      if [[ $j != $actual ]]; then
      frq=$frq":Cpufreq "$cnt":"`simple_math $j/1000000`" Ghz"
      fi
      cnt=`expr $cnt + 1`
    done
    echo $frq
}

pone_governors()
{
    possible_governors=([0]=powersave [1]=conservative [2]=ondemand [3]=performance)
    governor_command=([0]=Powersave [1]=Conservative [2]=Ondemand [3]=Performance)
    governor_text=([0]="Ahorro de energía" [1]="Modo conservador" [2]="Modo Bajo demanda" [3]="Modo rendimiento")
    available_governors=`cpufreq-info -g`

    for (( g=0; g<${#possible_governors[*]}; g++ ))
    do
    # echo $g
    # echo ${possible_governors[$g]}
    gov=${possible_governors[$g]}
    if [ -n "`echo $available_governors | grep $gov`" ]
    then
        frq=$frq":"${governor_command[$g]}":"${governor_text[$g]}
    fi
    done
   
    echo $frq
}

freqs="Exit:No hacer nada"
freqs=$freqs`pone_freqs`
freqs=$freqs`pone_governors`

OLD_IFS=$IFS
IFS=":"


$DIALOG --width=240 --height=250 --title="Selector de frecuencia" --list --column "ID" --column "Frecuencia" --hide-column 1 --text "Elige una opcion" $freqs > $tempfile

retval=$?
IFS="${OLD_IFS}"

choice=`cat $tempfile`

comando=`echo $choice | cut --delimiter " " --fields 1`
modif=`echo $choice | cut --delimiter " " --fields 2`

case $retval in
  0)
    case $comando in
        "Exit")
        echo "Salir" | osd_cat $XOSD_OPTIONS
        ;;
        "Cpufreq")
        freqdef=`saca_freq $modif`
        gksudo "$CPUFREQSET -g userspace"
        gksudo "$CPUFREQSET -f $freqdef"
        echo "Velocidad actual "`simple_math $freqdef/1000000`"Ghz" | $OSDCAT $XOSD_OPTIONS
        ;;
        "Powersave")
        gksudo "/usr/bin/cpufreq-set -g powersave"
        echo "Modo ahorro de energía" | $OSDCAT $XOSD_OPTIONS
        ;;
        "Conservative")
        gksudo "/usr/bin/cpufreq-set -g conservative"
        echo "Modo conservador" | $OSDCAT $XOSD_OPTIONS
        ;;
        "Ondemand")
        gksudo "/usr/bin/cpufreq-set -g ondemand"
        echo "Modo bajo demanda" | $OSDCAT $XOSD_OPTIONS
        ;;
        "Performance")
        gksudo "/usr/bin/cpufreq-set -g performance"
        echo "Modo rendimiento" | $OSDCAT $XOSD_OPTIONS
        ;;     
    esac;;
  1)
    echo "Cancelado";;
  255)
    echo "Escape";;
esac

Notas del script

  • He optado por filtrar el resultado de cpufreq-info -g y cambiar las palabras, me gusta filtrar todos los datos que me llegan.
  • Añadí la primera opción para no hacer nada, porque me resultó más cómoda cuando quiero cancelar el menú
  • zenity nos devuelve dos cosas: El resultado de la ejecución y el valor elegido, por tanto el primer valor lo podemos averiguar del script, el segundo lo devuelve como texto, por eso lo almacenamos en un archivo temporal
  • Para cambiar el tipo de letra, tenemos que ejecutar xfontsel, desde ese programa, elegir el tipo de letra y copiar el texto que nos devuelve a la variable XOSD_FONT
    • Por último…

      Para disfrutar de este script, lo bueno es asociarlo a una tecla, por ejemplo yo lo tengo en Meta+F3 y con ello se puede cambiar la frecuencia rápidamente.

Iniciación a los memory leaks [ejemplos en C++]

Lunes, 28 de Noviembre de 2011 Gaspar Fernández Sin comentarios

leak

Hablemos de un fenómeno que nos afecta, sobre todo en desarrollos que están en ejecución durante mucho tiempo, pero , y es que, debido a la mala gestión de la memoria podemos llegar a consumir más de lo necesario y podemos volver loco al sistema operativo utilizando la memoria virtual para darnos el espacio que necesitamos.

Los memory leaks son fugas de memoria debidas a que hemos pedido un cierto espacio de memoria durante la ejecución de nuestro programa, la hemos usado y cuando hemos dejado de usarla, no la hemos liberado, por tanto estamos ocupando más de lo que necesitamos y acaparando recursos; un ejemplo de esto son esos procesos o programas que tenemos arrancados durante varios días, y cuanto más tiempo llevan arrancados más memoria ocupan (a veces es necesario, pero otras veces, la mayoría, no).

Antes de iniciarnos en la creación de un programa acerca de lo que no debemos hacer, vamos a hacerlo bien, y echaremos un vistazo a un artículo sobre el Out Of Memory Killer (desconozco si Windows tiene algo parecido, tal vez instalando alguna aplicación), que será una utilidad de nuestro kernel que matará el proceso cuando esté consumiendo mucha memoria, o nos permitirá matarlo fácilmente con las teclas (Alt+SysRq o imprimir pantalla+F). Con unas líneas antes de nuestro programa, nos podemos evitar un disgusto, como puede ser un reinicio de sistema mientras hacemos pruebas, y puede que estemos ejecutando algo útil.

¡Precaución!

Si vemos que nuestro proceso hace que el sistema vaya muy lento, será porque en lugar de utilizar nuestra RAM, estará usando la memoria virtual de forma intensa, esta memoria es mucho más lenta que nuestra RAM, si hemos entendido lo que quiero demostrar, podemos parar el proceso gracias al OOM Killer de antes con Alt+SysRq+F, pero sólo pulsa una vez las teclas, aunque veamos que no nos hace mucho caso, el sistema tarda un tiempo en volver a recolocar toda la información y limpiar la memoria del proceso. Si pulsamos más veces, lo mismo terminamos matando el servidor gráfico o algún proceso importante, y no queremos eso.

Ajustando OOM Killer

Para todo eso, debemos incluir el siguiente código (al final pondré todo el programa, pero primero lo analizamos por separado), el objetivo es escribir el valor 15 sobre el fichero /proc/PID/oom_adj:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void error(const char *mens)
{
  cerr << "ERROR: ("<<mens<<") errno: "<<errno<<": "<<strerror(errno)<<endl;
  exit (1);
}

void ajusta_oom()
{
  ofstream fi;
  char nom[30];

  // Obtenemos el nombre del fichero, aunque estemos haciéndolo
  // a lo C++, uso sprintf() aquí porque es más rápido.
  sprintf(nom, "/proc/%d/oom_adj", getpid());

  // Abrimos el fichero
  fi.open(nom);
  if (fi.fail())
    error("No puedo abrir oom_adj");

  // Escribimos 15 en el fichero, para dar más "apeletas de muerte"
  // a este proceso. Ver:
  // http://totaki.com/poesiabinaria/2010/04/cuando-un-proceso-se-come-la-memoria-de-nuestro-sistema/
  fi<<"15";
  if (fi.fail())
    error("No puedo escribir oom_adj");

  fi.close();
}

Gastando memoria

Para esta parte hay que tener cuidado, ya que depende de la RAM que tengamos cada uno, yo he hecho esto en un equipo con 2GB de RAM, hasta que se ha vuelto extremadamente lento. Aunque el objetivo es que veamos la memoria que está actualmente en consumo. Podemos utilizar el comando free() en paralelo con el programa para ver que cada vez tenemos más memoria consumida, cuando no deberíamos, porque la intuición nos diría que cuando salimos de la función todo lo reservado se libera, pero no es así.
En los sistemas operativos actuales no podremos ponernos a reservar memoria sin control, ya que el SO casi siempre nos la dará (aunque no disponga de ella, dejando el marrón al gestor de memoria del futuro), si de verdad queremos reservar memoria, gastarla y darnos cuenta, debemos utilizar la memoria que reservamos; por ello he optado por rellenar un vector de números. Cuidado con subir mucho más MAX_NEW_ELEMENTS, es más, si tienes poca memoria, te recomiendo bajarla un poco, a la mitad, por ejemplo, en un primer cálculo, sólo contando los elementos del vector (8.000.000 x 8 (long int) = 64Mb), por lo que depende de lo que haya en ejecución, con cuatro llamadas a la función gasta_memoria() habremos gastado 256Mb de memoria.
Para ver lo que vamos gastando, debemos ejecutar en un terminal el programa que voy a mostrar, y en otro terminal ejecutamos free. El programa hará varias paradas pidiendo que pulsemos intro a cada llamada de gasta_memoria() para que podamos ver lo que se ha gastado, después del código veremos la ejecución.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <iostream>
#include <vector>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <cerrno>
#include <cstring>
#include <fstream>

#define MAX_NEW_ELEMENTS 8000000

using namespace std;

// Sale del programa devolviendo un error
void error(const char *mens);
// Ajunta oom_adjust para matar este proceso si se nos cuelga el sistema
// Así nos quitamos un disgusto
void ajusta_oom();
// Gasta memoria (casi) sin control
void gasta_memoria();
// Espera una tecla
void intro();

void gasta_memoria2()
{

  vector <long int> *v;


  v=new vector<long int>;

  for (unsigned long i=0; i<MAX_NEW_ELEMENTS; i++)
    v->push_back(i);

  intro();
  // delete v;
}


int main()
{
  ajusta_oom();
  cout << "OOM ajustado" << endl;
  intro();
  gasta_memoria();
  gasta_memoria2();
  gasta_memoria();
  gasta_memoria2();
}

void intro()
{
  char key;
  cout << "Pulse Intro"<<endl;
  cin.get(key);
}

void gasta_memoria()
{
  vector <long int> *v;

  v=new vector<long int>;

  for (unsigned long i=0; i<MAX_NEW_ELEMENTS; i++)
    v->push_back(i);

  intro();
  // delete v;
}

void error(const char *mens)
{
  cerr << "ERROR: ("<<mens<<") errno: "<<errno<<": "<<strerror(errno)<<endl;
  exit (1);
}

void ajusta_oom()
{
  ofstream fi;
  char nom[30];

  // Obtenemos el nombre del fichero, aunque estemos haciéndolo
  // a lo C++, uso sprintf() aquí porque es más rápido.
  sprintf(nom, "/proc/%d/oom_adj", getpid());

  // Abrimos el fichero
  fi.open(nom);
  if (fi.fail())
    error("No puedo abrir oom_adj");

  // Escribimos 15 en el fichero, para dar más "apeletas de muerte"
  // a este proceso. Ver:
  // http://totaki.com/poesiabinaria/2010/04/cuando-un-proceso-se-come-la-memoria-de-nuestro-sistema/
  fi<<"15";
  if (fi.fail())
    error("No puedo escribir oom_adj");

  fi.close();
}

La ejecución será escalonada, es decir, ejecutamos, y antes de pulsar intro ejecutamos free(), así vemos cómo se va gastando la memoria tal y como indica la imagen.
testi
Lo que quiero demostrar es que el puntero al vector v, cada vez que ejecutamos new vector sobre ella, restablece su valor, y por tanto, aunque la memoria asociada a ese vector sigue reservada (y encima tiene 8000000 de elementos), ya no tenemos forma de acceder a ella, ya no sabemos la dirección de memoria con la que accedemos; vamos que el hecho de que no sea accesible no significa que no esté reservada, en uso y molestando, porque el sistema no podrá utilizar esos datos para otras cosas.
En este caso, la solución a este problema habría sido escribir:

1
delete v;

al final de la función gasta_memoria(). Aunque en ocasiones esto no es tan fácil de ver.

Cuando el programa se cierra…

Generalmente el sistema operativo, que sí que sabe lo que el proceso ha reservado y consumido, libera la memoria, y a veces puede invertir un rato, aunque a veces no aparezca toda la memoria como libre directamente, al cabo de unos minutos (como mucho) ya estará listo.

Si el sistema no reacciona…

Recuerdo, que si hemos reservado mucha, mucha memoria, el sistema dejará de responder, para ello podemos pulsar Alt+SysRq+F, y el programa morirá rápidamente (pero, pulsad estas teclas, sólo una vez, y esperar).

Foto: tao_zhyn (Flickr) Compartido con CC-by a 26/11/2011

C.I. XIII: Tutorial Emacs, Taza VIM, supercomputador 10 petaflops, OSWC, Ubuntu ya no es el rey, IE baja y Chrome sube

Domingo, 27 de Noviembre de 2011 Gaspar Fernández Sin comentarios

Hace mucho que no recopilo enlaces, y es que a veces, por trabajo, ni puedo leer las noticias, ni el twitter a gusto, y mucho menos profundizar en algunos temas.

  • Curso intensivo de EMACS por parte de IBM. Me entero desde el blog MuyLinux y ya que es mi entorno de desarrollo preferido, tengo que promocionarlo un poco.
  • Aunque la noticia tiene un mes (K-Computer superó la barrera de los 10 petaflops). Vamos, ¡ una verdadera máquina para hacer raíces cuadradas ! Recuerdo cuando hacía simulaciones en los ordenadores de la facultad y nos tirábamos 2 ó 3 minutos a que salieran los resultados. Con uno como estos para todo el aula, hubiéramos terminado las prácticas en 20 minutos. Bueno, el paralelismo cuenta, hubiéramos aprendido algo muy interesante.
  • Conferencia Internacional de Open Source: Han cambiado de sede, y de fechas, ahora anuncian la Open Source World Conference para Granada, los días 12 y 13 de Enero. Aunque ya está en curso de forma anual la Libre Software World Conference, todos estos eventos son necesarios para el avance del Software Libre. ¿La cancelarán los políticos dos semanas antes de abrir sus puertas? ¿Invertirán menos dinero en las jornadas? ¿ Se meterá algún patrocinador que nada tenga que ver con el software libre?¿Predicarán con el ejemplo?  Se supone que deberían usar este tipo de software para que sea creíble que funciona.
  • Ubuntu, ya sí que no es la distribución más popular. Hace tiempo Ubuntu era la que más gustaba a la gente, aunque personalmente nunca me atrajo bastante, hace un par de años alcanzó un grado de estabilidad importante, y no estaba mal. Pero no quisieron (ni deben) quedarse estancados, pero parece que muchas decisiones que han tomado les han pasado factura.
  • Taza Vim. Si antes ponía un tutorial para Emacs, ahora es una cheatsheet en forma de taza de desayuno para aquellos que utilizáis Vim !

Bueno, también quiero compartir el gráfico de las últimas estadísticas de StatCounter, donde vemos la pérdida de cuota de mercado de Internet Explorer, que va por el 40%, y aunque sigue siendo el más usado (que tenga cuidado en Europa), muchos usuarios han preferido prescindir de una aplicación que viene instalada en su ordenador y han instalado otra mejor. También podemos ver que Chrome ha crecido mucho estos meses, y ya le planta cara seriamente a Firefox, llegando a superarle en algunos lugares:

112011stc 112011stc_eu 201111stdes
En todo el mundo En Europa En España

Conociendo el proceso que me ha enviado una señal (signal)

Jueves, 24 de Noviembre de 2011 Gaspar Fernández Sin comentarios

Hace tiempo hablábamos de capturar señales, aunque en ocasiones, es necesario saber quién me envía esa señal, si por ejemplo nos envían un SIGINT o SIGTERM, tal vez queremos saber qué proceso nos quiere muerto y qué usuario lo ha invocado. O tal vez estamos esperando una señal de control (SIGUSR1, por ejemplo) por parte de un proceso cliente específico.

El problema es que por nuestro modo actual de direccionar señales (con signal(señal, funcion)) sólo comunicamos el número de señal que se ha recibido, sin más información.

signals_from

Para capturar esta información necesitamos utilizar sigaction para establecer la función a la que llamaremos cuando llegue la señal, para utilizarla podemos utilizar el siguiente código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

void recibe_signal(int signum, siginfo_t *siginfo, void *context)
{
  /* Mostramos toda la información necesaria */
  printf ("[%d] Recibida %d (%s) de %d (UID: %d) ¿Error? %d \n",
      getpid(),
      signum,
      strsignal(signum),
      siginfo->si_pid,
      siginfo->si_uid,
      siginfo->si_errno);
}


int main(int argc, char *argv[])
{
    struct sigaction sact;
   
    sigfillset(&sact.sa_mask);
    /* Definimos la función callback */
    sact.sa_sigaction = recibe_signal;
    /* Queremos usar el callback sigaction en lugar del dado por signal() */
    sact.sa_flags     = SA_SIGINFO;

    sigaction(SIGUSR1, &sact, NULL);

    /* Bucle infinito, para cerrar el proceso, utilizar kill -9 PID */
    while (1)
      pause;

    return 0;
}

Como vemos sigaction tiene 3 parámetros:

  • La señal que queremos capturar
  • Un registro de tipo struct sigaction
  • La acción que se ejecutaba antes, por si queremos guardarla para restaurarla más tarde

Dentro del registro, tendremos como valores importantes (struct sigaction act):

  • sact.sa_sigaction : que especifica la función que la llamaremos, esta función será del tipo void funcion(int, siginfo_t*, void*), donde el primer int recibirá la señal que nos han enviado (tal y como hacía la función que asignábamos con signal), el segundo parámetro será información asociada a la señal, y la tercera el contexto de ejecución.
  • sact.sa_handler : será la función a la que se llama, es la misma que cuando hacemos signal(señal, funcion)
  • sact.sa_flags : Es un conjunto de flags, si especificamos SA_SIGINFO, estaremos dando paso a la función especificada por sa_sigaction, si no utilizaremos sa_handler. Aunque esta variable vale para más cosas, para esta práctica nos vale con saber esto. (man sigaction para más info)
  • sact.sa_mask
  • : Nos proporciona una máscara de las señales que serán bloquedas, podemos utilizar sigfillset() para rellenar toda la máscara automáticamente. Si queremos que unas se bloqueen y otras no podemos utilizar sigaddset() y sigdelset()

Ahora bien, la función que se llamará cuando venga una señal tendrá el prototipo que hemos visto antes con tres parámetros: la señal recibida, la información de la señal con un puntero a siginfo_t y el contexto de ejecución, que se pasará con un puntero a void, que por ahora no utilizaremos. La estructura que controla la información de la señal entre otros muchos datos nos facilitará lo siguiente:

  • si_pid : PID que nos envía la señal (y esta acción da título al post)
  • si_uid : Usuario que ejecuta el proceso que nos manda la señal
  • si_errno : Algún error que haya causado la señal
  • … para más información, man sigaction

Para preparar la sentencia tendremos que escribir varias líneas definiendo los valores del registro así como la llamada a la función sigaction(), por lo tanto podremos crear una función que tenga los parámetros más comunes a la hora de definir este tipo de acciones, así lo llamamos como a signal():

1
2
3
4
5
6
7
8
9
10
11
12
int sigact(int signum, void funcion(int, siginfo_t *, void *))
{
    struct sigaction sact;
   
    sigfillset(&sact.sa_mask);
    /* Definimos la función callback */
    sact.sa_sigaction = funcion;
    /* Queremos usar el callback sigaction en lugar del dado por signal() */
    sact.sa_flags     = SA_SIGINFO;

    return sigaction(signum, &sact, NULL);
}

En esta función es importante poner bien el prototipo de la función como parámetro, eso lo comenté en un post anterior sobre callbacks

Ahora, vamos a dejar el código más bonito, este programa implementará el control de errores y nos permitirá salir cuando recibamos 5 SIGINT (pulsemos 5 veces control+C):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

void error(char *cadena);
int sigact(int signum, void funcion(int, siginfo_t *, void *));
void llegasigint();
void recibe_signal(int signum, siginfo_t *siginfo, void *context);

int main(int argc, char *argv[])
{
  if (sigact(SIGUSR1, recibe_signal)==-1)
    error("No puedo establecer SIGUSR1");

  if (sigact(SIGINT, recibe_signal)==-1)
    error("No puedo establecer SIGINT");
  if (sigact(SIGTERM, recibe_signal)==-1)
    error("No puedo establecer SIGTERM");
  if (sigact(SIGUSR2, recibe_signal)==-1)
    error("No puedo establecer SIGUSR2");
  if (sigact(SIGQUIT, recibe_signal)==-1)
    error("No puedo establecer SIGQUIT");

    /* Bucle infinito, para cerrar el proceso, utilizar kill -9 PID */
    while (1)
      pause();

    return 0;
}

void error(char *cadena)
{
  fprintf(stderr, "ERROR: %s (errno: %d: %s)\n", cadena, errno, strerror(errno));
  exit(1);
}

void llegasigint()
{
  static int num=0;     /* No he querido usar variables globales */

  num++;
  if (num==5)
    {
      printf ("FIN del programa\n");
      exit(1);
    }
}

void recibe_signal(int signum, siginfo_t *siginfo, void *context)
{
  /* Mostramos toda la información necesaria */
  printf ("[%d] Recibida %d (%s) de %d (UID: %d) ¿Error? %d \n",
      getpid(),     /* PID del proceso actual */
      signum,       /* Número de señal recibida */
      strsignal(signum),    /* Señal escrita en texto (inglés) */
      siginfo->si_pid,  /* PID del proceso que nos manda la señal */
      siginfo->si_uid,  /* Usuario que nos manda la señal */
      siginfo->si_errno);   /* Error producido */

  if (signum==SIGINT)
    llegasigint();
}

int sigact(int signum, void funcion(int, siginfo_t *, void *))
{
    struct sigaction sact;
   
    sigfillset(&sact.sa_mask);
    /* Definimos la función callback */
    sact.sa_sigaction = funcion;
    /* Queremos usar el callback sigaction en lugar del dado por signal() */
    sact.sa_flags     = SA_SIGINFO;

    return sigaction(signum, &sact, NULL);
}

Tiempos difíciles

Martes, 22 de Noviembre de 2011 Gaspar Fernández 2 comentarios

Llevo muchos días saturado de trabajo y no tengo mucho tiempo para escribir en el blog. Suelo dedicar un tiempo para contestar los correos y los comentarios que dejáis, pero, aunque tengo muchos posts en la cabeza no tengo tiempo para escribirlos.

Aunque intento sacar unos minutos a la semana :)

Mis disculpas.

Categories: General Tags:

Instalar y configurar un servidor LAMP

Lunes, 17 de Octubre de 2011 Gaspar Fernández Sin comentarios

Lámpara de bajo consumoEn esta ocasión el servidor LAMP a instalar corresponderá con Linux + Apache + MySQL + PHP, intentaré dejarlo todo funcionando.

Éste es el servidor local que suelo utilizar para mis proyectos web, de todas formas no me quiero meter en necesidades muy avanzadas, ni de seguridad (es un servidor local para hacer pruebas, desarrollar webs, y correr servicios locales; no un servidor de producción), si el servidor está cerrado al exterior, mejor. Esta guía dejará el servidor operativo, lo que hagamos con él, es cosa nuestra.

En este tutorial tocaré los siguientes puntos:

Instalación de software

En este punto, supongo que tenéis una máquina GNU/Linux instalada, si necesitas ayuda para instalar una distribución, puedes probar con este enlace.
Esta parte, será especial para los derivados de Debian o Ubuntu, ya que el nombre de los paquetes es especial para dicha distribución. Lo instalamos desde terminal:

$ sudo apt-get install libapache2-mod-php5 php5-gd libgd-tools php5-curl php5-mcrypt php-pear mysql-server php-mysql

Con esto se instalarán más paquetes y dependencias que serán necesarios para nuestro servidor, además, cuando se esté instalando el servidor MySQL nos preguntará qué contraseña queremos para root:
Root MySQL
No tiene que ser la misma que root de nuestro sistema, será una clave para controlar todas las bases de datos del servidor.

apache2: Could not reliably determine the server’s fully qualified domain name, using 127.0.1.1 for ServerName

Si nada más instalar tu servidor web dice esto, pasar no pasa nada, pero molesta un poco que de un fallo, para ello tenemos que editar /etc/apache2/httpd.conf y escribir lo siguiente:

ServerName localhost

Reiniciamos el servidor y ya está todo correcto:

$ sudo service apache2 restart

Creando el directorio de trabajo

Yo utilizo esto para tener las webs alojadas en /home, ya que lo tengo montado en la partición más grande de mi disco duro. Aquí tenemos varias opciones:

  • En el directorio personal de nuestro usuario principal (es rápido y no está mal si sólo nosotros usamos el ordenador). Por ejemplo /home/usuario/proyectos/www/
  • Crear un directorio en /home; por ejemplo /home/servidor/www/
    • Tras ello, debemos darle privilegios de escritura al usuario con el que vamos a trabajar.
    • O por el contrario, si trabajarán varios usuarios, podemos crear un grupo (por ejemplo, desarrolloweb), dar privilegios de escritura al grupo y añadir todos los usuarios a ese grupo.

      $ sudo groupadd desarrolloweb
      $ sudo mkdir -p /home/servidor/www
      $ sudo chgrp -R desarrolloweb /home/servidor/www
      $ sudo gpasswd -M usuario1,usuario2,usuario3,…,usuarioN desarrolloweb

  • Crear un usuario (desarrolloweb) y un grupo (desarrolloweb) y dar privilegios a los usuarios que vayan a acceder como en el apartado anterior.
  • Utilizar el mismo usuario con el que se ejecuta apache (apache, httpd, www-data, depende del sistema, podemos mirar el archivo /etc/passwd para ver todos los usuarios). Para ese usuario crear un directorio en /home, asignar el grupo a desarrolloweb e introducir usuarios en ese grupo:

    $ sudo mkdir -p /home/servidor/www/
    $ sudo usermod -d /home/servidor/
    $ sudo chown -R www-data:desarrolloweb /home/servidor
    $ sudo gpasswd -M usuario1,usuario2,usuario3,…,usuarioN desarrolloweb

    Este último método puede sernos útil cuando nuestros scripts escriban en archivos dentro de nuestro árbol, siempre que esos directorios tengan a www-data como usuario

  • Normalmente, nuestra instalación de apache creará también un grupo llamado www-data (o apache, o httpd, etc), por lo que podemos añadir a todos los usuarios, en lugar de a desarrolloweb a www-data.
  • Se nos pueden ocurrir muchas más formas de organizarnos.

Nota: si optamos por alguna configuración de grupo, tenemos que dar permisos 775 a los directorios del servidor. Y cuando queramos que algún archivo sea modificado/creado por el servidor web debemos darle permiso al este servidor. Si los usuarios que pueden acceder pertenecen al mismo grupo que el servidor web (recordad, www-data, httpd, apache…) con dar permiso al grupo basta, si no, tendremos que modificar los permisos del fichero para permitir a otros la escritura (chmod o+w archivo). Ahora un truco, cuando estemos creando archivos desde terminal, con un usuario perteneciente a desarrolloweb podemos hacer lo siguiente:

$ newgrp desarrolloweb
$ umask 0002

Con esto conseguimos que todos los ficheros que creemos en la sesión pertenezcan al grupo desarrolloweb y tengan los permisos 664 (lectura y escritura para propietario y grupo y lectura para otros) y los directorios, 775 (lectura, escritura y ejecución (o entrada) para propietario y grupo, lectura y entrada para otros).

Una vez tenemos el directorio de trabajo creado, podemos crear enlaces a el dentro de los directorios personales de los usuarios que van a trabajar para que tengan un acceso más rápido, por ejemplo, para mi usuario, crearé un enlace a /home/gaspy/proyectos/www:

$ ln -s /home/servidorweb/www /home/gaspy/proyectos/www

Cambiando el directorio de trabajo en el servidor web

Una vez tenemos nuestro directorio de trabajo, tenemos que decirle a Apache que lo use, por defecto utilizará /var/www ; queremos utilizar nuestro directorio de trabajo. Los valores por defecto no los tocaremos, por si algún día queremos utilizarlos como plantilla ( y por si alguna actualización los re-escribe). El método que muestro es más o menos general, aunque tal vez dependiendo de la distribución varíe algún nombre de archivo:

$ cd /etc/apache2
$ sudo a2dissite 000-default

La utilidad a2dissite elimina el enlace 000-default (dentro de /etc/apache2/sites-enabled/) a sites-available/default, por lo que copiaremos ese último y crearemos otro enlace en sites-enabled para que sea nuestro sitio principal (ayudándonos de la utilidad a2ensite). Tanto a2dissite como a2ensite son dos scripts que nos facilitan un poco la vida a la hora de manejar esos enlaces.

$ sudo cp sites-available/default sites-available/trabajo
$ sudo a2ensite trabajo
$ sudo nano sites-available/trabajo

Ahora debemos modificar algunas líneas de ese documento relativas a la ruta de trabajo, sustituyendo donde ponga /var/www por /home/servidorweb/www dejándolas así:

DocumentRoot /home/servidorweb/www
<Directory /home/servidorweb/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>

Aunque más adelante modificaremos alguna línea más en este archivo (podemos hacerlo todo seguido, pero para este artículo prefiero indicarlo paso a paso), salvamos y salimos (en nano, Control-X).

Probando el servidor

Vamos a introducir un archivo index.php en /home/servidorweb/www/ para que se vea cuando accedemos al raíz de nuestro servidor. Sólo por hacer la prueba, puedes saltar este paso si quieres. El archivo contendrá (debéis sustituir UTF-8 por la codificación con la que creéis el archivo, y la zona horaria Europe/Madrid por la zona horaria donde estéis):

1
2
3
4
5
<?php
   date_default_timezone_set('Europe/Madrid');
   echo "<h1>Funciona!</h1>";
   echo '<p>'.htmlentities('El servidor está funcionando. Son las: '.date('H:i').' del día '.date('d/m/Y'), ENT_COMPAT, 'UTF-8').'</p>';
?>

Para ver el resultado, si estáis en el mismo ordenador donde habéis instalado el servidor, acceded a http://localhost/ , si no, acceded a través de la IP de la máquina servidor, debería dar un mensaje como este:
Server funcionando

Permitir cambiar las opciones de directorios con .htaccess

Es muy útil si vamos a utilizar mod_rewrite, contraseñas en directorios o modificar filtros, documentos de error, etc. aunque por defecto viene deshabilitada cualquier configuración que podamos hacer desde aquí. Para ello, debemos abrir el mismo archivo de antes /etc/apache2/sites-available/trabajo para edición (igual que antes, y cambiar la directiva AllowOverride de None a All (dentro de Directory /home/servidorweb/www), al final se quedaría así:

<Directory /home/servidorweb/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>

Seguramente haya otra etiqueta <Directory>, en este caso ““, con otra directiva AllowOverride que podemos dejar a None, esto es para cuando haya un archivo .htaccess en un nivel superior a nuestro directorio de trabajo, por ejemplo en /home/servidorweb; si ponemos la directiva a “All”, sí que se procesará ese archivo, aunque en este caso, si va a ser una configuración común a todo el servidor (ya que afectará a todos los subdirectorios que tengamos exportados) podemos ponerla en /etc/apache2/sites-available/trabajo.

Configurar mod-rewrite

$ sudo a2enmod rewrite

Ejecuta un script que habilita el módulo especificado. Para ver un listado de los módulos especificados podemos mirar en el directorio /etc/apache2/mods-available ; este script hará un enlace de un módulo en /etc/apache2/mods-enabled. Desde aquí podemos activar el módulo que queramos. Para desactivar ejecutamos como root a2dismod. De forma muy parecida a como hicimos con el sitio web.

Instalamos phpmyadmin

Podemos instalarlo automáticamente con nuestra distribución, por ejemplo en Debian/Ubuntu y derivados:

$ sudo apt-get install phpmyadmin

Nos pedirá la contraseña de la base de datos y listo.

Personalmente, no me gusta que mi distribución haga ciertos cambios y este es uno de ellos, me gusta hacer la instalación de phpMyAdmin de forma manual, así como la de ciertos scripts y utilidades del servidor… en ocasiones edito algún archivo de configuración por nfs y tengo un acceso directo a ellos, además, me gusta complicarme un poco la vida :)

Lo primero es descargarlo, de la web oficial. La última versión hoy es la 3.4.5 (bonito número) por tanto lo instalaremos. Primero creo un directorio para las utilidades de mi servidor local, y tras ello descomprimo ahí phpmyadmin; el archivo comprimido de phpMyAdmin se encuentra en /home/servidorweb/targz:

$ cd /home/servidorweb
$ mkdir util
$ cd util
$ tar xvzf ../targz/phpMyAdmin-3.4.5-all-languages.tar.gz

Se descomprimirá todo en el directorio phpMyAdmin-3.4.5-all-languages/ que renombraremos a pma (PhpMyAdmin), aunque el nombre es lo de menos, sólo queremos un acceso fácil:

$ mv phpMyAdmin-3.4.5-all-languages pma

A continuación vamos a dar acceso al servidor web al directorio /home/servidorweb/util/ ya que está fuera de /home/servidorweb/www/ que es el que tiene acceso desde web. Para ello creamos un nuevo archivo en /etc/apache2/conf.d/ llamado, por ejemplo utilidades.conf, y contendrá lo siguiente:

Alias /util/ “/home/servidorweb/util/”

<Directory “/home/servidorweb/util”>
AllowOverride None
Order allow,deny
Allow from all
</Directory>

Para ver los cambios recargamos la configuración del servidor:

$ sudo service apache2 reload

En este punto, si accedemos desde el navegador a nuestro servidor en la ruta donde hemos vinculado phpmyadmin, por ejemplo http://localhost/util/pma/ veremos:
pma
Ya tenemos phpMyAdmin funcionando, aunque falta un pequeño detalle (no nos impide en cierto modo trabajar, pero ya que lo instalamos lo instalamos bien). phpMyAdmin tiene funciones avanzadas como la creación de PDFs, diseñador de bases de datos, historial y algunas cosas más y para ello necesita que creemos una base de datos e instalemos algunas tablas en ella, para ello, primero crearemos el usuario pma en nuestra base de datos, lo haremos desde el comando mysql:

$ mysql -u root -p

Enter password: [introducimos la contraseña, la primera que introdujimos al principio del tutorial]
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 104

mysql> CREATE USER ‘pma’@'localhost’ IDENTIFIED BY ‘axK12jMf’
Query OK, 0 rows affected (0.03 sec)
mysql> exit

La contraseña podemos generarla con pwgen, cuando terminemos de configurar esto, no la necesitaremos para nada.
Ahora cargamos en la base de datos las tablas de phpMyAdmin (las encontramos dentro del directorio de instalación):

$ mysql -u root -p < /home/servidorweb/util/pma/scripts/create-tables.sql

Ahora damos privilegios al usuario pma para la base de datos phpmyadmin:

$ mysql -u root -p
mysql> GRANT SELECT, INSERT, DELETE, UPDATE ON `phpmyadmin`.* TO ‘pma’@'localhost’;
mysql> exit

Para terminar de configurar debemos crear el fichero config.inc.php, aunque phpMyAdmin trae un fichero llamado config.sample.inc.php que nos puede servir de plantilla. Para ello:

$ cd /home/servidorweb/util/pma/
$ cp config.sample.inc.php config.inc.php

Y editamos el archivo. Podemos ir a http://localhost/util/pma/setup/ y hacer algunos ajustes, luego podemos copiar el archivo generado en config.inc.php o, de manera manual, editando el archivo, para ello, lo primero que debemos rellenar es la línea de blowfish_secret, será una frase secreta para la autentificación de tipo cookie de la aplicación; podemos poner una frase cualquiera, lo primero que se nos ocurra, el caso es que sea secreto, podemos generarlo si queremos con:

$ pwgen -yns 46 1

El tema es que se quede algo como:

1
$cfg['blowfish_secret'] = 'Frase secreta que me acabo de inventar'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

Ahora, debemos rellenar las opciones del servidor MySQL, para ello (podemos copiar y pegar, aunque viene comentado en el archivo):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$cfg['Servers'][$i]['controluser'] = 'pma';
$cfg['Servers'][$i]['controlpass'] = 'CLAVE PMA';

/* Storage database and tables */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
$cfg['Servers'][$i]['relation'] = 'pma_relation';
$cfg['Servers'][$i]['table_info'] = 'pma_table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma_column_info';
$cfg['Servers'][$i]['history'] = 'pma_history';
$cfg['Servers'][$i]['tracking'] = 'pma_tracking';
$cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
$cfg['Servers'][$i]['userconfig'] = 'pma_userconfig';

Arriba del todo, en la segunda línea, debemos cambiar el valor por la clave que le asignamos al usuario pma.
Por otra parte, si utilizamos la base de datos adicional (phpmyadmin), necesitamos utilizar la extensión mysqli de php en lugar de mysql (puede haber problemas si no lo hacemos):

1
2
/* Select mysqli if your server has it */
$cfg['Servers'][$i]['extension'] = 'mysqli';

Si queremos, podemos incluir servidores a la lista de autentificación inicial de phpMyAdmin, con lo que podremos acceder sin contraseña a nuestro servidor (como root o como el usuario que elijamos), puede ser un método un tanto inseguro, pero si sólo estamos nosotros y tenemos el servidor cerrado al exterior no hay problema. Para ello, debajo de la identificación del primer servidor (las líneas que hemos añadido), añadimos lo siguiente en config.inc.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$i++;
$cfg['Servers'][$i]['verbose'] = 'Servidor Local';
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['port'] = '';
$cfg['Servers'][$i]['socket'] = '';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'NUESTRA CLAVE DE ROOT DE MYSQL';
$cfg['Servers'][$i]['controluser'] = 'pma';
$cfg['Servers'][$i]['controlpass'] = 'CLAVE PMA';
/* Ponemos esto de nuevo */
/* Storage database and tables */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
$cfg['Servers'][$i]['relation'] = 'pma_relation';
$cfg['Servers'][$i]['table_info'] = 'pma_table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma_column_info';
$cfg['Servers'][$i]['history'] = 'pma_history';
$cfg['Servers'][$i]['tracking'] = 'pma_tracking';
$cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
$cfg['Servers'][$i]['userconfig'] = 'pma_userconfig';

RIP Dennis Ritchie

Domingo, 16 de Octubre de 2011 Gaspar Fernández 2 comentarios

Muchos medios de comunicación y blogs ( 1, 2, 3, 4, 5 por ejemplo ) ya informaron de la noticia. Es una lástima que una de las grandes mentes del siglo XX y parte del XXI pasara tan desapercibida, y es que nos enteramos de la noticia hace 3 días habiendo sucedido hace una semana. Y es que sin él, este blog no existiría (C / C++ / PHP (hecho en C) / Linux (tipo Unix)), tal vez muchas de las cosas que hacemos en el ordenador no serían posibles, a lo mejor ni tendríamos ordenadores en casa, ni MP3, ni gadgets, ni smartphones, tal vez sea demasiado decir, puede que en un mundo paralelo todo esto exista sin su aportación lo que es seguro es que nada de esto sería como lo conocemos.

Dennis Ritche dejó su huella en el mundo de la informática, y una gran huella, si pudiéramos contar cuánto tiempo invirtió en su vida aprendiendo todo lo que tuvo que aprender y trabajando en su legado a la humanidad y todo el tiempo que el resto de la humanidad ha invertido utilizándolo estaríamos ante una persona situada en el Top 10 de la edad contemporánea. Desde aquí, le doy las gracias.

Después de enterarnos de esta pérdida, es inevitable compararla con la muerte de Steve Jobs, pocos días antes, alguien que sin duda, también ha hecho mucho por la tecnología, aunque se movieron en campos diferentes, uno nos proporcionó la base y las herramientas, otro utilizó esas herramientas para construir algo mayor y ver futuro en cosas que nadie consideraba útiles.

Y pensar que hace unos días estuve hablando de él en otro blog.
¡Descanse en paz Dennis Ritchie!

Guía de supervivencia para disfrutar de Linux Mint Debian Edition XFCE (IV : Soporte de idioma, tipografías y plugins de XFCE, complementos, efectos de escritorio con Compiz Fusion)

Jueves, 29 de Septiembre de 2011 Gaspar Fernández Sin comentarios

Hasta ahora, aunque en la instalación especificamos que queríamos el sistema en idioma español, era sólo para la instalación y algunas aplicaciones que ya instalaban el soporte para varios idiomas. Esto es así porque la instalación no requería de conexión a Internet, y en el DVD de instalación no se incluían los idiomas adicionales. Por ello tendremos que instalarlos.

Este post será largo, quiero incluir detalles de muchas cosas, y pongo aquí el índice:

Instalar paquetes de idioma para varias aplicaciones

A partir de ahora, instalaremos los paquetes de idioma español para Firefox, Thunderbird, LibreOffice y páginas del manual (man):

$ sudo apt-get install firefox-l10n-es thunderbird-l10n-es libreoffice-l10n-es manpages-es

También encontramos paquetes para Chromium o para la plataforma KDESC y muchos más.

Si queremos instalar los soportes de ortografía de Firefox debemos dirigirnos a esta dirección y podremos descargarlo e instalarlo directamente en el navegador.

Configuración de Linux Mint XFCE

Este paquete no viene instalado de serie, aunque estaría bien; a primera vista puede ser parecido a el administrador de configuración de XFCE (menu/Settings o Configuración/Administrador de Configuración; ejecutable: xfce4-settings-manager), aunque tiene algunas cosas más. Nos permite configurar la impresora, dispositivos bluetooth, usuarios, gestor de paquetes, monitor de sistema, diagnóstico de disco, copias de seguridad, etc. En definitiva es un centro de control donde podemos acceder a todo lo que tenemos en menu/Settings o Configuración , pero de una forma organizada.

Cuenta además con un grupo llamado Personalizar que nos permite elegir qué aplicaciones introducimos ahí de forma que tengamos un acceso directo.

xfce4-mintConfig

Para instalarlo,

$ sudo apt-get install mintconfig-xfce

Algo destacable acerca de esta aplicación y de los componentes que instala es que:

  • Permite configurar el sistema para iniciar los efectos de escritorio
  • Tiene herramientas para configurar recursos de red compartidos
  • Editor de configuración avanzada de XFCE.
  • Configuración de NDISwrapper (Controladores inalámbricos de Windows)
  • Copia de seguridad de tu home (mintBackup)
  • Bloqueador de dominios (mintnanny)
  • Soluciones a problemas con tipografías en algunos monitores a un click.

Si te gusta personalizar tu ordenador, es conveniente tenerlo a mano.

Instalar tipografías adicionales

Las tipografías suelen ser una parte importante para todos aquellos que diseñamos, escribimos, compartimos… el tipo de letra en sí expresa ya parte del mensaje. He oído varias veces decir que “instalar tipos de letra en Linux es complicado y que no hay tantas opciones como en otros sistemas”, cuando los formatos para los tipos de letra son los mismos para todos. Aquí instalaremos casi 600 tipografías ttf (TrueType)  sin complicarnos mucho la vida. Y ahora deberemos pasar al menos un par de días mirando todas las fuentes instaladas (muchas de ellas son libres).Tipografías

$ sudo apt-get install ttf-summersby ttf-ubuntu-title ttf-prociono ttf-liberation ttf-linux-libertine ttf-sjfonts ttf-okolaks ttf-opendin ttf-mplus ttf-georgewilliams ttf-femkeklaver ttf-engadget  ttf-dustin ttf-droid  ttf-breip  ttf-century-catalogue  ttf-comfortaa  ttf-baekmuk  ttf-ancient-fonts  ttf-adf-verana  ttf-aenigma  ttf-alee ttf-adf-baskervald  ttf-adf-libris ttf-bitstream-vera ttf-isabella ttf-xfree86-nonfree

Además, si alguien echa de menos los tipos de letra “de toda la vida” de Windows (Arial, Times New Roman, Verdana, Trebuchet), podemos instalarlos de la siguiente manera:

$ sudo apt-get install ttf-mscorefonts-installer

Complementos para el panel de XFCE

Los paneles pueden hacer mucho más de lo que hacen por defecto, por eso vamos a personalizarlos y a añadir complementos nuevos. Empecemos por el panel de arriba donde están los programas, la lista de escritorios y el botón de menú (arriba a la izquierda).

El primer paso, para añadir elementos es hacer click con el botón derecho en el panel > Panel > Añadir nuevos elementos:

PanelTras ello aparecerá una nueva ventana donde seleccionaremos el complemento a instalar, como primer complemento adicional escogeremos un control de volumen.

screenshot-17-09-2011-010935

Vamos a instalar unos cuantos plugins, aunque muchos de ellos los dejo para que cada uno descubra los que más le gustan o le resulten más útiles:

$ sudo apt-get install xfce4-clipman xfce4-clipman-plugin xfce4-cpugraph-plugin xfce4-genmon-plugin xfce4-mount-plugin xfce4-notes-plugin xfce4-notes xfce4-systemload-plugin xfce4-smartbookmark-plugin xfce4-timer-plugin  xfce4-verve-plugin xfce4-wmdock-plugin xfce4-datetime-plugin

Los cambios que diré ahora son algunas propuestas que a mí me resultan útiles:

  • Cambio del plugin por defecto de hora por el plugin “Fecha y hora”. Para ello debemos pulsar sobre el elemento actual de hora y elegimos “Quitar” del menú contextual. Luego añadir el elemento “Fecha y hora”, este elemento nos dará más información y, además, al hacer click con el botón izquierdo, nos mostrará un calendario.
    Calendario XFCE
  • Notas de escritorio. Para ello añadimos el plugin “Notas”
    Notas
  • . Nos permite ver los dispositivos que tenemos montados y desmontarlos a un clic.
    screenshot-17-09-2011-030935_2Aunque la configuración que viene por defecto no me gusta demasiado, propongo una configuración más práctica.
  • Clipman. Este complemento nos permite almacenar lo que vamos copiando en el portapapeles. Imagina que copiamos un texto, lo pegamos y seguimos trabajando, copiamos otro texto, y ahora necesitamos pegar el primer texto que copiamos. Este complemento nos ayuda a llevar a cabo esas acciones.
    Lo podemos ejecutar también como parte de la bandeja de sistema accediendo a menu/Settings o Configuración/Sesión e Inicio/Autoarranque de Aplicaciones y marcando Clipman.

Otras utilidades de XFCE

Ahora instalaremos algunas aplicaciones para XFCE que nos serán útiles en algunas circunstancias

  • xfce4-volumed . Esta aplicación es muy útil para usuarios de portátiles o teclados multimedia, ya que nos permitirá modificar el volumen del sistema con las teclas específicas para ello.
    Lo instalamos de la siguiente manera:
    $ sudo apt-get install xfce4-volumed

    Linux Mint configura este paquete para que se arranque automáticamente al iniciar XFCE.

  • orage . Es un gestor de calendario donde podemos anotar citas, eventos y tareas. Es muy sencillo, rápido y se integra bien con XFCE.
    Lo instalamos de la siguiente manera:
    $ sudo apt-get install orage
  • xfswitch-plugin . Es otro plugin para el panel que nos permite cambiar la sesión gráfica de usuario o identificarnos como un usuario nuevo sin cerrar la sesión actual. Podremos cambiar entre sesiones con Control+Alt+F7/F8/F9…
    Lo instalamos de la siguiente manera:
    $ sudo apt-get install xfswitch-plugin
  • epdfview . Es un visor de pdfs muy ligero. Tiene menos opciones que evince, pero para un visionado rápido nos vale.
  • pcmanfm . Es un administrador de archivos muy ligero, con soporte para pestañas y acceso a sistemas de archivos remotos (ssh/ftp/…)
    pcmanfmPodemos utilizarlo en lugar de Thunar para abrir directorios si nos vamos a Menu/Settings o Configuración/Aplicaciones preferidas > Utilidades y ahí seleccionamos PCMan File Manager:
    Por defecto PCManFM

Efectos de escritorio con Compiz

Seguro que es una de las partes que más llama la atención, y una de esas cosas que utilizaremos para sorprender a las visitas enseñándoles un entorno gráfico del futuro. Aunque, además de tener un entorno gráfico más amigable, si tenemos una tarjeta gráfica decente (Ati/NVIDIA o incluso Intel), y más o menos nueva (por lo menos de 2004/2005), podemos disfrutar de un mejor rendimiento general del sistema y de un entorno mucho más fluído (ya que dejamos algunas tareas más para la GPU) y tendremos un valor añadido en algunos efectos.

Cubo CompizYo no soy muy partidario de efectos elaborados y lentos, aunque el cubo de escritorios es una excepción, aunque lo tengo configurado para que tarde menos de medio segundo. Aunque tenemos otros efectos útiles como por ejemplo hacer Zoom a la pantalla (muy útil para diseñadores en algunas ocaiones, ¿quién no se ha acercado tanto al monitor para saber si dos líneas son paralelas?), o por ejemplo una previsualización de la ventana al pasar el ratón por encima de la barra de tareas.

Para instalar:

$ sudo apt-get install compiz-gtk compiz compizconfig-settings-manager  compiz-fusion-plugins-extra compiz-fusion-plugins-main

Ahora podremos habilitar Compiz desde la configuración de Linux Mint (xfce4-mintconfig), seleccionando Xfce mintDesktop y dentro del nuevo diálogo, en la pestaña Compiz Fusion, habilitando Compiz Fusion.

Configurar CompizAhora, debemos ir a la configuración de Compiz, Compiz Config Settings Manager, o CCSM; podemos hacerlo ejecutando el comando ccsm, o desde la misma pantalla de configuración de Linux Mint pulsando en Configurar Compiz con CompizConfig.

ccsmA partir de aquí os dejo para configurar vuestros efectos de escritorio a medida.

Apéndice I: Configurando el plugin Mount Devices

Configurar esta extensión no es complicado. Si vimos la captura anterior, se mostraban todos los puntos de montaje (yo tengo muchas particiones, para /usr, /var, /boot, etc y no me interesa desmontarlas, es más, no quiero verlas ahí; por otra parte, puede que utilice recursos de red y sí que quiera desmontar estos. Empecemos haciendo clic con el botón derecho del ratón y seleccionando Propiedades:

Mount props1Podemos mostrar un mensaje nada más desmontar el dispositivo, pero mejor desmarcamos esa casilla, ya que vamos a hacer algo más completo en la siguiente pestaña. También podemos seleccionar un icono, eso es a gusto del usuario.

En la siguiente pestaña, Commands, encontramos comandos personalizados a la hora de montar y desmontar volúmenes.

Command Mount pluginEn este punto, marcaremos la casilla “Custom commands“, para indicar comandos para montar/desmontar unidades manualmente. Los parámetros de montaje (Execute after mounting y Mount command) los podemos dejar en blanco, ya que el montaje se reserva para todos los puntos especificados en /etc/fstab y no para los dispositivos que el sistema vaya descubriendo.

Aunque para Unmount command, yo tengo puesto lo siguiente:

pumount %d && notify-send “%d desmontado correctamente” || notify-send “Hubo un problema al desmontar %d”

Es necesario tener pmount instalado. Con esta línea podremos ver un mensaje como notificación ya haya tenido éxito o no la operación. Esta línea no valdrá para ubicaciones de red aunque podemos vincular la operación a un script más complejo.

Por último, en la pestaña File Systems, podemos indicar qué queremos mostrar y qué no queremos mostrar

File Systems Mount devicesEn esta pestaña, podemos seleccionar la opción de  representar sistemas de archivos de red (Display network file systems), expulsar unidades de CD (Eject CD-drives) mostar sólo los puntos de montaje y no el dispositivo o el UUID, lo cual puede llegar a ser incómodo (Display mount points only), y por último excluir algunos sistemas de archivo (Exclude specified file systems), y es en esa opción donde escribimos separados por espacios los puntos de montaje separados por espacios que no queremos mostrar; en mi caso, son los puntos de montaje del sistema.

Visita otras webs de la red