Utilizando libparted para obtener información de nuestros discos

Pese a que en este blog normalmente solo escribe Jose Carlos (vosotros le llamáis rooibo), a partir de ahora yo también iré escribiendo de vez en cuando, a ver si así esto coge un poco mas de vida, ya que Jose Carlos no siempre tiene tiempo. Me llamo Noemi y a pesar de que es la primera vez que escribo en un blog como este (bueno, mas bien es la primera vez que escribo en un blog que no se hable solo de curiosidades tonterías) espero estar a la altura.

Libparted es una librería desarrollada en C por el proyecto GNU, la cual estoy utilizando casi a diario en el nuevo proyecto que estamos llevando a cabo Jose Carlos y yo.

Se trata de una librería que nos permite desde listar hasta crear, borrar y modificar particiones. Fue desarrollada para el programa parted, cuya versión gráfica y más conocida es gparted

Para instalar libparted en sistemas basados en debian (como ubuntu):

apt-get install libparted1.8-dev

Una vez instalada, podemos empezar a utilizarla desde nuestros programas, pero antes de entrar en detalle, mejor empezar con un ejemplo:

#include <stdio.h>
#include <parted/parted.h>
#define MEGABYTE 1048576

int main (void)
{
PedDevice* device = NULL;
PedDisk* disk = NULL;
PedPartition* part = NULL;
PedGeometry geom;

unsigned long size;
double length;
PedSector p_size;
char *fsname;

ped_device_probe_all ();

while ((device = ped_device_get_next(device))) {
disk = ped_disk_new(device);
p_size = device->length;
size = p_size/MEGABYTE;
size = size * device->sector_size;
printf(“%s name: %s size: %uMB\n”,device->path,device->model,size);

for (part = ped_disk_next_partition (disk, NULL); part;
part = ped_disk_next_partition (disk, part)) {
geom = part->geom;
length = (double)geom.length/MEGABYTE*device->sector_size;
if(part->fs_type) {
fsname = (char*)part->fs_type->name;
} else {
fsname = “Uknown”;
}

//if(part->num > 0) {
printf(“\t%s%d %10.2fMB %s\n”,device->path, part->num,length,fsname);
//}
}

}
return 0;
}

para compilarlo es suficiente poner

gcc -lparted test.c -o test

Al ejecutarlo nos muestra una lista con nuestros discos y sus particiones (debemos ejecutarlo como root ya que libparted utiliza instrucciones a bajo nivel que requieren privilegios de administrador para funcionar)

andr0med:/home/ap0# ./test
/dev/sda name: ATA Hitachi HTS54161 size: 152576MB
/dev/sda1  146389.14MB ext3
/dev/sda2    6236.17MB Uknown
/dev/sda5    6236.14MB linux-swap
andr0med:/home/ap0#

Si miramos el código, vemos que hay dos bucles anidados (uno dentro de otro), el primero es el que lee los discos mientras que el que está dentro se encarga de iterar sobre las particiones de cada disco leído.

Lo primero que tenemos que hacer es incluir la librería

#include <parted/parted.h>

Libparted necesita escanear el sistema busca de dispositivos de almacenamiento, para ello llamamos a ped_device_probe_all:

ped_device_probe_all ();

A continuación, creamos un bucle que itera sobre ped_device_get_next, obteniendo el siguiente dispositivo cada vez que es llamada la función. Cuando no queden mas dispositivos, la función devuelve NULL y el bucle finaliza:

while ((device = ped_device_get_next(device)))

con ped_disk_new(device) a partir de un dispositivo creamos un disco para poder tratarlo como tal

disk = ped_disk_new(device);

con esto obtenemos el tamaño del disco en megabytes

p_size = device->length;
size = p_size/MEGABYTE;
size = size * device->sector_size;

de esta forma ya podemos printear nuestro disco por pantalla con su ruta en el sistema(device->path), modelo(device->model) y su tamaño en MB (size)

printf(“%s name: %s size: %uMB\n”,device->path,device->model,size);

terminado esto, entramos en el segundo bucle el cual hace lo mismo que el primero pero en este caso llamando a las diferentes particiones de nuestro disco

for (part = ped_disk_next_partition (disk, NULL); part;
part = ped_disk_next_partition (disk, part))

Como veis, es un bucle exactamente igual, pero esta vez llamando a ped_disk_next_partition. Calculamos el tamaño de cada partición encontrada en el disco, de la misma forma que hacemos para calcular el tamaño de cada disco:

length = (double)geom.length/MEGABYTE*device->sector_size;

A continuación, comprobamos si la partición tiene un sistema de archivos conocido, en caso contrario lo llamamos Uknown

if(part->fs_type) {
fsname = (char*)part->fs_type->name;
} else {
fsname = “Uknown”;
}

finalmente, printeamos nuestras particiones filtrándolas

if(part->num > 0) {
printf(“\t%s%d %10.2fMB %s\n”,device->path, part->num,length,fsname);
}

Esta condición que comprueba si el número de partición es mayor que 0, es necesaria para impedir que se muestren por pantalla particiones inexistentes por pantalla, ya que ninguna partición está identificada por un número negativo, veamos que pasa si quitamos el condicional:

andr0med:/home/ap0# ./test
/dev/sda name: ATA Hitachi HTS54161 size: 152576MB
/dev/sda-1       0.03MB Uknown
/dev/sda1  146389.14MB ext3
/dev/sda2    6236.17MB Uknown
/dev/sda-1       0.03MB Uknown
/dev/sda5    6236.14MB linux-swap
/dev/sda-1       2.49MB Uknown
andr0med:/home/ap0#

Esto es solo una pequeña parte de lo que se puede hacer con libparted, en un futuro ya volveré a hablar de ella.

Clickjacking a fondo y con ejemplos

Hoy voy a cumplir un poco con mi fama de obsesionado por la seguridad, y voy a escribir un artículo sobre clickjacking, ese extraño y misterioso término que no para de aparecer por la blogosfera y las páginas de noticias…

Y es que en seguridad informática, todos los días suceden cosas graves, pero algunas, saltan a los medios populares, se convierten en “noticia” y perciben cierto protagonismo, como si otros problemas de seguridad, no fuesen igual de recientes y graves…pero vaya, esto es como cuando un caso de asesinato salta a la prensa amarillista: lo mismo.

El clickjacking no es un agujero de seguridad en si mismo, es una forma de darle la vuelta a las tecnologías que utilizamos hoy en día, para engañar al usuario y hacerle creer que ciertas cosas, son lo que realmente no son.

Este ataque consiste en cargar una página web externa dentro de un iframe invisible (con opacidad 0, por ejemplo) y poner debajo del iframe invisible (con menor z-index), elementos xhtml para que el usuario haga click, pero que realmente, tienen el iframe invisible encima, y es quien recibirá el click.

