6 #include "rpm_malloc.h"
11 static int labelstrlistToLabelList(char * str, int length,
12 struct rpmdbLabel ** list);
13 static char * prefix = "/var/lib/rpm";
15 char * rpmdbLabelToLabelstr(struct rpmdbLabel label, int withFileNum) {
19 if (withFileNum && label.fileNumber > -1)
20 c = malloc(strlen(label.name) + strlen(label.version) +
21 strlen(label.release) + 10);
23 c = malloc(strlen(label.name) + strlen(label.version) +
24 strlen(label.release) + 3);
26 strcpy(c, label.name);
28 strcat(c, label.version);
30 strcat(c, label.release);
32 if (withFileNum && label.fileNumber > -1) {
33 sprintf(buffer, "%d", label.fileNumber);
41 int rpmdbLabelstrToLabel(char * str, int length, struct rpmdbLabel * label) {
44 label->freeType = RPMDB_FREENAME;
46 label->name = malloc(length + 1);
50 memcpy(label->name, str, length);
51 label->name[length] = '\0';
54 while (*chptr != ':') chptr++;
56 label->version = ++chptr;
57 while (*chptr != ':') chptr++;
59 label->release = chptr + 1;
61 label->fileNumber = -1;
63 /* there might be a path number tagged on to the end of this */
64 while ((chptr - label->name) < length && *chptr != ':') chptr++;
65 if ((chptr - label->name) < length) {
67 label->fileNumber = atoi(chptr + 1);
73 static int labelstrlistToLabelList(char * str, int length,
74 struct rpmdbLabel ** list) {
75 char * start, * chptr;
76 struct rpmdbLabel * head = NULL;
77 struct rpmdbLabel * tail = NULL;
78 struct rpmdbLabel * label;
81 for (chptr = start; (chptr - str) < length; chptr++) {
82 /* spaces following a space get ignored */
83 if (*chptr == ' ' && start < chptr) {
84 label = malloc(sizeof(struct rpmdbLabel));
86 rpmdbFreeLabelList(head);
89 if (rpmdbLabelstrToLabel(start, chptr - start, label)) {
91 rpmdbFreeLabelList(head);
107 /* a space on the end would break things horribly w/o this test */
109 label = malloc(sizeof(struct rpmdbLabel));
111 rpmdbFreeLabelList(head);
114 if (rpmdbLabelstrToLabel(start, chptr - start, label)) {
116 rpmdbFreeLabelList(head);
135 /* returns 0 on success, -1 on failure */
136 int rpmdbOpen(struct rpmdb * rpmdb) {
137 unsigned int gdbmFlags;
141 rpmdb->rpmdbError = RPMDB_NONE;
143 gdbmFlags = GDBM_READER;
145 strcpy(path, prefix);
146 strcat(path, "/packages");
147 rpmdb->packages = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
148 if (!rpmdb->packages) {
149 error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
153 strcpy(path, prefix);
154 strcat(path, "/nameidx");
155 rpmdb->nameIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
156 if (!rpmdb->packages) {
157 error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
161 strcpy(path, prefix);
162 strcat(path, "/pathidx");
163 rpmdb->pathIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
164 if (!rpmdb->packages) {
165 error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
169 strcpy(path, prefix);
170 strcat(path, "/iconidx");
171 rpmdb->iconIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
172 if (!rpmdb->iconIndex) {
173 error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
177 strcpy(path, prefix);
178 strcat(path, "/groupindex");
179 rpmdb->groupIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
180 if (!rpmdb->packages) {
181 error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
185 strcpy(path, prefix);
186 strcat(path, "/postidx");
187 rpmdb->postIndex = gdbm_open(path, 1024, gdbmFlags, 0644, NULL);
188 if (!rpmdb->postIndex) {
189 error(RPMERR_GDBMOPEN, path, gdbm_strerror(gdbm_errno));
201 void rpmdbClose(struct rpmdb * rpmdb) {
202 gdbm_close(rpmdb->packages);
203 gdbm_close(rpmdb->nameIndex);
204 gdbm_close(rpmdb->pathIndex);
205 gdbm_close(rpmdb->postIndex);
206 gdbm_close(rpmdb->groupIndex);
207 gdbm_close(rpmdb->iconIndex);
210 struct rpmdbLabel * rpmdbGetAllLabels(struct rpmdb * rpmdb) {
213 struct rpmdbLabel * head = NULL;
214 struct rpmdbLabel * tail = NULL;
215 struct rpmdbLabel * label;
217 rpmdb->rpmdbError = RPMDB_NONE;
219 rec = gdbm_firstkey(rpmdb->packages);
221 label = malloc(sizeof(struct rpmdbLabel));
223 rpmdbFreeLabelList(head);
224 rpmdb->rpmdbError = RPMDB_NO_MEMORY;
227 if (rpmdbLabelstrToLabel(rec.dptr, rec.dsize, label)) {
229 rpmdbFreeLabelList(head);
230 rpmdb->rpmdbError = RPMDB_NO_MEMORY;
242 rec = gdbm_nextkey(rpmdb->packages, rec);
248 struct rpmdbLabel * rpmdbFindPackagesByFile(struct rpmdb * rpmdb, char * path) {
251 struct rpmdbLabel * list;
253 rpmdb->rpmdbError = RPMDB_NONE;
256 key.dsize = strlen(path);
257 rec = gdbm_fetch(rpmdb->pathIndex, key);
261 if (labelstrlistToLabelList(rec.dptr, rec.dsize, &list)) {
263 rpmdb->rpmdbError = RPMDB_NO_MEMORY;
271 struct rpmdbLabel * rpmdbFindPackagesByLabel(struct rpmdb * rpmdb,
272 struct rpmdbLabel label)
274 /* the Name has to be here. The version/release fields optionally
275 restrict the search. Either will do. */
280 struct rpmdbLabel * list;
281 struct rpmdbLabel * prospect;
282 struct rpmdbLabel * parent;
285 rpmdb->rpmdbError = RPMDB_NONE;
287 key.dptr = label.name;
288 key.dsize = strlen(label.name);
289 rec = gdbm_fetch(rpmdb->nameIndex, key);
293 if (labelstrlistToLabelList(rec.dptr, rec.dsize, &list)) {
295 rpmdb->rpmdbError = RPMDB_NO_MEMORY;
304 if (label.version && strcmp(label.version, prospect->version))
306 else if (label.release && strcmp(label.release, prospect->release))
310 rpmdbFreeLabel(*prospect);
312 list = prospect->next;
316 parent->next = prospect->next;
318 prospect = parent->next;
321 prospect = prospect->next;
328 struct rpmdbLabel rpmdbMakeLabel(char * name, char * version, char * release,
329 int fileNumber, enum rpmdbFreeType freeType) {
330 struct rpmdbLabel label;
333 label.freeType = freeType;
335 label.version = version;
336 label.release = release;
337 label.fileNumber = fileNumber;
342 void rpmdbFreeLabelList(struct rpmdbLabel * list) {
343 struct rpmdbLabel * saved;
346 rpmdbFreeLabel(*list);
353 void rpmdbFreeLabel(struct rpmdbLabel label) {
354 if (label.freeType == RPMDB_NOFREE) return;
357 if (label.freeType == RPMDB_FREEALL) {
363 /* Returns NULL on error */
364 char * rpmdbGetPackageGroup(struct rpmdb * rpmdb, struct rpmdbLabel label) {
368 key.dptr = label.name;
369 key.dsize = strlen(label.name);
371 rec = gdbm_fetch(rpmdb->groupIndex, key);
373 return strdup("Unknown");
376 g = malloc(rec.dsize + 1);
377 strncpy(g, rec.dptr, rec.dsize);
384 /* return 0 on success, 1 on failure */
385 int rpmdbGetPackageInfo(struct rpmdb * rpmdb, struct rpmdbLabel label,
386 struct rpmdbPackageInfo * pinfo) {
388 char ** list, ** prelist;
393 labelstr = rpmdbLabelToLabelstr(label, 0);
395 message(MESS_DEBUG, "pulling %s from database\n", labelstr);
398 key.dsize = strlen(labelstr);
400 rec = gdbm_fetch(rpmdb->packages, key);
402 error(RPMERR_OLDDBCORRUPT, "package not found in database");
408 list = splitString(rec.dptr, rec.dsize, '\1');
411 pinfo->version = strdup(list[1]);
412 pinfo->release = strdup(list[2]);
413 /* list[3] == "1" always */
414 pinfo->name = malloc(strlen(list[0]) + strlen(list[4]) + 2);
415 strcpy(pinfo->name, list[0]);
416 if (strlen(list[4])) {
417 strcat(pinfo->name, "-");
418 strcat(pinfo->name, list[4]);
420 pinfo->labelstr = malloc(strlen(pinfo->name) + strlen(pinfo->version) +
421 strlen(pinfo->release) + 3);
422 strcpy(pinfo->labelstr, pinfo->name);
423 strcat(pinfo->labelstr, ":");
424 strcat(pinfo->labelstr, pinfo->version);
425 strcat(pinfo->labelstr, ":");
426 strcat(pinfo->labelstr, pinfo->release);
428 pinfo->preamble = strdup(list[5]);
429 pinfo->installTime = atoi(list[6]);
430 pinfo->fileCount = atoi(list[7]);
432 prelist = splitString(pinfo->preamble, strlen(pinfo->preamble), '\n');
434 /* these are optional */
435 pinfo->distribution = NULL;
436 pinfo->vendor = NULL;
437 pinfo->description = NULL;
438 pinfo->copyright = NULL;
440 for (strptr = prelist; *strptr; strptr++) {
441 if (!strncasecmp("Description: ", *strptr, 13))
442 pinfo->description = strdup((*strptr) + 13);
443 else if (!strncasecmp("Copyright: ", *strptr, 11))
444 pinfo->copyright = strdup((*strptr) + 11);
445 else if (!strncasecmp("Distribution: ", *strptr, 14))
446 pinfo->distribution = strdup((*strptr) + 14);
447 else if (!strncasecmp("Vendor: ", *strptr, 8))
448 pinfo->vendor = strdup((*strptr) + 8);
449 else if (!strncasecmp("size: ", *strptr, 6))
450 pinfo->size = atoi((*strptr) + 6);
451 else if (!strncasecmp("BuildDate: ", *strptr, 11))
452 pinfo->buildTime =atoi((*strptr) + 11);
453 else if (!strncasecmp("BuildHost: ", *strptr, 11))
454 pinfo->buildHost = strdup((*strptr) + 11);
456 freeSplitString(prelist);
458 if (!pinfo->vendor) pinfo->vendor = strdup("");
459 if (!pinfo->description) pinfo->description = strdup("");
460 if (!pinfo->distribution) pinfo->distribution = strdup("");
461 if (!pinfo->copyright) {
462 pinfo->copyright = strdup("");
463 printf("no copyright!\n");
466 pinfo->files = malloc(sizeof(struct rpmFileInfo) * pinfo->fileCount);
469 for (i = 0; i < pinfo->fileCount; i++) {
470 rpmfileFromInfoLine(list[j], list[j + 1], list[j + 2],
475 freeSplitString(list);
480 void rpmdbFreePackageInfo(struct rpmdbPackageInfo package) {
483 free(package.version);
484 free(package.release);
486 free(package.labelstr);
487 free(package.buildHost);
488 free(package.vendor);
489 free(package.description);
490 free(package.copyright);
491 free(package.distribution);
492 free(package.preamble);
494 for (i = 0; i < package.fileCount; i++) {
495 rpmfileFree(&package.files[i]);
501 int rpmdbLabelCmp(struct rpmdbLabel * one, struct rpmdbLabel * two) {
504 if ((i = strcmp(one->name, two->name)))
506 else if ((i = strcmp(one->version, two->version)))
509 return strcmp(one->release, two->release);
512 void rpmdbSetPrefix(char * new) {