Declarar structs a lo pro

Curioseando las cosas del kernel, me he encontré hace unos días con una construcción de los structs que no conocía, y que es bastante útil cuando tienes un struct muy grande con muchos campos, y que no necesitas utilizar todos cada vez que lo declaras, o que lo declaras con unos pocos:

typedef struct __chona__ {
int a;
int b;
} chona_t;
/* ejemplo de uso */
int main () {
chona_t chona = {
.a = 1
};
printf("*** Chona vale a: %d - b: %d \n", chona.a, chona.b);
}

Como se ve, usando un punto seguido del nombre del campo se puede referenciar a ese campo, y si no está referenciado, se pone a NULL.
Mucho cuidado, esta sintaxis pertenece a C99, el último estándar de C, lo que requiere un compilador relativamente reciente (gcc 2.95 ya lo soportaba…).
En fin, suerte y no traten de usar esto para ligar en las discotecas.

Uncategorized

Comments (2)

Permalink

Cosas de los compiladores…

¿Cuál sería el comportamiento esperado de éste código?


int main () {
int i = 0;
printf("%d %d %d", i++, i++,i++);
}

Yo, dentro de mi ignorancia, esperaba algo como: 0 1 2
pero…. cual fue mi sorpresa cuando veo… :

$ ./prueba1
2 1 0

Si, es flipante. No se evalúa de izquierda a derecha, sino de derecha a izquierda. ¿Por qué?
¡¡ Pues porque eso es otra de las cosas no definidas en el estándar de C !! El orden de evaluación de los argumentos se deja a elección del compilador, así que no se puede garantizar cual de ellos se va a calcular primero. No necesariamente tiene que ver con el orden en que se inserten en la pila, aunque en este caso coincide. (En c, los parámetros se ponen en la pila desde el último al primero)
Por ejemplo, en gcc 4.1 sobre un x86_64, la salida es 2 1 0, pero en un itanium 64 con el compilador icc de intel…

$ ./prueba1
0 1 2

¿Y que hacemos los pobres programadores ante semejante locura?
Pues, lo único posible es evitar usar código en el que los parámetros se evalúen en la misma llamada, porque aunque en nuestra máquina de pruebas funcione, es posible que al llevarlo a otra deje de funcionar, aún con el mismo compilador! ya que incluso pasa con versiones diferentes del mismo…
En fin.. suerte!

Uncategorized

Comments (0)

Permalink

Finales de flujo

Una de las cosas que me suele preguntar la gente, y que hace tiempo me preguntaba yo mismo, es porqué cuando haces algo como:

int main() {
printf("Hola Mundo!");
}

a veces, no sale nada en pantalla.
La respuesta que he dado siempre, y es cierta, no se asuste nadie, que es necesario acabar los flujos de entrada con un fin de línea, para que salgan por pantalla. Esto se extiende a muchas otras situaciones y lenguajes (lo mismo pasa en C++ e incluso lo he visto en python).

Hoy por casualidad, encontré en comp.lang.c una explicación a este comportamiento, en vista de un código similar al anterior:

(..) The program given has a portability problem: the output to stdout does not finish with a \n. Implementations are permitted to drop any terminal partial line on text streams. (..)

Lo que viene a decir: Que salga por pantalla o no una cadena sin fin de línea, depende de la implementación del compilador: Algunos lo hacen, otros no.

Solución sencilla: Acaba siempre con un \n todas tus cadenas ;)

Uncategorized

Comments (1)

Permalink

Actualizaciones de Seguridad

