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