Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Quick and dirty pkg2legacy
Baptiste Daroussin committed 14 years ago
commit a44e929f9d48578087db4d2605325f3bfcc87130
parent 48fa84c
3 files changed +261 -1
modified Makefile
@@ -1,5 +1,6 @@
SUBDIR=	external \
	libpkg \
-
	pkg
+
	pkg \
+
	pkg2legacy

.include <bsd.subdir.mk>
added pkg2legacy/Makefile
@@ -0,0 +1,10 @@
+
PROG=	pkg2legacy
+
SRC=	pkg2legacy.c
+
BINDIR=	/usr/sbin
+

+
CFLAGS=	-I${.CURDIR}/../libpkg
+
LDADD=	-L../libpkg \
+
	-lpkgng
+
WARNS?=	6
+

+
.include <bsd.prog.mk>
added pkg2legacy/pkg2legacy.c
@@ -0,0 +1,249 @@
+
#include <err.h>
+

+
#include <bzlib.h>
+
#include <unistd.h>
+
#include <sys/sbuf.h>
+
#include <string.h>
+
#include <sysexits.h>
+
#include <sys/param.h>
+
#include <sys/types.h>
+
#include <sys/stat.h>
+

+
#include <archive.h>
+
#include <archive_entry.h>
+

+
#include <fts.h>
+

+
#include <pkg.h>
+

+
static int
+
usage(void)
+
{
+
	fprintf(stderr, "usage: %s pkgng_repository legacy_repository\n", getprogname());
+
	return (EX_USAGE);
+
}
+

+
int
+
main(int argc, char **argv)
+
{
+
	struct stat st;
+
	FTS *fts;
+
	FTSENT *p;
+
	char *dir[2];
+
	char *category;
+
	char destdir[MAXPATHLEN];
+
	char destpath[MAXPATHLEN];
+
	char relativepath[MAXPATHLEN];
+
	char linkpath[MAXPATHLEN];
+
	char *newpath;
+
	BZFILE *bz;
+
	int bzError;
+
	struct pkg **deps;
+
	struct archive *pkgng;
+
	struct archive *legacypkg;
+
	struct archive_entry *ae;
+
	size_t size;
+
	int i;
+
	int r;
+

+
	char *tmp;
+
	char *buf;
+
	struct pkg *pkg = NULL;
+

+
	struct sbuf *sbuf = sbuf_new_auto();
+
	struct sbuf *indexfile = sbuf_new_auto();
+

+
	FILE *indexf;
+

+
	if (argc != 3)
+
		return (usage());
+

+
	if (lstat(argv[1], &st) != 0)
+
		err(EX_USAGE, "Can't find pkgng repository");
+

+
	dir[0] = argv[1];
+
	dir[1] = NULL;
+

+
	if (!S_ISDIR(st.st_mode))
+
		errx(EX_USAGE, "%s is not a pkgng repository", argv[1]);
+

+
	if (lstat(argv[2], &st) != 0) {
+
		if (mkdir(argv[2], 0755) != 0)
+
			err(EX_CANTCREAT, "Unable to create legacy repository: %s", argv[2]);
+
	} else {
+
		errx(EX_USAGE, "legacy repository already exist");
+
	}
+

+
	getcwd(destdir, MAXPATHLEN);
+

+
	if (argv[2][0] == '/')
+
		strlcpy(destdir, argv[2], MAXPATHLEN);
+
	else
+
		snprintf(destdir, MAXPATHLEN, "%s/%s", destdir, argv[2]);
+

+
	snprintf(destpath, MAXPATHLEN, "%s/All", destdir);
+
	mkdir(destpath, 0755);
+

+
	if ((fts = fts_open(dir, FTS_NOSTAT, NULL)) == NULL)
+
		err(EX_SOFTWARE, "Problem reading the pkgng repository");
+

+
	ae = archive_entry_new();
+

+
	while ((p = fts_read(fts)) != NULL) {
+
		if (!strcmp(p->fts_name, "repo.txz"))
+
			continue;
+

+
		if (p->fts_info != FTS_F)
+
			continue;
+

+
		if (pkg_open(&pkg, p->fts_accpath) != EPKG_OK) {
+
			pkg_error_warn("Unable to open package %s (ignoring)", p->fts_accpath);
+
			continue;
+
		}
+

+
		archive_entry_clear(ae);
+
		category = strdup(pkg_get(pkg, PKG_ORIGIN));
+
		tmp = strrchr(category, '/');
+
		tmp[0] = '\0';
+

+
		/* prepare the indexfile */
+
		sbuf_printf(indexfile, "%s-%s|" /* name */
+
				"/usr/ports/%s|" /* path */
+
				"%s|" /* prefix */
+
				"%s|" /* comment */
+
				"/usr/ports/%s/pkg-descr|" /* origin */
+
				"%s|" /*maintainer */
+
				"%s|" /* categories */
+
				"|", /* build depends */
+
				pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION),
+
				pkg_get(pkg, PKG_ORIGIN),
+
				pkg_get(pkg, PKG_PREFIX),
+
				pkg_get(pkg, PKG_COMMENT),
+
				pkg_get(pkg, PKG_ORIGIN),
+
				pkg_get(pkg, PKG_MAINTAINER),
+
				category /* FIXME where are the other categories */
+
			   );
+

+

+
		snprintf(destpath, MAXPATHLEN, "%s/%s", destdir, category);
+
		bzero(&st, sizeof(struct stat));
+
		if (lstat(category, &st) != 0)
+
			mkdir(destpath, 0755);
+

+
		snprintf(destpath, MAXPATHLEN, "%s/%s-%s.tbz", destpath, pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION));
+
		snprintf(relativepath, MAXPATHLEN, "../%s/%s-%s.tbz", category, pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION));
