Mon Aug 11 15:58:15 2008 UTC ()
pkg_create actually does want to mess with the plist before reading it,
so introduce append_plist to give the old behavior and unbreak
pkg_create.


(joerg)
diff -r1.19.2.3 -r1.19.2.4 pkgsrc/pkgtools/pkg_install/files/create/perform.c
diff -r1.42.2.13 -r1.42.2.14 pkgsrc/pkgtools/pkg_install/files/lib/lib.h
diff -r1.17.4.9 -r1.17.4.10 pkgsrc/pkgtools/pkg_install/files/lib/plist.c

cvs diff -r1.19.2.3 -r1.19.2.4 pkgsrc/pkgtools/pkg_install/files/create/perform.c (switch to unified diff)

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

cvs diff -r1.42.2.13 -r1.42.2.14 pkgsrc/pkgtools/pkg_install/files/lib/lib.h (switch to unified diff)

--- pkgsrc/pkgtools/pkg_install/files/lib/lib.h 2008/08/05 22:56:24 1.42.2.13
+++ pkgsrc/pkgtools/pkg_install/files/lib/lib.h 2008/08/11 15:58:15 1.42.2.14
@@ -1,416 +1,417 @@ @@ -1,416 +1,417 @@
1/* $NetBSD: lib.h,v 1.42.2.13 2008/08/05 22:56:24 joerg Exp $ */ 1/* $NetBSD: lib.h,v 1.42.2.14 2008/08/11 15:58:15 joerg Exp $ */
2 2
3/* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */ 3/* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */
4 4
5/* 5/*
6 * FreeBSD install - a package for the installation and maintainance 6 * FreeBSD install - a package for the installation and maintainance
7 * of non-core utilities. 7 * of non-core utilities.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * Jordan K. Hubbard 18 * Jordan K. Hubbard
19 * 18 July 1993 19 * 18 July 1993
20 * 20 *
21 * Include and define various things wanted by the library routines. 21 * Include and define various things wanted by the library routines.
22 * 22 *
23 */ 23 */
24 24
25#ifndef _INST_LIB_LIB_H_ 25#ifndef _INST_LIB_LIB_H_
26#define _INST_LIB_LIB_H_ 26#define _INST_LIB_LIB_H_
27 27
28#if HAVE_CONFIG_H 28#if HAVE_CONFIG_H
29#include "config.h" 29#include "config.h"
30#endif 30#endif
31#include <nbcompat.h> 31#include <nbcompat.h>
32#if HAVE_SYS_PARAM_H 32#if HAVE_SYS_PARAM_H
33#include <sys/param.h> 33#include <sys/param.h>
34#endif 34#endif
35#if HAVE_SYS_STAT_H 35#if HAVE_SYS_STAT_H
36#include <sys/stat.h> 36#include <sys/stat.h>
37#endif 37#endif
38#if HAVE_SYS_FILE_H 38#if HAVE_SYS_FILE_H
39#include <sys/file.h> 39#include <sys/file.h>
40#endif 40#endif
41#if HAVE_SYS_QUEUE_H 41#if HAVE_SYS_QUEUE_H
42#include <sys/queue.h> 42#include <sys/queue.h>
43#endif 43#endif
44 44
45#if HAVE_CTYPE_H 45#if HAVE_CTYPE_H
46#include <ctype.h> 46#include <ctype.h>
47#endif 47#endif
48#if HAVE_DIRENT_H 48#if HAVE_DIRENT_H
49#include <dirent.h> 49#include <dirent.h>
50#endif 50#endif
51#if HAVE_STDIO_H 51#if HAVE_STDIO_H
52#include <stdio.h> 52#include <stdio.h>
53#endif 53#endif
54#if HAVE_STDLIB_H 54#if HAVE_STDLIB_H
55#include <stdlib.h> 55#include <stdlib.h>
56#endif 56#endif
57#if HAVE_STDARG_H 57#if HAVE_STDARG_H
58#include <stdarg.h> 58#include <stdarg.h>
59#endif 59#endif
60#if HAVE_STRING_H 60#if HAVE_STRING_H
61#include <string.h> 61#include <string.h>
62#endif 62#endif
63#if HAVE_UNISTD_H 63#if HAVE_UNISTD_H
64#include <unistd.h> 64#include <unistd.h>
65#endif 65#endif
66 66
67#include "path.h" 67#include "path.h"
68 68
69/* Macros */ 69/* Macros */
70#define SUCCESS (0) 70#define SUCCESS (0)
71#define FAIL (-1) 71#define FAIL (-1)
72 72
73#ifndef TRUE 73#ifndef TRUE
74#define TRUE (1) 74#define TRUE (1)
75#endif 75#endif
76 76
77#ifndef FALSE 77#ifndef FALSE
78#define FALSE (0) 78#define FALSE (0)
79#endif 79#endif
80 80
81#ifndef OPSYS_NAME 81#ifndef OPSYS_NAME
82#define OPSYS_NAME "NetBSD" 82#define OPSYS_NAME "NetBSD"
83#endif 83#endif
84 84
85#ifndef DEF_UMASK 85#ifndef DEF_UMASK
86#define DEF_UMASK 022 86#define DEF_UMASK 022
87#endif 87#endif
88 88
89#ifndef PATH_MAX 89#ifndef PATH_MAX
90# ifdef MAXPATHLEN 90# ifdef MAXPATHLEN
91# define PATH_MAX MAXPATHLEN 91# define PATH_MAX MAXPATHLEN
92# else 92# else
93# define PATH_MAX 1024 93# define PATH_MAX 1024
94# endif 94# endif
95#endif 95#endif
96 96
97enum { 97enum {
98 MaxPathSize = PATH_MAX 98 MaxPathSize = PATH_MAX
99}; 99};
100 100
101/* The names of our "special" files */ 101/* The names of our "special" files */
102#define CONTENTS_FNAME "+CONTENTS" 102#define CONTENTS_FNAME "+CONTENTS"
103#define COMMENT_FNAME "+COMMENT" 103#define COMMENT_FNAME "+COMMENT"
104#define DESC_FNAME "+DESC" 104#define DESC_FNAME "+DESC"
105#define INSTALL_FNAME "+INSTALL" 105#define INSTALL_FNAME "+INSTALL"
106#define DEINSTALL_FNAME "+DEINSTALL" 106#define DEINSTALL_FNAME "+DEINSTALL"
107#define REQUIRED_BY_FNAME "+REQUIRED_BY" 107#define REQUIRED_BY_FNAME "+REQUIRED_BY"
108#define REQUIRED_BY_FNAME_TMP "+REQUIRED_BY.tmp" 108#define REQUIRED_BY_FNAME_TMP "+REQUIRED_BY.tmp"
109#define DISPLAY_FNAME "+DISPLAY" 109#define DISPLAY_FNAME "+DISPLAY"
110#define MTREE_FNAME "+MTREE_DIRS" 110#define MTREE_FNAME "+MTREE_DIRS"
111#define BUILD_VERSION_FNAME "+BUILD_VERSION" 111#define BUILD_VERSION_FNAME "+BUILD_VERSION"
112#define BUILD_INFO_FNAME "+BUILD_INFO" 112#define BUILD_INFO_FNAME "+BUILD_INFO"
113#define INSTALLED_INFO_FNAME "+INSTALLED_INFO" 113#define INSTALLED_INFO_FNAME "+INSTALLED_INFO"
114#define SIZE_PKG_FNAME "+SIZE_PKG" 114#define SIZE_PKG_FNAME "+SIZE_PKG"
115#define SIZE_ALL_FNAME "+SIZE_ALL" 115#define SIZE_ALL_FNAME "+SIZE_ALL"
116#define PRESERVE_FNAME "+PRESERVE" 116#define PRESERVE_FNAME "+PRESERVE"
117#define VIEWS_FNAME "+VIEWS" 117#define VIEWS_FNAME "+VIEWS"
118#define VIEWS_FNAME_TMP "+VIEWS.tmp" 118#define VIEWS_FNAME_TMP "+VIEWS.tmp"
119#define DEPOT_FNAME "+DEPOT" 119#define DEPOT_FNAME "+DEPOT"
120 120
121/* The names of special variables */ 121/* The names of special variables */
122#define AUTOMATIC_VARNAME "automatic" 122#define AUTOMATIC_VARNAME "automatic"
123 123
124/* Prefix for extended PLIST cmd */ 124/* Prefix for extended PLIST cmd */
125#define CMD_CHAR '@'  125#define CMD_CHAR '@'
126 126
127/* The name of the "prefix" environment variable given to scripts */ 127/* The name of the "prefix" environment variable given to scripts */
128#define PKG_PREFIX_VNAME "PKG_PREFIX" 128#define PKG_PREFIX_VNAME "PKG_PREFIX"
129 129
130/* The name of the "destdir" environment variable given to scripts */ 130/* The name of the "destdir" environment variable given to scripts */
131#define PKG_DESTDIR_VNAME "PKG_DESTDIR" 131#define PKG_DESTDIR_VNAME "PKG_DESTDIR"
132 132
133/* 133/*
134 * The name of the "metadatadir" environment variable given to scripts. 134 * The name of the "metadatadir" environment variable given to scripts.
135 * This variable holds the location of the +-files for this package. 135 * This variable holds the location of the +-files for this package.
136 */ 136 */
137#define PKG_METADATA_DIR_VNAME "PKG_METADATA_DIR" 137#define PKG_METADATA_DIR_VNAME "PKG_METADATA_DIR"
138 138
139/* 139/*
140 * The name of the environment variable holding the location to the 140 * The name of the environment variable holding the location to the
141 * reference-counts database directory. 141 * reference-counts database directory.
142 */ 142 */
143#define PKG_REFCOUNT_DBDIR_VNAME "PKG_REFCOUNT_DBDIR" 143#define PKG_REFCOUNT_DBDIR_VNAME "PKG_REFCOUNT_DBDIR"
144 144
145#define PKG_PATTERN_MAX MaxPathSize /* max length of pattern, including nul */ 145#define PKG_PATTERN_MAX MaxPathSize /* max length of pattern, including nul */
146#define PKG_SUFFIX_MAX 10 /* max length of suffix, including nul */ 146#define PKG_SUFFIX_MAX 10 /* max length of suffix, including nul */
147 147
148enum { 148enum {
149 ReadWrite, 149 ReadWrite,
150 ReadOnly 150 ReadOnly
151}; 151};
152 152
153 153
154/* Enumerated constants for plist entry types */ 154/* Enumerated constants for plist entry types */
155typedef enum pl_ent_t { 155typedef enum pl_ent_t {
156 PLIST_SHOW_ALL = -1, 156 PLIST_SHOW_ALL = -1,
157 PLIST_FILE, /* 0 */ 157 PLIST_FILE, /* 0 */
158 PLIST_CWD, /* 1 */ 158 PLIST_CWD, /* 1 */
159 PLIST_CMD, /* 2 */ 159 PLIST_CMD, /* 2 */
160 PLIST_CHMOD, /* 3 */ 160 PLIST_CHMOD, /* 3 */
161 PLIST_CHOWN, /* 4 */ 161 PLIST_CHOWN, /* 4 */
162 PLIST_CHGRP, /* 5 */ 162 PLIST_CHGRP, /* 5 */
163 PLIST_COMMENT, /* 6 */ 163 PLIST_COMMENT, /* 6 */
164 PLIST_IGNORE, /* 7 */ 164 PLIST_IGNORE, /* 7 */
165 PLIST_NAME, /* 8 */ 165 PLIST_NAME, /* 8 */
166 PLIST_UNEXEC, /* 9 */ 166 PLIST_UNEXEC, /* 9 */
167 PLIST_SRC, /* 10 */ 167 PLIST_SRC, /* 10 */
168 PLIST_DISPLAY, /* 11 */ 168 PLIST_DISPLAY, /* 11 */
169 PLIST_PKGDEP, /* 12 */ 169 PLIST_PKGDEP, /* 12 */
170 PLIST_MTREE, /* 13 */ 170 PLIST_MTREE, /* 13 */
171 PLIST_DIR_RM, /* 14 */ 171 PLIST_DIR_RM, /* 14 */
172 PLIST_IGNORE_INST, /* 15 */ 172 PLIST_IGNORE_INST, /* 15 */
173 PLIST_OPTION, /* 16 */ 173 PLIST_OPTION, /* 16 */
174 PLIST_PKGCFL, /* 17 */ 174 PLIST_PKGCFL, /* 17 */
175 PLIST_BLDDEP /* 18 */ 175 PLIST_BLDDEP /* 18 */
176} pl_ent_t; 176} pl_ent_t;
177 177
178/* Enumerated constants for build info */ 178/* Enumerated constants for build info */
179typedef enum bi_ent_t { 179typedef enum bi_ent_t {
180 BI_OPSYS, /* 0 */ 180 BI_OPSYS, /* 0 */
181 BI_OS_VERSION, /* 1 */ 181 BI_OS_VERSION, /* 1 */
182 BI_MACHINE_ARCH, /* 2 */ 182 BI_MACHINE_ARCH, /* 2 */
183 BI_IGNORE_RECOMMENDED, /* 3 */ 183 BI_IGNORE_RECOMMENDED, /* 3 */
184 BI_USE_ABI_DEPENDS, /* 4 */ 184 BI_USE_ABI_DEPENDS, /* 4 */
185 BI_ENUM_COUNT /* 5 */ 185 BI_ENUM_COUNT /* 5 */
186} bi_ent_t; 186} bi_ent_t;
187 187
188/* Types */ 188/* Types */
189typedef unsigned int Boolean; 189typedef unsigned int Boolean;
190 190
191/* This structure describes a packing list entry */ 191/* This structure describes a packing list entry */
192typedef struct plist_t { 192typedef struct plist_t {
193 struct plist_t *prev; /* previous entry */ 193 struct plist_t *prev; /* previous entry */
194 struct plist_t *next; /* next entry */ 194 struct plist_t *next; /* next entry */
195 char *name; /* name of entry */ 195 char *name; /* name of entry */
196 Boolean marked; /* whether entry has been marked */ 196 Boolean marked; /* whether entry has been marked */
197 pl_ent_t type; /* type of entry */ 197 pl_ent_t type; /* type of entry */
198} plist_t; 198} plist_t;
199 199
200/* This structure describes a package's complete packing list */ 200/* This structure describes a package's complete packing list */
201typedef struct package_t { 201typedef struct package_t {
202 plist_t *head; /* head of list */ 202 plist_t *head; /* head of list */
203 plist_t *tail; /* tail of list */ 203 plist_t *tail; /* tail of list */
204} package_t; 204} package_t;
205 205
206#define SYMLINK_HEADER "Symlink:" 206#define SYMLINK_HEADER "Symlink:"
207#define CHECKSUM_HEADER "MD5:" 207#define CHECKSUM_HEADER "MD5:"
208 208
209enum { 209enum {
210 ChecksumHeaderLen = 4, /* strlen(CHECKSUM_HEADER) */ 210 ChecksumHeaderLen = 4, /* strlen(CHECKSUM_HEADER) */
211 SymlinkHeaderLen = 8, /* strlen(SYMLINK_HEADER) */ 211 SymlinkHeaderLen = 8, /* strlen(SYMLINK_HEADER) */
212 ChecksumLen = 16, 212 ChecksumLen = 16,
213 LegibleChecksumLen = 33 213 LegibleChecksumLen = 33
214}; 214};
215 215
216/* List of files */ 216/* List of files */
217typedef struct _lfile_t { 217typedef struct _lfile_t {
218 TAILQ_ENTRY(_lfile_t) lf_link; 218 TAILQ_ENTRY(_lfile_t) lf_link;
219 char *lf_name; 219 char *lf_name;
220} lfile_t; 220} lfile_t;
221TAILQ_HEAD(_lfile_head_t, _lfile_t); 221TAILQ_HEAD(_lfile_head_t, _lfile_t);
222typedef struct _lfile_head_t lfile_head_t; 222typedef struct _lfile_head_t lfile_head_t;
223#define LFILE_ADD(lfhead,lfp,str) do { \ 223#define LFILE_ADD(lfhead,lfp,str) do { \
224 lfp = xmalloc(sizeof(lfile_t)); \ 224 lfp = xmalloc(sizeof(lfile_t)); \
225 lfp->lf_name = str; \ 225 lfp->lf_name = str; \
226 TAILQ_INSERT_TAIL(lfhead,lfp,lf_link); \ 226 TAILQ_INSERT_TAIL(lfhead,lfp,lf_link); \
227 } while(0) 227 } while(0)
228 228
229/* List of packages */ 229/* List of packages */
230typedef struct _lpkg_t { 230typedef struct _lpkg_t {
231 TAILQ_ENTRY(_lpkg_t) lp_link; 231 TAILQ_ENTRY(_lpkg_t) lp_link;
232 char *lp_name; 232 char *lp_name;
233} lpkg_t; 233} lpkg_t;
234TAILQ_HEAD(_lpkg_head_t, _lpkg_t); 234TAILQ_HEAD(_lpkg_head_t, _lpkg_t);
235typedef struct _lpkg_head_t lpkg_head_t; 235typedef struct _lpkg_head_t lpkg_head_t;
236 236
237struct pkg_vulnerabilities { 237struct pkg_vulnerabilities {
238 size_t entries; 238 size_t entries;
239 char **vulnerability; 239 char **vulnerability;
240 char **classification; 240 char **classification;
241 char **advisory; 241 char **advisory;
242}; 242};
243 243
244/* If URLlength()>0, then there is a ftp:// or http:// in the string, 244/* If URLlength()>0, then there is a ftp:// or http:// in the string,
245 * and this must be an URL. Hide this behind a more obvious name. */ 245 * and this must be an URL. Hide this behind a more obvious name. */
246#define IS_URL(str) (URLlength(str) > 0) 246#define IS_URL(str) (URLlength(str) > 0)
247 247
248#define IS_STDIN(str) ((str) != NULL && !strcmp((str), "-")) 248#define IS_STDIN(str) ((str) != NULL && !strcmp((str), "-"))
249#define IS_FULLPATH(str) ((str) != NULL && (str)[0] == '/') 249#define IS_FULLPATH(str) ((str) != NULL && (str)[0] == '/')
250 250
251/* Conflict handling (conflicts.c) */ 251/* Conflict handling (conflicts.c) */
252int some_installed_package_conflicts_with(const char *, const char *, char **, char **); 252int some_installed_package_conflicts_with(const char *, const char *, char **, char **);
253 253
254 254
255/* Prototypes */ 255/* Prototypes */
256/* Misc */ 256/* Misc */
257void cleanup(int); 257void cleanup(int);
258void show_version(void); 258void show_version(void);
259int fexec(const char *, ...); 259int fexec(const char *, ...);
260int fexec_skipempty(const char *, ...); 260int fexec_skipempty(const char *, ...);
261int fcexec(const char *, const char *, ...); 261int fcexec(const char *, const char *, ...);
262int pfcexec(const char *, const char *, const char **); 262int pfcexec(const char *, const char *, const char **);
263 263
264/* variables file handling */ 264/* variables file handling */
265 265
266char *var_get(const char *, const char *); 266char *var_get(const char *, const char *);
267char *var_get_memory(const char *, const char *); 267char *var_get_memory(const char *, const char *);
268int var_set(const char *, const char *, const char *); 268int var_set(const char *, const char *, const char *);
269int var_copy_list(const char *, const char **); 269int var_copy_list(const char *, const char **);
270 270
271/* automatically installed as dependency */ 271/* automatically installed as dependency */
272 272
273Boolean is_automatic_installed(const char *); 273Boolean is_automatic_installed(const char *);
274int mark_as_automatic_installed(const char *, int); 274int mark_as_automatic_installed(const char *, int);
275 275
276/* String */ 276/* String */
277const char *basename_of(const char *); 277const char *basename_of(const char *);
278const char *dirname_of(const char *); 278const char *dirname_of(const char *);
279const char *suffix_of(const char *); 279const char *suffix_of(const char *);
280int pkg_match(const char *, const char *); 280int pkg_match(const char *, const char *);
281int pkg_order(const char *, const char *, const char *); 281int pkg_order(const char *, const char *, const char *);
282int ispkgpattern(const char *); 282int ispkgpattern(const char *);
283int quick_pkg_match(const char *, const char *); 283int quick_pkg_match(const char *, const char *);
284 284
285/* Iterator functions */ 285/* Iterator functions */
286int iterate_pkg_generic_src(int (*)(const char *, void *), void *, 286int iterate_pkg_generic_src(int (*)(const char *, void *), void *,
287 const char *(*)(void *),void *); 287 const char *(*)(void *),void *);
288int iterate_local_pkg_dir(const char *, int, int, int (*)(const char *, void *), 288int iterate_local_pkg_dir(const char *, int, int, int (*)(const char *, void *),
289 void *); 289 void *);
290int iterate_pkg_db(int (*)(const char *, void *), void *); 290int iterate_pkg_db(int (*)(const char *, void *), void *);
291 291
292int add_installed_pkgs_by_basename(const char *, lpkg_head_t *); 292int add_installed_pkgs_by_basename(const char *, lpkg_head_t *);
293int add_installed_pkgs_by_pattern(const char *, lpkg_head_t *); 293int add_installed_pkgs_by_pattern(const char *, lpkg_head_t *);
294char *find_best_matching_installed_pkg(const char *); 294char *find_best_matching_installed_pkg(const char *);
295char *find_best_matching_file(const char *, const char *, int, int); 295char *find_best_matching_file(const char *, const char *, int, int);
296int match_installed_pkgs(const char *, int (*)(const char *, void *), void *); 296int match_installed_pkgs(const char *, int (*)(const char *, void *), void *);
297int match_local_files(const char *, int, int, const char *, int (*cb)(const char *, void *), void *); 297int match_local_files(const char *, int, int, const char *, int (*cb)(const char *, void *), void *);
298 298
299/* File */ 299/* File */
300Boolean fexists(const char *); 300Boolean fexists(const char *);
301Boolean isdir(const char *); 301Boolean isdir(const char *);
302Boolean islinktodir(const char *); 302Boolean islinktodir(const char *);
303Boolean isemptydir(const char *); 303Boolean isemptydir(const char *);
304Boolean isemptyfile(const char *); 304Boolean isemptyfile(const char *);
305Boolean isfile(const char *); 305Boolean isfile(const char *);
306Boolean isbrokenlink(const char *); 306Boolean isbrokenlink(const char *);
307Boolean isempty(const char *); 307Boolean isempty(const char *);
308int URLlength(const char *); 308int URLlength(const char *);
309Boolean make_preserve_name(char *, size_t, char *, char *); 309Boolean make_preserve_name(char *, size_t, char *, char *);
310void remove_files(const char *, const char *); 310void remove_files(const char *, const char *);
311int delete_hierarchy(char *, Boolean, Boolean); 311int delete_hierarchy(char *, Boolean, Boolean);
312int format_cmd(char *, size_t, const char *, const char *, const char *); 312int format_cmd(char *, size_t, const char *, const char *, const char *);
313 313
314int recursive_remove(const char *, int); 314int recursive_remove(const char *, int);
315 315
316/* pkg_io.c: Local and remote archive handling */ 316/* pkg_io.c: Local and remote archive handling */
317struct archive; 317struct archive;
318struct archive_entry; 318struct archive_entry;
319 319
320struct archive *open_archive(const char *, void **); 320struct archive *open_archive(const char *, void **);
321void close_archive(void *); 321void close_archive(void *);
322struct archive *find_archive(const char *, void **); 322struct archive *find_archive(const char *, void **);
323 323
324/* Packing list */ 324/* Packing list */
325plist_t *new_plist_entry(void); 325plist_t *new_plist_entry(void);
326plist_t *last_plist(package_t *); 326plist_t *last_plist(package_t *);
327plist_t *find_plist(package_t *, pl_ent_t); 327plist_t *find_plist(package_t *, pl_ent_t);
328char *find_plist_option(package_t *, char *); 328char *find_plist_option(package_t *, char *);
329void plist_delete(package_t *, Boolean, pl_ent_t, char *); 329void plist_delete(package_t *, Boolean, pl_ent_t, char *);
330void free_plist(package_t *); 330void free_plist(package_t *);
331void mark_plist(package_t *); 331void mark_plist(package_t *);
332void csum_plist_entry(char *, plist_t *); 332void csum_plist_entry(char *, plist_t *);
333void add_plist(package_t *, pl_ent_t, const char *); 333void add_plist(package_t *, pl_ent_t, const char *);
334void add_plist_top(package_t *, pl_ent_t, const char *); 334void add_plist_top(package_t *, pl_ent_t, const char *);
335void delete_plist(package_t *, Boolean, pl_ent_t, char *); 335void delete_plist(package_t *, Boolean, pl_ent_t, char *);
336void write_plist(package_t *, FILE *, char *); 336void write_plist(package_t *, FILE *, char *);
337void stringify_plist(package_t *, char **, size_t *, const char *); 337void stringify_plist(package_t *, char **, size_t *, const char *);
338void parse_plist(package_t *, const char *); 338void parse_plist(package_t *, const char *);
339void read_plist(package_t *, FILE *); 339void read_plist(package_t *, FILE *);
 340void append_plist(package_t *, FILE *);
