Catégorie : modules apache

Tout ce qui concerne les modules du serveur Apache, que ce soit du point de vue développement ou du point de vue de l’utilisation.

Activemq : principe de messagerie interne producteur / consommateur

J’ai eu un besoin que je pensais assez particulier, mais qui, en fait, dans certains cas, semble tellement récurrent que beaucoup de choses ont déjà été faites dans ce sens.
Mon besoin est simple :

J’ai un site distant qui est d’accord pour qu’on l’interroge en lui demandant des informations sur des Ids, mais pas très souvent : une demande toute les 5 secondes. Par contre, lors de la demande, on peut lui faire passer plein d’Ids (jusqu’à 100 !).

Donc j’ai fait un script Php, lancé à la main, qui tourne en boucle, et qui va interroger ce fameux site, toutes les 5 secondes.
Une fois ce script fait, j’ai besoin que l’on puisse préciser « à la main » les Ids. Je fais donc un site Internet, et je mets à disposition de tout le monde la possibilité d’entrer des Ids « à la main ».

Problème

La demande Internet peut se faire n’importe quand, et il faut que la réponse soit rapide, donc que la demande soit immédiatement inclue dans le « paquet » lors de la prochaine interrogation. De plus, il peut y avoir plein de demandes à la fois. Et elles doivent toutes s’ajouter facilement.

Solutions

Plusieurs solutions sont possibles :

  1. Utiliser une sorte de dossiers « partagés » où d’un côté le Web/Php dépose un fichier avec un Id, et attend dans un autre dossier la réponse comportant le même nom de fichier ; gros problème : ce n’est pas une méthode 100% fiable ;
  2. Faire un serveur interne qui attend des informations, et lorsque son timer tombe, hop, fait la demande. Gros problème : écrire un vrai serveur Web en Php n’est pas une chose facile, et je n’ai pas le temps de faire tout ça ;
  3. Faire une écriture en base de données pour chaque demande Web, et du côté script, faire un simple « SELECT * FROM… WHERE DATE_DEMANDE IS NULL » (ou quelque chose comme ça). Problème bloquant : comment faire pour signaler à chaque demande Web que leur réponse est disponible ?
  4. Dernière solution : utiliser quelque chose qui existe déjà et tourne très bien : un serveur producteur/consommateur (je l’appelle comme ça mais ce n’est pas le vrai nom). Il implémente en gros tout ce que je demande : d’un côté le client qui envoie des messages, et peut – ou pas – attendre un retour de manière bloquante, et de l’autre côté, le serveur qui lit les messages qui arrivent quand il en a envie, et peut leur répondre facilement – quand je dis « facilement », je parle du point de vue du code à faire en Php.

Solution finale

La dernière solution existe, tourne depuis bien longtemps, fait partie de l’association Apache, et a une implémentation en Php, soit tout ce que je veux : cliquez ici pour plus d’informations : http://activemq.apache.org/

Résumé mémo pour mon installation sous Linux (car si je change de serveur j’aurais besoin de me souvenir de ce qui suit !) :

  • apt-get install activemq
  • Ce qui m’a fait perdre beaucoup de temps : la configuration est la même que le principe available/enabled de la configuration du serveur Web Apache, à la différence près qu’une configuration n’est pas un fichier simple, mais un dossier. Il faut donc faire un lien symbolique dans le dossier enabled sur le dossier d’exemple : sudo ln -s ../instances-available/main/
  • Pour le lancer, faire le grand classique et ne pas suivre d’autres suggestions moisies qu’on trouve un peu partout sur le Web. Simplement service activemq start
  • Enfin, installer en Php. Sur Debian, si on enlève le temps de recherche, ça prend deux minutes maximum : pecl install stomp. L’installation de stomp pour activemq va compiler une extension pour Php. Il suffit de l’inclure dans /etc/php.ini (je l’ai ajouté en fin de fichier, ça a parfaitement fonctionné) : extension=stomp.so. Au cas où, n’oubliez pas de redémarrer le serveur Web ! service apache2 restart

Et voilà tout fonctionne ! Le meilleur exemple – et plus parlant – à mon sens se trouve ici. Code très simple et efficace.

vim et xdebug principes de base pour y arriver

Le principe est de comprendre comment fonctionne xdebug sinon vous n’arriverez jamais à faire du pas à pas en Php.

L’idée plutôt bizarre mais fonctionne très bien, et ça semble le moyen le plus efficace pour y arriver.

