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