registry_url.c 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "daemon/common.h"
  3. #include "registry_internals.h"
  4. // ----------------------------------------------------------------------------
  5. // REGISTRY_URL
  6. int registry_url_compare(void *a, void *b) {
  7. if(((REGISTRY_URL *)a)->hash < ((REGISTRY_URL *)b)->hash) return -1;
  8. else if(((REGISTRY_URL *)a)->hash > ((REGISTRY_URL *)b)->hash) return 1;
  9. else return strcmp(((REGISTRY_URL *)a)->url, ((REGISTRY_URL *)b)->url);
  10. }
  11. inline REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) {
  12. return (REGISTRY_URL *)avl_insert(&(registry.registry_urls_root_index), (avl_t *)(u));
  13. }
  14. inline REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) {
  15. return (REGISTRY_URL *)avl_remove(&(registry.registry_urls_root_index), (avl_t *)(u));
  16. }
  17. REGISTRY_URL *registry_url_get(const char *url, size_t urllen) {
  18. // protection from too big URLs
  19. if(urllen > registry.max_url_length)
  20. urllen = registry.max_url_length;
  21. debug(D_REGISTRY, "Registry: registry_url_get('%s', %zu)", url, urllen);
  22. char buf[sizeof(REGISTRY_URL) + urllen]; // no need for +1, 1 is already in REGISTRY_URL
  23. REGISTRY_URL *n = (REGISTRY_URL *)&buf[0];
  24. n->len = (uint16_t)urllen;
  25. strncpyz(n->url, url, n->len);
  26. n->hash = simple_hash(n->url);
  27. REGISTRY_URL *u = (REGISTRY_URL *)avl_search(&(registry.registry_urls_root_index), (avl_t *)n);
  28. if(!u) {
  29. debug(D_REGISTRY, "Registry: registry_url_get('%s', %zu): allocating %zu bytes", url, urllen, sizeof(REGISTRY_URL) + urllen);
  30. u = callocz(1, sizeof(REGISTRY_URL) + urllen); // no need for +1, 1 is already in REGISTRY_URL
  31. // a simple strcpy() should do the job
  32. // but I prefer to be safe, since the caller specified urllen
  33. u->len = (uint16_t)urllen;
  34. strncpyz(u->url, url, u->len);
  35. u->links = 0;
  36. u->hash = simple_hash(u->url);
  37. registry.urls_memory += sizeof(REGISTRY_URL) + urllen; // no need for +1, 1 is already in REGISTRY_URL
  38. debug(D_REGISTRY, "Registry: registry_url_get('%s'): indexing it", url);
  39. n = registry_url_index_add(u);
  40. if(n != u) {
  41. error("INTERNAL ERROR: registry_url_get(): url '%s' already exists in the registry as '%s'", u->url, n->url);
  42. freez(u);
  43. u = n;
  44. }
  45. else
  46. registry.urls_count++;
  47. }
  48. return u;
  49. }
  50. void registry_url_link(REGISTRY_URL *u) {
  51. u->links++;
  52. debug(D_REGISTRY, "Registry: registry_url_link('%s'): URL has now %u links", u->url, u->links);
  53. }
  54. void registry_url_unlink(REGISTRY_URL *u) {
  55. u->links--;
  56. if(!u->links) {
  57. debug(D_REGISTRY, "Registry: registry_url_unlink('%s'): No more links for this URL", u->url);
  58. REGISTRY_URL *n = registry_url_index_del(u);
  59. if(!n) {
  60. error("INTERNAL ERROR: registry_url_unlink('%s'): cannot find url in index", u->url);
  61. }
  62. else {
  63. if(n != u) {
  64. error("INTERNAL ERROR: registry_url_unlink('%s'): deleted different url '%s'", u->url, n->url);
  65. }
  66. registry.urls_memory -= sizeof(REGISTRY_URL) + n->len; // no need for +1, 1 is already in REGISTRY_URL
  67. freez(n);
  68. }
  69. }
  70. else
  71. debug(D_REGISTRY, "Registry: registry_url_unlink('%s'): URL has %u links left", u->url, u->links);
  72. }