h1

Reverse SSH tips

2013.04.04

Hello,

Today I will share some tips with SSH. It is very useful everytime even with crappy OS like Windows. One of the most funny feature is the TCP forwarding by Reverse SSH. For example in the case where you must connect to a SSH server and this one is behind a firewall. You have no access to the firewall because you are at work.

First one

You must connect the computer (behind the firewall) to a server available on Internet (at home).

ssh -R 8888:localhost:22 homeuser@homeip

It will create an SSH tunnel with your computer at home. You can choose an other port; 8888 is just for the example.

Second one

At home, you can connect to your computer at work by this way :

ssh workuser@localhost -p 8888

Easy, isn’t it? Note that is possible to forward every things with SSH. All local servers in your company…

But, with Windows it’s a pain

Not really, just use Cygwin. You can install openssh-server with the packages manager. Just use ssh-host-config -y from the Cygwin terminal. Start the terminal with admin rights if necessary. A service will be installed in order to start openssh. Start the service and enjoy.

You should search on the web for more examples and tips. Here you will found the essential.

Bye

Mathieu Schroeter

h1

Mount a gunzip’ed image disk file from a network share

2013.03.03

Hello,

Some tips about a way to restore a very big gunzip’ed image disk from a network share. I’ve changed of computer and my previous disk was saved in a image with `dd` and a pipe on gunzip. The image is located on a network share. But I can not restore the whole image because it uses too much spaces. Then, I will mount this one but it was compressed. The solution is `mountavfs`. You can use this command in order to open compressed files on the fly.

The steps are something like this:

avfsd -o allow_root ~/.avfs
mountavfs

Look at avf.sourceforge.net

 

sudo mount -t nfs 192.168.1.1:backup ~/mybackup

Just my backup; mount yours as usual…

 

cd ~/.avfs/home/myuser/mybackup

Here, I will found my image disk file.

 

sudo mount -o ro,loop,offset=$((63 * 512)) backup.img.gz ~/dst

I mount my file from the ~/.avfs directory (then it will be uncompressed on the fly). I must specify the partition offset because the image is the whole disk with a GPT structure. Look for fdisk, gdisk in order to retrieve the offset. The first seems to be always 63th bloc.

Now you can see the whole content of your gunzip’ed image in the ~/dst directory.

 

Mathieu SCHROETER

h1

libvalhalla-2.1.0

2012.08.12

Hey ça faisait vraiment longtemps. Comme quoi, vaut mieux tard que jamais.

J’ai publié une nouvelle version de libvalhalla qui remet à jour les grabbers Amazon et TMDB. C’était principalement des problèmes de changement d’API chez ces deux services. A noter que les grabbers qui se basent sur des scripts PHP maison sont cassés mais non-réparés. Je pense à Allocine et ImDB. Mais pour ces deux grabbers il faut être clair, sans vrai webservice c’est très pénible à maintenir. Il existe un webservice caché pour Allocine et j’ai cet API sous la main. Par contre je ne sais pas si c’est encore fonctionnel (car l’API que j’ai a plus d’une année) et peut être que depuis tout ce temps il y a quelque chose d’officiel. En ce qui concerne ImDB j’en ai aucune idée.

A part ça il y a quelques changements plus spécifiques. Je vous invite à consulter le ChangeLog.

Site : http://libvalhalla.geexbox.org

Sources : http://libvalhalla.geexbox.org/releases/libvalhalla-2.1.0.tar.bz2

Bye bye

Mathieu

h1

La bibliothèque des ELFs

2010.12.05

Hello,

Il y a beaucoup de choses que l’on apprend pas du tout dans les cours de programmation, et même en suivant une haute école pour une formation en tant qu’ingénieur. Heureusement les logiciels libres permettent de côtoyer des spécialistes qui ont une expérience pratique du logiciel, contrairement à de nombreux professeurs qui ne connaissent que la théorie mais ne semblent pas vraiment pratiquer et passent ainsi à côté de potentiels problèmes importants. Je pense tout particulièrement au C dans le contexte des exécutables ELF utilisés par les OS Unix-like. Bien que beaucoup d’écoles restent encore trop rattachées sur les technologies Microsoft, dans le monde des systèmes embarqués GNU/Linux est particulièrement présent. Néanmoins la formation sur le langage C n’est pas toujours très bonne. Une erreur trop courante concerne les espaces de nom utilisés par les bibliothèques.

Les fonctions "static"