Voici comment fonctionne une session de déboguage et après vous pourrez en déduire ce qu’il faut pour avancer :

  • Le client Web = Chrome demande une page en précisant qu’il veut faire du débogague pas à pas (ajouter dans l’URL XDEBUG_SESSION_START=1 (c’est la valeur xdebug par défaut))
  • Lorsque cela arrive sur le serveur Apache, ce dernier fait passer la demande à toutes les librairies liées à Apache, comme d’habitude. Ici, parmi celles qui l’ont demandé, il y a xdebug
  • Là, xdebug voit XDEBUG_SESSION_START=1. Il va alors essayer de se connecter au serveur de déboguage qu’on a configuré via ces directives dans php.ini :
    zend_extension=/chemincomplet/xdebug.so
    xdebug.remote_enable=1
    xdebug.remote_host=127.0.0.1
    xdebug.remote_port=9000
  • Oui j’insiste bien : Apache devient un client, et se connecte à un serveur de déboguage
  • C’est pourquoi dans vim, même si, comme moi, vous arrivez à installer correctement l’extension pour faire du pas à pas Vdebug, tant que vous n’aurez pas compris ce que j’explique juste avant, vous n’arriverez pas à faire du pas à pas
  • Donc dernière étape : je vous explique l’ordre correct de lancement des applications pour réussir à déboguer :
    1. Préparer l’URL concernée dans le navigateur avec le paramètre XDEBUG_SESSION_START=1
    2. Lancer vim avec l’extension Vdebug
    3. Appuyez sur <F5> dans vim afin qu’il se mette en mode serveur et qu’il attende une connexion. Là un message vous affiche qu’il attend 20s.
    4. Allez dans le navigateur et validez l’URL (entrée ou ‘Refresh’)
    5. Regardez vim: automatiquement il passe en mode pas à pas ! C’est magique, génial, efficace et la crème de la crème : vous pouvez déboguer directement sur un serveur distant quand vous connaissez vim. Le top.

Une fois en mode débogage, voici les raccourcis possibles :

<F5> : start/run (jusqu’au prochain breakpoint/ou fin du script)
<F2> : pas par dessus
<F3> : pas entrant dans la fonction
<F4> : sauter à la fin de la fonction
<F6> : stopper le déboguage
<F7> : detacher le script du débogueur
<F9> : continuer jusqu’au curseur
<F10> : mettre un breakpoint
<F11> : voir les variables du contexte (p.ex. après « eval »)
<F12> : évaluer une variable sous le curseur
:Breakpoint <type> <args>: mettre un breakpoint de n’importe quel type (voir :help VdebugBreakpoints)
:VdebugEval <code> : évaluer du code et afficher le résultat
<Leader>e : évaluer l’expression sous le curseur et afficher le résultat
Pour arrêter le déboguage, appuyez sur <F6>. Appuyez encore une fois pour fermer l’interface de déboguage.

If you can’t get a connection, then chances are you need to spend a bit of time setting up your environment. Type :help Vdebug for more information.

Voici une capture de vim / débogage de mon blog WordPress. En plus, en faisant du pas à pas dans WordPress, j’ai appris énormément de choses… Maintenant, à vous de jouer !

vim xdebug image

Apache 2.4 : mod_rewrite et RewriteLog et httpd.conf : du changement

RewriteLog n’existe plus

Vous avez la description ici.

RewriteLog n’existe plus ; il faut mettre LogLevel et ensuite tracer le debug dans le errorlog via la commande :
tail -f error_log|fgrep '[rewrite:'

Mes anciens logs ressemblaient à ceci :
RewriteLog "/web/logs/bonnapizza.rewrite.log"
RewriteLogLevel 9

Maintenant ils sont tous ainsi :
LogLevel alert rewrite:trace2

Awstats et activation de plugins

Lorsque vous installez awstats (un outil pour faire des jolies statistiques de fréquentation), certains plugins sont désactivés par défaut :

  • decodeutfkeys
  • ipv6

(entre autres).

L’astuce est extrêmement simple :

Il suffit de lire les commentaires dans le fichier et de lire les modules requis :

Cherchez # REQUIRED MODULES

Respectivement, pour les deux modules :

  • Encode and URI::Escape
  • Net::IP and Net::DNS

En gros il faut installer ces « plugins Perl » Encode, URI::Escape, Net::IP et Net::DNS.

