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: /
Date: Thu, 02 Jan 2020 15:09:53
Message-Id: 1577977164.5d0261aabae596a7beb9b6879201c43a064be800.grobian@gentoo
1 commit: 5d0261aabae596a7beb9b6879201c43a064be800
2 Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
3 AuthorDate: Thu Jan 2 14:59:24 2020 +0000
4 Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
5 CommitDate: Thu Jan 2 14:59:24 2020 +0000
6 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=5d0261aa
7
8 qpkg: make use of tree being able to traverse binpkg trees
9
10 Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
11
12 qpkg.c | 172 ++++++++++++++++++++++++++---------------------------------------
13 1 file changed, 69 insertions(+), 103 deletions(-)
14
15 diff --git a/qpkg.c b/qpkg.c
16 index 771241c..b210b09 100644
17 --- a/qpkg.c
18 +++ b/qpkg.c
19 @@ -54,115 +54,79 @@ extern char pretend;
20 static char *qpkg_bindir = NULL;
21 static int eclean = 0;
22
23 -/* checks to make sure this is a .tbz2 file. used by scandir() */
24 -static int
25 -filter_tbz2(const struct dirent *dentry)
26 -{
27 - if (dentry->d_name[0] == '.')
28 - return 0;
29 - if (strlen(dentry->d_name) < 6)
30 - return 0;
31 - return !strcmp(".tbz2", dentry->d_name + strlen(dentry->d_name) - 5);
32 -}
33 -
34 -/* process a single dir for cleaning. dir can be a $PKGDIR, $PKGDIR/All/, $PKGDIR/$CAT */
35 -static uint64_t
36 -qpkg_clean_dir(char *dirp, set *vdb)
37 -{
38 - set *ll = NULL;
39 - struct dirent **fnames;
40 - int i, count;
41 - char buf[_Q_PATH_MAX * 2];
42 - struct stat st;
43 - uint64_t num_all_bytes = 0;
44 - size_t disp_units = 0;
45 - char **t;
46 - bool ignore;
47 -
48 - if (dirp == NULL)
49 - return 0;
50 - if (chdir(dirp) != 0)
51 - return 0;
52 - if ((count = scandir(".", &fnames, filter_tbz2, alphasort)) < 0)
53 - return 0;
54 -
55 - /* create copy of vdb with only basenames */
56 - for ((void)list_set(vdb, &t); *t != NULL; t++)
57 - ll = add_set_unique(basename(*t), ll, &ignore);
58 -
59 - for (i = 0; i < count; i++) {
60 - fnames[i]->d_name[strlen(fnames[i]->d_name)-5] = 0;
61 - if (contains_set(fnames[i]->d_name, ll))
62 - continue;
63 - snprintf(buf, sizeof(buf), "%s.tbz2", fnames[i]->d_name);
64 - if (lstat(buf, &st) != -1) {
65 - if (S_ISREG(st.st_mode)) {
66 - disp_units = KILOBYTE;
67 - if ((st.st_size / KILOBYTE) > 1000)
68 - disp_units = MEGABYTE;
69 - num_all_bytes += st.st_size;
70 - qprintf(" %s[%s %3s %s %s] %s%s%s\n",
71 - DKBLUE, GREEN,
72 - make_human_readable_str(st.st_size, 1, disp_units),
73 - disp_units == MEGABYTE ? "MiB" : "KiB",
74 - DKBLUE, BLUE, fnames[i]->d_name, NORM);
75 - }
76 - if (!pretend)
77 - unlink(buf);
78 - }
79 - }
80 -
81 - free_set(ll);
82 - scandir_free(fnames, count);
83 -
84 - return num_all_bytes;
85 -}
86 -
87 /* figure out what dirs we want to process for cleaning and display results. */
88 static int
89 qpkg_clean(char *dirp)
90 {
91 - int i, count;
92 + size_t n;
93 size_t disp_units = 0;
94 - uint64_t num_all_bytes;
95 - struct dirent **dnames;
96 - set *vdb = NULL;
97 + uint64_t num_all_bytes = 0;
98 + set *known_pkgs = NULL;
99 + set *bin_pkgs = NULL;
100 + DECLARE_ARRAY(bins);
101 tree_ctx *t;
102 + tree_ctx *pkgs;
103 + char *binatomstr;
104 + depend_atom *atom;
105 + char buf[_Q_PATH_MAX];
106 + struct stat st;
107
108 - if (chdir(dirp) != 0)
109 - return 1;
110 - if ((count = scandir(".", &dnames, filter_hidden, alphasort)) < 0)
111 + pkgs = tree_open_binpkg(portroot, dirp);
112 + if (pkgs == NULL)
113 return 1;
114
115 + bin_pkgs = tree_get_atoms(pkgs, true, bin_pkgs);
116 + array_set(bin_pkgs, bins);
117 +
118 if (eclean) {
119 - size_t n;
120 const char *overlay;
121
122 array_for_each(overlays, n, overlay) {
123 t = tree_open(portroot, overlay);
124 if (t != NULL) {
125 - vdb = tree_get_atoms(t, true, vdb);
126 + known_pkgs = tree_get_atoms(t, true, known_pkgs);
127 tree_close(t);
128 }
129 }
130 } else {
131 t = tree_open_vdb(portroot, portvdb);
132 if (t != NULL) {
133 - vdb = tree_get_atoms(t, true, vdb);
134 + known_pkgs = tree_get_atoms(t, true, known_pkgs);
135 tree_close(t);
136 }
137 }
138
139 - num_all_bytes = qpkg_clean_dir(dirp, vdb);
140 + /* check which binpkgs exist in the known_pkgs (vdb or trees), such
141 + * that the remainder is what we would clean */
142 + array_for_each(bins, n, binatomstr) {
143 + if (contains_set(binatomstr, known_pkgs))
144 + xarraydelete_ptr(bins, n--);
145 + }
146 +
147 + free_set(known_pkgs);
148
149 - for (i = 0; i < count; i++) {
150 - char buf[_Q_PATH_MAX * 2];
151 - snprintf(buf, sizeof(buf), "%s/%s", dirp, dnames[i]->d_name);
152 - num_all_bytes += qpkg_clean_dir(buf, vdb);
153 + array_for_each(bins, n, binatomstr) {
154 + snprintf(buf, sizeof(buf), "%s/%s.tbz2", dirp, binatomstr);
155 + atom = atom_explode(binatomstr);
156 + if (lstat(buf, &st) != -1) {
157 + if (S_ISREG(st.st_mode)) {
158 + disp_units = KILOBYTE;
159 + if ((st.st_size / KILOBYTE) > 1000)
160 + disp_units = MEGABYTE;
161 + num_all_bytes += st.st_size;
162 + qprintf(" %s[%s %3s %s %s]%s %s\n",
163 + DKBLUE, GREEN,
164 + make_human_readable_str(st.st_size, 1, disp_units),
165 + disp_units == MEGABYTE ? "MiB" : "KiB",
166 + DKBLUE, NORM, atom_format("%[CAT]/%[PF]", atom));
167 + }
168 + if (!pretend)
169 + unlink(buf);
170 + }
171 }
172 - scandir_free(dnames, count);
173
174 - free_set(vdb);
175 + xarrayfree_int(bins);
176 + free_set(bin_pkgs);
177
178 disp_units = KILOBYTE;
179 if ((num_all_bytes / KILOBYTE) > 1000)
180 @@ -328,15 +292,23 @@ qpkg_make(depend_atom *atom)
181 return 0;
182 }
183
184 +static int
185 +qpkg_cb(tree_pkg_ctx *pkg, void *priv)
186 +{
187 + size_t *pkgs_made = priv;
188 +
189 + if (qpkg_make(tree_get_atom(pkg, false)) == 0)
190 + (*pkgs_made)++;
191 +
192 + return 0;
193 +}
194 +
195 int qpkg_main(int argc, char **argv)
196 {
197 tree_ctx *ctx;
198 - tree_cat_ctx *cat_ctx;
199 - tree_pkg_ctx *pkg_ctx;
200 size_t s, pkgs_made;
201 int i;
202 struct stat st;
203 - char buf[BUFSIZE];
204 depend_atom *atom;
205 int restrict_chmod = 0;
206 int qclean = 0;
207 @@ -417,27 +389,21 @@ int qpkg_main(int argc, char **argv)
208 if (!ctx)
209 return EXIT_FAILURE;
210
211 - /* scan all the categories */
212 - while ((cat_ctx = tree_next_cat(ctx))) {
213 - /* scan all the packages in this category */
214 - while ((pkg_ctx = tree_next_pkg(cat_ctx))) {
215 - /* see if user wants any of these packages */
216 - atom = tree_get_atom(pkg_ctx, false);
217 - snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN);
218 - for (i = optind; i < argc; ++i) {
219 - if (argv[i] == NULL)
220 - continue;
221 -
222 - if (!strcmp(argv[i], atom->PN) ||
223 - !strcmp(argv[i], atom->P) ||
224 - !strcmp(argv[i], buf) ||
225 - !strcmp(argv[i], "world"))
226 - if (!qpkg_make(atom))
227 - ++pkgs_made;
228 - }
229 - tree_close_pkg(pkg_ctx);
230 + for (i = optind; i < argc; ++i) {
231 + if (argv[i] == NULL)
232 + continue;
233 + if (strcmp(argv[i], "world") == 0) {
234 + /* we're basically done, this means all */
235 + tree_foreach_pkg_fast(ctx, qpkg_cb, &pkgs_made, NULL);
236 }
237 + atom = atom_explode(argv[i]);
238 + if (atom == NULL)
239 + continue;
240 +
241 + tree_foreach_pkg_fast(ctx, qpkg_cb, &pkgs_made, atom);
242 + atom_implode(atom);
243 }
244 + tree_close(ctx);
245
246 if (pkgs_made)
247 qprintf(" %s*%s Packages can be found in %s\n",