home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / rpm / oldrpmdb.c < prev    next >
C/C++ Source or Header  |  1997-09-17  |  14KB  |  579 lines

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