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

Generated at Thu Apr 19 15:29:43 2001 for rpm by doxygen1.2.6-20010408 written by Dimitri van Heesch, © 1997-2001