42fd7a2b36a7424cde14e720e68c8d373915d43d
[tools/librpm-tizen.git] / lib / rpmgi.c
1 /*@-modfilesys@*/
2 /** \ingroup rpmio
3  * \file rpmio/rpmio.c
4  */
5 #include "system.h"
6
7 #define _RPMGI_INTERNAL
8 #include <rpmgi.h>
9
10 #include <rpmdb.h>
11
12 #include "debug.h"
13
14 /*@unchecked@*/
15 int _rpmgi_debug = 0;
16
17 rpmgi XrpmgiUnlink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
18 {
19     if (gi == NULL) return NULL;
20
21 if (_rpmgi_debug && msg != NULL)
22 fprintf(stderr, "--> gi %p -- %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
23
24     gi->nrefs--;
25     return NULL;
26 }
27
28 rpmgi XrpmgiLink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
29 {
30     if (gi == NULL) return NULL;
31     gi->nrefs++;
32
33 if (_rpmgi_debug && msg != NULL)
34 fprintf(stderr, "--> gi %p ++ %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
35
36     /*@-refcounttrans@*/ return gi; /*@=refcounttrans@*/
37 }
38
39 rpmgi rpmgiFree(rpmgi gi)
40 {
41     if (gi == NULL)
42         return NULL;
43
44     if (gi->nrefs > 1)
45         return rpmgiUnlink(gi, NULL);
46
47 if (_rpmgi_debug < 0)
48 fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
49
50     (void) rpmgiUnlink(gi, NULL);
51
52     switch (gi->tag) {
53     default:
54     case RPMGI_RPMDB:
55         break;
56     case RPMGI_HDLIST:
57         break;
58     case RPMGI_ARGLIST:
59         break;
60     case RPMGI_FTSWALK:
61         break;
62     }
63
64     if (gi->ftsp != NULL) {
65         int xx;
66         xx = Fts_close(gi->ftsp);
67         gi->ftsp = NULL;
68         gi->fts = NULL;
69     }
70     gi->mi = rpmdbFreeIterator(gi->mi);
71     gi->ts = rpmtsFree(gi->ts);
72
73     memset(gi, 0, sizeof(*gi));         /* XXX trash and burn */
74     gi = _free(gi);
75     return NULL;
76 }
77
78 rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen)
79 {
80     rpmgi gi = xcalloc(1, sizeof(*gi));
81
82     if (gi == NULL)
83         return NULL;
84
85     gi->ts = rpmtsLink(ts, NULL);
86     gi->tag = tag;
87     gi->i = -1;
88
89     switch (gi->tag) {
90     default:
91     case RPMGI_RPMDB:
92         gi->mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
93
94 if (_rpmgi_debug < 0)
95 fprintf(stderr, "*** gi %p\t%p\n", gi, gi->mi);
96
97         break;
98     case RPMGI_HDLIST:
99         break;
100     case RPMGI_ARGLIST:
101     case RPMGI_FTSWALK:
102     {   char *const * argv = keyp;
103         unsigned flags = keylen;
104
105         gi->argv = argv;
106         gi->argc = 0;
107         if (argv != NULL)
108         while (*argv++ != NULL)
109            gi->argc++;
110         gi->ftsOpts = flags;
111
112 if (_rpmgi_debug < 0)
113 fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
114
115     }   break;
116     }
117
118     gi = rpmgiLink(gi, NULL);
119
120     return gi;
121 }
122
123 static int indent = 2;
124
125 static const char * ftsInfoStrings[] = {
126     "UNKNOWN",
127     "D",
128     "DC",
129     "DEFAULT",
130     "DNR",
131     "DOT",
132     "DP",
133     "ERR",
134     "F",
135     "INIT",
136     "NS",
137     "NSOK",
138     "SL",
139     "SLNONE",
140     "W",
141 };
142
143 static const char * ftsInfoStr(int fts_info) {
144     if (!(fts_info >= 1 && fts_info <= 14))
145         fts_info = 0;
146     return ftsInfoStrings[ fts_info ];
147 }
148
149 const char * rpmgiNext(/*@null@*/ rpmgi gi)
150         /*@modifies gi @*/
151 {
152     const char * val = NULL;
153     Header h = NULL;
154
155     if (gi != NULL && ++gi->i >= 0)
156     switch (gi->tag) {
157     default:
158     case RPMGI_RPMDB:
159         h = rpmdbNextIterator(gi->mi);
160         if (h != NULL) {
161             const char * fmt = "%{NAME}-%{VERSION}-%{RELEASE}";
162             val = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, NULL);
163         } else {
164             gi->mi = rpmdbFreeIterator(gi->mi);
165             gi->i = -1;
166         }
167         break;
168     case RPMGI_HDLIST:
169         break;
170     case RPMGI_ARGLIST:
171         if (gi->argv != NULL && gi->argv[gi->i] != NULL) {
172 if (_rpmgi_debug  < 0)
173 fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]);
174             val = xstrdup(gi->argv[gi->i]);
175         } else
176             gi->i = -1;
177         break;
178     case RPMGI_FTSWALK:
179         if (gi->ftsp == NULL && gi->i == 0)
180             gi->ftsp = Fts_open(gi->argv, gi->ftsOpts, NULL);
181
182         while (val == NULL && (gi->fts = Fts_read(gi->ftsp)) != NULL) {
183             FTSENT * fts = gi->fts;
184
185 if (_rpmgi_debug < 0)
186 fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
187                 indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
188                 fts->fts_name);
189
190             switch (fts->fts_info) {
191             case FTS_F:
192             case FTS_SL:
193 if (_rpmgi_debug  < 0)
194 fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->ftsp, gi->i, fts->fts_path);
195                 val = xstrdup(fts->fts_path);
196                 break;
197             default:
198                 break;
199             }
200         }
201         if (gi->fts == NULL && gi->ftsp != NULL) {
202             int xx;
203             xx = Fts_close(gi->ftsp);
204             gi->ftsp = NULL;
205             gi->i = -1;
206         }
207         break;
208     }
209
210     return val;
211 }
212 /*@=modfilesys@*/