dimanche 11 septembre 2011

spacef

Some time ago, I started working on a gopher server (gopher is the protocol behind the gopherspace, an important part of Internet) and I choose to write it in a modern, efficient language: C. The gopher protocol is mostly about sending tab-separated data from the server to the client in response to the requested path. So, most of the parsing work is done on the client side and the server just have to generate this data.

But recent implementations of gopher serves introduced a new concept: Gophermaps: those are server side files that describe what should be displayed to the client. That also means the server has some parsing work to do. But it should be ok, C comes with maybe one the best string manipulation library ever made with short, descriptive function names (for instance, strpbrk or strrchr) and a sane way to store string length (I really wonder why would anyone use an alternate implementation such as bstring).

So, the problem was quite simple: I wanted to read several pieces of non-tab data separated by tabs and wrote something like that:
sscanf(buffer, "%s\t%s", &first, &second);
I expected it would read some non-space data (yes, there's already a problem here if there's space before the tab), then a tab, then some other non-space data. It doesn't.

After reading the man page and doing some tests, I understood a few things about my expression:
  • %s first skips leading spaces, before reading non-space data;
  • \t match any number of spaces, in fact any space in a pattern match any number of spaces.
So my scanf call was the same as this one:
sscanf(buffer, "%s%s", &first, &second);
and is equivalent to this regular expresssion:
"[:space:]*([^:space:]+)[:space:]*([^:space:]+)"
not really what I wanted to read...

First I needed to figure how to read non-tab data only, and it happens that this part was simple enough. The square brackets in scanf patterns work somehow the same than in regular expression. So %[^\t] will read a sequence of non-tab characters (ho yeah... a \t between square brackets only match a tab).

Next I have to read the "only one tab" part and this part was a lot more fun. %[\t] would match a sequence of tabs. To match only a specified number of tabs, you have to use a decimal between the % and the square bracket. The pattern is now %1[\t] but there still a problem: each conversion specification (those %... things) needs to be stored in some output variable and that would be stupid to store a tab each time I need to read one. Scanf provides the * modifier that tells to discard output of the conversion specification. The final pattern for reading a that is then %*1[\t].

And the correct version  of my scanf is:
sscanf(buffer, "%[^\t]%*1[\t]%[^\t]", &first, &second);
For those curious about my gopher server, the mercurial repository is here: http://hg.tuxfamily.org/mercurialroot/gophrier/gophrier/ and there's a mirror here: https://bitbucket.org/guillaume/gophrier

samedi 3 septembre 2011

Freeplug le dauphin

Je suis abonné Free depuis maintenant de nombreuses années et j'ai, à ce titre, eu le plaisir d'utiliser plusieurs versions de leur fameuse Freebox, et surtout la joie sans cesse renouvelée de migrer de la version précédente à la nouvelle.
Ayant sorti une nouvelle box récemment (enfin, heu... ouais, décembre 2010, pas si récemment en fait...) et tout le monde autour de moi m'expliquant qu'elle allait complètement changer ma vie (d'où le nom « révolution »), je me suis décidé à sauter le pas de nouveau et faire la mise à jour.

Donc, je vous passe les détails, mais je fais l'échange, j'installe et tout se passe à peu près bien... tout étant dans le « à peu près ». En fait, c'est un peu ma faute aussi, je cherche un peu les ennuis ; récemment j'avais souscrit à l'option Multi TV qui permet d'avoir deux gros boitiers moches au lieu d'un seul et donc, de regarder la télé Free sur plusieurs postes.
Ce truc absolument génial permet, par exemple, de regarder « Sauvez Willy » en même temps que vous épluchez des patates, ce qui du coup rend le film vachement plus intéressant.

C'est à ce moment là que j'ai découvert les Freeplug : des boitiers CPL en plus gros et devant être associés (ça ne sert à rien, mais Orange le fait sur ses Livebox, donc ça doit être bien). Avec ma nouvelle Freebox, j'ai reçu de nouveaux Freeplugs, une nouvelle version, plus petits, plus simples d'utilisation, tout ça. Sauf que voilà, pour pouvoir brancher mon boitier supplémentaires il fallait que j'associe un ancien Freeplug à mon couple de nouveaux et, a priori, ils semblaient assez réfractaires pour le plan à 3.

Après avoir cherché un peu sur les forums et trouvé des solutions innovantes telles que danser autour des boitiers en invoquant un dieu sumérien, je me suis décidé à appeler le support Free. Là au niveau 1, je suis tombé sur une demoiselle (sûrement à l'autre bout du monde vu la qualité de la transmission) qui m'a fait refaire (lentement) la plupart des manipulations que j'avais trouvées sur les forums (bon, pas la danse autour des boitiers) ; mais non, toujours pas d'association. Au bout d'un moment, elle décide de me faire passer en niveau 2.

Là, clairement, j'ai affaire à un technicien (en France, en plus) qui rapidement m'explique la bonne procédure pour associer des Freeplug, quels que soient les Freeplug et quelle que soit la situation. Et donc, pour vous faire économisez plus d'une heure de hotline, je vous fournis gratis cette procédure :

Association des Freeplug
  1. Faire table rase sur les Freeplug : chaque Freeplug doit être réinitialisé, surement pour couper une éventuelle association précédente. Pour les nouveaux Freeplug, il faut appuyer 15 secondes sur le bouton lumineux, vous devriez le voir passer à l'orange, puis relâcher. Pour les anciens Freeplug, il faut appuyer sur le minuscule bouton noir pendant 10 secondes, les diodes devraient clignoter, puis repasser au vert.
  2. Une fois que tous les Freeplug (anciens ou nouveaux) ont été réinitialisés, il faut les associer deux par deux. Dans mon cas, j'ai d'abord associé les nouveaux, puis un nouveau avec un ancien. Sur un nouveau Freeplug le passage en « mode association » se fait en appuyant deux secondes sur le bouton lumineux puis en relâchant. Le voyant devrait clignoter jusqu'à ce qu'il trouve un copain. Sur les anciens Freeplug, il faut appuyer au moins une seconde sur le petit bouton noir. Pareil, il devrait clignoter jusqu'à ce qu'il trouve un copain.
Clairement, l'étape cruciale, c'est cette fameuse réinitialisation. Sans ça, pas d'association.

À partir de ce moment, les choses se sont simplifiées. Mon boitier supplémentaire avait accès au réseau mais ne voyait pas le serveur. Ah mais oui, forcément, il faut faire un « hard reboot » : retirer l'alimentation du boitier, appuyer sur un bouton de la façade, rebrancher l'alimentation. On y est presque, le boitier tente de s'installer mais le téléchargement loupe (la fameuse erreur 3), donc nouveau hard reboot... encore et encore, au moins 10 fois en tout. Mais au bout d'un moment, il y arrive et la télé est de nouveau là et je vais de nouveau pouvoir regarder les aventures de mon dauphin préféré dans ma cuisine ! Cool !

Voilà, c'était surement la pire migration de Freebox que j'ai eu à faire, mais bon rien de vraiment terrible non plus. Surtout si vous n'avez pas de boitier supplémentaire. À part ça, ma vie n'a pas changé, mon débit est toujours aussi pourri ;  certaines chaines on l'air de mieux passer sans que je ne comprenne vraiment pourquoi. Par contre, je peux appeler des portables depuis mon fixe, c'est cool parce que je ne consommais déjà pas tout mon forfait portable.