340int delete_package(Boolean, Boolean, package_t *, Boolean, const char *); 341int delete_package(Boolean, Boolean, package_t *, Boolean, const char *);
341 342
342/* Package Database */ 343/* Package Database */
343int pkgdb_open(int); 344int pkgdb_open(int);
344void pkgdb_close(void); 345void pkgdb_close(void);
345int pkgdb_store(const char *, const char *); 346int pkgdb_store(const char *, const char *);
346char *pkgdb_retrieve(const char *); 347char *pkgdb_retrieve(const char *);
347int pkgdb_dump(void); 348int pkgdb_dump(void);
348int pkgdb_remove(const char *); 349int pkgdb_remove(const char *);
349int pkgdb_remove_pkg(const char *); 350int pkgdb_remove_pkg(const char *);
350char *pkgdb_refcount_dir(void); 351char *pkgdb_refcount_dir(void);
351char *_pkgdb_getPKGDB_FILE(char *, unsigned); 352char *_pkgdb_getPKGDB_FILE(char *, unsigned);
352const char *_pkgdb_getPKGDB_DIR(void); 353const char *_pkgdb_getPKGDB_DIR(void);
353void _pkgdb_setPKGDB_DIR(const char *); 354void _pkgdb_setPKGDB_DIR(const char *);
354 355
355char *pkgdb_pkg_file(const char *, const char *); 356char *pkgdb_pkg_file(const char *, const char *);
356 357
357/* List of packages functions */ 358/* List of packages functions */
358lpkg_t *alloc_lpkg(const char *); 359lpkg_t *alloc_lpkg(const char *);
359lpkg_t *find_on_queue(lpkg_head_t *, const char *); 360lpkg_t *find_on_queue(lpkg_head_t *, const char *);
360void free_lpkg(lpkg_t *); 361void free_lpkg(lpkg_t *);
361 362
362/* Extract input if compressed to NUL terminated buffer (not counted) */ 363/* Extract input if compressed to NUL terminated buffer (not counted) */
363int decompress_buffer(const char *, size_t, char **, size_t *); 364int decompress_buffer(const char *, size_t, char **, size_t *);
364 365
365/* Parse NUL terminated inputed, argument is strlen of the input */ 366/* Parse NUL terminated inputed, argument is strlen of the input */
366struct pkg_vulnerabilities *parse_pkg_vulnerabilities(const char *, size_t, int); 367struct pkg_vulnerabilities *parse_pkg_vulnerabilities(const char *, size_t, int);
367/* Read pkg_vulnerabilities from file */ 368/* Read pkg_vulnerabilities from file */
368struct pkg_vulnerabilities *read_pkg_vulnerabilities(const char *, int, int); 369struct pkg_vulnerabilities *read_pkg_vulnerabilities(const char *, int, int);
369void free_pkg_vulnerabilities(struct pkg_vulnerabilities *); 370void free_pkg_vulnerabilities(struct pkg_vulnerabilities *);
370 371
371/* Parse configuration file */ 372/* Parse configuration file */
372void pkg_install_config(void); 373void pkg_install_config(void);
373/* Print configuration variable */ 374/* Print configuration variable */
374void pkg_install_show_variable(const char *); 375void pkg_install_show_variable(const char *);
375 376
376#ifdef HAVE_SSL 377#ifdef HAVE_SSL
377/* Package signature creation and validation */ 378/* Package signature creation and validation */
378int pkg_verify_signature(struct archive **, struct archive_entry **, char **, 379int pkg_verify_signature(struct archive **, struct archive_entry **, char **,
379 void **); 380 void **);
380int pkg_full_signature_check(struct archive *); 381int pkg_full_signature_check(struct archive *);
381void pkg_free_signature(void *); 382void pkg_free_signature(void *);
382void pkg_sign(const char *, const char *, const char *, const char *); 383void pkg_sign(const char *, const char *, const char *, const char *);
383#endif 384#endif
384 385
385#ifdef HAVE_SSL 386#ifdef HAVE_SSL
386/* PKCS7 signing/verification */ 387/* PKCS7 signing/verification */
387int easy_pkcs7_verify(const char *, size_t, const char *, size_t, 388int easy_pkcs7_verify(const char *, size_t, const char *, size_t,
388 const char *, int); 389 const char *, int);
389int easy_pkcs7_sign(const char *, size_t, char **, size_t *, const char *, 390int easy_pkcs7_sign(const char *, size_t, char **, size_t *, const char *,
390 const char *); 391 const char *);
391#endif 392#endif
392 393
393char *xstrdup(const char *); 394char *xstrdup(const char *);
394void *xrealloc(void *, size_t); 395void *xrealloc(void *, size_t);
395void *xcalloc(size_t, size_t); 396void *xcalloc(size_t, size_t);
396void *xmalloc(size_t); 397void *xmalloc(size_t);
397char *xasprintf(const char *, ...); 398char *xasprintf(const char *, ...);
398 399
399/* Externs */ 400/* Externs */
400extern Boolean Verbose; 401extern Boolean Verbose;
401extern Boolean Fake; 402extern Boolean Fake;
402extern Boolean Force; 403extern Boolean Force;
403extern const char *cert_chain_file; 404extern const char *cert_chain_file;
404extern const char *certs_packages; 405extern const char *certs_packages;
405extern const char *certs_pkg_vulnerabilities; 406extern const char *certs_pkg_vulnerabilities;
406extern const char *config_file; 407extern const char *config_file;
407extern const char *verified_installation; 408extern const char *verified_installation;
408extern const char *gpg_cmd; 409extern const char *gpg_cmd;
409 410
410extern const char *pkg_vulnerabilities_dir; 411extern const char *pkg_vulnerabilities_dir;
411extern const char *pkg_vulnerabilities_file; 412extern const char *pkg_vulnerabilities_file;
412extern const char *pkg_vulnerabilities_url; 413extern const char *pkg_vulnerabilities_url;
413extern const char *ignore_advisories; 414extern const char *ignore_advisories;
414extern const char tnf_vulnerability_base[]; 415extern const char tnf_vulnerability_base[];
415 416
416#endif /* _INST_LIB_LIB_H_ */ 417#endif /* _INST_LIB_LIB_H_ */

