<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Emile "iMil" Heitor 's home &#187; c0daz</title>
	<atom:link href="http://imil.net/wp/tag/c0daz/feed/" rel="self" type="application/rss+xml" />
	<link>http://imil.net/wp</link>
	<description>life, unix and stuff</description>
	<lastBuildDate>Sun, 13 May 2012 10:43:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>t&#8217;as fait de l&#8217;autoQUOI ??</title>
		<link>http://imil.net/wp/2009/12/03/tas-fait-de-lautoquoi/</link>
		<comments>http://imil.net/wp/2009/12/03/tas-fait-de-lautoquoi/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 17:31:15 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[autoconf]]></category>
		<category><![CDATA[c0daz]]></category>
		<category><![CDATA[pkgin]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=358</guid>
		<description><![CDATA[Ceux qui me connaissent et qui ont lu le post prÃ©cÃ©dent ont peut-Ãªtre cru Ã  l&#8217;imposture: &#8220;. Basculement vers autoconf pour la gÃ©nÃ©ration du Makefile&#8221;
iMil ? c&#8217;est bien toi ?
Oui alors attention hein, pas d&#8217;affolement. Il s&#8217;agit rÃ©ellement d&#8217;une utilisation trÃ¨s trÃ¨s light de ces outils que j&#8217;Ã©vite habituellement comme la peste. Tellement light que [...]]]></description>
			<content:encoded><![CDATA[<p>Ceux qui me connaissent et qui ont lu le post prÃ©cÃ©dent ont peut-Ãªtre cru Ã  l&#8217;imposture: <i>&#8220;. Basculement vers autoconf pour la gÃ©nÃ©ration du Makefile&#8221;</i></p>
<p>iMil ? c&#8217;est bien toi ?</p>
<p>Oui alors attention hein, pas d&#8217;affolement. Il s&#8217;agit rÃ©ellement d&#8217;une utilisation trÃ¨s trÃ¨s <i>light</i> de ces outils que j&#8217;Ã©vite habituellement comme la peste. Tellement <i>light</i> que seul <a href="http://www.gnu.org/software/hello/manual/autoconf/">autoconf</a> m&#8217;a Ã©tÃ© utile.</p>
<p>Mais reprenons. Ceux qui ont eu le courage de se plonger dans le code de <a href="http://imil.net/pkgin/">pkgin</a> se rappellent peut-Ãªtre de ce genre de choses :</p>
<pre>
.if ${OPSYS} != "Linux"
LDADD+=         -lssl
.endif
.if ${OPSYS} == "Darwin" || ${OPSYS} == "SunOS"
LDADD+=         -lcrypto
.endif
.if ${OPSYS} == "DragonFly"
LDADD+=         -lutil
.endif
.if ${OPSYS} == "SunOS" || ${OPSYS} == "Linux"
LDADD+=         -lnbcompat
.endif
.if ${OPSYS} == "SunOS"
LDADD+=         -lnsl -lsocket -lresolv
LDADD+=         -Wl,-R -Wl,${LOCALBASE}/lib -L${LOCALBASE}/lib -lsqlite3
.else
LDADD+=         -Wl,-rpath -Wl,${LOCALBASE}/lib -L${LOCALBASE}/lib -lsqlite3
.endif
</pre>
<p>etc etc etc&#8230;</p>
<p>Ces petites plaisanteries, c&#8217;est mignon lorsqu&#8217;on adresse une ou deux plateformes, mais Ã  la longue, Ã§a devient parfaitement inmaintebable. Et c&#8217;est lÃ  qu&#8217;intervient <i>autoconf</i>; plutot que de tester le systÃ¨me sur lequel nous oeuvrons puis dÃ©duire quelle librairie / <i>header</i> inclure, nous allons plutot tester l&#8217;existence de fonctions particuliÃ¨res au sein du systÃ¨me visÃ©.</p>
<p>La premiÃ¨re chose Ã  faire, c&#8217;est d&#8217;utiliser la commande <code>autoscan</code>. Cette derniÃ¨re crÃ©era un fichier <code>configure.scan</code>, soit une sorte de template destinÃ© Ã  devenir <code>configure.ac</code>. Dans ce template, des tests assez basiques sur l&#8217;existence de certains <i>headers</i> ou autres fonctions sont prÃ©sents.</p>
<p>Exemple simple, la directive <a href="http://www.gnu.org/software/hello/manual/autoconf/Libraries.html">AC_CHECK_LIB</a> permet de verifier si une fonction fait ou pas partie d&#8217;une librairie. Cette macro prend en premier paramÃ¨tre le nom de la fonction recherchÃ©e, en second la librairie dans laquelle rechercher, le 3Ã¨me parametre permet d&#8217;affecter une action en cas de succÃ¨s, le 4eme en cas d&#8217;Ã©chec et enfin le dernier d&#8217;ajouter des librairies au test. Fort heureusement, dans la plupart des cas, nous n&#8217;utiliserons pas plus de trois paramÃ¨tres :</p>
<pre>
AC_SEARCH_LIBS([sqlite3_open], [sqlite3],,
        AC_MSG_ERROR(SQLite3 not found.)
)
</pre>
<p>Dans l&#8217;exemple ci-dessus, on verifie que la fonction <code>sqlite3_open</code> existe bien dans la librairie <i>libsqlite3</i>, si tel n&#8217;est pas le cas -en particulier si la librairie elle mÃªme n&#8217;est pas prÃ©sente ou pas trouvÃ©e-, nous arrÃªterons le script de configuration et afficherons un message d&#8217;erreur.<br />
Notez que la macro <code>AC_SEARCH_LIBS</code> aura pour effet, en cas de succÃ¨s, d&#8217;ajouter Ã  la variable <code>LIBS</code> la librairie testÃ©e.</p>
<p>Et c&#8217;est bien lÃ  tout l&#8217;intÃ©rÃªt de la chose, car ce que nous souhaitons, c&#8217;est bÃ©nÃ©ficier d&#8217;un fichier Makefile gÃ©nÃ©rique qui se remplira des librairies-dÃ©pendances. En l&#8217;occurrence, c&#8217;est le fameux <code>Makefile.in</code> qui remplit cette fonction. En effet, Ã  l&#8217;issue du non moins fameux <code>configure</code>, le fichier <code>Makefile.in</code> est complÃ©tÃ© avec les variables dÃ©tÃ©ctÃ©es et le rÃ©sultat publiÃ© dans un <code>Makefile</code> classique.<br />
La bonne nouvelle, c&#8217;est que le <code>Makefile.in</code> peut tout Ã  fait Ãªtre sous la forme d&#8217;un BSD Makefile.</p>
<p>Voici par exemple un <code>LDADD</code> qui serait totalement complÃ©tÃ© par <code>autoconf :</p>
<pre>
LDADD+=	@LIBS@
</pre>
<p>Il y a des dizaines, des centaines, des milliers de tutoriaux sur les <i>autotools</i> un peu partout sur le web, mais Ã  mon humble avis une bonne partie d'entre eux brillent par leur facultÃ© Ã  rendre ces outils aussi repoussants qu'imbuvables. Par chance, je suis tombÃ© sur deux liens qui m'ont grandement aidÃ© Ã  comprendre ce que je faisais: <a href="http://www.webta.org/projects/apachetop/browser/configure.ac">le premier</a> est un des </code><code>configure.ac</code> les mieux foutus qu&#8217;il m&#8217;ait Ã©tÃ© donnÃ© de voir, il s&#8217;agit de celui d&#8217;<a href="http://www.webta.org/projects/apachetop/">apachetop</a>, et il est truffÃ© de bons exemples.<br />
<a href="http://www.infres.enst.fr/~dax/polys/configure/slide1.html">le second</a> ressemble Ã  un <i>slideware</i> mais regroupe de maniÃ¨re synthetique des informations d&#8217;habitude noyÃ©es dans 500 pages de documentation soporifiques. On notera en particulier le <a href="http://www.infres.enst.fr/~dax/polys/configure/slide12.html">slide 12</a> qui liste les principales variables substituÃ©es.</p>
<p>Un dernier exemple relatif Ã  la substitution de variables :</p>
<pre>
# check for humanize_number
AC_CHECK_FUNC([humanize_number],,
        # in DragonFly humanize_number is in libutil
        AC_SEARCH_LIBS([humanize_number], [util],,
                # don't have it, include humanize_number.c to SRCS
                [SRCS="humanize_number.c $SRCS"]
        )
)
AC_SUBST(SRCS)
</pre>
<p>Celui-ci est un tout petit peu plus complexe. Dans l&#8217;ordre, nous vÃ©rifions si la fonction <code>humanize_number</code> est prÃ©sente dans la <code>libc</code>, si oui, nous ne faisons rien, autrement (notez les deux virgules), nous cherchons dans la <code>libutil</code> qui heberge cette fonction sous DragonFly BSD. Finalement, si nous ne trouvons toujours pas cette fonction, nous ajoutons le fichier <code>humanize_number.c</code> Ã  la variable <code>SRCS</code>.<br />
Cette variable n&#8217;Ã©tant pas automatiquement remplacÃ©e dans le fichier <code>Makefile.in</code>, nous indiquons Ã  <code>autoconf</code> qu&#8217;il devra effectuer cette substitution grace Ã  la macro <code>AC_SUBST</code>.</p>
<p>Finalement, Ã  l&#8217;issue de l&#8217;ecriture du <code>configure.ac</code> et du <code>Makefile.in</code> associÃ©, nous invoquons <code>autoconf</code> qui gÃ©nÃ¨rera un script <code>configure</code>. L&#8217;execution de ce dernier produira un <code>Makefile</code> adaptÃ© Ã  votre plateforme cible.</p>
<p>Convenient isn&#8217;t it ?<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2009/12/03/tas-fait-de-lautoquoi/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>snprintf(surprise, BUFSIZ, &#8220;prout%s&#8221;, surprise);</title>
		<link>http://imil.net/wp/2009/05/19/snprintfsurprise-bufsiz-prouts-surprise/</link>
		<comments>http://imil.net/wp/2009/05/19/snprintfsurprise-bufsiz-prouts-surprise/#comments</comments>
		<pubDate>Tue, 19 May 2009 19:58:46 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[c0daz]]></category>
		<category><![CDATA[pkgin]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=272</guid>
		<description><![CDATA[Cet aprÃ¨s midi, j&#8217;ai eu une mauvaise surprise. Je fus en effet Ã©tonnÃ© de constater qu&#8217;en compilant pkgin sous GNU/Linux, les appels du type :

snprintf(a, size, "unechaine/%s", a);

tronquaient a avec uniquement unechaine.
Evidemment, mon premier reflexe fut de blÃ¢mer GNU/Linux puisque ce code passait sans aucun soucis sur NetBSD, DragonFly BSD et mÃªme Solaris. Et pourtant. [...]]]></description>
			<content:encoded><![CDATA[<p>Cet aprÃ¨s midi, j&#8217;ai eu une mauvaise surprise. Je fus en effet Ã©tonnÃ© de constater qu&#8217;en compilant <a href="http://imil.net/pkgin">pkgin</a> sous GNU/Linux, les appels du type :</p>
<pre>
snprintf(a, size, "unechaine/%s", a);
</pre>
<p>tronquaient <code>a</code> avec uniquement <code>unechaine</code>.</p>
<p>Evidemment, mon premier reflexe fut de blÃ¢mer GNU/Linux puisque ce code passait sans aucun soucis sur NetBSD, DragonFly BSD et mÃªme Solaris. Et pourtant. C&#8217;est <i>gl</i> qui m&#8217;informa que <a href="http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf">ce document issu de l&#8217;ISO et l&#8217;IEC</a> explique clairement que le fait d&#8217;appeler <code>snprintf()</code> de la sorte rendait le rÃ©sultat &#8220;imprÃ©visible&#8221;. Dont acte.</p>
<p>Ainsi, j&#8217;ai imaginÃ© la parade suivante :</p>
<p>Faire renvoyer le resultat <i>malloc</i>&#8216;Ã© du <i>format string</i></p>
<pre>
char *
safe_snprintf(int size, const char *fmt, ...)
{
    char *p;
    va_list ap;

    XMALLOC(p, size * sizeof(char));
    va_start(ap, fmt);
    (void) vsnprintf(p, size, fmt, ap);
    va_end(ap);

    return p;
}
</pre>
<p>Puis simuler le prÃ©cÃ©dent appel Ã  <code>snprintf</code> via un <code>define</code> qui s&#8217;occuppera de libÃ©rer la destination et la faire pointer vers la chaine allouÃ©e prÃ©cÃ©demment renvoyÃ©e par <code>safe_printf()</code>.</p>
<pre>
#define XSNPRINTF(dst, size, fmt...)            \
    do {                                        \
        char *pdst;                             \
        pdst = safe_snprintf(size, fmt);        \
        XFREE(dst);                             \
        dst = pdst;                             \
} while (/* CONSTCOND */ 0)
</pre>
<p>Je teste ce workaround en ce moment, et le rÃ©sultat semble probant.<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2009/05/19/snprintfsurprise-bufsiz-prouts-surprise/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>la magie des SLIST</title>
		<link>http://imil.net/wp/2009/03/14/la-magie-des-slist/</link>
		<comments>http://imil.net/wp/2009/03/14/la-magie-des-slist/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 17:21:05 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[BSD]]></category>
		<category><![CDATA[c0daz]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=263</guid>
		<description><![CDATA[Il y a 5 ans de cela, je vous entretenais sur la beautÃ© des SLIST, un concept issu du monde BSD permettant de facilement manipuler des listes chainÃ©es dans votre code C sans avoir Ã  rÃ©inventer la roue Ã  chaque code.
Comme je n&#8217;avais plus manipulÃ© ce type d&#8217;objet depuis un certain temps, je me suis [...]]]></description>
			<content:encoded><![CDATA[<p>Il y a 5 ans de cela, <a href="http://imil.net/docs/slists.txt">je vous entretenais sur la beautÃ© des SLIST</a>, un concept issu du monde BSD permettant de facilement manipuler des listes chainÃ©es dans votre code C sans avoir Ã  rÃ©inventer la roue Ã  chaque code.</p>
<p>Comme je n&#8217;avais plus manipulÃ© ce type d&#8217;objet depuis un certain temps, je me suis replongÃ© dans ce petit tutoriel, mais je lui ai trouvÃ© un manque que je m&#8217;apprÃ¨te Ã  combler ici mÃªme.</p>
<p>La manipulation des <i>SLIST</i> est trÃ¨s aisÃ©e lorsque l&#8217;on a la possibilitÃ© de dÃ©clarer sa liste de maniÃ¨re globale, il suffit alors, dans chaque fonction, d&#8217;appeler la &#8220;tÃªte de liste&#8221;, souvent appelÃ©e <code>head</code>, via les multiples macros prÃ©sentes dans <code>queue.h</code>.<br />
J&#8217;ai ecrit, toujours dans la documentation sus-citÃ©e, un minuscule passage sur la faÃ§on d&#8217;utiliser les <i>SLIST</i> avec les macros <i>SLIST_FIRST</i> et <i>SLIST_NEXT</i>, mais je m&#8217;aperÃ§ois qu&#8217;on ne se rend pas compte de leur utilitÃ©.</p>
<p>Prenons le cas suivant, je veux crÃ©er une liste chainÃ©e de type <i>SLIST</i> dans une fonction. Je souhaite pouvoir ballader cette liste de fonctions en fonctions, et evidemment, la libÃ©rer Ã  la fin de mes travaux. Nous utiliserons notre liste de la sorte :</p>
<pre>
/* headers et diverses dÃ©clarations */
#include &lt;sys/queue.h&gt;

typedef struct Mastruct {
	int id;
	char *element;
	SLIST_ENTRY(, Mastruct) next;
} Mastruct;

/* plein de trucs */

Mastruct *
initialisation(int id, const char *str)
{
	Mastruct *mesdatas;

	/* on dÃ©clare la tÃªte de liste */
	SLIST_HEAD(, Mastruct) datahead;
	/* on l'initialise Ã  NULL */
	SLIST_INIT(&#038;datahead);

	if ((mesdatas = malloc(sizeof(Mastruct)) == NULL)
		err("malloc error");

	mesdatas->id = id;
	if (str != NULL) {
		mesdatas->element = strdup(str);
	} else {
		mesdatas->element = NULL;
	}

	/* on accroche la structure fraichement allouÃ©e Ã  la tÃªte de liste */
	SLIST_INSERT_HEAD(&#038;datahead, mesdatas, next);

	/* et on renvoie le premier Ã©lÃ©ment de datahead, ici, mesdatas*/
	return SLIST_FIRST(&#038;datahead);
}
</pre>
<p>Dans ce cas de figure, nous ne renvoyons pas la tÃªte de la liste mais simplement le premier Ã©lÃ©ment de la liste chainÃ©e. Pour parcourir simplement cette liste, nous utiliserons la macro <code>SLIST_NEXT</code> :</p>
<pre>
	Mastruct *mesdatas, *p;

	/* des trucs */

	mesdatas = initialisation(id, unechaine);

	for (p = mesdatas; p != NULL; p = SLIST_NEXT(p, next))
		printf("%d -> %s", p->id, p->element);
</pre>
<p>De la mÃªme faÃ§on, on pourra simplement libÃ©rer cette liste simplement chainÃ©e grace Ã  une boucle de ce type :</p>
<pre>
void
free_datas(Mastruct *mesdatas)
{
	struct Mastruct *p;

	/* on boucle tant que le nouveau chainon n'est pas nul */
	while (mesdatas != NULL) {
		/* on sauvegarde le prochain chainon */
		p = SLIST_NEXT(mesdatas, next);
		/* on libÃ¨re le contenu */
		free(mesdatas->element);
		/* puis le chainon courant */
		free(mesdatas);
		/* puis on fait pointer la variable principale vers la sauvegarde */
		mesdatas = p;
	}
}
</pre>
<p>DÃ©sormais, avec un effort minimum, nous voici en mesure de trÃ¨s simplement crÃ©er des listes de donnÃ©es rapides et dynamiques.<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2009/03/14/la-magie-des-slist/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>char *slurp(const char *url)</title>
		<link>http://imil.net/wp/2009/03/10/char-slurpconst-char-url/</link>
		<comments>http://imil.net/wp/2009/03/10/char-slurpconst-char-url/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 10:12:37 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[c0daz]]></category>
		<category><![CDATA[NetBSD]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=262</guid>
		<description><![CDATA[Pour mon projet top secret que j&#8217;ai, j&#8217;avais besoin de tÃ©lÃ©charger un fichier, en C, via FTP ou HTTP. En cherchant ce qui est fait dans pkg_install, et plus particuliÃ¨rement dans admin/audit.c, j&#8217;ai trouvÃ© un bon exemple d&#8217;utilisation de la libfetch, dont le man est Ã  mon avis complÃ¨tement indigeste.
Petit rÃ©sumÃ©.
Afin de visualiser un code [...]]]></description>
			<content:encoded><![CDATA[<p>Pour mon <a href="http://cvs.gcu.info/viewvc.py/pkg_dry/">projet top secret que j&#8217;ai</a>, j&#8217;avais besoin de tÃ©lÃ©charger un fichier, en C, via FTP ou HTTP. En cherchant ce qui est fait dans <a href="http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/pkgtools/pkg_install/">pkg_install</a>, et plus particuliÃ¨rement dans <a href="http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/pkgtools/pkg_install/files/admin/audit.c">admin/audit.c</a>, j&#8217;ai trouvÃ© un bon exemple d&#8217;utilisation de la <a href="http://netbsd.gw.com/cgi-bin/man-cgi?fetch+3+NetBSD-current">libfetch</a>, dont le man est Ã  mon avis complÃ¨tement indigeste.</p>
<p>Petit rÃ©sumÃ©.</p>
<p>Afin de visualiser un code complet et fonctionnel sur l&#8217;utilisation de la <i>libfetch</i>, le fichier <code>audit.c</code> prÃ©cedemment citÃ© fera reference.</p>
<p>ConsidÃ©rons une fonction, <i>fetch_url</i> qui prendra en paramÃ¨tre une URL. Afin d&#8217;utiliser la <i>libfetch</i>, nous auront besoin du header <code>fetch.h</code>. Voici donc le dÃ©but de notre fichier contenant la fonction <i>fetch_url</i> :</p>
<pre>
#include &lt;fetch.h&gt;

void
fetch_url(const char *url)
</pre>
<p>La premiÃ¨re fonction que nous allons utiliser se nomme <code>fetchXGetURL()</code>, elle permettra de valider que l&#8217;url passÃ©e en paramÃ¨tre est bien de la forme <code>proto://hostname/peut-etre-quelque-chose</code>, elle renverra une sorte de descripteur, de type <code>fetchIO</code> et placera la taille du fichier visÃ© dans la variable <code>st</code>, de type <code>struct url_stat</code>, le 3eme parametre reprÃ©sente les flags eventuels, nous n&#8217;en passons pas :</p>
<pre>
	struct url_stat st;
	fetchIO *f;

	if ((f = fetchXGetURL(url, &#038;st, "")) == NULL) {
		/* gÃ©rez l'erreur */
	}
</pre>
<p>Une fois le descripteur ouvert et les informations sur la cible rÃ©cupÃ©rÃ©es dans la variable <code>st</code>, nous pouvons prÃ©parer le conteneur, un pointeur de type <code>char *</code> dont nous pouvons d&#8217;ores et dÃ©jÃ  reserver la taille :</p>
<pre>
    buf_len = st.size;
    if ((buf = malloc(buf_len + 1)) == NULL)
        err(EXIT_FAILURE, "malloc failed");
</pre>
<p>On aura bien entendu prÃ©alablement dÃ©clarÃ© les variables <code>buf_len</code> et <code>buf</code> :</p>
<pre>
	char *buf;
	size_t buf_len;
</pre>
<p>On n&#8217;oubliera evidemment pas de libÃ©rer <code>buf</code> lorsque l&#8217;on en aura plus besoin grace Ã  un <code>free(buf)</code>.</p>
<p>Arrive la boucle principale, qui bouclera tant que la taille de ce qui est lu + ce qui a dÃ©jÃ  Ã©tÃ© lu est inferieure Ã  la taille prÃ©sente dans <code>st.size</code>, soit <code>buf_len</code>. La fonction issue de la <i>libfetch</i> en charge de la lecture se nomme <code>fetchIO_read()</code> :</p>
<pre>
    while (buf_fetched < buf_len) {
        cur_fetched = fetchIO_read(f, buf + buf_fetched,
            buf_len - buf_fetched);
        if (cur_fetched == 0)
            errx(EXIT_FAILURE, "truncated file");
        else if (cur_fetched == -1)
            errx(EXIT_FAILURE, "Failure during fetch: %s",
                fetchLastErrString);
        buf_fetched += cur_fetched;
    }
</pre>
<p>Et voila ! la variable <code>buf</code> contient maintenant le resultat de la lecture de l'url <code>const char *url</code>, Ã  vous d'inventer le reste :)<br />

</pre>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2009/03/10/char-slurpconst-char-url/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La magie de l&#8217;ELF</title>
		<link>http://imil.net/wp/2008/12/10/la-magie-de-lelf/</link>
		<comments>http://imil.net/wp/2008/12/10/la-magie-de-lelf/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 14:01:00 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[c0daz]]></category>
		<category><![CDATA[NetBSD]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=242</guid>
		<description><![CDATA[En comparant le projet qui m&#8217;obsÃ¨de jour et nuit et les outils similaires dÃ©jÃ  existants (crunchgen(1), rescue), j&#8217;en suis venu Ã  me poser des questions sur le cas d&#8217;un mode &#8220;full static&#8221;. Pour mÃ©moire, BeastieBox &#8220;trouve&#8221; la fonction Ã  appeler fonction de argv[0], et je pars du principe que chaque nom de fonction doit Ãªtre [...]]]></description>
			<content:encoded><![CDATA[<p>En comparant <a href="http://beastiebox.sourceforge.net/">le projet qui m&#8217;obsÃ¨de jour et nuit</a> et les outils similaires dÃ©jÃ  existants (<code>crunchgen(1), rescue</code>), j&#8217;en suis venu Ã  me poser des questions sur le cas d&#8217;un mode &#8220;full static&#8221;. Pour mÃ©moire, BeastieBox &#8220;trouve&#8221; la fonction Ã  appeler fonction de <code>argv[0]</code>, et je pars du principe que chaque nom de fonction doit Ãªtre construit dynamiquement. Ce <a href="http://mollacademy.gcu.info/doku.php?id=c:dlopen_self">tour de passe-passe</a> est facilement gerÃ© par les fonctions <code>dlopen(3) / dlsym(3)</code> dans le cas d&#8217;un binaire compilÃ© dynamiquement, mais quid d&#8217;un binaire <code>beastiebox</code> compilÃ© Ã  l&#8217;aide du swtich <code>-static</code> ? Point de <code>ld.so_elf</code> Ã  la rescousse ici, la seule solution qui m&#8217;est apparue&#8230; c&#8217;est d&#8217;attaquer le binaire comme le fait prÃ©cisemment <code>ld.so_elf</code>, en <code>mmap</code>&#8216;ant le binaire et en l&#8217;adressant via les structures ELF.</p>
<p>J&#8217;ai postÃ© l&#8217;explication dans la <a href="http://mollacademy.gcu.info/doku.php?id=c:static_symbols_with_elf">Mollacademy</a>, et le code associÃ© de <i>BeastieBox</i> est visible <a href="http://beastiebox.cvs.sourceforge.net/viewvc/beastiebox/beastiebox/slsym.c?revision=1.3&#038;view=markup">ici</a>, <a href="http://beastiebox.cvs.sourceforge.net/viewvc/beastiebox/beastiebox/slsym.h?revision=1.3&#038;view=markup">ici</a> et <a href="http://beastiebox.cvs.sourceforge.net/viewvc/beastiebox/beastiebox/main.c?revision=1.14&#038;view=markup">lÃ </a>.<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2008/12/10/la-magie-de-lelf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Duplication de symboles, la bonne methode</title>
		<link>http://imil.net/wp/2008/12/06/duplication-de-symboles-la-bonne-methode/</link>
		<comments>http://imil.net/wp/2008/12/06/duplication-de-symboles-la-bonne-methode/#comments</comments>
		<pubDate>Sat, 06 Dec 2008 14:03:09 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[c0daz]]></category>
		<category><![CDATA[NetBSD]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=241</guid>
		<description><![CDATA[On oublie le post ci dessous. En effet, aprÃ¨s avoir postÃ© le resultat de mes travaux sur tech-userlevel@, j&#8217;ai appris une astuce des plus magiques. Arnaud Lacombe me dit dans une rÃ©ponse :

Just looking quickly at the code, you can avoid the &#8220;#ifdef BBOX commant_() #else main() #endif&#8221; heavy logic and the `commonfunc.sh&#8217; hack by [...]]]></description>
			<content:encoded><![CDATA[<p>On oublie le post ci dessous. En effet, aprÃ¨s avoir postÃ© le resultat de mes travaux sur <i>tech-userlevel@</i>, j&#8217;ai appris une astuce des plus magiques. Arnaud Lacombe me dit dans une rÃ©ponse :<br />
<i><br />
Just looking quickly at the code, you can avoid the &#8220;#ifdef BBOX commant_<foo>() #else main() #endif&#8221; heavy logic and the `commonfunc.sh&#8217; hack by using nm(1), objcopy(1) and symbol renaming as done by crunchgen(1).<br />
</foo></i><br />
Je regarde donc comment s&#8217;y prend le gaillard de <code>crunchgen(1)</code> pour eviter les conflits de symboles et je vois ceci :</p>
<pre>
        ${NM} -ng cat/cat.ro | awk '/^ *U / { next }; /^[0-9a-fA-F]+ C/ { next }; / main$$/ { print "main _crunched_cat_stub"; next }; { print $3 " " $3 "$$from$$cat" }' > cat.cro.syms
${OBJCOPY} --redefine-syms cat.cro.syms cat/cat.ro cat.cro
</pre>
<p>Et Ã§a, Ã§a va m&#8217;apprendre Ã  lire les manpages en entier.</p>
<p>En clair, Ã  l&#8217;aide de <code>nm(1)</code>, on liste les symboles exportÃ©s par les objets, on leur associe un nouveau nom avec <code>awk(1)</code> puis on redefinit les noms des symboles en passant Ã  <code>objcopy(1)</code> le fichier de correspondances fraichement crÃ©Ã©.</p>
<p>Magnifique.<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2008/12/06/duplication-de-symboles-la-bonne-methode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>cvs co ya7ans</title>
		<link>http://imil.net/wp/2008/01/26/cvs-co-ya7ans/</link>
		<comments>http://imil.net/wp/2008/01/26/cvs-co-ya7ans/#comments</comments>
		<pubDate>Sat, 26 Jan 2008 15:05:43 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[c0daz]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[OpenBSD]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=178</guid>
		<description><![CDATA[fouyou, ce voyage dans le passÃ©&#8230;
Il y a 7 ans, je commettais ceci. EasyLDAP Ã©tait une librairie qui permettait d&#8217;implÃ©menter une interaction LDAP en C assez simplement. Mais son but final Ã©tait plus concret; en effet, en 2001, FreeBSD ne possÃ©dait pas de port nss_ldap, son architecture nss Ã©tait quelque peu aride, et l&#8217;un de [...]]]></description>
			<content:encoded><![CDATA[<p>fouyou, ce voyage dans le passÃ©&#8230;</p>
<p>Il y a 7 ans, je commettais <a href="http://imil.net/eldap/">ceci</a>. EasyLDAP Ã©tait une librairie qui permettait d&#8217;implÃ©menter une interaction LDAP en C assez simplement. Mais son but final Ã©tait plus concret; en effet, en 2001, FreeBSD ne possÃ©dait pas de port <code>nss_ldap</code>, son architecture <i>nss</i> Ã©tait quelque peu aride, et l&#8217;un de mes projets dans <a href="http://www.cw.com/">mon job de l&#8217;Ã©poque</a>, c&#8217;Ã©tait de trouver le moyen de centraliser l&#8217;authentification de nos serveurs FreeBSD, et de prÃ©fÃ©rence, via LDAP.<br />
La sale magouille que j&#8217;avais trouvÃ© Ã  l&#8217;Ã©poque, c&#8217;Ã©tait d&#8217;utiliser la variable <code>LD_PRELOAD</code> et de prÃ©loader, donc, la librairie <i>eldap</i> dans laquelle j&#8217;avais redÃ©fini les fonctions <code>getpwnam</code>, <code>getpwuid</code>, <code>getgrnam</code> etc etc&#8230;<br />
Et Ã§a marchait ! :)</p>
<p>Aujourd&#8217;hui, FreeBSD et NetBSD sont tous deux capables de loader des plugins <code>nss_ldap</code> et <code>pam_ldap</code>, c&#8217;est tout beau tout propre, et il n&#8217;y a plus besoin de bidouiller de trucs infames pour centraliser ses utilisateurs.<br />
Sauf sous OpenBSD.<br />
Et c&#8217;est la que les vapeurs du passÃ© ressurgissent; deux des domU de <a href="http://zone0.gcu.info/">zone0</a> sont des OpenBSD, l&#8217;un d&#8217;eux plus particuliÃ¨rement, est destinÃ© Ã  heberger moult shells des membres contributeurs du groupe. jusqu&#8217;Ã  prÃ©sent, nous avions jetÃ© notre dÃ©volu sur <a href="http://wiki.gcu.info/doku.php?id=openbsd:login_ldap">cette methode</a>, qui prÃ©sente le dÃ©savantage de devoir tout de mÃªme ajouter l&#8217;utilisateur au fichier <code>/etc/passwd</code>. Et puis de fil en aiguille, je me rappelle de mon &#8220;fameux&#8221; EasyLDAP.<br />
D&#8217;abord Ã  tatons, je regarde mon code de loin, je fixe les <i>autotrucs</i> permettant sa compilation, et apres quelques ajustements, ce dernier compile. J&#8217;ecris sans trop y croire ce bout de code de verification :</p>
<pre>
#include &lt;stdio.h&gt;

#include &lt;sys/types.h&gt;
#include &lt;pwd.h&gt;

int
main(int argc, char *argv[])
{
        if (getpwnam(argv[1]) != NULL)
                printf("%s exists\\n", argv[1]);
        else
                printf("%s does NOT exists\\n", argv[1]);

        return 0;
}
</pre>
<p>Je compile puis quelques SEGFAULT / corrections plus loin, je tente ma chance :</p>
<pre>
[~/src/eldap] LD_PRELOAD=.libs/libeldap.so.1.1 ./testpw pinpin
pinpin exists
</pre>
<p>Je n&#8217;en crois pas mes yeux, Ã§a fonctionne toujours !<br />
Quelques ajustements plus tard, j&#8217;arrivais Ã  me connecter via <a href="http://dev.inversepath.com/trac/openssh-lpk">OpenSSH-lpk</a> (clÃ© publique dans une db LDAP, donc) avec un utilisateur absent du fichier <code>/etc/passwd</code>.</p>
<p>J&#8217;ai donc entrepris de faire subir Ã  ce vieux code mal indentÃ©, peu sur et emprunt de vapeurs de gin, un bon gros lifting. Le site est de nouveau en ligne, le CVS ne nouveau accessible, et j&#8217;ai revampÃ© un peu le codebase. Il est Ã  peu prÃ¨s certain que ce travail n&#8217;aura d&#8217;interet que le temps qu&#8217;OpenBSD n&#8217;integre une vraie abstraction dans la libc, mais il est toujours agrÃ©able de jouer avec ces notions. Si le cÅ“ur vous en dit, vous savez ou me trouver.<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2008/01/26/cvs-co-ya7ans/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ã  peine classe</title>
		<link>http://imil.net/wp/2007/09/03/a-peine-classe/</link>
		<comments>http://imil.net/wp/2007/09/03/a-peine-classe/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 16:01:37 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[c0daz]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=147</guid>
		<description><![CDATA[Bon c&#8217;est pas encore super brillant, j&#8217;imagine que Ã§a fera hurler les puristes, mais au cas ou quelqu&#8217;un aurait besoin d&#8217;une toute petite classe de rien du tout pour manipuler des fichiers de conf &#8220;basiques&#8221; du type :

# ce genre de format
clÃ©: valeur
# ou celui-ci
clÃ©= valeur
# ou encore celui lÃ
clÃ©	valeur

J&#8217;ai pondu un truc ici.
Ã‡a s&#8217;utilise [...]]]></description>
			<content:encoded><![CDATA[<p>Bon c&#8217;est pas encore super brillant, j&#8217;imagine que Ã§a fera hurler les puristes, mais au cas ou quelqu&#8217;un aurait besoin d&#8217;une toute petite classe de rien du tout pour manipuler des fichiers de conf &#8220;basiques&#8221; du type :</p>
<pre>
# ce genre de format
clÃ©: valeur
# ou celui-ci
clÃ©= valeur
# ou encore celui lÃ
clÃ©	valeur
</pre>
<p>J&#8217;ai pondu un truc <a href="http://imil.net/code/simpleconf.py">ici</a>.<br />
Ã‡a s&#8217;utilise comme Ã§a :</p>
<pre>
>>> import simpleconf
>>> cf = simpleconf.SimpleConf()
>>> test = cf.read('/etc/nsswitch.conf')
>>> cf.valueupdate('group', 'pwetpwet')
>>> cf.write('/tmp/out.tmp')
</pre>
<p>et magie :</p>
<pre>
$ grep ^group /tmp/out.tmp
group:       pwetpwet
</pre>
<p>AmÃ©liorations bienvenues toussa.<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2007/09/03/a-peine-classe/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>fsHhshhhshhhHHh tsssk tssk fFSShhhsh</title>
		<link>http://imil.net/wp/2007/08/26/fshhshhhshhhhhh-tsssk-tssk-ffsshhhsh/</link>
		<comments>http://imil.net/wp/2007/08/26/fshhshhhshhhhhh-tsssk-tssk-ffsshhhsh/#comments</comments>
		<pubDate>Sun, 26 Aug 2007 20:21:28 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[c0daz]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=144</guid>
		<description><![CDATA[Alors voila. Y&#8217;a bien quoi, 3 ans ? 4 ans ? que moult lutins me chantaient les louanges de python, mais flemme, manque de proj et de temps aidant, je snobais le langage au serpent, tout juste capable de gentiment hacker quelques codes existants, rien d&#8217;excitant. Et puis arrive ce petit proj au boulot, un [...]]]></description>
			<content:encoded><![CDATA[<p>Alors voila. Y&#8217;a bien quoi, 3 ans ? 4 ans ? que moult lutins me chantaient les louanges de <a href="http://python.org/">python</a>, mais flemme, manque de proj et de temps aidant, je snobais le langage au serpent, tout juste capable de gentiment hacker quelques codes existants, rien d&#8217;excitant. Et puis arrive ce petit proj au boulot, un truc sympa, pas bien mÃ©chant, qui me ferait manipuler des IO, des connexions interactives, un proj avec un potentiel futur relativement interessant. Du coup, moi qui aime me coller dans la merde, je dis fiÃ¨rement &#8220;ouais allez en python&#8221;. Coup&#8217;d'pression coup&#8217;d'pression.<br />
Evidemment, je commence par <a href="http://diveintopython.adrahon.org/">Dive Into Python</a>, que j&#8217;accroche pas, mais alors _pas_du_tout_. Puis je m&#8217;attaque au classique <a href="http://www.cifen.ulg.ac.be/inforef/swi/python.htm">Apprendre Ã  programmer avec python</a>. Juste enorme, excellente ressource qui met les idÃ©es bien au clair, ce fÃ»t ma rÃ©vÃ©lation. J&#8217;ai poursuivi en achetant <a href="http://www.amazon.fr/Au-coeur-Python-Notions-avanc%C3%A9es/dp/2744021954">ce bouquin</a>, et lÃ , je dois marcher en me penchant quand je sors du metro et que je finis la lecture de 3/4 pages. Programmation reseau, <i>Twisted</i>, multithreading et autres sujets plus kiffants les uns que les autres. LÃ  dessus arrivent les dÃ©licieux conseils des experimentÃ©s pythonneurs tahorg, dzen, yota, mial, anhj, Klyr et j&#8217;en passe, et je finis par claquer un code pas-si-dÃ©gueu pour un coup d&#8217;essai. Allez, je rÃ©siste pas au plaisir de paster la derniÃ¨re astuce issue du canal, une boucle qui construit des noms de fonctions en addictionnant des strings puis les rend <i>callable</i>, une tuerie &#8220;classique&#8221; :</p>
<pre>
# des trucs avant

argsmap = {
	'truc': 'bla',
# plein d'autres comme Ã§a
}

# [...]
# d'autres trucs
#

def process_es(data, action):
        switch = {}

        for section in argsmap.keys():
                switch[section] = getattr(modules["__main__"], section + '_func')
	# et encore plein de trucs super bien
	switch[key](value.rstrip()) # on appelle la fonction
</pre>
<p>L&#8217;astuce reside dans le paramÃ¨tre <code>modules["__main__"]</code>, qui informe l&#8217;incroyable <a href="http://diveintopython.adrahon.org/power_of_introspection/getattr.html">getattr</a> que l&#8217;objet auquel juxtaposer la fonction construite n&#8217;est autre que le code courant.</p>
<p>Pour finir, un petit tour de passe-passe avec <code>getattr()</code></p>
<pre>
Python 2.5.1 (r251:54863, May  2 2007, 16:56:35)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> toto = "pwet"
>>> getattr(toto, "split")('e')
['pw', 't']
</pre>
<p>Sans dÃ©conner&#8230;<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2007/08/26/fshhshhhshhhhhh-tsssk-tssk-ffsshhhsh/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>back to c0daze</title>
		<link>http://imil.net/wp/2007/03/03/back-to-c0daze/</link>
		<comments>http://imil.net/wp/2007/03/03/back-to-c0daze/#comments</comments>
		<pubDate>Sat, 03 Mar 2007 00:30:36 +0000</pubDate>
		<dc:creator>iMil</dc:creator>
				<category><![CDATA[Ma vie, mon oeuvre]]></category>
		<category><![CDATA[c0daz]]></category>
		<category><![CDATA[Fonera]]></category>
		<category><![CDATA[Ma vie. mon oeuvre]]></category>
		<category><![CDATA[Wireless]]></category>

		<guid isPermaLink="false">http://imil.net/wp/?p=118</guid>
		<description><![CDATA[Pour dÃ©conner j&#8217;ai pondu Ã§a ce soir: infon.c
Il s&#8217;agit d&#8217;un bÃªte petit serveur TCP Ã  compiler avec l&#8217;environnement de developpement de la Fonera et qui rÃ©pond pour le moment aux requetes l[oad] et m[em]. Genre comme Ã§a :

imil@tatooine:~$ telnet fonera 1702
Trying 192.168.10.1...
Connected to fonera.
Escape character is '^]'.
type h for help
fonera> l
1.16
fonera> l
1.14
fonera> m
724
fonera> l
1.13
fonera> m
724
fonera> [...]]]></description>
			<content:encoded><![CDATA[<p>Pour dÃ©conner j&#8217;ai pondu Ã§a ce soir: <a href="http://imil.net/fon/infon.c">infon.c</a><br />
Il s&#8217;agit d&#8217;un bÃªte petit serveur TCP Ã  compiler avec <a href="http://imil.net/docs/fonera-build.txt">l&#8217;environnement de developpement de la Fonera</a> et qui rÃ©pond pour le moment aux requetes l[oad] et m[em]. Genre comme Ã§a :</p>
<pre>
imil@tatooine:~$ telnet fonera 1702
Trying 192.168.10.1...
Connected to fonera.
Escape character is '^]'.
type h for help
fonera> l
1.16
fonera> l
1.14
fonera> m
724
fonera> l
1.13
fonera> m
724
fonera> m
736
fonera> l
1.12
fonera> q
Connection closed by foreign host.
</pre>
<p>Tu l&#8217;auras compris ami lecteur, tout ce qui manque Ã  ce bidule, c&#8217;est un frontend sur un desktop qui se glissera gentiment dans un gnome-panel ou equivalent. Tu t&#8217;ennuies ?</p>
<p>NB: la commande de compil qui va bien: <i>mips-linux-uclibc-gcc -Os -pedantic -Wall -o infon infon.c</i></p>
<p><b>update</b></p>
<p>Un peu de cleanage de code, et maintenant on peut avoir la qualitÃ© du link wifi sur ath0 et ath1.</p>
<p><b>update</b></p>
<pre>
fonera> h
l: load average
m: memory info (total / free)
k: link quality (ath0 / ath1)
t: ath0 rx / ath0 tx | ath1 rx / ath1 tx
q: exit console
fonera> t
103811786 / 876388 | 959653066 / 835499
</pre>
<p>Ã§a peut servir&#8230; :)<br />
</p>
]]></content:encoded>
			<wfw:commentRss>http://imil.net/wp/2007/03/03/back-to-c0daze/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!-- Served from: imil.net @ 2012-05-22 22:28:41 by W3 Total Cache -->
