Files
oxmc f6176009b1 Add recovery_ui and recovery_toolkit scaffolding (first draft, not build-tested)
Stages TWRP's GUI engine and standalone tooling as PawletOS-owned modules
instead of a bootable/recovery fork, per the plugin-architecture finding in
NOTES-ota-recovery-ab.md: stock recovery_main.cpp already dlopen()s
librecovery_ui_ext.so and dlsym()s make_device() from it at runtime, so the
UI layer doesn't require touching stock bootable/recovery at all. Confirmed
via source grep that recovery.cpp/install.cpp have zero references into the
partition manager/backup engine/GUI code and vice versa.

recovery_ui/: TWRP's gui/, minuitwrp/, libpixelflinger/ (copied verbatim,
GPL-3.0), plus a new device/ providing PawletTwrpUI (a ScreenRecoveryUI
subclass) and make_device() — written from scratch against stock's
RecoveryUI/ScreenRecoveryUI virtual-method contract, since TWRP's own fork
never ships a make_device() (every real TWRP device provides its own, and
no reference device tree was available to copy from). Top-level Android.bp
defines librecovery_ui_pawlet_twrp, the module TARGET_RECOVERY_UI_LIB should
point at. gui/Android.bp and minuitwrp/Android.bp had their include_dirs
rewritten for the new paths.

recovery_toolkit/: partition manager, backup engine (tar/digest/adbbu/apex),
filesystem/format support (exfat/dosfstools/gpt/fuse/mtp/crypto), scripting
(openrecoveryscript/orscmd/twrpinstall), shared helpers. Source only, no
Android.bp yet for any of it.

Known gap blocking recovery_ui from actually linking: gui/'s libguitwrp
depends on libaosprecovery, built from recovery_toolkit/helpers/twrp.cpp via
a Go Soong plugin (libaosprecovery_defaults.go) not yet ported. Neither repo
has been build-tested — no local AOSP build environment available in this
workspace. See each directory's README.md for a precise done/not-done
breakdown.
2026-07-11 16:34:35 -07:00

345 lines
6.3 KiB
C

