7 #include "rpm_malloc.h"
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);
17 static char * prefix = "/var/lib/rpm";
19 char * oldrpmdbLabelToLabelstr(struct oldrpmdbLabel label, int withFileNum) {
23 if (withFileNum && label.fileNumber > -1)
24 c = malloc(strlen(label.name) + strlen(label.version) +
25 strlen(label.release) + 10);
27 c = malloc(strlen(label.name) + strlen(label.version) +
28 strlen(label.release) + 3);
30 strcpy(c, label.name);
32 strcat(c, label.version);
34 strcat(c, label.release);
36 if (withFileNum && label.fileNumber > -1) {
37 sprintf(buffer, "%d", label.fileNumber);
45 int oldrpmdbLabelstrToLabel(char * str, int length, struct oldrpmdbLabel * label) {
48 label->freeType = RPMDB_FREENAME;
50 label->name = malloc(length + 1);
54 memcpy(label->name, str, length);
55 label->name[length] = '\0';
58 while (*chptr != ':') chptr++;
60 label->version = ++chptr;
61 while (*chptr != ':') chptr++;
63 label->release = chptr + 1;
65 label->fileNumber = -1;
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) {
71 label->fileNumber = atoi(chptr + 1);
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;
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));
90 oldrpmdbFreeLabelList(head);
93 if (oldrpmdbLabelstrToLabel(start, chptr - start, label)) {
95 oldrpmdbFreeLabelList(head);
111 /* a space on the end would break things horribly w/o this test */
113 label = malloc(sizeof(struct oldrpmdbLabel));
115 oldrpmdbFreeLabelList(head);
118 if (oldrpmdbLabelstrToLabel(start, chptr - start, label)) {
120 oldrpmdbFreeLabelList(head);
139 /* returns 0 on success, -1 on failure */
140 int oldrpmdbOpen(struct oldrpmdb * oldrpmdb) {
141 unsigned int gdbmFlags;
145 oldrpmdb->rpmdbError = RPMDB_NONE;
147 gdbmFlags = GDBM_READER;
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));
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));
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));
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));
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));
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));
198 oldrpmdbClose(oldrpmdb);
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);
214 struct oldrpmdbLabel * oldrpmdbGetAllLabels(struct oldrpmdb * oldrpmdb) {
217 struct oldrpmdbLabel * head = NULL;
218 struct oldrpmdbLabel * tail = NULL;
219 struct oldrpmdbLabel * label;
221 oldrpmdb->rpmdbError = RPMDB_NONE;
223 rec = gdbm_firstkey(oldrpmdb->packages);
225 label = malloc(sizeof(struct oldrpmdbLabel));
227 oldrpmdbFreeLabelList(head);
228 oldrpmdb->rpmdbError = RPMDB_NO_MEMORY;
231 if (oldrpmdbLabelstrToLabel(rec.dptr, rec.dsize, label)) {
233 oldrpmdbFreeLabelList(head);
234 oldrpmdb->rpmdbError = RPMDB_NO_MEMORY;
246 rec = gdbm_nextkey(oldrpmdb->packages, rec);
252 struct oldrpmdbLabel * oldrpmdbFindPackagesByFile(struct oldrpmdb * oldrpmdb, char * path) {
255 struct oldrpmdbLabel * list;
257 oldrpmdb->rpmdbError = RPMDB_NONE;
260 key.dsize = strlen(path);
261 rec = gdbm_fetch(oldrpmdb->pathIndex, key);
265 if (labelstrlistToLabelList(rec.dptr, rec.dsize, &list)) {
267 oldrpmdb->rpmdbError = RPMDB_NO_MEMORY;
275 struct oldrpmdbLabel * oldrpmdbFindPackagesByLabel(struct oldrpmdb * oldrpmdb,
276 struct oldrpmdbLabel label)
278 /* the Name has to be here. The version/release fields optionally
279 restrict the search. Either will do. */
284 struct oldrpmdbLabel * list;
285 struct oldrpmdbLabel * prospect;
286 struct oldrpmdbLabel * parent;
289 oldrpmdb->rpmdbError = RPMDB_NONE;
291 key.dptr = label.name;
292 key.dsize = strlen(label.name);
293 rec = gdbm_fetch(oldrpmdb->nameIndex, key);
297 if (labelstrlistToLabelList(rec.dptr, rec.dsize, &list)) {
299 oldrpmdb->rpmdbError = RPMDB_NO_MEMORY;
308 if (label.version && strcmp(label.version, prospect->version))
310 else if (label.release && strcmp(label.release, prospect->release))
314 oldrpmdbFreeLabel(*prospect);
316 list = prospect->next;
320 parent->next = prospect->next;
322 prospect = parent->next;
325 prospect = prospect->next;
332 struct oldrpmdbLabel oldrpmdbMakeLabel(char * name, char * version, char * release,
333 int fileNumber, enum oldrpmdbFreeType freeType) {
334 struct oldrpmdbLabel label;
337 label.freeType = freeType;
339 label.version = version;
340 label.release = release;
341 label.fileNumber = fileNumber;
346 void oldrpmdbFreeLabelList(struct oldrpmdbLabel * list) {
347 struct oldrpmdbLabel * saved;
350 oldrpmdbFreeLabel(*list);
357 void oldrpmdbFreeLabel(struct oldrpmdbLabel label) {
358 if (label.freeType == RPMDB_NOFREE) return;
361 if (label.freeType == RPMDB_FREEALL) {
367 /* Returns NULL on error */
368 char * oldrpmdbGetPackageGroup(struct oldrpmdb * oldrpmdb, struct oldrpmdbLabel label) {
372 key.dptr = label.name;
373 key.dsize = strlen(label.name);
375 rec = gdbm_fetch(oldrpmdb->groupIndex, key);
377 return strdup("Unknown");
380 g = malloc(rec.dsize + 1);
381 strncpy(g, rec.dptr, rec.dsize);
388 static char * getScript(char * which, struct oldrpmdb *oldrpmdb,
389 struct oldrpmdbLabel label) {
391 char * labelstr, * l;
393 labelstr = oldrpmdbLabelToLabelstr(label, 0);
394 labelstr = realloc(labelstr, strlen(labelstr) + 10);
395 strcat(labelstr, ":");
396 strcat(labelstr, which);
399 key.dsize = strlen(labelstr);
401 rec = gdbm_fetch(oldrpmdb->postIndex, key);
404 if (!rec.dptr) return NULL;
406 l = malloc(rec.dsize + 1);
407 strncpy(l, rec.dptr, rec.dsize);
415 char *oldrpmdbGetPackagePostun (struct oldrpmdb *oldrpmdb,
416 struct oldrpmdbLabel label) {
417 return getScript("post", oldrpmdb, label);
420 char *oldrpmdbGetPackagePreun (struct oldrpmdb *oldrpmdb,
421 struct oldrpmdbLabel label) {
422 return getScript("pre", oldrpmdb, label);
425 /* Returns NULL on error or if no icon exists */
426 char * oldrpmdbGetPackageGif(struct oldrpmdb * oldrpmdb,
427 struct oldrpmdbLabel label, int * size) {
431 labelstr = oldrpmdbLabelToLabelstr(label, 0);
434 key.dsize = strlen(labelstr);
436 rec = gdbm_fetch(oldrpmdb->iconIndex, key);
447 /* return 0 on success, 1 on failure */
448 int oldrpmdbGetPackageInfo(struct oldrpmdb * oldrpmdb, struct oldrpmdbLabel label,
449 struct oldrpmdbPackageInfo * pinfo) {
451 char ** list, ** prelist;
456 labelstr = oldrpmdbLabelToLabelstr(label, 0);
458 rpmMessage(RPMMESS_DEBUG, "pulling %s from database\n", labelstr);
461 key.dsize = strlen(labelstr);
463 rec = gdbm_fetch(oldrpmdb->packages, key);
465 rpmError(RPMERR_OLDDBCORRUPT, "package not found in database");
471 list = splitString(rec.dptr, rec.dsize, '\1');
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]);
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);
491 pinfo->preamble = strdup(list[5]);
492 pinfo->installTime = atoi(list[6]);
493 pinfo->fileCount = atoi(list[7]);
495 prelist = splitString(pinfo->preamble, strlen(pinfo->preamble), '\n');
497 /* these are optional */
498 pinfo->distribution = NULL;
499 pinfo->vendor = NULL;
500 pinfo->description = NULL;
501 pinfo->copyright = NULL;
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);
519 freeSplitString(prelist);
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");
529 pinfo->files = malloc(sizeof(struct oldrpmFileInfo) * pinfo->fileCount);
532 for (i = 0; i < pinfo->fileCount; i++) {
533 oldrpmfileFromInfoLine(list[j], list[j + 1], list[j + 2],
538 freeSplitString(list);
543 void oldrpmdbFreePackageInfo(struct oldrpmdbPackageInfo package) {
546 free(package.version);
547 free(package.release);
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);
557 for (i = 0; i < package.fileCount; i++) {
558 oldrpmfileFree(&package.files[i]);
564 int oldrpmdbLabelCmp(struct oldrpmdbLabel * one, struct oldrpmdbLabel * two) {
567 if ((i = strcmp(one->name, two->name)))
569 else if ((i = strcmp(one->version, two->version)))
572 return strcmp(one->release, two->release);
575 void oldrpmdbSetPrefix(char * new) {