xref: /dflybsd-src/usr.bin/dsynth/repo.c (revision 1645cafe2e12d248b171769271df3b29f9435f8a)
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