~ubuntu-branches/ubuntu/trusty/net-snmp/trusty

« back to all changes in this revision

Viewing changes to agent/mibgroup/host/hr_swinst.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-13 12:06:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040913120621-g952ntonlleihcvm
Tags: upstream-5.1.1
ImportĀ upstreamĀ versionĀ 5.1.1

Show diffs side-by-side

added added

removed removed

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