18e25f19bSMatthew Dillon /* 28e25f19bSMatthew Dillon * Copyright (c) 2019 The DragonFly Project. All rights reserved. 38e25f19bSMatthew Dillon * 48e25f19bSMatthew Dillon * This code is derived from software contributed to The DragonFly Project 58e25f19bSMatthew Dillon * by Matthew Dillon <dillon@backplane.com> 68e25f19bSMatthew Dillon * 78e25f19bSMatthew Dillon * This code uses concepts and configuration based on 'synth', by 88e25f19bSMatthew Dillon * John R. Marino <draco@marino.st>, which was written in ada. 98e25f19bSMatthew Dillon * 108e25f19bSMatthew Dillon * Redistribution and use in source and binary forms, with or without 118e25f19bSMatthew Dillon * modification, are permitted provided that the following conditions 128e25f19bSMatthew Dillon * are met: 138e25f19bSMatthew Dillon * 148e25f19bSMatthew Dillon * 1. Redistributions of source code must retain the above copyright 158e25f19bSMatthew Dillon * notice, this list of conditions and the following disclaimer. 168e25f19bSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 178e25f19bSMatthew Dillon * notice, this list of conditions and the following disclaimer in 188e25f19bSMatthew Dillon * the documentation and/or other materials provided with the 198e25f19bSMatthew Dillon * distribution. 208e25f19bSMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its 218e25f19bSMatthew Dillon * contributors may be used to endorse or promote products derived 228e25f19bSMatthew Dillon * from this software without specific, prior written permission. 238e25f19bSMatthew Dillon * 248e25f19bSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 258e25f19bSMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 268e25f19bSMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 278e25f19bSMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 288e25f19bSMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 298e25f19bSMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 308e25f19bSMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 318e25f19bSMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 328e25f19bSMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 338e25f19bSMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 348e25f19bSMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 358e25f19bSMatthew Dillon * SUCH DAMAGE. 368e25f19bSMatthew Dillon */ 378e25f19bSMatthew Dillon #include "dsynth.h" 388e25f19bSMatthew Dillon 391645cafeSMatthew Dillon typedef struct pinfo { 401645cafeSMatthew Dillon struct pinfo *next; 411645cafeSMatthew Dillon char *spath; 421645cafeSMatthew Dillon int foundit; 431645cafeSMatthew Dillon } pinfo_t; 441645cafeSMatthew Dillon 45f4094b20SMatthew Dillon static void removePackagesMetaRecurse(pkg_t *pkg); 461645cafeSMatthew Dillon static int pinfocmp(const void *s1, const void *s2); 471645cafeSMatthew Dillon static void scanit(const char *path, const char *subpath, 481645cafeSMatthew Dillon int *countp, pinfo_t ***list_tailp); 491645cafeSMatthew Dillon pinfo_t *pinfofind(pinfo_t **ary, int count, char *spath); 50066daf2aSMatthew Dillon static void childRebuildRepo(bulk_t *bulk); 51f7f25838SMatthew Dillon static void scandeletenew(const char *path); 521645cafeSMatthew Dillon 53066daf2aSMatthew Dillon static void rebuildTerminateSignal(int signo); 54066daf2aSMatthew Dillon 55066daf2aSMatthew Dillon static char *RebuildRemovePath; 56066daf2aSMatthew Dillon 578e25f19bSMatthew Dillon void 581645cafeSMatthew Dillon DoRebuildRepo(int ask) 598e25f19bSMatthew Dillon { 60066daf2aSMatthew Dillon bulk_t *bulk; 61066daf2aSMatthew Dillon FILE *fp; 62066daf2aSMatthew Dillon int fd; 63066daf2aSMatthew Dillon char tpath[256]; 6468dc2eeaSMatthew Dillon const char *sufx; 651645cafeSMatthew Dillon 661645cafeSMatthew Dillon if (ask) { 671645cafeSMatthew Dillon if (askyn("Rebuild the repository? ") == 0) 681645cafeSMatthew Dillon return; 691645cafeSMatthew Dillon } 70f7f25838SMatthew Dillon 71f7f25838SMatthew Dillon /* 72f7f25838SMatthew Dillon * Scan the repository for temporary .new files and delete them. 73f7f25838SMatthew Dillon */ 74f7f25838SMatthew Dillon scandeletenew(RepositoryPath); 75f7f25838SMatthew Dillon 76f7f25838SMatthew Dillon /* 77066daf2aSMatthew Dillon * Generate temporary file 78f7f25838SMatthew Dillon */ 79066daf2aSMatthew Dillon snprintf(tpath, sizeof(tpath), "/tmp/meta.XXXXXXXX.conf"); 80066daf2aSMatthew Dillon 81066daf2aSMatthew Dillon signal(SIGTERM, rebuildTerminateSignal); 82066daf2aSMatthew Dillon signal(SIGINT, rebuildTerminateSignal); 83066daf2aSMatthew Dillon signal(SIGHUP, rebuildTerminateSignal); 84066daf2aSMatthew Dillon 85066daf2aSMatthew Dillon RebuildRemovePath = tpath; 86066daf2aSMatthew Dillon 87483dbac9SMatthew Dillon sufx = UsePkgSufx; 88066daf2aSMatthew Dillon fd = mkostemps(tpath, 5, 0); 89066daf2aSMatthew Dillon if (fd < 0) 90066daf2aSMatthew Dillon dfatal_errno("Cannot create %s", tpath); 91066daf2aSMatthew Dillon fp = fdopen(fd, "w"); 92066daf2aSMatthew Dillon fprintf(fp, "version = 1;\n"); 9368dc2eeaSMatthew Dillon fprintf(fp, "packing_format = \"%s\";\n", sufx + 1); 94066daf2aSMatthew Dillon fclose(fp); 95066daf2aSMatthew Dillon 96066daf2aSMatthew Dillon /* 97066daf2aSMatthew Dillon * Run the operation under our bulk infrastructure to 98066daf2aSMatthew Dillon * get the correct environment. 99066daf2aSMatthew Dillon */ 100066daf2aSMatthew Dillon initbulk(childRebuildRepo, 1); 101066daf2aSMatthew Dillon queuebulk(tpath, NULL, NULL, NULL); 102066daf2aSMatthew Dillon bulk = getbulk(); 103066daf2aSMatthew Dillon 104066daf2aSMatthew Dillon if (bulk->r1) 1051645cafeSMatthew Dillon printf("Rebuild succeeded\n"); 106066daf2aSMatthew Dillon else 107066daf2aSMatthew Dillon printf("Rebuild failed\n"); 108066daf2aSMatthew Dillon donebulk(); 109066daf2aSMatthew Dillon 110066daf2aSMatthew Dillon remove(tpath); 111066daf2aSMatthew Dillon } 112066daf2aSMatthew Dillon 113066daf2aSMatthew Dillon static void 114*7f2422cfSMatthew Dillon repackage(const char *basepath, const char *basefile, 115*7f2422cfSMatthew Dillon const char *decomp_suffix, const char *comp_suffix, 116*7f2422cfSMatthew Dillon const char *decomp, const char *comp); 117cda252a4SMatthew Dillon 118cda252a4SMatthew Dillon static void 119066daf2aSMatthew Dillon childRebuildRepo(bulk_t *bulk) 120066daf2aSMatthew Dillon { 121066daf2aSMatthew Dillon FILE *fp; 122066daf2aSMatthew Dillon char *ptr; 123066daf2aSMatthew Dillon size_t len; 124066daf2aSMatthew Dillon pid_t pid; 125066daf2aSMatthew Dillon const char *cav[MAXCAC]; 126066daf2aSMatthew Dillon int cac; 127*7f2422cfSMatthew Dillon int repackage_mode = 0; 128066daf2aSMatthew Dillon 129066daf2aSMatthew Dillon cac = 0; 130066daf2aSMatthew Dillon cav[cac++] = PKG_BINARY; 131066daf2aSMatthew Dillon cav[cac++] = "repo"; 132066daf2aSMatthew Dillon cav[cac++] = "-m"; 133066daf2aSMatthew Dillon cav[cac++] = bulk->s1; 134066daf2aSMatthew Dillon cav[cac++] = "-o"; 135066daf2aSMatthew Dillon cav[cac++] = PackagesPath; 136cda252a4SMatthew Dillon 137cda252a4SMatthew Dillon /* 138cda252a4SMatthew Dillon * The yaml needs to generate paths relative to PackagePath 139cda252a4SMatthew Dillon */ 140cda252a4SMatthew Dillon if (strncmp(PackagesPath, RepositoryPath, strlen(PackagesPath)) == 0) 141cda252a4SMatthew Dillon cav[cac++] = PackagesPath; 142cda252a4SMatthew Dillon else 143066daf2aSMatthew Dillon cav[cac++] = RepositoryPath; 144066daf2aSMatthew Dillon 145cda252a4SMatthew Dillon printf("pkg repo -m %s -o %s %s\n", bulk->s1, cav[cac-2], cav[cac-1]); 146066daf2aSMatthew Dillon 14768dc2eeaSMatthew Dillon fp = dexec_open(cav, cac, &pid, NULL, 1, 0); 148066daf2aSMatthew Dillon while ((ptr = fgetln(fp, &len)) != NULL) 149066daf2aSMatthew Dillon fwrite(ptr, 1, len, stdout); 15096cc8f92SMatthew Dillon if (dexec_close(fp, pid) == 0) 151066daf2aSMatthew Dillon bulk->r1 = strdup(""); 15296cc8f92SMatthew Dillon 15396cc8f92SMatthew Dillon /* 15496cc8f92SMatthew Dillon * Check package version. Pkg version 1.12 and later generates 15596cc8f92SMatthew Dillon * the proper repo compression format. Prior to that version 15696cc8f92SMatthew Dillon * the repo directive always generated .txz files. 15796cc8f92SMatthew Dillon */ 15896cc8f92SMatthew Dillon cac = 0; 15996cc8f92SMatthew Dillon cav[cac++] = PKG_BINARY; 16096cc8f92SMatthew Dillon cav[cac++] = "-v"; 16196cc8f92SMatthew Dillon fp = dexec_open(cav, cac, &pid, NULL, 1, 0); 16296cc8f92SMatthew Dillon if ((ptr = fgetln(fp, &len)) != NULL && len > 0) { 16396cc8f92SMatthew Dillon int v1; 16496cc8f92SMatthew Dillon int v2; 16596cc8f92SMatthew Dillon 16696cc8f92SMatthew Dillon ptr[len-1] = 0; 16796cc8f92SMatthew Dillon if (sscanf(ptr, "%d.%d", &v1, &v2) == 2) { 16896cc8f92SMatthew Dillon if (v1 > 1 || (v1 == 1 && v2 >= 12)) 169*7f2422cfSMatthew Dillon repackage_mode = 1; 1701645cafeSMatthew Dillon } 17196cc8f92SMatthew Dillon } 17296cc8f92SMatthew Dillon dexec_close(fp, pid); 173cda252a4SMatthew Dillon 174cda252a4SMatthew Dillon /* 175cda252a4SMatthew Dillon * Repackage the .txz files created by pkg repo if necessary 176cda252a4SMatthew Dillon */ 177*7f2422cfSMatthew Dillon if (repackage_mode == 0 && strcmp(UsePkgSufx, ".txz") != 0) { 178cda252a4SMatthew Dillon const char *comp; 179cda252a4SMatthew Dillon const char *decomp; 180cda252a4SMatthew Dillon 181*7f2422cfSMatthew Dillon printf("pkg repo - recompressing digests and packagesite\n"); 18296cc8f92SMatthew Dillon 183483dbac9SMatthew Dillon if (strcmp(UsePkgSufx, ".tar") == 0) { 184cda252a4SMatthew Dillon decomp = "unxz"; 185cda252a4SMatthew Dillon comp = "cat"; 186483dbac9SMatthew Dillon } else if (strcmp(UsePkgSufx, ".tgz") == 0) { 187cda252a4SMatthew Dillon decomp = "unxz"; 188cda252a4SMatthew Dillon comp = "gzip"; 189483dbac9SMatthew Dillon } else if (strcmp(UsePkgSufx, ".tbz") == 0) { 190cda252a4SMatthew Dillon decomp = "unxz"; 191cda252a4SMatthew Dillon comp = "bzip"; 192cda252a4SMatthew Dillon } else { 193*7f2422cfSMatthew Dillon dfatal("recompressing as %s not supported", 194*7f2422cfSMatthew Dillon UsePkgSufx); 195cda252a4SMatthew Dillon decomp = "unxz"; 196cda252a4SMatthew Dillon comp = "cat"; 197cda252a4SMatthew Dillon } 198*7f2422cfSMatthew Dillon repackage(PackagesPath, "digests", 199*7f2422cfSMatthew Dillon ".txz", UsePkgSufx, 200*7f2422cfSMatthew Dillon decomp, comp); 201*7f2422cfSMatthew Dillon repackage(PackagesPath, "packagesite", 202*7f2422cfSMatthew Dillon ".txz", UsePkgSufx, 203*7f2422cfSMatthew Dillon decomp, comp); 204*7f2422cfSMatthew Dillon } else if (repackage_mode == 1 && strcmp(UsePkgSufx, ".txz") != 0) { 205*7f2422cfSMatthew Dillon const char *comp; 206*7f2422cfSMatthew Dillon const char *decomp; 207*7f2422cfSMatthew Dillon 208*7f2422cfSMatthew Dillon printf("pkg repo - recompressing meta\n"); 209*7f2422cfSMatthew Dillon 210*7f2422cfSMatthew Dillon if (strcmp(UsePkgSufx, ".tar") == 0) { 211*7f2422cfSMatthew Dillon decomp = "cat"; 212*7f2422cfSMatthew Dillon comp = "xz"; 213*7f2422cfSMatthew Dillon } else if (strcmp(UsePkgSufx, ".tgz") == 0) { 214*7f2422cfSMatthew Dillon decomp = "gunzip"; 215*7f2422cfSMatthew Dillon comp = "xz"; 216*7f2422cfSMatthew Dillon } else if (strcmp(UsePkgSufx, ".tbz") == 0) { 217*7f2422cfSMatthew Dillon decomp = "bunzip2"; 218*7f2422cfSMatthew Dillon comp = "xz"; 219*7f2422cfSMatthew Dillon } else { 220*7f2422cfSMatthew Dillon dfatal("recompressing from %s not supported", 221*7f2422cfSMatthew Dillon UsePkgSufx); 222*7f2422cfSMatthew Dillon decomp = "cat"; 223*7f2422cfSMatthew Dillon comp = "cat"; 224*7f2422cfSMatthew Dillon } 225*7f2422cfSMatthew Dillon repackage(PackagesPath, "meta", 226*7f2422cfSMatthew Dillon UsePkgSufx, ".txz", 227*7f2422cfSMatthew Dillon decomp, comp); 228cda252a4SMatthew Dillon } 229cda252a4SMatthew Dillon } 230cda252a4SMatthew Dillon 231cda252a4SMatthew Dillon static 232cda252a4SMatthew Dillon void 233*7f2422cfSMatthew Dillon repackage(const char *basepath, const char *basefile, 234*7f2422cfSMatthew Dillon const char *decomp_suffix, const char *comp_suffix, 235*7f2422cfSMatthew Dillon const char *decomp, const char *comp) 236cda252a4SMatthew Dillon { 237cda252a4SMatthew Dillon char *buf; 238cda252a4SMatthew Dillon 239*7f2422cfSMatthew Dillon asprintf(&buf, "%s < %s/%s%s | %s > %s/%s%s", 240*7f2422cfSMatthew Dillon decomp, basepath, basefile, decomp_suffix, 241*7f2422cfSMatthew Dillon comp, basepath, basefile, comp_suffix); 242cda252a4SMatthew Dillon if (system(buf) != 0) { 243cda252a4SMatthew Dillon dfatal("command failed: %s", buf); 244cda252a4SMatthew Dillon } 245cda252a4SMatthew Dillon free(buf); 2468e25f19bSMatthew Dillon } 2478e25f19bSMatthew Dillon 2488e25f19bSMatthew Dillon void 2498e25f19bSMatthew Dillon DoUpgradePkgs(pkg_t *pkgs __unused, int ask __unused) 2508e25f19bSMatthew Dillon { 2518e25f19bSMatthew Dillon dfatal("Not Implemented"); 2528e25f19bSMatthew Dillon } 2538e25f19bSMatthew Dillon 2548e25f19bSMatthew Dillon void 2551645cafeSMatthew Dillon PurgeDistfiles(pkg_t *pkgs) 2568e25f19bSMatthew Dillon { 2571645cafeSMatthew Dillon pinfo_t *list; 2581645cafeSMatthew Dillon pinfo_t *item; 2591645cafeSMatthew Dillon pinfo_t **list_tail; 2601645cafeSMatthew Dillon pinfo_t **ary; 2611645cafeSMatthew Dillon char *dstr; 2621645cafeSMatthew Dillon char *buf; 2631645cafeSMatthew Dillon int count; 2641645cafeSMatthew Dillon int delcount; 2651645cafeSMatthew Dillon int i; 2661645cafeSMatthew Dillon 2671645cafeSMatthew Dillon printf("Scanning distfiles... "); 2681645cafeSMatthew Dillon fflush(stdout); 2691645cafeSMatthew Dillon count = 0; 2701645cafeSMatthew Dillon list = NULL; 2711645cafeSMatthew Dillon list_tail = &list; 2721645cafeSMatthew Dillon scanit(DistFilesPath, NULL, &count, &list_tail); 2731645cafeSMatthew Dillon printf("Checking %d distfiles\n", count); 2741645cafeSMatthew Dillon fflush(stdout); 2751645cafeSMatthew Dillon 2761645cafeSMatthew Dillon ary = calloc(count, sizeof(pinfo_t *)); 2771645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 2781645cafeSMatthew Dillon ary[i] = list; 2791645cafeSMatthew Dillon list = list->next; 2801645cafeSMatthew Dillon } 2811645cafeSMatthew Dillon ddassert(list == NULL); 2821645cafeSMatthew Dillon qsort(ary, count, sizeof(pinfo_t *), pinfocmp); 2831645cafeSMatthew Dillon 2841645cafeSMatthew Dillon for (; pkgs; pkgs = pkgs->bnext) { 2851645cafeSMatthew Dillon if (pkgs->distfiles == NULL || pkgs->distfiles[0] == 0) 2861645cafeSMatthew Dillon continue; 2871645cafeSMatthew Dillon ddprintf(0, "distfiles %s\n", pkgs->distfiles); 2881645cafeSMatthew Dillon dstr = strtok(pkgs->distfiles, " \t"); 2891645cafeSMatthew Dillon while (dstr) { 2901645cafeSMatthew Dillon for (;;) { 2914ea2ee4dSMatthew Dillon if (pkgs->distsubdir) { 2921645cafeSMatthew Dillon asprintf(&buf, "%s/%s", 2931645cafeSMatthew Dillon pkgs->distsubdir, dstr); 2941645cafeSMatthew Dillon item = pinfofind(ary, count, buf); 2951645cafeSMatthew Dillon ddprintf(0, "TEST %s %p\n", buf, item); 2961645cafeSMatthew Dillon free(buf); 2971645cafeSMatthew Dillon buf = NULL; 2981645cafeSMatthew Dillon } else { 2991645cafeSMatthew Dillon item = pinfofind(ary, count, dstr); 3001645cafeSMatthew Dillon ddprintf(0, "TEST %s %p\n", dstr, item); 3011645cafeSMatthew Dillon } 3021645cafeSMatthew Dillon if (item) { 3031645cafeSMatthew Dillon item->foundit = 1; 3041645cafeSMatthew Dillon break; 3051645cafeSMatthew Dillon } 3061645cafeSMatthew Dillon if (strrchr(dstr, ':') == NULL) 3071645cafeSMatthew Dillon break; 3081645cafeSMatthew Dillon *strrchr(dstr, ':') = 0; 3091645cafeSMatthew Dillon } 3101645cafeSMatthew Dillon dstr = strtok(NULL, " \t"); 3111645cafeSMatthew Dillon } 3121645cafeSMatthew Dillon } 3131645cafeSMatthew Dillon 3141645cafeSMatthew Dillon delcount = 0; 3151645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 3161645cafeSMatthew Dillon item = ary[i]; 3171645cafeSMatthew Dillon if (item->foundit == 0) { 3181645cafeSMatthew Dillon ++delcount; 3191645cafeSMatthew Dillon } 3201645cafeSMatthew Dillon } 3211645cafeSMatthew Dillon if (askyn("Delete %d of %d items? ", delcount, count)) { 3221645cafeSMatthew Dillon printf("Deleting %d/%d obsolete source distfiles\n", 3231645cafeSMatthew Dillon delcount, count); 3241645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 3251645cafeSMatthew Dillon item = ary[i]; 3261645cafeSMatthew Dillon if (item->foundit == 0) { 3271645cafeSMatthew Dillon asprintf(&buf, "%s/%s", 3281645cafeSMatthew Dillon DistFilesPath, item->spath); 3291645cafeSMatthew Dillon if (remove(buf) < 0) 3301645cafeSMatthew Dillon printf("Cannot delete %s\n", buf); 3311645cafeSMatthew Dillon free(buf); 3321645cafeSMatthew Dillon } 3331645cafeSMatthew Dillon } 3341645cafeSMatthew Dillon } 3351645cafeSMatthew Dillon 3361645cafeSMatthew Dillon 3371645cafeSMatthew Dillon free(ary); 3388e25f19bSMatthew Dillon } 3398e25f19bSMatthew Dillon 3408e25f19bSMatthew Dillon void 341f4094b20SMatthew Dillon RemovePackages(pkg_t *list) 3428e25f19bSMatthew Dillon { 343f4094b20SMatthew Dillon pkg_t *scan; 344f4094b20SMatthew Dillon char *path; 345f4094b20SMatthew Dillon 346f4094b20SMatthew Dillon for (scan = list; scan; scan = scan->bnext) { 347f4094b20SMatthew Dillon if ((scan->flags & PKGF_MANUALSEL) == 0) 348f4094b20SMatthew Dillon continue; 349f4094b20SMatthew Dillon if (scan->pkgfile) { 350f4094b20SMatthew Dillon scan->flags &= ~PKGF_PACKAGED; 351f4094b20SMatthew Dillon scan->pkgfile_size = 0; 352f4094b20SMatthew Dillon asprintf(&path, "%s/%s", RepositoryPath, scan->pkgfile); 353f4094b20SMatthew Dillon if (remove(path) == 0) 354f4094b20SMatthew Dillon printf("Removed: %s\n", path); 355f4094b20SMatthew Dillon free(path); 356f4094b20SMatthew Dillon } 357f4094b20SMatthew Dillon if (scan->pkgfile == NULL || 358f4094b20SMatthew Dillon (scan->flags & (PKGF_DUMMY | PKGF_META))) { 359f4094b20SMatthew Dillon removePackagesMetaRecurse(scan); 360f4094b20SMatthew Dillon } 361f4094b20SMatthew Dillon } 362f4094b20SMatthew Dillon } 363f4094b20SMatthew Dillon 364f4094b20SMatthew Dillon static void 365f4094b20SMatthew Dillon removePackagesMetaRecurse(pkg_t *pkg) 366f4094b20SMatthew Dillon { 367f4094b20SMatthew Dillon pkglink_t *link; 368f4094b20SMatthew Dillon pkg_t *scan; 369f4094b20SMatthew Dillon char *path; 370f4094b20SMatthew Dillon 371f4094b20SMatthew Dillon PKGLIST_FOREACH(link, &pkg->idepon_list) { 372f4094b20SMatthew Dillon scan = link->pkg; 373f4094b20SMatthew Dillon if (scan == NULL) 374f4094b20SMatthew Dillon continue; 375f4094b20SMatthew Dillon if (scan->pkgfile == NULL || 376f4094b20SMatthew Dillon (scan->flags & (PKGF_DUMMY | PKGF_META))) { 377f4094b20SMatthew Dillon removePackagesMetaRecurse(scan); 378f4094b20SMatthew Dillon continue; 379f4094b20SMatthew Dillon } 380f4094b20SMatthew Dillon scan->flags &= ~PKGF_PACKAGED; 381f4094b20SMatthew Dillon scan->pkgfile_size = 0; 382f4094b20SMatthew Dillon 383f4094b20SMatthew Dillon asprintf(&path, "%s/%s", RepositoryPath, scan->pkgfile); 384f4094b20SMatthew Dillon if (remove(path) == 0) 385f4094b20SMatthew Dillon printf("Removed: %s\n", path); 386f4094b20SMatthew Dillon free(path); 387f4094b20SMatthew Dillon } 3888e25f19bSMatthew Dillon } 3891645cafeSMatthew Dillon 3901645cafeSMatthew Dillon static int 3911645cafeSMatthew Dillon pinfocmp(const void *s1, const void *s2) 3921645cafeSMatthew Dillon { 3931645cafeSMatthew Dillon const pinfo_t *item1 = *(const pinfo_t *const*)s1; 3941645cafeSMatthew Dillon const pinfo_t *item2 = *(const pinfo_t *const*)s2; 3951645cafeSMatthew Dillon 3961645cafeSMatthew Dillon return (strcmp(item1->spath, item2->spath)); 3971645cafeSMatthew Dillon } 3981645cafeSMatthew Dillon 3991645cafeSMatthew Dillon pinfo_t * 4001645cafeSMatthew Dillon pinfofind(pinfo_t **ary, int count, char *spath) 4011645cafeSMatthew Dillon { 4021645cafeSMatthew Dillon pinfo_t *item; 4031645cafeSMatthew Dillon int res; 4041645cafeSMatthew Dillon int b; 4051645cafeSMatthew Dillon int e; 4061645cafeSMatthew Dillon int m; 4071645cafeSMatthew Dillon 4081645cafeSMatthew Dillon b = 0; 4091645cafeSMatthew Dillon e = count; 4101645cafeSMatthew Dillon while (b != e) { 4111645cafeSMatthew Dillon m = b + (e - b) / 2; 4121645cafeSMatthew Dillon item = ary[m]; 4131645cafeSMatthew Dillon res = strcmp(spath, item->spath); 4141645cafeSMatthew Dillon if (res == 0) 4151645cafeSMatthew Dillon return item; 4161645cafeSMatthew Dillon if (res < 0) { 4171645cafeSMatthew Dillon e = m; 4181645cafeSMatthew Dillon } else { 4191645cafeSMatthew Dillon b = m + 1; 4201645cafeSMatthew Dillon } 4211645cafeSMatthew Dillon } 4221645cafeSMatthew Dillon return NULL; 4231645cafeSMatthew Dillon } 4241645cafeSMatthew Dillon 4251645cafeSMatthew Dillon void 4261645cafeSMatthew Dillon scanit(const char *path, const char *subpath, 4271645cafeSMatthew Dillon int *countp, pinfo_t ***list_tailp) 4281645cafeSMatthew Dillon { 4291645cafeSMatthew Dillon struct dirent *den; 4301645cafeSMatthew Dillon pinfo_t *item; 4311645cafeSMatthew Dillon char *npath; 4321645cafeSMatthew Dillon char *spath; 4331645cafeSMatthew Dillon DIR *dir; 4341645cafeSMatthew Dillon struct stat st; 4351645cafeSMatthew Dillon 4361645cafeSMatthew Dillon if ((dir = opendir(path)) != NULL) { 4371645cafeSMatthew Dillon while ((den = readdir(dir)) != NULL) { 4381645cafeSMatthew Dillon if (den->d_namlen == 1 && den->d_name[0] == '.') 4391645cafeSMatthew Dillon continue; 4401645cafeSMatthew Dillon if (den->d_namlen == 2 && den->d_name[0] == '.' && 4411645cafeSMatthew Dillon den->d_name[1] == '.') 4421645cafeSMatthew Dillon continue; 4431645cafeSMatthew Dillon asprintf(&npath, "%s/%s", path, den->d_name); 4441645cafeSMatthew Dillon if (lstat(npath, &st) < 0) { 4451645cafeSMatthew Dillon free(npath); 4461645cafeSMatthew Dillon continue; 4471645cafeSMatthew Dillon } 4481645cafeSMatthew Dillon if (S_ISDIR(st.st_mode)) { 4491645cafeSMatthew Dillon if (subpath) { 4501645cafeSMatthew Dillon asprintf(&spath, "%s/%s", 4511645cafeSMatthew Dillon subpath, den->d_name); 4521645cafeSMatthew Dillon scanit(npath, spath, 4531645cafeSMatthew Dillon countp, list_tailp); 4541645cafeSMatthew Dillon free(spath); 4551645cafeSMatthew Dillon } else { 4561645cafeSMatthew Dillon scanit(npath, den->d_name, 4571645cafeSMatthew Dillon countp, list_tailp); 4581645cafeSMatthew Dillon } 4591645cafeSMatthew Dillon } else if (S_ISREG(st.st_mode)) { 4601645cafeSMatthew Dillon item = calloc(1, sizeof(*item)); 4611645cafeSMatthew Dillon if (subpath) { 4621645cafeSMatthew Dillon asprintf(&item->spath, "%s/%s", 4631645cafeSMatthew Dillon subpath, den->d_name); 4641645cafeSMatthew Dillon } else { 4651645cafeSMatthew Dillon item->spath = strdup(den->d_name); 4661645cafeSMatthew Dillon } 4671645cafeSMatthew Dillon **list_tailp = item; 4681645cafeSMatthew Dillon *list_tailp = &item->next; 4691645cafeSMatthew Dillon ++*countp; 4701645cafeSMatthew Dillon ddprintf(0, "scan %s\n", item->spath); 4711645cafeSMatthew Dillon } 4726a3a20b1SMatthew Dillon free(npath); 4731645cafeSMatthew Dillon } 4741645cafeSMatthew Dillon closedir(dir); 4751645cafeSMatthew Dillon } 4761645cafeSMatthew Dillon } 477f7f25838SMatthew Dillon 478f7f25838SMatthew Dillon /* 479f7f25838SMatthew Dillon * This removes any .new files left over in the repo. These can wind 480f7f25838SMatthew Dillon * being left around when dsynth is killed. 481f7f25838SMatthew Dillon */ 482f7f25838SMatthew Dillon static void 483f7f25838SMatthew Dillon scandeletenew(const char *path) 484f7f25838SMatthew Dillon { 485f7f25838SMatthew Dillon struct dirent *den; 486f7f25838SMatthew Dillon const char *ptr; 487f7f25838SMatthew Dillon DIR *dir; 488f7f25838SMatthew Dillon char *buf; 489f7f25838SMatthew Dillon 490f7f25838SMatthew Dillon if ((dir = opendir(path)) == NULL) 491f7f25838SMatthew Dillon dfatal_errno("Cannot scan directory %s", path); 492f7f25838SMatthew Dillon while ((den = readdir(dir)) != NULL) { 493f7f25838SMatthew Dillon if ((ptr = strrchr(den->d_name, '.')) != NULL && 494f7f25838SMatthew Dillon strcmp(ptr, ".new") == 0) { 495f7f25838SMatthew Dillon asprintf(&buf, "%s/%s", path, den->d_name); 496f7f25838SMatthew Dillon if (remove(buf) < 0) 497f7f25838SMatthew Dillon dfatal_errno("remove: Garbage %s\n", buf); 498f7f25838SMatthew Dillon printf("Deleted Garbage %s\n", buf); 499f7f25838SMatthew Dillon free(buf); 500f7f25838SMatthew Dillon } 501f7f25838SMatthew Dillon } 502f7f25838SMatthew Dillon closedir(dir); 503f7f25838SMatthew Dillon } 504066daf2aSMatthew Dillon 505066daf2aSMatthew Dillon static void 506066daf2aSMatthew Dillon rebuildTerminateSignal(int signo __unused) 507066daf2aSMatthew Dillon { 508066daf2aSMatthew Dillon if (RebuildRemovePath) 509066daf2aSMatthew Dillon remove(RebuildRemovePath); 510066daf2aSMatthew Dillon exit(1); 511066daf2aSMatthew Dillon 512066daf2aSMatthew Dillon } 513