XML y los tipos de archivos en UNIX

22 Oct 2005

Tradicionalmente los sistemas UNIX no han utilizado lo que venimos a llamar “extensiones” de los archivos. Por ejemplo, en Windows los archivos .doc se suponen de Word, o los .txt ficheros ascii. Pero es de cajón que el contenido de un archivo no tiene porqué ser obligatoriamente lo que su extensión nos dice ser. Además XML ha entrado en juego para meter más ruido al asunto.
<!--more-->

Coge un mp3 y cámbiale la extensión a JPG, si están bajo Windows dirás, ¡coño! una foto Pues no, intenta abrirlo y un error saltará diciendo que el archivo está corrupto. O eso o es que es una canción. Desde Windows ¿98? por defecto el sistema oculta las extensiones, poniendo un iconito u otro según la extensión (que aunque no se vea sigue ahí).

Esto último ha dado lugar a la propagación a gran escala de viruses que, siendo ejecutables con un icono propio igual que el del bloc de notas se llamaban, por poner un ejemplo, cartadeamor.txt.exe. Claro, parece un txt y en realidad es un ejecutable con un virus, bravo Mr. Gates, seguridad ante todo.

En UNIX hay un ejecutable de nombre file que te dice de qué tipo es un archivo, pero no por la extensión sino analizando las cabeceras. La base de datos que utiliza ese programa es fácilmente actualizable para que reconozca cabeceras de nuevos tipos de archivo, se encuentra en unos archivos en /usr/share/misc/magic* donde están los números mágicos (supongo que serán hashes de cabeceras o algo así). A ese programa no se le engaña tan fácilmente, y al preguntarle sobre un ejecutable te dice la plataforma de ejecución, el compilador utilizado, etc…

Ahora a mí se me ha planteado una duda. Se habla mucho sobre los formatos XML (si alguien se pierde escribí esto hace un tiempo, aclarará muchas cosas), como OpenDocument, que son los que usan el recién salido del horno OpenOffice.org 2.0 Pues bien, XML tiene sus ventajas pero ocupa mucho, muchísimo para lo que es, pero por otro lado se puede comprimir muchísimo así que la solución adoptada normalmente para estos formatos es un archivo comprimido en zip (que no con extensión .zip) en el que van varios xml con la información sobre el documento. Además cada tipo de archivo seguirá teniendo sus extensiones, odt para texto por ejemplo.

Vale muy bonito, todo suena genial. ¿Y cómo hace UNIX para saber qué tipo de archivo es? En teoría si le preguntas sobre un OpenDocumentText debería decirte que es un ZIP (y es que lo es), y lo que te dice en la práctica se corresponde con la teoría:
<br /> bash-2.02$ file hola.odt<br /> hola.odt: Zip archive data, at least v2.0 to extract<br />

¿Por qué? Pues porque al ver que es un zip no analiza nada más… Pero, ¿podría? Claro que sí, los que han definido los formatos XML no son tontos y han añadido algunos archivos especiales a sus “zip”:
<br /> bash-2.02$ unzip -l hola.odt<br /> Archive: hola.odt<br /> Length Date Time Name<br /> ------ ---- ---- ----<br /> 39 10-22-05 16:26 mimetype<br /> 0 10-22-05 16:26 Configurations2/<br /> 0 10-22-05 16:26 Pictures/<br /> 2425 10-22-05 16:26 content.xml<br /> 7623 10-22-05 16:26 styles.xml<br /> 1009 10-22-05 16:26 meta.xml<br /> 449 10-22-05 16:26 Thumbnails/thumbnail.png<br /> 6613 10-22-05 16:26 settings.xml<br /> 1074 10-22-05 16:26 META-INF/manifest.xml<br /> ------ -------<br /> 19232 9 files<br />

Y es en ese mimtype donde está la clave, si miramos su interior encontramos lo siguiente:
<br /> bash-2.02$ unzip -p hola.odt mimetype ; echo " "<br /> application/vnd.oasis.opendocument.text
Lo que describe perfectamente el tipo de archivo del que se trata.

Además si echamos un ojo a lo que nos dice unzip vemos que mimetype es el primer archivo que está codificado en el zip, con lo que no sería difícil actualizar la base de datos de números mágicos del comando file para que tuviera en cuenta este nuevo (y espero que muy usado) tipo de archivo.

Esto lo he probado en un FreeBSD 4.6.1 y en una Debian más o menos actualizada y no sé la versión exacta de esas bases de datos. ¿Algún valiente lo prueba en una Ubuntu modernita modernita?<!--more-->