#include "system.h"
#include <netdb.h>
+#include <errno.h>
#include <rpm/rpmtypes.h>
#include <rpm/rpmstring.h>
#include "lib/header_internal.h"
#include "lib/misc.h" /* tag function proto */
+#include <errno.h>
#include "debug.h"
/** \ingroup header
return i;
if (hdrchkAlign(info->type, info->offset))
return i;
- if (!negate && hdrchkRange(dl, info->offset))
+ if (hdrchkRange(dl, info->offset))
return i;
if (hdrchkData(info->count))
return i;
return size;
}
-/* Bounded header string (array) size calculation, return -1 on error */
+/*
+ * Header string (array) size calculation, bounded if end is non-NULL.
+ * Return length (including \0 termination) on success, -1 on error.
+ */
static inline int strtaglen(const char *str, rpm_count_t c, const char *end)
{
const char *start = str;
const char *s;
- while ((s = memchr(start, '\0', end-start))) {
- if (--c == 0 || s > end)
- break;
- start = s + 1;
+ if (end) {
+ while ((s = memchr(start, '\0', end-start))) {
+ if (--c == 0 || s > end)
+ break;
+ start = s + 1;
+ }
+ } else {
+ while ((s = strchr(start, '\0'))) {
+ if (--c == 0)
+ break;
+ start = s + 1;
+ }
}
return (c > 0) ? -1 : (s - str + 1);
}
int onDisk, rpm_constdata_t pend)
{
const char * s = p;
- /* Not all callers supply data end, avoid falling over edge of the world */
- const char * se = pend ? pend : s + HEADER_DATA_MAX;
+ const char * se = pend;
int length = 0;
switch (type) {
entry->info.type = htonl(pe->type);
entry->info.count = htonl(pe->count);
+ entry->info.tag = htonl(pe->tag);
- if (hdrchkType(entry->info.type))
+ if (!ENTRY_IS_REGION(entry))
goto errxit;
- if (hdrchkTags(entry->info.count))
+ if (entry->info.type != REGION_TAG_TYPE)
+ goto errxit;
+ if (entry->info.count != REGION_TAG_COUNT)
goto errxit;
{ int off = ntohl(pe->offset);
ril = rdl/sizeof(*pe);
if (hdrchkTags(ril) || hdrchkData(rdl))
goto errxit;
- entry->info.tag = htonl(pe->tag);
} else {
ril = il;
rdl = (ril * sizeof(struct entryInfo_s));
if (magicp == HEADER_MAGIC_YES) {
int32_t magic;
- if (Fread(block, 1, 4*sizeof(*block), fd) != 4*sizeof(*block))
+ if (Freadall(fd, block, 4*sizeof(*block)) != 4*sizeof(*block))
goto exit;
magic = block[0];
il = ntohl(block[2]);
dl = ntohl(block[3]);
} else {
- if (Fread(block, 1, 2*sizeof(*block), fd) != 2*sizeof(*block))
+ if (Freadall(fd, block, 2*sizeof(*block)) != 2*sizeof(*block))
goto exit;
il = ntohl(block[0]);
ei[0] = htonl(il);
ei[1] = htonl(dl);
- if (Fread((char *)&ei[2], 1, blen, fd) != blen)
+ if (Freadall(fd, (char *)&ei[2], blen) != blen)
goto exit;
h = headerImport(ei, len, 0);
{
indexEntry entry;
rpm_data_t data;
- int length;
+ int length = 0;
/* Count must always be >= 1 for headerAddEntry. */
if (td->count <= 0)
if (hdrchkData(td->count))
return 0;
- length = 0;
data = grabData(td->type, td->data, td->count, &length);
- if (data == NULL || length <= 0)
+ if (data == NULL)
return 0;
/* Allocate more index space if necessary */
indexEntry entry;
rpm_data_t oldData;
rpm_data_t data;
- int length;
+ int length = 0;
/* First find the tag */
entry = findEntry(h, td->tag, td->type);
if (!entry)
return 0;
- length = 0;
data = grabData(td->type, td->data, td->count, &length);
- if (data == NULL || length <= 0)
+ if (data == NULL)
return 0;
/* make sure entry points to the first occurence of this tag */
h->instance = instance;
}
+#define RETRY_ERROR(_err) \
+ ((_err) == EINTR || (_err) == EAGAIN || (_err) == EWOULDBLOCK)
+
+ssize_t Freadall(FD_t fd, void * buf, ssize_t size)
+{
+ ssize_t total = 0;
+ ssize_t nb = 0;
+ char * bufp = buf;
+
+ while (total < size) {
+ nb = Fread(bufp, 1, size - total, fd);
+
+ if (nb == 0 || (nb < 0 && !RETRY_ERROR(errno))) {
+ total = nb;
+ break;
+ }
+
+ if (nb > 0) {
+ bufp += nb;
+ total += nb;
+ }
+ }
+
+ return total;
+}
+