Les ordres à taper sont hyper simples : il vous suffit, en ligne de commande, de :

  • lancer la console d’outils Perl
    (ce n’est peut-être pas exactement cela, mais je le vois comme ça) : tapez
    cpan
  • puis tapez install "nom du module"
  • install Encode
  • install URI::Escape
  • install Net::IP
  • install Net::DNS

Et à chaque ordre, lorsque vous validez par la touche entrée, toute une liste de modules s’installent, et à la fin… tout fonctionne comme par magie !

Cours à l’institut universitaire d’informatique (IUT) d’Aix en Provence

Voici le fichier PDF du cours sur :

  • la base des DNS ;
  • les hôtes virtuels (« virtual hosts ») ;
  • règles de réécriture (« RewriteRules ») ;
  • les 3 principes de sécurité à avoir en tête.

Pour les quelques étudiants qui voudraient récupérer et lire le cours, un petit conseil sur les question qui vont vous être posées :

  • il vous faut connaitre les directives de réécriture les plus utilisées (redirection, etc) ;
  • il vous faut impérativement réussir à installer un ou plusieurs hôtes virtuels sur un ordinateur local et vous assurer que vous vous souvenez des étapes à faire ;
  • il vous faut savoir mettre en place une ou deux règle de réécriture afin de bien comprendre le fonctionnement. Vous allez avoir un ou deux exemples de règles à expliquer, et si vous n’avez jamais essayé d’en mettre une en place vous ne pourrez jamais les expliquer ;
  • enfin… avez vous bien en tête les 3 principes de sécurité ?

Bonne chance !

Et surtout n’hésitez pas à laisser un commentaire ou poser des questions ici.
Si vous avez des commentaires à faire sur mon cours, même chose : lâchez vous !

Apache : rotation de log

J’ai trouvé un article sur la rotation des logs très intéressant, mais il y a une lacune du côté du serveur Apache qui n’est pas résolue. D’ailleurs qui ne semble résolue nulle part.

>_<

A savoir lorsqu’on utilise la gestion des hôtes virtuels, apache crée un processus de log *par* fichier log. Donc par exemple : un hôte virtuel, un fichier de access_log et un fichier error_log dédié = 2 process rotatelogs. J’ai 12 sites vhost (très peu de fréquentation heureusement), ça me fait un total de 24 process dans ma liste des process… J’ai beau chercher un moyen de n’avoir qu’un seul process, je n’ai trouvé que le module mod_log_rotate qui donne la possibilité d’avoir la rotation de log directement en interne dans Apache, mais, à cause de la gestion des erreurs telle qu’implémentée dans Apache, ce module ne peut gérer que les logs d’accès, pas les logs d’erreur. Autrement dit il me restera tout de même 12 logs différents qui correspondront aux logs d’erreur.

Je me demandais, si, éventuellement, il ne serait pas plus judicieux de faire comme le suggère ce monsieur, à savoir ne pas utiliser mod_log_rotate, ni le programme livré avec Apache, mais de se servir plutôt de l’outil système d’archivage, et, en pratique, juste avant de les archiver, de faire un « awstats » sur les logs. Ce qui me gêne, c’est l’éventualité d’un conflit d’écriture. Que se passe-t-il si jamais j’ai 30 visiteurs de connectés sur mon site en même temps (ce qui serait très bien), qu’Apache écrit dans le log concerné, et que Logrotate est lancé à ce moment là ? C’est la seule et unique chose qui me retient pour l’instant de faire le saut dans cette direction.

Apache : développement C et tutoriaux apr

Mes petits articles vont peut être me rendre célèbre.
Enfin chez les geeks. Et les asiatiques (les deux pages sur lesquelles je suis cité sont en Japonais)

Voilà la réponse du type qui a fait les exemples les plus pratiques, question « tutoriaux apr » :

Hi,

Sorry for the late reply.

I appreciate what you’ve done.

I put the links on the following pages (the former is written in Japanese).

http://dev.ariel-networks.com/column/tech/libarp_tutorial/
http://dev.ariel-networks.com/apr/

Thanks again.

Librairie Apr : tutoriels : 6 et 7

6. Les verrous sur les fichiers

Lorsqu’on veut verrouiller des fichiers entre processus, il faut utiliser apr_file_lock(). Historiquement, des confusions se sont installées concernant le verouillage sur Unix. C’est pourquoi le fait de n’avoir que deux fonctions simples grâce à la librairie libapr est très appréciable.