cvs diff -r1.17.4.9 -r1.17.4.10 pkgsrc/pkgtools/pkg_install/files/lib/plist.c (switch to unified diff)

--- pkgsrc/pkgtools/pkg_install/files/lib/plist.c 2008/08/10 22:09:38 1.17.4.9
+++ pkgsrc/pkgtools/pkg_install/files/lib/plist.c 2008/08/11 15:58:15 1.17.4.10
@@ -1,729 +1,735 @@ @@ -1,729 +1,735 @@
1/* $NetBSD: plist.c,v 1.17.4.9 2008/08/10 22:09:38 joerg Exp $ */ 1/* $NetBSD: plist.c,v 1.17.4.10 2008/08/11 15:58:15 joerg Exp $ */
2 2
3#if HAVE_CONFIG_H 3#if HAVE_CONFIG_H
4#include "config.h" 4#include "config.h"
5#endif 5#endif
6#include <nbcompat.h> 6#include <nbcompat.h>
7#if HAVE_SYS_CDEFS_H 7#if HAVE_SYS_CDEFS_H
8#include <sys/cdefs.h> 8#include <sys/cdefs.h>
9#endif 9#endif
10#ifndef lint 10#ifndef lint
11#if 0 11#if 0
12static const char *rcsid = "from FreeBSD Id: plist.c,v 1.24 1997/10/08 07:48:15 charnier Exp"; 12static const char *rcsid = "from FreeBSD Id: plist.c,v 1.24 1997/10/08 07:48:15 charnier Exp";
13#else 13#else
14__RCSID("$NetBSD: plist.c,v 1.17.4.9 2008/08/10 22:09:38 joerg Exp $"); 14__RCSID("$NetBSD: plist.c,v 1.17.4.10 2008/08/11 15:58:15 joerg Exp $");
15#endif 15#endif
16#endif 16#endif
17 17
18/* 18/*
19 * FreeBSD install - a package for the installation and maintainance 19 * FreeBSD install - a package for the installation and maintainance
20 * of non-core utilities. 20 * of non-core utilities.
21 * 21 *
22 * Redistribution and use in source and binary forms, with or without 22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions 23 * modification, are permitted provided that the following conditions
24 * are met: 24 * are met:
25 * 1. Redistributions of source code must retain the above copyright 25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer. 26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright 27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the 28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution. 29 * documentation and/or other materials provided with the distribution.
30 * 30 *
31 * Jordan K. Hubbard 31 * Jordan K. Hubbard
32 * 18 July 1993 32 * 18 July 1993
33 * 33 *
34 * General packing list routines. 34 * General packing list routines.
35 * 35 *
36 */ 36 */
37 37
38/*- 38/*-
39 * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>. 39 * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
40 * All rights reserved. 40 * All rights reserved.
41 * 41 *
42 * Redistribution and use in source and binary forms, with or without 42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions 43 * modification, are permitted provided that the following conditions
44 * are met: 44 * are met:
45 * 45 *
46 * 1. Redistributions of source code must retain the above copyright 46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer. 47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright 48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in 49 * notice, this list of conditions and the following disclaimer in
50 * the documentation and/or other materials provided with the 50 * the documentation and/or other materials provided with the
51 * distribution. 51 * distribution.
52 * 52 *
53 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 53 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 54 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 55 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
56 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 56 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
57 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 57 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
58 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 58 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
59 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 59 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 60 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
61 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 61 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
62 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 62 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
63 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE. 64 * SUCH DAMAGE.
65 */ 65 */
66 66
67#include "lib.h" 67#include "lib.h"
68#if HAVE_ERRNO_H 68#if HAVE_ERRNO_H
69#include <errno.h> 69#include <errno.h>
70#endif 70#endif
71#if HAVE_ERR_H 71#if HAVE_ERR_H
72#include <err.h> 72#include <err.h>
73#endif 73#endif
74#ifndef NETBSD 74#ifndef NETBSD
75#include <nbcompat/md5.h> 75#include <nbcompat/md5.h>
76#else 76#else
77#include <md5.h> 77#include <md5.h>
78#endif 78#endif
79 79
80/* This struct defines a plist command type */ 80/* This struct defines a plist command type */
81typedef struct cmd_t { 81typedef struct cmd_t {
82 const char *c_s; /* string to recognise */ 82 const char *c_s; /* string to recognise */
83 pl_ent_t c_type; /* type of command */ 83 pl_ent_t c_type; /* type of command */
84 int c_argc; /* # of arguments */ 84 int c_argc; /* # of arguments */
85 int c_subst; /* can substitute real prefix */ 85 int c_subst; /* can substitute real prefix */
86} cmd_t; 86} cmd_t;
87 87
88/* Commands to recognise */ 88/* Commands to recognise */
89static const cmd_t cmdv[] = { 89static const cmd_t cmdv[] = {
90 {"cwd", PLIST_CWD, 1, 1}, 90 {"cwd", PLIST_CWD, 1, 1},
91 {"src", PLIST_SRC, 1, 1}, 91 {"src", PLIST_SRC, 1, 1},
92 {"cd", PLIST_CWD, 1, 1}, 92 {"cd", PLIST_CWD, 1, 1},
93 {"exec", PLIST_CMD, 1, 0}, 93 {"exec", PLIST_CMD, 1, 0},
94 {"unexec", PLIST_UNEXEC, 1, 0}, 94 {"unexec", PLIST_UNEXEC, 1, 0},
95 {"mode", PLIST_CHMOD, 1, 0}, 95 {"mode", PLIST_CHMOD, 1, 0},
96 {"owner", PLIST_CHOWN, 1, 0}, 96 {"owner", PLIST_CHOWN, 1, 0},
97 {"group", PLIST_CHGRP, 1, 0}, 97 {"group", PLIST_CHGRP, 1, 0},
98 {"comment", PLIST_COMMENT, 1, 0}, 98 {"comment", PLIST_COMMENT, 1, 0},
99 {"ignore", PLIST_IGNORE, 0, 0}, 99 {"ignore", PLIST_IGNORE, 0, 0},
100 {"ignore_inst", PLIST_IGNORE_INST, 0, 0}, 100 {"ignore_inst", PLIST_IGNORE_INST, 0, 0},
101 {"name", PLIST_NAME, 1, 0}, 101 {"name", PLIST_NAME, 1, 0},
102 {"display", PLIST_DISPLAY, 1, 0}, 102 {"display", PLIST_DISPLAY, 1, 0},
103 {"pkgdep", PLIST_PKGDEP, 1, 0}, 103 {"pkgdep", PLIST_PKGDEP, 1, 0},
104 {"pkgcfl", PLIST_PKGCFL, 1, 0}, 104 {"pkgcfl", PLIST_PKGCFL, 1, 0},
105 {"mtree", PLIST_MTREE, 1, 0}, 105 {"mtree", PLIST_MTREE, 1, 0},
106 {"dirrm", PLIST_DIR_RM, 1, 0}, 106 {"dirrm", PLIST_DIR_RM, 1, 0},
107 {"option", PLIST_OPTION, 1, 0}, 107 {"option", PLIST_OPTION, 1, 0},
108 {"blddep", PLIST_BLDDEP, 1, 0}, 108 {"blddep", PLIST_BLDDEP, 1, 0},
109 {NULL, FAIL, 0, 0} 109 {NULL, FAIL, 0, 0}
110}; 110};
111 111
112/* 112/*
113 * Add an item to the end of a packing list 113 * Add an item to the end of a packing list
114 */ 114 */
115void 115void
116add_plist(package_t *p, pl_ent_t type, const char *arg) 116add_plist(package_t *p, pl_ent_t type, const char *arg)
117{ 117{
118 plist_t *tmp; 118 plist_t *tmp;
119 119
120 tmp = new_plist_entry(); 120 tmp = new_plist_entry();
121 tmp->name = (arg == NULL) ? NULL : xstrdup(arg); 121 tmp->name = (arg == NULL) ? NULL : xstrdup(arg);
122 tmp->type = type; 122 tmp->type = type;
123 if (!p->head) { 123 if (!p->head) {
124 p->head = p->tail = tmp; 124 p->head = p->tail = tmp;
125 } else { 125 } else {
126 tmp->prev = p->tail; 126 tmp->prev = p->tail;
127 p->tail->next = tmp; 127 p->tail->next = tmp;
128 p->tail = tmp; 128 p->tail = tmp;
129 } 129 }
130} 130}
131 131
132/* 132/*
133 * Add an item to the start of a packing list 133 * Add an item to the start of a packing list
134 */ 134 */
135void 135void
136add_plist_top(package_t *p, pl_ent_t type, const char *arg) 136add_plist_top(package_t *p, pl_ent_t type, const char *arg)
137{ 137{
138 plist_t *tmp; 138 plist_t *tmp;
139 139
140 tmp = new_plist_entry(); 140 tmp = new_plist_entry();
141 tmp->name = (arg == NULL) ? NULL : xstrdup(arg); 141 tmp->name = (arg == NULL) ? NULL : xstrdup(arg);
142 tmp->type = type; 142 tmp->type = type;
143 if (!p->head) { 143 if (!p->head) {
144 p->head = p->tail = tmp; 144 p->head = p->tail = tmp;
145 } else { 145 } else {
146 tmp->next = p->head; 146 tmp->next = p->head;
147 p->head->prev = tmp; 147 p->head->prev = tmp;
148 p->head = tmp; 148 p->head = tmp;
149 } 149 }
150} 150}
151 151
152/* 152/*
153 * Return the last (most recent) entry in a packing list 153 * Return the last (most recent) entry in a packing list
154 */ 154 */
155plist_t * 155plist_t *
156last_plist(package_t *p) 156last_plist(package_t *p)
157{ 157{
158 return p->tail; 158 return p->tail;
159} 159}
160 160
161/* 161/*
162 * Mark all items in a packing list to prevent iteration over them 162 * Mark all items in a packing list to prevent iteration over them
163 */ 163 */
164void 164void
165mark_plist(package_t *pkg) 165mark_plist(package_t *pkg)
166{ 166{
167 plist_t *pp; 167 plist_t *pp;
168 168
169 for (pp = pkg->head; pp; pp = pp->next) { 169 for (pp = pkg->head; pp; pp = pp->next) {
170 pp->marked = TRUE; 170 pp->marked = TRUE;
171 } 171 }
172} 172}
173 173
174/* 174/*
175 * Find a given item in a packing list and, if so, return it (else NULL) 175 * Find a given item in a packing list and, if so, return it (else NULL)
176 */ 176 */
177plist_t * 177plist_t *
178find_plist(package_t *pkg, pl_ent_t type) 178find_plist(package_t *pkg, pl_ent_t type)
179{ 179{
180 plist_t *pp; 180 plist_t *pp;
181 181
182 for (pp = pkg->head; pp && pp->type != type; pp = pp->next) { 182 for (pp = pkg->head; pp && pp->type != type; pp = pp->next) {
183 } 183 }
184 return pp; 184 return pp;
185} 185}
186 186
187/* 187/*
188 * Look for a specific boolean option argument in the list 188 * Look for a specific boolean option argument in the list
189 */ 189 */
190char * 190char *
191find_plist_option(package_t *pkg, char *name) 191find_plist_option(package_t *pkg, char *name)
192{ 192{
193 plist_t *p; 193 plist_t *p;
194 194
195 for (p = pkg->head; p; p = p->next) { 195 for (p = pkg->head; p; p = p->next) {
196 if (p->type == PLIST_OPTION 196 if (p->type == PLIST_OPTION
197 && strcmp(p->name, name) == 0) { 197 && strcmp(p->name, name) == 0) {
198 return p->name; 198 return p->name;
199 } 199 }
200 } 200 }
201  201
202 return (char *) NULL; 202 return (char *) NULL;
203} 203}
204 204
205/* 205/*
206 * Delete plist item 'type' in the list (if 'name' is non-null, match it 206 * Delete plist item 'type' in the list (if 'name' is non-null, match it
207 * too.) If 'all' is set, delete all items, not just the first occurance. 207 * too.) If 'all' is set, delete all items, not just the first occurance.
208 */ 208 */
209void 209void
210delete_plist(package_t *pkg, Boolean all, pl_ent_t type, char *name) 210delete_plist(package_t *pkg, Boolean all, pl_ent_t type, char *name)
211{ 211{
212 plist_t *p = pkg->head; 212 plist_t *p = pkg->head;
213 213
214 while (p) { 214 while (p) {
215 plist_t *pnext = p->next; 215 plist_t *pnext = p->next;
216 216
217 if (p->type == type && (!name || !strcmp(name, p->name))) { 217 if (p->type == type && (!name || !strcmp(name, p->name))) {
218 free(p->name); 218 free(p->name);
219 if (p->prev) 219 if (p->prev)
220 p->prev->next = pnext; 220 p->prev->next = pnext;
221 else 221 else
222 pkg->head = pnext; 222 pkg->head = pnext;
223 if (pnext) 223 if (pnext)
224 pnext->prev = p->prev; 224 pnext->prev = p->prev;
225 else 225 else
226 pkg->tail = p->prev; 226 pkg->tail = p->prev;
227 free(p); 227 free(p);
228 if (!all) 228 if (!all)
229 return; 229 return;
230 p = pnext; 230 p = pnext;
231 } else 231 } else
232 p = p->next; 232 p = p->next;
233 } 233 }
234} 234}
235 235
236/* 236/*
237 * Allocate a new packing list entry, and return a pointer to it.  237 * Allocate a new packing list entry, and return a pointer to it.
238 */ 238 */
239plist_t * 239plist_t *
240new_plist_entry(void) 240new_plist_entry(void)
241{ 241{
242 return xcalloc(1, sizeof(plist_t)); 242 return xcalloc(1, sizeof(plist_t));
243} 243}
244 244
245/* 245/*
246 * Free an entire packing list 246 * Free an entire packing list
247 */ 247 */
248void 248void
249free_plist(package_t *pkg) 249free_plist(package_t *pkg)
250{ 250{
251 plist_t *p = pkg->head; 251 plist_t *p = pkg->head;
252 252
253 while (p) { 253 while (p) {
254 plist_t *p1 = p->next; 254 plist_t *p1 = p->next;
255 255
256 free(p->name); 256 free(p->name);
257 free(p); 257 free(p);
258 p = p1; 258 p = p1;
259 } 259 }
260 pkg->head = pkg->tail = NULL; 260 pkg->head = pkg->tail = NULL;
261} 261}
262 262
263/* 263/*
264 * For an ASCII string denoting a plist command, return its code and 264 * For an ASCII string denoting a plist command, return its code and
265 * optionally its argument(s) 265 * optionally its argument(s)
266 */ 266 */
267static int 267static int
268plist_cmd(const char *s, char **arg) 268plist_cmd(const char *s, char **arg)
269{ 269{
270 const cmd_t *cmdp; 270 const cmd_t *cmdp;
271 const char *cp, *sp; 271 const char *cp, *sp;
272 char *sp2; 272 char *sp2;
273 273
274 for (cmdp = cmdv; cmdp->c_s; ++cmdp) { 274 for (cmdp = cmdv; cmdp->c_s; ++cmdp) {
275 for (sp = s, cp = cmdp->c_s; *sp && *cp; ++cp, ++sp) 275 for (sp = s, cp = cmdp->c_s; *sp && *cp; ++cp, ++sp)
276 if (tolower((unsigned char)*sp) != *cp) 276 if (tolower((unsigned char)*sp) != *cp)
277 break; 277 break;
278 if (*cp == '\0') 278 if (*cp == '\0')
279 break; 279 break;
280 } 280 }
281 281
282 if (cmdp->c_s == NULL || arg == NULL) 282 if (cmdp->c_s == NULL || arg == NULL)
283 return cmdp->c_type; 283 return cmdp->c_type;
284 284
285 while (isspace((unsigned char)*sp)) 285 while (isspace((unsigned char)*sp))
286 ++sp; 286 ++sp;
287 *arg = xstrdup(sp); 287 *arg = xstrdup(sp);
288 if (*sp) { 288 if (*sp) {
289 sp2 = *arg + strlen(*arg) - 1; 289 sp2 = *arg + strlen(*arg) - 1;
290 /* 290 /*
291 * The earlier loop ensured that at least one non-whitespace 291 * The earlier loop ensured that at least one non-whitespace
292 * is in the string. 292 * is in the string.
293 */ 293 */
294 while (isspace((unsigned char)*sp2)) 294 while (isspace((unsigned char)*sp2))
295 --sp2; 295 --sp2;
296 sp2[1] = '\0'; 296 sp2[1] = '\0';
297 } 297 }
298 return cmdp->c_type; 298 return cmdp->c_type;
299} 299}
300 300
301/* 301/*
302 * Parse a packaging list from a memory buffer. 302 * Parse a packaging list from a memory buffer.
303 */ 303 */
304void 304void
305parse_plist(package_t *pkg, const char *buf) 305parse_plist(package_t *pkg, const char *buf)
306{ 306{
307 int cmd; 307 int cmd;
308 char *line, *cp; 308 char *line, *cp;
309 const char *eol, *next; 309 const char *eol, *next;
310 size_t len; 310 size_t len;
311 311
312 pkg->head = NULL; 312 pkg->head = NULL;
313 pkg->tail = NULL; 313 pkg->tail = NULL;
314 314
315 for (; *buf; buf = next) { 315 for (; *buf; buf = next) {
316 /* Until add_plist can deal with trailing whitespace. */ 316 /* Until add_plist can deal with trailing whitespace. */
317 if ((eol = strchr(buf, '\n')) != NULL) { 317 if ((eol = strchr(buf, '\n')) != NULL) {
318 next = eol + 1; 318 next = eol + 1;
319 len = eol - buf; 319 len = eol - buf;
320 } else { 320 } else {
321 len = strlen(buf); 321 len = strlen(buf);
322 next = buf + len; 322 next = buf + len;
323 } 323 }
324 324
325 while (len && isspace((unsigned char)buf[len - 1])) 325 while (len && isspace((unsigned char)buf[len - 1]))
326 --len; 326 --len;
327 327
328 if (len == 0) 328 if (len == 0)
329 continue; 329 continue;
330 330
331 line = xmalloc(len + 1); 331 line = xmalloc(len + 1);
332 memcpy(line, buf, len); 332 memcpy(line, buf, len);
333 line[len] = '\0'; 333 line[len] = '\0';
334 334
335 if (*(cp = line) == CMD_CHAR) { 335 if (*(cp = line) == CMD_CHAR) {
336 if ((cmd = plist_cmd(line + 1, &cp)) == FAIL) { 336 if ((cmd = plist_cmd(line + 1, &cp)) == FAIL) {
337 warnx("Unrecognised PLIST command `%s'", line); 337 warnx("Unrecognised PLIST command `%s'", line);
338 continue; 338 continue;
339 } 339 }
340 if (*cp == '\0') { 340 if (*cp == '\0') {
341 free(cp); 341 free(cp);
342 cp = NULL; 342 cp = NULL;
343 } 343 }
344 } else { 344 } else {
345 cmd = PLIST_FILE; 345 cmd = PLIST_FILE;
346 } 346 }
347 add_plist(pkg, cmd, cp); 347 add_plist(pkg, cmd, cp);
348 free(cp); 348 free(cp);
349 } 349 }
350} 350}
351 351
352/* 352/*
353 * Read a packing list from a file 353 * Read a packing list from a file
354 */ 354 */
355void 355void
356read_plist(package_t *pkg, FILE * fp) 356append_plist(package_t *pkg, FILE * fp)
357{ 357{
358 char pline[MaxPathSize]; 358 char pline[MaxPathSize];
359 char *cp; 359 char *cp;
360 int cmd; 360 int cmd;
361 int len; 361 int len;
362 int free_cp; 362 int free_cp;
363 363
364 pkg->head = NULL; 
365 pkg->tail = NULL; 
366 
367 while (fgets(pline, MaxPathSize, fp) != (char *) NULL) { 364 while (fgets(pline, MaxPathSize, fp) != (char *) NULL) {
368 for (len = strlen(pline); len && 365 for (len = strlen(pline); len &&
369 isspace((unsigned char) pline[len - 1]);) { 366 isspace((unsigned char) pline[len - 1]);) {
370 pline[--len] = '\0'; 367 pline[--len] = '\0';
371 } 368 }
372 if (len == 0) { 369 if (len == 0) {
373 continue; 370 continue;
374 } 371 }
375 free_cp = 0; 372 free_cp = 0;
376 if (*(cp = pline) == CMD_CHAR) { 373 if (*(cp = pline) == CMD_CHAR) {
377 if ((cmd = plist_cmd(pline + 1, &cp)) == FAIL) { 374 if ((cmd = plist_cmd(pline + 1, &cp)) == FAIL) {
378 warnx("Unrecognised PLIST command `%s'", pline); 375 warnx("Unrecognised PLIST command `%s'", pline);
379 continue; 376 continue;
380 } 377 }
381 if (*cp == '\0') { 378 if (*cp == '\0') {
382 free(cp); 379 free(cp);
383 cp = NULL; 380 cp = NULL;
384 } 381 }
385 free_cp = 1; 382 free_cp = 1;
386 } else { 383 } else {
387 cmd = PLIST_FILE; 384 cmd = PLIST_FILE;
388 } 385 }
389 add_plist(pkg, cmd, cp); 386 add_plist(pkg, cmd, cp);
390 if (free_cp) 387 if (free_cp)
391 free(cp); 388 free(cp);
392 } 389 }
393} 390}
394 391
 392void
 393read_plist(package_t *pkg, FILE * fp)
 394{
 395 pkg->head = NULL;
 396 pkg->tail = NULL;
 397
 398 append_plist(pkg, fp);
 399}
 400