/* listhash/libtar_hash.c. Generated from hash.c.in by configure. */
/*
** Copyright 1998-2002 University of Illinois Board of Trustees
** Copyright 1998-2002 Mark D. Roth
** All rights reserved.
**
** libtar_hash.c - hash table routines
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <config.h>
#include <compat.h>
#include <libtar_listhash.h>
#include <stdio.h>
#include <errno.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
#endif
/*
** libtar_hashptr_reset() - reset a hash pointer
*/
void
libtar_hashptr_reset(libtar_hashptr_t *hp)
{
libtar_listptr_reset(&(hp->node));
hp->bucket = -1;
}
/*
** libtar_hashptr_data() - retrieve the data being pointed to
*/
void *
libtar_hashptr_data(libtar_hashptr_t *hp)
{
return libtar_listptr_data(&(hp->node));
}
/*
** libtar_str_hashfunc() - default hash function, optimized for
** 7-bit strings
*/
unsigned int
libtar_str_hashfunc(char *key, unsigned int num_buckets)
{
#if 0
register unsigned result = 0;
register int i;
if (key == NULL)
return 0;
for (i = 0; *key != '\0' && i < 32; i++)
result = result * 33U + *key++;
return (result % num_buckets);
#else
if (key == NULL)
return 0;
return (key[0] % num_buckets);
#endif
}
/*
** libtar_hash_nents() - return number of elements from hash
*/
unsigned int
libtar_hash_nents(libtar_hash_t *h)
{
return h->nents;
}
/*
** libtar_hash_new() - create a new hash
*/
libtar_hash_t *
libtar_hash_new(int num, libtar_hashfunc_t hashfunc)
{
libtar_hash_t *hash;
hash = (libtar_hash_t *)calloc(1, sizeof(libtar_hash_t));
if (hash == NULL)
return NULL;
hash->numbuckets = num;
if (hashfunc != NULL)
hash->hashfunc = hashfunc;
else
hash->hashfunc = (libtar_hashfunc_t)libtar_str_hashfunc;
hash->table = (libtar_list_t **)calloc(num, sizeof(libtar_list_t *));
if (hash->table == NULL)
{
free(hash);
return NULL;
}
return hash;
}
/*
** libtar_hash_next() - get next element in hash
** returns:
** 1 data found
** 0 end of list
*/
int
libtar_hash_next(libtar_hash_t *h,
libtar_hashptr_t *hp)
{
#ifdef DS_DEBUG
LOG("==> libtar_hash_next(h=0x%lx, hp={%d,0x%lx})\n",
h, hp->bucket, hp->node);
#endif
if (hp->bucket >= 0 && hp->node != NULL &&
libtar_list_next(h->table[hp->bucket], &(hp->node)) != 0)
{
#ifdef DS_DEBUG
LOG(" libtar_hash_next(): found additional "
"data in current bucket (%d), returing 1\n",
hp->bucket);
#endif
return 1;
}
#ifdef DS_DEBUG
LOG(" libtar_hash_next(): done with bucket %d\n",
hp->bucket);
#endif
for (hp->bucket++; hp->bucket < h->numbuckets; hp->bucket++)
{
#ifdef DS_DEBUG
LOG(" libtar_hash_next(): "
"checking bucket %d\n", hp->bucket);
#endif
hp->node = NULL;
if (h->table[hp->bucket] != NULL &&
libtar_list_next(h->table[hp->bucket],
&(hp->node)) != 0)
{
#ifdef DS_DEBUG
LOG(" libtar_hash_next(): "
"found data in bucket %d, returing 1\n",
hp->bucket);
#endif
return 1;
}
}
if (hp->bucket == h->numbuckets)
{
#ifdef DS_DEBUG
LOG(" libtar_hash_next(): hash pointer "
"wrapped to 0\n");
#endif
hp->bucket = -1;
hp->node = NULL;
}
#ifdef DS_DEBUG
LOG("<== libtar_hash_next(): no more data, "
"returning 0\n");
#endif
return 0;
}
/*
** libtar_hash_del() - delete an entry from the hash
** returns:
** 0 success
** -1 (and sets errno) failure
*/
int
libtar_hash_del(libtar_hash_t *h,
libtar_hashptr_t *hp)
{
if (hp->bucket < 0
|| hp->bucket >= h->numbuckets
|| h->table[hp->bucket] == NULL
|| hp->node == NULL)
{
errno = EINVAL;
return -1;
}
libtar_list_del(h->table[hp->bucket], &(hp->node));
h->nents--;
return 0;
}
/*
** libtar_hash_empty() - empty the hash
*/
void
libtar_hash_empty(libtar_hash_t *h, libtar_freefunc_t freefunc)
{
int i;
for (i = 0; i < h->numbuckets; i++)
if (h->table[i] != NULL)
libtar_list_empty(h->table[i], freefunc);
h->nents = 0;
}
/*
** libtar_hash_free() - delete all of the nodes in the hash
*/
void
libtar_hash_free(libtar_hash_t *h, libtar_freefunc_t freefunc)
{
int i;
for (i = 0; i < h->numbuckets; i++)
if (h->table[i] != NULL)
libtar_list_free(h->table[i], freefunc);
free(h->table);
free(h);
}
/*
** libtar_hash_search() - iterative search for an element in a hash
** returns:
** 1 match found
** 0 no match
*/
int
libtar_hash_search(libtar_hash_t *h,
libtar_hashptr_t *hp, void *data,
libtar_matchfunc_t matchfunc)
{
while (libtar_hash_next(h, hp) != 0)
if ((*matchfunc)(data, libtar_listptr_data(&(hp->node))) != 0)
return 1;
return 0;
}
/*
** libtar_hash_getkey() - hash-based search for an element in a hash
** returns:
** 1 match found
** 0 no match
*/
int
libtar_hash_getkey(libtar_hash_t *h,
libtar_hashptr_t *hp, void *key,
libtar_matchfunc_t matchfunc)
{
#ifdef DS_DEBUG
LOG("==> libtar_hash_getkey(h=0x%lx, hp={%d,0x%lx}, "
"key=0x%lx, matchfunc=0x%lx)\n",
h, hp->bucket, hp->node, key, matchfunc);
#endif
if (hp->bucket == -1)
{
hp->bucket = (*(h->hashfunc))(key, h->numbuckets);
#ifdef DS_DEBUG
LOG(" libtar_hash_getkey(): hp->bucket "
"set to %d\n", hp->bucket);
#endif
}
if (h->table[hp->bucket] == NULL)
{
#ifdef DS_DEBUG
LOG(" libtar_hash_getkey(): no list "
"for bucket %d, returning 0\n", hp->bucket);
#endif
hp->bucket = -1;
return 0;
}
#ifdef DS_DEBUG
LOG("<== libtar_hash_getkey(): "
"returning libtar_list_search()\n");
#endif
return libtar_list_search(h->table[hp->bucket], &(hp->node),
key, matchfunc);
}
/*
** libtar_hash_add() - add an element to the hash
** returns:
** 0 success
** -1 (and sets errno) failure
*/
int
libtar_hash_add(libtar_hash_t *h, void *data)
{
int bucket, i;
#ifdef DS_DEBUG
LOG("==> libtar_hash_add(h=0x%lx, data=0x%lx)\n",
h, data);
#endif
bucket = (*(h->hashfunc))(data, h->numbuckets);
#ifdef DS_DEBUG
LOG(" libtar_hash_add(): inserting in bucket %d\n",
bucket);
#endif
if (h->table[bucket] == NULL)
{
#ifdef DS_DEBUG
LOG(" libtar_hash_add(): creating new list\n");
#endif
h->table[bucket] = libtar_list_new(LIST_QUEUE, NULL);
}
#ifdef DS_DEBUG
LOG("<== libtar_hash_add(): "
"returning libtar_list_add()\n");
#endif
i = libtar_list_add(h->table[bucket], data);
if (i == 0)
h->nents++;
return i;
}