Compiler oe2mbx sur Macintosh (et machines en big endian).

Introduction.

Comme tout le monde ou presque, au boulot, je n'ai pas le choix du matériel ni des logiciels que j'utilise. Il se trouve que l'ordinateur est généralement un pécé sous ouinedoze, et parmi les logiciels imposés, il y a out£ook expre$$. Comme je suis prestataire de service dans une SSII, je suis généralement 3 mois par-ci, 12 mois par là et 6 mois ailleurs, mais j'aimerais bien pouvoir archiver le contenu des boîtes aux lettres chez moi sur mon matériel, des Macintosh, et en plus sous Linux car ma Linux box dispose non seulement d'un espace disque libre important, mais aussi d'un DAT qui est bien pratique pour l'archivage. J'aimerais aussi pouvoir consulter ces messages. Pour cela, il faut convertir le format des boîtes aux lettres d'out£ook expre$$ dans un format plus répandu, le format mbx. C'est là qu'intervient oe2mbx.

Oe2mbx.

Oe2mbx convertit les boîtes aux lettres d'out£ook expre$$ dans le format mbx. Oe2mbx est écrit par Stephan B. Nedregård, et se trouve sur le web à http://www.micropop.com/code/.

Comme d'habitude, je télécharge l'archive, en l'occurrence oe2mbx-1.21.tar.gz, je décompacte, et je regarde ce qu'il y a là-dedans.

La version binaire exécutable est contenue dans l'archive, mais elle est pour Linux Intel. Il n'y a ni script configure, ni de fichier Imakefile, ce qui signifie que les spécificités de la plate-forme sur laquelle on compile ne seront certainement pas prises en compte. Je compile quand même la chose, je l'essaie et comme je pouvais m'y attendre, ça ne marche pas.

Les indiens de mon Macintosh sont plus gros que ceux de ton pécé.

En jetant un coup d'oeil dans les sources, et comme on pouvait s'en douter, oe2mbx lit différentes valeurs numériques (des offsets) dans le fichier boîte aux lettres pour déterminer les débuts et fins des messages qui sont stockés dans la boîte aux lettres. Ne cherchons pas plus loin, il y a là un premier problème car Macintosh fonctionne en gros boutiste (big endian) et un pécé est en petit boutiste (little endian). Il va donc falloir modifier le programme, et faire les conversions nécessaires.

Mais d'abord, non, il n'y a pas d'indiens dans un Macintosh, ni dans un pécé d'ailleurs ...

Par big endian et little endian, on désigne la façon dont les valeurs numériques contenues dans plusieurs octets sont stockées en mémoire, c'est à dire le boutisme ou endianess.

Par exemple, on veut stocker la valeur 0x12345678 (0x indique que le nombre qui suit est exprimé en base 16 ou hexadécimal) dans la case mémoire (ou adresse) 1000. 0x12345678 aura besoin de 4 octets pour être stocké. Sur un système fonctionnant en big endian, ce nombre sera stocké de la façon suivante :

adresse valeur
1000:   0x12
1001:   0x34
1002:   0x56
1003:   0x78

Sur un système fonctionnant en little endian, ce nombre sera stocké de la façon suivante :

adresse valeur
1000:   0x78
1001:   0x56
1002:   0x34
1003:   0x12

Les octets sont donc stockés dans des sens différents suivant que l'on est en gros boutiste ou petit boutiste. Pour passer d'une représentation à l'autre, il suffit de permuter les octets 2 par 2, le premier et le dernier d'une part, le 2e et le 3e d'autre part. Pour une valeur stockée sur 2 octets, il n'y a bien sur que ces 2 octets à permuter.

Solutions possibles.

Pour résoudre le problème d'oe2mbx, il suffit donc de faire la conversion little endian vers big endian. Pour cela, j'ai ajouté 2 fonctions au fichier liboe.c, les appels à ces fonctions là où c'est nécessaire, et une option de compilation pour activer les fonctions de conversion.

Les fonctions de conversion sont les suivantes :

/* conversion d'un entier court */
short cvrt_short(short in)
{
   char     *pin,*pout;
   short    out;
   pin=(char *)∈
   pout=(char *)&out;
   pout[0]=pin[1];
   pout[1]=pin[0];
   return out;
}
/* conversion d'un entier long */
long cvrt_long(long in)
{
   char     *pin,*pout;
   long     out;
   pin=(char *)∈
   pout=(char *)&out;
   pout[0]=pin[3];
   pout[1]=pin[2];
   pout[2]=pin[1];
   pout[3]=pin[0];
   return out;
}

L'option de compilation ajoutée est -D_BIG_ENDIAN. L'appel au compilateur devient donc :

gcc -c -D_BIG_ENDIAN src/liboe.c -o lib/liboe.o

Les autres modifications effectuées dans le fichier-source sont encadrées par les lignes suivantes :

#ifdef _BIG_ENDIAN
et
#endif

Elles contiennent l'appel à l'une des 2 fonctions précédentes, géneralement après avoir lu une valeur numérique ou un ensemble de valeurs numériques dans le fichier boîte aux lettres par fread, par exemple :

   fread(&self,4,1,data->oe);
#ifdef _BIG_ENDIAN
   self=cvrt_long(self);
#endif

ou

   fread(&thead,sizeof(oe_table_header),1,data->oe);
#ifdef _BIG_ENDIAN
   thead.self=cvrt_long(thead.self);
   thead.list=cvrt_long(thead.list);
   thead.next=cvrt_long(thead.next);
#endif

Ces modifications ont été faites à la va vite, quick and dirty comme ils disent. Il y a moyen de faire plus efficace, mais au moins on comprend facilement ce qui se passe.

Téléchargement.

Les tarballs sont disponibles ici avec l'accord entousiaste de Stephan B. Nedregård, qui ne devrait pas tarder à intégrer ces modifications dans son programme.

La version 1.21 originale d'oe2mbx, sous license GPL : oe2mbx-1.21.tar.gz

La version modifiée, sous license GPL également, mais sans les exécutables : oe2mbx-1.21-big-endian.tar.gz

Remarques.

Je n'ai pu tester cette modification que sur des fichiers de boîtes aux lettres produits par out£ook expre$$ 4 pour ouinedoze. Je ne sais pas si ça fonctionne avec les fichiers d'OE 5, ni avec les versions d'OE pour Macintosh. Si vous avez l'occasion d'essayer sur des fichiers produits par ces versions, merci de m'indiquer si ça marche ou pas.

Etienne Herlent.

 

Dernière mise à jour le 19/7/00.

les fichiers en téléchargement sont à ftp://ftp.linux-france.org/pub/macintosh/

 

Retour à GNU Linux sur Macintosh