395/* 401/*
396 * Write a packing list to a file, converting commands to ASCII equivs 402 * Write a packing list to a file, converting commands to ASCII equivs
397 */ 403 */
398void 404void
399write_plist(package_t *pkg, FILE * fp, char *realprefix) 405write_plist(package_t *pkg, FILE * fp, char *realprefix)
400{ 406{
401 plist_t *p; 407 plist_t *p;
402 const cmd_t *cmdp; 408 const cmd_t *cmdp;
403 409
404 for (p = pkg->head; p; p = p->next) { 410 for (p = pkg->head; p; p = p->next) {
405 if (p->type == PLIST_FILE) { 411 if (p->type == PLIST_FILE) {
406 /* Fast-track files - these are the most common */ 412 /* Fast-track files - these are the most common */
407 (void) fprintf(fp, "%s\n", p->name); 413 (void) fprintf(fp, "%s\n", p->name);
408 continue; 414 continue;
409 } 415 }
410 for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) { 416 for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) {
411 } 417 }
412 if (cmdp->c_type == FAIL) { 418 if (cmdp->c_type == FAIL) {
413 warnx("Unknown PLIST command type %d (%s)", p->type, p->name); 419 warnx("Unknown PLIST command type %d (%s)", p->type, p->name);
414 } else if (cmdp->c_argc == 0) { 420 } else if (cmdp->c_argc == 0) {
415 (void) fprintf(fp, "%c%s\n", CMD_CHAR, cmdp->c_s); 421 (void) fprintf(fp, "%c%s\n", CMD_CHAR, cmdp->c_s);
416 } else if (cmdp->c_subst && realprefix) { 422 } else if (cmdp->c_subst && realprefix) {
417 (void) fprintf(fp, "%c%s %s\n", CMD_CHAR, cmdp->c_s, realprefix); 423 (void) fprintf(fp, "%c%s %s\n", CMD_CHAR, cmdp->c_s, realprefix);
418 } else { 424 } else {
419 (void) fprintf(fp, "%c%s %s\n", CMD_CHAR, cmdp->c_s, 425 (void) fprintf(fp, "%c%s %s\n", CMD_CHAR, cmdp->c_s,
420 (p->name) ? p->name : ""); 426 (p->name) ? p->name : "");
421 } 427 }
422 } 428 }
423} 429}
424 430
425/* 431/*
426 * Like write_plist, but compute memory string. 432 * Like write_plist, but compute memory string.
427 */ 433 */
428void 434void
429stringify_plist(package_t *pkg, char **real_buf, size_t *real_len, 435stringify_plist(package_t *pkg, char **real_buf, size_t *real_len,
430 const char *realprefix) 436 const char *realprefix)
431{ 437{
432 plist_t *p; 438 plist_t *p;
433 const cmd_t *cmdp; 439 const cmd_t *cmdp;
434 char *buf; 440 char *buf;
435 size_t len; 441 size_t len;
436 int item_len; 442 int item_len;
437 443
438 /* Pass One: compute output size only. */ 444 /* Pass One: compute output size only. */
439 len = 0; 445 len = 0;
440 446
441 for (p = pkg->head; p; p = p->next) { 447 for (p = pkg->head; p; p = p->next) {
442 if (p->type == PLIST_FILE) { 448 if (p->type == PLIST_FILE) {
443 len += strlen(p->name) + 1; 449 len += strlen(p->name) + 1;
444 continue; 450 continue;
445 } 451 }
446 for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) { 452 for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) {
447 } 453 }
448 if (cmdp->c_type == FAIL) 454 if (cmdp->c_type == FAIL)
449 continue; 455 continue;
450 if (cmdp->c_argc == 0) 456 if (cmdp->c_argc == 0)
451 len += 1 + strlen(cmdp->c_s) + 1; 457 len += 1 + strlen(cmdp->c_s) + 1;
452 else if (cmdp->c_subst && realprefix) 458 else if (cmdp->c_subst && realprefix)
453 len += 1 + strlen(cmdp->c_s) + 1 + strlen(realprefix) + 1; 459 len += 1 + strlen(cmdp->c_s) + 1 + strlen(realprefix) + 1;
454 else 460 else
455 len += 1 + strlen(cmdp->c_s) + 1 + strlen(p->name ? p->name : "") + 1; 461 len += 1 + strlen(cmdp->c_s) + 1 + strlen(p->name ? p->name : "") + 1;
456 } 462 }
457 463
458 /* Pass Two: build actual string. */ 464 /* Pass Two: build actual string. */
459 buf = xmalloc(len + 1); 465 buf = xmalloc(len + 1);
460 *real_buf = buf; 466 *real_buf = buf;
461 *real_len = len; 467 *real_len = len;
462 ++len; 468 ++len;
463 469
464#define UPDATE_LEN \ 470#define UPDATE_LEN \
465do { \ 471do { \
466 if (item_len < 0 || item_len > len) \ 472 if (item_len < 0 || item_len > len) \
467 errx(2, "Size computation failed, aborted."); \ 473 errx(2, "Size computation failed, aborted."); \
468 buf += item_len; \ 474 buf += item_len; \
469 len -= item_len; \ 475 len -= item_len; \
470} while (0) 476} while (0)
471 477
472 for (p = pkg->head; p; p = p->next) { 478 for (p = pkg->head; p; p = p->next) {
473 if (p->type == PLIST_FILE) { 479 if (p->type == PLIST_FILE) {
474 /* Fast-track files - these are the most common */ 480 /* Fast-track files - these are the most common */
475 item_len = snprintf(buf, len, "%s\n", p->name); 481 item_len = snprintf(buf, len, "%s\n", p->name);
476 UPDATE_LEN; 482 UPDATE_LEN;
477 continue; 483 continue;
478 } 484 }
479 for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) { 485 for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) {
480 } 486 }
481 if (cmdp->c_type == FAIL) { 487 if (cmdp->c_type == FAIL) {
482 warnx("Unknown PLIST command type %d (%s)", p->type, p->name); 488 warnx("Unknown PLIST command type %d (%s)", p->type, p->name);
483 } else if (cmdp->c_argc == 0) { 489 } else if (cmdp->c_argc == 0) {
484 item_len = snprintf(buf, len, "%c%s\n", CMD_CHAR, cmdp->c_s); 490 item_len = snprintf(buf, len, "%c%s\n", CMD_CHAR, cmdp->c_s);
485 UPDATE_LEN; 491 UPDATE_LEN;
486 } else if (cmdp->c_subst && realprefix) { 492 } else if (cmdp->c_subst && realprefix) {
487 item_len = snprintf(buf, len, "%c%s %s\n", CMD_CHAR, cmdp->c_s, realprefix); 493 item_len = snprintf(buf, len, "%c%s %s\n", CMD_CHAR, cmdp->c_s, realprefix);
488 UPDATE_LEN; 494 UPDATE_LEN;
489 } else { 495 } else {
490 item_len = snprintf(buf, len, "%c%s %s\n", CMD_CHAR, cmdp->c_s, 496 item_len = snprintf(buf, len, "%c%s %s\n", CMD_CHAR, cmdp->c_s,
491 (p->name) ? p->name : ""); 497 (p->name) ? p->name : "");
492 UPDATE_LEN; 498 UPDATE_LEN;
493 } 499 }
494 } 500 }
495 501
496 if (len != 1) 502 if (len != 1)
497 errx(2, "Size computation failed, aborted."); 503 errx(2, "Size computation failed, aborted.");
498} 504}
499 505
500/* 506/*
501 * Delete the results of a package installation. 507 * Delete the results of a package installation.
502 * 508 *
503 * This is here rather than in the pkg_delete code because pkg_add needs to 509 * This is here rather than in the pkg_delete code because pkg_add needs to
504 * run it too in cases of failure. 510 * run it too in cases of failure.
505 */ 511 */
506int 512int
507delete_package(Boolean ign_err, Boolean nukedirs, package_t *pkg, 513delete_package(Boolean ign_err, Boolean nukedirs, package_t *pkg,
508 Boolean NoDeleteFiles, const char *destdir) 514 Boolean NoDeleteFiles, const char *destdir)
509{ 515{
510 plist_t *p; 516 plist_t *p;
511 char *Where = ".", *last_file = ""; 517 char *Where = ".", *last_file = "";
512 int fail = SUCCESS; 518 int fail = SUCCESS;
513 Boolean preserve; 519 Boolean preserve;
514 char tmp[MaxPathSize], *name = NULL; 520 char tmp[MaxPathSize], *name = NULL;
515 521
516 if (!pkgdb_open(ReadWrite)) { 522 if (!pkgdb_open(ReadWrite)) {
517 err(EXIT_FAILURE, "cannot open pkgdb"); 523 err(EXIT_FAILURE, "cannot open pkgdb");
518 } 524 }
519 525
520 preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE; 526 preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
521 for (p = pkg->head; p; p = p->next) { 527 for (p = pkg->head; p; p = p->next) {
522 switch (p->type) { 528 switch (p->type) {
523 case PLIST_NAME: 529 case PLIST_NAME:
524 name = p->name; 530 name = p->name;
525 break; 531 break;
526 532
527 case PLIST_IGNORE: 533 case PLIST_IGNORE:
528 p = p->next; 534 p = p->next;
529 break; 535 break;
530 536
531 case PLIST_CWD: 537 case PLIST_CWD:
532 Where = p->name; 538 Where = p->name;
533 if (Verbose) 539 if (Verbose)
534 printf("Change working directory to %s\n", Where); 540 printf("Change working directory to %s\n", Where);
535 break; 541 break;
536 542
537 case PLIST_UNEXEC: 543 case PLIST_UNEXEC:
538 if (NoDeleteFiles) 544 if (NoDeleteFiles)
539 break; 545 break;
540 format_cmd(tmp, sizeof(tmp), p->name, Where, last_file); 546 format_cmd(tmp, sizeof(tmp), p->name, Where, last_file);
541 /* XXX cleanup(0); */ 547 /* XXX cleanup(0); */
542 printf("Executing `%s'\n", tmp); 548 printf("Executing `%s'\n", tmp);
543 if (!Fake && system(tmp)) { 549 if (!Fake && system(tmp)) {
544 warnx("unexec command for `%s' failed", tmp); 550 warnx("unexec command for `%s' failed", tmp);
545 fail = FAIL; 551 fail = FAIL;
546 } 552 }
547 break; 553 break;
548 554
549 case PLIST_FILE: 555 case PLIST_FILE:
550 last_file = p->name; 556 last_file = p->name;
551 (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s", 557 (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s",
552 destdir ? destdir : "", destdir ? "/" : "", 558 destdir ? destdir : "", destdir ? "/" : "",
553 Where, p->name); 559 Where, p->name);
554 if (isdir(tmp)) { 560 if (isdir(tmp)) {
555 warnx("attempting to delete directory `%s' as a file\n" 561 warnx("attempting to delete directory `%s' as a file\n"
556 "this packing list is incorrect - ignoring delete request", tmp); 562 "this packing list is incorrect - ignoring delete request", tmp);
557 } else { 563 } else {
558 int restored = 0; /* restored from preserve? */ 564 int restored = 0; /* restored from preserve? */
559 565
560 if (p->next && p->next->type == PLIST_COMMENT) { 566 if (p->next && p->next->type == PLIST_COMMENT) {
561 if (strncmp(p->next->name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) { 567 if (strncmp(p->next->name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) {
562 char *cp, buf[LegibleChecksumLen]; 568 char *cp, buf[LegibleChecksumLen];
563 569
564 if ((cp = MD5File(tmp, buf)) != NULL) { 570 if ((cp = MD5File(tmp, buf)) != NULL) {
565 /* Mismatch? */ 571 /* Mismatch? */
566 if (strcmp(cp, p->next->name + ChecksumHeaderLen) != 0) { 572 if (strcmp(cp, p->next->name + ChecksumHeaderLen) != 0) {
567 printf("original MD5 checksum failed, %s: %s\n", 573 printf("original MD5 checksum failed, %s: %s\n",
568 Force ? "deleting anyway" : "not deleting", tmp); 574 Force ? "deleting anyway" : "not deleting", tmp);
569 if (!Force) { 575 if (!Force) {
570 fail = FAIL; 576 fail = FAIL;
571 continue; 577 continue;
572 } 578 }
573 } 579 }
574 } 580 }
575 } else if (strncmp(p->next->name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) { 581 } else if (strncmp(p->next->name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) {
576 char buf[MaxPathSize + SymlinkHeaderLen]; 582 char buf[MaxPathSize + SymlinkHeaderLen];
577 int cc; 583 int cc;
578 584
579 (void) strlcpy(buf, SYMLINK_HEADER, 585 (void) strlcpy(buf, SYMLINK_HEADER,
580 sizeof(buf)); 586 sizeof(buf));
581 if ((cc = readlink(tmp, &buf[SymlinkHeaderLen], 587 if ((cc = readlink(tmp, &buf[SymlinkHeaderLen],
582 sizeof(buf) - SymlinkHeaderLen - 1)) < 0) { 588 sizeof(buf) - SymlinkHeaderLen - 1)) < 0) {
583 warn("can't readlink `%s'", tmp); 589 warn("can't readlink `%s'", tmp);
584 continue; 590 continue;
585 } 591 }
586 buf[SymlinkHeaderLen + cc] = 0x0; 592 buf[SymlinkHeaderLen + cc] = 0x0;
587 if (strcmp(buf, p->next->name) != 0) { 593 if (strcmp(buf, p->next->name) != 0) {
588 if ((cc = readlink(&buf[SymlinkHeaderLen], &buf[SymlinkHeaderLen], 594 if ((cc = readlink(&buf[SymlinkHeaderLen], &buf[SymlinkHeaderLen],
589 sizeof(buf) - SymlinkHeaderLen)) < 0) { 595 sizeof(buf) - SymlinkHeaderLen)) < 0) {
590 printf("symlink %s is not same as recorded value, %s: %s\n", 596 printf("symlink %s is not same as recorded value, %s: %s\n",
591 buf, Force ? "deleting anyway" : "not deleting", tmp); 597 buf, Force ? "deleting anyway" : "not deleting", tmp);
592 if (!Force) { 598 if (!Force) {
593 fail = FAIL; 599 fail = FAIL;
594 continue; 600 continue;
595 } 601 }
596 } 602 }
597 buf[SymlinkHeaderLen + cc] = 0x0; 603 buf[SymlinkHeaderLen + cc] = 0x0;
598 if (strcmp(buf, p->next->name) != 0) { 604 if (strcmp(buf, p->next->name) != 0) {
599 printf("symlink %s is not same as recorded value, %s: %s\n", 605 printf("symlink %s is not same as recorded value, %s: %s\n",
600 buf, Force ? "deleting anyway" : "not deleting", tmp); 606 buf, Force ? "deleting anyway" : "not deleting", tmp);
601 if (!Force) { 607 if (!Force) {
602 fail = FAIL; 608 fail = FAIL;
603 continue; 609 continue;
604 } 610 }
605 } 611 }
606 } 612 }
607 } 613 }
608 } 614 }
609 if (Verbose && !NoDeleteFiles) 615 if (Verbose && !NoDeleteFiles)
610 printf("Delete file %s\n", tmp); 616 printf("Delete file %s\n", tmp);
611 if (!Fake && !NoDeleteFiles) { 617 if (!Fake && !NoDeleteFiles) {
612 if (delete_hierarchy(tmp, ign_err, nukedirs)) 618 if (delete_hierarchy(tmp, ign_err, nukedirs))
613 fail = FAIL; 619 fail = FAIL;
614 if (preserve && name) { 620 if (preserve && name) {
615 char tmp2[MaxPathSize]; 621 char tmp2[MaxPathSize];
616 622
617 if (make_preserve_name(tmp2, MaxPathSize, name, tmp)) { 623 if (make_preserve_name(tmp2, MaxPathSize, name, tmp)) {
618 if (fexists(tmp2)) { 624 if (fexists(tmp2)) {
619 if (rename(tmp2, tmp)) 625 if (rename(tmp2, tmp))
620 warn("preserve: unable to restore %s as %s", 626 warn("preserve: unable to restore %s as %s",
621 tmp2, tmp); 627 tmp2, tmp);
622 else 628 else
623 restored = 1; 629 restored = 1;
624 } 630 }
625 } 631 }
626 } 632 }
627 } 633 }
628 634
629 if (!Fake) { 635 if (!Fake) {
630 if (!restored) { 636 if (!restored) {
631#ifdef PKGDB_DEBUG 637#ifdef PKGDB_DEBUG
632 printf("pkgdb_remove(\"%s\")\n", tmp); /* HF */ 638 printf("pkgdb_remove(\"%s\")\n", tmp); /* HF */
633#endif 639#endif
634 errno = 0; 640 errno = 0;
635 if (pkgdb_remove(tmp)) { 641 if (pkgdb_remove(tmp)) {
636 if (errno) { 642 if (errno) {
637 perror("pkgdb_remove"); 643 perror("pkgdb_remove");
638 } 644 }
639 } else { 645 } else {
640#ifdef PKGDB_DEBUG 646#ifdef PKGDB_DEBUG
641 printf("pkgdb_remove: ok\n"); 647 printf("pkgdb_remove: ok\n");
642#endif 648#endif
643 } 649 }
644 } 650 }
645 } 651 }
646 } 652 }
647 break; 653 break;
648 654
649 case PLIST_DIR_RM: 655 case PLIST_DIR_RM:
650 if (NoDeleteFiles) 656 if (NoDeleteFiles)
651 break; 657 break;
652 658
653 (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s", 659 (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s",
654 destdir ? destdir : "", destdir ? "/" : "", 660 destdir ? destdir : "", destdir ? "/" : "",
655 Where, p->name); 661 Where, p->name);
656 if (fexists(tmp)) { 662 if (fexists(tmp)) {
657 if (!isdir(tmp)) { 663 if (!isdir(tmp)) {
658 warnx("cannot remove `%s' as a directory\n" 664 warnx("cannot remove `%s' as a directory\n"
659 "this packing list is incorrect - ignoring delete request", tmp); 665 "this packing list is incorrect - ignoring delete request", tmp);
660 } else { 666 } else {
661 if (Verbose) 667 if (Verbose)
662 printf("Delete directory %s\n", tmp); 668 printf("Delete directory %s\n", tmp);
663 if (!Fake && delete_hierarchy(tmp, ign_err, FALSE)) { 669 if (!Fake && delete_hierarchy(tmp, ign_err, FALSE)) {
664 warnx("unable to completely remove directory '%s'", tmp); 670 warnx("unable to completely remove directory '%s'", tmp);
665 fail = FAIL; 671 fail = FAIL;
666 } 672 }
667 } 673 }
668 } else { 674 } else {
669 warnx("cannot remove non-existent directory `%s'\n" 675 warnx("cannot remove non-existent directory `%s'\n"
670 "this packing list is incorrect - ignoring delete request", tmp); 676 "this packing list is incorrect - ignoring delete request", tmp);
671 } 677 }
672 last_file = p->name; 678 last_file = p->name;
673 break; 679 break;
674 default: 680 default:
675 break; 681 break;
676 } 682 }
677 } 683 }
678 pkgdb_close(); 684 pkgdb_close();
679 return fail; 685 return fail;
680} 686}
681 687
682/* 688/*
683 * Selectively delete a hierarchy 689 * Selectively delete a hierarchy
684 * Returns 1 on error, 0 else. 690 * Returns 1 on error, 0 else.
685 */ 691 */
686int 692int
687delete_hierarchy(char *dir, Boolean ign_err, Boolean nukedirs) 693delete_hierarchy(char *dir, Boolean ign_err, Boolean nukedirs)
688{ 694{
689 char *cp1, *cp2; 695 char *cp1, *cp2;
690 696
691 cp1 = cp2 = dir; 697 cp1 = cp2 = dir;
692 if (!fexists(dir)) { 698 if (!fexists(dir)) {
693 if (!ign_err) 699 if (!ign_err)
694 warnx("%s `%s' doesn't really exist", 700 warnx("%s `%s' doesn't really exist",
695 isdir(dir) ? "directory" : "file", dir); 701 isdir(dir) ? "directory" : "file", dir);
696 return !ign_err; 702 return !ign_err;
697 } else if (nukedirs) { 703 } else if (nukedirs) {
698 if (recursive_remove(dir, ign_err)) { 704 if (recursive_remove(dir, ign_err)) {
699 warn("Couldn't remove %s", dir); 705 warn("Couldn't remove %s", dir);
700 return 1; 706 return 1;
701 } 707 }
702 } else if (isdir(dir)) { 708 } else if (isdir(dir)) {
703 if (rmdir(dir) && !ign_err) 709 if (rmdir(dir) && !ign_err)
704 return 1; 710 return 1;
705 } else { 711 } else {
706 if (remove(dir) && !ign_err) 712 if (remove(dir) && !ign_err)
707 return 1; 713 return 1;
708 } 714 }
709 715
710 if (!nukedirs) 716 if (!nukedirs)
711 return 0; 717 return 0;
712 while (cp2) { 718 while (cp2) {
713 if ((cp2 = strrchr(cp1, '/')) != NULL) 719 if ((cp2 = strrchr(cp1, '/')) != NULL)
714 *cp2 = '\0'; 720 *cp2 = '\0';
715 if (!isemptydir(dir)) 721 if (!isemptydir(dir))
716 return 0; 722 return 0;
717 if (rmdir(dir) && !ign_err) { 723 if (rmdir(dir) && !ign_err) {
718 if (!fexists(dir)) 724 if (!fexists(dir))
719 warnx("directory `%s' doesn't really exist", dir); 725 warnx("directory `%s' doesn't really exist", dir);
720 else 726 else
721 return 1; 727 return 1;
722 } 728 }
723 /* back up the pathname one component */ 729 /* back up the pathname one component */
724 if (cp2) { 730 if (cp2) {
725 cp1 = dir; 731 cp1 = dir;
726 } 732 }
727 } 733 }
728 return 0; 734 return 0;
729} 735}