Archivos de la categoría Software libre

Úsalo, modifícalo, cópialo, distribúyelo…

Empiezo a aprender Qt

Los últimos capítulos de Accelerated C++ los he leído un poco por encima, porque tratan de temas complejos (gestión de memoria, etc) que creo que de momento no voy a necesitar. Siempre podré volver a ellos en caso de que lo necesite.

Así que ya he empezado a aprender Qt. Como sabréis, Qt son unas bibliotecas multiplataforma de Nokia (que adquirió la noruega TrollTech a principios 2008). No es un simple conjunto de widgets (window gadgets, es decir elementos gráficos como botones, deslizadores, menús, etc), sino que aporta muchas otras funcionalidades, haciendo innecesaria la STL (Standard Template Library). Probablemente sea más comparable a Boost que a GTK+.

Hay unos cuantos libros sobre Qt, entre los que destacan:

El primero es el libro oficial, el más moderno, y sus autores conocen Qt 4 como la palma de su mano. Pero por los comentarios de Amazon, parece que podría ser más pedagógico.

El último es una introducción a patrones de diseño usando C++ y Qt que sobre Qt en sí, así que no es realmente lo que necesito.

Entre los dos restantes, el de Thelin abarca un poco más que el de Molketin (CMake, unit testing, plugins), así que es el que he elegido.

En C/C++, argc puede ser 0

Esta semana he continuado leyendo Accelerated C++. Intento seguir un ritmo de un capítulo diario, habiendo llegado ya al capítulo 10 (aproximadamente dos tercios del libro). Confío en acabarlo a lo largo de esta semana.

Hoy he descubierto una cosa curiosa. La mayoría de los programas en C/C++ incluye una línea similar a int main(int argc, char **argv) o su equivalente int main(int argc, char* argv[]) para permitir pasarle argumentos.

argv es un puntero a un array de punteros, uno para cada argumento, y argc es el número de punteros del array. El elemento inicial del array, argv[0], representa el nombre con el que se ha llamado al programa, y argv[argc] es siempre un puntero nulo. Los argumentos -si los hay- ocupan los restantes elementos del array, de argv[1] a argv[argc - 1].

Así pues, aparentemente argc debe siempre ser mayor o igual que 1. Sin embargo, resulta que como explican en stackoverflow y alt.comp.c, el estándar dice explícitamente que argc puede ser cero. Y es que por medio de las llamadas al sistema exec() de POSIX, argv[0] puede ser NULL.

Cómo borrar todos los ficheros de hace más de x días

Un usuario no ha descargado su correo electrónico en 9 meses, y me pide que le borre todos los mensajes que tengan más de 15 días. Es muy fácil de hacer, y en How-to Geek lo explican a la perfección, así que me limitaré a traducirlo.

La herramienta find de Unix (así como GNU/Linux, etc) permite que se le pasen varios argumentos interesantes, incluyendo uno para ejecutar otra orden sobre cada uno de los ficheros. Usaremos esto para averiguar qué ficheros tienen más de un cierto número de días, y entonces usar la orden rm para borrarlos.

Sintaxis de la orden

find /home/fulano/Maildir/cur -mtime +15 -exec rm {} ;

Obsérvese que hay espacios entre rm, {}, y ;.

Explicación

  • El primer argumento es la ruta a los ficheros. Puede ser una ruta, un directorio o un comodín. Recomiendo usar la ruta completa, y ejecutar la orden sin el exec rm para estar seguros de que se va a conseguir los resultados deseados.
  • El segundo argumento, -mtime, se usa para indicar el número días que tiene el fichero. Si introducimos +15, buscará ficheros que tengan más de 15 días.
  • El tercer argumento, -exec, permite pasar una orden como rm. El {} ; al final es necesario para terminar la orden.

Otra forma de hacerlo sería:
find /home/usuario/Maildir/cur -mtime +15 | xargs rm

Estas órdenes deberían funcionar en cualquier versión de Unix o distribución de GNU/Linux o *BSD.

Resucitando un scanner USB Suvil del siglo pasado

Desde hace 10 u 11 años tengo un scanner Suvil ColorBrush Family II criando polvo. Lo cierto es que rara vez tengo necesidad de digitalizar ninguna imagen. Al intentar ponerlo en marcha, me he encontrado que en Internet prácticamente no hay ninguna referencia a este aparato, y mucho menos drivers (ni Windows ni Mac OS X lo reconocen).

