Home | History | Annotate | Line # | Download | only in create
perform.c revision 1.1.1.1.6.1
      1 /*	$NetBSD: perform.c,v 1.1.1.1.6.1 2009/05/30 16:40:32 snj 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.1.6.1 2009/05/30 16:40:32 snj 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 		cleanup(0);
    103 		errx(2, "can't stat '%s'", fname);
    104 	}
    105 
    106 	contents = xmalloc((size_t) (sb.st_size) + 1);
    107 	fd = open(fname, O_RDONLY, 0);
    108 	if (fd == FAIL) {
    109 		cleanup(0);
    110 		errx(2, "unable to open '%s' for reading", fname);
    111 	}
    112 	if (read(fd, contents, (size_t) sb.st_size) != (size_t) sb.st_size) {
    113 		cleanup(0);
    114 		errx(2, "short read on '%s' - did not get %lld bytes",
    115 		    fname, (long long) sb.st_size);
    116 	}
    117 	close(fd);
    118 	contents[(size_t) sb.st_size] = '\0';
    119 	return contents;
    120 }
    121 
    122 /*
    123  * Get a string parameter as a file spec or as a "contents follow -" spec
    124  */
    125 static void
    126 get_dash_string(char **s)
    127 {
    128 	if (**s == '-')
    129 		*s = xstrdup(*s + 1);
    130 	else
    131 		*s = fileGetContents(*s);
    132 }
    133 
    134 int
    135 pkg_perform(const char *pkg)
    136 {
    137 	char   *cp;
    138 	FILE   *pkg_in;
    139 	package_t plist;
    140 	const char *full_pkg, *suffix;
    141 	char *allocated_pkg;
    142 	int retval;
    143 
    144 	/* Break the package name into base and desired suffix (if any) */
    145 	if ((cp = strrchr(pkg, '.')) != NULL) {
    146 		allocated_pkg = xmalloc(cp - pkg + 1);
    147 		memcpy(allocated_pkg, pkg, cp - pkg);
    148 		allocated_pkg[cp - pkg] = '\0';
    149 		suffix = cp + 1;
    150 		full_pkg = pkg;
    151 		pkg = allocated_pkg;
    152 	} else {
    153 		allocated_pkg = NULL;
    154 		full_pkg = pkg;
    155 		suffix = "tgz";
    156 	}
    157 
    158 	/* Preliminary setup */
    159 	sanity_check();
    160 	if (Verbose && !PlistOnly)
    161 		printf("Creating package %s\n", pkg);
    162 	get_dash_string(&Comment);
    163 	get_dash_string(&Desc);
    164 	if (IS_STDIN(Contents))
    165 		pkg_in = stdin;
    166 	else {
    167 		pkg_in = fopen(Contents, "r");
    168 		if (!pkg_in)
    169 			errx(2, "unable to open contents file '%s' for input", Contents);
    170 	}
    171 
    172 	plist.head = plist.tail = NULL;
    173 
    174 	/* If a SrcDir override is set, add it now */
    175 	if (SrcDir) {
    176 		if (Verbose && !PlistOnly)
    177 			printf("Using SrcDir value of %s\n", (realprefix) ? realprefix : SrcDir);
    178 		add_plist(&plist, PLIST_SRC, SrcDir);
    179 	}
    180 
    181 	/* Stick the dependencies, if any, at the top */
    182 	if (Pkgdeps)
    183 		register_depends(&plist, Pkgdeps, 0);
    184 
    185 	/*
    186 	 * Put the build dependencies after the dependencies.
    187 	 * This works due to the evaluation order in pkg_add.
    188 	 */
    189 	if (BuildPkgdeps)
    190 		register_depends(&plist, BuildPkgdeps, 1);
    191 
    192 	/* Put the conflicts directly after the dependencies, if any */
    193 	if (Pkgcfl) {
    194 		if (Verbose && !PlistOnly)
    195 			printf("Registering conflicts:");
    196 		while (Pkgcfl) {
    197 			cp = strsep(&Pkgcfl, " \t\n");
    198 			if (*cp) {
    199 				add_plist(&plist, PLIST_PKGCFL, cp);
    200 				if (Verbose && !PlistOnly)
    201 					printf(" %s", cp);
    202 			}
    203 		}
    204 		if (Verbose && !PlistOnly)
    205 			printf(".\n");
    206 	}
    207 
    208 	/* Slurp in the packing list */
    209 	append_plist(&plist, pkg_in);
    210 
    211 	if (pkg_in != stdin)
    212 		fclose(pkg_in);
    213 
    214 	/* Prefix should override the packing list */
    215 	if (Prefix) {
    216 		delete_plist(&plist, FALSE, PLIST_CWD, NULL);
    217 		add_plist_top(&plist, PLIST_CWD, Prefix);
    218 	}
    219 	/*
    220          * Run down the list and see if we've named it, if not stick in a name
    221          * at the top.
    222          */
    223 	if (find_plist(&plist, PLIST_NAME) == NULL) {
    224 		add_plist_top(&plist, PLIST_NAME, basename_of(pkg));
    225 	}
    226 
    227 	/* Make first "real contents" pass over it */
    228 	check_list(&plist, basename_of(pkg));
    229 
    230 	/*
    231          * We're just here for to dump out a revised plist for the FreeBSD ports
    232          * hack.  It's not a real create in progress.
    233          */
    234 	if (PlistOnly) {
    235 		write_plist(&plist, stdout, realprefix);
    236 		retval = TRUE;
    237 	} else {
    238 #ifdef BOOTSTRAP
    239 		warnx("Package building is not supported in bootstrap mode");
    240 		retval = FALSE;
    241 #else
    242 		retval = pkg_build(pkg, full_pkg, suffix, &plist);
    243 #endif
    244 	}
    245 
    246 	/* Cleanup */
    247 	free(Comment);
    248 	free(Desc);
    249 	free_plist(&plist);
    250 
    251 	free(allocated_pkg);
    252 
    253 	return retval;
    254 }
    255