Dicho de otra forma, imaginaos un cristal (opacidad 0) con algo debajo, intentamos tocar con el dedo lo que hay debajo, pero tocamos el cristal, esto es lo mismo que sucede cuando ponemos un iframe con opacidad 0 (invisible) encima de ciertos elementos de nuestra web: el usuario irá a hacer click en nuestros elementos, pero hará click dentro del iframe.

Ahora imaginemos que cargamos en el iframe una página de noticias, como meneame, fresqui, o digg, lo volvemos transparente, y debajo metemos un botón que diga: haz click aquí, posicionándolo justo exactamente debajo de donde aparece el botón para votar a la noticia, dentro de la página de noticias.

Cuando el usuario haga click en nuestro botón, que está debajo del iframe transparente, justo donde está el botón para votar de la web de noticias que hay cargada dentro del iframe, hará click en el botón votar de la pagina que hay dentro del iframe.

Creo que lo mejor para acabar de entenderlo es una imagen:

Sin embargo, muchos de vosotros pensaréis: y para que tanta historia, si para simular el click de un usuario, podemos realizar la petición, cargando un iframe con la dirección de destino?…es decir, podemos realizar un ataque CSRF (Cross-site request forgery).

Para entrar bien a fondo en el tema del clickjacking, tenemos que comprender primero los ataques CSRF, ya que el clickjacking es una extensión de los CSRF (a mi modo de verlo :).

Un ataque CSRF consiste en que si en una web, digamos: http://www.example.com, hay una página de noticias, y para votar una noticia, digamos la noticia número 51, se usa un enlace tal como:

http://www.example.com/noticias.php?votar=51

Podríamos crear una página con un iframe invisible apuntando a esa dirección, y cuando el usuario entre a nuestra web, sin saberlo, votará la noticia 51.

Eso es un típico ejemplo de CSRF.

Sin embargo, cuando ese tipo de ataques empezó a popularizarse, muchos sitios web, como meneame, fresqui, etc empezaron a agregar números de control a las peticiones, es decir, para realizar acciones en la web, las peticiones deben incluir un número aleatorio que te dan cuando cargas la página, de esta forma, sin ese número, no puedes hacer una petición como la anterior y votar una noticia, además, el número de control cambia por cada petición que haces.

Con esta técnica, parecía que los CSRF habían muerto, y ahí es donde aparece el clickjacking, podemos crear una web, y utilizar lo explicado arriba, para inducir a un usuario a hacer click en un botón, que realmente tiene encima, de forma invisible, un botón de otra web.

De esta forma, los números de control son enviados por el javascript de la página original, y todo sucede de forma normal.

Cabe decir, después de toda esta explicación, que existen alguna páginas que no son vulnerables a este ataque, como por ejemplo meneame, ya que no permite que cargues la web dentro de un iframe, lo mismo pasa con gmail, entre otras.

Aunque a mi me gusta hacer los experimentos con meneame, contactar con Ricardo antes de publicar nada, para que lo arregle, y entonces hacer el artículo, esta vez no puedo, por que meneame no es vulnerable a clickjacking, así que voy a hacer el experimento con fresqui.

He creado una página que utilizando las técnicas de clickjacking, crea un botón, que de pulsarlo, estarías votando esta noticia de fresqui:

http://tec.fresqui.com/cientificos-descubren-que-el-sol-no-es-una-esfera-perfecta

El ejemplo, lo podéis ver aquí, y solo funciona en firefox (paso de internet explorer :):

http://eyeideas.es/clickjacking.html

Como se puede ver en el código, hay una función javascript:

function initBoton() {
var obj = document.getElementById(“boton”);
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == ‘number’ ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in ‘standards compliant mode’
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
var finalW = myWidth-910;
finalW = finalW/2;
//910-722 = 188 (mas tamaño…238)
finalW = finalW + 248;
obj.style.position=’absolute';
obj.style.right=finalW+’px';
obj.style.top=’244px';
obj.style.display=’block';
}

Que de forma un poco sucia, posiciona el botón rojo justo debajo del botón para votar la noticia en fresqui.

El iframe es algo así:

<iframe src=”http://tec.fresqui.com/cientificos-descubren-que-el-sol-no-es-una-esfera-perfecta” style=”opacity:0;position:absolute;top:0px;left:0px;width:99%;height:95%;margin:0px;padding:0px;z-index:100;”></iframe>

Como conclusión, decir que el ataque no es tan peligroso como lo pintan, aunque tiene su potencial impacto en la seguridad del usuario.

Por cierto, el ejemplo no se lo bien que irá en otras resoluciones y tal, he intentado hacerlo bastante portable, pero no lo he probado en otro sistema mas que el mio, es una simple prueba de concepto.

Richard Stallman critica el cloud computing

Bueno, sintiéndolo mucho, y por culpa de que el trabajo me tiene demasiado ocupado, tengo que intercalar un post de opinión (yo prefiero los posts con código, los posts prácticos) antes de publicar la versión 1.1 del img2xhtml, una pena.

El caso es que según leo en meneame, Richard Stallman advierte que el Cloud Computing es una trampa.

Se conoce como cloud computing, dicho de una forma generalizada, al hecho de que la computación reside en internet, en algún sitio externo a la organización, y se consume en forma de servicio, ejemplos de esto lo tenemos en Amazon EC2, pero como mis dotes explicativas acerca de estos términos tan modernos y cools, son muy limitadas, si no sabéis lo que es cloud computing, os recomiendo este artículo y este otro.

Pero volviendo al tema de que Stallman crítica el cloud computing, y lo tacha de trampa, la verdad es que no me extraña demasiado, se veía venir de lejos.

El Cloud computing está atacando de lleno al software libre, como muchas otras cosas entorno a la web 2.0, y que nadie se escandalice cuando digo esto.

Si bien mucha gente desarrolla cosas entorno a la filosofía o estilo (o moda) de la web 2.0, y además lo hace usando software libre, y compartiendo luego sus desarrollos con la comunidad, existen muchos otros casos, como fresqui, en el cual, alguien coge un drupal (software libre), lo modifica, crea un nuevo producto en base a un producto libre, pero nunca comparte los cambios, ni enriquece a la comunidad: recibe, pero no devuelve nada.

Si bien la licencia de drupal (tristemente) permite hacer esto, es éticamente reprochable, y la realidad, es que no es raro que en la web 2.0 exista mucha gente que sigue esa tendencia: la mayoría de webs 2.0, incluso usando software libre, no son libres, estás obligado a consumirlas como servicio.

Y el cloud computing no es mas que la máxima expresión de todo esto, en lo que todo es un servicio, en el que el usuario va viendo recortado no solo su libertad, sino también su control sobre los datos que maneja.

Pero bueno, es solo una opinión, esto también depende mucho de lo que pase en los proximos años, y de muchos otros factores, aunque así de entrada, el cloud computing no me inspira confianza, y comparto la idea de Richard Stallman.

