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); 50*066daf2aSMatthew Dillon static void childRebuildRepo(bulk_t *bulk); 51f7f25838SMatthew Dillon static void scandeletenew(const char *path); 521645cafeSMatthew Dillon 53*066daf2aSMatthew Dillon static void rebuildTerminateSignal(int signo); 54*066daf2aSMatthew Dillon 55*066daf2aSMatthew Dillon static char *RebuildRemovePath; 56*066daf2aSMatthew Dillon 578e25f19bSMatthew Dillon void 581645cafeSMatthew Dillon DoRebuildRepo(int ask) 598e25f19bSMatthew Dillon { 60*066daf2aSMatthew Dillon bulk_t *bulk; 61*066daf2aSMatthew Dillon FILE *fp; 62*066daf2aSMatthew Dillon int fd; 63*066daf2aSMatthew Dillon char tpath[256]; 641645cafeSMatthew Dillon 651645cafeSMatthew Dillon if (ask) { 661645cafeSMatthew Dillon if (askyn("Rebuild the repository? ") == 0) 671645cafeSMatthew Dillon return; 681645cafeSMatthew Dillon } 69f7f25838SMatthew Dillon 70f7f25838SMatthew Dillon /* 71f7f25838SMatthew Dillon * Scan the repository for temporary .new files and delete them. 72f7f25838SMatthew Dillon */ 73f7f25838SMatthew Dillon scandeletenew(RepositoryPath); 74f7f25838SMatthew Dillon 75f7f25838SMatthew Dillon /* 76*066daf2aSMatthew Dillon * Generate temporary file 77f7f25838SMatthew Dillon */ 78*066daf2aSMatthew Dillon snprintf(tpath, sizeof(tpath), "/tmp/meta.XXXXXXXX.conf"); 79*066daf2aSMatthew Dillon 80*066daf2aSMatthew Dillon signal(SIGTERM, rebuildTerminateSignal); 81*066daf2aSMatthew Dillon signal(SIGINT, rebuildTerminateSignal); 82*066daf2aSMatthew Dillon signal(SIGHUP, rebuildTerminateSignal); 83*066daf2aSMatthew Dillon 84*066daf2aSMatthew Dillon RebuildRemovePath = tpath; 85*066daf2aSMatthew Dillon 86*066daf2aSMatthew Dillon fd = mkostemps(tpath, 5, 0); 87*066daf2aSMatthew Dillon if (fd < 0) 88*066daf2aSMatthew Dillon dfatal_errno("Cannot create %s", tpath); 89*066daf2aSMatthew Dillon fp = fdopen(fd, "w"); 90*066daf2aSMatthew Dillon fprintf(fp, "version = 1;\n"); 91*066daf2aSMatthew Dillon fprintf(fp, "packing_format = \"%s\";\n", USE_PKG_SUFX + 1); 92*066daf2aSMatthew Dillon fclose(fp); 93*066daf2aSMatthew Dillon 94*066daf2aSMatthew Dillon /* 95*066daf2aSMatthew Dillon * Run the operation under our bulk infrastructure to 96*066daf2aSMatthew Dillon * get the correct environment. 97*066daf2aSMatthew Dillon */ 98*066daf2aSMatthew Dillon initbulk(childRebuildRepo, 1); 99*066daf2aSMatthew Dillon queuebulk(tpath, NULL, NULL, NULL); 100*066daf2aSMatthew Dillon bulk = getbulk(); 101*066daf2aSMatthew Dillon 102*066daf2aSMatthew Dillon if (bulk->r1) 1031645cafeSMatthew Dillon printf("Rebuild succeeded\n"); 104*066daf2aSMatthew Dillon else 105*066daf2aSMatthew Dillon printf("Rebuild failed\n"); 106*066daf2aSMatthew Dillon donebulk(); 107*066daf2aSMatthew Dillon 108*066daf2aSMatthew Dillon remove(tpath); 109*066daf2aSMatthew Dillon } 110*066daf2aSMatthew Dillon 111*066daf2aSMatthew Dillon static void 112*066daf2aSMatthew Dillon childRebuildRepo(bulk_t *bulk) 113*066daf2aSMatthew Dillon { 114*066daf2aSMatthew Dillon FILE *fp; 115*066daf2aSMatthew Dillon char *ptr; 116*066daf2aSMatthew Dillon size_t len; 117*066daf2aSMatthew Dillon pid_t pid; 118*066daf2aSMatthew Dillon const char *cav[MAXCAC]; 119*066daf2aSMatthew Dillon int cac; 120*066daf2aSMatthew Dillon 121*066daf2aSMatthew Dillon cac = 0; 122*066daf2aSMatthew Dillon cav[cac++] = PKG_BINARY; 123*066daf2aSMatthew Dillon cav[cac++] = "repo"; 124*066daf2aSMatthew Dillon cav[cac++] = "-m"; 125*066daf2aSMatthew Dillon cav[cac++] = bulk->s1; 126*066daf2aSMatthew Dillon cav[cac++] = "-o"; 127*066daf2aSMatthew Dillon cav[cac++] = PackagesPath; 128*066daf2aSMatthew Dillon cav[cac++] = RepositoryPath; 129*066daf2aSMatthew Dillon 130*066daf2aSMatthew Dillon printf("pkg repo -m %s -o %s %s\n", 131*066daf2aSMatthew Dillon bulk->s1, PackagesPath, RepositoryPath); 132*066daf2aSMatthew Dillon 133*066daf2aSMatthew Dillon fp = dexec_open(cav, cac, &pid, 1, 0); 134*066daf2aSMatthew Dillon while ((ptr = fgetln(fp, &len)) != NULL) 135*066daf2aSMatthew Dillon fwrite(ptr, 1, len, stdout); 136*066daf2aSMatthew Dillon if (dexec_close(fp, pid) == 0) { 137*066daf2aSMatthew Dillon bulk->r1 = strdup(""); 1381645cafeSMatthew Dillon } 1398e25f19bSMatthew Dillon } 1408e25f19bSMatthew Dillon 1418e25f19bSMatthew Dillon void 1428e25f19bSMatthew Dillon DoUpgradePkgs(pkg_t *pkgs __unused, int ask __unused) 1438e25f19bSMatthew Dillon { 1448e25f19bSMatthew Dillon dfatal("Not Implemented"); 1458e25f19bSMatthew Dillon } 1468e25f19bSMatthew Dillon 1478e25f19bSMatthew Dillon void 1481645cafeSMatthew Dillon PurgeDistfiles(pkg_t *pkgs) 1498e25f19bSMatthew Dillon { 1501645cafeSMatthew Dillon pinfo_t *list; 1511645cafeSMatthew Dillon pinfo_t *item; 1521645cafeSMatthew Dillon pinfo_t **list_tail; 1531645cafeSMatthew Dillon pinfo_t **ary; 1541645cafeSMatthew Dillon char *dstr; 1551645cafeSMatthew Dillon char *buf; 1561645cafeSMatthew Dillon int count; 1571645cafeSMatthew Dillon int delcount; 1581645cafeSMatthew Dillon int i; 1591645cafeSMatthew Dillon 1601645cafeSMatthew Dillon printf("Scanning distfiles... "); 1611645cafeSMatthew Dillon fflush(stdout); 1621645cafeSMatthew Dillon count = 0; 1631645cafeSMatthew Dillon list = NULL; 1641645cafeSMatthew Dillon list_tail = &list; 1651645cafeSMatthew Dillon scanit(DistFilesPath, NULL, &count, &list_tail); 1661645cafeSMatthew Dillon printf("Checking %d distfiles\n", count); 1671645cafeSMatthew Dillon fflush(stdout); 1681645cafeSMatthew Dillon 1691645cafeSMatthew Dillon ary = calloc(count, sizeof(pinfo_t *)); 1701645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 1711645cafeSMatthew Dillon ary[i] = list; 1721645cafeSMatthew Dillon list = list->next; 1731645cafeSMatthew Dillon } 1741645cafeSMatthew Dillon ddassert(list == NULL); 1751645cafeSMatthew Dillon qsort(ary, count, sizeof(pinfo_t *), pinfocmp); 1761645cafeSMatthew Dillon 1771645cafeSMatthew Dillon for (; pkgs; pkgs = pkgs->bnext) { 1781645cafeSMatthew Dillon if (pkgs->distfiles == NULL || pkgs->distfiles[0] == 0) 1791645cafeSMatthew Dillon continue; 1801645cafeSMatthew Dillon ddprintf(0, "distfiles %s\n", pkgs->distfiles); 1811645cafeSMatthew Dillon dstr = strtok(pkgs->distfiles, " \t"); 1821645cafeSMatthew Dillon while (dstr) { 1831645cafeSMatthew Dillon for (;;) { 1844ea2ee4dSMatthew Dillon if (pkgs->distsubdir) { 1851645cafeSMatthew Dillon asprintf(&buf, "%s/%s", 1861645cafeSMatthew Dillon pkgs->distsubdir, dstr); 1871645cafeSMatthew Dillon item = pinfofind(ary, count, buf); 1881645cafeSMatthew Dillon ddprintf(0, "TEST %s %p\n", buf, item); 1891645cafeSMatthew Dillon free(buf); 1901645cafeSMatthew Dillon buf = NULL; 1911645cafeSMatthew Dillon } else { 1921645cafeSMatthew Dillon item = pinfofind(ary, count, dstr); 1931645cafeSMatthew Dillon ddprintf(0, "TEST %s %p\n", dstr, item); 1941645cafeSMatthew Dillon } 1951645cafeSMatthew Dillon if (item) { 1961645cafeSMatthew Dillon item->foundit = 1; 1971645cafeSMatthew Dillon break; 1981645cafeSMatthew Dillon } 1991645cafeSMatthew Dillon if (strrchr(dstr, ':') == NULL) 2001645cafeSMatthew Dillon break; 2011645cafeSMatthew Dillon *strrchr(dstr, ':') = 0; 2021645cafeSMatthew Dillon } 2031645cafeSMatthew Dillon dstr = strtok(NULL, " \t"); 2041645cafeSMatthew Dillon } 2051645cafeSMatthew Dillon } 2061645cafeSMatthew Dillon 2071645cafeSMatthew Dillon delcount = 0; 2081645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 2091645cafeSMatthew Dillon item = ary[i]; 2101645cafeSMatthew Dillon if (item->foundit == 0) { 2111645cafeSMatthew Dillon ++delcount; 2121645cafeSMatthew Dillon } 2131645cafeSMatthew Dillon } 2141645cafeSMatthew Dillon if (askyn("Delete %d of %d items? ", delcount, count)) { 2151645cafeSMatthew Dillon printf("Deleting %d/%d obsolete source distfiles\n", 2161645cafeSMatthew Dillon delcount, count); 2171645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 2181645cafeSMatthew Dillon item = ary[i]; 2191645cafeSMatthew Dillon if (item->foundit == 0) { 2201645cafeSMatthew Dillon asprintf(&buf, "%s/%s", 2211645cafeSMatthew Dillon DistFilesPath, item->spath); 2221645cafeSMatthew Dillon if (remove(buf) < 0) 2231645cafeSMatthew Dillon printf("Cannot delete %s\n", buf); 2241645cafeSMatthew Dillon free(buf); 2251645cafeSMatthew Dillon } 2261645cafeSMatthew Dillon } 2271645cafeSMatthew Dillon } 2281645cafeSMatthew Dillon 2291645cafeSMatthew Dillon 2301645cafeSMatthew Dillon free(ary); 2318e25f19bSMatthew Dillon } 2328e25f19bSMatthew Dillon 2338e25f19bSMatthew Dillon void 234f4094b20SMatthew Dillon RemovePackages(pkg_t *list) 2358e25f19bSMatthew Dillon { 236f4094b20SMatthew Dillon pkg_t *scan; 237f4094b20SMatthew Dillon char *path; 238f4094b20SMatthew Dillon 239f4094b20SMatthew Dillon for (scan = list; scan; scan = scan->bnext) { 240f4094b20SMatthew Dillon if ((scan->flags & PKGF_MANUALSEL) == 0) 241f4094b20SMatthew Dillon continue; 242f4094b20SMatthew Dillon if (scan->pkgfile) { 243f4094b20SMatthew Dillon scan->flags &= ~PKGF_PACKAGED; 244f4094b20SMatthew Dillon scan->pkgfile_size = 0; 245f4094b20SMatthew Dillon asprintf(&path, "%s/%s", RepositoryPath, scan->pkgfile); 246f4094b20SMatthew Dillon if (remove(path) == 0) 247f4094b20SMatthew Dillon printf("Removed: %s\n", path); 248f4094b20SMatthew Dillon free(path); 249f4094b20SMatthew Dillon } 250f4094b20SMatthew Dillon if (scan->pkgfile == NULL || 251f4094b20SMatthew Dillon (scan->flags & (PKGF_DUMMY | PKGF_META))) { 252f4094b20SMatthew Dillon removePackagesMetaRecurse(scan); 253f4094b20SMatthew Dillon } 254f4094b20SMatthew Dillon } 255f4094b20SMatthew Dillon } 256f4094b20SMatthew Dillon 257f4094b20SMatthew Dillon static void 258f4094b20SMatthew Dillon removePackagesMetaRecurse(pkg_t *pkg) 259f4094b20SMatthew Dillon { 260f4094b20SMatthew Dillon pkglink_t *link; 261f4094b20SMatthew Dillon pkg_t *scan; 262f4094b20SMatthew Dillon char *path; 263f4094b20SMatthew Dillon 264f4094b20SMatthew Dillon PKGLIST_FOREACH(link, &pkg->idepon_list) { 265f4094b20SMatthew Dillon scan = link->pkg; 266f4094b20SMatthew Dillon if (scan == NULL) 267f4094b20SMatthew Dillon continue; 268f4094b20SMatthew Dillon if (scan->pkgfile == NULL || 269f4094b20SMatthew Dillon (scan->flags & (PKGF_DUMMY | PKGF_META))) { 270f4094b20SMatthew Dillon removePackagesMetaRecurse(scan); 271f4094b20SMatthew Dillon continue; 272f4094b20SMatthew Dillon } 273f4094b20SMatthew Dillon scan->flags &= ~PKGF_PACKAGED; 274f4094b20SMatthew Dillon scan->pkgfile_size = 0; 275f4094b20SMatthew Dillon 276f4094b20SMatthew Dillon asprintf(&path, "%s/%s", RepositoryPath, scan->pkgfile); 277f4094b20SMatthew Dillon if (remove(path) == 0) 278f4094b20SMatthew Dillon printf("Removed: %s\n", path); 279f4094b20SMatthew Dillon free(path); 280f4094b20SMatthew Dillon } 2818e25f19bSMatthew Dillon } 2821645cafeSMatthew Dillon 2831645cafeSMatthew Dillon static int 2841645cafeSMatthew Dillon pinfocmp(const void *s1, const void *s2) 2851645cafeSMatthew Dillon { 2861645cafeSMatthew Dillon const pinfo_t *item1 = *(const pinfo_t *const*)s1; 2871645cafeSMatthew Dillon const pinfo_t *item2 = *(const pinfo_t *const*)s2; 2881645cafeSMatthew Dillon 2891645cafeSMatthew Dillon return (strcmp(item1->spath, item2->spath)); 2901645cafeSMatthew Dillon } 2911645cafeSMatthew Dillon 2921645cafeSMatthew Dillon pinfo_t * 2931645cafeSMatthew Dillon pinfofind(pinfo_t **ary, int count, char *spath) 2941645cafeSMatthew Dillon { 2951645cafeSMatthew Dillon pinfo_t *item; 2961645cafeSMatthew Dillon int res; 2971645cafeSMatthew Dillon int b; 2981645cafeSMatthew Dillon int e; 2991645cafeSMatthew Dillon int m; 3001645cafeSMatthew Dillon 3011645cafeSMatthew Dillon b = 0; 3021645cafeSMatthew Dillon e = count; 3031645cafeSMatthew Dillon while (b != e) { 3041645cafeSMatthew Dillon m = b + (e - b) / 2; 3051645cafeSMatthew Dillon item = ary[m]; 3061645cafeSMatthew Dillon res = strcmp(spath, item->spath); 3071645cafeSMatthew Dillon if (res == 0) 3081645cafeSMatthew Dillon return item; 3091645cafeSMatthew Dillon if (res < 0) { 3101645cafeSMatthew Dillon e = m; 3111645cafeSMatthew Dillon } else { 3121645cafeSMatthew Dillon b = m + 1; 3131645cafeSMatthew Dillon } 3141645cafeSMatthew Dillon } 3151645cafeSMatthew Dillon return NULL; 3161645cafeSMatthew Dillon } 3171645cafeSMatthew Dillon 3181645cafeSMatthew Dillon void 3191645cafeSMatthew Dillon scanit(const char *path, const char *subpath, 3201645cafeSMatthew Dillon int *countp, pinfo_t ***list_tailp) 3211645cafeSMatthew Dillon { 3221645cafeSMatthew Dillon struct dirent *den; 3231645cafeSMatthew Dillon pinfo_t *item; 3241645cafeSMatthew Dillon char *npath; 3251645cafeSMatthew Dillon char *spath; 3261645cafeSMatthew Dillon DIR *dir; 3271645cafeSMatthew Dillon struct stat st; 3281645cafeSMatthew Dillon 3291645cafeSMatthew Dillon if ((dir = opendir(path)) != NULL) { 3301645cafeSMatthew Dillon while ((den = readdir(dir)) != NULL) { 3311645cafeSMatthew Dillon if (den->d_namlen == 1 && den->d_name[0] == '.') 3321645cafeSMatthew Dillon continue; 3331645cafeSMatthew Dillon if (den->d_namlen == 2 && den->d_name[0] == '.' && 3341645cafeSMatthew Dillon den->d_name[1] == '.') 3351645cafeSMatthew Dillon continue; 3361645cafeSMatthew Dillon asprintf(&npath, "%s/%s", path, den->d_name); 3371645cafeSMatthew Dillon if (lstat(npath, &st) < 0) { 3381645cafeSMatthew Dillon free(npath); 3391645cafeSMatthew Dillon continue; 3401645cafeSMatthew Dillon } 3411645cafeSMatthew Dillon if (S_ISDIR(st.st_mode)) { 3421645cafeSMatthew Dillon if (subpath) { 3431645cafeSMatthew Dillon asprintf(&spath, "%s/%s", 3441645cafeSMatthew Dillon subpath, den->d_name); 3451645cafeSMatthew Dillon scanit(npath, spath, 3461645cafeSMatthew Dillon countp, list_tailp); 3471645cafeSMatthew Dillon free(spath); 3481645cafeSMatthew Dillon } else { 3491645cafeSMatthew Dillon scanit(npath, den->d_name, 3501645cafeSMatthew Dillon countp, list_tailp); 3511645cafeSMatthew Dillon } 3521645cafeSMatthew Dillon } else if (S_ISREG(st.st_mode)) { 3531645cafeSMatthew Dillon item = calloc(1, sizeof(*item)); 3541645cafeSMatthew Dillon if (subpath) { 3551645cafeSMatthew Dillon asprintf(&item->spath, "%s/%s", 3561645cafeSMatthew Dillon subpath, den->d_name); 3571645cafeSMatthew Dillon } else { 3581645cafeSMatthew Dillon item->spath = strdup(den->d_name); 3591645cafeSMatthew Dillon } 3601645cafeSMatthew Dillon **list_tailp = item; 3611645cafeSMatthew Dillon *list_tailp = &item->next; 3621645cafeSMatthew Dillon ++*countp; 3631645cafeSMatthew Dillon ddprintf(0, "scan %s\n", item->spath); 3641645cafeSMatthew Dillon } 3656a3a20b1SMatthew Dillon free(npath); 3661645cafeSMatthew Dillon } 3671645cafeSMatthew Dillon closedir(dir); 3681645cafeSMatthew Dillon } 3691645cafeSMatthew Dillon } 370f7f25838SMatthew Dillon 371f7f25838SMatthew Dillon /* 372f7f25838SMatthew Dillon * This removes any .new files left over in the repo. These can wind 373f7f25838SMatthew Dillon * being left around when dsynth is killed. 374f7f25838SMatthew Dillon */ 375f7f25838SMatthew Dillon static void 376f7f25838SMatthew Dillon scandeletenew(const char *path) 377f7f25838SMatthew Dillon { 378f7f25838SMatthew Dillon struct dirent *den; 379f7f25838SMatthew Dillon const char *ptr; 380f7f25838SMatthew Dillon DIR *dir; 381f7f25838SMatthew Dillon char *buf; 382f7f25838SMatthew Dillon 383f7f25838SMatthew Dillon if ((dir = opendir(path)) == NULL) 384f7f25838SMatthew Dillon dfatal_errno("Cannot scan directory %s", path); 385f7f25838SMatthew Dillon while ((den = readdir(dir)) != NULL) { 386f7f25838SMatthew Dillon if ((ptr = strrchr(den->d_name, '.')) != NULL && 387f7f25838SMatthew Dillon strcmp(ptr, ".new") == 0) { 388f7f25838SMatthew Dillon asprintf(&buf, "%s/%s", path, den->d_name); 389f7f25838SMatthew Dillon if (remove(buf) < 0) 390f7f25838SMatthew Dillon dfatal_errno("remove: Garbage %s\n", buf); 391f7f25838SMatthew Dillon printf("Deleted Garbage %s\n", buf); 392f7f25838SMatthew Dillon free(buf); 393f7f25838SMatthew Dillon } 394f7f25838SMatthew Dillon } 395f7f25838SMatthew Dillon closedir(dir); 396f7f25838SMatthew Dillon } 397*066daf2aSMatthew Dillon 398*066daf2aSMatthew Dillon static void 399*066daf2aSMatthew Dillon rebuildTerminateSignal(int signo __unused) 400*066daf2aSMatthew Dillon { 401*066daf2aSMatthew Dillon if (RebuildRemovePath) 402*066daf2aSMatthew Dillon remove(RebuildRemovePath); 403*066daf2aSMatthew Dillon exit(1); 404*066daf2aSMatthew Dillon 405*066daf2aSMatthew Dillon } 406