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

  1. #include <fcntl.h>
  2. #include <netinet/in.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6.  
  7. #include "errno.h"
  8. #include "header.h"
  9. #include "misc.h"
  10. #include "oldheader.h"
  11. #include "rpmlead.h"
  12. #include "rpmlib.h"
  13. #include "signature.h"
  14. #include "messages.h"
  15.  
  16. /* 0 = success */
  17. /* !0 = error */
  18. static int readOldHeader(int fd, Header * hdr, int * isSource);
  19.  
  20. /* 0 = success */
  21. /* 1 = bad magic */
  22. /* 2 = error */
  23. static int readPackageHeaders(int fd, struct rpmlead * leadPtr, 
  24.                   Header * sigs, Header * hdrPtr) {
  25.     Header hdrBlock;
  26.     struct rpmlead leadBlock;
  27.     Header * hdr;
  28.     struct rpmlead * lead;
  29.     struct oldrpmlead * oldLead;
  30.     int_8 arch;
  31.     int isSource;
  32.  
  33.     hdr = hdrPtr ? hdrPtr : &hdrBlock;
  34.     lead = leadPtr ? leadPtr : &leadBlock;
  35.  
  36.     oldLead = (struct oldrpmlead *) lead;
  37.  
  38.     if (readLead(fd, lead)) {
  39.     return 2;
  40.     }
  41.  
  42.     if (lead->magic[0] != RPMLEAD_MAGIC0 || lead->magic[1] != RPMLEAD_MAGIC1 ||
  43.     lead->magic[2] != RPMLEAD_MAGIC2 || lead->magic[3] != RPMLEAD_MAGIC3) {
  44.     return 1;
  45.     }
  46.  
  47.     if (lead->major == 1) {
  48.     rpmMessage(RPMMESS_DEBUG, "package is a version one package!\n");
  49.  
  50.     if (lead->type == RPMLEAD_SOURCE) {
  51.         rpmMessage(RPMMESS_DEBUG, "old style source package -- "
  52.             "I'll do my best\n");
  53.         oldLead->archiveOffset = ntohl(oldLead->archiveOffset);
  54.         rpmMessage(RPMMESS_DEBUG, "archive offset is %d\n", 
  55.             oldLead->archiveOffset);
  56.         lseek(fd, oldLead->archiveOffset, SEEK_SET);
  57.         
  58.         /* we can't put togeher a header for old format source packages,
  59.            there just isn't enough information there. We'll return
  60.            NULL <gulp> */
  61.  
  62.         *hdr = NULL;
  63.     } else {
  64.         rpmMessage(RPMMESS_DEBUG, "old style binary package\n");
  65.         readOldHeader(fd, hdr, &isSource);
  66.         arch = lead->archnum;
  67.         headerAddEntry(*hdr, RPMTAG_ARCH, RPM_INT8_TYPE, &arch, 1);
  68.         arch = 1;          /* old versions of RPM only supported Linux */
  69.         headerAddEntry(*hdr, RPMTAG_OS, RPM_INT8_TYPE, &arch, 1);
  70.     }
  71.     } else if (lead->major == 2 || lead->major == 3) {
  72.     if (rpmReadSignature(fd, sigs, lead->signature_type)) {
  73.        return 2;
  74.     }
  75.     *hdr = headerRead(fd, (lead->major >= 3) ?
  76.               HEADER_MAGIC_YES : HEADER_MAGIC_NO);
  77.     if (! *hdr) {
  78.         if (sigs) headerFree(*sigs);
  79.         return 2;
  80.     }
  81.     } else {
  82.     rpmError(RPMERR_NEWPACKAGE, "only packages with major numbers <= 3 are"
  83.         " supported by this version of RPM");
  84.     return 2;
  85.     } 
  86.  
  87.     if (!hdrPtr) headerFree(*hdr);
  88.     
  89.     return 0;
  90. }
  91.  
  92. /* 0 = success */
  93. /* 1 = bad magic */
  94. /* 2 = error */
  95. int rpmReadPackageInfo(int fd, Header * signatures, Header * hdr) {
  96.     return readPackageHeaders(fd, NULL, signatures, hdr);
  97. }
  98.  
  99. /* 0 = success */
  100. /* 1 = bad magic */
  101. /* 2 = error */
  102. int rpmReadPackageHeader(int fd, Header * hdr, int * isSource, int * major,
  103.           int * minor) {
  104.     int rc;
  105.     struct rpmlead lead;
  106.  
  107.     rc = readPackageHeaders(fd, &lead, NULL, hdr);
  108.     if (rc) return rc;
  109.    
  110.     if (isSource) *isSource = lead.type == RPMLEAD_SOURCE;
  111.     if (major) *major = lead.major;
  112.     if (minor) *minor = lead.minor;
  113.    
  114.     return 0;
  115. }
  116.  
  117. static int readOldHeader(int fd, Header * hdr, int * isSource) {
  118.     struct oldrpmHeader oldheader;
  119.     struct oldrpmHeaderSpec spec;
  120.     Header dbentry;
  121.     int_32 installTime = 0;
  122.     char ** fileList;
  123.     char ** fileMD5List;
  124.     char ** fileLinktoList;
  125.     int_32 * fileSizeList;
  126.     int_32 * fileUIDList;
  127.     int_32 * fileGIDList;
  128.     int_32 * fileMtimesList;
  129.     int_32 * fileFlagsList;
  130.     int_16 * fileModesList;
  131.     int_16 * fileRDevsList;
  132.     char * fileStatesList;
  133.     int i, j;
  134.     char ** unames, ** gnames;
  135.  
  136.     lseek(fd, 0, SEEK_SET);
  137.     if (oldhdrReadFromStream(fd, &oldheader)) {
  138.     return 1;
  139.     }
  140.  
  141.     if (oldhdrParseSpec(&oldheader, &spec)) {
  142.     return 1;
  143.     }
  144.  
  145.     dbentry = headerNew();
  146.     headerAddEntry(dbentry, RPMTAG_NAME, RPM_STRING_TYPE, oldheader.name, 1);
  147.     headerAddEntry(dbentry, RPMTAG_VERSION, RPM_STRING_TYPE, oldheader.version, 1);
  148.     headerAddEntry(dbentry, RPMTAG_RELEASE, RPM_STRING_TYPE, oldheader.release, 1);
  149.     headerAddEntry(dbentry, RPMTAG_DESCRIPTION, RPM_STRING_TYPE, 
  150.          spec.description, 1);
  151.     headerAddEntry(dbentry, RPMTAG_BUILDTIME, RPM_INT32_TYPE, &spec.buildTime, 1);
  152.     headerAddEntry(dbentry, RPMTAG_BUILDHOST, RPM_STRING_TYPE, spec.buildHost, 1);
  153.     headerAddEntry(dbentry, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &installTime, 1); 
  154.     headerAddEntry(dbentry, RPMTAG_DISTRIBUTION, RPM_STRING_TYPE, 
  155.          spec.distribution, 1);
  156.     headerAddEntry(dbentry, RPMTAG_VENDOR, RPM_STRING_TYPE, spec.vendor, 1);
  157.     headerAddEntry(dbentry, RPMTAG_SIZE, RPM_INT32_TYPE, &oldheader.size, 1);
  158.     headerAddEntry(dbentry, RPMTAG_COPYRIGHT, RPM_STRING_TYPE, spec.copyright, 1); 
  159.  
  160.     if (oldheader.group)
  161.     headerAddEntry(dbentry, RPMTAG_GROUP, RPM_STRING_TYPE, oldheader.group, 1);
  162.     else
  163.     headerAddEntry(dbentry, RPMTAG_GROUP, RPM_STRING_TYPE, "Unknown", 1);
  164.  
  165.     if (spec.prein) 
  166.     headerAddEntry(dbentry, RPMTAG_PREIN, RPM_STRING_TYPE, spec.prein, 1);
  167.     if (spec.preun) 
  168.     headerAddEntry(dbentry, RPMTAG_PREUN, RPM_STRING_TYPE, spec.preun, 1);
  169.     if (spec.postin) 
  170.     headerAddEntry(dbentry, RPMTAG_POSTIN, RPM_STRING_TYPE, spec.postin, 1);
  171.     if (spec.postun) 
  172.     headerAddEntry(dbentry, RPMTAG_POSTUN, RPM_STRING_TYPE, spec.postun, 1);
  173.  
  174.     *hdr = dbentry;
  175.  
  176.     if (spec.fileCount) {
  177.     /* some packages have no file lists */
  178.  
  179.     fileList = malloc(sizeof(char *) * spec.fileCount);
  180.     fileLinktoList = malloc(sizeof(char *) * spec.fileCount);
  181.     fileMD5List = malloc(sizeof(char *) * spec.fileCount);
  182.     fileSizeList = malloc(sizeof(int_32) * spec.fileCount);
  183.     fileUIDList = malloc(sizeof(int_32) * spec.fileCount);
  184.     fileGIDList = malloc(sizeof(int_32) * spec.fileCount);
  185.     fileMtimesList = malloc(sizeof(int_32) * spec.fileCount);
  186.     fileFlagsList = malloc(sizeof(int_32) * spec.fileCount);
  187.     fileModesList = malloc(sizeof(int_16) * spec.fileCount);
  188.     fileRDevsList = malloc(sizeof(int_16) * spec.fileCount);
  189.     fileStatesList = malloc(sizeof(char) * spec.fileCount);
  190.     unames = malloc(sizeof(char *) * spec.fileCount);
  191.     gnames = malloc(sizeof(char *) * spec.fileCount);
  192.  
  193.  
  194.     /* We also need to contstruct a file owner/group list. We'll just
  195.        hope the numbers all map to something, those that don't will
  196.        get set as 'id%d'. Not perfect, but this should be
  197.        good enough. */
  198.  
  199.     /* old packages were reverse sorted, new ones are forward sorted */
  200.     j = spec.fileCount - 1;
  201.     for (i = 0; i < spec.fileCount; i++, j--) {
  202.         fileList[j] = spec.files[i].path;
  203.         fileMD5List[j] = spec.files[i].md5;
  204.         fileSizeList[j] = spec.files[i].size;
  205.         fileUIDList[j] = spec.files[i].uid;
  206.         fileGIDList[j] = spec.files[i].gid;
  207.         fileMtimesList[j] = spec.files[i].mtime;
  208.         fileModesList[j] = spec.files[i].mode;
  209.         fileRDevsList[j] = spec.files[i].rdev;
  210.         fileStatesList[j] = spec.files[i].state;
  211.  
  212.         if (spec.files[i].linkto)
  213.         fileLinktoList[j] = spec.files[i].linkto;
  214.         else
  215.         fileLinktoList[j] = "";
  216.         
  217.         fileFlagsList[j] = 0;
  218.         if (spec.files[i].isdoc) 
  219.         fileFlagsList[j] |= RPMFILE_DOC;
  220.         if (spec.files[i].isconf)
  221.         fileFlagsList[j] |= RPMFILE_CONFIG;
  222.  
  223.         unames[j] = uidToUname(fileUIDList[j]);
  224.         if (unames[j])
  225.         unames[j] = strdup(unames[j]);
  226.         else {
  227.         unames[j] = malloc(20);
  228.         sprintf(unames[j], "uid%d", fileUIDList[j]);
  229.         }
  230.  
  231.         gnames[j] = gidToGname(fileGIDList[j]);
  232.         if (gnames[j])
  233.         gnames[j] = strdup(gnames[j]);
  234.         else {
  235.         gnames[j] = malloc(20);
  236.         sprintf(gnames[j], "gid%d", fileGIDList[j]);
  237.         }
  238.     }
  239.  
  240.     headerAddEntry(dbentry, RPMTAG_FILENAMES, RPM_STRING_ARRAY_TYPE, 
  241.             fileList, spec.fileCount);
  242.     headerAddEntry(dbentry, RPMTAG_FILELINKTOS, RPM_STRING_ARRAY_TYPE, 
  243.          fileLinktoList, spec.fileCount);
  244.     headerAddEntry(dbentry, RPMTAG_FILEMD5S, RPM_STRING_ARRAY_TYPE, 
  245.             fileMD5List, spec.fileCount);
  246.     headerAddEntry(dbentry, RPMTAG_FILESIZES, RPM_INT32_TYPE, fileSizeList, 
  247.              spec.fileCount);
  248.     headerAddEntry(dbentry, RPMTAG_FILEUIDS, RPM_INT32_TYPE, fileUIDList, 
  249.              spec.fileCount);
  250.     headerAddEntry(dbentry, RPMTAG_FILEGIDS, RPM_INT32_TYPE, fileGIDList, 
  251.              spec.fileCount);
  252.     headerAddEntry(dbentry, RPMTAG_FILEMTIMES, RPM_INT32_TYPE, 
  253.             fileMtimesList, spec.fileCount);
  254.     headerAddEntry(dbentry, RPMTAG_FILEFLAGS, RPM_INT32_TYPE, 
  255.             fileFlagsList, spec.fileCount);
  256.     headerAddEntry(dbentry, RPMTAG_FILEMODES, RPM_INT16_TYPE, 
  257.             fileModesList, spec.fileCount);
  258.     headerAddEntry(dbentry, RPMTAG_FILERDEVS, RPM_INT16_TYPE, 
  259.             fileRDevsList, spec.fileCount);
  260.     headerAddEntry(dbentry, RPMTAG_FILESTATES, RPM_INT8_TYPE, 
  261.             fileStatesList, spec.fileCount);
  262.     headerAddEntry(dbentry, RPMTAG_FILEUSERNAME, RPM_STRING_ARRAY_TYPE, 
  263.             unames, spec.fileCount);
  264.     headerAddEntry(dbentry, RPMTAG_FILEGROUPNAME, RPM_STRING_ARRAY_TYPE, 
  265.             gnames, spec.fileCount);
  266.  
  267.     free(fileList);
  268.     free(fileLinktoList);
  269.     free(fileMD5List);
  270.     free(fileSizeList);
  271.     free(fileUIDList);
  272.     free(fileGIDList);
  273.     free(fileMtimesList);
  274.     free(fileFlagsList);
  275.     free(fileModesList);
  276.     free(fileRDevsList);
  277.     free(fileStatesList);
  278.  
  279.     for (i = 0; i < spec.fileCount; i++) {
  280.         free(unames[i]);
  281.         free(gnames[i]);
  282.     }
  283.  
  284.     free(unames);
  285.     free(gnames);
  286.     }
  287.  
  288.     oldhdrFree(&oldheader);
  289.  
  290.     return 0;
  291. }
  292.