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 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 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 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, struct rpmlead * leadPtr,
00089 Header * sigs, Header *hdrPtr)
00090
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
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 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
00138
00139
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
00147
00148
00149
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
00160
00161
00162
00163
00164 if (lead->major < 4)
00165 compressFilelist(*hdr);
00166
00167
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
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 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 }