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

Generated at Thu Sep 6 11:32:29 2001 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001