Quand j’étudiais le C++ à l’école d’ingénieur on devait travailler avec un outil que je déteste absolument, c’est Rhapsody. Un générateur de code à partir d’UML. L’UML c’est très bien pour poser les idées et réfléchir sérieusement sur un programme. Mais le fait qu’un langage de programmation ne soit pas objet ou orienté-objet n’empêche pas de se donner des règles reposants sur les concepts objets. Bref, Rhapsody c’est pire que tout, il génère du code (C, C++ ou autre) à partir d’UML. Finalement le programmeur fait du dessin, des carrés, des ronds et les relie avec des flèches. Il presse un bouton et des centaines de lignes de code se génèrent. Wouhaw.. moi qui aime programmer.. Bientôt on devra se former en tant que graphiste avant de réaliser un logiciel :-).

OK vous l’aurez compris, je déteste ça. Mais là où je veux en venir c’est à une petite anecdote. On travaillait donc sur ce logiciel et un des objet était instancié une seule fois (donc en tant que Singleton). Alors je demande à l’assistant qui était présent avec nous pour répondre à nos questions:

Qu’est-ce que c’est concrètement un Singleton?

Il s’assied et m’explique ce que je sais déjà, c’est à dire que l’objet est instancié qu’une seule fois. Il me montrait via l’interface de Rhapsody comment on paramètre la classe pour être un Singleton. Et me ré-expliquait toujours la même chose. J’essayais de reformuler ma question en vain. C’est finalement en allant observer le code C généré que j’ai vu l’objet instancié en tant que variable globale statique.

5 secondes pour lire le code et comprendre, 15 minutes d’explication dans le monde "merveilleux" de Rhapsody et des formes géométriques.

Mais revenons à nos fonctions statiques

Une chose que tout le monde apprend aux cours c’est qu’une variable déclarée comme étant "static" dans une fonction, garde sa valeur entre chaque appel de fonction. Par contre je n’ai jamais eu un seul professeur qui nous ait expliqué à quoi sert une variable globale statique, ou alors une fonction statique (sauf les fonctions statiques en C++, mais ici je fais référence au C).

En fait, il est très rare de voir un professeur proposer de créer une bibliothèque pendant un cours. En principe on créer des exécutables avec un main. En C je n’ai jamais vu (en dehors des logiciels libres et des professionnels), des fonctions déclarées comme étant statiques. Que se sois du code créé par des professeurs ou par des étudiants. Pourtant l’écriture de bibliothèques demandent quelques considérations supplémentaires qui concernent les espaces de nom et plus particulièrement les ELF.

Mais tout d’abord une fonction "static" est une fonction qui n’est pas "extern" (qui est le qualificateur de type par défaut). En étant "static" la visibilité de la fonction est restreinte au fichier source où elle a été déclarée. Une fonction externe peut être atteignable depuis n’importe où dans les sources. Mais dans le cas des ELF c’est encore plus subtile que ça car elle peut être atteinte depuis n’importe quelles bibliothèques ou applications étant liées avec elle.

Les Shared Object (so) et les DLL

Sans partir dans des explications compliquées et inutiles il faut bien faire la différence entre une DLL (de chez Microsoft) et un Shared Object (qui vient du monde Unix). Les développeurs pour Windows connaissent bien:

__declspec(dllexport)

Qui est un qualificateur de type inventé par Microsoft. Il permet de spécifier les fonctions qui doivent être exportées par la DLL. Vous pouvez aussi utiliser un fichier .def qui donne la liste des fonctions à exporter. Ce principe existe aussi avec les gcc >=4 mais est rarement utilisé à ma connaissance. Quoi qu’il en soit dans tous les cas vous avez une liste de symboles exportés.

La différence qui m’intéresse c’est au runtime, lorsque le lanceur d’application doit charger les bibliothèques. Dans le cas d’une DLL, le programme va rechercher les pointeurs sur les fonctions désirées à l’aide de LoadLibrary. C’est lourd mais ça fonctionne. Dans le cas d’un "so" le fonctionnement est très différent. Le lanceur de programme de Linux va charger les bibliothèques les unes après les autres dans l’ordre où elles ont été liées. Lorsque le programme a besoin d’une fonction, c’est la première occurrence trouvée qui sera utilisée.

Concrètement

Imaginons un programme qui utilise libplayer et libvalhalla. Si je n’étais pas conscient du problème que je viens d’expliquer, dans ces deux bibliothèques j’aurais pu écrire une fonction qui a exactement le même nom (de part et d’autre) comme par exemple:

libplayer:

void foobar (int a, int b);

libvalhalla:

void foobar (int c);

Ces fonctions ne sont pas static car bien entendu j’aimerais les utiliser partout dans les projets. Alors que se passe-t-il lorsqu’on lie l’application sur ces deux bibliothèques? Notez que ces deux fonctions ne sont pas non plus déclarées dans les en-têtes "publiques" que vous distribuez à vos développeurs. Par exemple vous donnez ceci à un ami:

player.so (que vous avez compilé vous même)

Et un fichier d’en-tête:

player.h

/* libplayer header */
void libplayer_is_the_best (void);

De même avec la seconde bibliothèque:

valhalla.so
valhalla.h

/* libvalhalla header */
void libvalhalla_is_the_best (void);

Maintenant vous avez créé une application tel que:

#include <player.h>
#include <valhalla.h>

int
main (void)
{
  libplayer_is_the_best ();
  libvalhalla_is_the_best ();
  return 0;
}

Dans libplayer.so il y a le symbole "foobar", mais il existe également dans la bibliothèque libvalhalla.so. Lorsque vous liez votre application vous n’avez aucune erreur. Vous utilisez deux fonctions considérées comme publiques et qui n’ont pas du tout le même nom. Alors où est le problème? Et bien c’est très simple. Quand vous liez votre programme vous devez passer les noms des bibliothèques. Par exemple:

cas 1: gcc -lplayer -lvalhalla main.c -o main

Mais vous auriez aussi pu faire

cas 2: gcc -lvalhalla -lplayer main.c -o main

Les deux façons sont correctes mais le comportement de l’application main n’est pas du tout le même. Les deux bibliothèques utilisent la fonction foobar. Cette fonction n’a pas le même nombre d’arguments dans libvalhalla que dans libplayer et leurs comportements sont différents. Les fonctions libplayer_is_the_best et libvalhalla_is_the_best utilisent "en théorie" leurs propres fonction foobar. Et bien en réalité ce n’est pas le cas.

Dans le cas 1, le chargeur de programme va commencer par player.so, puis par valhalla.so. Lorsque la fonction libplayer_is_the_best va utiliser foobar, alors le foobar de player.so va être utilisé. Mais lorsque valhalla.so va utiliser foobar, c’est aussi le foobar de player.so qui sera utilisé (aïe). Dans le cas 2 c’est le même principe mais inversé. Les conséquences peuvent être très imprévisibles.

Si vous avez une application qui est liée à des dizaines de bibliothèques il faut espérer que tout le monde ait pris la peine de faire deux choses importantes:

  1. Utilisez toujours un espace de nom pour vos fonctions. Par exemple libvalhalla en utilise trois  (libvalhalla_, valhalla_ et vh_). Un espace de nom en C ce n’est rien d’autre qu’un nom identique que vous concaténez au début des noms. Par exemple nos foobar auraient pût se nommer libplayer_foobar et libvalhalla_foobar, ce qui aurait évité la collision.
  2. Déclarez toujours en static toutes les fonctions qui ne sont pas utilisées en dehors du fichier source. Une fonction static n’a pas besoin d’espace de nom, car elle n’est jamais exportée! Et faire ainsi permet d’aider le compilateur à effectuer de meilleurs optimisations.

Comment détecter et debugger les collisions

Une des solution c’est de compiler votre programme entièrement en static. Il doit donc être lié aux .a de toutes les bibliothèques. Dans ce cas de figure, une collision sera forcément détectée par le linker.

Pour debugger commencez par tout compiler en -O0 -g3, puis utilisez valgrind. Vous arriverez à remonter sur l’appel de fonction qui s’est fait de la libA à la libB. Vous pourriez voir le foobar de player.so appelé par valhalla.so.

En pratique…

Il y a de nombreux mois, j’ai eu des problèmes de ce type avec libVLC et libplayer, car les fonctions de getopt étaient exportées par libVLC bien que c’était uniquement pour son propre usage. Ça me provoquait des collisions avec le getopt que j’utilise dans libplayer-test. J’ai bien entendu reporté le problème qui a été corrigé.

