/*- * Copyright 2010. Ivan Voras * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. */ /* * FreeBSD install - a package for the installation and maintainance * of non-core utilities. * * This is the module for creating patches en masse from two directories with * binary packages. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include "pkg_patch.h" #include "mkpatchdir.h" #include "mkpatch.h" #include "hashjob.h" void perform_mkpatchdir(char *dir_old, char *dir_new, char *dir_patch) { char dold[PATH_MAX], dnew[PATH_MAX], dpatch[PATH_MAX], flog[PATH_MAX]; char basename[PATH_MAX], version1[20], version2[20], suff[20]; struct filelist_head fl_old, fl_new; struct pkgjoinlist_head pkglist; struct pkgjoinlist *pl; FILE *fpl; if (realpath(dir_old, dold) == NULL) err(1, "Error resolving path: %s", dir_old); if (realpath(dir_new, dnew) == NULL) err(1, "Error resolving path: %s", dir_new); if (realpath(dir_patch, dpatch) == NULL) err(1, "Error resolving path: %s", dir_patch); if (access(dold, F_OK) != 0) err(1, "File not found: %s", dold); if (access(dnew, F_OK) != 0) err(1, "File not found: %s", dnew); if (access(dpatch, F_OK) != 0) err(1, "File not found: %s", dpatch); if (access(dold, R_OK) != 0) err(1, "Access error reading directory: %s", dold); if (access(dnew, R_OK) != 0) err(1, "Access error reading directory: %s", dnew); if (access(dpatch, W_OK) != 0) err(1, "Access error writing directory: %s", dpatch); if (pkg_repo_url == NULL) warnx("Package repository URL not specified for this " "patchset. Read the manual for details."); snprintf(flog, PATH_MAX, "%s/%s", dpatch, PKGPATCHINDEX_FNAME); fpl = fopen(flog, "a+"); if (fpl == NULL) err(1, "Cannot open patch log file: %s", flog); SLIST_INIT(&fl_old); SLIST_INIT(&fl_new); SLIST_INIT(&pkglist); if (filelist_gather(dold, &fl_old) != 0) errx(1, "Error gathering old package directory from: %s", dold); if (filelist_gather(dnew, &fl_new) != 0) errx(1, "Error gathering new package directory list from: %s", dnew); if (filelist_intersect_pkg(&fl_old, &fl_new, &pkglist) != 0) errx(1, "Error matching packages"); fprintf(fpl, "# Created by mkpatchdir at %s\n", time_ctime(-1)); fprintf(fpl, "@version %d.%d\n", PKGPATCH_VERSION_MAJOR, PKGPATCH_VERSION_MINOR); if (pkg_repo_url != NULL) fprintf(fpl, "@pkgrepo %s\n", pkg_repo_url); SLIST_FOREACH(pl, &pkglist, linkage) { char pname[PATH_MAX]; char pold[PATH_MAX], pnew[PATH_MAX], ppatch[PATH_MAX]; parse_package_name(pl->name1, basename, version1, NULL); parse_package_name(pl->name2, NULL, version2, suff); snprintf(pname, PATH_MAX, "%s-%s-%s%s", basename, version1, version2, suff); if (Verbose) printf("%s -> %s via %s\n", pl->name1, pl->name2, pname); snprintf(pold, PATH_MAX, "%s/%s", dold, pl->name1); snprintf(pnew, PATH_MAX, "%s/%s", dnew, pl->name2); snprintf(ppatch, PATH_MAX, "%s/%s", dpatch, pname); if (Verbose > 2) printf("\t(%s -> %s via %s)\n", pold, pnew, ppatch); if (Verbose) baton_twirl(); perform_mkpatch(pold, pnew, ppatch); fprintf(fpl, "@havepatch %s-%s %s-%s %s %s\n", basename, version1, basename, version2, pname, time_to_iso8601(-1)); } fclose(fpl); filelist_free(&fl_old); filelist_free(&fl_new); pkgjoinlist_free(&pkglist); }