fix: prevent segfault if malicious server sends 1 GB of data through ftpNLST.
[platform/upstream/rpm.git] / rpmdb / rpmdb.h
1 #ifndef H_RPMDB
2 #define H_RPMDB
3 /*@-bounds@*/
4
5 /** \ingroup rpmdb dbi db1 db3
6  * \file rpmdb/rpmdb.h
7  * Access RPM indices using Berkeley DB interface(s).
8  */
9
10 #include <assert.h>
11 #include "rpmlib.h"
12 #include "rpmsw.h"
13 #include "db.h"
14
15 /*@-exportlocal@*/
16 /*@unchecked@*/
17 extern int _rpmdb_debug;
18 /*@=exportlocal@*/
19
20 #ifdef  NOTYET
21 /** \ingroup rpmdb
22  * Database of headers and tag value indices.
23  */
24 typedef /*@abstract@*/ /*@refcounted@*/ struct rpmdb_s * rpmdb;
25
26 /** \ingroup rpmdb
27  * Database iterator.
28  */
29 typedef /*@abstract@*/ struct _rpmdbMatchIterator * rpmdbMatchIterator;
30 #endif
31
32 /**
33  * Tag value pattern match mode.
34  */
35 typedef enum rpmMireMode_e {
36     RPMMIRE_DEFAULT     = 0,    /*!< regex with \., .* and ^...$ added */
37     RPMMIRE_STRCMP      = 1,    /*!< strings  using strcmp(3) */
38     RPMMIRE_REGEX       = 2,    /*!< regex(7) patterns through regcomp(3) */
39     RPMMIRE_GLOB        = 3     /*!< glob(7) patterns through fnmatch(3) */
40 } rpmMireMode;
41
42 /**
43  */
44 typedef /*@abstract@*/ struct _dbiIndexItem * dbiIndexItem;
45
46 /** \ingroup rpmdb
47  * A single element (i.e. inverted list from tag values) of a database.
48  */
49 typedef /*@abstract@*/ struct _dbiIndexSet * dbiIndexSet;
50
51 /**
52  */
53 typedef /*@abstract@*/ struct _dbiIndex * dbiIndex;
54
55 /* this will break if sizeof(int) != 4 */
56 /** \ingroup dbi
57  * A single item from an index database (i.e. the "data returned").
58  * Note: In rpm-3.0.4 and earlier, this structure was passed by value,
59  * and was identical to the "data saved" structure below.
60  */
61 struct _dbiIndexItem {
62     unsigned int hdrNum;                /*!< header instance in db */
63     unsigned int tagNum;                /*!< tag index in header */
64     unsigned int fpNum;                 /*!< finger print index */
65 };
66
67 /** \ingroup dbi
68  * Items retrieved from the index database.
69  */
70 struct _dbiIndexSet {
71 /*@owned@*/ struct _dbiIndexItem * recs; /*!< array of records */
72     int count;                          /*!< number of records */
73 };
74
75 /** \ingroup dbi
76  * Private methods for accessing an index database.
77  */
78 struct _dbiVec {
79     int dbv_major;                      /*!< Berkeley db version major */
80     int dbv_minor;                      /*!< Berkeley db version minor */
81     int dbv_patch;                      /*!< Berkeley db version patch */
82
83 /** \ingroup dbi
84  * Return handle for an index database.
85  * @param rpmdb         rpm database
86  * @param rpmtag        rpm tag
87  * @return              0 on success
88  */
89     int (*open) (rpmdb rpmdb, rpmTag rpmtag, /*@out@*/ dbiIndex * dbip)
90         /*@globals fileSystem @*/
91         /*@modifies *dbip, fileSystem @*/;
92
93 /** \ingroup dbi
94  * Close index database, and destroy database handle.
95  * @param dbi           index database handle
96  * @param flags         (unused)
97  * @return              0 on success
98  */
99     int (*close) (/*@only@*/ dbiIndex dbi, unsigned int flags)
100         /*@globals fileSystem @*/
101         /*@modifies dbi, fileSystem @*/;
102
103 /** \ingroup dbi
104  * Flush pending operations to disk.
105  * @param dbi           index database handle
106  * @param flags         (unused)
107  * @return              0 on success
108  */
109     int (*sync) (dbiIndex dbi, unsigned int flags)
110         /*@globals fileSystem @*/
111         /*@modifies fileSystem @*/;
112
113 /** \ingroup dbi
114  * Associate secondary database with primary.
115  * @param dbi           index database handle
116  * @param dbisecondary  secondary index database handle
117  * @param callback      create secondary key from primary (NULL if DB_RDONLY)
118  * @param flags         DB_CREATE or 0
119  * @return              0 on success
120  */
121     int (*associate) (dbiIndex dbi, dbiIndex dbisecondary,
122                 int (*callback) (DB *, const DBT *, const DBT *, DBT *),
123                 unsigned int flags)
124         /*@globals fileSystem @*/
125         /*@modifies dbi, fileSystem @*/;
126
127 /** \ingroup dbi
128  * Return join cursor for list of cursors.
129  * @param dbi           index database handle
130  * @param curslist      NULL terminated list of database cursors
131  * @retval dbcp         address of join database cursor
132  * @param flags         DB_JOIN_NOSORT or 0
133  * @return              0 on success
134  */
135     int (*join) (dbiIndex dbi, DBC ** curslist, /*@out@*/ DBC ** dbcp,
136                 unsigned int flags)
137         /*@globals fileSystem @*/
138         /*@modifies dbi, *dbcp, fileSystem @*/;
139
140 /** \ingroup dbi
141  * Open database cursor.
142  * @param dbi           index database handle
143  * @param txnid         database transaction handle
144  * @retval dbcp         address of new database cursor
145  * @param dbiflags      DB_WRITECURSOR or 0
146  * @return              0 on success
147  */
148     int (*copen) (dbiIndex dbi, /*@null@*/ DB_TXN * txnid,
149                         /*@out@*/ DBC ** dbcp, unsigned int dbiflags)
150         /*@globals fileSystem @*/
151         /*@modifies dbi, *txnid, *dbcp, fileSystem @*/;
152
153 /** \ingroup dbi
154  * Close database cursor.
155  * @param dbi           index database handle
156  * @param dbcursor      database cursor
157  * @param flags         (unused)
158  * @return              0 on success
159  */
160     int (*cclose) (dbiIndex dbi, /*@only@*/ DBC * dbcursor, unsigned int flags)
161         /*@globals fileSystem @*/
162         /*@modifies dbi, *dbcursor, fileSystem @*/;
163
164 /** \ingroup dbi
165  * Duplicate a database cursor.
166  * @param dbi           index database handle
167  * @param dbcursor      database cursor
168  * @retval dbcp         address of new database cursor
169  * @param flags         DB_POSITION for same position, 0 for uninitialized
170  * @return              0 on success
171  */
172     int (*cdup) (dbiIndex dbi, DBC * dbcursor, /*@out@*/ DBC ** dbcp,
173                 unsigned int flags)
174         /*@globals fileSystem @*/
175         /*@modifies dbi, *dbcp, fileSystem @*/;
176
177 /** \ingroup dbi
178  * Delete (key,data) pair(s) using db->del or dbcursor->c_del.
179  * @param dbi           index database handle
180  * @param dbcursor      database cursor (NULL will use db->del)
181  * @param key           delete key value/length/flags
182  * @param data          delete data value/length/flags
183  * @param flags         (unused)
184  * @return              0 on success
185  */
186     int (*cdel) (dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
187                         unsigned int flags)
188         /*@globals fileSystem @*/
189         /*@modifies *dbcursor, fileSystem @*/;
190
191 /** \ingroup dbi
192  * Retrieve (key,data) pair using db->get or dbcursor->c_get.
193  * @param dbi           index database handle
194  * @param dbcursor      database cursor (NULL will use db->get)
195  * @param key           retrieve key value/length/flags
196  * @param data          retrieve data value/length/flags
197  * @param flags         (unused)
198  * @return              0 on success
199  */
200     int (*cget) (dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
201                         unsigned int flags)
202         /*@globals fileSystem @*/
203         /*@modifies *dbcursor, *key, *data, fileSystem @*/;
204
205 /** \ingroup dbi
206  * Retrieve (key,data) pair using dbcursor->c_pget.
207  * @param dbi           index database handle
208  * @param dbcursor      database cursor
209  * @param key           secondary retrieve key value/length/flags
210  * @param pkey          primary retrieve key value/length/flags
211  * @param data          primary retrieve data value/length/flags
212  * @param flags         DB_NEXT, DB_SET, or 0
213  * @return              0 on success
214  */
215     int (*cpget) (dbiIndex dbi, /*@null@*/ DBC * dbcursor,
216                 DBT * key, DBT * pkey, DBT * data, unsigned int flags)
217         /*@globals fileSystem @*/
218         /*@modifies *dbcursor, *key, *pkey, *data, fileSystem @*/;
219
220 /** \ingroup dbi
221  * Store (key,data) pair using db->put or dbcursor->c_put.
222  * @param dbi           index database handle
223  * @param dbcursor      database cursor (NULL will use db->put)
224  * @param key           store key value/length/flags
225  * @param data          store data value/length/flags
226  * @param flags         (unused)
227  * @return              0 on success
228  */
229     int (*cput) (dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
230                         unsigned int flags)
231         /*@globals fileSystem @*/
232         /*@modifies *dbcursor, fileSystem @*/;
233
234 /** \ingroup dbi
235  * Retrieve count of (possible) duplicate items using dbcursor->c_count.
236  * @param dbi           index database handle
237  * @param dbcursor      database cursor
238  * @param countp        address of count
239  * @param flags         (unused)
240  * @return              0 on success
241  */
242     int (*ccount) (dbiIndex dbi, DBC * dbcursor,
243                         /*@out@*/ unsigned int * countp,
244                         unsigned int flags)
245         /*@globals fileSystem @*/
246         /*@modifies *dbcursor, fileSystem @*/;
247
248 /** \ingroup dbi
249  * Is database byte swapped?
250  * @param dbi           index database handle
251  * @return              0 no
252  */
253     int (*byteswapped) (dbiIndex dbi)
254         /*@globals fileSystem @*/
255         /*@modifies fileSystem @*/;
256
257 /** \ingroup dbi
258  * Save statistics in database handle.
259  * @param dbi           index database handle
260  * @param flags         retrieve statistics that don't require traversal?
261  * @return              0 on success
262  */
263     int (*stat) (dbiIndex dbi, unsigned int flags)
264         /*@globals fileSystem @*/
265         /*@modifies dbi, fileSystem @*/;
266
267 };
268
269 /** \ingroup dbi
270  * Describes an index database (implemented on Berkeley db3 functionality).
271  */
272 struct _dbiIndex {
273 /*@null@*/
274     const char * dbi_root;      /*!< chroot(2) component of path */
275 /*@null@*/
276     const char * dbi_home;      /*!< directory component of path */
277 /*@null@*/
278     const char * dbi_file;      /*!< file component of path */
279 /*@null@*/
280     const char * dbi_subfile;
281 /*@null@*/
282     const char * dbi_tmpdir;    /*!< temporary directory */
283
284     int dbi_ecflags;            /*!< db_env_create flags */
285     int dbi_cflags;             /*!< db_create flags */
286     int dbi_oeflags;            /*!< common (db,dbenv}->open flags */
287     int dbi_eflags;             /*!< dbenv->open flags */
288     int dbi_oflags;             /*!< db->open flags */
289     int dbi_tflags;             /*!< dbenv->txn_begin flags */
290
291     int dbi_type;               /*!< db index type */
292     unsigned dbi_mode;          /*!< mode to use on open */
293     int dbi_perms;              /*!< file permission to use on open */
294     long dbi_shmkey;            /*!< shared memory base key */
295     int dbi_api;                /*!< Berkeley API type */
296
297     int dbi_verify_on_close;
298     int dbi_use_dbenv;          /*!< use db environment? */
299     int dbi_permit_dups;        /*!< permit duplicate entries? */
300     int dbi_no_fsync;           /*!< no-op fsync for db */
301     int dbi_no_dbsync;          /*!< don't call dbiSync */
302     int dbi_lockdbfd;           /*!< do fcntl lock on db fd */
303     int dbi_temporary;          /*!< non-persistent */
304     int dbi_debug;
305     int dbi_byteswapped;
306
307 /*@null@*/
308     char * dbi_host;
309     unsigned long dbi_cl_timeout;
310     unsigned long dbi_sv_timeout;
311
312         /* dbenv parameters */
313     int dbi_lorder;
314 /*@unused@*/
315     void (*db_errcall) (const char *db_errpfx, char *buffer)
316         /*@globals fileSystem @*/
317         /*@modifies fileSystem @*/;
318 /*@unused@*/ /*@shared@*/
319     FILE *      dbi_errfile;
320     const char * dbi_errpfx;
321     int dbi_verbose;
322     int dbi_region_init;
323     int dbi_tas_spins;
324         /* mpool sub-system parameters */
325     int dbi_mmapsize;   /*!< (10Mb) */
326     int dbi_cachesize;  /*!< (128Kb) */
327         /* lock sub-system parameters */
328     unsigned int dbi_lk_max;
329     unsigned int dbi_lk_detect;
330 /*@unused@*/ int dbi_lk_nmodes;
331 /*@unused@*/ unsigned char * dbi_lk_conflicts;
332         /* log sub-system parameters */
333     unsigned int dbi_lg_max;
334     unsigned int dbi_lg_bsize;
335         /* transaction sub-system parameters */
336     unsigned int dbi_tx_max;
337 #if 0
338     int (*dbi_tx_recover) (DB_ENV *dbenv, DBT *log_rec,
339                                 DB_LSN *lsnp, int redo, void *info)
340         /*@globals fileSystem @*/
341         /*@modifies fileSystem @*/;
342 #endif
343         /* dbinfo parameters */
344     int dbi_pagesize;           /*!< (fs blksize) */
345 /*@unused@*/ /*@null@*/
346     void * (*dbi_malloc) (size_t nbytes)
347         /*@*/;
348         /* hash access parameters */
349     unsigned int dbi_h_ffactor; /*!< */
350     unsigned int (*dbi_h_hash_fcn) (DB *, const void *bytes,
351                                 unsigned int length)
352         /*@*/;
353     unsigned int dbi_h_nelem;   /*!< */
354     unsigned int dbi_h_flags;   /*!< DB_DUP, DB_DUPSORT */
355     int (*dbi_h_dup_compare_fcn) (DB *, const DBT *, const DBT *)
356         /*@*/;
357         /* btree access parameters */
358     int dbi_bt_flags;
359     int dbi_bt_minkey;
360     int (*dbi_bt_compare_fcn) (DB *, const DBT *, const DBT *)
361         /*@*/;
362     int (*dbi_bt_dup_compare_fcn) (DB *, const DBT *, const DBT *)
363         /*@*/;
364     size_t (*dbi_bt_prefix_fcn) (DB *, const DBT *, const DBT *)
365         /*@*/;
366         /* recno access parameters */
367     int dbi_re_flags;
368     int dbi_re_delim;
369     unsigned int dbi_re_len;
370     int dbi_re_pad;
371     const char * dbi_re_source;
372         /* queue access parameters */
373     unsigned int dbi_q_extentsize;
374
375 /*@refcounted@*/
376     rpmdb dbi_rpmdb;            /*!< the parent rpm database */
377     rpmTag dbi_rpmtag;          /*!< rpm tag used for index */
378     int dbi_jlen;               /*!< size of join key */
379
380 /*@only@*//*@null@*/
381     DB * dbi_db;                /*!< Berkeley DB * handle */
382 /*@only@*//*@null@*/
383     DB_TXN * dbi_txnid;         /*!< Bekerley DB_TXN * transaction id */
384 /*@only@*//*@null@*/
385     void * dbi_stats;           /*!< Berkeley db statistics */
386
387 /*@observer@*/
388     const struct _dbiVec * dbi_vec;     /*!< private methods */
389
390 };
391
392 /** \ingroup rpmdb
393  * Describes the collection of index databases used by rpm.
394  */
395 struct rpmdb_s {
396 /*@owned@*/
397     const char * db_root;/*!< path prefix */
398 /*@owned@*/
399     const char * db_home;/*!< directory path */
400     int         db_flags;
401     int         db_mode;        /*!< open mode */
402     int         db_perms;       /*!< open permissions */
403     int         db_api;         /*!< Berkeley API type */
404 /*@owned@*/
405     const char * db_errpfx;
406     int         db_remove_env;
407     int         db_filter_dups;
408     int         db_chrootDone;  /*!< If chroot(2) done, ignore db_root. */
409     void (*db_errcall) (const char *db_errpfx, char *buffer)
410         /*@*/;
411 /*@shared@*/
412     FILE *      db_errfile;
413 /*@only@*/
414     void * (*db_malloc) (size_t nbytes)
415         /*@*/;
416 /*@only@*/
417     void * (*db_realloc) (/*@only@*//*@null@*/ void * ptr,
418                                                 size_t nbytes)
419         /*@*/;
420     void (*db_free) (/*@only@*/ void * ptr)
421         /*@modifies *ptr @*/;
422 /*@only@*/ /*@null@*/
423     unsigned char * db_bits;    /*!< package instance bit mask. */
424     int         db_nbits;       /*!< no. of bits in mask. */
425     rpmdb       db_next;
426     int         db_opens;
427 /*@only@*/ /*@null@*/
428     void *      db_dbenv;       /*!< Berkeley DB_ENV handle. */
429     int         db_ndbi;        /*!< No. of tag indices. */
430     dbiIndex * _dbi;            /*!< Tag indices. */
431
432     struct rpmop_s db_getops;
433     struct rpmop_s db_putops;
434     struct rpmop_s db_delops;
435
436 /*@refs@*/
437     int nrefs;                  /*!< Reference count. */
438 };
439
440 /* for RPM's internal use only */
441
442 /** \ingroup rpmdb
443  */
444 enum rpmdbFlags {
445         RPMDB_FLAG_JUSTCHECK    = (1 << 0),
446         RPMDB_FLAG_MINIMAL      = (1 << 1),
447 /*@-enummemuse@*/
448         RPMDB_FLAG_CHROOT       = (1 << 2)
449 /*@=enummemuse@*/
450 };
451
452 #ifdef __cplusplus
453 extern "C" {
454 #endif
455
456 /*@-exportlocal@*/
457 /** \ingroup db3
458  * Return new configured index database handle instance.
459  * @param rpmdb         rpm database
460  * @param rpmtag        rpm tag
461  * @return              index database handle
462  */
463 /*@unused@*/ /*@only@*/ /*@null@*/
464 dbiIndex db3New(rpmdb rpmdb, rpmTag rpmtag)
465         /*@globals rpmGlobalMacroContext @*/
466         /*@modifies rpmGlobalMacroContext @*/;
467
468 /** \ingroup db3
469  * Destroy index database handle instance.
470  * @param dbi           index database handle
471  * @return              NULL always
472  */
473 /*@null@*/
474 dbiIndex db3Free( /*@only@*/ /*@null@*/ dbiIndex dbi)
475         /*@*/;
476
477 /** \ingroup db3
478  * Format db3 open flags for debugging print.
479  * @param dbflags               db open flags
480  * @param print_dbenv_flags     format db env flags instead?
481  * @return                      formatted flags (static buffer)
482  */
483 /*@-redecl@*/
484 /*@exposed@*/
485 extern const char *const prDbiOpenFlags(int dbflags, int print_dbenv_flags)
486         /*@*/;
487 /*@=redecl@*/
488
489 /** \ingroup dbi
490  * Return handle for an index database.
491  * @param db            rpm database
492  * @param rpmtag        rpm tag
493  * @param flags         (unused)
494  * @return              index database handle
495  */
496 /*@only@*/ /*@null@*/ dbiIndex dbiOpen(/*@null@*/ rpmdb db, rpmTag rpmtag,
497                 unsigned int flags)
498         /*@globals rpmGlobalMacroContext, errno @*/
499         /*@modifies db, rpmGlobalMacroContext, errno @*/;
500
501 /*@-globuse -mustmod @*/ /* FIX: vector annotations */
502 /** \ingroup dbi
503  * Open a database cursor.
504  * @param dbi           index database handle
505  * @param txnid         database transaction handle
506  * @retval dbcp         returned database cursor
507  * @param flags         DB_WRITECURSOR if writing, or 0
508  * @return              0 on success
509  */
510 /*@unused@*/ static inline
511 int dbiCopen(dbiIndex dbi, /*@null@*/ DB_TXN * txnid,
512                 /*@out@*/ DBC ** dbcp, unsigned int flags)
513         /*@globals fileSystem @*/
514         /*@modifies dbi, *dbcp, fileSystem @*/
515 {
516     return (*dbi->dbi_vec->copen) (dbi, txnid, dbcp, flags);
517 }
518
519 /** \ingroup dbi
520  * Close a database cursor.
521  * @param dbi           index database handle
522  * @param dbcursor      database cursor
523  * @param flags         (unused)
524  * @return              0 on success
525  */
526 /*@unused@*/ static inline
527 int dbiCclose(dbiIndex dbi, /*@only@*/ DBC * dbcursor, unsigned int flags)
528         /*@globals fileSystem @*/
529         /*@modifies dbi, *dbcursor, fileSystem @*/
530 {
531     return (*dbi->dbi_vec->cclose) (dbi, dbcursor, flags);
532 }
533
534 /** \ingroup dbi
535  * Duplicate a database cursor.
536  * @param dbi           index database handle
537  * @param dbcursor      database cursor
538  * @retval dbcp         address of new database cursor
539  * @param flags         DB_POSITION for same position, 0 for uninitialized
540  * @return              0 on success
541  */
542 /*@unused@*/ static inline
543 int dbiCdup(dbiIndex dbi, DBC * dbcursor, /*@out@*/ DBC ** dbcp,
544                 unsigned int flags)
545         /*@modifies dbi, *dbcp @*/
546 {
547     return (*dbi->dbi_vec->cdup) (dbi, dbcursor, dbcp, flags);
548 }
549
550 /** \ingroup dbi
551  * Delete (key,data) pair(s) from index database.
552  * @param dbi           index database handle
553  * @param dbcursor      database cursor (NULL will use db->del)
554  * @param key           delete key value/length/flags
555  * @param data          delete data value/length/flags
556  * @param flags         (unused)
557  * @return              0 on success
558  */
559 /*@unused@*/ static inline
560 int dbiDel(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
561                 unsigned int flags)
562         /*@globals fileSystem, internalState @*/
563         /*@modifies dbi, *dbcursor, fileSystem, internalState @*/
564 {
565     int rc;
566     assert(key->data != NULL && key->size > 0);
567     (void) rpmswEnter(&dbi->dbi_rpmdb->db_delops, 0);
568     rc = (dbi->dbi_vec->cdel) (dbi, dbcursor, key, data, flags);
569     (void) rpmswExit(&dbi->dbi_rpmdb->db_delops, data->size);
570     return rc;
571 }
572
573 /** \ingroup dbi
574  * Retrieve (key,data) pair from index database.
575  * @param dbi           index database handle
576  * @param dbcursor      database cursor (NULL will use db->get)
577  * @param key           retrieve key value/length/flags
578  * @param data          retrieve data value/length/flags
579  * @param flags         (unused)
580  * @return              0 on success
581  */
582 /*@unused@*/ static inline
583 int dbiGet(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
584                 unsigned int flags)
585         /*@globals fileSystem, internalState @*/
586         /*@modifies dbi, *dbcursor, *key, *data, fileSystem, internalState @*/
587 {
588     int rc;
589     assert((flags == DB_NEXT) || (key->data != NULL && key->size > 0));
590     (void) rpmswEnter(&dbi->dbi_rpmdb->db_getops, 0);
591     rc = (dbi->dbi_vec->cget) (dbi, dbcursor, key, data, flags);
592     (void) rpmswExit(&dbi->dbi_rpmdb->db_getops, data->size);
593     return rc;
594 }
595
596 /** \ingroup dbi
597  * Retrieve (key,data) pair using dbcursor->c_pget.
598  * @param dbi           index database handle
599  * @param dbcursor      database cursor (NULL will use db->get)
600  * @param key           secondary retrieve key value/length/flags
601  * @param pkey          primary retrieve key value/length/flags
602  * @param data          primary retrieve data value/length/flags
603  * @param flags         DB_NEXT, DB_SET, or 0
604  * @return              0 on success
605  */
606 /*@unused@*/ static inline
607 int dbiPget(dbiIndex dbi, /*@null@*/ DBC * dbcursor,
608                 DBT * key, DBT * pkey, DBT * data, unsigned int flags)
609         /*@globals fileSystem, internalState @*/
610         /*@modifies dbi, *dbcursor, *key, *pkey, *data, fileSystem, internalState @*/
611 {
612     int rc;
613     assert((flags == DB_NEXT) || (key->data != NULL && key->size > 0));
614     (void) rpmswEnter(&dbi->dbi_rpmdb->db_getops, 0);
615     rc = (dbi->dbi_vec->cpget) (dbi, dbcursor, key, pkey, data, flags);
616     (void) rpmswExit(&dbi->dbi_rpmdb->db_getops, data->size);
617     return rc;
618 }
619
620 /** \ingroup dbi
621  * Store (key,data) pair in index database.
622  * @param dbi           index database handle
623  * @param dbcursor      database cursor (NULL will use db->put)
624  * @param key           store key value/length/flags
625  * @param data          store data value/length/flags
626  * @param flags         (unused)
627  * @return              0 on success
628  */
629 /*@unused@*/ static inline
630 int dbiPut(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
631                 unsigned int flags)
632         /*@globals fileSystem, internalState @*/
633         /*@modifies dbi, *dbcursor, *key, fileSystem, internalState @*/
634 {
635     int rc;
636     assert(key->data != NULL && key->size > 0 && data->data != NULL && data->size > 0);
637     (void) rpmswEnter(&dbi->dbi_rpmdb->db_putops, 0);
638     rc = (dbi->dbi_vec->cput) (dbi, dbcursor, key, data, flags);
639     (void) rpmswExit(&dbi->dbi_rpmdb->db_putops, data->size);
640     return rc;
641 }
642
643 /** \ingroup dbi
644  * Retrieve count of (possible) duplicate items.
645  * @param dbi           index database handle
646  * @param dbcursor      database cursor
647  * @param countp        address of count
648  * @param flags         (unused)
649  * @return              0 on success
650  */
651 /*@unused@*/ static inline
652 int dbiCount(dbiIndex dbi, DBC * dbcursor, /*@out@*/ unsigned int * countp,
653                 unsigned int flags)
654         /*@globals fileSystem @*/
655         /*@modifies *dbcursor, fileSystem @*/
656 {
657     return (*dbi->dbi_vec->ccount) (dbi, dbcursor, countp, flags);
658 }
659
660 /** \ingroup dbi
661  * Verify (and close) index database.
662  * @param dbi           index database handle
663  * @param flags         (unused)
664  * @return              0 on success
665  */
666 /*@unused@*/ static inline
667 int dbiVerify(/*@only@*/ dbiIndex dbi, unsigned int flags)
668         /*@globals fileSystem @*/
669         /*@modifies dbi, fileSystem @*/
670 {
671     dbi->dbi_verify_on_close = 1;
672     return (*dbi->dbi_vec->close) (dbi, flags);
673 }
674
675 /** \ingroup dbi
676  * Close index database.
677  * @param dbi           index database handle
678  * @param flags         (unused)
679  * @return              0 on success
680  */
681 /*@unused@*/ static inline
682 int dbiClose(/*@only@*/ dbiIndex dbi, unsigned int flags)
683         /*@globals fileSystem @*/
684         /*@modifies dbi, fileSystem @*/
685 {
686     return (*dbi->dbi_vec->close) (dbi, flags);
687 }
688
689 /** \ingroup dbi
690  * Flush pending operations to disk.
691  * @param dbi           index database handle
692  * @param flags         (unused)
693  * @return              0 on success
694  */
695 /*@unused@*/ static inline
696 int dbiSync (dbiIndex dbi, unsigned int flags)
697         /*@globals fileSystem @*/
698         /*@modifies fileSystem @*/
699 {
700     return (*dbi->dbi_vec->sync) (dbi, flags);
701 }
702
703 /** \ingroup dbi
704  * Associate secondary database with primary.
705  * @param dbi           index database handle
706  * @param dbisecondary  secondary index database handle
707  * @param callback      create secondary key from primary (NULL if DB_RDONLY)
708  * @param flags         DB_CREATE or 0
709  * @return              0 on success
710  */
711 /*@unused@*/ static inline
712 int dbiAssociate(dbiIndex dbi, dbiIndex dbisecondary,
713                 int (*callback) (DB *, const DBT *, const DBT *, DBT *),
714                 unsigned int flags)
715         /*@globals fileSystem @*/
716         /*@modifies dbi, fileSystem @*/
717 {
718     return (*dbi->dbi_vec->associate) (dbi, dbisecondary, callback, flags);
719 }
720
721 /** \ingroup dbi
722  * Return join cursor for list of cursors.
723  * @param dbi           index database handle
724  * @param curslist      NULL terminated list of database cursors
725  * @retval dbcp         address of join database cursor
726  * @param flags         DB_JOIN_NOSORT or 0
727  * @return              0 on success
728  */
729 /*@unused@*/ static inline
730 int dbiJoin(dbiIndex dbi, DBC ** curslist, /*@out@*/ DBC ** dbcp,
731                 unsigned int flags)
732         /*@globals fileSystem @*/
733         /*@modifies dbi, *dbcp, fileSystem @*/
734 {
735     return (*dbi->dbi_vec->join) (dbi, curslist, dbcp, flags);
736 }
737
738 /** \ingroup dbi
739  * Is database byte swapped?
740  * @param dbi           index database handle
741  * @return              0 same order, 1 swapped order
742  */
743 /*@unused@*/ static inline
744 int dbiByteSwapped(dbiIndex dbi)
745         /*@modifies dbi @*/
746 {
747     if (dbi->dbi_byteswapped == -1)
748         dbi->dbi_byteswapped = (*dbi->dbi_vec->byteswapped) (dbi);
749     return dbi->dbi_byteswapped;
750 }
751 /** \ingroup dbi
752  * Is database byte swapped?
753  * @param dbi           index database handle
754  * @param flags         DB_FAST_STAT or 0
755  * @return              0 on success
756  */
757 /*@unused@*/ static inline
758 int dbiStat(dbiIndex dbi, unsigned int flags)
759         /*@modifies dbi @*/
760 {
761     return (*dbi->dbi_vec->stat) (dbi, flags);
762 }
763 /*@=globuse =mustmod @*/
764
765 /*@=exportlocal@*/
766
767 /** \ingroup rpmdb
768  */
769 unsigned int rpmdbGetIteratorFileNum(rpmdbMatchIterator mi)
770         /*@*/;
771
772 /** \ingroup dbi
773  * Destroy set of index database items.
774  * @param set   set of index database items
775  * @return      NULL always
776  */
777 /*@null@*/ dbiIndexSet dbiFreeIndexSet(/*@only@*/ /*@null@*/ dbiIndexSet set)
778         /*@modifies set @*/;
779
780 /** \ingroup dbi
781  * Count items in index database set.
782  * @param set   set of index database items
783  * @return      number of items
784  */
785 unsigned int dbiIndexSetCount(dbiIndexSet set)
786         /*@*/;
787
788 /** \ingroup dbi
789  * Return record offset of header from element in index database set.
790  * @param set   set of index database items
791  * @param recno index of item in set
792  * @return      record offset of header
793  */
794 unsigned int dbiIndexRecordOffset(dbiIndexSet set, int recno)
795         /*@*/;
796
797 /** \ingroup dbi
798  * Return file index from element in index database set.
799  * @param set   set of index database items
800  * @param recno index of item in set
801  * @return      file index
802  */
803 unsigned int dbiIndexRecordFileNumber(dbiIndexSet set, int recno)
804         /*@*/;
805
806 /** \ingroup rpmdb
807  * Tags for which rpmdb indices will be built.
808  */
809 /*@-exportlocal@*/
810 /*@unchecked@*/
811 /*@only@*/ /*@null@*/ extern int * dbiTags;
812 /*@unchecked@*/
813 extern int dbiTagsMax;
814 /*@=exportlocal@*/
815
816 /** \ingroup rpmdb
817  * Unreference a database instance.
818  * @param db            rpm database
819  * @param msg
820  * @return              NULL always
821  */
822 /*@unused@*/ /*@null@*/
823 rpmdb rpmdbUnlink (/*@killref@*/ /*@only@*/ rpmdb db, const char * msg)
824         /*@modifies db @*/;
825
826 /** @todo Remove debugging entry from the ABI. */
827 /*@-exportlocal@*/
828 /*@null@*/
829 rpmdb XrpmdbUnlink (/*@killref@*/ /*@only@*/ rpmdb db, const char * msg,
830                 const char * fn, unsigned ln)
831         /*@modifies db @*/;
832 /*@=exportlocal@*/
833 #define rpmdbUnlink(_db, _msg)  XrpmdbUnlink(_db, _msg, __FILE__, __LINE__)
834
835 /** \ingroup rpmdb
836  * Reference a database instance.
837  * @param db            rpm database
838  * @param msg
839  * @return              new rpm database reference
840  */
841 /*@unused@*/
842 rpmdb rpmdbLink (rpmdb db, const char * msg)
843         /*@modifies db @*/;
844
845 /** @todo Remove debugging entry from the ABI. */
846 /*@-exportlocal@*/
847 rpmdb XrpmdbLink (rpmdb db, const char * msg,
848                 const char * fn, unsigned ln)
849         /*@modifies db @*/;
850 /*@=exportlocal@*/
851 #define rpmdbLink(_db, _msg)    XrpmdbLink(_db, _msg, __FILE__, __LINE__)
852
853 /** \ingroup rpmdb
854  * Open rpm database.
855  * @param prefix        path to top of install tree
856  * @retval dbp          address of rpm database
857  * @param mode          open(2) flags:  O_RDWR or O_RDONLY (O_CREAT also)
858  * @param perms         database permissions
859  * @return              0 on success
860  */
861 int rpmdbOpen (/*@null@*/ const char * prefix, /*@null@*/ /*@out@*/ rpmdb * dbp,
862                 int mode, int perms)
863         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
864         /*@modifies *dbp, rpmGlobalMacroContext, fileSystem, internalState @*/;
865
866 /** \ingroup rpmdb
867  * Initialize database.
868  * @param prefix        path to top of install tree
869  * @param perms         database permissions
870  * @return              0 on success
871  */
872 int rpmdbInit(/*@null@*/ const char * prefix, int perms)
873         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
874         /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
875
876 /** \ingroup rpmdb
877  * Verify database components.
878  * @param prefix        path to top of install tree
879  * @return              0 on success
880  */
881 int rpmdbVerify(/*@null@*/ const char * prefix)
882         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
883         /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
884
885 /**
886  * Close a single database index.
887  * @param db            rpm database
888  * @param rpmtag        rpm tag
889  * @return              0 on success
890  */
891 int rpmdbCloseDBI(/*@null@*/ rpmdb db, int rpmtag)
892         /*@globals fileSystem @*/
893         /*@modifies db, fileSystem @*/;
894
895 /** \ingroup rpmdb
896  * Close all database indices and free rpmdb.
897  * @param db            rpm database
898  * @return              0 on success
899  */
900 int rpmdbClose (/*@killref@*/ /*@only@*/ /*@null@*/ rpmdb db)
901         /*@globals fileSystem @*/
902         /*@modifies db, fileSystem @*/;
903
904 /** \ingroup rpmdb
905  * Sync all database indices.
906  * @param db            rpm database
907  * @return              0 on success
908  */
909 int rpmdbSync (/*@null@*/ rpmdb db)
910         /*@globals fileSystem @*/
911         /*@modifies fileSystem @*/;
912
913 /** \ingroup rpmdb
914  * Open all database indices.
915  * @param db            rpm database
916  * @return              0 on success
917  */
918 /*@-exportlocal@*/
919 int rpmdbOpenAll (/*@null@*/ rpmdb db)
920         /*@globals rpmGlobalMacroContext @*/
921         /*@modifies db, rpmGlobalMacroContext @*/;
922 /*@=exportlocal@*/
923
924 /** \ingroup rpmdb
925  * Return number of instances of package in rpm database.
926  * @param db            rpm database
927  * @param name          rpm package name
928  * @return              number of instances
929  */
930 int rpmdbCountPackages(/*@null@*/ rpmdb db, const char * name)
931         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
932         /*@modifies db, rpmGlobalMacroContext, fileSystem, internalState @*/;
933
934 /** \ingroup rpmdb
935  * Return header join key for current position of rpm database iterator.
936  * @param mi            rpm database iterator
937  * @return              current header join key
938  */
939 unsigned int rpmdbGetIteratorOffset(/*@null@*/ rpmdbMatchIterator mi)
940         /*@*/;
941
942 /** \ingroup rpmdb
943  * Return number of elements in rpm database iterator.
944  * @param mi            rpm database iterator
945  * @return              number of elements
946  */
947 int rpmdbGetIteratorCount(/*@null@*/ rpmdbMatchIterator mi)
948         /*@*/;
949
950 /** \ingroup rpmdb
951  * Append items to set of package instances to iterate.
952  * @param mi            rpm database iterator
953  * @param hdrNums       array of package instances
954  * @param nHdrNums      number of elements in array
955  * @return              0 on success, 1 on failure (bad args)
956  */
957 int rpmdbAppendIterator(/*@null@*/ rpmdbMatchIterator mi,
958                 /*@null@*/ const int * hdrNums, int nHdrNums)
959         /*@modifies mi @*/;
960
961 /** \ingroup rpmdb
962  * Remove items from set of package instances to iterate.
963  * @note Sorted hdrNums are always passed in rpmlib.
964  * @param mi            rpm database iterator
965  * @param hdrNums       array of package instances
966  * @param nHdrNums      number of elements in array
967  * @param sorted        is the array sorted? (array will be sorted on return)
968  * @return              0 on success, 1 on failure (bad args)
969  */
970 int rpmdbPruneIterator(/*@null@*/ rpmdbMatchIterator mi,
971                 /*@null@*/ int * hdrNums, int nHdrNums, int sorted)
972         /*@modifies mi, hdrNums @*/;
973
974 /** \ingroup rpmdb
975  * Add pattern to iterator selector.
976  * @param mi            rpm database iterator
977  * @param tag           rpm tag
978  * @param mode          type of pattern match
979  * @param pattern       pattern to match
980  * @return              0 on success
981  */
982 int rpmdbSetIteratorRE(/*@null@*/ rpmdbMatchIterator mi, rpmTag tag,
983                 rpmMireMode mode, /*@null@*/ const char * pattern)
984         /*@globals rpmGlobalMacroContext @*/
985         /*@modifies mi, mode, rpmGlobalMacroContext @*/;
986
987 /** \ingroup rpmdb
988  * Prepare iterator for lazy writes.
989  * @note Must be called before rpmdbNextIterator() with CDB model database.
990  * @param mi            rpm database iterator
991  * @param rewrite       new value of rewrite
992  * @return              previous value
993  */
994 int rpmdbSetIteratorRewrite(/*@null@*/ rpmdbMatchIterator mi, int rewrite)
995         /*@modifies mi @*/;
996
997 /** \ingroup rpmdb
998  * Modify iterator to mark header for lazy write on release.
999  * @param mi            rpm database iterator
1000  * @param modified      new value of modified
1001  * @return              previous value
1002  */
1003 int rpmdbSetIteratorModified(/*@null@*/ rpmdbMatchIterator mi, int modified)
1004         /*@modifies mi @*/;
1005
1006 /** \ingroup rpmdb
1007  * Modify iterator to verify retrieved header blobs.
1008  * @param mi            rpm database iterator
1009  * @param ts            transaction set
1010  * @param (*hdrchk)     headerCheck() vector
1011  * @return              0 always
1012  */
1013 int rpmdbSetHdrChk(/*@null@*/ rpmdbMatchIterator mi, /*@null@*/ rpmts ts,
1014                 /*@null@*/ rpmRC (*hdrchk) (rpmts ts, const void * uh, size_t uc, const char ** msg))
1015         /*@modifies mi @*/;
1016
1017 /** \ingroup rpmdb
1018  * Return database iterator.
1019  * @param db            rpm database
1020  * @param rpmtag        rpm tag
1021  * @param keyp          key data (NULL for sequential access)
1022  * @param keylen        key data length (0 will use strlen(keyp))
1023  * @return              NULL on failure
1024  */
1025 /*@only@*/ /*@null@*/
1026 rpmdbMatchIterator rpmdbInitIterator(/*@null@*/ rpmdb db, rpmTag rpmtag,
1027                         /*@null@*/ const void * keyp, size_t keylen)
1028         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
1029         /*@modifies db, rpmGlobalMacroContext, fileSystem, internalState @*/;
1030
1031 /** \ingroup rpmdb
1032  * Return next package header from iteration.
1033  * @param mi            rpm database iterator
1034  * @return              NULL on end of iteration.
1035  */
1036 /*@null@*/
1037 Header rpmdbNextIterator(/*@null@*/ rpmdbMatchIterator mi)
1038         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
1039         /*@modifies mi, rpmGlobalMacroContext, fileSystem, internalState @*/;
1040
1041 /** \ingroup rpmdb
1042  * Check rpmdb signal handler for trapped signal exit.
1043  */
1044 /*@mayexit@*/
1045 int rpmdbCheckSignals(void)
1046         /*@globals fileSystem, internalState @*/
1047         /*@modifies fileSystem, internalState @*/;
1048
1049 /** \ingroup rpmdb
1050  * Destroy rpm database iterator.
1051  * @param mi            rpm database iterator
1052  * @return              NULL always
1053  */
1054 /*@null@*/
1055 rpmdbMatchIterator rpmdbFreeIterator(/*@only@*/ /*@null@*/rpmdbMatchIterator mi)
1056         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
1057         /*@modifies mi, rpmGlobalMacroContext, fileSystem, internalState @*/;
1058
1059 /** \ingroup rpmdb
1060  * Add package header to rpm database and indices.
1061  * @param db            rpm database
1062  * @param iid           install transaction id (iid = 0 or -1 to skip)
1063  * @param h             header
1064  * @param ts            (unused) transaction set (or NULL)
1065  * @param (*hdrchk)     (unused) headerCheck() vector (or NULL)
1066  * @return              0 on success
1067  */
1068 int rpmdbAdd(/*@null@*/ rpmdb db, int iid, Header h, /*@null@*/ rpmts ts,
1069                 /*@null@*/ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, const char ** msg))
1070         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
1071         /*@modifies db, h, rpmGlobalMacroContext, fileSystem, internalState @*/;
1072
1073 /** \ingroup rpmdb
1074  * Remove package header from rpm database and indices.
1075  * @param db            rpm database
1076  * @param rid           (unused) remove transaction id (rid = 0 or -1 to skip)
1077  * @param hdrNum        package instance number in database
1078  * @param ts            (unused) transaction set (or NULL)
1079  * @param (*hdrchk)     (unused) headerCheck() vector (or NULL)
1080  * @return              0 on success
1081  */
1082 int rpmdbRemove(/*@null@*/ rpmdb db, /*@unused@*/ int rid, unsigned int hdrNum,
1083                 /*@null@*/ rpmts ts,
1084                 /*@null@*/ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, const char ** msg))
1085         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
1086         /*@modifies db, rpmGlobalMacroContext, fileSystem, internalState @*/;
1087
1088 /** \ingroup rpmdb
1089  * Rebuild database indices from package headers.
1090  * @param prefix        path to top of install tree
1091  * @param ts            transaction set (or NULL)
1092  * @param (*hdrchk)     headerCheck() vector (or NULL)
1093  * @return              0 on success
1094  */
1095 int rpmdbRebuild(/*@null@*/ const char * prefix, /*@null@*/ rpmts ts,
1096                 /*@null@*/ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, const char ** msg))
1097         /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
1098         /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
1099
1100 /**
1101  * Mergesort, same arguments as qsort(2).
1102  */
1103 /*@unused@*/
1104 int mergesort(void *base, size_t nmemb, size_t size,
1105                 int (*cmp) (const void *, const void *))
1106         /*@globals errno @*/
1107         /*@modifies base, errno @*/;
1108
1109 #ifdef __cplusplus
1110 }
1111 #endif
1112
1113 /*@=bounds@*/
1114 #endif  /* H_RPMDB */