00001
00005 #include "system.h"
00006
00007 #if !defined(__LCLINT__)
00008 #include <netinet/in.h>
00009 #endif
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
00021
00022
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;
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;
00082 if (!headerIsEntry(sig, stag))
00083 (void) headerAddEntry(sig, stag, type, ptr, count);
00084 }
00085 hi = headerFreeIterator(hi);
00086 return sig;
00087 }
00088
00089
00098 static rpmRC readPackageHeaders(FD_t fd,
00099 struct rpmlead * leadPtr,
00100 Header * sigs,
00101 Header * hdrPtr)
00102
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
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 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
00150
00151
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
00160
00161
00162
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
00175
00176
00177
00178
00179 if (lead->major < 4)
00180 compressFilelist(*hdr);
00181
00182
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
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 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
00236 if (major) *major = lead.major;
00237 if (minor) *minor = lead.minor;
00238
00239
00240 exit:
00241 return rc;
00242 }