|
Packit |
54873f |
/*
|
|
Packit |
54873f |
* Copyright (c) 2007, Novell Inc.
|
|
Packit |
54873f |
*
|
|
Packit |
54873f |
* This program is licensed under the BSD license, read LICENSE.BSD
|
|
Packit |
54873f |
* for further information
|
|
Packit |
54873f |
*/
|
|
Packit |
54873f |
|
|
Packit |
54873f |
#define _GNU_SOURCE
|
|
Packit |
54873f |
|
|
Packit |
54873f |
#include <stdio.h>
|
|
Packit |
54873f |
#include <stdlib.h>
|
|
Packit |
54873f |
#include <unistd.h>
|
|
Packit |
54873f |
#include <string.h>
|
|
Packit |
54873f |
#include <fcntl.h>
|
|
Packit |
54873f |
#ifdef _WIN32
|
|
Packit |
54873f |
#include <windows.h>
|
|
Packit |
54873f |
#include <io.h>
|
|
Packit |
54873f |
#else
|
|
Packit |
54873f |
#include <sys/time.h>
|
|
Packit |
54873f |
#endif
|
|
Packit |
54873f |
|
|
Packit |
54873f |
#include "util.h"
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void
|
|
Packit |
54873f |
solv_oom(size_t num, size_t len)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
if (num)
|
|
Packit |
54873f |
fprintf(stderr, "Out of memory allocating %zu*%zu bytes!\n", num, len);
|
|
Packit |
54873f |
else
|
|
Packit |
54873f |
fprintf(stderr, "Out of memory allocating %zu bytes!\n", len);
|
|
Packit |
54873f |
abort();
|
|
Packit |
54873f |
exit(1);
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void *
|
|
Packit |
54873f |
solv_malloc(size_t len)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
void *r = malloc(len ? len : 1);
|
|
Packit |
54873f |
if (!r)
|
|
Packit |
54873f |
solv_oom(0, len);
|
|
Packit |
54873f |
return r;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void *
|
|
Packit |
54873f |
solv_malloc2(size_t num, size_t len)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
if (len && (num * len) / len != num)
|
|
Packit |
54873f |
solv_oom(num, len);
|
|
Packit |
54873f |
return solv_malloc(num * len);
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void *
|
|
Packit |
54873f |
solv_realloc(void *old, size_t len)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
if (old == 0)
|
|
Packit |
54873f |
old = malloc(len ? len : 1);
|
|
Packit |
54873f |
else
|
|
Packit |
54873f |
old = realloc(old, len ? len : 1);
|
|
Packit |
54873f |
if (!old)
|
|
Packit |
54873f |
solv_oom(0, len);
|
|
Packit |
54873f |
return old;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void *
|
|
Packit |
54873f |
solv_realloc2(void *old, size_t num, size_t len)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
if (len && (num * len) / len != num)
|
|
Packit |
54873f |
solv_oom(num, len);
|
|
Packit |
54873f |
return solv_realloc(old, num * len);
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void *
|
|
Packit |
54873f |
solv_calloc(size_t num, size_t len)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
void *r;
|
|
Packit |
54873f |
if (num == 0 || len == 0)
|
|
Packit |
54873f |
r = malloc(1);
|
|
Packit |
54873f |
else
|
|
Packit |
54873f |
r = calloc(num, len);
|
|
Packit |
54873f |
if (!r)
|
|
Packit |
54873f |
solv_oom(num, len);
|
|
Packit |
54873f |
return r;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
/* this was solv_realloc2(old, len, size), but we now overshoot
|
|
Packit |
54873f |
* for huge len sizes */
|
|
Packit |
54873f |
void *
|
|
Packit |
54873f |
solv_extend_realloc(void *old, size_t len, size_t size, size_t block)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
size_t xblock = (block + 1) << 5;
|
|
Packit |
54873f |
len = (len + block) & ~block;
|
|
Packit |
54873f |
if (len >= xblock && xblock)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
xblock <<= 1;
|
|
Packit |
54873f |
while (len >= xblock && xblock)
|
|
Packit |
54873f |
xblock <<= 1;
|
|
Packit |
54873f |
if (xblock)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
size_t nlen;
|
|
Packit |
54873f |
xblock = (xblock >> 5) - 1;
|
|
Packit |
54873f |
nlen = (len + xblock) & ~xblock;
|
|
Packit |
54873f |
if (nlen > len)
|
|
Packit |
54873f |
len = nlen;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
return solv_realloc2(old, len, size);
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void *
|
|
Packit |
54873f |
solv_free(void *mem)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
if (mem)
|
|
Packit |
54873f |
free(mem);
|
|
Packit |
54873f |
return 0;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
char *
|
|
Packit |
54873f |
solv_strdup(const char *s)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
char *r;
|
|
Packit |
54873f |
if (!s)
|
|
Packit |
54873f |
return 0;
|
|
Packit |
54873f |
r = strdup(s);
|
|
Packit |
54873f |
if (!r)
|
|
Packit |
54873f |
solv_oom(0, strlen(s));
|
|
Packit |
54873f |
return r;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
unsigned int
|
|
Packit |
54873f |
solv_timems(unsigned int subtract)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
#ifdef _WIN32
|
|
Packit |
54873f |
return GetTickCount() - subtract;
|
|
Packit |
54873f |
#else
|
|
Packit |
54873f |
struct timeval tv;
|
|
Packit |
54873f |
unsigned int r;
|
|
Packit |
54873f |
|
|
Packit |
54873f |
if (gettimeofday(&tv, 0))
|
|
Packit |
54873f |
return 0;
|
|
Packit |
54873f |
r = (((unsigned int)tv.tv_sec >> 16) * 1000) << 16;
|
|
Packit |
54873f |
r += ((unsigned int)tv.tv_sec & 0xffff) * 1000;
|
|
Packit |
54873f |
r += (unsigned int)tv.tv_usec / 1000;
|
|
Packit |
54873f |
return r - subtract;
|
|
Packit |
54873f |
#endif
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
int
|
|
Packit |
54873f |
solv_setcloexec(int fd, int state)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
#ifdef _WIN32
|
|
Packit |
54873f |
return SetHandleInformation((HANDLE) _get_osfhandle(fd), HANDLE_FLAG_INHERIT, state ? 0 : HANDLE_FLAG_INHERIT);
|
|
Packit |
54873f |
#else
|
|
Packit |
54873f |
return fcntl(fd, F_SETFD, state ? FD_CLOEXEC : 0) == 0;
|
|
Packit |
54873f |
#endif
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
/* bsd's qsort_r has different arguments, so we define our
|
|
Packit |
54873f |
own version in case we need to do some clever mapping
|
|
Packit |
54873f |
|
|
Packit |
54873f |
see also: http://sources.redhat.com/ml/libc-alpha/2008-12/msg00003.html
|
|
Packit |
54873f |
*/
|
|
Packit |
54873f |
#if (defined(__GLIBC__) || defined(__NEWLIB__)) && (defined(HAVE_QSORT_R) || defined(HAVE___QSORT_R))
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void
|
|
Packit |
54873f |
solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
# if defined(HAVE_QSORT_R)
|
|
Packit |
54873f |
qsort_r(base, nmemb, size, compar, compard);
|
|
Packit |
54873f |
# else
|
|
Packit |
54873f |
/* backported for SLE10-SP2 */
|
|
Packit |
54873f |
__qsort_r(base, nmemb, size, compar, compard);
|
|
Packit |
54873f |
# endif
|
|
Packit |
54873f |
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
#elif defined(HAVE_QSORT_R) /* not glibc, but has qsort_r() */
|
|
Packit |
54873f |
|
|
Packit |
54873f |
struct solv_sort_data {
|
|
Packit |
54873f |
int (*compar)(const void *, const void *, void *);
|
|
Packit |
54873f |
void *compard;
|
|
Packit |
54873f |
};
|
|
Packit |
54873f |
|
|
Packit |
54873f |
static int
|
|
Packit |
54873f |
solv_sort_helper(void *compard, const void *a, const void *b)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
struct solv_sort_data *d = compard;
|
|
Packit |
54873f |
return (*d->compar)(a, b, d->compard);
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
void
|
|
Packit |
54873f |
solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
struct solv_sort_data d;
|
|
Packit |
54873f |
d.compar = compar;
|
|
Packit |
54873f |
d.compard = compard;
|
|
Packit |
54873f |
qsort_r(base, nmemb, size, &d, solv_sort_helper);
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
#else /* not glibc and no qsort_r() */
|
|
Packit |
54873f |
/* use own version of qsort if none available */
|
|
Packit |
54873f |
#include "qsort_r.c"
|
|
Packit |
54873f |
#endif
|
|
Packit |
54873f |
|
|
Packit |
54873f |
char *
|
|
Packit |
54873f |
solv_dupjoin(const char *str1, const char *str2, const char *str3)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
int l1, l2, l3;
|
|
Packit |
54873f |
char *s, *str;
|
|
Packit |
54873f |
l1 = str1 ? strlen(str1) : 0;
|
|
Packit |
54873f |
l2 = str2 ? strlen(str2) : 0;
|
|
Packit |
54873f |
l3 = str3 ? strlen(str3) : 0;
|
|
Packit |
54873f |
s = str = solv_malloc(l1 + l2 + l3 + 1);
|
|
Packit |
54873f |
if (l1)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
strcpy(s, str1);
|
|
Packit |
54873f |
s += l1;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
if (l2)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
strcpy(s, str2);
|
|
Packit |
54873f |
s += l2;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
if (l3)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
strcpy(s, str3);
|
|
Packit |
54873f |
s += l3;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
*s = 0;
|
|
Packit |
54873f |
return str;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
char *
|
|
Packit |
54873f |
solv_dupappend(const char *str1, const char *str2, const char *str3)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
char *str = solv_dupjoin(str1, str2, str3);
|
|
Packit |
54873f |
solv_free((void *)str1);
|
|
Packit |
54873f |
return str;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
int
|
|
Packit |
54873f |
solv_hex2bin(const char **strp, unsigned char *buf, int bufl)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
const char *str = *strp;
|
|
Packit |
54873f |
int i;
|
|
Packit |
54873f |
|
|
Packit |
54873f |
for (i = 0; i < bufl; i++)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
int c = *str;
|
|
Packit |
54873f |
int d;
|
|
Packit |
54873f |
if (c >= '0' && c <= '9')
|
|
Packit |
54873f |
d = c - '0';
|
|
Packit |
54873f |
else if (c >= 'a' && c <= 'f')
|
|
Packit |
54873f |
d = c - ('a' - 10);
|
|
Packit |
54873f |
else if (c >= 'A' && c <= 'F')
|
|
Packit |
54873f |
d = c - ('A' - 10);
|
|
Packit |
54873f |
else
|
|
Packit |
54873f |
break;
|
|
Packit |
54873f |
c = str[1];
|
|
Packit |
54873f |
d <<= 4;
|
|
Packit |
54873f |
if (c >= '0' && c <= '9')
|
|
Packit |
54873f |
d |= c - '0';
|
|
Packit |
54873f |
else if (c >= 'a' && c <= 'f')
|
|
Packit |
54873f |
d |= c - ('a' - 10);
|
|
Packit |
54873f |
else if (c >= 'A' && c <= 'F')
|
|
Packit |
54873f |
d |= c - ('A' - 10);
|
|
Packit |
54873f |
else
|
|
Packit |
54873f |
break;
|
|
Packit |
54873f |
buf[i] = d;
|
|
Packit |
54873f |
str += 2;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
*strp = str;
|
|
Packit |
54873f |
return i;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
char *
|
|
Packit |
54873f |
solv_bin2hex(const unsigned char *buf, int l, char *str)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
int i;
|
|
Packit |
54873f |
for (i = 0; i < l; i++, buf++)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
int c = *buf >> 4;
|
|
Packit |
54873f |
*str++ = c < 10 ? c + '0' : c + ('a' - 10);
|
|
Packit |
54873f |
c = *buf & 15;
|
|
Packit |
54873f |
*str++ = c < 10 ? c + '0' : c + ('a' - 10);
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
*str = 0;
|
|
Packit |
54873f |
return str;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
size_t
|
|
Packit |
54873f |
solv_validutf8(const char *buf)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
const unsigned char *p;
|
|
Packit |
54873f |
int x;
|
|
Packit |
54873f |
|
|
Packit |
54873f |
for (p = (const unsigned char *)buf; (x = *p) != 0; p++)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
if (x < 0x80)
|
|
Packit |
54873f |
continue;
|
|
Packit |
54873f |
if (x < 0xc0)
|
|
Packit |
54873f |
break;
|
|
Packit |
54873f |
if (x < 0xe0)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
/* one byte to follow */
|
|
Packit |
54873f |
if ((p[1] & 0xc0) != 0x80)
|
|
Packit |
54873f |
break;
|
|
Packit |
54873f |
if ((x & 0x1e) == 0)
|
|
Packit |
54873f |
break; /* not minimal */
|
|
Packit |
54873f |
p += 1;
|
|
Packit |
54873f |
continue;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
if (x < 0xf0)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
/* two bytes to follow */
|
|
Packit |
54873f |
if ((p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80)
|
|
Packit |
54873f |
break;
|
|
Packit |
54873f |
if ((x & 0x0f) == 0 && (p[1] & 0x20) == 0)
|
|
Packit |
54873f |
break; /* not minimal */
|
|
Packit |
54873f |
if (x == 0xed && (p[1] & 0x20) != 0)
|
|
Packit |
54873f |
break; /* d800-dfff surrogate */
|
|
Packit |
54873f |
if (x == 0xef && p[1] == 0xbf && (p[2] == 0xbe || p[2] == 0xbf))
|
|
Packit |
54873f |
break; /* fffe or ffff */
|
|
Packit |
54873f |
p += 2;
|
|
Packit |
54873f |
continue;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
if (x < 0xf8)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
/* three bytes to follow */
|
|
Packit |
54873f |
if ((p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80 || (p[3] & 0xc0) != 0x80)
|
|
Packit |
54873f |
break;
|
|
Packit |
54873f |
if ((x & 0x07) == 0 && (p[1] & 0x30) == 0)
|
|
Packit |
54873f |
break; /* not minimal */
|
|
Packit |
54873f |
if ((x & 0x07) > 4 || ((x & 0x07) == 4 && (p[1] & 0x30) != 0))
|
|
Packit |
54873f |
break; /* above 0x10ffff */
|
|
Packit |
54873f |
p += 3;
|
|
Packit |
54873f |
continue;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
break; /* maybe valid utf8, but above 0x10ffff */
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
return (const char *)p - buf;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
char *
|
|
Packit |
54873f |
solv_latin1toutf8(const char *buf)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
int l = 1;
|
|
Packit |
54873f |
const char *p;
|
|
Packit |
54873f |
char *r, *rp;
|
|
Packit |
54873f |
|
|
Packit |
54873f |
for (p = buf; *p; p++)
|
|
Packit |
54873f |
if ((*(const unsigned char *)p & 128) != 0)
|
|
Packit |
54873f |
l++;
|
|
Packit |
54873f |
r = rp = solv_malloc(p - buf + l);
|
|
Packit |
54873f |
for (p = buf; *p; p++)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
if ((*(const unsigned char *)p & 128) != 0)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
*rp++ = *(const unsigned char *)p & 64 ? 0xc3 : 0xc2;
|
|
Packit |
54873f |
*rp++ = *p & 0xbf;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
else
|
|
Packit |
54873f |
*rp++ = *p;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
*rp = 0;
|
|
Packit |
54873f |
return r;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|
|
Packit |
54873f |
char *
|
|
Packit |
54873f |
solv_replacebadutf8(const char *buf, int replchar)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
size_t l, nl;
|
|
Packit |
54873f |
const char *p;
|
|
Packit |
54873f |
char *r = 0, *rp = 0;
|
|
Packit |
54873f |
int repllen, replin;
|
|
Packit |
54873f |
|
|
Packit |
54873f |
if (replchar < 0 || replchar > 0x10ffff)
|
|
Packit |
54873f |
replchar = 0xfffd;
|
|
Packit |
54873f |
if (!replchar)
|
|
Packit |
54873f |
repllen = replin = 0;
|
|
Packit |
54873f |
else if (replchar < 0x80)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
repllen = 1;
|
|
Packit |
54873f |
replin = (replchar & 0x40) | 0x80;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
else if (replchar < 0x800)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
repllen = 2;
|
|
Packit |
54873f |
replin = 0x40;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
else if (replchar < 0x10000)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
repllen = 3;
|
|
Packit |
54873f |
replin = 0x60;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
else
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
repllen = 4;
|
|
Packit |
54873f |
replin = 0x70;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
for (;;)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
for (p = buf, nl = 0; *p; )
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
l = solv_validutf8(p);
|
|
Packit |
54873f |
if (rp && l)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
memcpy(rp, p, l);
|
|
Packit |
54873f |
rp += l;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
nl += l;
|
|
Packit |
54873f |
p += l;
|
|
Packit |
54873f |
if (!*p)
|
|
Packit |
54873f |
break;
|
|
Packit |
54873f |
/* found a bad char, replace with replchar */
|
|
Packit |
54873f |
if (rp && replchar)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
switch (repllen)
|
|
Packit |
54873f |
{
|
|
Packit |
54873f |
case 4:
|
|
Packit |
54873f |
*rp++ = (replchar >> 18 & 0x3f) | 0x80;
|
|
Packit |
54873f |
case 3:
|
|
Packit |
54873f |
*rp++ = (replchar >> 12 & 0x3f) | 0x80;
|
|
Packit |
54873f |
case 2:
|
|
Packit |
54873f |
*rp++ = (replchar >> 6 & 0x3f) | 0x80;
|
|
Packit |
54873f |
default:
|
|
Packit |
54873f |
*rp++ = (replchar & 0x3f) | 0x80;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
rp[-repllen] ^= replin;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
nl += repllen;
|
|
Packit |
54873f |
p++;
|
|
Packit |
54873f |
while ((*(const unsigned char *)p & 0xc0) == 0x80)
|
|
Packit |
54873f |
p++;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
if (rp)
|
|
Packit |
54873f |
break;
|
|
Packit |
54873f |
r = rp = solv_malloc(nl + 1);
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
*rp = 0;
|
|
Packit |
54873f |
return r;
|
|
Packit |
54873f |
}
|
|
Packit |
54873f |
|