#define DEP_GREATER (1 << 2)
#define DEP_EQUAL (1 << 3)
#define DEP_STRONG (1 << 27)
-#define DEP_PRE ((1 << 6) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12))
+#define DEP_PRE_IN ((1 << 6) | (1 << 9) | (1 << 10))
+#define DEP_PRE_UN ((1 << 6) | (1 << 11) | (1 << 12))
#define FILEFLAG_GHOST (1 << 6)
int cnt;
int dcnt;
unsigned char *dp;
- int forcebinary; /* sigh */
+ int forcebinary; /* sigh, see rh#478907 */
unsigned char data[1];
} RpmHead;
return d[0] << 24 | d[1] << 16 | d[2] << 8 | d[3];
}
+static unsigned long long *
+headint64array(RpmHead *h, int tag, int *cnt)
+{
+ unsigned int i, o;
+ unsigned long long *r;
+ unsigned char *d = headfindtag(h, tag);
+
+ if (!d || d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 5)
+ return 0;
+ o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
+ i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
+ if (o + 8 * i > h->dcnt)
+ return 0;
+ d = h->dp + o;
+ r = solv_calloc(i ? i : 1, sizeof(unsigned long long));
+ if (cnt)
+ *cnt = i;
+ for (o = 0; o < i; o++, d += 8)
+ {
+ unsigned int x = d[0] << 24 | d[1] << 16 | d[2] << 8 | d[3];
+ r[o] = (unsigned long long)x << 32 | (d[4] << 24 | d[5] << 16 | d[6] << 8 | d[7]);
+ }
+ return r;
+}
+
/* returns the first entry of an 64bit integer array */
static unsigned long long
headint64(RpmHead *h, int tag)
static void
setutf8string(Repodata *repodata, Id handle, Id tag, const char *str)
{
- const unsigned char *cp;
- int state = 0;
- int c;
- unsigned char *buf = 0, *bp;
-
- /* check if it's already utf8, code taken from screen ;-) */
- cp = (const unsigned char *)str;
- while ((c = *cp++) != 0)
+ if (str[solv_validutf8(str)])
{
- if (state)
- {
- if ((c & 0xc0) != 0x80)
- break; /* encoding error */
- c = (c & 0x3f) | (state << 6);
- if (!(state & 0x40000000))
- {
- /* check for overlong sequences */
- if ((c & 0x820823e0) == 0x80000000)
- break;
- else if ((c & 0x020821f0) == 0x02000000)
- break;
- else if ((c & 0x000820f8) == 0x00080000)
- break;
- else if ((c & 0x0000207c) == 0x00002000)
- break;
- }
- }
- else
- {
- /* new sequence */
- if (c >= 0xfe)
- break;
- else if (c >= 0xfc)
- c = (c & 0x01) | 0xbffffffc; /* 5 bytes to follow */
- else if (c >= 0xf8)
- c = (c & 0x03) | 0xbfffff00; /* 4 */
- else if (c >= 0xf0)
- c = (c & 0x07) | 0xbfffc000; /* 3 */
- else if (c >= 0xe0)
- c = (c & 0x0f) | 0xbff00000; /* 2 */
- else if (c >= 0xc2)
- c = (c & 0x1f) | 0xfc000000; /* 1 */
- else if (c >= 0x80)
- break;
- }
- state = (c & 0x80000000) ? c : 0;
+ char *ustr = solv_latin1toutf8(str); /* not utf8, assume latin1 */
+ repodata_set_str(repodata, handle, tag, ustr);
+ solv_free(ustr);
}
- if (c)
- {
- /* not utf8, assume latin1 */
- buf = solv_malloc(2 * strlen(str) + 1);
- cp = (const unsigned char *)str;
- str = (char *)buf;
- bp = buf;
- while ((c = *cp++) != 0)
- {
- if (c >= 0xc0)
- {
- *bp++ = 0xc3;
- c ^= 0x80;
- }
- else if (c >= 0x80)
- *bp++ = 0xc2;
- *bp++ = c;
- }
- *bp++ = 0;
- }
- repodata_set_str(repodata, handle, tag, str);
- if (buf)
- solv_free(buf);
+ else
+ repodata_set_str(repodata, handle, tag, str);
}
char **n, **v;
unsigned int *f;
int i, cc, nc, vc, fc;
- int haspre;
+ int haspre, premask;
unsigned int olddeps;
Id *ida;
int strong;
cc = nc;
haspre = 0; /* add no prereq marker */
+ premask = DEP_PRE_IN | DEP_PRE_UN;
if (flags)
{
/* we do filtering */
if ((flags & MAKEDEPS_NO_RPMLIB) != 0)
if (!strncmp(n[i], "rpmlib(", 7))
continue;
- if ((f[i] & DEP_PRE) != 0)
+ if ((f[i] & premask) != 0)
haspre = 1;
cc++;
}
{
/* no filtering, just look for the first prereq */
for (i = 0; i < nc; i++)
- if ((f[i] & DEP_PRE) != 0)
+ if ((f[i] & premask) != 0)
{
haspre = 1;
break;
solv_free(f);
return 0;
}
- cc += haspre;
+ cc += haspre; /* add slot for the prereq marker */
olddeps = repo_reserve_ids(repo, 0, cc);
ida = repo->idarraydata + olddeps;
for (i = 0; ; i++)
}
if (strong && (f[i] & DEP_STRONG) != (strong == MAKEDEPS_FILTER_WEAK ? 0 : DEP_STRONG))
continue;
- if (haspre == 1 && (f[i] & DEP_PRE) != 0)
+ if (haspre == 1 && (f[i] & premask) != 0)
continue;
- if (haspre == 2 && (f[i] & DEP_PRE) == 0)
+ if (haspre == 2 && (f[i] & premask) == 0)
continue;
if ((flags & MAKEDEPS_NO_RPMLIB) != 0)
if (!strncmp(n[i], "rpmlib(", 7))
Id name, evr;
int flags = 0;
if ((f[i] & DEP_LESS) != 0)
- flags |= 4;
+ flags |= REL_LT;
if ((f[i] & DEP_EQUAL) != 0)
- flags |= 2;
+ flags |= REL_EQ;
if ((f[i] & DEP_GREATER) != 0)
- flags |= 1;
+ flags |= REL_GT;
name = pool_str2id(pool, n[i], 1);
if (v[i][0] == '0' && v[i][1] == ':' && v[i][2])
evr = pool_str2id(pool, v[i] + 2, 1);
Id did;
int i, fszc;
unsigned int *fkb, *fn, *fsz, *fm, *fino;
+ unsigned long long *fsz64;
unsigned int inotest[256], inotestok;
if (!fc)
return;
- /* XXX: use TAG_LONGFILESIZES if available */
- fsz = headint32array(rpmhead, TAG_FILESIZES, &fszc);
- if (!fsz || fc != fszc)
+ if ((fsz64 = headint64array(rpmhead, TAG_LONGFILESIZES, &fszc)) != 0)
+ {
+ /* convert to kbyte */
+ fsz = solv_malloc2(fszc, sizeof(*fsz));
+ for (i = 0; i < fszc; i++)
+ fsz[i] = fsz64[i] ? fsz64[i] / 1024 + 1 : 0;
+ solv_free(fsz64);
+ }
+ else if ((fsz = headint32array(rpmhead, TAG_FILESIZES, &fszc)) != 0)
+ {
+ /* convert to kbyte */
+ for (i = 0; i < fszc; i++)
+ if (fsz[i])
+ fsz[i] = fsz[i] / 1024 + 1;
+ }
+ else
+ return;
+ if (fc != fszc)
{
solv_free(fsz);
return;
}
+
/* stupid rpm records sizes of directories, so we have to check the mode */
fm = headint16array(rpmhead, TAG_FILEMODES, &fszc);
if (!fm || fc != fszc)
solv_free(fino);
return;
}
+
+ /* kill hardlinked entries */
inotestok = 0;
if (fc < sizeof(inotest))
{
+ /* quick test just hashing the inode numbers */
memset(inotest, 0, sizeof(inotest));
for (i = 0; i < fc; i++)
{
int off, bit;
if (fsz[i] == 0 || !S_ISREG(fm[i]))
- continue;
+ continue; /* does not matter */
off = (fino[i] >> 5) & (sizeof(inotest)/sizeof(*inotest) - 1);
bit = 1 << (fino[i] & 31);
if ((inotest[off] & bit) != 0)
inotest[off] |= bit;
}
if (i == fc)
- inotestok = 1;
+ inotestok = 1; /* no conflict found */
}
if (!inotestok)
{
+ /* hardlinked files are possible, check ino/dev pairs */
unsigned int *fdev = headint32array(rpmhead, TAG_FILEDEVICES, &fszc);
unsigned int *fx, j;
unsigned int mask, hash, hh;
solv_free(fdev);
}
solv_free(fino);
+
+ /* sum up inode count and kbytes for each directory */
fn = solv_calloc(dc, sizeof(unsigned int));
fkb = solv_calloc(dc, sizeof(unsigned int));
for (i = 0; i < fc; i++)
fn[di[i]]++;
if (fsz[i] == 0 || !S_ISREG(fm[i]))
continue;
- fkb[di[i]] += fsz[i] / 1024 + 1;
+ fkb[di[i]] += fsz[i];
}
solv_free(fsz);
solv_free(fm);
if (ct[i])
repodata_set_num(data, h, SOLVABLE_CHANGELOG_TIME, ct[i]);
if (cn[i])
- repodata_set_str(data, h, SOLVABLE_CHANGELOG_AUTHOR, cn[i]);
+ setutf8string(data, h, SOLVABLE_CHANGELOG_AUTHOR, cn[i]);
if (cx[i])
- repodata_set_str(data, h, SOLVABLE_CHANGELOG_TEXT, cx[i]);
+ setutf8string(data, h, SOLVABLE_CHANGELOG_TEXT, cx[i]);
queue_push(&hq, h);
}
for (i = 0; i < hq.count; i++)
solv_free(cn);
}
+static void
+set_description_author(Repodata *data, Id handle, char *str)
+{
+ char *aut, *p;
+ for (aut = str; (aut = strchr(aut, '\n')) != 0; aut++)
+ if (!strncmp(aut, "\nAuthors:\n--------\n", 19))
+ break;
+ if (aut)
+ {
+ /* oh my, found SUSE special author section */
+ int l = aut - str;
+ str = solv_strdup(str);
+ aut = str + l;
+ str[l] = 0;
+ while (l > 0 && str[l - 1] == '\n')
+ str[--l] = 0;
+ if (l)
+ setutf8string(data, handle, SOLVABLE_DESCRIPTION, str);
+ p = aut + 19;
+ aut = str; /* copy over */
+ while (*p == ' ' || *p == '\n')
+ p++;
+ while (*p)
+ {
+ if (*p == '\n')
+ {
+ *aut++ = *p++;
+ while (*p == ' ')
+ p++;
+ continue;
+ }
+ *aut++ = *p++;
+ }
+ while (aut != str && aut[-1] == '\n')
+ aut--;
+ *aut = 0;
+ if (*str)
+ setutf8string(data, handle, SOLVABLE_AUTHORS, str);
+ free(str);
+ }
+ else if (*str)
+ setutf8string(data, handle, SOLVABLE_DESCRIPTION, str);
+}
static int
rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, int flags)
setutf8string(data, handle, SOLVABLE_SUMMARY, str);
str = headstring(rpmhead, TAG_DESCRIPTION);
if (str)
- {
- char *aut, *p;
- for (aut = str; (aut = strchr(aut, '\n')) != 0; aut++)
- if (!strncmp(aut, "\nAuthors:\n--------\n", 19))
- break;
- if (aut)
- {
- /* oh my, found SUSE special author section */
- int l = aut - str;
- str = solv_strdup(str);
- aut = str + l;
- str[l] = 0;
- while (l > 0 && str[l - 1] == '\n')
- str[--l] = 0;
- if (l)
- setutf8string(data, handle, SOLVABLE_DESCRIPTION, str);
- p = aut + 19;
- aut = str; /* copy over */
- while (*p == ' ' || *p == '\n')
- p++;
- while (*p)
- {
- if (*p == '\n')
- {
- *aut++ = *p++;
- while (*p == ' ')
- p++;
- continue;
- }
- *aut++ = *p++;
- }
- while (aut != str && aut[-1] == '\n')
- aut--;
- *aut = 0;
- if (*str)
- setutf8string(data, handle, SOLVABLE_AUTHORS, str);
- free(str);
- }
- else if (*str)
- setutf8string(data, handle, SOLVABLE_DESCRIPTION, str);
- }
+ set_description_author(data, handle, str);
str = headstring(rpmhead, TAG_GROUP);
if (str)
repodata_set_poolstr(data, handle, SOLVABLE_GROUP, str);
*/
struct rpmdbstate {
- Pool *pool;
+ Pool *pool;
char *rootdir;
RpmHead *rpmhead; /* header storage space */