> Tech > L’API Qp01GetAttr()

L’API Qp01GetAttr()

Tech - Par Renaud ROSSET - Publié le 24 juin 2010
email

L’API stat() présente la caractéristique suivante, que vous avez peut-être remarquée : elle ne contient aucune information sur la date de création initiale du fichier, et elle ne dit rien non plus sur d’autres attributs IFS moins évident. Ainsi, les attributs cachés, archive, système et lecture seule que l’iSeries maintient

pour préserver la compatibilité avec des systèmes Windows, ne se trouvent pas dans la structure de données stat(). C’est l’API Qp01GetAttr() qui fournit cette information.
L’API Qp01GetAttr() n’est disponible que sur l’iSeries, à l’inverse de stat() que l’on trouve aussi sur les systèmes Unix. Malheureusement, Qp01GetAttr() est un peu plus difficile à utiliser que l’API stat(), parce que les résultats ne sont pas en format fixe. On transmet à Qp01GetAttr() la liste des attributs auxquels on s’intéresse, et elle renvoie une liste de résultats. Comme chaque élément de la liste de résultats peut être de longueur variable, il faut recourir à des calculs de pointeurs pour passer en revue les résultats et interpréter ce qui a été reçu.
Comme beaucoup de structures de données et de constantes sont associées à cette famille d’API, j’ai jugé préférable de mettre les prototypes et autres définitions dans deux membres /COPY séparés. Le premier, QLG_H, contient les définitions qui appartiennent à la structure de données du nom de chemin indépendant du langage, que cette famille d’API utilise. Le second membre /COPY, Qp01StdI_H, contient les structures de données, les constantes et les prototypes pour Qp01Get Attr() et autres API similaires. J’ai utilisé ces noms de membres pour les rendre similaires à ceux qu’IBM utilise pour ILE C. Ainsi, si vous les rencontrez dans l’iSeries Information Center, les noms seront les mêmes et le sens de la documentation sera plus évident.
En A de la figure 7, se trouve le prototype pour l’API Qp01GetAttr(). Son premier paramètre, Path_Name, est une structure de données qui contient le nom du chemin d’accès ainsi que l’information le concernant (B en figure 7).
Le deuxième paramètre, Attr_Array, est une structure de données représentant les attributs que vous aimeriez extraire (C en figure 7). A noter que chaque attribut sera fourni comme un entier. On définit les constantes nommées dans le membre source Qp01Stdi_H, et elles correspondent à chaque attribut que l’on pourrait vouloir extraire.
Le troisième paramètre, Buffer, est un pointeur dirigé vers un emplacement en mémoire où les résultats seront renvoyés. Comme les résultats ne sont pas en format fixe, une structure de données ne fonctionnera pas pour ce paramètre.
Le quatrième paramètre, Buffer_ Size, indique à l’API combien de mémoire elle peut utiliser pour les résultats. C’est la garantie que l’API ne submergera pas la mémoire indiquée dans le troisième paramètre.
L’API renvoie le cinquième paramètre, Buf_Size_Need, à votre programme, pour indiquer la quantité de mémoire nécessaire pour extraire tous les attributs demandés.
Le sixième paramètre, Bytes_ Returnd, indique quelle quantité de la mémoire fournie par vous, a été utilisée par l’API. Si la valeur de ce paramètre est inférieure à Buf_Size_Need, c’est que vous n’avez pas fourni suffisamment de mémoire pour tout obtenir.
Le septième paramètre, Follow_ Symlnk, dit à l’API si elle doit suivre des liens symboliques, ou si elle doit fournir des informations à propos du lien symbolique lui-même. J’expliquerai les liens symboliques et leur fonctionnement dans le prochain article de cette série, « Travailler avec des liens ».
Le paramètre final de l’API, Qp01 GetAttr(), est un réceptacle pour d’éventuels paramètres qu’IBM pourrait ajouter dans une future release. Pour l’instant, il n’est pas nécessaire de le transmettre.
La figure 8 montre le programme GETATTR, que j’ai écrit pour démontrer comment utiliser Qp01GetAttr(). Il commence par créer une structure de nom de chemin (A en figure 8). Il définit « / » comme délimiteur pour indiquer à l’API que le caractère « / » sépare les répertoires du nom du fichier et des autres répertoires. Le programme définit le Path_Type en tant que QLG_CHAR_SINGLE, pour indiquer deux choses : que le nom de chemin sera fourni comme une chaîne de caractères (plutôt que comme un pointeur) et que le caractère délimiteur ne comporte qu’un caractère. Le programme définit le champ Path_Name de la structure de données d’après le nom de chemin de l’objet dont je veux extraire les attributs, et le champ Path_Name_Length est défini d’après la longueur du nom de chemin. J’ai défini x’00’ pour le reste de la structure de données, pour indiquer qu’il faut utiliser le CCSID, l’ID pays et l’ID langage par défaut pour mon job.
Ensuite, cet exemple de programme crée la liste des attributs à extraire (B en figure 8). Je lui demande d’en extraire quatre: PC_HIDDEN, PC_READ_ ONLY, PC_SYSTEM et CREATE_TIME.
Quelle taille dois-je déclarer pour le troisième paramètre, sachant que le buffer dans lequel l’API renvoie ses résultats peut être de longueur variable ? Plutôt que de le deviner, j’ai interrogé l’API. Dans l’appel de l’API, j’indique n’avoir pas réservé d’espace pour les résultats (C en figure 8). Par conséquent, l’API n’essaiera pas de fournir de résultats puisqu’il n’y a pas de place pour eux. En revanche, dans la variable SizeNeeded, l’API renvoie le nombre d’octets de mémoire dont elle a besoin. Il me suffit d’utiliser cette variable pour allouer la bonne quantité de mémoire (D en figure 8).
Une fois la mémoire nécessaire réservée, j’appelle à nouveau l’API, cette fois-ci en passant un pointeur vers la mémoire que j’ai allouée pour le paramètre « buffer » (E en figure 8).
La figure 9 montre la présentation de la structure de données d’en-tête d’attribut renvoyée pour chaque attribut que cette API fournit. Le programme GETATTR crée sa propre copie de cette structure de données qui est basée sur un pointeur. Cela, parce que le pointeur sera utilisé pour interpréter les résultats de l’API Qp01GetAttr(). Le programme pointe la structure de données vers le début du paramètre buffer (F en figure 8). Il examine l’ID attribut provenant de la structure de données pour voir quel attribut a été renvoyé et, en fonction de ce dernier, il copie cet attribut dans une variable (G en figure 8). L’attribut « change time » (heure de changement) est un autre des tampons horodateurs Unix, exactement comme ceux que renvoie l’API stat(). J’ai exclu la sous-procédure Unix2Ts() de cette figure parce que c’est la même routine que celle de la figure 5.
Une fois cet attribut interprété, le programme ajoute le champ Next_Attr_Offset au pointeur. Ce champ indique de combien il faut déplacer la structure de données en mémoire, pour trouver l’attribut suivant. Par exemple, si le champ Next_Attr_Offset contient le nombre 112, on en déduit que l’attribut suivant est 112 octets plus loin en mémoire que l’attribut courant. Quand j’ajoute la valeur de ce décalage (offset) au pointeur, la structure de données est déplacée de manière à visualiser cette nouvelle zone de mémoire.
Le champ Next_Attr_Offset est mis à 0 au moment où l’on visualise le dernier attribut qui a été renvoyé. Le programme GETATTR utilise cela pour mettre le pointeur à *NULL, ce qui a pour effet de terminer la boucle (H en figure 8). Pour les besoins de la démonstration, les attributs sont affichés avec l’opcode DSPLY après qu’ils aient été extraits (I en figure 8).

Téléchargez cette ressource

Comment sécuriser une PME avec l’approche par les risques ?

Comment sécuriser une PME avec l’approche par les risques ?

Disposant de moyens financiers et humains contraints, les PME éprouvent des difficultés à mettre en place une véritable stratégie de cybersécurité. Opérateur de services et d’infrastructures, Naitways leur propose une approche pragmatique de sécurité « by design » en priorisant les risques auxquelles elles sont confrontées.

Tech - Par Renaud ROSSET - Publié le 24 juin 2010