Una de las cosas que más se le acusa a gentoo es el no estar preparado para utilizarlo en servidores, y a causa de eso, no está muy extendido en ese campo. Sin embargo, son grandes los esfuerzos que se están haciendo para conseguirlo.
Buena prueba de estos esfuerzos es la existencia de un sistema de actualizaciones de seguridad, que ya lleva algún tiempo utilizándose pero que yo estoy implantando ahora.
Las actualizaciones de seguridad requieren de dos cosas: Un sistema para generar alertas de seguridad, y una forma de actualizar nuestra instalación sin actualizar el sistema completo.
En cuanto a la primera parte, gentoo ha creado la lista de “glsa” (http://www.gentoo.org/security/en/glsa/). GLSA son las siglas de “Gentoo Linux Security Advisories”, y como su propio nombre indica, son los avisos de seguridad de gentoo. Cuando se reporta un fallo de seguridad en un paquete (desde la propia gente de Gentoo o desde los desarrolladores del programa), se crea un aviso de GLSA. El anuncio se publica en la lista de correo GLSA (y también en gentoo-announce@gentoo.org), indicando que hacer para solucionar el error, si existe o no una actualización y el motivo del error (sólo una breve descripción para evitar que se haga mal uso de esa información). Cada GLSA se identifica con un código basado en la fecha: AñoMes-Fecha.
Para actualizar nuestra instalación, podemos hacer manualmente los cambios, pero eso sería inviable para un servidor, ya que significaría tener que estar pendiente de la información y de los pasos para actualizarla.
Como eso no es posible, existe el programa “glsa-check”, que funciona al estilo de apt-get update en debian (aunque no exactamente igual).
glsa-check se utiliza siempre con un primer parámetro que es el modo de ejecución y el segundo parámetro que es la lista de glsa a usar.
Los parámetros a destacar son “-l” y “-f”.

    “-l”, lista los glsa y el segundo los aplica. Si no tiene parámetros, lista todos los glsa existentes y no aplicados
    “-f” aplica los glsa de la lista.

La lista puede ser una serie de identificadores de GLSA o bien una de tres palabras clave: “all” , “new” y “affected”. Con all, la acción especificada se aplica a todos los glsa disponibles. Con new sólo a los recientes desde la última comprobación. Con affected (y este es el interesante), el comando se aplica a los glsa que afectan a nuestro sistema.
Por ejemplo:

Encrucijada alu3066 # glsa-check -l affected
[A] means this GLSA was already applied,
[U] means the system is not affected and
[N] indicates that the system might be affected.

200701-10 [A] WordPress: Multiple vulnerabilities ( www-apps/wordpress )

Como vemos, hemos listado los glsa que afectan a nuestro sistema. En este caso, sólo aparece uno (wordpress), con la letra [A], que significa que ya está aplicado. Utilizando “glsa-check -f affected” , aplicaríamos los glsa que afectan al sistema (lo que habitualmente consiste en actualizar un paquete).
La ventaja que tiene éste método frente a un típico update es que se limita a actualizar ese paquete, evitando pulular por dependencias siempre que puede, y también que permite automatizarlo fácilmente. Por ejemplo, yo lo he puesto en un cron.daily:

#! /bin/sh
emerge sync
glsa-check -f affected

Efectivamente, glsa-check depende de la actualización del árbol del portage, así que hay que actualizarlo frecuentemente para que tenga sentido.
No todo es de color de rosas, no. glsa-check no está terminado. Está pendiente de ser incorporado al emerge y todavía da falsos positivos, entre otras cosas, porque no tiene en cuenta los slots de los paquetes (es posible que un paquete tenga el fallo únicamente si tiene el soporte para un determinado programa). Sin embargo, es una utilidad interesante para la gestión de la seguridad en nuestra distribución favorita, y un paso más a su integración en entornos de servidor, ¡donde no es factible hacer un emerge world todos los días!

Uncategorized

Comments (0)

Permalink

MiniScript service

Aquí tengo un pequeño scrip (sí, en perl) para ahorrarse escribir todo el /etc/init.d/nombreservicio cuando queremos iniciar o apagar un servicio del sistema. Así, para , por ejemplo, parar el servidor apache, no tendremos que hacer /etc/init.d/apache2 stop, sino que haremos service apache2 stop.
Como se ve en el código, siemplemente el primer parámetro se concatena a la ruta y el segundo pasa al script del init.d directamente, siempre que no sea –status-all, que es la opción que en el service original de red hat muestra el estado de todos los servicios del sistema.
En éste script no está puesto porque hace que se cuelgue algún servicio no determinado.
[perl]
#!/usr/bin/perl -w
#
# Wrapper para usar las funciones de /etc/init.d/ con la sintáxis de red hat
# Ruymán Reyes Castro versión 1.0
#
# Ejemplo
# start: service tutu start
# stop : service tutu stop
# restart: service tutu restart

use strict;

my $name = $ARGV[0] or die (“Parámetros insuficientes\n”);
# Cambiarlo por algo más decente!!
if ( $name =~ “–status-all” ) {
# Listamos los servicios disponibles
# No implementado! Cuelga cuando llama
# al status de algunos servicios
} else {
my $line = “/etc/init.d/$name”;
# Obtenemos la acción o ejecutamos la línea
my $action = $ARGV[1] or exec $line;
# Comprueba si eres superusuario
($ENV{“USER”} eq “root”) or die(‘Debes ser superusuario!’);
# Comprobamos si el servicio existe
my @services = glob(“/etc/init.d/*”);
(grep m/$name/, @services) or die (‘El servicio no se encuentra!’);
# Creamos la línea de acción
my @line = (“$line $action”);
# y la ejecutamos
exec @line;
}
[/perl]

Uncategorized

Comments (0)

Permalink

Lista de wikis interesantes

Aquí pongo una recopilación de wikis de gentoo que son imprescindibles una vez acabada la instalación:

Unicode, para tener tildes y demás

Fuentes “bonitas” (sin bordes rugosos, etc) para tener unas fuentes decentes

Detalles del son vaio para mi portaca nuevo (y resto de portacas con acpi)

Hardware Sensors sensores de temperatura, hardware, etc

Uncategorized

Comments (1)

Permalink

Violación de segmento en Rhythmbox

El rhythmbox se colgaba cargando mi colección de música (copiada bastardamente de la de Tankian).
Ejecutando el rhythmbox con la opción de depuración (rhythmbox -d), se ve que se cuelga leyendo el primer archivo m4a.
Quitando los archivos m4a del directorio de la colección, se carga el resto de archivos.
Al parecer hay un bug del rhythmbox cuando carga ese tipo de archivos, aunque no está reportado en el bugzilla de gentoo. Si me vuelven a pasar un archivo con .m4a, lo reporto al bugzilla (Porque mi solución fue borrarlos! xD).

Uncategorized

Comments (0)

Permalink

dhcpd en HyperWRT

Para aquellos que no lo sepan, la estructura de la red de mi casa es algo “complicada”. Hay tres subredes, una para mi esquina friki, otra para el wifi y otra que es una DMZ.

La subred del wifi y la de la esquina friki están detrás del servidor encrucijada, que es el que provee de acceso a internet en ambas redes, con sus cortafuegos, dns y demás. En el caso de la red wifi, hay un punto de acceso que es el que asigna las ips a lo que se conecte por wifi (actualmente un pc fijo de la planta alta y n portátiles). El AP es un linksys parcheado con el HyperWRT para poder aumentar la potencia de la señal a más del 50% y que llegue bien a las otras plantas.

El problema es que cuando se conectan los pcs por wifi, el ap les sirve la información de dhcpd, que les asigna la ip del rango correcto, pero les da como puerta de enlace la dirección del ap, que no tiene conexión por si mismo a internet, ya que es Encrucijada el que se la da. En realidad, la puerta de enlace de los pcs que se conectan por el wifi debe de ser la dirección de encrucijada, y no la del AP. Cuando intento cambiarlo usando las opciones de la interfaz web, veo que no existe opción para cambiar eso.

La solución fue lanzar el demonio de telnet del HyperWRT y entrar en la shell del ap:

telnet 192.168.1.1

Una vez allí, localicé el archivo udhcpd.conf, que contiene la configuración del servidor de dhcpd que usa el ap

# cd /tmp
Como en el busybox (el linux que tiene el ap) no hay editor, hay que modificar los archivos a pelo con el sed
# sed 's/option router 192\.168\.1\.1/ \
option router 192.168.1.100/' udhcpd.conf > udhcpd2.conf

Ahora hay que reiniciar el servidor de dhcpd cargando el nuevo archivo de configuración
# ps au
# kill $pidDelUdhcpd
# udhcpd udhcpd2.conf &

Cuidado, porque estos cambios se perderán cuando se reinicie el ap, todavía tengo que ver como hacerlos permanentes, tal vez editando uno de los scripts de arranque, pero por ahora me vale como workaround.

Antes de cerrar, no olvidar parar el demonio de telnet desde la propia interfaz web, ¡porque si no cualquiera podría entrar a tocar el router!.

Uncategorized

Comments (0)

Permalink

Sonido en Rhythmbox

Llevo un par de días con problemas de sonido usando el rhythmbox (y también con otras aplicaciones de gnome). El sonido se escucha distorsionado algunas veces y otras dice que no se encuentra el plugin.

Tras un par de busquedas por las wiki de gentoo e inspirado por Tankian, encontré que el problema está en dos partes:

Primero, un poco de teoría. Los elementos multimedia en gnome se han tratado de centralizar en un sólo punto de configuración, de forma que los diferentes programas que utilizan gnome no tengan que preocuparse por los drivers o plugins de sonido, sino que tengan una interfaz sencilla para interactuar ellos. Esa interfaz es gstreamer, y se configura utilizando el programa gstreamer-properties. Cada usuario tiene su propia configuración de gstreamer, que se guarda junto con el resto de configuración de gnome.

Ahora, el problema. Gnome 2.14 y superiores utilizan la versión 0.10 de gstreamer. Pero la versión de rhythmbox que está en el portage a fecha del post , la 0.8.8 , espera la versión 0.8 de gstreamer. La configuración de las dos versiones de gstreamer está en sitios distintos, pero cuando lanzamos gstreamer-properties, la versión que se configura es la 0.10, no la 0.8 !. Así que no podemos ajustar la salida de audio de esa versión, que por defecto está usando el driver de oss. Si instalamos la versión más reciente del rhythmbox, el sonido se escucha, pero se escucha mal, como distorsionado.
¿Como arreglarlo?
Error de salida incorrecta: Editar la configuración del gstreamer-0.8. Para ello, utilizamos gconf-editor, el editor de configuración de gnome. Vamos a la clave System, luego a gstreamer y veremos dos valores, que son las versiones de gstreamer instaladas: 0.8 y 0.10. Entramos en la 0.8 y en la clave default, encontramos los valores audiosink y audiosrc. Audiosink es el plugin que se utilizará para mezclar la salida, y audiosrc es el plugin para la salida. En el primero, editamos el valor y ponemos “autoaudiosink”, y en el segundo ponemos “alsasrc”, para que utilice alsa como salida. Ya podemos cerramos el editor de configuración.

Sonido Distorsionado: Es un problema con el mezclador de alsa, no con el gnome. Hay que editar un archivo en el home que se llame “.asoundrc” que contiene las preferencias de alsa. En él, poner:

“defaults.pcm.dmix_max_periods -1″

Con eso debería de funcionar el sonido correctamente, por lo menos a mi me funciona ;).

Uncategorized

Comments (4)

Permalink

¡Hola, mundo!

Bueno, como primer post de este blog, seguiré la moda actual en los blog de éste tipo, y presentaré mis máquinas. No las del trabajo, sino las de mi casa ;).

No quiero entrar en detalles sobre ellas para no alargar el post de introducción, pero las fotos en flickr están anotadas con alguna información básica para ir rompiendo el hielo ;).

Aquí está la parte de pcs “cliente”

La esquina Friki

Y aquí la infraestructura de “servidor”

El Armario Servidor

Dedicaré algun post cuando tenga tiempo al servidor, porque realmente tiene tela.

Espero que éste blog sea de utilidad o al menos como curiosidad para aquellos que se decidan a seguirlo. Para mi lo será, ya que así no se me olvidarán las cosas que hago ;).

Uncategorized

Comments (2)

Permalink