Por cierto, como ejemplo de webs 2.0 que comparten la filosofía del software libre, para demostrar que no es algo contradictorio, pondría a meneame, sin lugar a dudas, y a eyeOS.

Ambos son servicios que todos sus competidores son software privativo, salvo ellos.

Convierte imagenes JPEG en XHTML

Si, se que el título es un poco raro, pero es la forma mas rápida de describir el último lío en el que me he metido.

La historia comienza hace un año mas o menos, cuando alguien me propuso como se podría crear un captcha en PHP sin usar GD ni Imagemagick o similares, y como por aquel entonces yo ya estaba trabajando en eyeOS, tenía muy presente el tema del DHTML, y de jugar con elementos DIV con posición absoluta por todas partes, etc, por lo que pensé, que si una imagen es un conjunto de pixels, se podría pintar una imagen, con un conjunto de divs con width:1px y height:1px, y posicionándolos todos con position absolute, en su sitio.

Me di cuenta enseguida de que era viable, pero nunca me puse a hacerlo (tenía demasiado trabajo en eyeOS por aquel entonces), el caso es que hace 2 días, tras el artículo que hice sobre un programa que habíamos hecho mi novia y yo, para romper el viejo captcha de meneame, y como tenía tan reciente el uso de libjpeg, decidí empezar un nuevo mini-proyecto con ella…y ahí nació img2xhtml.

La idea es sencilla, img2xhtml es un programa que usando libjpeg, lee una imagen jpeg linea a linea, y genera un archivo xhtml de salida, que pinta exactamente la misma imagen, pero utilizando anchors (<a>) de un pixel de alto por un pixel de ancho, con el mismo background-color que tenía el pixel en la imagen original, y position absolute en el sitio que le pertoca.

Dicho así, suena muy simple, pero ya me imaginaba que no iba a ser tan fácil, nunca lo es.

En primer lugar, hay una linea que se va a repetir dentro del xhtml muchísimas veces: el pixel, por lo que si podemos reducir esa linea en 1 caracter, reduciremos considerablemente el peso total del archivo html resultante, por ello se usan anchors (<a>) en lugar de div (<div>) por que los primeros se escriben con 2 letras menos. Veamos un pixel:

<a class=w style=top:74px;left:62px;background:rgb(52,52,52) />

Un pixel como vemos, es un anchor (<a>) un poco guarro para pesar lo mínimo, que omite las comillas en los atributos html por que no contienen espacios, etc.

w es una clase css, tal como:

.w{position:absolute;height:1px;width:1px;}

De esta forma, todo lo que no es variable en un pixel, está en la clase CSS, lo que nos ahorra tamaño por pixel.

Vale, con todo esto en mente, hicimos el programa, el cual funciona bastante bien, por ejemplo, esta imagen:

Se puede ver pasada a xhtml aquí.

Lo cual, al menos en mi Firefox3, se renderiza así:

El resultado es bastante bueno, sin embargo, uno enseguida se da cuenta de que esta imagen debe tener MUCHOS elementos xhtml para pintarse así, pesa 277k, frente al original, que pesa 2,8k, además, dentro tiene:

jcarlosn@linux-wnp3:~/img2xhtml> cat tux.html | sed “s/<a/\n/g” | wc -l
4343
jcarlosn@linux-wnp3:~/img2xhtml>

4343 anchors (<a>).

Además, el problema que surge es que la CPU se dispara al abrir imágenes medianamente grandes.

Con el problema de la cpu y del tamaño en mente, estaba claro que teníamos que empezar a trabajar en ideas para reducir los elementos xhtml, le conté la idea a SirKeldon,y me picó un poco para que siguiese reduciendo el tamaño de los pixeles al mínimo, pero eso no servia para intentar reducir el número de elementos xhtml que disparan la cpu.

El segundo paso fue un poco mas complejo, hablando con mi novia, enseguida nos dimos cuenta de que había una manera fácil de reducir el número de <a> en pantalla: uniendo horizontalmente los pixels contiguos del mismo color, en un mismo elemento xhtml, alargado.

Tras hacerlo, obtuvimos una mejora considerable, sin embargo, no era suficiente para imágenes grandes, por lo que decidimos agregar un nuevo concepto: tolerancia.

La tolerancia es el tope de diferencia entre dos colores RGB, para considerarlos “iguales” y unirlos bajo un mismo elemento xhtml, de esta forma, cuanta mas tolerancia, menor calidad y mayor velocidad. Vamos a hacer una prueba con tolerancia 15: (R+-15, G+-15, B+-15):

img2xhtml -f tux.jpg -t 15 > tux_15.html

Lo cual genera esto.

Como vemos, la calidad ha bajado un poco, en mi firefox3 se renderiza así:

Vale, no es perfecto, pero, ahora el tamaño es de 89k, y la cantidad de elementos xhtml es de:

jcarlosn@linux-wnp3:~/img2xhtml> cat tux_15.html | sed “s/<a/\n/g” | wc -l
1313
jcarlosn@linux-wnp3:~/img2xhtml>

Con solo 1313 elementos xhtml, se dibuja esa imagen, si la analizamos un poco, veremos que está hecha con elementos xhtml alargados, no con pixels sueltos.

Lo mejor, es que lo probéis vosotros mismos, y jugueis un poco, no os recomiendo probar con imagenes mayores de 250×250. El programa lo podéis bajar de aquí:

Descargar img2xhtml

Compilarlo e instalarlo es como siempre, primero lo extraemos y ejecutamos ./configure:

jcarlosn@linux-wnp3:~/downloads> tar -xzf img2xhtml-1.0.tar.gz
jcarlosn@linux-wnp3:~/downloads> cd img2xhtml-1.0/
jcarlosn@linux-wnp3:~/downloads/img2xhtml-1.0> ./configure
checking for a BSD-compatible install… /usr/bin/install -c
checking whether build environment is sane… yes
checking for a thread-safe mkdir -p… /bin/mkdir -p
checking for gawk… gawk
checking whether make sets $(MAKE)… yes
checking for gcc… gcc
checking for C compiler default output file name… a.out
checking whether the C compiler works… yes
checking whether we are cross compiling… no
checking for suffix of executables…
checking for suffix of object files… o
checking whether we are using the GNU C compiler… yes
checking whether gcc accepts -g… yes
checking for gcc option to accept ISO C89… none needed
checking for style of include used by make… GNU
checking dependency style of gcc… gcc3
checking for a BSD-compatible install… /usr/bin/install -c
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands
checking for jpeg_start_compress in -ljpeg… yes
checking for zlibVersion in -lz… yes

Y luego lo compilamos:

jcarlosn@linux-wnp3:~/downloads/img2xhtml-1.0> make
make all-am
make[1]: se ingresa al directorio `/home/jcarlosn/downloads/img2xhtml-1.0′
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT libjpg.o -MD -MP -MF .deps/libjpg.Tpo -c -o libjpg.o libjpg.c
mv -f .deps/libjpg.Tpo .deps/libjpg.Po
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT libhtml.o -MD -MP -MF .deps/libhtml.Tpo -c -o libhtml.o libhtml.c
mv -f .deps/libhtml.Tpo .deps/libhtml.Po
gcc -g -O2 -o img2xhtml main.o libjpg.o libhtml.o -ljpeg
make[1]: se sale del directorio `/home/jcarlosn/downloads/img2xhtml-1.0′

