1 1.4 nia /* $NetBSD: perform.c,v 1.4 2021/04/10 19:49:59 nia Exp $ */ 2 1.1 joerg 3 1.1 joerg #if HAVE_CONFIG_H 4 1.1 joerg #include "config.h" 5 1.1 joerg #endif 6 1.1 joerg #include <nbcompat.h> 7 1.1 joerg #if HAVE_SYS_CDEFS_H 8 1.1 joerg #include <sys/cdefs.h> 9 1.1 joerg #endif 10 1.4 nia __RCSID("$NetBSD: perform.c,v 1.4 2021/04/10 19:49:59 nia Exp $"); 11 1.1 joerg 12 1.1 joerg /* 13 1.1 joerg * FreeBSD install - a package for the installation and maintainance 14 1.1 joerg * of non-core utilities. 15 1.1 joerg * 16 1.1 joerg * Redistribution and use in source and binary forms, with or without 17 1.1 joerg * modification, are permitted provided that the following conditions 18 1.1 joerg * are met: 19 1.1 joerg * 1. Redistributions of source code must retain the above copyright 20 1.1 joerg * notice, this list of conditions and the following disclaimer. 21 1.1 joerg * 2. Redistributions in binary form must reproduce the above copyright 22 1.1 joerg * notice, this list of conditions and the following disclaimer in the 23 1.1 joerg * documentation and/or other materials provided with the distribution. 24 1.1 joerg * 25 1.1 joerg * Jordan K. Hubbard 26 1.1 joerg * 18 July 1993 27 1.1 joerg * 28 1.1 joerg * This is the main body of the create module. 29 1.1 joerg * 30 1.1 joerg */ 31 1.1 joerg 32 1.1 joerg #include "lib.h" 33 1.1 joerg #include "create.h" 34 1.1 joerg 35 1.1 joerg #if HAVE_ERR_H 36 1.1 joerg #include <err.h> 37 1.1 joerg #endif 38 1.2 joerg #if HAVE_FCNTL_H 39 1.2 joerg #include <fcntl.h> 40 1.2 joerg #endif 41 1.1 joerg #if HAVE_UNISTD_H 42 1.1 joerg #include <unistd.h> 43 1.1 joerg #endif 44 1.1 joerg 45 1.1 joerg static void 46 1.1 joerg sanity_check(void) 47 1.1 joerg { 48 1.1 joerg if (!Comment) 49 1.1 joerg errx(2, "required package comment string is missing (-c comment)"); 50 1.1 joerg if (!Desc) 51 1.1 joerg errx(2, "required package description string is missing (-d desc)"); 52 1.1 joerg if (!Contents) 53 1.1 joerg errx(2, "required package contents list is missing (-f [-]file)"); 54 1.1 joerg } 55 1.1 joerg 56 1.1 joerg static void 57 1.1 joerg register_depends(package_t *plist, char *deps, int build_only) 58 1.1 joerg { 59 1.1 joerg char *cp; 60 1.1 joerg 61 1.1 joerg if (Verbose && !PlistOnly) { 62 1.1 joerg if (build_only) 63 1.1 joerg printf("Registering build depends:"); 64 1.1 joerg else 65 1.1 joerg printf("Registering depends:"); 66 1.1 joerg } 67 1.1 joerg while (deps) { 68 1.1 joerg cp = strsep(&deps, " \t\n"); 69 1.1 joerg if (*cp) { 70 1.1 joerg char *best_installed; 71 1.3 wiz best_installed = find_best_matching_installed_pkg(cp, 1); 72 1.1 joerg if (best_installed != NULL) { 73 1.1 joerg add_plist(plist, PLIST_BLDDEP, best_installed); 74 1.1 joerg if (Verbose && !PlistOnly && build_only) 75 1.1 joerg printf(" %s", cp); 76 1.1 joerg } else 77 1.1 joerg warnx("No matching package installed for %s", cp); 78 1.1 joerg free(best_installed); 79 1.1 joerg if (!build_only) { 80 1.1 joerg add_plist(plist, PLIST_PKGDEP, cp); 81 1.1 joerg if (Verbose && !PlistOnly) 82 1.1 joerg printf(" %s", cp); 83 1.1 joerg } 84 1.1 joerg } 85 1.1 joerg } 86 1.1 joerg if (Verbose && !PlistOnly) 87 1.1 joerg printf(".\n"); 88 1.1 joerg } 89 1.1 joerg 90 1.1 joerg /* 91 1.2 joerg * Expect "fname" to point at a file, and read it into 92 1.2 joerg * the buffer returned. 93 1.2 joerg */ 94 1.2 joerg static char * 95 1.2 joerg fileGetContents(char *fname) 96 1.2 joerg { 97 1.2 joerg char *contents; 98 1.2 joerg struct stat sb; 99 1.2 joerg int fd; 100 1.2 joerg 101 1.2 joerg if (stat(fname, &sb) == FAIL) { 102 1.2 joerg errx(2, "can't stat '%s'", fname); 103 1.2 joerg } 104 1.2 joerg 105 1.2 joerg contents = xmalloc((size_t) (sb.st_size) + 1); 106 1.2 joerg fd = open(fname, O_RDONLY, 0); 107 1.2 joerg if (fd == FAIL) { 108 1.2 joerg errx(2, "unable to open '%s' for reading", fname); 109 1.2 joerg } 110 1.2 joerg if (read(fd, contents, (size_t) sb.st_size) != (ssize_t) sb.st_size) { 111 1.2 joerg errx(2, "short read on '%s' - did not get %lld bytes", 112 1.2 joerg fname, (long long) sb.st_size); 113 1.2 joerg } 114 1.2 joerg close(fd); 115 1.2 joerg contents[(size_t) sb.st_size] = '\0'; 116 1.2 joerg return contents; 117 1.2 joerg } 118 1.2 joerg 119 1.2 joerg /* 120 1.1 joerg * Get a string parameter as a file spec or as a "contents follow -" spec 121 1.1 joerg */ 122 1.1 joerg static void 123 1.1 joerg get_dash_string(char **s) 124 1.1 joerg { 125 1.1 joerg if (**s == '-') 126 1.2 joerg *s = xstrdup(*s + 1); 127 1.1 joerg else 128 1.1 joerg *s = fileGetContents(*s); 129 1.1 joerg } 130 1.1 joerg 131 1.1 joerg int 132 1.1 joerg pkg_perform(const char *pkg) 133 1.1 joerg { 134 1.1 joerg char *cp; 135 1.1 joerg FILE *pkg_in; 136 1.1 joerg package_t plist; 137 1.1 joerg const char *full_pkg, *suffix; 138 1.1 joerg char *allocated_pkg; 139 1.1 joerg int retval; 140 1.1 joerg 141 1.1 joerg /* Break the package name into base and desired suffix (if any) */ 142 1.1 joerg if ((cp = strrchr(pkg, '.')) != NULL) { 143 1.2 joerg allocated_pkg = xmalloc(cp - pkg + 1); 144 1.1 joerg memcpy(allocated_pkg, pkg, cp - pkg); 145 1.1 joerg allocated_pkg[cp - pkg] = '\0'; 146 1.1 joerg suffix = cp + 1; 147 1.1 joerg full_pkg = pkg; 148 1.1 joerg pkg = allocated_pkg; 149 1.1 joerg } else { 150 1.1 joerg allocated_pkg = NULL; 151 1.1 joerg full_pkg = pkg; 152 1.1 joerg suffix = "tgz"; 153 1.1 joerg } 154 1.1 joerg 155 1.1 joerg /* Preliminary setup */ 156 1.1 joerg sanity_check(); 157 1.1 joerg if (Verbose && !PlistOnly) 158 1.1 joerg printf("Creating package %s\n", pkg); 159 1.1 joerg get_dash_string(&Comment); 160 1.1 joerg get_dash_string(&Desc); 161 1.1 joerg if (IS_STDIN(Contents)) 162 1.1 joerg pkg_in = stdin; 163 1.1 joerg else { 164 1.1 joerg pkg_in = fopen(Contents, "r"); 165 1.1 joerg if (!pkg_in) 166 1.1 joerg errx(2, "unable to open contents file '%s' for input", Contents); 167 1.1 joerg } 168 1.2 joerg 169 1.1 joerg plist.head = plist.tail = NULL; 170 1.1 joerg 171 1.1 joerg /* Stick the dependencies, if any, at the top */ 172 1.1 joerg if (Pkgdeps) 173 1.1 joerg register_depends(&plist, Pkgdeps, 0); 174 1.1 joerg 175 1.1 joerg /* 176 1.1 joerg * Put the build dependencies after the dependencies. 177 1.1 joerg * This works due to the evaluation order in pkg_add. 178 1.1 joerg */ 179 1.1 joerg if (BuildPkgdeps) 180 1.1 joerg register_depends(&plist, BuildPkgdeps, 1); 181 1.1 joerg 182 1.1 joerg /* Put the conflicts directly after the dependencies, if any */ 183 1.1 joerg if (Pkgcfl) { 184 1.1 joerg if (Verbose && !PlistOnly) 185 1.1 joerg printf("Registering conflicts:"); 186 1.1 joerg while (Pkgcfl) { 187 1.1 joerg cp = strsep(&Pkgcfl, " \t\n"); 188 1.1 joerg if (*cp) { 189 1.1 joerg add_plist(&plist, PLIST_PKGCFL, cp); 190 1.1 joerg if (Verbose && !PlistOnly) 191 1.1 joerg printf(" %s", cp); 192 1.1 joerg } 193 1.1 joerg } 194 1.1 joerg if (Verbose && !PlistOnly) 195 1.1 joerg printf(".\n"); 196 1.1 joerg } 197 1.1 joerg 198 1.1 joerg /* Slurp in the packing list */ 199 1.1 joerg append_plist(&plist, pkg_in); 200 1.1 joerg 201 1.1 joerg if (pkg_in != stdin) 202 1.1 joerg fclose(pkg_in); 203 1.1 joerg 204 1.1 joerg /* Prefix should override the packing list */ 205 1.1 joerg if (Prefix) { 206 1.1 joerg delete_plist(&plist, FALSE, PLIST_CWD, NULL); 207 1.1 joerg add_plist_top(&plist, PLIST_CWD, Prefix); 208 1.1 joerg } 209 1.1 joerg /* 210 1.1 joerg * Run down the list and see if we've named it, if not stick in a name 211 1.1 joerg * at the top. 212 1.1 joerg */ 213 1.1 joerg if (find_plist(&plist, PLIST_NAME) == NULL) { 214 1.1 joerg add_plist_top(&plist, PLIST_NAME, basename_of(pkg)); 215 1.1 joerg } 216 1.1 joerg 217 1.1 joerg /* Make first "real contents" pass over it */ 218 1.1 joerg check_list(&plist, basename_of(pkg)); 219 1.1 joerg 220 1.1 joerg /* 221 1.1 joerg * We're just here for to dump out a revised plist for the FreeBSD ports 222 1.1 joerg * hack. It's not a real create in progress. 223 1.1 joerg */ 224 1.1 joerg if (PlistOnly) { 225 1.1 joerg write_plist(&plist, stdout, realprefix); 226 1.1 joerg retval = TRUE; 227 1.1 joerg } else { 228 1.1 joerg retval = pkg_build(pkg, full_pkg, suffix, &plist); 229 1.1 joerg } 230 1.1 joerg 231 1.1 joerg /* Cleanup */ 232 1.1 joerg free(Comment); 233 1.1 joerg free(Desc); 234 1.1 joerg free_plist(&plist); 235 1.1 joerg 236 1.1 joerg free(allocated_pkg); 237 1.1 joerg 238 1.1 joerg return retval; 239 1.1 joerg } 240