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 int pinfocmp(const void *s1, const void *s2);
46 static void scanit(const char *path, const char *subpath,
47 int *countp, pinfo_t ***list_tailp);
48 pinfo_t *pinfofind(pinfo_t **ary, int count, char *spath);
49 static void scandeletenew(const char *path);
52 DoRebuildRepo(int ask)
57 if (askyn("Rebuild the repository? ") == 0)
62 * Scan the repository for temporary .new files and delete them.
64 scandeletenew(RepositoryPath);
67 * Issue the repo command to rebuild the repo
69 asprintf(&buf, "pkg repo -o %s %s", PackagesPath, RepositoryPath);
70 printf("Rebuilding repository\n");
72 printf("Rebuild failed\n");
74 printf("Rebuild succeeded\n");
79 DoUpgradePkgs(pkg_t *pkgs __unused, int ask __unused)
81 dfatal("Not Implemented");
85 PurgeDistfiles(pkg_t *pkgs)
97 printf("Scanning distfiles... ");
102 scanit(DistFilesPath, NULL, &count, &list_tail);
103 printf("Checking %d distfiles\n", count);
106 ary = calloc(count, sizeof(pinfo_t *));
107 for (i = 0; i < count; ++i) {
111 ddassert(list == NULL);
112 qsort(ary, count, sizeof(pinfo_t *), pinfocmp);
114 for (; pkgs; pkgs = pkgs->bnext) {
115 if (pkgs->distfiles == NULL || pkgs->distfiles[0] == 0)
117 ddprintf(0, "distfiles %s\n", pkgs->distfiles);
118 dstr = strtok(pkgs->distfiles, " \t");
121 if (pkgs->distsubdir && pkgs->distsubdir[0]) {
122 asprintf(&buf, "%s/%s",
123 pkgs->distsubdir, dstr);
124 item = pinfofind(ary, count, buf);
125 ddprintf(0, "TEST %s %p\n", buf, item);
129 item = pinfofind(ary, count, dstr);
130 ddprintf(0, "TEST %s %p\n", dstr, item);
136 if (strrchr(dstr, ':') == NULL)
138 *strrchr(dstr, ':') = 0;
140 dstr = strtok(NULL, " \t");
145 for (i = 0; i < count; ++i) {
147 if (item->foundit == 0) {
151 if (askyn("Delete %d of %d items? ", delcount, count)) {
152 printf("Deleting %d/%d obsolete source distfiles\n",
154 for (i = 0; i < count; ++i) {
156 if (item->foundit == 0) {
157 asprintf(&buf, "%s/%s",
158 DistFilesPath, item->spath);
160 printf("Cannot delete %s\n", buf);
171 RemovePackages(pkg_t *pkgs __unused)
173 dfatal("Not Implemented");
177 pinfocmp(const void *s1, const void *s2)
179 const pinfo_t *item1 = *(const pinfo_t *const*)s1;
180 const pinfo_t *item2 = *(const pinfo_t *const*)s2;
182 return (strcmp(item1->spath, item2->spath));
186 pinfofind(pinfo_t **ary, int count, char *spath)
199 res = strcmp(spath, item->spath);
212 scanit(const char *path, const char *subpath,
213 int *countp, pinfo_t ***list_tailp)
222 if ((dir = opendir(path)) != NULL) {
223 while ((den = readdir(dir)) != NULL) {
224 if (den->d_namlen == 1 && den->d_name[0] == '.')
226 if (den->d_namlen == 2 && den->d_name[0] == '.' &&
227 den->d_name[1] == '.')
229 asprintf(&npath, "%s/%s", path, den->d_name);
230 if (lstat(npath, &st) < 0) {
234 if (S_ISDIR(st.st_mode)) {
236 asprintf(&spath, "%s/%s",
237 subpath, den->d_name);
242 scanit(npath, den->d_name,
245 } else if (S_ISREG(st.st_mode)) {
246 item = calloc(1, sizeof(*item));
248 asprintf(&item->spath, "%s/%s",
249 subpath, den->d_name);
251 item->spath = strdup(den->d_name);
254 *list_tailp = &item->next;
256 ddprintf(0, "scan %s\n", item->spath);
265 * This removes any .new files left over in the repo. These can wind
266 * being left around when dsynth is killed.
269 scandeletenew(const char *path)
276 if ((dir = opendir(path)) == NULL)
277 dfatal_errno("Cannot scan directory %s", path);
278 while ((den = readdir(dir)) != NULL) {
279 if ((ptr = strrchr(den->d_name, '.')) != NULL &&
280 strcmp(ptr, ".new") == 0) {
281 asprintf(&buf, "%s/%s", path, den->d_name);
283 dfatal_errno("remove: Garbage %s\n", buf);
284 printf("Deleted Garbage %s\n", buf);