Sin embargo, he conseguido hacerlo funcionar con SANE en GNU/Linux. Tras conectarlo, he ejecutado # sane-find-scanner, que me ha revelado su ubicación: found USB scanner (vendor=0x055f, product=0x0002, chip=MA-1017) at libusb:004:003.  Compruebo que efectivamente el programa reconoce el escáner:
# scanimage --list-devices
device `mustek_usb:libusb:004:003' is a Mustek 600 CU flatbed scanner

Y escaneo una imagen con # scanimage –format tiff > foo.tif. Sale en blanco y negro (cosa de las opciones predeterminadas), pero funciona.

Sin embargo, cuando con mi usuario intento lanzar xsane o skanlite me dice que no hay dispositivos disponibles. ¿Será que no tengo los permisos necesarios? Efectivamente, al intentar ejecutar la orden anterior, me dice
% scanimage --format tiff > blah.tif
scanimage: no SANE devices found

La solución es sencilla:
# addgroup quique scanner
Añadiendo al usuario `quique' al grupo `scanner' ...
Adding user quique to group scanner
Hecho.

Tras iniciar una nueva sesión, todo va a la perfección. Gracias a Debian, he recuparado un dispositivo que de otra manera probablemente habría ido a parar a la basura. Hora de probar retr0bright, supongo.

Accelerated C++: capitulos 3-4

Este fin de semana lo he pasado en Zaragoza, pero no obstante he sacado un poco de tiempo para estudiar.

El capítulo 3 da entrada a los vectores, almacenando en ellos con el método push_back series de datos leídos desde el teclado, para después operar con ellos. Introduce también el operador condicional (? :).

En el capítulo 4 aprendemos a lanzar y capturar excepciones, la diferencia entre pasar argumentos por valor y pasar argumentos por referencia (sean o no const).  También aprendemos a crear nuestras propias estructuras de datos con struct, y a usar los ficheros de cabecera (headers), la directiva ifndef y las funciones inline. Un capítulo muy interesante.

Accelerated C++: capítulos 0-2

Accelerated C++ se compone de 17 capítulos numerados del 0 al 16. Ya me he leído los 3 primeros. Esto no significa que me vaya a merendar el libro en menos de una semana, claro. El contenido de estos tres capítulos es sencillo, y además ya los había leído anteriormente.

El libro empieza (como no) con un Hello, world!. Eso sí, escrito usando output streams. Aprovecha este ejemplo para explicar la sintaxis de C++ y su estructura (includes, espacios de nombres, tipos de datos, etc).

El capítulo 1 está dedicado a las cadenas de texto. Presenta además la inicialización/construcción de variables, los flujos de entrada, el tipo carácter, la concatenación y un par de métodos de las cadenas.

El capítulo 2 trata de los bucles, los conocidos while y for, para lo que introduce también las condiciones (if), los operadores lógicos, el tipo boolean y varios tipos numéricos.

Hasta aquí, facilito.

Primer paso: Aprender C++

De cara a Husq, lo primero que tengo que hacer para ponerme en marcha es conocer el lenguaje, porque en la carrera sólo hemos aprendido Ada95, Java y algo de C y PHP. En el mercado hay centenares de libros sobre C++, entre los que he seleccionado unos pocos guiándome por las reseñas de la Association of C and C++ Users. Los agraciados son:

El primero es muy bueno para gente que no ha programado nunca, en ningún lenguaje. Lógicamente no profundiza demasiado, y algo de programación ya sé, así que lo he desechado.
Los dos últimos son libros larguísimos que cubren todos los aspectos del lenguaje, y C++ es enorme. Mucho más de lo que necesito.

Entre los dos restantes, me he decantado finalmente hacia Accelerated C++. Es una obra mucho más reconocida, y no utiliza ninguna biblioteca extraña. Eso sí, el título es muy adecuado: avanza a un ritmo frenético, lo que lo hace muy exigente con el lector. De hecho, compré este libro hace un tiempo, y lo empecé un par de veces, dejándolo a medias. Esta vez espero que sea diferente, gracias al Java y principios de OOP aprendidos en la carrera,

Por otro lado, los amigos de eBox han presentado Zentyal en Teruel esta mañana. Zentyal es un servidor para pequeñas empresas, siendo una alternativa superior a Windows Small Business Server, y que ha tenido una buena acogida. Da gusto comprobar como las empresas locales dedicadas al software libre tienen éxito 🙂

Husq: un gestor de tareas pendientes

¡Esta vez en serio! [Puñetazo en la mesa] Ya es hora de aprender C++ y Qt. Para motivarse a estudiar hay que marcarse objetivos, como un pequeño proyecto. Con tal propósito me he inscrito en la quinta edición del Concurso Universitario de Software Libre, con una propuesta llamada Husq.