Finalmente lo instalamos con:

sudo make install

Ahora para ver la ayuda del programa:

jcarlosn@linux-wnp3:~> img2xhtml -h
img2xhtml -f file [-m maxLine] [-t color tolerance]
Convert images to xhtml files

-f FILENAME Filename to convert to xhtml
-m MAXLINE Maximum number of pixels to join with tolerance
-t TOLERANCE Color tolerance to join two pixels with similar colors
into a single xhtml element (between 0-127)

img2xhtml Copyright (C) 2008 Noemi Blazquez & Jose Carlos Norte
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.

Please send bugs to jose@eyeos.org

El parametro -m (maxline) especifica el máximo largo que puede tomar un pixel estirado tragandose a su pixel de al lado, sirve para jugar con tolerancias altas sin obtener imagenes que parecen códigos de barras.

Si alguien me pregunta para que sirve todo esto, la verdad es que no lo tengo muy claro, pero…¿y lo bien que se lo pasa uno haciendo el friki y programando en C estas extravagancias?

La dirección del proyecto en sourceforge es:

http://sourceforge.net/projects/img2xhtml/

Pero aún no nos ha dado tiempo de subir los paquetes y todo eso.

Rompiendo el antiguo captcha de meneame!

Hoy para variar, hago un post un poco mas práctico que los anteriores.

El caso es que estoy ayudando a mi novia a entender C/C++, sistemas y todo eso, así que decidí que hoy programaría algo con ella (algo simple,para empezar) y como no se me ocurría nada mas ameno, pensé en programar un programa en C, que usando libjpeg, fuese capaz de leer una imagen del viejo captcha clásico de meneame (como el que usan en enchilame para el registro) y sacar los números que hay en la imagen.

Nada mas empezar, nos dimos cuenta de que los números de ese captcha, siempre salen en la misma posición, tamaño y medida, además del mismo color y misma fuente, solo varía un poco el fondo, pero poco.

Para localizar los pixeles que pertenecen a un dígito y no al fondo, basta con comprobar si su nivel de azul (colores RGB) es mayor que 100.

El programa básicamente lo que hace es leer la imagen, linea a linea (linea de pixeles) y comprobar que pixeles están con azul mayor que 100, en la linea 20, lo cual es suficiente para distinguir todo los números.

El programa junto con una imagen de ejemplo, lo podéis bajar de aquí:

Enlace

Se compila con:

gcc -ljpeg image.c -o image

Y tiene como dependencia libjpeg (y libjpeg-dev para sistemas basados en debian)

Al ejecutarlo, lee el archivo image.jpeg de su mismo directorio, y muestra por la salida estandar, los números contenidos dentro de la imagen.

Con este pequeño programa y un script en bash bastante sencillo, uno puede dar de alta cuantas cuentas como quiera, de forma automatizada en páginas que usen las versión de meneame sin recaptcha.

Prueba con el programa compilado y la imagen que viene el .tar.gz:

jcarlosn@linux-wnp3:~/captcha> ./image
724160
jcarlosn@linux-wnp3:~/captcha>

Tiene en principio, un 100% de efectividad.

Trucos y misterios de meneame

He decidido hacer un paréntesis en el tipo de entradas que agrego al blog, de carácter técnico y dirigidas a un público muy concreto, para hacer una entrada que llevo tiempo queriendo hacer (desde mucho antes de abrir este blog).

Para los despistados, una de mis aficiones es colaborar con el meneame de una forma un tanto friki (si es que todo lo que toco, lo convierto en friki) que consiste en auditar su código y comunicar los errores de seguridad que encuentro, a Ricardo, para que los arregle.

Pese a que el meneame está muy bien programado, en contra de lo que dicen algunos sujetos, es cierto que ha tenido ciertos problemas de seguridad durante su historia, desde que colaboro, he encontrado varios problemas y de gravedad variada, sin embargo, el número total de problemas de seguridad, ha sido mucho menor que en otros sites populares y con mas tiempo, y el tiempo de reacción ante estos problemas, ha sido de minutos, por lo que considero a meneame, un site muy seguro y una demostración irrefutable de que el software libre es beneficioso cara a la seguridad.

Dejando de lado las presentaciones y la explicación de mi relación con meneame, este post trata sobre algo que llevo tiempo queriendo escribir…y es que auditando meneame continuamente, he aprendido mucho de su código y sus secretos, el como funciona, etc…y hay algunas cosas que siempre he querido documentar, pero nunca he encontrado el momento.

Antes de empezar, podemos ver el código de meneame, navegando por la carpeta www/ de su repositorio svn:

http://svn.meneame.net/index.cgi/branches/version3/www/

El primer directorio que vemos, es admin/, del cual nos llama la atención que no tiene index.php, por lo que si hacemos:

http://meneame.net/admin/

Veremos un forbidden, que nos impide listar el contenido del directorio, el único archivo que hay en ese directorio, es el archivo bans.php:

http://svn.meneame.net/index.cgi/branches/version3/www/admin/bans.php?rev=1372&view=markup

El cual, nada mas empezar hace una comprobación:

