Main Page Modules Data Structures File List Data Fields Globals Related Pages

# lib/package.c

Go to the documentation of this file.

    00001
    00005 #include "system.h"
    00006
    00007 #include <netinet/in.h>
    00008
    00009 #include <rpmlib.h>
    00010
    00011 #include "misc.h"
    00012 #include "rpmlead.h"
    00013 #include "signature.h"
    00014 #include "debug.h"
    00015
    00016 #define alloca_strdup(_s)       strcpy(alloca(strlen(_s)+1), (_s))
    00017
    00018 /*@access Header@*/             /* XXX compared with NULL */
    00019
    00020 void headerMergeLegacySigs(Header h, const Header sig)
    00021 {
    00022     HFD_t hfd = (HFD_t) headerFreeData;
    00023     HAE_t hae = (HAE_t) headerAddEntry;
    00024     HeaderIterator hi;
    00025     int_32 tag, type, count;
    00026     const void * ptr;
    00027     int xx;
    00028
    00029     /*@-mods@*/ /* FIX: undocumented modification of sig */
    00030     for (hi = headerInitIterator(sig);
    00031     /*@=mods@*/
    00032         headerNextIterator(hi, &tag, &type, &ptr, &count);
    00033         ptr = hfd(ptr, type))
    00034     {
    00035         switch (tag) {
    00036         case RPMSIGTAG_SIZE:
    00037             tag = RPMTAG_SIGSIZE;
    00038             /*@switchbreak@*/ break;
    00039         case RPMSIGTAG_LEMD5_1:
    00040             tag = RPMTAG_SIGLEMD5_1;
    00041             /*@switchbreak@*/ break;
    00042         case RPMSIGTAG_PGP:
    00043             tag = RPMTAG_SIGPGP;
    00044             /*@switchbreak@*/ break;
    00045         case RPMSIGTAG_LEMD5_2:
    00046             tag = RPMTAG_SIGLEMD5_2;
    00047             /*@switchbreak@*/ break;
    00048         case RPMSIGTAG_MD5:
    00049             tag = RPMTAG_SIGMD5;
    00050             /*@switchbreak@*/ break;
    00051         case RPMSIGTAG_GPG:
    00052             tag = RPMTAG_SIGGPG;
    00053             /*@switchbreak@*/ break;
    00054         case RPMSIGTAG_PGP5:
    00055             tag = RPMTAG_SIGPGP5;
    00056             /*@switchbreak@*/ break;
    00057         case RPMSIGTAG_PAYLOADSIZE:
    00058             tag = RPMTAG_ARCHIVESIZE;
    00059             /*@switchbreak@*/ break;
    00060         case RPMSIGTAG_SHA1:
    00061         case RPMSIGTAG_DSA:
    00062         case RPMSIGTAG_RSA:
    00063         default:
    00064             if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
    00065                 continue;
    00066             /*@switchbreak@*/ break;
    00067         }
    00068         if (ptr == NULL) continue;      /* XXX can't happen */
    00069         if (!headerIsEntry(h, tag))
    00070             xx = hae(h, tag, type, ptr, count);
    00071     }
    00072     hi = headerFreeIterator(hi);
    00073 }
    00074
    00075 Header headerRegenSigHeader(const Header h)
    00076 {
    00077     HFD_t hfd = (HFD_t) headerFreeData;
    00078     Header sig = rpmNewSignature();
    00079     HeaderIterator hi;
    00080     int_32 tag, stag, type, count;
    00081     const void * ptr;
    00082     int xx;
    00083
    00084     /*@-mods@*/ /* FIX: undocumented modification of h */
    00085     for (hi = headerInitIterator(h);
    00086     /*@=mods@*/
    00087         headerNextIterator(hi, &tag, &type, &ptr, &count);
    00088         ptr = hfd(ptr, type))
    00089     {
    00090         switch (tag) {
    00091         case RPMTAG_SIGSIZE:
    00092             stag = RPMSIGTAG_SIZE;
    00093             /*@switchbreak@*/ break;
    00094         case RPMTAG_SIGLEMD5_1:
    00095             stag = RPMSIGTAG_LEMD5_1;
    00096             /*@switchbreak@*/ break;
    00097         case RPMTAG_SIGPGP:
    00098             stag = RPMSIGTAG_PGP;
    00099             /*@switchbreak@*/ break;
    00100         case RPMTAG_SIGLEMD5_2:
    00101             stag = RPMSIGTAG_LEMD5_2;
    00102             /*@switchbreak@*/ break;
    00103         case RPMTAG_SIGMD5:
    00104             stag = RPMSIGTAG_MD5;
    00105             /*@switchbreak@*/ break;
    00106         case RPMTAG_SIGGPG:
    00107             stag = RPMSIGTAG_GPG;
    00108             /*@switchbreak@*/ break;
    00109         case RPMTAG_SIGPGP5:
    00110             stag = RPMSIGTAG_PGP5;
    00111             /*@switchbreak@*/ break;
    00112         case RPMTAG_ARCHIVESIZE:
    00113             stag = RPMSIGTAG_PAYLOADSIZE;
    00114             /*@switchbreak@*/ break;
    00115         case RPMTAG_SHA1HEADER:
    00116         case RPMTAG_DSAHEADER:
    00117         case RPMTAG_RSAHEADER:
    00118         default:
    00119             if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
    00120                 continue;
    00121             stag = tag;
    00122             /*@switchbreak@*/ break;
    00123         }
    00124         if (ptr == NULL) continue;      /* XXX can't happen */
    00125         if (!headerIsEntry(sig, stag))
    00126             xx = headerAddEntry(sig, stag, type, ptr, count);
    00127     }
    00128     hi = headerFreeIterator(hi);
    00129     return sig;
    00130 }
    00131
    00140 static rpmRC readPackageHeaders(FD_t fd,
    00141                 /*@null@*/ /*@out@*/ struct rpmlead * leadPtr,
    00142                 /*@null@*/ /*@out@*/ Header * sigs,
    00143                 /*@null@*/ /*@out@*/ Header * hdrPtr)
    00144         /*@modifies fd, *leadPtr, *sigs, *hdrPtr @*/
    00145 {
    00146     Header hdrBlock;
    00147     struct rpmlead leadBlock;
    00148     Header * hdr = NULL;
    00149     struct rpmlead * lead;
    00150     char * defaultPrefix;
    00151     struct stat sb;
    00152     rpmRC rc;
    00153
    00154     hdr = hdrPtr ? hdrPtr : &hdrBlock;
    00155     lead = leadPtr ? leadPtr : &leadBlock;
    00156
    00157     memset(&sb, 0, sizeof(sb));
    00158     (void) fstat(Fileno(fd), &sb);
    00159     /* if fd points to a socket, pipe, etc, sb.st_size is *always* zero */
    00160     if (S_ISREG(sb.st_mode) && sb.st_size < sizeof(*lead)) return 1;
    00161
    00162     if (readLead(fd, lead))
    00163         return RPMRC_FAIL;
    00164
    00165     if (lead->magic[0] != RPMLEAD_MAGIC0 || lead->magic[1] != RPMLEAD_MAGIC1 ||
    00166         lead->magic[2] != RPMLEAD_MAGIC2 || lead->magic[3] != RPMLEAD_MAGIC3) {
    00167         return RPMRC_BADMAGIC;
    00168     }
    00169
    00170     switch (lead->major) {
    00171     case 1:
    00172         rpmError(RPMERR_NEWPACKAGE,
    00173             _("packaging version 1 is not supported by this version of RPM\n"));
    00174         return RPMRC_FAIL;
    00175         /*@notreached@*/ break;
    00176     case 2:
    00177     case 3:
    00178     case 4:
    00179         rc = rpmReadSignature(fd, sigs, lead->signature_type);
    00180         if (rc == RPMRC_FAIL)
    00181             return rc;
    00182         *hdr = headerRead(fd, (lead->major >= 3)
    00183                           ? HEADER_MAGIC_YES : HEADER_MAGIC_NO);
    00184         if (*hdr == NULL) {
    00185             if (sigs != NULL)
    00186                 *sigs = rpmFreeSignature(*sigs);
    00187             return RPMRC_FAIL;
    00188         }
    00189
    00190         /*
    00191          * We don't use these entries (and rpm >= 2 never has) and they are
    00192          * pretty misleading. Let's just get rid of them so they don't confuse
    00193          * anyone.
    00194          */
    00195         if (headerIsEntry(*hdr, RPMTAG_FILEUSERNAME))
    00196             (void) headerRemoveEntry(*hdr, RPMTAG_FILEUIDS);
    00197         if (headerIsEntry(*hdr, RPMTAG_FILEGROUPNAME))
    00198             (void) headerRemoveEntry(*hdr, RPMTAG_FILEGIDS);
    00199
    00200         /*
    00201          * We switched the way we do relocateable packages. We fix some of
    00202          * it up here, though the install code still has to be a bit
    00203          * careful. This fixup makes queries give the new values though,
    00204          * which is quite handy.
    00205          */
    00206         if (headerGetEntry(*hdr, RPMTAG_DEFAULTPREFIX, NULL,
    00207                            (void **) &defaultPrefix, NULL))
    00208         {
    00209             defaultPrefix =
    00210                 stripTrailingChar(alloca_strdup(defaultPrefix), '/');
    00211             (void) headerAddEntry(*hdr, RPMTAG_PREFIXES, RPM_STRING_ARRAY_TYPE,
    00212                            &defaultPrefix, 1);
    00213         }
    00214
    00215         /*
    00216          * The file list was moved to a more compressed format which not
    00217          * only saves memory (nice), but gives fingerprinting a nice, fat
    00218          * speed boost (very nice). Go ahead and convert old headers to
    00219          * the new style (this is a noop for new headers).
    00220          */
    00221         if (lead->major < 4)
    00222             compressFilelist(*hdr);
    00223
    00224     /* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
    00225         if (lead->type == RPMLEAD_SOURCE) {
    00226             int_32 one = 1;
    00227             if (!headerIsEntry(*hdr, RPMTAG_SOURCEPACKAGE))
    00228                 (void)headerAddEntry(*hdr, RPMTAG_SOURCEPACKAGE, RPM_INT32_TYPE,
    00229                                 &one, 1);
    00230         } else if (lead->major < 4) {
    00231             /* Retrofit "Provide: name = EVR" for binary packages. */
    00232             providePackageNVR(*hdr);
    00233         }
    00234         break;
    00235
    00236     default:
    00237         rpmError(RPMERR_NEWPACKAGE, _("only packaging with major numbers <= 4 "
    00238                 "is supported by this version of RPM\n"));
    00239         return RPMRC_FAIL;
    00240         /*@notreached@*/ break;
    00241     }
    00242
    00243     if (hdrPtr == NULL)
    00244         *hdr = headerFree(*hdr);
    00245
    00246     return RPMRC_OK;
    00247 }
    00248
    00249 rpmRC rpmReadPackageInfo(FD_t fd, Header * sigp, Header * hdrp)
    00250 {
    00251     rpmRC rc = readPackageHeaders(fd, NULL, sigp, hdrp);
    00252     if (rc != RPMRC_OK)
    00253         return rc;
    00254     if (hdrp == NULL || sigp == NULL)
    00255         return rc;
    00256     if (*hdrp && *sigp)
    00257         headerMergeLegacySigs(*hdrp, *sigp);
    00258     return rc;
    00259 }
    00260
    00261 rpmRC rpmReadPackageHeader(FD_t fd, Header * hdrp, int * isSource, int * major,
    00262                   int * minor)
    00263 {
    00264     struct rpmlead lead;
    00265     Header sig = NULL;
    00266     rpmRC rc = readPackageHeaders(fd, &lead, &sig, hdrp);
    00267
    00268     if (rc != RPMRC_OK)
    00269         goto exit;
    00270
    00271     if (hdrp && *hdrp && sig) {
    00272         headerMergeLegacySigs(*hdrp, sig);
    00273         sig = rpmFreeSignature(sig);
    00274     }
    00275
    00276     if (isSource) *isSource = lead.type == RPMLEAD_SOURCE;
    00277     /*@-mods@*/
    00278     if (major) *major = lead.major;
    00279     if (minor) *minor = lead.minor;
    00280     /*@=mods@*/
    00281
    00282 exit:
    00283     return rc;
    00284 }