Added includes of miscfn.h
[tools/librpm-tizen.git] / oldrpmdb.c
1 #include "miscfn.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "rpmlib.h"
7 #include "rpm_malloc.h"
8 #include "messages.h"
9 #include "misc.h"
10 #include "oldrpmdb.h"
11
12 static int labelstrlistToLabelList(char * str, int length, 
13                                    struct oldrpmdbLabel ** list);
14 static char * getScript(char * which, struct oldrpmdb *oldrpmdb, 
15                         struct oldrpmdbLabel label);
16
17 static char * prefix = "/var/lib/rpm";
18
19 char * oldrpmdbLabelToLabelstr(struct oldrpmdbLabel label, int withFileNum) {
20     char * c;
21     char buffer[50];
22  
23     if (withFileNum && label.fileNumber > -1) 
24         c = malloc(strlen(label.name) + strlen(label.version) + 
25                    strlen(label.release) + 10);
26     else
27         c = malloc(strlen(label.name) + strlen(label.version) + 
28                    strlen(label.release) + 3);
29
30     strcpy(c, label.name);
31     strcat(c, ":");
32     strcat(c, label.version);
33     strcat(c, ":");
34     strcat(c, label.release);
35
36     if (withFileNum && label.fileNumber > -1)  {
37         sprintf(buffer, "%d", label.fileNumber);
38         strcat(c, ":");
39         strcat(c, buffer);
40     }
41
42     return c;
43 }
44
45 int oldrpmdbLabelstrToLabel(char * str, int length, struct oldrpmdbLabel * label) {
46     char * chptr;
47
48     label->freeType = RPMDB_FREENAME;
49     label->next = NULL;
50     label->name = malloc(length + 1);
51     if (!label->name) {
52         return 1;
53     }
54     memcpy(label->name, str, length);
55     label->name[length] = '\0';
56
57     chptr = label->name;
58     while (*chptr != ':') chptr++;
59     *chptr = '\0';
60     label->version = ++chptr;
61     while (*chptr != ':') chptr++;
62     *chptr = '\0';
63     label->release = chptr + 1;
64
65     label->fileNumber = -1;
66
67     /* there might be a path number tagged on to the end of this */
68     while ((chptr - label->name) < length && *chptr != ':') chptr++;
69     if ((chptr - label->name) < length) {
70         *chptr = '\0';
71         label->fileNumber = atoi(chptr + 1);
72     }
73
74     return 0;
75 }
76
77 static int labelstrlistToLabelList(char * str, int length, 
78                                    struct oldrpmdbLabel ** list) {
79     char * start, * chptr;
80     struct oldrpmdbLabel * head = NULL;
81     struct oldrpmdbLabel * tail = NULL;
82     struct oldrpmdbLabel * label;
83     
84     start = str;
85     for (chptr = start; (chptr - str) < length; chptr++) {
86         /* spaces following a space get ignored */
87         if (*chptr == ' ' && start < chptr) {
88             label = malloc(sizeof(struct oldrpmdbLabel));
89             if (!label) {
90                 oldrpmdbFreeLabelList(head);
91                 return 1;
92             }
93             if (oldrpmdbLabelstrToLabel(start, chptr - start, label)) {
94                 free(label);
95                 oldrpmdbFreeLabelList(head);
96                 return 1;
97             }
98
99             if (!head) {
100                 head = label;
101                 tail = label;
102             } else {
103                 tail->next = label;
104                 tail = tail->next;
105             }
106
107             start = chptr + 1;
108         }
109     }
110
111     /* a space on the end would break things horribly w/o this test */
112     if (start < chptr) {
113         label = malloc(sizeof(struct oldrpmdbLabel));
114         if (!label) {
115             oldrpmdbFreeLabelList(head);
116             return 1;
117         }
118         if (oldrpmdbLabelstrToLabel(start, chptr - start, label)) {
119             free(label);
120             oldrpmdbFreeLabelList(head);
121             return 1;
122         }
123
124         if (!head) {
125             head = label;
126             tail = label;
127         } else {
128             tail->next = label;
129             tail = tail->next;
130         }
131
132         start = chptr + 1;
133     }
134
135     *list = head;
136     return 0;
137 }
138
139 /* returns 0 on success, -1 on failure */
140 int oldrpmdbOpen(struct oldrpmdb * oldrpmdb) {
141     unsigned int gdbmFlags;
142     char path[255];
143     int goterr = 0;
144
145     oldrpmdb->rpmdbError = RPMDB_NONE;
146
147     gdbmFlags = GDBM_READER;
148
149     strcpy(path, prefix);
150     strcat(path, "/packages");
151     oldrpmdb->packages = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
152     if (!oldrpmdb->packages) {
153         rpmError(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
154         goterr = 1;
155     }
156
157     strcpy(path, prefix);
158     strcat(path, "/nameidx");
159     oldrpmdb->nameIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
160     if (!oldrpmdb->packages) {
161         rpmError(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
162         goterr = 1;
163     }
164
165     strcpy(path, prefix);
166     strcat(path, "/pathidx");
167     oldrpmdb->pathIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
168     if (!oldrpmdb->packages) {
169         rpmError(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
170         goterr = 1;
171     }
172
173     strcpy(path, prefix);
174     strcat(path, "/iconidx");
175     oldrpmdb->iconIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
176     if (!oldrpmdb->iconIndex) {
177         rpmError(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
178         goterr = 1;
179     }
180
181     strcpy(path, prefix);
182     strcat(path, "/groupindex");
183     oldrpmdb->groupIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
184     if (!oldrpmdb->packages) {
185         rpmError(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
186         goterr = 1;
187     }
188
189     strcpy(path, prefix);
190     strcat(path, "/postidx");
191     oldrpmdb->postIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
192     if (!oldrpmdb->postIndex) {
193         rpmError(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
194         goterr = 1;
195     }
196
197     if (goterr) {
198         oldrpmdbClose(oldrpmdb);
199         return -1;
200     }
201
202     return 0;
203 }
204
205 void oldrpmdbClose(struct oldrpmdb * oldrpmdb) {
206     gdbm_close(oldrpmdb->packages);
207     gdbm_close(oldrpmdb->nameIndex);
208     gdbm_close(oldrpmdb->pathIndex);
209     gdbm_close(oldrpmdb->postIndex);
210     gdbm_close(oldrpmdb->groupIndex);
211     gdbm_close(oldrpmdb->iconIndex);
212 }
213
214 struct oldrpmdbLabel * oldrpmdbGetAllLabels(struct oldrpmdb * oldrpmdb) {
215     datum rec;
216
217     struct oldrpmdbLabel * head = NULL;
218     struct oldrpmdbLabel * tail = NULL;
219     struct oldrpmdbLabel * label;
220
221     oldrpmdb->rpmdbError = RPMDB_NONE;
222
223     rec = gdbm_firstkey(oldrpmdb->packages);
224     while (rec.dptr) {
225         label = malloc(sizeof(struct oldrpmdbLabel));
226         if (!label) {
227             oldrpmdbFreeLabelList(head);
228             oldrpmdb->rpmdbError = RPMDB_NO_MEMORY;
229             return NULL;
230         }
231         if (oldrpmdbLabelstrToLabel(rec.dptr, rec.dsize, label)) {
232             free(label);
233             oldrpmdbFreeLabelList(head);
234             oldrpmdb->rpmdbError = RPMDB_NO_MEMORY;
235             return NULL;
236         }
237
238         if (!head) {
239             head = label;
240             tail = label;
241         } else {
242             tail->next = label;
243             tail = tail->next;
244         }
245
246         rec = gdbm_nextkey(oldrpmdb->packages, rec);
247     }
248
249     return head;
250 }
251
252 struct oldrpmdbLabel * oldrpmdbFindPackagesByFile(struct oldrpmdb * oldrpmdb, char * path) {
253     datum rec;
254     datum key;
255     struct oldrpmdbLabel * list;
256
257     oldrpmdb->rpmdbError = RPMDB_NONE;
258
259     key.dptr = path;
260     key.dsize = strlen(path);
261     rec = gdbm_fetch(oldrpmdb->pathIndex, key);
262     
263     if (!rec.dptr) 
264         return NULL;
265     if (labelstrlistToLabelList(rec.dptr, rec.dsize, &list)) {
266         free(rec.dptr);
267         oldrpmdb->rpmdbError = RPMDB_NO_MEMORY;
268         return NULL;
269     }
270     free(rec.dptr);
271
272     return list;
273 }
274
275 struct oldrpmdbLabel * oldrpmdbFindPackagesByLabel(struct oldrpmdb * oldrpmdb, 
276                                              struct oldrpmdbLabel label)
277
278 /* the Name has to be here. The version/release fields optionally
279    restrict the search. Either will do. */
280
281 {
282     datum rec;
283     datum key;
284     struct oldrpmdbLabel * list;
285     struct oldrpmdbLabel * prospect;
286     struct oldrpmdbLabel * parent;
287     int bad;
288
289     oldrpmdb->rpmdbError = RPMDB_NONE;
290
291     key.dptr = label.name;
292     key.dsize = strlen(label.name);
293     rec = gdbm_fetch(oldrpmdb->nameIndex, key);
294     
295     if (!rec.dptr) 
296         return NULL;
297     if (labelstrlistToLabelList(rec.dptr, rec.dsize, &list)) {
298         free(rec.dptr);
299         oldrpmdb->rpmdbError = RPMDB_NO_MEMORY;
300         return NULL;
301     }
302     free(rec.dptr);
303
304     prospect = list;
305     parent = NULL;
306     while (prospect) {
307         bad = 0;
308         if (label.version && strcmp(label.version, prospect->version))
309             bad = 1;
310         else if (label.release && strcmp(label.release, prospect->release))
311             bad = 1;
312
313         if (bad) {
314             oldrpmdbFreeLabel(*prospect);
315             if (!parent) {
316                 list = prospect->next;
317                 free(prospect);
318                 prospect = list;
319             } else {
320                 parent->next = prospect->next;
321                 free(prospect);
322                 prospect = parent->next;
323             }
324         } else {
325             prospect = prospect->next;
326         }
327     }
328
329     return list;
330 }
331
332 struct oldrpmdbLabel oldrpmdbMakeLabel(char * name, char * version, char * release,
333                                  int fileNumber, enum oldrpmdbFreeType freeType) {
334     struct oldrpmdbLabel label;
335
336     label.next = NULL;
337     label.freeType = freeType;
338     label.name = name;
339     label.version = version;
340     label.release = release;
341     label.fileNumber = fileNumber;
342
343     return label;
344 }
345
346 void oldrpmdbFreeLabelList(struct oldrpmdbLabel * list) {
347     struct oldrpmdbLabel * saved;
348
349     while (list) {
350         oldrpmdbFreeLabel(*list);
351         saved = list->next;
352         free(list);
353         list = saved;
354     }
355 }
356
357 void oldrpmdbFreeLabel(struct oldrpmdbLabel label) {
358     if (label.freeType == RPMDB_NOFREE) return;
359
360     free(label.name);
361     if (label.freeType == RPMDB_FREEALL) {
362         free(label.version);
363         free(label.release);
364     }
365 }
366
367 /* Returns NULL on error */
368 char * oldrpmdbGetPackageGroup(struct oldrpmdb * oldrpmdb, struct oldrpmdbLabel label) {
369     datum key, rec;
370     char * g;
371     
372     key.dptr = label.name;
373     key.dsize = strlen(label.name);
374     
375     rec = gdbm_fetch(oldrpmdb->groupIndex, key);
376     if (!rec.dptr) {
377         return strdup("Unknown");
378     }
379     
380     g = malloc(rec.dsize + 1);
381     strncpy(g, rec.dptr, rec.dsize);
382     g[rec.dsize] = '\0';
383     free(rec.dptr);
384
385     return g;
386 }
387
388 static char * getScript(char * which, struct oldrpmdb *oldrpmdb, 
389                         struct oldrpmdbLabel label) {
390     datum key, rec;
391     char * labelstr, * l;
392
393     labelstr = oldrpmdbLabelToLabelstr(label, 0);
394     labelstr = realloc(labelstr, strlen(labelstr) + 10);
395     strcat(labelstr, ":");
396     strcat(labelstr, which);
397
398     key.dptr = labelstr;
399     key.dsize = strlen(labelstr);
400     
401     rec = gdbm_fetch(oldrpmdb->postIndex, key);
402     free(labelstr);
403
404     if (!rec.dptr) return NULL;
405
406     l = malloc(rec.dsize + 1);
407     strncpy(l, rec.dptr, rec.dsize);
408     l[rec.dsize] = '\0';
409
410     free(rec.dptr);
411
412     return l;
413 }
414
415 char *oldrpmdbGetPackagePostun (struct oldrpmdb *oldrpmdb, 
416                                 struct oldrpmdbLabel label) {
417     return getScript("post", oldrpmdb, label);
418 }
419
420 char *oldrpmdbGetPackagePreun (struct oldrpmdb *oldrpmdb, 
421                                 struct oldrpmdbLabel label) {
422     return getScript("pre", oldrpmdb, label);
423 }
424
425 /* Returns NULL on error or if no icon exists */
426 char * oldrpmdbGetPackageGif(struct oldrpmdb * oldrpmdb, 
427                              struct oldrpmdbLabel label, int * size) {
428     datum key, rec;
429     char * labelstr;
430
431     labelstr = oldrpmdbLabelToLabelstr(label, 0);
432     
433     key.dptr = labelstr;
434     key.dsize = strlen(labelstr);
435     
436     rec = gdbm_fetch(oldrpmdb->iconIndex, key);
437     free(labelstr);
438     if (!rec.dptr) {
439         return NULL;
440     }
441
442     *size = rec.dsize;
443
444     return rec.dptr;
445 }
446
447 /* return 0 on success, 1 on failure */
448 int oldrpmdbGetPackageInfo(struct oldrpmdb * oldrpmdb, struct oldrpmdbLabel label,
449                         struct oldrpmdbPackageInfo * pinfo) {
450     char * labelstr;
451     char ** list, ** prelist;
452     char ** strptr;
453     datum key, rec;
454     int i, j;
455
456     labelstr = oldrpmdbLabelToLabelstr(label, 0);
457
458     rpmMessage(RPMMESS_DEBUG, "pulling %s from database\n", labelstr);
459
460     key.dptr = labelstr;
461     key.dsize = strlen(labelstr);
462     
463     rec = gdbm_fetch(oldrpmdb->packages, key);
464     if (!rec.dptr) {
465         rpmError(RPMERR_OLDDBCORRUPT, "package not found in database");
466         return 1;
467     }
468
469     free(labelstr);
470
471     list = splitString(rec.dptr, rec.dsize, '\1');
472     free(rec.dptr);
473
474     pinfo->version = strdup(list[1]); 
475     pinfo->release = strdup(list[2]); 
476     /* list[3] == "1" always */
477     pinfo->name = malloc(strlen(list[0]) + strlen(list[4]) + 2);
478     strcpy(pinfo->name, list[0]);
479     if (strlen(list[4])) {
480         strcat(pinfo->name, "-");
481         strcat(pinfo->name, list[4]);
482     }
483     pinfo->labelstr = malloc(strlen(pinfo->name) + strlen(pinfo->version) +
484                              strlen(pinfo->release) + 3);
485     strcpy(pinfo->labelstr, pinfo->name);
486     strcat(pinfo->labelstr, ":");
487     strcat(pinfo->labelstr, pinfo->version);
488     strcat(pinfo->labelstr, ":");
489     strcat(pinfo->labelstr, pinfo->release);
490
491     pinfo->preamble = strdup(list[5]);
492     pinfo->installTime = atoi(list[6]);
493     pinfo->fileCount = atoi(list[7]);
494     
495     prelist = splitString(pinfo->preamble, strlen(pinfo->preamble), '\n');
496
497     /* these are optional */
498     pinfo->distribution = NULL;
499     pinfo->vendor = NULL;
500     pinfo->description = NULL;
501     pinfo->copyright = NULL;
502
503     for (strptr = prelist; *strptr; strptr++) {
504         if (!strncasecmp("Description: ", *strptr, 13))
505             pinfo->description = strdup((*strptr) + 13);
506         else if (!strncasecmp("Copyright: ", *strptr, 11))
507             pinfo->copyright = strdup((*strptr) + 11);
508         else if (!strncasecmp("Distribution: ", *strptr, 14))
509             pinfo->distribution = strdup((*strptr) + 14);
510         else if (!strncasecmp("Vendor: ", *strptr, 8))
511             pinfo->vendor = strdup((*strptr) + 8);
512         else if (!strncasecmp("size: ", *strptr, 6))
513             pinfo->size = atoi((*strptr) + 6);
514         else if (!strncasecmp("BuildDate: ", *strptr, 11))
515             pinfo->buildTime =atoi((*strptr) + 11);
516         else if (!strncasecmp("BuildHost: ", *strptr, 11))
517             pinfo->buildHost = strdup((*strptr) + 11);
518     }
519     freeSplitString(prelist);
520
521     if (!pinfo->vendor) pinfo->vendor = strdup("");
522     if (!pinfo->description) pinfo->description = strdup("");
523     if (!pinfo->distribution) pinfo->distribution = strdup("");
524     if (!pinfo->copyright) {
525         pinfo->copyright = strdup("");
526         printf("no copyright!\n");
527     }
528
529     pinfo->files = malloc(sizeof(struct oldrpmFileInfo) * pinfo->fileCount);
530
531     j = 8;
532     for (i = 0; i < pinfo->fileCount; i++) {
533         oldrpmfileFromInfoLine(list[j], list[j + 1], list[j + 2],
534                             &pinfo->files[i]);
535         j += 3;
536     }
537
538     freeSplitString(list);
539                 
540     return 0;
541 }
542
543 void oldrpmdbFreePackageInfo(struct oldrpmdbPackageInfo package) {
544     int i;
545
546     free(package.version);
547     free(package.release);
548     free(package.name);
549     free(package.labelstr);
550     free(package.buildHost);
551     free(package.vendor);
552     free(package.description);
553     free(package.copyright);
554     free(package.distribution);
555     free(package.preamble);
556
557     for (i = 0; i < package.fileCount; i++) {
558         oldrpmfileFree(&package.files[i]);
559     }
560
561     free(package.files);
562 }
563
564 int oldrpmdbLabelCmp(struct oldrpmdbLabel * one, struct oldrpmdbLabel * two) {
565     int i;
566
567     if ((i = strcmp(one->name, two->name)))
568         return i;
569     else if ((i = strcmp(one->version, two->version)))
570         return i;
571     else
572         return strcmp(one->release, two->release);
573 }
574
575 void oldrpmdbSetPrefix(char * new) {
576     prefix = new;
577 }