2 * Copyright (c) 2019 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * This code uses concepts and configuration based on 'synth', by
8 * John R. Marino <draco@marino.st>, which was written in ada.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
20 * 3. Neither the name of The DragonFly Project nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific, prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 typedef struct pinfo {
45 static void removePackagesMetaRecurse(pkg_t *pkg);
46 static int pinfocmp(const void *s1, const void *s2);
47 static void scanit(const char *path, const char *subpath,
48 int *countp, pinfo_t ***list_tailp);
49 pinfo_t *pinfofind(pinfo_t **ary, int count, char *spath);
50 static void scandeletenew(const char *path);
53 DoRebuildRepo(int ask)
58 if (askyn("Rebuild the repository? ") == 0)
63 * Scan the repository for temporary .new files and delete them.
65 scandeletenew(RepositoryPath);
68 * Issue the repo command to rebuild the repo
70 asprintf(&buf, "pkg repo -o %s %s", PackagesPath, RepositoryPath);
71 printf("Rebuilding repository\n");
73 printf("Rebuild failed\n");
75 printf("Rebuild succeeded\n");
80 DoUpgradePkgs(pkg_t *pkgs __unused, int ask __unused)
82 dfatal("Not Implemented");
86 PurgeDistfiles(pkg_t *pkgs)
98 printf("Scanning distfiles... ");
103 scanit(DistFilesPath, NULL, &count, &list_tail);
104 printf("Checking %d distfiles\n", count);
107 ary = calloc(count, sizeof(pinfo_t *));
108 for (i = 0; i < count; ++i) {
112 ddassert(list == NULL);
113 qsort(ary, count, sizeof(pinfo_t *), pinfocmp);
115 for (; pkgs; pkgs = pkgs->bnext) {
116 if (pkgs->distfiles == NULL || pkgs->distfiles[0] == 0)
118 ddprintf(0, "distfiles %s\n", pkgs->distfiles);
119 dstr = strtok(pkgs->distfiles, " \t");
122 if (pkgs->distsubdir) {
123 asprintf(&buf, "%s/%s",
124 pkgs->distsubdir, dstr);
125 item = pinfofind(ary, count, buf);
126 ddprintf(0, "TEST %s %p\n", buf, item);
130 item = pinfofind(ary, count, dstr);
131 ddprintf(0, "TEST %s %p\n", dstr, item);
137 if (strrchr(dstr, ':') == NULL)
139 *strrchr(dstr, ':') = 0;
141 dstr = strtok(NULL, " \t");
146 for (i = 0; i < count; ++i) {
148 if (item->foundit == 0) {
152 if (askyn("Delete %d of %d items? ", delcount, count)) {
153 printf("Deleting %d/%d obsolete source distfiles\n",
155 for (i = 0; i < count; ++i) {
157 if (item->foundit == 0) {
158 asprintf(&buf, "%s/%s",
159 DistFilesPath, item->spath);
161 printf("Cannot delete %s\n", buf);
172 RemovePackages(pkg_t *list)
177 for (scan = list; scan; scan = scan->bnext) {
178 if ((scan->flags & PKGF_MANUALSEL) == 0)
181 scan->flags &= ~PKGF_PACKAGED;
182 scan->pkgfile_size = 0;
183 asprintf(&path, "%s/%s", RepositoryPath, scan->pkgfile);
184 if (remove(path) == 0)
185 printf("Removed: %s\n", path);
188 if (scan->pkgfile == NULL ||
189 (scan->flags & (PKGF_DUMMY | PKGF_META))) {
190 removePackagesMetaRecurse(scan);
196 removePackagesMetaRecurse(pkg_t *pkg)
202 PKGLIST_FOREACH(link, &pkg->idepon_list) {
206 if (scan->pkgfile == NULL ||
207 (scan->flags & (PKGF_DUMMY | PKGF_META))) {
208 removePackagesMetaRecurse(scan);
211 scan->flags &= ~PKGF_PACKAGED;
212 scan->pkgfile_size = 0;
214 asprintf(&path, "%s/%s", RepositoryPath, scan->pkgfile);
215 if (remove(path) == 0)
216 printf("Removed: %s\n", path);
222 pinfocmp(const void *s1, const void *s2)
224 const pinfo_t *item1 = *(const pinfo_t *const*)s1;
225 const pinfo_t *item2 = *(const pinfo_t *const*)s2;
227 return (strcmp(item1->spath, item2->spath));
231 pinfofind(pinfo_t **ary, int count, char *spath)
244 res = strcmp(spath, item->spath);
257 scanit(const char *path, const char *subpath,
258 int *countp, pinfo_t ***list_tailp)
267 if ((dir = opendir(path)) != NULL) {
268 while ((den = readdir(dir)) != NULL) {
269 if (den->d_namlen == 1 && den->d_name[0] == '.')
271 if (den->d_namlen == 2 && den->d_name[0] == '.' &&
272 den->d_name[1] == '.')
274 asprintf(&npath, "%s/%s", path, den->d_name);
275 if (lstat(npath, &st) < 0) {
279 if (S_ISDIR(st.st_mode)) {
281 asprintf(&spath, "%s/%s",
282 subpath, den->d_name);
287 scanit(npath, den->d_name,
290 } else if (S_ISREG(st.st_mode)) {
291 item = calloc(1, sizeof(*item));
293 asprintf(&item->spath, "%s/%s",
294 subpath, den->d_name);
296 item->spath = strdup(den->d_name);
299 *list_tailp = &item->next;
301 ddprintf(0, "scan %s\n", item->spath);
310 * This removes any .new files left over in the repo. These can wind
311 * being left around when dsynth is killed.
314 scandeletenew(const char *path)
321 if ((dir = opendir(path)) == NULL)
322 dfatal_errno("Cannot scan directory %s", path);
323 while ((den = readdir(dir)) != NULL) {
324 if ((ptr = strrchr(den->d_name, '.')) != NULL &&
325 strcmp(ptr, ".new") == 0) {
326 asprintf(&buf, "%s/%s", path, den->d_name);
328 dfatal_errno("remove: Garbage %s\n", buf);
329 printf("Deleted Garbage %s\n", buf);