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 39*1645cafeSMatthew Dillon typedef struct pinfo { 40*1645cafeSMatthew Dillon struct pinfo *next; 41*1645cafeSMatthew Dillon char *spath; 42*1645cafeSMatthew Dillon int foundit; 43*1645cafeSMatthew Dillon } pinfo_t; 44*1645cafeSMatthew Dillon 45*1645cafeSMatthew Dillon static int pinfocmp(const void *s1, const void *s2); 46*1645cafeSMatthew Dillon static void scanit(const char *path, const char *subpath, 47*1645cafeSMatthew Dillon int *countp, pinfo_t ***list_tailp); 48*1645cafeSMatthew Dillon pinfo_t *pinfofind(pinfo_t **ary, int count, char *spath); 49*1645cafeSMatthew Dillon 508e25f19bSMatthew Dillon void 51*1645cafeSMatthew Dillon DoRebuildRepo(int ask) 528e25f19bSMatthew Dillon { 53*1645cafeSMatthew Dillon char *buf; 54*1645cafeSMatthew Dillon 55*1645cafeSMatthew Dillon if (ask) { 56*1645cafeSMatthew Dillon if (askyn("Rebuild the repository? ") == 0) 57*1645cafeSMatthew Dillon return; 58*1645cafeSMatthew Dillon } 59*1645cafeSMatthew Dillon asprintf(&buf, "pkg repo -o %s %s", PackagesPath, RepositoryPath); 60*1645cafeSMatthew Dillon printf("Rebuilding repository\n"); 61*1645cafeSMatthew Dillon if (system(buf)) { 62*1645cafeSMatthew Dillon printf("Rebuild failed\n"); 63*1645cafeSMatthew Dillon } else { 64*1645cafeSMatthew Dillon printf("Rebuild succeeded\n"); 65*1645cafeSMatthew Dillon } 668e25f19bSMatthew Dillon } 678e25f19bSMatthew Dillon 688e25f19bSMatthew Dillon void 698e25f19bSMatthew Dillon DoUpgradePkgs(pkg_t *pkgs __unused, int ask __unused) 708e25f19bSMatthew Dillon { 718e25f19bSMatthew Dillon dfatal("Not Implemented"); 728e25f19bSMatthew Dillon } 738e25f19bSMatthew Dillon 748e25f19bSMatthew Dillon void 75*1645cafeSMatthew Dillon PurgeDistfiles(pkg_t *pkgs) 768e25f19bSMatthew Dillon { 77*1645cafeSMatthew Dillon pinfo_t *list; 78*1645cafeSMatthew Dillon pinfo_t *item; 79*1645cafeSMatthew Dillon pinfo_t **list_tail; 80*1645cafeSMatthew Dillon pinfo_t **ary; 81*1645cafeSMatthew Dillon char *dstr; 82*1645cafeSMatthew Dillon char *buf; 83*1645cafeSMatthew Dillon int count; 84*1645cafeSMatthew Dillon int delcount; 85*1645cafeSMatthew Dillon int i; 86*1645cafeSMatthew Dillon 87*1645cafeSMatthew Dillon printf("Scanning distfiles... "); 88*1645cafeSMatthew Dillon fflush(stdout); 89*1645cafeSMatthew Dillon count = 0; 90*1645cafeSMatthew Dillon list = NULL; 91*1645cafeSMatthew Dillon list_tail = &list; 92*1645cafeSMatthew Dillon scanit(DistFilesPath, NULL, &count, &list_tail); 93*1645cafeSMatthew Dillon printf("Checking %d distfiles\n", count); 94*1645cafeSMatthew Dillon fflush(stdout); 95*1645cafeSMatthew Dillon 96*1645cafeSMatthew Dillon ary = calloc(count, sizeof(pinfo_t *)); 97*1645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 98*1645cafeSMatthew Dillon ary[i] = list; 99*1645cafeSMatthew Dillon list = list->next; 100*1645cafeSMatthew Dillon } 101*1645cafeSMatthew Dillon ddassert(list == NULL); 102*1645cafeSMatthew Dillon qsort(ary, count, sizeof(pinfo_t *), pinfocmp); 103*1645cafeSMatthew Dillon 104*1645cafeSMatthew Dillon for (; pkgs; pkgs = pkgs->bnext) { 105*1645cafeSMatthew Dillon if (pkgs->distfiles == NULL || pkgs->distfiles[0] == 0) 106*1645cafeSMatthew Dillon continue; 107*1645cafeSMatthew Dillon ddprintf(0, "distfiles %s\n", pkgs->distfiles); 108*1645cafeSMatthew Dillon dstr = strtok(pkgs->distfiles, " \t"); 109*1645cafeSMatthew Dillon while (dstr) { 110*1645cafeSMatthew Dillon for (;;) { 111*1645cafeSMatthew Dillon if (pkgs->distsubdir && pkgs->distsubdir[0]) { 112*1645cafeSMatthew Dillon asprintf(&buf, "%s/%s", 113*1645cafeSMatthew Dillon pkgs->distsubdir, dstr); 114*1645cafeSMatthew Dillon item = pinfofind(ary, count, buf); 115*1645cafeSMatthew Dillon ddprintf(0, "TEST %s %p\n", buf, item); 116*1645cafeSMatthew Dillon free(buf); 117*1645cafeSMatthew Dillon buf = NULL; 118*1645cafeSMatthew Dillon } else { 119*1645cafeSMatthew Dillon item = pinfofind(ary, count, dstr); 120*1645cafeSMatthew Dillon ddprintf(0, "TEST %s %p\n", dstr, item); 121*1645cafeSMatthew Dillon } 122*1645cafeSMatthew Dillon if (item) { 123*1645cafeSMatthew Dillon item->foundit = 1; 124*1645cafeSMatthew Dillon break; 125*1645cafeSMatthew Dillon } 126*1645cafeSMatthew Dillon if (strrchr(dstr, ':') == NULL) 127*1645cafeSMatthew Dillon break; 128*1645cafeSMatthew Dillon *strrchr(dstr, ':') = 0; 129*1645cafeSMatthew Dillon } 130*1645cafeSMatthew Dillon dstr = strtok(NULL, " \t"); 131*1645cafeSMatthew Dillon } 132*1645cafeSMatthew Dillon } 133*1645cafeSMatthew Dillon 134*1645cafeSMatthew Dillon delcount = 0; 135*1645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 136*1645cafeSMatthew Dillon item = ary[i]; 137*1645cafeSMatthew Dillon if (item->foundit == 0) { 138*1645cafeSMatthew Dillon ++delcount; 139*1645cafeSMatthew Dillon } 140*1645cafeSMatthew Dillon } 141*1645cafeSMatthew Dillon if (askyn("Delete %d of %d items? ", delcount, count)) { 142*1645cafeSMatthew Dillon printf("Deleting %d/%d obsolete source distfiles\n", 143*1645cafeSMatthew Dillon delcount, count); 144*1645cafeSMatthew Dillon for (i = 0; i < count; ++i) { 145*1645cafeSMatthew Dillon item = ary[i]; 146*1645cafeSMatthew Dillon if (item->foundit == 0) { 147*1645cafeSMatthew Dillon asprintf(&buf, "%s/%s", 148*1645cafeSMatthew Dillon DistFilesPath, item->spath); 149*1645cafeSMatthew Dillon if (remove(buf) < 0) 150*1645cafeSMatthew Dillon printf("Cannot delete %s\n", buf); 151*1645cafeSMatthew Dillon free(buf); 152*1645cafeSMatthew Dillon } 153*1645cafeSMatthew Dillon } 154*1645cafeSMatthew Dillon } 155*1645cafeSMatthew Dillon 156*1645cafeSMatthew Dillon 157*1645cafeSMatthew Dillon free(ary); 1588e25f19bSMatthew Dillon } 1598e25f19bSMatthew Dillon 1608e25f19bSMatthew Dillon void 1618e25f19bSMatthew Dillon RemovePackages(pkg_t *pkgs __unused) 1628e25f19bSMatthew Dillon { 1638e25f19bSMatthew Dillon dfatal("Not Implemented"); 1648e25f19bSMatthew Dillon } 165*1645cafeSMatthew Dillon 166*1645cafeSMatthew Dillon static int 167*1645cafeSMatthew Dillon pinfocmp(const void *s1, const void *s2) 168*1645cafeSMatthew Dillon { 169*1645cafeSMatthew Dillon const pinfo_t *item1 = *(const pinfo_t *const*)s1; 170*1645cafeSMatthew Dillon const pinfo_t *item2 = *(const pinfo_t *const*)s2; 171*1645cafeSMatthew Dillon 172*1645cafeSMatthew Dillon return (strcmp(item1->spath, item2->spath)); 173*1645cafeSMatthew Dillon } 174*1645cafeSMatthew Dillon 175*1645cafeSMatthew Dillon pinfo_t * 176*1645cafeSMatthew Dillon pinfofind(pinfo_t **ary, int count, char *spath) 177*1645cafeSMatthew Dillon { 178*1645cafeSMatthew Dillon pinfo_t *item; 179*1645cafeSMatthew Dillon int res; 180*1645cafeSMatthew Dillon int b; 181*1645cafeSMatthew Dillon int e; 182*1645cafeSMatthew Dillon int m; 183*1645cafeSMatthew Dillon 184*1645cafeSMatthew Dillon b = 0; 185*1645cafeSMatthew Dillon e = count; 186*1645cafeSMatthew Dillon while (b != e) { 187*1645cafeSMatthew Dillon m = b + (e - b) / 2; 188*1645cafeSMatthew Dillon item = ary[m]; 189*1645cafeSMatthew Dillon res = strcmp(spath, item->spath); 190*1645cafeSMatthew Dillon if (res == 0) 191*1645cafeSMatthew Dillon return item; 192*1645cafeSMatthew Dillon if (res < 0) { 193*1645cafeSMatthew Dillon e = m; 194*1645cafeSMatthew Dillon } else { 195*1645cafeSMatthew Dillon b = m + 1; 196*1645cafeSMatthew Dillon } 197*1645cafeSMatthew Dillon } 198*1645cafeSMatthew Dillon return NULL; 199*1645cafeSMatthew Dillon } 200*1645cafeSMatthew Dillon 201*1645cafeSMatthew Dillon void 202*1645cafeSMatthew Dillon scanit(const char *path, const char *subpath, 203*1645cafeSMatthew Dillon int *countp, pinfo_t ***list_tailp) 204*1645cafeSMatthew Dillon { 205*1645cafeSMatthew Dillon struct dirent *den; 206*1645cafeSMatthew Dillon pinfo_t *item; 207*1645cafeSMatthew Dillon char *npath; 208*1645cafeSMatthew Dillon char *spath; 209*1645cafeSMatthew Dillon DIR *dir; 210*1645cafeSMatthew Dillon struct stat st; 211*1645cafeSMatthew Dillon 212*1645cafeSMatthew Dillon if ((dir = opendir(path)) != NULL) { 213*1645cafeSMatthew Dillon while ((den = readdir(dir)) != NULL) { 214*1645cafeSMatthew Dillon if (den->d_namlen == 1 && den->d_name[0] == '.') 215*1645cafeSMatthew Dillon continue; 216*1645cafeSMatthew Dillon if (den->d_namlen == 2 && den->d_name[0] == '.' && 217*1645cafeSMatthew Dillon den->d_name[1] == '.') 218*1645cafeSMatthew Dillon continue; 219*1645cafeSMatthew Dillon asprintf(&npath, "%s/%s", path, den->d_name); 220*1645cafeSMatthew Dillon if (lstat(npath, &st) < 0) { 221*1645cafeSMatthew Dillon free(npath); 222*1645cafeSMatthew Dillon continue; 223*1645cafeSMatthew Dillon } 224*1645cafeSMatthew Dillon if (S_ISDIR(st.st_mode)) { 225*1645cafeSMatthew Dillon if (subpath) { 226*1645cafeSMatthew Dillon asprintf(&spath, "%s/%s", 227*1645cafeSMatthew Dillon subpath, den->d_name); 228*1645cafeSMatthew Dillon scanit(npath, spath, 229*1645cafeSMatthew Dillon countp, list_tailp); 230*1645cafeSMatthew Dillon free(spath); 231*1645cafeSMatthew Dillon } else { 232*1645cafeSMatthew Dillon scanit(npath, den->d_name, 233*1645cafeSMatthew Dillon countp, list_tailp); 234*1645cafeSMatthew Dillon } 235*1645cafeSMatthew Dillon free(npath); 236*1645cafeSMatthew Dillon } else if (S_ISREG(st.st_mode)) { 237*1645cafeSMatthew Dillon item = calloc(1, sizeof(*item)); 238*1645cafeSMatthew Dillon if (subpath) { 239*1645cafeSMatthew Dillon asprintf(&item->spath, "%s/%s", 240*1645cafeSMatthew Dillon subpath, den->d_name); 241*1645cafeSMatthew Dillon } else { 242*1645cafeSMatthew Dillon item->spath = strdup(den->d_name); 243*1645cafeSMatthew Dillon } 244*1645cafeSMatthew Dillon **list_tailp = item; 245*1645cafeSMatthew Dillon *list_tailp = &item->next; 246*1645cafeSMatthew Dillon ++*countp; 247*1645cafeSMatthew Dillon ddprintf(0, "scan %s\n", item->spath); 248*1645cafeSMatthew Dillon } else { 249*1645cafeSMatthew Dillon free(npath); 250*1645cafeSMatthew Dillon } 251*1645cafeSMatthew Dillon } 252*1645cafeSMatthew Dillon closedir(dir); 253*1645cafeSMatthew Dillon } 254*1645cafeSMatthew Dillon } 255