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 }

Generated at Tue Dec 23 04:54:11 2003 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001