J’ai aussi eu un cas avec GeeXboX et le projet GuPNP. Le développeur principal a aussi été prévenu mais a priori il s’en fiche (ce n’est pas moi qui l’a contacté mais un autre du team). Du coup ce n’est pas possible de lier en static si on utilise deux de ses libs car elles ont les même fonctions non-static pour traiter le XML. Et le pire c’est que le nom de ces fonctions n’a pas d’espace de nom très original. Notez qu’en dynamique il n’y a jamais de problème car heureusement dans les deux bibliothèques, les fonctions sont les mêmes.

Bref, en fouillant bien on doit trouver ce genre d’exemple un peu partout…

J’espère que ce poste vous sera utile pour vos propres développements.

Bon code et à bientôt!

Mathieu SCHROETER

h1

OpenBricks

2010.10.19

Hello,

OpenBricksUn "nouveau" (notez bien les guillemets) projet vient de faire surface officiellement de nos dépôts. Il est nommé OpenBricks et son but et de fournir un environnement assisté pour construire sa propre distribution pour l’embarqué (ou pas, c’est pas une obligation). Au premier abord il n’y a rien de bien nouveau dans le principe, car il existe déjà de gros projets qui vont en ce sens tel que OpenEmbedded ou encore Buildroot. La première question étant bien sûr "pourquoi réinventer la roue?" est complètement illusoire dans notre cas. Car bien que ce projet voit le jour uniquement depuis ce mois, en réalité il couvre 8 ans de développement et d’expérience.

Je veux en parler sur mon blog pour une raison en particulier. Je parcours un peu les commentaires sur les news relatives à OpenBricks. Les réactions sont du genre "beuh? à quoi ça sert? quel intérêt?".

La réponse est très simple et tout simplement incroyable, OpenBricks sert à créer la distribution GeeXboX.

Et un outil de ce genre vaut mieux le rendre un peu plus générique (c’est comme si on avait transformé notre marteau planteur de clous GeeXboX en marteau universel). Avant OpenBricks le toolchain GeeXboX était très orienté sur les spécificités du multimédia et de ce que GeeXboX propose tel que les images ISO, le générateur d’ISO, etc,… Ils arrivaient à certaines personnes d’utiliser notre toolchain à d’autres fins. Je l’ai personnellement hacké pour avoir un petite distribution Linux perso sur mon Palm ainsi que pour un robot de laboratoire. Car bien que le toolchain GeeXboX était très axé sur le multimédia, c’était facile à le modifier pour le dédier à autre chose.

Alors on peut imaginer une autre réponse pour la question "à quoi ça sert?", et bien OpenBricks sert à créer une distribution pour différentes applications et sans devoir bidouiller (contrairement à l’époque).

Que du positif! non?

A+

Mathieu SCHROETER

h1

Un petit retour sur Vim

2010.07.25

Hello,

J’avais déjà écrit un article sur Vim il y a pas mal de temps. J’indiquais simplement ma configuration de l’éditeur. Depuis ce jour j’ai fait quelques modifications pour mon confort, mais absolument rien d’extraordinaire. J’aurais pu reprendre mon ancien article, mais quitte à en écrire un nouveau.

Les différences par rapport à l’ancien se situent principalement au niveau de "l’auto-completion". Le but est d’avoir quelque chose de mieux que des listes indigestes comme avec  <CTRL-P>, <CTRL-N>,…. Qui ont bien entendu aussi leurs utilités. J’ai donc rajouté OmniCppComplete que vous devez installer dans votre ~/.vim. Les menus de popup s’affichent automatiquement dès que l’on tape un [.] ou une "->" pour les structures par exemple. Si par contre vous tapez le nom d’une fonction et que vous voulez la liste des arguments, alors commencez à taper un peu son nom, puis elle sera visible dans un popup avec <CTRL-X> <CTRL-O>.

Le .vimrc ci-dessous créer également les tags à l’aide de <CTRL-F12>. Alors n’oubliez pas d’installer ctags sur votre distribution.

" Global settings
set nocompatible
syntax on
set hlsearch
set shiftwidth=2
set background=dark
set cursorline
inoremap <S-Tab> <C-V><Tab>

" Show line number
set number
highlight LineNr term=bold ctermfg=darkgray guifg=darkgray

" Special configuration for devel
filetype on
filetype plugin on
set ofu=syntaxcomplete#Complete
autocmd FileType c,cpp,cxx,h,fl,php set cindent|set cino=:0|set tabstop=8|set softtabstop=2|set expandtab
autocmd FileType make setlocal noexpandtab

" Special highlighting for Doxygen
let g:load_doxygen_syntax=1