if ($current_user->user_level==”god” || $current_user->user_level==”admin”) {

Esto nos lleva a nuestra primera deducción: en meneame hay dos tipos de administradores, unos conocidos como admin, y otros conocidos como god, como si fuesen dos niveles distintos de acceso.

La primera pregunta que se nos viene a la cabeza es: vale, ¿Pero que es eso de $current_user? $current_user es una instancia de la clase User, que se encuentra en:

http://svn.meneame.net/index.cgi/*checkout*/branches/version3/www/libs/user.php?content-type=text%2Fplain&rev=1547

Esta clase, como vemos, es una clase que representa a un usuario del meneame, y maneja su información, tanto su karma, como su nivel de acceso, etc.

Todo el meneame funciona con clases como esta, que representan cosas en meneame, están todas en:

http://svn.meneame.net/index.cgi/branches/version3/www/libs/

Otro ejemplo de clase como user, pero que representa links, es Link:

http://svn.meneame.net/index.cgi/*checkout*/branches/version3/www/libs/link.php?content-type=text%2Fplain&rev=1550

Para los javeros, estas clases podríamos decir que son una mezcla entre DAO y TO (Transfer Object), pero todo junto en una misma clase.

Aparte de este mecanismo de clases que representan cosas en meneame, existe otro mecanismo interesante usado en el meneame: el de los backend.

En meneame, en muchos sitios, pasamos el ratón por encima y sale un cartelito con información, por ejemplo, cuando alguien cita otro comentario en una noticia, usando #X, si pasamos el ratón por encima del #, veremos el comentario número X en una cajita amarilla, que sigue al ratón.

Esto lo consigue con unos pequeños php, que están en:

http://svn.meneame.net/index.cgi/branches/version3/www/backend/

Y que reciben un argumento, por ejemplo, el numero de comentario, y devuelven un pequeño código html, que es el que va dentro del cuadro amarillo.

Ademas de los cuadros amarillos (que también van por ajax), el backend se utiliza en realidad para recibir las peticiones Ajax de toda la web, y procesarlas, así está todo bien ordenado.

Un ejemplo de esto es el backend get_user_api_key, que está en:

http://svn.meneame.net/index.cgi/branches/version3/www/backend/get_user_api_key.php?rev=1431&view=markup

Que es quien atiende a la llamada Ajax que se produce, cuando en tu perfil, haces click sobre ver tu clave api, como vemos en su código:

if ($id != $current_user->user_id && $current_user->user_level != ‘god’ ) {

Cada usuario puede ver solo su API key, excepto los gods, que pueden ver las de todos, sin embargo, los admins no pueden.

Esto aclara un poco lo de los dos distintos niveles de acceso, admin y god.

Aparte de todo esto, tenemos otra carpeta interesante en el svn:

http://svn.meneame.net/index.cgi/branches/version3/www/api/?rev=1550

Api, que es donde se alojan los archivos php que atienden las llamadas a la API pública del meneame, una API que podemos usar, para comunicar nuestros blogs, webs o aplicaciones de terceros con meneame, vamos a ver alguna interesante:

http://meneame.net/api/url.php?url=http://www.adn.es&all=1

Con esto obtenemos todos los enlaces en meneame hacia el site www.adn.es.

Existen algunas otras API en el meneame, todas en esa carpeta, sin embargo hay un archivo muy curioso ahí:

http://svn.meneame.net/index.cgi/branches/version3/www/api/check_url_test.php?rev=1340&view=markup

Que como se puede ver, es alguna especie de prueba, pero que está en el svn desde hace mucho tiempo, y ahí sigue…misterios del código.

Aparte de todo esto, en el código de meneame hay algunas otras curiosidades, por ejemplo, un site accesible llamado mueveme, aquí:

http://meneame.net/mueveme/

El cual parece algo para acceder desde el mobil, o algo así, ni idea, no navego con el mobil.

Otra versión alternativa accesible de meneame, es la versión para nintendo DS:

http://meneame.net/nds/

Y por si la nintendo DS fuese poco, también hay para la WII:

http://meneame.net/wii/

Otra curiosidad que no acabo de entender (aunque seguro que ha sido dicha en el blog de meneame…), es por que hay un icono en el svn con nombre: apple-touch-icon.png:

http://meneame.net/apple-touch-icon.png

Supongo que sera para cuando entras con el iphone, a saber, ya lo buscaré por el código.

Como conclusión, decir que si eres informático, el código de meneame tiene muchas cosas interesantes y muchos ejemplos de como hacer cosas…como hacer un portal para la WII, para la NDS, etc etc.

Normalmente la gente no suele mirarse el código de meneame (me refiero a la gente que lo podría entender,a los desarrolladores), incluso si deciden bajarlo y usarlo en su site, no suelen estudiarlo ni un poco, y si lo hacen, no suelen compartir sus cambios con meneame.net.

Yo soy uno de los talibanes que sigue pensando que una web como meneame, donde el modelo de negocio es la publicidad, puede ser compatible con tener una comunidad a su alrededor, sin embargo, el caso de meneame me ha demostrado que muchos “webmasters” (como llamarlos?) solo buscan aprovecharse de que meneame comparte su código, y no buscan ni ayudar, ni colaborar, ni enriquecer nada mas que sus bolsillos.

Se que es una conclusión un tanto rara para un artículo como este, pero tenía que decirlo :)

Como montar un terminal Kiosk con debian y firefox

No suelo escribir sobre mi trabajo…pero esta semana como caso excepcional, he estado haciendo tareas de administrador de sistemas, en lugar de programar…y he tenido que enfrentarme a un problema bastante complejo, que pensaba que estaría mas documentado, pero no….

El problema es como modificar un debian, para que nada mas encenderlo autoconfigure la wifi (esto es fácil), muestre una pantalla visual con el logo de la empresa o organización mientras carga el sistema, y cuando acabe, ejecutar un firefox a pantalla completa, del que no se pueda salir para nada, y tampoco de cerrar las X, es decir, el terminal se convierte en un firefox en pantalla completa. A esto se le llama terminal kiosk.

Este artículo no cubre la parte de configurar las X o la red en debian, ya que se supone que si intentas montar un kiosk con debian, entiendes mas o menos como configurar el sistema básico usando esta distro linux.

Existen varios documentos acerca de como conseguir esto en debian, sin embargo se complican demasiado, están desactualizados o son erróneos en mayor o menor medida, así que he decidido documentar como lo he hecho yo, ya que me ha quedado bastante bien, y no requiere mucho trabajo.

El primer paso es instalar debian, etch o lenny, con el cd normal de instalación que podemos descargar de la web, al escoger los conjuntos de paquetes a instalar, solo dejamos marcado sistema base y equipo portátil si es un ordenador portátil.

Al terminar la instalación, tendremos un sistema que inicia y muestra un login en consola, y al hacer login obtenemos una consola, nada mas.

Configuramos la red según las necesidades, antes de continuar, y despues de configurar la red…

El primer paso es modificar el fichero /etc/apt/sources.list que contiene los repositorios de paquetes que utilizará aptitude para instalar software, lo dejamos así:

deb http://http.us.debian.org/debian etch main contrib non-free

Si estamos usando etch, o bien:

deb http://http.us.debian.org/debian lenny main contrib non-free

Si estamos utilizando lenny.

Ahora actualizamos la lista de paquetes:

apt-get update

Ahora ya tenemos la lista de paquetes actualizados, instalamos:

apt-get install xserver-xorg mingetty iceweasel

Esto instala las X y firefox, además de mingetty que ahora veremos que hace, y firefox, que en debian se llama iceweasel, por problemas de licencias.

Una vez instalados, creamos un nuevo usuario, lo llamamos kiosk por ejemplo, hacemos:

su kiosk

Para pasarnos a su cuenta, y creamos dos archivos en su home, uno llamado .bash_profile, que contenga:

while true
do
startx
done

Eso es un bucle en bash que ejecuta las X infinitamente, por lo que si por algún las X se cerrasen, volverían a lanzarse automaticamente.

El archivo .bash_profile contiene comandos a ejecutar cuando el usuario kisok inicia sesión (solo si su consola es bash, como es el caso en debian)

Ahora que ya hemos configurado que cuando “kiosk” haga login se ejecuten las X, vamos a configurar que es es lo que se ejecutará encima de las X, es decir, ni gnome, ni kde, sino que editamos el archivo /home/kiosk/.xinitrc e introducimos:

iceweasel

Esto hará que el usuario obtenga un iceweasel inmediatamente encima de las X.

Navegamos con ese firefox e instalamos la extensión r-kiosk, la cual pone el modo pantalla por defecto, del cual no se podrá salir, no permite descargar archivos y no permite salir del firefox de ninguna manera.

Ahora ya tenemos que cada vez que kiosk haga login, se ejecutarán las X, se ejecutará un firefox encima, y se pondrá a pantalla completa, sin que se pueda salir de el, solo nos falta hacer que kiosk haga login automáticamente nada mas arrancar el sistema, para ello editamos el fichero /etc/inittab y modificamos:

1:23:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6

Cambiandolo por:

1:23:respawn:/sbin/mingetty –autologin kiosk tty1
#2:23:respawn:/sbin/getty 38400 tty2
#3:23:respawn:/sbin/getty 38400 tty3
#4:23:respawn:/sbin/getty 38400 tty4
#5:23:respawn:/sbin/getty 38400 tty5
#6:23:respawn:/sbin/getty 38400 tty6

Esto hará que nada mas iniciar debian, sea el usuario kiosk quien inicie sesión, sin que lleguemos a ver la pantalla de login.

Ahora solo nos falta instalar splashy, lo cual solo es posible si hemos hecho todo lo anterior con lenny, por que en etch no hay paquete de splashy en aptitude:

apt-get install splashy

Splashy lo que hace es situar una pantalla gráfica que se muestra con una barra de progreso, mientras inicia debian, en luga de mostrar texto en el arranque.

Si queremos modificar la imagen que mostrará splashy al iniciar el sistema, solo hay que sustituir:

/etc/splashy/themes/default/background.png

Por un png nuestro, que debe ser de 1024×768, una vez sustituido debemos regenerar initram, con:

update-initramfs -u -t

Para que splashy funcione, hay que modificar nuestro /boot/grub/menu.lst y agregar: vga=791 splash al final de los parametros pasados al kernel en el arranque, es decir, cambiar algo similar a esto:

kernel        /boot/vmlinuz-2.6.24-19-generic […]

Por:

kernel        /boot/vmlinuz-2.6.24-19-generic […] vga=791 splash

Ahora ya tenemos nuestro splashy listo.

Si queremos deshabilitar el ctrl+alt+backspace que detiene las X, solo hemos de agregar:

SectionServerFlags
Option “DontZap
EndSection

A nuestro /etc/X11/xorg.conf, pero en realidad no hace falta, por que ejecutamos startx dentro de un bucle :)

También podría ser interesante que configuréis grub para pedir password antes de editar ningún parámetro de inicialización, pero eso ya entra dentro de temas específicos de las necesidades de cada uno.

Como vemos, montar un kiosk con debian es muy fácil, son las bondades del software libre.

Como leer un feed RSS desde C

Esta semana estoy muy liado en el trabajo, no tengo mucho tiempo para mantener la calidad del blog, así que tendré que meter algún artículo de relleno, lo siento :D

Bromas aparte, en realidad este es un artículo que quería escribir hace días, pero no encontraba el momento.

Para entrar al tema y no dar los rodeos que acostumbro a dar, existe una librería para C, llamada libmrss, la cual proporciona un conjunto de funciones y estructuras de datos para leer de un feeds rss.

Dicha librería, utiliza libcurl para obtener los feeds y nxml para parsearlos, son sus únicas dependencias.

Para instalar la librería en ubuntu/debian basta con hacer:

apt-get install libmrss0-dev libmrss0

El paquete -dev es el que proporciona los .h para utilizarlos desde nuestro programa, el paquete normal, proporciona los .so, de la librería.

Una vez con la librería instalada, los pasos son sencillos, en primer lugar, incluimos mrss.h desde nuestro código:

#include <mrss.h>

Esto nos define las estructuras de datos y las funciones de la librería, para que las usemos en nuestro programa, en realidad, solo usaremos una función y 2 structs, la función es:

mrss_parse_url

Y las estructuras son el struct mrss_t y mrss_item_t, el primero representa a la información de un feed, y el segundo a los elementos del feed.

Lo interesante de esta librería, es lo sencilla que es de usar, vamos a ver un ejemplo:

#include <mrss.h>
#include <stdio.h>

