Gentoo Archives: gentoo-commits

From: Fabian Groffen <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage-utils:master commit in: libq/
Date: Sun, 05 May 2019 08:58:37
Message-Id: 1557046007.0bbdb3f1328dcd0dd91c1ea502da3ba3e1fd364d.grobian@gentoo
1 commit: 0bbdb3f1328dcd0dd91c1ea502da3ba3e1fd364d
2 Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
3 AuthorDate: Sun May 5 08:46:47 2019 +0000
4 Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
5 CommitDate: Sun May 5 08:46:47 2019 +0000
6 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=0bbdb3f1
7
8 libq/cache: add support for reading metadata.xml
9
10 currently only one field is extracted: email
11
12 Bug: https://bugs.gentoo.org/685052
13 Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
14
15 libq/cache.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
16 libq/cache.h | 9 ++++++
17 2 files changed, 106 insertions(+), 2 deletions(-)
18
19 diff --git a/libq/cache.c b/libq/cache.c
20 index a8b4ede..c0ea85e 100644
21 --- a/libq/cache.c
22 +++ b/libq/cache.c
23 @@ -167,6 +167,9 @@ cache_next_pkg(cache_cat_ctx *cat_ctx)
24 ctx->ebuilddir_pkg_ctx = NULL;
25 return NULL;
26 }
27 +
28 + /* "zap" the pkg such that it looks like CAT/P */
29 + ctx->ebuilddir_cat_ctx->name = cat_ctx->name;
30 }
31
32 ret = q_vdb_next_pkg(ctx->ebuilddir_cat_ctx);
33 @@ -178,8 +181,6 @@ cache_next_pkg(cache_cat_ctx *cat_ctx)
34 cache_close_pkg(ret);
35 ret = NULL;
36 } else {
37 - /* "zap" the pkg such that it looks like CAT/P */
38 - ret->cat_ctx->name = cat_ctx->name;
39 *p = '\0';
40 }
41 }
42 @@ -529,6 +530,100 @@ cache_close_meta(cache_pkg_meta *cache)
43 free(cache);
44 }
45
46 +cache_metadata_xml *
47 +cache_read_metadata(cache_pkg_ctx *pkg_ctx)
48 +{
49 + cache_ctx *ctx = (cache_ctx *)(pkg_ctx->cat_ctx->ctx);
50 + int fd;
51 + FILE *f;
52 + struct stat s;
53 + char *xbuf;
54 + char *p;
55 + char *q;
56 + size_t len;
57 + cache_metadata_xml *ret = NULL;
58 + struct elist *emailw = NULL;
59 + char buf[_Q_PATH_MAX];
60 +
61 + /* lame @$$ XML parsing, I don't want to pull in a real parser
62 + * library because we only retrieve one element for now: email
63 + * technically speaking, email may occur only once in a maintainer
64 + * tag, but practically speaking we don't care at all, so we can
65 + * just extract everything between <email> and </email> */
66 +
67 + if (ctx->cachetype == CACHE_EBUILD) {
68 + fd = openat(pkg_ctx->cat_ctx->fd, "metadata", O_RDONLY | O_CLOEXEC);
69 + } else {
70 + depend_atom *atom;
71 + snprintf(buf, sizeof(buf), "%s/%s",
72 + pkg_ctx->cat_ctx->name, pkg_ctx->name);
73 + atom = atom_explode(buf);
74 + snprintf(buf, sizeof(buf), "../../%s/%s/metadata.xml",
75 + atom->CATEGORY, atom->PN);
76 + atom_implode(atom);
77 + fd = openat(ctx->vdb_fd, buf, O_RDONLY | O_CLOEXEC);
78 + }
79 +
80 + if (fd == -1)
81 + return NULL;
82 +
83 + if ((f = fdopen(fd, "r")) == NULL) {
84 + close(fd);
85 + return NULL;
86 + }
87 +
88 + if (fstat(fd, &s) != 0) {
89 + fclose(f);
90 + return NULL;
91 + }
92 +
93 + len = sizeof(*ret) + s.st_size + 1;
94 + p = xbuf = xzalloc(len);
95 + if ((off_t)fread(p, 1, s.st_size, f) != s.st_size) {
96 + free(p);
97 + fclose(f);
98 + pkg_ctx->fd = -1;
99 + return NULL;
100 + }
101 +
102 + ret = xmalloc(sizeof(*ret));
103 + ret->email = NULL;
104 +
105 + while ((q = strstr(p, "<email>")) != NULL) {
106 + p = q + sizeof("<email>") - 1;
107 + if ((q = strstr(p, "</email>")) == NULL)
108 + break;
109 + *q = '\0';
110 + rmspace(p);
111 + if (emailw == NULL) {
112 + emailw = ret->email = xmalloc(sizeof(*emailw));
113 + } else {
114 + emailw = emailw->next = xmalloc(sizeof(*emailw));
115 + }
116 + emailw->next = NULL;
117 + emailw->addr = xstrdup(p);
118 + p = q + 1;
119 + }
120 +
121 + free(xbuf);
122 + fclose(f);
123 + return ret;
124 +}
125 +
126 +void
127 +cache_close_metadata(cache_metadata_xml *meta_ctx)
128 +{
129 + struct elist *e;
130 + while (meta_ctx->email != NULL) {
131 + e = meta_ctx->email;
132 + free(e->addr);
133 + e = e->next;
134 + free(meta_ctx->email);
135 + meta_ctx->email = e;
136 + }
137 + free(meta_ctx);
138 +}
139 +
140 void
141 cache_close_pkg(cache_pkg_ctx *pkg_ctx)
142 {
143
144 diff --git a/libq/cache.h b/libq/cache.h
145 index 74f45b8..2ad2e78 100644
146 --- a/libq/cache.h
147 +++ b/libq/cache.h
148 @@ -43,6 +43,13 @@ typedef struct {
149 char *_md5_;
150 } cache_pkg_meta;
151
152 +typedef struct {
153 + struct elist {
154 + char *addr;
155 + struct elist *next;
156 + } *email;
157 +} cache_metadata_xml;
158 +
159 typedef int (cache_pkg_cb)(cache_pkg_ctx *, void *priv);
160 typedef int (cache_cat_filter)(cache_cat_ctx *, void *priv);
161
162 @@ -55,6 +62,8 @@ cache_pkg_ctx *cache_open_pkg(cache_cat_ctx *cat_ctx, const char *name);
163 cache_pkg_ctx *cache_next_pkg(cache_cat_ctx *cat_ctx);
164 cache_pkg_meta *cache_pkg_read(cache_pkg_ctx *pkg_ctx);
165 void cache_close_meta(cache_pkg_meta *cache);
166 +cache_metadata_xml *cache_read_metadata(cache_pkg_ctx *pkg_ctx);
167 +void cache_close_metadata(cache_metadata_xml *meta_ctx);
168 void cache_close_pkg(cache_pkg_ctx *pkg_ctx);
169 int cache_foreach_pkg(const char *sroot, const char *portdir,
170 cache_pkg_cb callback, void *priv, cache_cat_filter filter);