" Show when a line exceeds 80 chars
au BufWinEnter * let w:m1=matchadd('ErrorMsg', '\%>80v.\+', -1)

" Highlight Tabs and Spaces
au BufWinEnter * let w:m2=matchadd('Tab', '\t', -1)
au BufWinEnter * let w:m3=matchadd('Space', '\s\+$\| \+\ze\t', -1)
set list listchars=tab:»·,trail:·
highlight Tab ctermbg=darkgray guibg=darkgray
highlight Space ctermbg=darkblue guibg=darkblue

" OmniCppComplete
let OmniCpp_NamespaceSearch = 1
let OmniCpp_GlobalScopeSearch = 1
let OmniCpp_ShowAccess = 1
let OmniCpp_ShowPrototypeInAbbr = 1
let OmniCpp_MayCompleteDot = 1
let OmniCpp_MayCompleteArrow = 1
let OmniCpp_MayCompleteScope = 1
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]

" CTags
map <C-F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR><CR>
set tags=~/.vim/stdtags,tags,.tags,../tags
au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
set completeopt=menuone,menu,longest,preview

Bien entendu ce .vimrc est de loin pas parfait, mais il remplit parfaitement mes besoins. En quelques mots, les dépassements du 80ème caractère s’affichent en rouge, les tabulations et les espaces en fin de ligne sont mis en évidence. Pour insérer une vraie tabulation alors il faut faire <SHIFT-TAB>

Un exemple avec libvalhalla que j’ai "salopé" exprès :o)

Vim - libvalhalla

A bientôt,

Mathieu SCHROETER

h1

Quoi de neuf…

2010.07.03

Hello,

Pas beaucoup de nouvelles depuis passablement de temps. Je vais faire néanmoins un petit tour en bref des quelques activités sur lesquels j’ai travaillé. Mon activité sur les projets GeeXboX à baissé nettement depuis quelques semaines pour plusieurs raisons. J’ai eu 3 mois de service civil où j’ai qu’en même pu travailler dans mon domaine (l’informatique et plus précisément la programmation). Et de ces trois mois, sont nés deux petits projets hébergés sur les serveurs GeeXboX.

DaisyDuck & libduck

DaisyDuckJe vous invite à consulter le site internet. DaisyDuck est un lecteur de livre audio Daisy 2.02, basé sur Qt et libVLC. Il est multi-plateforme et distribué aussi bien pour Windows que pour Linux. Il pourrait également être adapté sans trop de problème à MacOSX. Mais pour des questions de temps, je me suis arrêté à la version Windows.

Il existe de "nombreux" (beaucoup de commerciaux aussi) programmes de lecteur de livre Daisy. Mais la grande différence avec DaisyDuck c’est tout d’abord libVLC. La plupart ne sont pas capables de lire une grande variété de format, et encore moins de protocole réseau. Même qu’en principe pouvoir lire n’importe quel format n’est pas un respect entier des spécifications. Par contre c’était le but de mon travail. Permettre la lecture de livre en ligne, ce que le logiciel est parfaitement capable de faire, et ça fonctionne à merveille. Merci à l’équipe de VideoLAN.

Le deuxième petit projet est donc libduck. Il est également présenté sur le site internet de DaisyDuck. Son but est de réaliser le "parsing" des fichiers Daisy 2.02.

Malheureusement je n’ai pas utilisé libplayer comme base à DaisyDuck. La raison principale est que libplayer n’est pas encore très utilisable (compilable) pour Windows pour différentes raisons techniques. Et faute de temps, je ne pouvais pas me permettre de travailler sur le port de libplayer dans mon temps destiné à mon service civil.

Valhalla

Bien que j’ai terminé le service civil depuis fin mai, il me fallait également trouver un emploi. Et depuis mi juin, j’effectue des trajets relativement longs par jour. Mon temps libre en soirée est devenu presque nul. Je me motive alors à travailler sur les projets GeeXboX, dans le train. Et faut bien l’avouer, c’est difficile d’avancer vite. Mais ça avance qu’en même, et sur libvalhalla cette fois ci.