+
		snprintf(linkpath, MAXPATHLEN, "%s/All/%s.tbz",destdir, pkg_get(pkg, PKG_NAME));
+

+
		pkgng = archive_read_new();
+
		archive_read_support_format_tar(pkgng);
+
		archive_read_support_compression_all(pkgng);
+
		archive_read_open_filename(pkgng, p->fts_accpath, 4096);
+

+
		legacypkg = archive_write_new();
+
		archive_write_set_format_ustar(legacypkg);
+
		archive_write_set_compression_bzip2(legacypkg);
+
		archive_write_open_filename(legacypkg, destpath);
+

+
		archive_entry_set_pathname(ae, "+COMMENT");
+
		archive_entry_set_filetype(ae, AE_IFREG);
+
		archive_entry_set_perm(ae, 0644);
+
		archive_entry_set_gname(ae, "wheel");
+
		archive_entry_set_uname(ae, "root");
+
		archive_entry_set_size(ae, strlen(pkg_get(pkg, PKG_COMMENT)));
+
		archive_write_header(legacypkg, ae);
+
		archive_write_data(legacypkg, pkg_get(pkg, PKG_COMMENT), strlen(pkg_get(pkg, PKG_COMMENT)));
+

+
		sbuf_clear(sbuf);
+
		sbuf_printf(sbuf, "@comment PKG_FORMAT_REVISION:1.1\n"
+
				"@name %s-%s\n"
+
				"@comment ORIGIN:%s\n"
+
				"@cwd %s\n",
+
				pkg_get(pkg, PKG_NAME),
+
				pkg_get(pkg, PKG_VERSION),
+
				pkg_get(pkg, PKG_ORIGIN),
+
				pkg_get(pkg, PKG_PREFIX));
+

+
		if ((deps = pkg_deps(pkg)) != NULL) {
+
			for (i = 0; deps[i] != NULL; i++) {
+
				sbuf_printf(sbuf, "@pkgdep %s-%s\n"
+
						"@comment DEPORIGIN:%s\n",
+
						pkg_get(deps[i], PKG_NAME),
+
						pkg_get(deps[i], PKG_VERSION),
+
						pkg_get(deps[i], PKG_ORIGIN));
+
				sbuf_printf(indexfile, "%s-%s ", pkg_get(deps[i], PKG_NAME), pkg_get(deps[i], PKG_VERSION));
+
			}
+
		}
+

+
		sbuf_cat(indexfile, "|");
+
		sbuf_printf(indexfile, "%s|"
+
				"|" /* extract depends */
+
				"|" /* patch depends */
+
				"\n", /* fetch depends */
+
				pkg_get(pkg, PKG_WWW));
+
		archive_entry_clear(ae);
+
		while ((r = archive_read_next_header(pkgng, &ae)) != ARCHIVE_EOF) {
+
			if (archive_entry_pathname(ae)[0] == '+') {
+
				if (strcmp(archive_entry_pathname(ae), "+MANIFEST") == 0)
+
					continue;
+
				else {
+
					size = archive_entry_size(ae);
+
					buf = malloc(size + 1);
+
					archive_write_header(legacypkg, ae);
+
					archive_read_data(pkgng, buf, size);
+
					archive_write_data(legacypkg, buf, size);
+
					free(buf);
+
					continue;
+
				}
+
			}
+

+
			size = archive_entry_size(ae);
+

+
			strlcpy(destpath, archive_entry_pathname(ae), MAXPATHLEN);
+
			if (strncmp(destpath, pkg_get(pkg, PKG_PREFIX), strlen(pkg_get(pkg, PKG_PREFIX))) == 0)
+
				newpath = destpath + strlen(pkg_get(pkg, PKG_PREFIX));
+
			else {
+
				sbuf_cat(sbuf, "@cwd /");
+
				newpath = destpath;
+
			}
+

+
			if (newpath[0] == '/')
+
				newpath++;
+

+
			sbuf_printf(sbuf, "%s\n", newpath);
+
			archive_entry_set_pathname(ae, newpath);
+
			buf = malloc(size + 1);
+
			archive_write_header(legacypkg, ae);
+
			archive_read_data(pkgng, buf, size);
+
			archive_write_data(legacypkg, buf, size);
+
			free(buf);
+
		}
+

+
		archive_entry_set_pathname(ae, "+CONTENTS");
+
		archive_entry_set_filetype(ae, AE_IFREG);
+
		archive_entry_set_perm(ae, 0644);
+
		archive_entry_set_gname(ae, "wheel");
+
		archive_entry_set_uname(ae, "root");
+
		archive_entry_set_size(ae, sbuf_len(sbuf));
+
		archive_write_header(legacypkg, ae);
+
		archive_write_data(legacypkg, sbuf_data(sbuf), sbuf_len(sbuf));
+

+
		archive_write_finish(legacypkg);
+
		archive_read_finish(pkgng);
+

+
		snprintf(destpath, MAXPATHLEN, "%s/All", destdir);
+
		symlink(relativepath, linkpath);
+
	}
+

+
	snprintf(destpath, MAXPATHLEN, "%s/INDEX.bz2", destdir);
+
	indexf = fopen(destpath, "w");
+
	bz = BZ2_bzWriteOpen(&bzError, indexf, 9, 0, 0);
+
	BZ2_bzWrite(&bzError, bz, sbuf_data(indexfile), sbuf_len(indexfile));
+
	BZ2_bzWriteClose(&bzError, bz, 0, NULL, NULL);
+
	fclose(indexf);
+

+
	pkg_free(pkg);
+
	sbuf_delete(indexfile);
+
	sbuf_delete(sbuf);
+

+
	return (EXIT_SUCCESS);
+
}