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 }

Generated on Sat Oct 28 09:19:06 2006 for rpm by  doxygen 1.4.7