J’ai commencé sérieusement à ajouter le support des langues pour les méta-données. Le patch devrait arriver très vite, peut être même demain. Par contre ce n’est pas encore complet. Je dois adapter les fonctions pour les sélections des méta-données afin de pouvoir filtrer sur les langues, il me faut aussi encore implémenter le support des grabbers multi-lingues. Ou tout du moins, pouvoir paramétrer les grabbers multi-lingues pour récupérer les données dans une langue spécifique. Au moment où j’écris ces lignes, j’ai uniquement ajouté le support des langues dans la base de donnée, et adapté les grabbers afin que l’information de langue soit correctement indiquée avec les meta-données. Par exemple, le grabber Allocine indique ainsi du "fr" pour ce qui est des résumés, catégories, etc,.. Les autres grabbers sont en principe en "en" et les données qui n’ont pas de langue (par exemple un codec, la taille du fichier ou alors la résolution) sont indiquées comme "undef". Toutes les méta-données récupérées par les "parsers" sont également en "undef".

Un autre projet dans lequel je veux me lancer sérieusement, c’est de pouvoir paralléliser le "downloader" et les "grabbers" pour un même fichier. Afin de récupérer les images un peu plus vite. Mais je ne veux pas rentrer dans ce genre d’explications avec ce poste.

libplayer

Aux alentours de mai, j’ai intégré le support de VDPAU directement dans libplayer. Alors non, il n’y a rien d’extraordinaire, ça concerne quelques lignes. L’idée c’est que pour pouvoir exécuter MPlayer correctement avec VDPAU, il faut connaître les caractéristiques du GPU. Et pour ça, il faut interroger la carte graphique. Avec GeeXboX, cela se faisait en dehors d’Enna/libplayer avec un script et un exécutable. Mais ceci n’est plus nécessaire, car maintenant libplayer fait cette tâche de manière transparente.

Enna

Nicolas à modifié en profondeur le VFS d’Enna. J’ai donc pris le temps de retravailler le browser Valhalla. Celui-ci est désormais mieux fait au niveau des chemins d’accès (je n’ai pas envie d’expliquer ça ici). Bref, en gros ce browser re-fonctionne avec le nouveau VFS mais il a qu’en même quelques petites régressions qui ne devraient pas être trop difficiles à corriger.

Le projet de "hardware"

Réaliser un set-top box GeeXboX est très nouveau et assez ambitieux. L’idée est de partir de zéro, de la schématique au PCB puis aux prototypes, pour finir avec la distribution GeeXboX/Enna optimisée au mieux pour le matériel. Le seul gros obstacle actuellement c’est la difficulté à avoir accès aux datasheets des composants intéressants (NDA nécessaires dans quasiment tous les cas). On vise bien sûr le full-HD avec si possible un petit plus par rapport aux autres boards. Tel que par exemple des ports miniPCIe. On a les ressources techniques, manque la doc :-). Ensuite il y aura forcément le problème du temps qui pourra être investi dans ce projet. Mais pour le moment je suis assez confiant.

Pour terminer (et pour arrêter de parler de moi)

Toolchain

Davide fait un gros boulot depuis plusieurs semaines. Il a pris une excellente initiative concernant le toolchain GeeXboX. Le but est d’avoir un toolchain basé sur opkg. Tout se construit via des paquetages, que se sois les dépendances pour la construction du toolchain (gcc, binutils, etc…) que les éléments du "target".

J’ai toujours aimé le toolchain GeeXboX pour sa simplicité. On entend souvent parler d’OpenWRT par exemple. Il est sûrement très bien, mais notre toolchain c’est notre identité. J’ai toujours été réticent à le voir se faire remplacer par une solution qui viendrait d’ailleurs. Alors un grand merci à Davide pour avoir fait ce gros job!

Le site web

Benjamin en avait marre du site web. Je le comprend tout à fait car j’ai toujours eu la flemme d’y faire des modifs. Faut être clair, chez GeeXboX en principe faut un peu toucher à tout. Mais parfois les tâches comme le site, pas grand monde à envie d’y mettre les mains. Alors Benjamin à basculer sur WordPress qui simplifie grandement la vie aussi bien pour la facilité que pour le design.

J’aimerais qu’en même dire un mot sur l’ancien site. Il avait une particularité en comparaison à beaucoup d’autres sites internet. Ce bon vieux site était entièrement réalisé en XML+XSL (un très bel exemple et très professionnel). Bien sûr les sources sont toujours bien au chaud, dans les dépots Mercurial.

Enna

Nicolas a fait diverses modifications sur Enna en plus du VFS. Néanmoins je n’ai pas encore pu compiler ces dernières modifs :-P. Faute de temps principalement, car je dois mettre à jour les EFL.

A bientôt,

Mathieu SCHROETER

Suivre

Recevez les nouvelles publications par mail.

%d bloggers like this: