2008-04-17 14:09:13 +00:00
|
|
|
/* apk_defines.c - Alpine Package Keeper (APK)
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
|
2011-09-13 08:53:01 +00:00
|
|
|
* Copyright (C) 2008-2011 Timo Teräs <timo.teras@iki.fi>
|
2008-04-17 14:09:13 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2009-06-25 08:09:40 +00:00
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
2008-04-17 14:09:13 +00:00
|
|
|
* under the terms of the GNU General Public License version 2 as published
|
|
|
|
* by the Free Software Foundation. See http://www.gnu.org/ for details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef APK_DEFINES_H
|
|
|
|
#define APK_DEFINES_H
|
|
|
|
|
2013-07-02 07:51:27 +00:00
|
|
|
#include <endian.h>
|
2009-01-06 17:19:52 +00:00
|
|
|
#include <string.h>
|
2019-06-03 13:18:29 +00:00
|
|
|
#include <time.h>
|
2008-11-14 12:26:59 +00:00
|
|
|
|
2013-06-11 11:06:06 +00:00
|
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
|
|
#define BIT(x) (1 << (x))
|
2013-06-17 14:28:03 +00:00
|
|
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
2013-06-11 11:06:06 +00:00
|
|
|
#define max(a, b) ((a) > (b) ? (a) : (b))
|
2008-04-17 14:09:13 +00:00
|
|
|
|
|
|
|
#ifndef TRUE
|
|
|
|
#define TRUE 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef FALSE
|
|
|
|
#define FALSE 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef NULL
|
|
|
|
#define NULL 0L
|
|
|
|
#endif
|
|
|
|
|
2015-04-24 06:31:28 +00:00
|
|
|
#define EAPKBADURL 1024
|
|
|
|
#define EAPKSTALEINDEX 1025
|
2015-04-22 06:40:03 +00:00
|
|
|
|
2014-10-08 08:13:21 +00:00
|
|
|
static inline void *ERR_PTR(long error) { return (void*) error; }
|
|
|
|
static inline void *ERR_CAST(const void *ptr) { return (void*) ptr; }
|
|
|
|
static inline int PTR_ERR(const void *ptr) { return (int)(long) ptr; }
|
|
|
|
static inline int IS_ERR(const void *ptr) { return (unsigned long)ptr >= (unsigned long)-4095; }
|
|
|
|
static inline int IS_ERR_OR_NULL(const void *ptr) { return IS_ERR(ptr) || !ptr; }
|
|
|
|
|
2009-07-14 11:08:15 +00:00
|
|
|
#if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ < 96
|
|
|
|
#define __builtin_expect(x, expected_value) (x)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef likely
|
|
|
|
#define likely(x) __builtin_expect((!!(x)),1)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef unlikely
|
|
|
|
#define unlikely(x) __builtin_expect((!!(x)),0)
|
|
|
|
#endif
|
|
|
|
|
2020-02-04 08:33:56 +00:00
|
|
|
#ifndef typeof
|
|
|
|
#define typeof(x) __typeof__(x)
|
|
|
|
#endif
|
|
|
|
|
2008-04-17 14:09:13 +00:00
|
|
|
#ifndef container_of
|
|
|
|
#define container_of(ptr, type, member) ({ \
|
|
|
|
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
|
|
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
|
|
|
#endif
|
|
|
|
|
2010-03-05 08:13:25 +00:00
|
|
|
extern int apk_verbosity;
|
2018-01-03 13:17:11 +00:00
|
|
|
extern unsigned int apk_flags, apk_force;
|
2010-12-14 15:04:26 +00:00
|
|
|
extern const char *apk_arch;
|
2011-01-01 13:48:10 +00:00
|
|
|
extern char **apk_argv;
|
2009-04-14 15:48:02 +00:00
|
|
|
|
|
|
|
#define APK_SIMULATE 0x0002
|
|
|
|
#define APK_CLEAN_PROTECTED 0x0004
|
|
|
|
#define APK_PROGRESS 0x0008
|
2009-04-15 06:56:09 +00:00
|
|
|
#define APK_RECURSIVE 0x0020
|
2009-07-22 13:06:34 +00:00
|
|
|
#define APK_ALLOW_UNTRUSTED 0x0100
|
2009-07-22 18:34:25 +00:00
|
|
|
#define APK_PURGE 0x0200
|
2009-07-24 11:18:07 +00:00
|
|
|
#define APK_INTERACTIVE 0x0400
|
2009-08-06 13:00:20 +00:00
|
|
|
#define APK_NO_NETWORK 0x1000
|
2009-12-21 14:53:47 +00:00
|
|
|
#define APK_OVERLAY_FROM_STDIN 0x2000
|
2013-09-10 10:51:30 +00:00
|
|
|
#define APK_NO_SCRIPTS 0x4000
|
2015-12-07 10:41:13 +00:00
|
|
|
#define APK_NO_CACHE 0x8000
|
2017-12-29 20:10:44 +00:00
|
|
|
#define APK_NO_COMMIT_HOOKS 0x00010000
|
2008-04-22 06:04:20 +00:00
|
|
|
|
2018-01-03 13:17:11 +00:00
|
|
|
#define APK_FORCE_OVERWRITE BIT(0)
|
|
|
|
#define APK_FORCE_OLD_APK BIT(1)
|
|
|
|
#define APK_FORCE_BROKEN_WORLD BIT(2)
|
|
|
|
#define APK_FORCE_REFRESH BIT(3)
|
|
|
|
#define APK_FORCE_NON_REPOSITORY BIT(4)
|
|
|
|
#define APK_FORCE_BINARY_STDOUT BIT(5)
|
|
|
|
|
2012-02-22 06:45:40 +00:00
|
|
|
/* default architecture for APK packages. */
|
|
|
|
#if defined(__x86_64__)
|
|
|
|
#define APK_DEFAULT_ARCH "x86_64"
|
|
|
|
#elif defined(__i386__)
|
|
|
|
#define APK_DEFAULT_ARCH "x86"
|
|
|
|
#elif defined(__powerpc__) && !defined(__powerpc64__)
|
|
|
|
#define APK_DEFAULT_ARCH "ppc"
|
2017-01-16 19:16:04 +00:00
|
|
|
#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
2012-02-22 06:45:40 +00:00
|
|
|
#define APK_DEFAULT_ARCH "ppc64"
|
2017-01-16 19:16:04 +00:00
|
|
|
#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
#define APK_DEFAULT_ARCH "ppc64le"
|
2015-11-12 07:24:02 +00:00
|
|
|
#elif defined(__arm__) && defined(__ARM_PCS_VFP) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __ARM_ARCH>=7
|
|
|
|
#define APK_DEFAULT_ARCH "armv7"
|
2013-09-05 08:51:24 +00:00
|
|
|
#elif defined(__arm__) && defined(__ARM_PCS_VFP) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
#define APK_DEFAULT_ARCH "armhf"
|
2013-07-02 07:51:27 +00:00
|
|
|
#elif defined(__arm__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
#define APK_DEFAULT_ARCH "armel"
|
2016-07-08 08:09:00 +00:00
|
|
|
#elif defined(__aarch64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
#define APK_DEFAULT_ARCH "aarch64"
|
2016-11-20 15:39:44 +00:00
|
|
|
#elif defined(__s390x__)
|
|
|
|
#define APK_DEFAULT_ARCH "s390x"
|
2017-12-10 00:19:26 +00:00
|
|
|
#elif defined(__mips64) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
|
|
#define APK_DEFAULT_ARCH "mips64"
|
|
|
|
#elif defined(__mips64) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
#define APK_DEFAULT_ARCH "mips64el"
|
2017-12-14 17:06:39 +00:00
|
|
|
#elif defined(__mips__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
2017-12-10 00:19:26 +00:00
|
|
|
#define APK_DEFAULT_ARCH "mips"
|
|
|
|
#elif defined(__mips__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
#define APK_DEFAULT_ARCH "mipsel"
|
2012-02-22 06:45:40 +00:00
|
|
|
#else
|
2016-07-08 08:09:00 +00:00
|
|
|
#error APK_DEFAULT_ARCH not detected for this architecture
|
2012-02-22 06:45:40 +00:00
|
|
|
#endif
|
|
|
|
|
2013-05-30 05:46:30 +00:00
|
|
|
#define APK_MAX_REPOS 32 /* see struct apk_package */
|
2012-02-22 06:45:40 +00:00
|
|
|
#define APK_MAX_TAGS 16 /* see solver; unsigned short */
|
|
|
|
#define APK_CACHE_CSUM_BYTES 4
|
|
|
|
|
2009-01-07 19:45:11 +00:00
|
|
|
static inline size_t apk_calc_installed_size(size_t size)
|
|
|
|
{
|
|
|
|
const size_t bsize = 4 * 1024;
|
|
|
|
|
|
|
|
return (size + bsize - 1) & ~(bsize - 1);
|
|
|
|
}
|
|
|
|
static inline size_t muldiv(size_t a, size_t b, size_t c)
|
|
|
|
{
|
|
|
|
unsigned long long tmp;
|
|
|
|
tmp = a;
|
|
|
|
tmp *= b;
|
|
|
|
tmp /= c;
|
|
|
|
return (size_t) tmp;
|
|
|
|
}
|
2017-06-01 04:24:15 +00:00
|
|
|
static inline size_t mulmod(size_t a, size_t b, size_t c)
|
|
|
|
{
|
|
|
|
unsigned long long tmp;
|
|
|
|
tmp = a;
|
|
|
|
tmp *= b;
|
|
|
|
tmp %= c;
|
|
|
|
return (size_t) tmp;
|
|
|
|
}
|
2009-01-07 19:45:11 +00:00
|
|
|
|
2020-02-21 07:31:21 +00:00
|
|
|
static inline uint32_t get_unaligned32(const void *ptr)
|
|
|
|
{
|
|
|
|
#if defined(__x86_64__) || defined(__i386__)
|
|
|
|
return *(const uint32_t *)ptr;
|
|
|
|
#else
|
|
|
|
const uint8_t *p = ptr;
|
|
|
|
return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-01-07 19:45:11 +00:00
|
|
|
typedef void (*apk_progress_cb)(void *cb_ctx, size_t);
|
|
|
|
|
2010-06-05 09:06:41 +00:00
|
|
|
void *apk_array_resize(void *array, size_t new_size, size_t elem_size);
|
|
|
|
|
2008-04-17 14:09:13 +00:00
|
|
|
#define APK_ARRAY(array_type_name, elem_type_name) \
|
|
|
|
struct array_type_name { \
|
2011-09-20 14:07:47 +00:00
|
|
|
size_t num; \
|
2008-04-17 14:09:13 +00:00
|
|
|
elem_type_name item[]; \
|
|
|
|
}; \
|
2010-06-05 09:06:41 +00:00
|
|
|
static inline void \
|
|
|
|
array_type_name##_init(struct array_type_name **a) \
|
|
|
|
{ \
|
|
|
|
*a = apk_array_resize(NULL, 0, 0); \
|
|
|
|
} \
|
|
|
|
static inline void \
|
|
|
|
array_type_name##_free(struct array_type_name **a) \
|
|
|
|
{ \
|
|
|
|
*a = apk_array_resize(*a, 0, 0); \
|
|
|
|
} \
|
|
|
|
static inline void \
|
|
|
|
array_type_name##_resize(struct array_type_name **a, size_t size)\
|
2008-04-17 14:09:13 +00:00
|
|
|
{ \
|
2010-06-05 09:06:41 +00:00
|
|
|
*a = apk_array_resize(*a, size, sizeof(elem_type_name));\
|
2008-04-17 14:09:13 +00:00
|
|
|
} \
|
2011-09-09 13:31:11 +00:00
|
|
|
static inline void \
|
|
|
|
array_type_name##_copy(struct array_type_name **a, struct array_type_name *b)\
|
|
|
|
{ \
|
2012-01-06 08:25:28 +00:00
|
|
|
if (*a == b) return; \
|
2011-09-09 13:31:11 +00:00
|
|
|
*a = apk_array_resize(*a, b->num, sizeof(elem_type_name));\
|
|
|
|
memcpy((*a)->item, b->item, b->num * sizeof(elem_type_name));\
|
|
|
|
} \
|
2008-04-17 14:09:13 +00:00
|
|
|
static inline elem_type_name * \
|
|
|
|
array_type_name##_add(struct array_type_name **a) \
|
|
|
|
{ \
|
2010-06-05 09:06:41 +00:00
|
|
|
int size = 1 + (*a)->num; \
|
|
|
|
*a = apk_array_resize(*a, size, sizeof(elem_type_name));\
|
2008-04-17 14:09:13 +00:00
|
|
|
return &(*a)->item[size-1]; \
|
|
|
|
}
|
|
|
|
|
2008-11-14 12:26:59 +00:00
|
|
|
APK_ARRAY(apk_string_array, char *);
|
|
|
|
|
2013-06-13 15:20:39 +00:00
|
|
|
#define foreach_array_item(iter, array) \
|
|
|
|
for (iter = &(array)->item[0]; iter < &(array)->item[(array)->num]; iter++)
|
|
|
|
|
2008-04-17 14:09:13 +00:00
|
|
|
#define LIST_END (void *) 0xe01
|
|
|
|
#define LIST_POISON1 (void *) 0xdeadbeef
|
|
|
|
#define LIST_POISON2 (void *) 0xabbaabba
|
|
|
|
|
|
|
|
struct hlist_head {
|
|
|
|
struct hlist_node *first;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct hlist_node {
|
|
|
|
struct hlist_node *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline int hlist_empty(const struct hlist_head *h)
|
|
|
|
{
|
|
|
|
return !h->first;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int hlist_hashed(const struct hlist_node *n)
|
|
|
|
{
|
|
|
|
return n->next != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void __hlist_del(struct hlist_node *n, struct hlist_node **pprev)
|
|
|
|
{
|
|
|
|
*pprev = n->next;
|
2008-04-22 08:16:26 +00:00
|
|
|
n->next = NULL;
|
2008-04-17 14:09:13 +00:00
|
|
|
}
|
|
|
|
|
2008-04-22 08:16:26 +00:00
|
|
|
static inline void hlist_del(struct hlist_node *n, struct hlist_head *h)
|
2008-04-17 14:09:13 +00:00
|
|
|
{
|
2008-04-22 08:16:26 +00:00
|
|
|
struct hlist_node **pp = &h->first;
|
|
|
|
|
|
|
|
while (*pp != NULL && *pp != LIST_END && *pp != n)
|
|
|
|
pp = &(*pp)->next;
|
|
|
|
|
|
|
|
if (*pp == n)
|
|
|
|
__hlist_del(n, pp);
|
2008-04-17 14:09:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
|
|
|
{
|
|
|
|
struct hlist_node *first = h->first;
|
|
|
|
|
|
|
|
n->next = first ? first : LIST_END;
|
|
|
|
h->first = n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void hlist_add_after(struct hlist_node *n, struct hlist_node **prev)
|
|
|
|
{
|
|
|
|
n->next = *prev ? *prev : LIST_END;
|
|
|
|
*prev = n;
|
|
|
|
}
|
|
|
|
|
2008-04-22 08:16:26 +00:00
|
|
|
static inline struct hlist_node **hlist_tail_ptr(struct hlist_head *h)
|
|
|
|
{
|
|
|
|
struct hlist_node *n = h->first;
|
|
|
|
if (n == NULL || n == LIST_END)
|
|
|
|
return &h->first;
|
|
|
|
while (n->next != NULL && n->next != LIST_END)
|
|
|
|
n = n->next;
|
|
|
|
return &n->next;
|
|
|
|
}
|
|
|
|
|
2008-04-17 14:09:13 +00:00
|
|
|
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
|
|
|
|
|
|
|
#define hlist_for_each(pos, head) \
|
|
|
|
for (pos = (head)->first; pos && pos != LIST_END; \
|
|
|
|
pos = pos->next)
|
|
|
|
|
|
|
|
#define hlist_for_each_safe(pos, n, head) \
|
|
|
|
for (pos = (head)->first; pos && pos != LIST_END && \
|
|
|
|
({ n = pos->next; 1; }); \
|
|
|
|
pos = n)
|
|
|
|
|
|
|
|
#define hlist_for_each_entry(tpos, pos, head, member) \
|
|
|
|
for (pos = (head)->first; \
|
|
|
|
pos && pos != LIST_END && \
|
|
|
|
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
|
|
|
pos = pos->next)
|
|
|
|
|
|
|
|
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
|
|
|
for (pos = (head)->first; \
|
|
|
|
pos && pos != LIST_END && ({ n = pos->next; 1; }) && \
|
|
|
|
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
|
|
|
pos = n)
|
|
|
|
|
2008-11-27 18:25:01 +00:00
|
|
|
|
|
|
|
struct list_head {
|
|
|
|
struct list_head *next, *prev;
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline void list_init(struct list_head *list)
|
|
|
|
{
|
|
|
|
list->next = list;
|
|
|
|
list->prev = list;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void __list_add(struct list_head *new,
|
|
|
|
struct list_head *prev,
|
|
|
|
struct list_head *next)
|
|
|
|
{
|
|
|
|
next->prev = new;
|
|
|
|
new->next = next;
|
|
|
|
new->prev = prev;
|
|
|
|
prev->next = new;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void list_add(struct list_head *new, struct list_head *head)
|
|
|
|
{
|
|
|
|
__list_add(new, head, head->next);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
|
|
|
{
|
|
|
|
__list_add(new, head->prev, head);
|
|
|
|
}
|
|
|
|
|
2013-06-11 11:06:06 +00:00
|
|
|
static inline void __list_del(struct list_head *prev, struct list_head *next)
|
2008-11-27 18:25:01 +00:00
|
|
|
{
|
|
|
|
next->prev = prev;
|
|
|
|
prev->next = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void list_del(struct list_head *entry)
|
|
|
|
{
|
|
|
|
__list_del(entry->prev, entry->next);
|
|
|
|
entry->next = LIST_POISON1;
|
|
|
|
entry->prev = LIST_POISON2;
|
|
|
|
}
|
|
|
|
|
2013-06-11 11:06:06 +00:00
|
|
|
static inline void list_del_init(struct list_head *entry)
|
|
|
|
{
|
|
|
|
__list_del(entry->prev, entry->next);
|
|
|
|
entry->next = NULL;
|
|
|
|
entry->prev = NULL;
|
|
|
|
}
|
|
|
|
|
2008-11-27 18:25:01 +00:00
|
|
|
static inline int list_hashed(const struct list_head *n)
|
|
|
|
{
|
2009-08-13 11:10:30 +00:00
|
|
|
return n->next != n && n->next != NULL;
|
2008-11-27 18:25:01 +00:00
|
|
|
}
|
|
|
|
|
2012-02-18 09:54:17 +00:00
|
|
|
static inline int list_empty(const struct list_head *n)
|
|
|
|
{
|
|
|
|
return n->next == n;
|
|
|
|
}
|
|
|
|
|
2013-06-11 11:06:06 +00:00
|
|
|
static inline struct list_head *__list_pop(struct list_head *head)
|
|
|
|
{
|
|
|
|
struct list_head *n = head->next;
|
|
|
|
list_del_init(n);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2008-11-27 18:25:01 +00:00
|
|
|
#define list_entry(ptr, type, member) container_of(ptr,type,member)
|
|
|
|
|
2013-06-11 11:06:06 +00:00
|
|
|
#define list_pop(head, type, member) container_of(__list_pop(head),type,member)
|
|
|
|
|
2008-11-27 18:25:01 +00:00
|
|
|
#define list_for_each(pos, head) \
|
|
|
|
for (pos = (head)->next; pos != (head); pos = pos->next)
|
|
|
|
|
|
|
|
#define list_for_each_safe(pos, n, head) \
|
|
|
|
for (pos = (head)->next, n = pos->next; pos != (head); \
|
|
|
|
pos = n, n = pos->next)
|
|
|
|
|
|
|
|
#define list_for_each_entry(pos, head, member) \
|
|
|
|
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
|
|
|
&pos->member != (head); \
|
|
|
|
pos = list_entry(pos->member.next, typeof(*pos), member))
|
|
|
|
|
|
|
|
#define list_for_each_entry_safe(pos, n, head, member) \
|
|
|
|
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
|
|
|
n = list_entry(pos->member.next, typeof(*pos), member); \
|
|
|
|
&pos->member != (head); \
|
|
|
|
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
|
|
|
|
2008-04-17 14:09:13 +00:00
|
|
|
#endif
|