int main() {
mrss_t *data=NULL;
mrss_error_t ret;
mrss_item_t *item;
ret=mrss_parse_url(“http://rooibo.wordpress.com/feed/”, &data);
if(ret != MRSS_OK || data == NULL) {
return 0;
}
item=data->item;
while (item) {
printf(“%s\n——————————-\n”,item->title);
item = item->next;
}
return 0;
}

Este miniejemplo hecho en un segundo,  lee las entradas del rss de este blog, y las printea por pantalla, se puede compilar así:

gcc -lmrss ejemplo.c -o ejemplo

Y se ejecuta sin argumentos. Como veis, es muy sencillo utilizar libmrss, la función mrss_parse_url rellena un puntero de tipo data, que dentro contiene un puntero a un struct de tipo mrss_item_t, en el cual tenemos el titulo de la noticia, descripción, etc y un puntero al siguiente elemento de tipo mrss_item_t, con los datos de la siguiente entrada del feed.

Para ver que contiene mrss_item_t aparte de title, podemos consultar la web de mrss, aqui.

Leer feds desde C sirve para muchas cosas, desde extender tu aplicación con soporte para algún tipo de feed, como para hacerse programas que hagan acciones con RSS en dispositivos empotrados, como la fonera.

Lo único negativo de esta librería es que no existe documentación alguna para ella, yo aprendí a usarla leyendo el mrss.h.

El LHC y el peligro asumible frente al peligro real

Como todos sabréis, el LHC es es un aparato muy caro, tanto, que vale nada mas y nada menos que 6.000 millones de dolares.

Dicho así, de entrada, uno podría pensar que es un poco caro, pero teniendo en cuenta que es posiblemente el mayor experimento científico de la humanidad, incluso parece barato (¿Quien no tiene 6.000M euros en calderilla? :), sin embargo, no ha sido su precio lo que ha levantado la liebre sobre este trasto, sino su supuesto peligro.

El caso, es que se ha hablado largo y tendido en foros, blogs y en meneame sobre el peligro del LHC, resulto que hay quien piensa, que generará uno o mas agujeros negros, que crecerán hasta absorber la tierra, el sistema solar, o todo el universo.

Esto plantea serias dudas, para algunos, sobre si se debería continuar con el experimento. Sin embargo otros se muestran en otra postura, y preguntan si de verdad existe un riesgo real, y se asustan al escuchar a gente entendida, decir que si.

Llegados a este punto de alarmismo social entorno al LHC, hoy, leyendo a supuestos entendidos el tema, por blogs y por meneame, creo que he entendido por que se niegan a decir que no hay riesgo.

Pero en lugar de entrar en divagaciones, sobre los riesgos, que seguramente, ni yo entendería, por que no soy físico, me he dado cuenta de que existe una analogía entre el tema del LHC y la seguridad informática (eso, o yo veo analogías con la seguridad en todas partes).

En seguridad informática, se habla mucho sobre el riesgo teórico (donde juega un papel clave), el cual muchas veces, está muy alejado del riesgo real.

El riesgo teórico es ese que podría pasar, pero nuestra lógica y conocimientos en la materia nos indica lo contrario, sin embargo, queda una posibilidad, la cual nosotros sabemos que no se cumplirá, pero que podríamos decir que existe, y por ello, no la descartamos.

Voy a poner un ejemplo técnico: el caso del overflow en los mbuf de OpenBSD en ipv6:

http://www.securiteam.com/unixfocus/5HP0C1FKUO.html

Es un bug en OpenBSD, que permite provocar un overflow en la pila ipv6, lo cual, por el tamaño y disposición de las estructuras en memoria, no permite ejecutar código arbitrario de mas de una instrucción.

Es decir, el exploit que porporcionan, solo ejecuta int 3h y punto, por que? por que no caben mas instrucciones, dada la naturaleza del bug.

Sin embargo, a día de hoy, nadie se ha atrevido a decir que ese exploit, no se pueda usar para conseguir acceso remoto a un OpenBSD, y es por que aunque en teoría, no caben mas instrucciones en memoria, y nuestra lógica dice que nunca nadie podrá aprovechar eso para ejecutar nada de mas de una instrucción, la historia nos ha enseñado a no hacer afirmaciones del tipo “nunca nadie…“, por lo que pese a que todos sabemos que ese bug no tiene mas riesgo que que te cuelguen el sistema, ¿Que pasaría si el sistema fuese el planeta, y funcionase sobre OpenBSD?

Seguramente, todos los que no entendiesen de esto, vendrían corriendo a preguntar, si realmente hay riesgo de que alguien consiga acceso a nuestro mundo, utilizando este bug. Y cualquiera que sepa un mínimo del tema, les tendría – tristemente – que contestar: existe una cierta posibilidad.

El problema de estas situaciones, es que la frase “existe cierta posibilidad” no significa lo mismo para un experto en el tema, que para alguien que no tiene ni idea, el segundo, seguramente se asustará, mientras que el experto, discernirá que se trata de una posibilidad teórica, y que si pudiésemos hablar de forma menos científica y menos ortodoxa, podríamos decir que no existe esa posibilidad.

Nota: no se como me atrevo a escribir posts mezclando el LHC, el universo, y OpenBSD.

Librería en C para usar la API de meneame, y meneame-utils

Hoy es sábado, y como informático que soy, los sábados no salgo por ahí, no voy a bares ni discotecas, ni me paseo por ningún sitio…Me quedo en casa programando, igual que el resto de la semana, pero programando lo que yo quiero, es decir, como hobby.

Este sábado he decidido programar algo un poco rebuscado…empezaré por el principio.

Como todos sabéis, meneame es una página web, donde los usuarios envían noticias, las cuales los usuarios votan, y las que mas votos reciben, llegan a portada, y son vistas por miles de personas. Es una especie digg en español, pero que además, es software libre.

El caso es que meneame tiene una API pública, que cualquiera puede utilizar, para interactuar con meneame, desde cualquier programa, mediante el protocolo http, por ejemplo, si queremos comprobar si una url existe en meneame, ha sido enviada antes:

http://meneame.net/api/url.php?url=http://www.google.com

Y nos devuelve OK seguido de los enlaces a las veces que ha sido enviada y los votos que recibió, si no ha sido envíada:

http://meneame.net/api/url.php?url=http://www.example.com

Nos devuelve “KO” y la url desde la que podemos enviarla.

Utilizando esta API, podemos hacer un programa, que tenga la opción de comprobar si una url, existe en meneame, y con eso, todo tipo de viguerías.

Otra API muy interesante de el meneame, es la de enviar notas al notame. El notame es una especie de twitter, pero integrado en la página de meneame.

Para enviar notas al notame, existe otra API que podemos utilizar:

http://meneame.net/api/newpost.php?user=NOMBREUSUARIO&key=CLAVEAPI&text=TEXTOAQUI

Donde la clave API, es nuestra clave API, que podemos consultar en nuestro perfil de meneame, habiendo iniciado sesión.

Bien, además de todo esto, las notas del notame se pueden leer vía rss, entre otras cosas.

No voy a continuar, por que no pretendo documentar aquí toda la API de meneame, era solo para hacer una idea de lo que es, y como funciona, para introduciros en lo que he programado hoy.

El caso, es que imaginaros que queréis hacer un programa que utilice una de esas API, necesitaréis hacer peticiones HTTP desde vuestro programa, en algunos casos parsear la respuesta…si queréis leer las notas del notame, necesitaréis leer del feed…todo esto, es demasiado trabajo para un simple programa que interactúa con meneame, por ello, he creado un conjunto de librerías en C, que disponen de una serie de funciones para interactuar con el meneame desde tu programa, sin preocuparte de nada.

Para ejemplificar como funcionan, he creado también 3 programas que utilizan las librerías, para que podáis ver en directo, como funciona todo esto.

Antes de entrar en materia de código, voy a enseñar un poco los 3 programas (en C, para consola) de los que hablo.

jcarlosn@thanatos:~$ mnmuserinfo -h
mnmuserinfo [-xkrwndz] [-i id] [-u usuario]
Consulta información sobre un usuario de meneame

-x    Muestra solo el username
-k    Muestra solo el karma
-r    Muestra solo la posicion en el ranking
-w    Muestra solo la web
-n    Muestra solo el nombre
-d    Muestra solo la fecha de registro
-z    Muestra solo el id

-i id    Consulta la informacion para el usuario con ese id
-u usuario    Consulta la informacion mediante el nombre de usuario

Ejemplos:

Consultar informacion de jcarlosn usando su id: mnmuserinfo -i 23321
Consultar informacion de jcarlosn usando su nombre: mnuserinfo -u jcarlosn

Para notificar bugs: jose@eyeos.org
jcarlosn@thanatos:~$

El primero, permite obtener información de un usuario de meneame, vamos a verlo:

jcarlosn@thanatos:~$ mnmuserinfo -u Carme
Id: 2682
Nombre de usuario: Carme
Web:
Nomre: Carmen
Karma: 15.220000
Ranking: 70
Fecha de registro: 2006-03-04
jcarlosn@thanatos:~$

Podemos pedirle información del usuario pasando su id, o su nombre de usuario, si queremos ver solo un campo, podemos hacerlo, por ejemplo, la web:

jcarlosn@thanatos:~$ mnmuserinfo -u jonarano -w

http://www.jonarano.es

jcarlosn@thanatos:~$

Vale, el siguiente comando de ejemplo, creado con las librerías es mnmchecklink, permite consultar una url, para saber si ya existe en meneame, y si existe, muestra su enlace a meneame, y sus votos:

jcarlosn@thanatos:~$ mnmchecklink www.google.com
http://meneame.net/story.php?id=41836  votes: 4
http://meneame.net/story.php?id=20861  votes: 3
jcarlosn@thanatos:~$

Y si no existe:

jcarlosn@thanatos:~$ mnmchecklink www.meloinvento.com
El link proporcionado no existe en meneame
jcarlosn@thanatos:~$

Y el tercer y último comando, el mas elaborado, permite enviar y leer notas del notame, vamos a verlo:

jcarlosn@thanatos:~$ cnotame -h
cnotame [-l] [-n usuario] [-v] [-k apikey] [-m mensaje]
Publica notas en el notame, usando la API de meneame

-v    modo verbose (salida con detalle)
-h    muestra la ayuda
-k CLAVE    la clave API que se utilizara para agregar las notas
-m MENSAJE    el texto de la nota a enviar
-u USUARIO    el usuario asociado a la clave API porporcionada

-n USUARIO    lista las ultimas notas de USUARIO
-l    lista las ultimas notas de el notame

Ejemplos:

Listar las ultimas notas: cnotame -l
Listar las ultimas notas del usuario jcarlosn: cnotame -n jcarlosn
Enviar una nota al notame: cnotame -k XXXXXXXXXX -m “hola meneantes” -u youuser

Para notificar bugs: jose@eyeos.org
jcarlosn@thanatos:~$

Por ejemplo, para ver las últimas 20 lineas del notame:

jcarlosn@thanatos:~$ cnotame -l | tail -n 20
#15   Abel.Florez

No creo que seas de Segovia. Si es así, te mando a “los Miami”.
autor: jmt
———————
Entro a tuenti.

Me encuentro con una foto de la Euskal Encounter, que salgo dormido como un angelito!!! Con una toalla al cuello (porque tenía frio). No conocía la existencia de tal foto

Eso si, la que la ha subido, ya tiene la respuesta en “modo foto”
autor: jonarano
———————
Odio cuando algunos videojuegos llegan a un punto de dificultad en el cual pasarte una pantalla significa “pulsar exactamente los mismos botones en los mismos instantes (durante un buen rato) porque no hay otra manera, llegar a un punto ligeramente más avanzado que la vez anterior, morir, repetir”.
autor: trollinator
———————
@trollinator Por curiosidad. Qué juego te atormenta?
autor: Cesc
———————
jcarlosn@thanatos:~$

Si no lo limitamos con tail ,la salida será un poco extensa.

Ahora para ver todas las notas de un usuario concreto:

jcarlosn@thanatos:~$ cnotame -n jcarlosn
No es lo mismo @PEP0M0LT0, no
autor: jcarlosn
———————
me aburro
autor: jcarlosn
———————
no es lo mismo ganar karma para votar, que votar para ganar karma (karmwhore)
autor: jcarlosn
———————
@Ancalagon: no, no lo merece
autor: jcarlosn
———————
las 3 y media y aun sin sueño, que dura la vida del informatico
autor: jcarlosn
———————
jcarlosn@thanatos:~$

Para enviar una nota al notame:

cnotame -m “introduce aqui tu nota” -k tuclaveapiaqui -u tuusuarioaqui

Estos programas, son ejemplos del uso de esta librería, podéis crear vuestros propios programas con ella, vamos a verla un poco por encima:

En la parte de notame, tenemos libnotame.h/libnotame.c que disponen de:

int sendNote(char *msg, char *key, char *user);
struct note *listNotes(char *author);

La primera envía una nota dado su texto, la clave API y el usuario, la segunda devuelve una lista enlazada con el contenido de las notas, si no queremos especificar autor, y queremos leer todas las notas del notame, basta con pasarle NULL, para iterar sobre la lista de notas, tenéis un ejemplo en cnotame.c:

result=listNotes(vuser);
if(result == NULL) {
fprintf(stderr, “Error obteniendo las notas de notame\n”);
}
while(result != NULL) {
ptr=result;
printf(“%s\n———————\n”,ptr->text);
result=ptr->next;
free(ptr->text);
free(ptr);
}

En el apartado de la API de consultar la información de un usuario, tenemos libuserinfo.c/libuserinfo.h, que disponen de:

int getUserInfo(int id, struct userInfo *uinfo);
int getIdByUser(char *user);

La primera, rellena el struct de tipo userInfo que le pases en el segundo argumento, con la información obtenida del usuario con id, recibido por el primer argumento, el struct userInfo es:

struct userInfo {
char username[60];
char name[512];
char web[1024];
int id;
float karma;
int ranking;
char regdate[11];
};

La segunda, devuelve el id de un usuario, dado su nombre de usuario.

Y en el apartado de links, tenemos liblink.h/liblink.c que dispone de:

struct link *linkExists(char *link);

La cual comprueba si el link dado existe ya en meneame, y si existe, devuelve una lista enlazada de structs del tipo:

struct link {
char url[42];
int votes;
struct link *next;
};

Con todos los enlaces de las veces que fue enviado a meneame, y los votos que obtuvo, para iterar sobre ella, hay un ejemplo en mnmchecklink.c:

stack = linkExists(argv[1]);

if(stack == NULL) {
printf(“El link proporcionado no existe en meneame\n”);
} else {
while(stack != NULL) {
printf(“%s votes: %d\n”,stack->url,stack->votes);
myLink=stack;
stack=stack->next;
free(myLink);
}
}

Bueno, tiene muchísimos detalles ocultos esta librería, y no voy a entrar demasiado en detalles por que me estoy extendiendo demasiado, si tenéis alguna duda sobre la librería, podéis escribirme, mi correo está en los headers de todos los archivos.

Para poder compilar los ejemplo, se requiere libmrss y libcurl, para instalarlos en sistemas basados en debian, como ubuntu:

sudo apt-get install libcurl4-openssl-dev libmrss0-dev libmrss0

Luego estando en el directorio donde lo habéis extraído, ejecutáis make y si queréis que se copien a /usr/local/bin, sudo make install.

El makefile es muy cutre, por que solo son ejemplos de lo que se puede hacer con la librería, nada mas.

Todo el código es software libre y está liberado bajo GPL3, como dice en los headers.

Podéis descargar la librería de aquí.

Aviso: no es una librería propiamente dicha, en el sentido de librería de linux :) recordad que es un trabajo de fin de semana por hobby, es simplemente archivos .h con su .c, que proporcionan funciones para interactuar con meneame, y programas de ejemplo que los utilizan.

Por cierto, me olvidaba, segun comentaban aquí:

[*] Crea un API para bobos y los frikis harán virguerías, además dejarán de darte la lata pidiendo cosas complicadas. Pero no serán capaces de hacer que esos programas lean las notas vía RSS

así que los frikis no eramos capaces de leer las notas vía RSS :p