]> TLD Linux GIT Repositories - packages/rpm.git/blob - rpm-shrink.patch
- package /usr/lib/rpm/macros.d dir
[packages/rpm.git] / rpm-shrink.patch
1 diff -urNp rpm-4.5.orig/rpmio/macro.c rpm-4.5/rpmio/macro.c
2 --- rpm-4.5.orig/rpmio/macro.c  2017-10-19 22:48:49.000000000 +0000
3 +++ rpm-4.5/rpmio/macro.c       2017-10-19 23:16:34.301644733 +0000
4 @@ -71,6 +71,7 @@ const char * rpmMacrofiles = MACROFILES;
5  #endif
6  
7  #include <rpmmacro.h>
8 +#include <rpmstring.h>
9  
10  #include "debug.h"
11  
12 @@ -1200,6 +1201,28 @@ doFoo(MacroBuf mb, int negate, const cha
13         if ((b = strrchr(buf, '/')) != NULL)
14             *b = '\0';
15         b = buf;
16 +    } else if (STREQ("shrink", f, fn)) {
17 +       /*
18 +        * shrink body by removing all leading and trailing whitespaces and
19 +        * reducing intermediate whitespaces to a single space character.
20 +        */
21 +       size_t i = 0, j = 0;
22 +       size_t buflen = strlen(buf);
23 +       int was_space = 0;
24 +       while (i < buflen) {
25 +           if (risspace(buf[i])) {
26 +               was_space = 1;
27 +               i++;
28 +               continue;
29 +           } else if (was_space) {
30 +               was_space = 0;
31 +               if (j > 0) /* remove leading blanks at all */
32 +                   buf[j++] = ' ';
33 +           }
34 +           buf[j++] = buf[i++];
35 +       }
36 +       buf[j] = '\0';
37 +       b = buf;
38      } else if (STREQ("suffix", f, fn)) {
39         if ((b = strrchr(buf, '.')) != NULL)
40             b++;
41 @@ -1549,6 +1572,7 @@ expandMacro(MacroBuf mb)
42         /* XXX necessary but clunky */
43         if (STREQ("basename", f, fn) ||
44             STREQ("dirname", f, fn) ||
45 +           STREQ("shrink", f, fn) ||
46             STREQ("suffix", f, fn) ||
47             STREQ("expand", f, fn) ||
48             STREQ("verbose", f, fn) ||
49 diff -urNp rpm-4.5.orig/rpmio/Makefile.am rpm-4.5/rpmio/Makefile.am
50 --- rpm-4.5.orig/rpmio/Makefile.am      2017-10-19 22:48:49.000000000 +0000
51 +++ rpm-4.5/rpmio/Makefile.am   2017-10-19 23:16:15.212645871 +0000
52 @@ -37,7 +37,7 @@ librpmio_la_SOURCES = \
53         md2.c md4.c rmd128.c rmd160.c rmd256.c rmd320.c sha224.c \
54         salsa10.c salsa20.c tiger.c \
55         rpmdav.c rpmhash.c rpmhook.c rpmio.c rpmlog.c rpmlua.c rpmmalloc.c \
56 -       rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c strtolocale.c \
57 +       rpmpgp.c rpmrpc.c rpmsq.c rpmstring.c rpmsw.c strcasecmp.c strtolocale.c \
58         stubs.c url.c ugid.c rpmuuid.c
59  librpmio_la_LDFLAGS = -no-undefined -release $(LT_CURRENT).$(LT_REVISION) $(LDFLAGS) \
60         @WITH_BEECRYPT_LIB@ \
61 diff -urNp rpm-4.5.orig/rpmio/Makefile.in rpm-4.5/rpmio/Makefile.in
62 --- rpm-4.5.orig/rpmio/Makefile.in      2008-07-09 09:41:32.000000000 +0000
63 +++ rpm-4.5/rpmio/Makefile.in   2017-10-19 23:16:15.212645871 +0000
64 @@ -68,7 +68,7 @@ am_librpmio_la_OBJECTS = argv.lo digest.
65         macro.lo mire.lo md2.lo md4.lo rmd128.lo rmd160.lo rmd256.lo \
66         rmd320.lo sha224.lo salsa10.lo salsa20.lo tiger.lo rpmdav.lo \
67         rpmhash.lo rpmhook.lo rpmio.lo rpmlog.lo rpmlua.lo \
68 -       rpmmalloc.lo rpmpgp.lo rpmrpc.lo rpmsq.lo rpmsw.lo \
69 +       rpmmalloc.lo rpmpgp.lo rpmrpc.lo rpmsq.lo rpmstring.lo rpmsw.lo \
70         strcasecmp.lo strtolocale.lo stubs.lo url.lo ugid.lo \
71         rpmuuid.lo
72  librpmio_la_OBJECTS = $(am_librpmio_la_OBJECTS)
73 diff -urNp rpm-4.5.orig/rpmio/rpmstring.c rpm-4.5/rpmio/rpmstring.c
74 --- rpm-4.5.orig/rpmio/rpmstring.c      1970-01-01 00:00:00.000000000 +0000
75 +++ rpm-4.5/rpmio/rpmstring.c   2017-10-19 23:16:15.212645871 +0000
76 @@ -0,0 +1,192 @@
77 +/**
78 + * \file rpmio/rpmstring.c
79 + */
80 +
81 +#include "system.h"
82 +
83 +#include <stdarg.h>
84 +#include <stdio.h>
85 +
86 +#include <rpmio/rpmstring.h>
87 +#include "debug.h"
88 +
89 +
90 +int rstrcasecmp(const char * s1, const char * s2)
91 +{
92 +  const char * p1 = s1;
93 +  const char * p2 = s2;
94 +  char c1, c2;
95 +
96 +  if (p1 == p2)
97 +    return 0;
98 +
99 +  do
100 +    {
101 +      c1 = rtolower (*p1++);
102 +      c2 = rtolower (*p2++);
103 +      if (c1 == '\0')
104 +        break;
105 +    }
106 +  while (c1 == c2);
107 +
108 +  return (int)(c1 - c2);
109 +}
110 +
111 +int rstrncasecmp(const char *s1, const char *s2, size_t n)
112 +{
113 +  const char * p1 = s1;
114 +  const char * p2 = s2;
115 +  char c1, c2;
116 +
117 +  if (p1 == p2 || n == 0)
118 +    return 0;
119 +
120 +  do
121 +    {
122 +      c1 = rtolower (*p1++);
123 +      c2 = rtolower (*p2++);
124 +      if (c1 == '\0' || c1 != c2)
125 +       break;
126 +    } while (--n > 0);
127 +
128 +  return (int)(c1 - c2);
129 +}
130 +
131 +/* 
132 + * Simple and stupid asprintf() clone.
133 + * FIXME: write to work with non-C99 vsnprintf or check for one in configure.
134 + */
135 +int rasprintf(char **strp, const char *fmt, ...)
136 +{
137 +    int n;
138 +    va_list ap;
139 +    char * p = NULL;
140 +  
141 +    if (strp == NULL) 
142 +       return -1;
143 +
144 +    va_start(ap, fmt);
145 +    n = vsnprintf(NULL, 0, fmt, ap);
146 +    va_end(ap);
147 +
148 +    if (n >= -1) {
149 +       size_t nb = n + 1;
150 +       p = xmalloc(nb);
151 +       va_start(ap, fmt);
152 +        n = vsnprintf(p, nb, fmt, ap);
153 +       va_end(ap);
154 +    } 
155 +    *strp = p;
156 +    return n;
157 +}
158 +
159 +/*
160 + * Concatenate two strings with dynamically (re)allocated
161 + * memory what prevents static buffer overflows by design.
162 + * *dest is reallocated to the size of strings to concatenate.
163 + *
164 + * Note:
165 + * 1) char *buf = rstrcat(NULL,"string"); is the same like rstrcat(&buf,"string");
166 + * 2) rstrcat(&buf,NULL) returns buf
167 + * 3) rstrcat(NULL,NULL) returns NULL
168 + * 4) *dest and src can overlap
169 + */
170 +char *rstrcat(char **dest, const char *src)
171 +{
172 +    if ( src == NULL ) {
173 +       return dest != NULL ? *dest : NULL;
174 +    }
175 +
176 +    if ( dest == NULL ) {
177 +       return xstrdup(src);
178 +    }
179 +
180 +    {
181 +       size_t dest_size = *dest != NULL ? strlen(*dest) : 0;
182 +       size_t src_size = strlen(src);
183 +
184 +       *dest = xrealloc(*dest, dest_size+src_size+1);          /* include '\0' */
185 +       memmove(&(*dest)[dest_size], src, src_size+1);
186 +    }
187 +
188 +    return *dest;
189 +}
190 +
191 +/*
192 + * Concatenate strings with dynamically (re)allocated
193 + * memory what prevents static buffer overflows by design.
194 + * *dest is reallocated to the size of strings to concatenate.
195 + * List of strings has to be NULL terminated.
196 + *
197 + * Note:
198 + * 1) char *buf = rstrscat(NULL,"string",NULL); is the same like rstrscat(&buf,"string",NULL);
199 + * 2) rstrscat(&buf,NULL) returns buf
200 + * 3) rstrscat(NULL,NULL) returns NULL
201 + * 4) *dest and argument strings can overlap
202 + */
203 +char *rstrscat(char **dest, const char *arg, ...)
204 +{
205 +    va_list ap;
206 +    size_t arg_size, dst_size;
207 +    const char *s;
208 +    char *dst, *p;
209 +
210 +    dst = dest ? *dest : NULL;
211 +
212 +    if ( arg == NULL ) {
213 +        return dst;
214 +    }
215 +
216 +    va_start(ap, arg);
217 +    for (arg_size=0, s=arg; s; s = va_arg(ap, const char *))
218 +        arg_size += strlen(s);
219 +    va_end(ap);
220 +
221 +    dst_size = dst ? strlen(dst) : 0;
222 +    dst = xrealloc(dst, dst_size+arg_size+1);    /* include '\0' */
223 +    p = &dst[dst_size];
224 +
225 +    va_start(ap, arg);
226 +    for (s = arg; s; s = va_arg(ap, const char *)) {
227 +        size_t size = strlen(s);
228 +        memmove(p, s, size);
229 +        p += size;
230 +    }
231 +    va_end(ap);
232 +    *p = '\0';
233 +
234 +    if ( dest ) {
235 +        *dest = dst;
236 +    }
237 +
238 +    return dst;
239 +}
240 +
241 +/*
242 + * Adapted from OpenBSD, strlcpy() originally developed by
243 + * Todd C. Miller <Todd.Miller@courtesan.com>
244 + */
245 +size_t rstrlcpy(char *dest, const char *src, size_t n)
246 +{
247 +    char *d = dest;
248 +    const char *s = src;
249 +    size_t len = n;
250 +
251 +    /* Copy as many bytes as will fit */
252 +    if (len != 0) {
253 +       while (--len != 0) {
254 +           if ((*d++ = *s++) == '\0')
255 +               break;
256 +       }
257 +    }
258 +
259 +    /* Not enough room in dst, add NUL and traverse rest of src */
260 +    if (len == 0) {
261 +       if (n != 0)
262 +           *d = '\0'; /* NUL-terminate dst */
263 +       while (*s++)
264 +           ;
265 +    }
266 +
267 +    return s - src - 1; /* count does not include NUL */
268 +}
269 diff -urNp rpm-4.5.orig/rpmio/rpmstring.h rpm-4.5/rpmio/rpmstring.h
270 --- rpm-4.5.orig/rpmio/rpmstring.h      1970-01-01 00:00:00.000000000 +0000
271 +++ rpm-4.5/rpmio/rpmstring.h   2017-10-19 23:16:15.212645871 +0000
272 @@ -0,0 +1,187 @@
273 +#ifndef _RPMSTRING_H_
274 +#define _RPMSTRING_H_
275 +
276 +/** \ingroup rpmstring
277 + * \file rpmio/rpmstring.h
278 + * String manipulation helper functions
279 + */
280 +
281 +#include <stddef.h>
282 +#include <string.h>
283 +
284 +#include <rpmio/rpmutil.h>
285 +
286 +#ifdef __cplusplus
287 +extern "C" {
288 +#endif
289 +
290 +/** \ingroup rpmstring
291 + * Locale insensitive islower(3) 
292 + */
293 +RPM_GNUC_CONST
294 +static inline int rislower(int c)  {
295 +    return (c >= 'a' && c <= 'z');
296 +}
297 +
298 +/** \ingroup rpmstring
299 + * Locale insensitive isupper(3)
300 + */
301 +RPM_GNUC_CONST
302 +static inline int risupper(int c)  {
303 +    return (c >= 'A' && c <= 'Z');
304 +}
305 +
306 +/** \ingroup rpmstring
307 + * Locale insensitive isalpha(3)
308 + */
309 +RPM_GNUC_CONST
310 +static inline int risalpha(int c)  {
311 +    return (rislower(c) || risupper(c));
312 +}
313 +
314 +/** \ingroup rpmstring
315 + * Locale insensitive isdigit(3)
316 + */
317 +RPM_GNUC_CONST
318 +static inline int risdigit(int c)  {
319 +    return (c >= '0' && c <= '9');
320 +}
321 +
322 +/** \ingroup rpmstring
323 + * Locale insensitive isalnum(3)
324 + */
325 +RPM_GNUC_CONST
326 +static inline int risalnum(int c)  {
327 +    return (risalpha(c) || risdigit(c));
328 +}
329 +
330 +/** \ingroup rpmstring
331 + * Locale insensitive isblank(3)
332 + */
333 +RPM_GNUC_CONST
334 +static inline int risblank(int c)  {
335 +    return (c == ' ' || c == '\t');
336 +}
337 +
338 +/** \ingroup rpmstring
339 + * Locale insensitive isspace(3)
340 + */
341 +RPM_GNUC_CONST
342 +static inline int risspace(int c)  {
343 +    return (risblank(c) || c == '\n' || c == '\r' || c == '\f' || c == '\v');
344 +}
345 +
346 +/** \ingroup rpmstring
347 + * Locale insensitive tolower(3)
348 + */
349 +RPM_GNUC_CONST
350 +static inline int rtolower(int c)  {
351 +    return ((risupper(c)) ? (c | ('a' - 'A')) : c);
352 +}
353 +
354 +/** \ingroup rpmstring
355 + * Locale insensitive toupper(3)
356 + */
357 +RPM_GNUC_CONST
358 +static inline int rtoupper(int c)  {
359 +    return ((rislower(c)) ? (c & ~('a' - 'A')) : c);
360 +}
361 +
362 +/**
363 + * Convert hex to binary nibble.
364 + * @param c            hex character
365 + * @return             binary nibble
366 + */
367 +RPM_GNUC_CONST
368 +static inline unsigned char rnibble(char c)
369 +{
370 +    if (c >= '0' && c <= '9')
371 +       return (c - '0');
372 +    if (c >= 'a' && c <= 'f')
373 +       return (c - 'a') + 10;
374 +    if (c >= 'A' && c <= 'F')
375 +       return (c - 'A') + 10;
376 +    return 0;
377 +}
378 +
379 +/**
380 + * Test for string equality
381 + * @param s1           string 1
382 + * @param s2           string 2
383 + * @return             0 if strings differ, 1 if equal
384 + */
385 +static inline int rstreq(const char *s1, const char *s2)
386 +{
387 +    return (strcmp(s1, s2) == 0);
388 +}
389 +
390 +/**
391 + * Test for string equality
392 + * @param s1           string 1
393 + * @param s2           string 2
394 + * @param n            compare at most n characters
395 + * @return             0 if strings differ, 1 if equal
396 + */
397 +static inline int rstreqn(const char *s1, const char *s2, size_t n)
398 +{
399 +    return (strncmp(s1, s2, n) == 0);
400 +}
401 +
402 +/** \ingroup rpmstring
403 + * Locale insensitive strcasecmp(3).
404 + */
405 +RPM_GNUC_PURE
406 +int rstrcasecmp(const char * s1, const char * s2)              ;
407 +
408 +/** \ingroup rpmstring
409 + * Locale insensitive strncasecmp(3).
410 + */
411 +RPM_GNUC_PURE
412 +int rstrncasecmp(const char *s1, const char * s2, size_t n)    ;
413 +
414 +/** \ingroup rpmstring
415 + * asprintf() clone
416 + */
417 +int rasprintf(char **strp, const char *fmt, ...) RPM_GNUC_PRINTF(2, 3);
418 +
419 +/** \ingroup rpmstring
420 + * Concatenate two strings with dynamically (re)allocated memory.
421 + * @param dest         pointer to destination string
422 + * @param src          source string
423 + * @return             realloc'd dest with src appended
424 + */
425 +char *rstrcat(char **dest, const char *src);
426 +
427 +/** \ingroup rpmstring
428 + * Concatenate multiple strings with dynamically (re)allocated memory.
429 + * @param dest         pointer to destination string
430 + * @param arg          NULL terminated list of strings to concatenate
431 + * @return             realloc'd dest with strings appended
432 + */
433 +char *rstrscat(char **dest, const char *arg, ...) RPM_GNUC_NULL_TERMINATED;
434 +
435 +/** \ingroup rpmstring
436 + * strlcpy() clone: 
437 + * Copy src to string dest of size n. At most n-1 characters
438 + * will be copied.  Always zero-terminates (unless n == 0).
439 + * Length of src is returned; if retval >= n, truncation occurred.
440 + * @param dest         destination buffer
441 + * @param src          string to copy
442 + * @param n            destination buffer size
443 + * @return             length of src string
444 + */
445 +size_t rstrlcpy(char *dest, const char *src, size_t n);
446 +
447 +/** \ingroup rpmstring
448 + * String hashing function
449 + * @param string       string to hash
450 + * @return             hash id
451 + */
452 +RPM_GNUC_PURE
453 +unsigned int rstrhash(const char * string);
454 +
455 +#ifdef __cplusplus
456 +}
457 +#endif
458 +
459 +#endif /* _RPMSTRING_H_ */
460 diff -urNp rpm-4.5.orig/rpmio/rpmutil.h rpm-4.5/rpmio/rpmutil.h
461 --- rpm-4.5.orig/rpmio/rpmutil.h        1970-01-01 00:00:00.000000000 +0000
462 +++ rpm-4.5/rpmio/rpmutil.h     2017-10-19 23:16:15.213645871 +0000
463 @@ -0,0 +1,160 @@
464 +#ifndef _RPMUTIL_H
465 +#define _RPMUTIL_H
466 +
467 +#include <unistd.h>
468 +
469 +/** \file rpmio/rpmutil.h
470 + *
471 + * Miscellaneous utility macros:
472 + * - portability wrappers for various gcc extensions like __attribute__()
473 + * - ...
474 + *
475 + * Copied from glib, names replaced to avoid clashing with glib.
476 + *
477 + */
478 +
479 +/* Here we provide RPM_GNUC_EXTENSION as an alias for __extension__,
480 + * where this is valid. This allows for warningless compilation of
481 + * "long long" types even in the presence of '-ansi -pedantic'. 
482 + */
483 +#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
484 +#  define RPM_GNUC_EXTENSION __extension__
485 +#else
486 +#  define RPM_GNUC_EXTENSION
487 +#endif
488 +
489 +/* Provide macros to feature the GCC function attribute.
490 + */
491 +#if    __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
492 +#define RPM_GNUC_PURE                            \
493 +  __attribute__((__pure__))
494 +#define RPM_GNUC_MALLOC                        \
495 +  __attribute__((__malloc__))
496 +#else
497 +#define RPM_GNUC_PURE
498 +#define RPM_GNUC_MALLOC
499 +#endif
500 +
501 +#if     (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
502 +#define RPM_GNUC_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
503 +#define RPM_GNUC_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y)))
504 +#else
505 +#define RPM_GNUC_ALLOC_SIZE(x)
506 +#define RPM_GNUC_ALLOC_SIZE2(x,y)
507 +#endif
508 +
509 +#if     __GNUC__ >= 4
510 +#define RPM_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
511 +#else
512 +#define RPM_GNUC_NULL_TERMINATED
513 +#endif
514 +
515 +#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
516 +#define RPM_GNUC_PRINTF( format_idx, arg_idx )    \
517 +  __attribute__((__format__ (__printf__, format_idx, arg_idx)))
518 +#define RPM_GNUC_SCANF( format_idx, arg_idx )     \
519 +  __attribute__((__format__ (__scanf__, format_idx, arg_idx)))
520 +#define RPM_GNUC_FORMAT( arg_idx )                \
521 +  __attribute__((__format_arg__ (arg_idx)))
522 +#define RPM_GNUC_NORETURN                         \
523 +  __attribute__((__noreturn__))
524 +#define RPM_GNUC_CONST                            \
525 +  __attribute__((__const__))
526 +#define RPM_GNUC_UNUSED                           \
527 +  __attribute__((__unused__))
528 +#define RPM_GNUC_NO_INSTRUMENT                 \
529 +  __attribute__((__no_instrument_function__))
530 +#else   /* !__GNUC__ */
531 +#define RPM_GNUC_PRINTF( format_idx, arg_idx )
532 +#define RPM_GNUC_SCANF( format_idx, arg_idx )
533 +#define RPM_GNUC_FORMAT( arg_idx )
534 +#define RPM_GNUC_NORETURN
535 +#define RPM_GNUC_CONST
536 +#define RPM_GNUC_UNUSED
537 +#define RPM_GNUC_NO_INSTRUMENT
538 +#endif  /* !__GNUC__ */
539 +
540 +#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
541 +#define RPM_GNUC_DEPRECATED                            \
542 +  __attribute__((__deprecated__))
543 +#else
544 +#define RPM_GNUC_DEPRECATED
545 +#endif /* __GNUC__ */
546 +
547 +#if     __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
548 +#define RPM_GNUC_MAY_ALIAS __attribute__((may_alias))
549 +#define RPM_GNUC_NONNULL( ... )        \
550 +  __attribute__((__nonnull__ (__VA_ARGS__)))
551 +#else
552 +#define RPM_GNUC_MAY_ALIAS
553 +#define RPM_GNUC_NONNULL( ... )
554 +#endif
555 +
556 +#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
557 +#define RPM_GNUC_WARN_UNUSED_RESULT            \
558 +  __attribute__((warn_unused_result))
559 +#else
560 +#define RPM_GNUC_WARN_UNUSED_RESULT
561 +#endif /* __GNUC__ */
562 +
563 +#if    __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
564 +#  define RPM_GNUC_INTERNAL __attribute__((visibility("hidden")))
565 +#else
566 +#  define RPM_GNUC_INTERNAL
567 +#endif
568 +
569 +
570 +/* Guard C code in headers, while including them from C++ */
571 +#ifdef  __cplusplus
572 +# define RPM_BEGIN_DECLS  extern "C" {
573 +# define RPM_END_DECLS    }
574 +#else
575 +# define RPM_BEGIN_DECLS
576 +# define RPM_END_DECLS
577 +#endif
578 +
579 +#ifdef __cplusplus
580 +extern "C" {
581 +#endif
582 +
583 +/* Rpm specific allocators which never return NULL but terminate on failure */
584 +RPM_GNUC_MALLOC RPM_GNUC_ALLOC_SIZE(1)
585 +void * rmalloc(size_t size);
586 +
587 +RPM_GNUC_MALLOC RPM_GNUC_ALLOC_SIZE2(1,2)
588 +void * rcalloc(size_t nmemb, size_t size);
589 +
590 +RPM_GNUC_ALLOC_SIZE(2)
591 +void * rrealloc(void *ptr, size_t size);
592 +
593 +char * rstrdup(const char *str);
594 +
595 +/* Rpm specific free() which returns NULL */
596 +void * rfree(void *ptr);
597 +
598 +/** \ingroup rpmutil
599 + * Memory allocation failure callback prototype. When registered through
600 + * rpmSetMemFail(), this gets called if memory allocation through rmalloc()
601 + * and friends fails. If the application can somehow recover memory here,
602 + * it can return a newly allocated memory block of requested size, otherwise
603 + * it must return NULL after performing it's own shutdown deeds or 
604 + * terminate itself.
605 + * @param size         Size of allocation request in bytes
606 + * @param data         User data (or NULL)
607 + * @return             Allocated memory block of requested size or NULL
608 + */
609 +typedef void * (*rpmMemFailFunc) (size_t size, void *data);
610 +
611 +/** \ingroup rpmutil
612 + * Set memory allocation failure callback.
613 + * @param func         Allocation failure callback function
614 + * @param data         User data (or NULL)
615 + * @return             Previous callback function
616 + */
617 +rpmMemFailFunc rpmSetMemFail(rpmMemFailFunc func, void *data);
618 +
619 +#ifdef __cplusplus
620 +}
621 +#endif
622 +
623 +#endif /* _RPMUTIL_H */