/* extrait de apr_file_io.h */
APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *thefile, int type);
APR_DECLARE(apr_status_t) apr_file_unlock(apr_file_t *thefile);

apr_file_lock() demande deux arguments. Le premier est un objet apr_file_t. Le second est un drapeau (« flag »), qui sert à spécifier les blocages qu’on veut imposer (« lock type »). Il peut être soit APR_FLOCK_SHARED, soit APR_FLOCK_EXCLUSIVE. We can use the former as a readable lock, and the latter as a writable lock. Pour déverrouiller le fichier, il suffit d’appeler apr_file_unlock(). Ou bien le fait d’appeler apr_file_close() le déverrouille implicitement. Regardez flock-sample.c pour savoir comment faire.
De plus, il est possible d’utiliser un paramètre composé de drapeaux (« bitwised-or flag ») en précisant APR_FLOCK_NONBLOCK. Sans le flag APR_FLOCK_NONBLOCK, apr_file_lock() est bloquant. Avec ce flag, APR_FLOCK_NONBLOCK, si apr_file_lock() ne peut pas verouiller un fichier, il ne bloque pas et renvoie immédiatement un code erreur : APR_EAGAIN.
Il faut toujours s’assurer que la valeur de retour de apr_file_lock() est APR_SUCCESS. Si c’est le cas, le fichier a été verouillé avec succès. Sinon, il n’a pas pu être verouillé.

7. Gestion des répertoires dans le système de fichiers

Quand on veut faire quelque chose avec des répertoires, il faut toujours appeler d’abord apr_dir_open(). Après cet appel, on a un objet apr_dir_t. La seule chose que l’on puisse faire avec un objet apr_dir_t est de parcourir le répertoire. La fonction à utiliser est apr_dir_read(). A la fin on appelle apr_dir_close() pour fermer le répertoire. Ci-suivent les déclarations de la librairie :

/* extrait de apr_file_info.h */
APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new_dir,
    const char *dirname, apr_pool_t *pool);
APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo,
    apr_int32_t wanted, apr_dir_t *thedir);
APR_DECLARE(apr_status_t) apr_dir_close(apr_dir_t *thedir);

Le premier argument de apr_dir_open() est un argument résultat. C’est grâce à lui qu’on récupère l’objet apr_dir_t qui est crée. Le second argument est le nom du répertoire. Le troisième est le nom du pool mémoire à utiliser.
Le premier arguement de  apr_dir_read() est un argument résultat. Comme mentionné précédemment, apr_finfo_t est un type complet. Donc il faut l’allouer explicitement. apr_dir_read() renvoie une entrée du répertoire  apr_finfo_t. L’entrée est soit un fichier soit un répertoire. Le second argument est une aggrégation de drapeaux (« bit-wised flag »). Ces drapeaux sont définis dans apr_file_info.h. Ils ont tous le préfixe APR_FINFO_, par exemple APR_FINFO_SIZE, APR_FINFO_TYPE et APR_FINFO_NAME. Le troisième argument est l’objet apr_dir_t à parcourir.

Voici un code d’exemple :

/* pseudo code expliquant apr_dir_read() */
/* no error checks */
apr_pool_t *mp;
apr_pool_create(&mp, NULL);
/* répertoire à scanner */
const char *dirpath = "/home";
apr_dir_t *dir;
/* créer l'objet apr_dir_t */
apr_dir_open(&dir, dirpath, mp);
apr_finfo_t dirent;
/* remplir l'objet apr_finfo_t */
apr_dir_read(&dirent, APR_FINFO_DIRENT, dir);
/* dirent est la première entrée du répertoire.
 * Cette entrée est soit un fichier soit un répertoire. */
apr_dir_close(dir);

Dans l’exemple au-dessus, on appelle apr_dir_read() une seule fois, mais habituellement on le fait en boucle pour énumérer tous les fichiers d’un répertoire. Pour ce faire, il suffit juste d’appeler apr_dir_read() tant qu’il renvoie APR_SUCCESS. Regardez l’exemple qui est plus parlant : dir-sample.c.

/* pseudo code sur la boucle apr_dir_read(). Vérif. des erreurs omise */
/* Boucle typique de apr_dir_read() */
apr_dir_open(&dir, dirpath, mp);
while ((apr_dir_read(&dirent, APR_FINFO_NAME, dir)) == APR_SUCCESS) {
    printf("Le nom est %s\n", dirent.name);
}
apr_dir_close(dir);

