hr_swinst.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:19k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  Host Resources MIB - Installed Software group implementation - hr_swinst.c
  3.  *
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #if HAVE_SYS_PARAM_H
  7. #include <sys/param.h>
  8. #endif
  9. #include <sys/stat.h>
  10. #if TIME_WITH_SYS_TIME
  11. # include <sys/time.h>
  12. # include <time.h>
  13. #else
  14. # if HAVE_SYS_TIME_H
  15. #  include <sys/time.h>
  16. # else
  17. #  include <time.h>
  18. # endif
  19. #endif
  20. #if HAVE_DIRENT_H
  21. #include <dirent.h>
  22. #else
  23. # define dirent direct
  24. # if HAVE_SYS_NDIR_H
  25. #  include <sys/ndir.h>
  26. # endif
  27. # if HAVE_SYS_DIR_H
  28. #  include <sys/dir.h>
  29. # endif
  30. # if HAVE_NDIR_H
  31. #  include <ndir.h>
  32. # endif
  33. #endif
  34. #ifdef HAVE_PKGLOCS_H
  35. #include <pkglocs.h>
  36. #endif
  37. #ifdef HAVE_PKGINFO_H
  38. #include <pkginfo.h>
  39. #endif
  40. #ifdef HAVE_LIBRPM
  41. #include <rpm/rpmlib.h>
  42. #include <rpm/header.h>
  43. #include <fcntl.h>
  44. #ifdef HAVE_RPMGETPATH
  45. #include <rpm/rpmmacro.h>
  46. #endif
  47. #ifdef HAVE_RPM_RPMDB_H
  48. #include <rpm/rpmdb.h>
  49. #endif
  50. #endif
  51. #if HAVE_STRING_H
  52. #include <string.h>
  53. #else
  54. #include <strings.h>
  55. #endif
  56. #include "host_res.h"
  57. #include "hr_swinst.h"
  58. #include <net-snmp/utilities.h>
  59. #define HRSWINST_MONOTONICALLY_INCREASING
  60.         /*********************
  61.  *
  62.  *  Kernel & interface information,
  63.  *   and internal forward declarations
  64.  *
  65.  *********************/
  66. /*
  67.  * Reorganize the global data into a single static structure.
  68.  *
  69.  *      Old                     New
  70.  *======================================================
  71.  *      HRSW_directory          swi->swi_directory
  72.  *      HRSW_name[100]          swi->swi_name[SNMP_MAXPATH]
  73.  *      HRSW_index              swi->swi_index
  74.  *
  75.  *                              swi->swi_dbpath         (RPM only)
  76.  *                              swi->swi_maxrec         (RPM only)
  77.  *                              swi->swi_nrec           (RPM only)
  78.  *                              swi->swi_recs           (RPM only)
  79.  *      rpm_db                  swi->swi_rpmdb          (RPM only)
  80.  *                              swi->swi_h              (RPM only)
  81.  *                              swi->swi_prevx          (RPM only)
  82.  *
  83.  *      dp                      swi->swi_dp
  84.  *      de_p                    swi->swi_dep
  85.  */
  86. typedef struct {
  87. #if HAVE_LIBRPM
  88.     char           *swi_directory;
  89. #else
  90.     const char     *swi_directory;
  91. #endif
  92.     char            swi_name[SNMP_MAXPATH];     /* XXX longest file name */
  93.     int             swi_index;
  94. #if HAVE_LIBRPM
  95.     const char     *swi_dbpath;
  96.     time_t          swi_timestamp;      /* modify time on database */
  97.     int             swi_maxrec; /* no. of allocations */
  98.     int             swi_nrec;   /* no. of valid offsets */
  99.     int            *swi_recs;   /* db record offsets */
  100.     rpmdb           swi_rpmdb;
  101.     Header          swi_h;
  102.     int             swi_prevx;
  103. #else
  104.     DIR            *swi_dp;
  105.     struct dirent  *swi_dep;
  106. #endif
  107. } SWI_t;
  108. static SWI_t    _myswi = { NULL, "", 0 };       /* XXX static for now */
  109. int             header_hrswinst(struct variable *, oid *, size_t *, int,
  110.                                 size_t *, WriteMethod **);
  111. int             header_hrswInstEntry(struct variable *, oid *, size_t *,
  112.                                      int, size_t *, WriteMethod **);
  113. extern struct timeval starttime;
  114.         /*********************
  115.  *
  116.  *  Initialisation & common implementation functions
  117.  *
  118.  *********************/
  119. extern void     Init_HR_SWInst(void);
  120. extern int      Get_Next_HR_SWInst(void);
  121. extern void     End_HR_SWInst(void);
  122. extern void     Save_HR_SW_info(int ix);
  123. #ifdef HAVE_LIBRPM
  124. static void     Mark_HRSW_token(void);
  125. static void     Release_HRSW_token(void);
  126. #else
  127. #define Mark_HRSW_token()
  128. #define Release_HRSW_token()
  129. #endif
  130. #define HRSWINST_CHANGE 1
  131. #define HRSWINST_UPDATE 2
  132. #define HRSWINST_INDEX 3
  133. #define HRSWINST_NAME 4
  134. #define HRSWINST_ID 5
  135. #define HRSWINST_TYPE 6
  136. #define HRSWINST_DATE 7
  137. struct variable4 hrswinst_variables[] = {
  138.     {HRSWINST_CHANGE, ASN_TIMETICKS, RONLY, var_hrswinst, 1, {1}},
  139.     {HRSWINST_UPDATE, ASN_TIMETICKS, RONLY, var_hrswinst, 1, {2}},
  140.     {HRSWINST_INDEX, ASN_INTEGER, RONLY, var_hrswinst, 3, {3, 1, 1}},
  141.     {HRSWINST_NAME, ASN_OCTET_STR, RONLY, var_hrswinst, 3, {3, 1, 2}},
  142.     {HRSWINST_ID, ASN_OBJECT_ID, RONLY, var_hrswinst, 3, {3, 1, 3}},
  143.     {HRSWINST_TYPE, ASN_INTEGER, RONLY, var_hrswinst, 3, {3, 1, 4}},
  144.     {HRSWINST_DATE, ASN_OCTET_STR, RONLY, var_hrswinst, 3, {3, 1, 5}}
  145. };
  146. oid             hrswinst_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 6 };
  147. #ifdef PKGLOC                   /* Description from HRSW_dir/.../pkginfo: DESC= */
  148. #define _PATH_HRSW_directory PKGLOC
  149. #endif
  150. #ifdef hpux9                    /* Description from HRSW_dir/.../index:   fd: */
  151. #define _PATH_HRSW_directory "/system"
  152. #endif
  153. #ifdef hpux10                   /* Description from HRSW_dir/.../pfiles/INDEX: title */
  154. #define _PATH_HRSW_directory "/var/adm/sw/products"
  155. #endif
  156. #ifdef hpux11                   /* Description from HRSW_dir/.../pfiles/INDEX: title */
  157. #define _PATH_HRSW_directory "/var/adm/sw/products"
  158. #endif
  159. #ifdef freebsd2
  160. #define _PATH_HRSW_directory "/var/db/pkg"
  161. #endif
  162. void
  163. init_hr_swinst(void)
  164. {
  165. #if defined(HAVE_LIBRPM) || defined(_PATH_HRSW_directory)
  166.     SWI_t          *swi = &_myswi;      /* XXX static for now */
  167. #endif
  168. #ifdef HAVE_LIBRPM
  169.     struct stat     stat_buf;
  170. #endif
  171.     /*
  172.      * Read settings from config file,
  173.      * or take system-specific defaults 
  174.      */
  175. #ifdef HAVE_LIBRPM
  176.     if (swi->swi_directory == NULL) {
  177.         char            path[SNMP_MAXPATH];
  178.         /*
  179.          * XXX distinguish between rpm-2.5.x and rpm-2.9x 
  180.          */
  181. #ifdef HAVE_RPMGETPATH
  182.         rpmReadConfigFiles(NULL, NULL);
  183.         swi->swi_dbpath = rpmGetPath("%{_dbpath}", NULL);
  184. #else
  185.         rpmReadConfigFiles(NULL, NULL, NULL, 0);
  186.         swi->swi_dbpath = rpmGetVar(RPMVAR_DBPATH);
  187. #endif
  188.         if (swi->swi_directory != NULL)
  189.             free(swi->swi_directory);
  190.         snprintf(path, sizeof(path), "%s/Packages", swi->swi_dbpath);
  191.         if (stat(path, &stat_buf) == -1)
  192.             snprintf(path, sizeof(path), "%s/packages.rpm", swi->swi_dbpath);
  193.         path[ sizeof(path)-1 ] = 0;
  194.         swi->swi_directory = strdup(path);
  195.     }
  196. #else
  197. #  ifdef _PATH_HRSW_directory
  198.     if (swi->swi_directory == NULL) {
  199.         swi->swi_directory = _PATH_HRSW_directory;
  200.     }
  201.     strcpy(swi->swi_name, "[installed name]");  /* default name */
  202. #  else
  203.     /*
  204.      * XXX SunOS4 package directory is ?? -MJS 
  205.      */
  206.     return;                     /* packages not known - don't register */
  207. #  endif
  208. #endif
  209.     REGISTER_MIB("host/hr_swinst", hrswinst_variables, variable4,
  210.                  hrswinst_variables_oid);
  211. }
  212. /*
  213.  * header_hrswinst(...
  214.  * Arguments:
  215.  * vp     IN      - pointer to variable entry that points here
  216.  * name    IN/OUT  - IN/name requested, OUT/name found
  217.  * length  IN/OUT  - length of IN/OUT oid's 
  218.  * exact   IN      - TRUE if an exact match was requested
  219.  * var_len OUT     - length of variable or 0 if function returned
  220.  * write_method
  221.  */
  222. int
  223. header_hrswinst(struct variable *vp,
  224.                 oid * name,
  225.                 size_t * length,
  226.                 int exact, size_t * var_len, WriteMethod ** write_method)
  227. {
  228. #define HRSWINST_NAME_LENGTH 9
  229.     oid             newname[MAX_OID_LEN];
  230.     int             result;
  231.     DEBUGMSGTL(("host/hr_swinst", "var_hrswinst: "));
  232.     DEBUGMSGOID(("host/hr_swinst", name, *length));
  233.     DEBUGMSG(("host/hr_swinst", " %dn", exact));
  234.     memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
  235.     newname[HRSWINST_NAME_LENGTH] = 0;
  236.     result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
  237.     if ((exact && (result != 0)) || (!exact && (result >= 0)))
  238.         return (MATCH_FAILED);
  239.     memcpy((char *) name, (char *) newname,
  240.            (vp->namelen + 1) * sizeof(oid));
  241.     *length = vp->namelen + 1;
  242.     *write_method = 0;
  243.     *var_len = sizeof(long);    /* default to 'long' results */
  244.     return (MATCH_SUCCEEDED);
  245. }
  246. int
  247. header_hrswInstEntry(struct variable *vp,
  248.                      oid * name,
  249.                      size_t * length,
  250.                      int exact,
  251.                      size_t * var_len, WriteMethod ** write_method)
  252. {
  253. #define HRSWINST_ENTRY_NAME_LENGTH 11
  254.     oid             newname[MAX_OID_LEN];
  255.     int             swinst_idx, LowIndex = -1;
  256.     int             result;
  257.     DEBUGMSGTL(("host/hr_swinst", "var_hrswinstEntry: "));
  258.     DEBUGMSGOID(("host/hr_swinst", name, *length));
  259.     DEBUGMSG(("host/hr_swinst", " %dn", exact));
  260.     memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
  261.     /*
  262.      * Find "next" installed software entry 
  263.      */
  264.     Init_HR_SWInst();
  265.     while ((swinst_idx = Get_Next_HR_SWInst()) != -1) {
  266.         DEBUGMSG(("host/hr_swinst", "(index %d ....", swinst_idx));
  267.         newname[HRSWINST_ENTRY_NAME_LENGTH] = swinst_idx;
  268.         DEBUGMSGOID(("host/hr_swinst", newname, *length));
  269.         DEBUGMSG(("host/hr_swinst", "n"));
  270.         result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
  271.         if (exact && (result == 0)) {
  272.             LowIndex = swinst_idx;
  273.             Save_HR_SW_info(LowIndex);
  274.             break;
  275.         }
  276.         if ((!exact && (result < 0)) &&
  277.             (LowIndex == -1 || swinst_idx < LowIndex)) {
  278.             LowIndex = swinst_idx;
  279.             Save_HR_SW_info(LowIndex);
  280. #ifdef HRSWINST_MONOTONICALLY_INCREASING
  281.             break;
  282. #endif
  283.         }
  284.     }
  285.     Mark_HRSW_token();
  286.     End_HR_SWInst();
  287.     if (LowIndex == -1) {
  288.         DEBUGMSGTL(("host/hr_swinst", "... index out of rangen"));
  289.         return (MATCH_FAILED);
  290.     }
  291.     memcpy((char *) name, (char *) newname,
  292.            (vp->namelen + 1) * sizeof(oid));
  293.     *length = vp->namelen + 1;
  294.     *write_method = 0;
  295.     *var_len = sizeof(long);    /* default to 'long' results */
  296.     DEBUGMSGTL(("host/hr_inst", "... get installed S/W stats "));
  297.     DEBUGMSGOID(("host/hr_inst", name, *length));
  298.     DEBUGMSG(("host/hr_inst", "n"));
  299.     return LowIndex;
  300. }
  301.         /*********************
  302.  *
  303.  *  System specific implementation functions
  304.  *
  305.  *********************/
  306. u_char         *
  307. var_hrswinst(struct variable * vp,
  308.              oid * name,
  309.              size_t * length,
  310.              int exact, size_t * var_len, WriteMethod ** write_method)
  311. {
  312.     SWI_t          *swi = &_myswi;      /* XXX static for now */
  313.     int             sw_idx = 0;
  314.     static char     string[SNMP_MAXPATH];
  315.     u_char         *ret = NULL;
  316.     struct stat     stat_buf;
  317.     if (vp->magic < HRSWINST_INDEX) {
  318.         if (header_hrswinst(vp, name, length, exact, var_len, write_method)
  319.             == MATCH_FAILED)
  320.             return NULL;
  321.     } else {
  322.         sw_idx =
  323.             header_hrswInstEntry(vp, name, length, exact, var_len,
  324.                                  write_method);
  325.         if (sw_idx == MATCH_FAILED)
  326.             return NULL;
  327.     }
  328.     switch (vp->magic) {
  329.     case HRSWINST_CHANGE:
  330.     case HRSWINST_UPDATE:
  331.         string[0] = '';
  332.         if (swi->swi_directory != NULL) {
  333.             strncpy(string, swi->swi_directory, sizeof(string));
  334.             string[ sizeof(string)-1 ] = 0;
  335.         }
  336.         if (*string && (stat(string, &stat_buf) != -1)) {
  337.             if (stat_buf.st_mtime > starttime.tv_sec)
  338.                 /*
  339.                  * changed 'recently' - i.e. since this agent started 
  340.                  */
  341.                 long_return = (stat_buf.st_mtime - starttime.tv_sec) * 100;
  342.             else
  343.                 long_return = 0;        /* predates this agent */
  344.         } else
  345. #if NO_DUMMY_VALUES
  346.             return NULL;
  347. #else
  348.             long_return = 363136200;
  349. #endif
  350.         ret = (u_char *) & long_return;
  351.         break;
  352.     case HRSWINST_INDEX:
  353.         long_return = sw_idx;
  354.         ret = (u_char *) & long_return;
  355.         break;
  356.     case HRSWINST_NAME:
  357.         {
  358.             strncpy(string, swi->swi_name, sizeof(string) - 1);
  359.             /*
  360.              * This will be unchanged from the initial "null"
  361.              * value, if swi->swi_name is not defined 
  362.              */
  363.             string[sizeof(string) - 1] = '';
  364.             *var_len = strlen(string);
  365.             ret = (u_char *) string;
  366.         }
  367.         break;
  368.     case HRSWINST_ID:
  369.         *var_len = nullOidLen;
  370.         ret = (u_char *) nullOid;
  371.         break;
  372.     case HRSWINST_TYPE:
  373.         {
  374. #ifdef HAVE_PKGINFO
  375.             /*
  376.              * at least on solaris2 this works 
  377.              */
  378.             char           *catg = pkgparam(swi->swi_name, "CATEGORY");
  379.             if (catg == NULL) {
  380.                 long_return = 1;        /*  unknown  */
  381.             } else {
  382.                 if (strstr(catg, "system") != NULL) {
  383.                     long_return = 2;    /*  operatingSystem  */
  384.                 } else if (strstr(catg, "application") != NULL) {
  385.                     long_return = 4;    /*  applcation  */
  386.                 } else {
  387.                     long_return = 1;    /*  unknown  */
  388.                 }
  389.                 free(catg);
  390.             }
  391. #else
  392.             long_return = 1;    /* unknown */
  393. #endif
  394.             ret = (u_char *) & long_return;
  395.         }
  396.         break;
  397.     case HRSWINST_DATE:
  398.         {
  399. #ifdef HAVE_LIBRPM
  400.             int_32         *rpm_data;
  401.             headerGetEntry(swi->swi_h, RPMTAG_INSTALLTIME, NULL,
  402.                            (void **) &rpm_data, NULL);
  403.             if (rpm_data != NULL) {
  404.                 time_t          installTime = *rpm_data;
  405.                 ret = date_n_time(&installTime, var_len);
  406.             } else {
  407.                 ret = date_n_time(0, var_len);
  408.             }
  409. #else
  410.             if (swi->swi_directory != NULL) {
  411.                 snprintf(string, sizeof(string), "%s/%s",
  412.                          swi->swi_directory, swi->swi_name);
  413.                 string[ sizeof(string)-1 ] = 0;
  414.                 stat(string, &stat_buf);
  415.                 ret = date_n_time(&stat_buf.st_mtime, var_len);
  416.             } else {
  417. #if NO_DUMMY_VALUES
  418.                 return NULL;
  419. #endif
  420.                 sprintf(string, "back in the mists of time");
  421.                 *var_len = strlen(string);
  422.                 ret = (u_char *) string;
  423.             }
  424. #endif
  425.         }
  426.         break;
  427.     default:
  428.         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrswinstn",
  429.                     vp->magic));
  430.         ret = NULL;
  431.         break;
  432.     }
  433.     Release_HRSW_token();
  434.     return ret;
  435. }
  436.         /*********************
  437.  *
  438.  *  Internal implementation functions
  439.  *
  440.  *********************/
  441. #ifdef HAVE_LIBRPM
  442. static void
  443. Check_HRSW_cache(void *xxx)
  444. {
  445.     SWI_t          *swi = (SWI_t *) xxx;
  446.     /*
  447.      * Make sure cache is up-to-date 
  448.      */
  449.     if (swi->swi_recs != NULL) {
  450.         struct stat     sb;
  451.         lstat(swi->swi_directory, &sb);
  452.         if (swi->swi_timestamp == sb.st_mtime)
  453.             return;
  454.         swi->swi_timestamp = sb.st_mtime;
  455.     }
  456.     /*
  457.      * Get header offsets 
  458.      */
  459.     {
  460.         int             ix = 0;
  461.         int             offset;
  462. #if defined(RPMDBI_PACKAGES)
  463.         rpmdbMatchIterator mi = NULL;
  464.         Header          h;
  465.         mi = rpmdbInitIterator(swi->swi_rpmdb, RPMDBI_PACKAGES, NULL, 0);
  466.         while ((h = rpmdbNextIterator(mi)) != NULL) {
  467.             offset = rpmdbGetIteratorOffset(mi);
  468. #else
  469.         for (offset = rpmdbFirstRecNum(swi->swi_rpmdb);
  470.              offset != 0;
  471.              offset = rpmdbNextRecNum(swi->swi_rpmdb, offset)) {
  472. #endif
  473.             if (ix >= swi->swi_maxrec) {
  474.                 swi->swi_maxrec += 256;
  475.                 swi->swi_recs = (swi->swi_recs == NULL)
  476.                     ? (int *) malloc(swi->swi_maxrec * sizeof(int))
  477.                     : (int *) realloc(swi->swi_recs,
  478.                                       swi->swi_maxrec * sizeof(int));
  479.             }
  480.             swi->swi_recs[ix++] = offset;
  481. #if !defined(RPMDBI_PACKAGES)
  482.         }
  483. #else
  484.         }
  485.         rpmdbFreeIterator(mi);
  486. #endif
  487.         swi->swi_nrec = ix;
  488.     }
  489. }
  490. #endif                          /* HAVE_LIBRPM */
  491. void
  492. Init_HR_SWInst(void)
  493. {
  494.     SWI_t          *swi = &_myswi;      /* XXX static for now */
  495.     swi->swi_index = 0;
  496. #ifdef HAVE_LIBRPM
  497.     if (swi->swi_rpmdb != NULL)
  498.         return;
  499.     if (rpmdbOpen("", &swi->swi_rpmdb, O_RDONLY, 0644) != 0)
  500.         swi->swi_index = -1;
  501.     Check_HRSW_cache(swi);
  502. #else
  503.     if (swi->swi_directory != NULL) {
  504.         if (swi->swi_dp != NULL) {
  505.             closedir(swi->swi_dp);
  506.             swi->swi_dp = NULL;
  507.         }
  508.         if ((swi->swi_dp = opendir(swi->swi_directory)) == NULL)
  509.             swi->swi_index = -1;
  510.     } else
  511.         swi->swi_index = -1;
  512. #endif
  513. }
  514. int
  515. Get_Next_HR_SWInst(void)
  516. {
  517.     SWI_t          *swi = &_myswi;      /* XXX static for now */
  518.     if (swi->swi_index == -1)
  519.         return -1;
  520. #ifdef HAVE_LIBRPM
  521.     /*
  522.      * XXX Watchout: index starts with 1 
  523.      */
  524.     if (0 <= swi->swi_index && swi->swi_index < swi->swi_nrec)
  525.         return ++swi->swi_index;
  526. #else
  527.     if (swi->swi_directory != NULL) {
  528.         while ((swi->swi_dep = readdir(swi->swi_dp)) != NULL) {
  529.             if (swi->swi_dep->d_name[0] == '.')
  530.                 continue;
  531.             /*
  532.              * Ought to check for "properly-formed" entry 
  533.              */
  534.             return ++swi->swi_index;
  535.         }
  536.     }
  537. #endif
  538.     return -1;
  539. }
  540. void
  541. Save_HR_SW_info(int ix)
  542. {
  543.     SWI_t          *swi = &_myswi;      /* XXX static for now */
  544. #ifdef HAVE_LIBRPM
  545.     /*
  546.      * XXX Watchout: ix starts with 1 
  547.      */
  548.     if (1 <= ix && ix <= swi->swi_nrec && ix != swi->swi_prevx) {
  549.         int             offset;
  550.         Header          h;
  551.         char           *n, *v, *r;
  552.         offset = swi->swi_recs[ix - 1];
  553. #if defined(RPMDBI_PACKAGES)
  554.         {
  555.             rpmdbMatchIterator mi;
  556.             mi = rpmdbInitIterator(swi->swi_rpmdb, RPMDBI_PACKAGES,
  557.                                    &offset, sizeof(offset));
  558.             if ((h = rpmdbNextIterator(mi)) != NULL)
  559.                 h = headerLink(h);
  560.             rpmdbFreeIterator(mi);
  561.         }
  562. #else
  563.         h = rpmdbGetRecord(swi->swi_rpmdb, offset);
  564. #endif
  565.         if (h == NULL)
  566.             return;
  567.         if (swi->swi_h != NULL)
  568.             headerFree(swi->swi_h);
  569.         swi->swi_h = h;
  570.         swi->swi_prevx = ix;
  571.         headerGetEntry(swi->swi_h, RPMTAG_NAME, NULL, (void **) &n, NULL);
  572.         headerGetEntry(swi->swi_h, RPMTAG_VERSION, NULL, (void **) &v,
  573.                        NULL);
  574.         headerGetEntry(swi->swi_h, RPMTAG_RELEASE, NULL, (void **) &r,
  575.                        NULL);
  576.         snprintf(swi->swi_name, sizeof(swi->swi_name), "%s-%s-%s", n, v, r);
  577.         swi->swi_name[ sizeof(swi->swi_name)-1 ] = 0;
  578.     }
  579. #else
  580.     snprintf(swi->swi_name, sizeof(swi->swi_name), swi->swi_dep->d_name);
  581.     swi->swi_name[ sizeof(swi->swi_name)-1 ] = 0;
  582. #endif
  583. }
  584. #ifdef HAVE_LIBRPM
  585. void
  586. Mark_HRSW_token(void)
  587. {
  588. }
  589. void
  590. Release_HRSW_token(void)
  591. {
  592.     SWI_t          *swi = &_myswi;      /* XXX static for now */
  593.     if (swi != NULL && swi->swi_h) {
  594.         headerFree(swi->swi_h);
  595.         swi->swi_h = NULL;
  596.         swi->swi_prevx = -1;
  597.     }
  598. }
  599. #endif                          /* HAVE_LIBRPM */
  600. void
  601. End_HR_SWInst(void)
  602. {
  603.     SWI_t          *swi = &_myswi;      /* XXX static for now */
  604. #ifdef HAVE_LIBRPM
  605.     rpmdbClose(swi->swi_rpmdb); /* or only on finishing ? */
  606.     swi->swi_rpmdb = NULL;
  607. #else
  608.     if (swi->swi_dp != NULL)
  609.         closedir(swi->swi_dp);
  610.     swi->swi_dp = NULL;
  611. #endif
  612. }