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
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
00030 for (hi = headerInitIterator(sig);
00031
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 break;
00039 case RPMSIGTAG_LEMD5_1:
00040 tag = RPMTAG_SIGLEMD5_1;
00041 break;
00042 case RPMSIGTAG_PGP:
00043 tag = RPMTAG_SIGPGP;
00044 break;
00045 case RPMSIGTAG_LEMD5_2:
00046 tag = RPMTAG_SIGLEMD5_2;
00047 break;
00048 case RPMSIGTAG_MD5:
00049 tag = RPMTAG_SIGMD5;
00050 break;
00051 case RPMSIGTAG_GPG:
00052 tag = RPMTAG_SIGGPG;
00053 break;
00054 case RPMSIGTAG_PGP5:
00055 tag = RPMTAG_SIGPGP5;
00056 break;
00057 default:
00058 if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
00059 continue;
00060 break;
00061 }
00062 if (ptr == NULL) continue;
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
00079 for (hi = headerInitIterator(h);
00080
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 break;
00088 case RPMTAG_SIGLEMD5_1:
00089 stag = RPMSIGTAG_LEMD5_1;
00090 break;
00091 case RPMTAG_SIGPGP:
00092 stag = RPMSIGTAG_PGP;
00093 break;
00094 case RPMTAG_SIGLEMD5_2:
00095 stag = RPMSIGTAG_LEMD5_2;
00096 break;
00097 case RPMTAG_SIGMD5:
00098 stag = RPMSIGTAG_MD5;
00099 break;
00100 case RPMTAG_SIGGPG:
00101 stag = RPMSIGTAG_GPG;
00102 break;
00103 case RPMTAG_SIGPGP5:
00104 stag = RPMSIGTAG_PGP5;
00105 break;
00106 default:
00107 if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
00108 continue;
00109 stag = tag;
00110 break;
00111 }
00112 if (ptr == NULL) continue;
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 struct rpmlead * leadPtr,
00130 Header * sigs,
00131 Header * hdrPtr)
00132
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
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 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
00180
00181
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
00190
00191
00192
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
00205
00206
00207
00208
00209 if (lead->major < 4)
00210 compressFilelist(*hdr);
00211
00212
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
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 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
00266 if (major) *major = lead.major;
00267 if (minor) *minor = lead.minor;
00268
00269
00270 exit:
00271 return rc;
00272 }