Comme vous pouvez l’imaginer, la position courante du répertoire est stockée dans l’objet apr_dir_t. Le fait d’appeler apr_dir_read() fait avancer la position d’un cran. On peut reculer cette potision (qui est interne) en appelant apr_dir_rewind(). Les seules opération que l’on peut faire avec la position sont ces deux là : aller en avant et aller en arrière.

Comme vous pouvez le voir dans dir-sample.c, si vous scannez un répertoire de manière récursive, vous devez appeler apr_dir_open() de manière récursive, ici aussi.

REMARQUE : Sur Unix, apr_dir_read() renvoie un objet apr_finfo_t dont la propriété apr_file_t::fname est NULL.

Librairie Apr : tutoriel 5

5. Gestion des fichiers

Quand on veut des opérations dans un fichier, il faut en premier lieu appeler apr_file_open(). Voilà la déclaration :

/* extrait de apr_file_io.h */
APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **newf,
    const char *fname, apr_int32_t flag,
    apr_fileperms_t perm, apr_pool_t *pool);

Le type du premier argument est apr_file_t**, qui est un argument résultat. Plus précisément, il stocke l’objet apr_file_nouvellement crée lors de l’appel à apr_file_open(). Le second argument est le répertoire + nom du fichier. Le troisième est une composition de flags, définis dans apr_file_io.h. Le quatrième argument est le type de permission qu’on accorde sur ce fichier, mais cela ne fonctionne que lors de la création de fichier. Les flags sont définis dans apr_file_info.h. Par exemple, si vous voulez créer un fichier dont les permissions d’accès sont 0600, c-à-d. lecture-écriture uniquement autorisée par le possesseur du fichier, il vous faudra spécifier APR_UREAD|APR_UWRITE. Vous utiliserez le plus couramment APR_OS_DEFAULT comme permission. Le cinquième et dernier argument est le pool mémoire à utiliser. Précisons pour le lecteur occasionnel que le pool mémoire aura été crée auparavant via apr_pool_create().
Après qu’on ait ouvert le fichier, on peut l’utiliser pour d’autres fonctions de la librairie apr. On peut trouver ces fonctions dans apr_file_io.h. Les fonctions les plus basiques sont apr_file_read() et apr_file_write(). Comme vous l’imaginez, apr_file_read() donne la possibilité de lire quelque chose du fichier et apr_file_write() d’écrire quelque chose dedans.Voilà les déclarations :

/* extrait de apr_file_io.h */
APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile,
    void *buf, apr_size_t *nbytes);
APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile,
    const void *buf, apr_size_t *nbytes);

Le troisième argument des deux fonctions est un argument en entrée mais aussi en sortie (= résultat). En entrée, il sert à spécifier la longueur de la valeur, et on a en sortie le retour du nombre d’octets résultant de l’opération. Pour simplifier, apr_file_read() renvoie le nombre d’octets lus, et apr_file_write() renvoie le nombre d’octets écrits. Voici un code d’exemple.

/* pseudo-code expliquant apr_file_write() */
strcpy(outbuf, "123456789");
apr_size_t outlen = strlen(outbuf);
rv = apr_file_write(fp, outbuf, &outlen);
printf("apr_file_write() rv = %d, nb octets = %d\n", rv, outlen);

Dans ce cas, avant d’appeler apr_file_write(), la variable ‘outlen’ vaut 9. En passant &outlen à apr_file_write(), on dit à la librairie qu’il faut écrire 9 octets. Au retour de apr_file_write(), la valeur de ‘outlen’ est remplie de ce qui a été effectivement écrit. Habituellement c’est 9, surtout si c’est un fichier local. En théorie, la valeur pourrait être plus petite (si le disque est plein par exemple).
Il faut toujours appeler apr_file_close() pour fermer le fichier. Il est possible aussi de le fermer automatiquement en détruisant le pool mémoire par lequel il a été crée, mais je préfère fermer mes fichiers de manière explicite. Cela n’engage que moi.

REMARQUE : Il y a quelques incompatibilités entre les différentes versions de la librairie libapr. Le troisième argument de apr_file_open() a comme préfixe APR_FOPEN_ depuis libapr-1.1.0, alors que ce n’était pas le cas avant. Il faut donc utiliser APR_FOPEN_CREATE au lieu de APR_CREATE. Consultez apr_file_io.h pour voir ce qu’il vous faut réellement utiliser. De la même façon, le quatrième argument de apr_file_open() a le préfixe APR_FPROT_ depuis la libapr-1.1.0.