Husq será un programa gráfico para la gestión de tareas pendientes, organizadas jerárquicamente.
Cada tarea tendrá nombre, descripción, fecha límite y, opcionalmente, prioridad y categoría. Además, y como punto clave y diferencial, podrá ser desglosada en varias subtareas. Así mismo podrá disparar alarmas programadas.

Mi idea inicial es basarme, en la medida de lo posible, en TuDu. Intentaría que tuviera las mismas funcionalidades que esta utilidad (e incluso que sus archivos fueran compatibles). Como TuDu no es demasiado grande (unas 7000 líneas de código), creo que puede ser un proyecto realista y asequible para meterme en harina y aprender.

No obstante también recogeré ideas de hnb, yaGTD, Taskwarrior, gtg, Yokadi y otros, por lo que quizá dicha compatibilidad no sea posible, o precise de aportar parches a TuDu.

Con respecto a TuDu, Husq aportará:

  • Interfaz gráfica: TuDu es un programa ncurses para la terminal Unix, mientras que Husq será un programa gráfico basado en las bibliotecas Qt de Nokia, por lo que tendrá un look’n’feel nativo tanto en GNU/Linux como en Mac OS X y Microsoft Windows.
  • Internacionalización: TuDu sólo está disponible en inglés, pero Husq lo estará en al menos inglés y castellano, y será posible adaptarlo fácilmente a otros idiomas.
  • Robustez del código: en el código de TuDu la interfaz ncurses está íntimamente imbricada en la lógica del programa. Husq seguirá patrones de diseño, como MVC, que lo harán más robusto y flexible.
  • Mejoras a la usabilidad, nuevas funciones útiles y corrección de bugs.

Un efecto colateral de este proyecto es que las bases del concurso exigen que se vaya informando del desarrollo en un blog, lo que me obligará a retomar éste 🙂

MySQL: cómo copiar un dato de una fila a otra fila de la misma tabla

He intentado ingenuamente hacer esto:

mysql> UPDATE wp_sitemeta SET meta_value=(SELECT P2.meta_value FROM wp_sitemeta P2 WHERE P2.site_id="8" AND P2.meta_key="illegal_names") WHERE site_id="7" AND meta_key="illegal_names";

pero al SGBD no le ha gustado:
ERROR 1093 (HY000): You can't specify target table 'wp_sitemeta' for update in FROM clause

Se puede usar una subconsulta para asignaciones dentro del comando UPDATE, pero no se puede usar la misma tabla para la cláusula FROM de la subconsulta y el objetivo a actualizar. Tras leer esta historia, lo he resuelto usando una tabla temporal:

mysql> UPDATE wp_sitemeta SET meta_value=(SELECT meta_value FROM (SELECT meta_value FROM wp_sitemeta WHERE site_id="8" AND meta_key="illegal_names") AS X) WHERE site_id="7" AND meta_key="illegal_names";
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

OpenBSD 4.6 en VirtualBox 3

He instalado OpenBSD 4.6 en una máquina virtual de VirtualBox 3 sobre Debian. Al hacerlo he tropezado con el bug #639: el instalador daba muchos segmentation fault por no tener habilitadas las extensiones de virtualización VT-x/AMD-V en el BIOS del sistema anfitrión.

Lo he solucionado como explica Siddi en un comentario del fallo:

  1. Creamos la máquina virtual en la interfaz de VirtualBox, indicando como disco de arranque install46.iso.
  2. Abrimos una terminal, y listamos las máquinas virtuales que tenemos:
    % VBoxManage list vms
    VirtualBox Command Line Management Interface Version 3.1.2_OSE
    (C) 2005-2009 Sun Microsystems, Inc.
    All rights reserved.

    "WinXP" {d31d7f15-79c8-4779-5ea3-434217af0881}
    "Solaris" {0c1e6b9d-7748-49ac-14a5-e927da229a6a}
    "CDLive" {d935f872-7ce4-4dc1-9c14-1a9525ac1ff7}
    "OpenBSD" {c361b3c2-5773-49df-b7c0-74eb1fa84f50}

  3. Nos fijamos en el ID de la máquina virtual de OpenBSD, y la iniciamos con la orden
    % VBoxSDL -norawr0 -vm c361b3c2-5773-49df-b7c0-74eb1fa84f50

Y ya podemos proceder a realizar la instalación, sin errores 🙂

Captura de OpenBSD sobre VirtualBox

Cada vez que queramos usar la máquina virtual de OpenBSD, tendremos que acordarnos de lanzar VirtualBox con esa orden.