REMARQUE : Il y a un problème de portabilité sur le séparateur des répertoires/noms de fichiers. Unix(POSIX) utilise le slash (‘/’), et les systèmes Microsoft utilisent le backslash (‘\’) en tant que séparateur. Si vous voulez écrire une application qui tourne sur les deux système, je vous conseille de transformer toujours les séparateur en slash (‘/’) car les systèmes Microsoft l’acceptent quand même.

REMARQUE : Faites attention lors du l’utilisation de apr_file_gets(). Faire un appel à cette fonction sans le paramètre APR_BUFFERED dégrade sérieusement les performances de l’opération. Cela s’explique par le fait que apr_file_gets() appelle apr_file_read(), et, sans ce paramètre, il y aura un appel pour chaque octet à lire. Souvenez vous bien qu’il vous faut ouvrir le fichier avec le flag APR_BUFFERED si vous voulez utiliser apr_file_gets().

Je vous recommande d’utiliser toujours APR_BUFFERED sauf dans ces cas :

  • Quand vous « mmap »-ez le fichier (cela génère une erreur du fichier à « mmapp-er ») ;
  • Aucune lecture/écriture (p.ex. un fichier destiné à être uniquement un verrou) ;
  • Vous êtes sûr que vous lisez ou écrivez avec un buffer suffisamment gros.

REMARQUE : Si vous ouvrez un fichier avec le flag APR_BUFFERED et que vous appelez par la suite apr_file_trunc(), n’oubliez pas d’appeler apr_file_flush() avant apr_file_trunc(). Sinon vous allez perdre des informations.

REMARQUE: Si vous ouvrez un fichier avec le flag APR_BUFFERED, et que le fichier est partagé par plusieurs threads, il vous faut obligatoirement préciser APR_XTHREAD. Malheureusement, ce flag a quelques revers de médailles sur les systèmes d’exploitation Windows. Par expérience, je vous conseillerai d’éviter d’utiliser APR_XTHREAD sur les systèmes d’exploitation Windows.

Il est possible d’avoir des informations sur le fichier telles que la date de création, de modification, le possesseur du fichier, les permissions, etc. Ces informations sont dans la structure apr_finfo_t, que vous trouverez décrite dans apr_file_info.h. Il y a deux fonctions que fournit la librairie libapr :

/* extrait de apr_file_io.h */
APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo,
    apr_int32_t wanted, apr_file_t *thefile);
/* extrait de apr_file_info.h */
APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo,
    const char *fname, apr_int32_t wanted, apr_pool_t *pool);

Il faut un objet apr_file_t pour la fonction apr_file_info_get(), et un nom de fichier pour apr_stat(). Si on a déjà ouvert ce fichier et qu’on a donc un objet apr_file_t crée, c’est plus pratique de se servir de apr_file_info_get(). Sinon, il faut appeler apr_stat(). A l’inverse de beaucoup d’autres types, apr_finfo_t est un type complet. Plutôt que d’appeler une fonction de la librairie pour créer l’objet, il faut allouer une structure apr_finfo_t explicitement. Typiquement, c’est alloué sur la pile locale, parce qu’on n’a souvent besoin besoin que d’un seul attribut, comme la taille du fichier, ou sa date de création, et rien de plus. Notez que quelquefois des informations telles que apr_finfo_t::fname, sont allouées dans le pool mémoire que vous passez en paramètre. Faites attention, c’est parfois la cause de problèmes de fuites mémoire. Regardez l’exemple à finfo-sample.c pour bien comprendre le fonctionnement.

Il y a quelques fonctions de gestion des fichiers qui fonctionnent en se basant sur un nom de fichiers. Par exemple, apr_file_remove() et apr_file_copy(). Vous lez trouverez dans apr_file_io.h et apr_file_info.h.

REMARQUE : Quelques fonctions de la librairie aprlib prennent en paramètre des argument initialisés par des flags que l’on peut combiner (« bit-wised flags ») pour récupérer les attributs des fichiers. Ces fonctions sont apr_dir_read(), apr_stat(), apr_lstat(), et apr_file_info_get(). Notez que selon la valeur que vous donnez à l’argument, ce dernier peut ne pas exister sur le système d’exploitation, et dans ce cas, renvoyer la valeur d’erreur APR_INCOMPLETE.