Import pkg_install-20090528:
[netbsd-mini2440.git] / external / bsd / pkg_install / dist / lib / path.c
blob982510bc57786883b18374e30007a25ead949069
1 /* $NetBSD: path.c,v 1.7 2009/02/02 12:35:01 joerg Exp $ */
3 /*-
4 * Copyright (c)2002 YAMAMOTO Takashi,
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
29 #if HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 #include <nbcompat.h>
33 #if HAVE_SYS_CDEFS_H
34 #include <sys/cdefs.h>
35 #endif
36 __RCSID("$NetBSD: path.c,v 1.7 2009/02/02 12:35:01 joerg Exp $");
38 #if HAVE_ERR_H
39 #include <err.h>
40 #endif
42 #include "lib.h"
44 struct pathhead PkgPath = TAILQ_HEAD_INITIALIZER(PkgPath);
45 static struct path *prepend = 0;
47 static struct path *path_new_entry(const char *cp, size_t len);
50 * path_create: make PkgPath from a given string.
52 * => relative pathes are resolved to absolute ones.
53 * => if NULL is passed, use "." instead. XXX
55 void
56 path_create(const char *path)
58 const char *cp;
59 size_t len;
61 path_free();
63 if (path == NULL) {
64 path = "."; /* XXX */
67 if (Verbose)
68 printf("parsing: %s\n", path);
70 cp = path;
71 while (*cp) {
72 len = strcspn(cp, ";");
73 if (len > 0) {
74 /* add a new path */
75 struct path *new;
77 new = path_new_entry(cp, len);
78 if (Verbose)
79 printf("path: %s\n", new->pl_path);
80 TAILQ_INSERT_TAIL(&PkgPath, new, pl_entry);
83 cp += len;
84 if (*cp == '\0')
85 break;
86 cp++;
91 * path_free: free PkgPath.
93 void
94 path_free()
96 struct path *p;
98 while ((p = TAILQ_FIRST(&PkgPath)) != NULL) {
99 TAILQ_REMOVE(&PkgPath, p, pl_entry);
100 free(p->pl_path);
101 free(p);
106 * path_new_entry: Generate a new 'struct path' entry to be included in
107 * 'PkgPath' using the first 'len' characters of 'cp'.
109 static struct path *
110 path_new_entry(const char *cp, size_t len)
112 struct path *new;
114 new = xmalloc(sizeof(*new));
116 if (!IS_FULLPATH(cp) && !IS_URL(cp)) {
117 /* this is a relative path */
118 char cwd[MaxPathSize];
120 if (getcwd(cwd, sizeof(cwd)) == NULL)
121 err(EXIT_FAILURE, "getcwd");
122 new->pl_path = xasprintf("%s/%*.*s", cwd, (int)len, (int)len, cp);
124 else {
125 new->pl_path = xmalloc(len + 1);
126 memcpy(new->pl_path, cp, len);
127 new->pl_path[len] = '\0';
129 return new;
133 * path_prepend_from_pkgname: prepend the path for a package onto 'PkgPath'
135 void
136 path_prepend_from_pkgname(const char *pkgname)
138 char *ptr;
139 if ((ptr = strrchr(pkgname , '/'))) {
140 prepend = path_new_entry(pkgname, ptr - pkgname);
141 TAILQ_INSERT_HEAD(&PkgPath, prepend, pl_entry);
146 * path_prepend_clear: Remove any prepended entry from 'PkgPath'
148 void
149 path_prepend_clear()
151 if (prepend) {
152 TAILQ_REMOVE(&PkgPath, prepend, pl_entry);
153 prepend = 0;
158 * path_setenv: construct string from PkgPath and set it to a environment.
160 * => the environment name is given by envname.
162 void
163 path_setenv(const char *envname)
165 struct path *p;
166 ssize_t len = 0;
167 char *env, *env0, *envend;
168 char *sep;
170 TAILQ_FOREACH(p, &PkgPath, pl_entry)
171 len += strlen(p->pl_path) + 1;
173 env = xmalloc(len);
175 env0 = env;
176 envend = env + len;
177 sep = "";
178 TAILQ_FOREACH(p, &PkgPath, pl_entry) {
179 int r;
181 r = snprintf(env, envend - env, "%s%s", sep, p->pl_path);
182 if (r < 0 || r >= envend - env)
183 err(EXIT_FAILURE, "snprintf");
184 env += r;
185 sep = ";";
188 if (Verbose)
189 printf("%s = %s\n", envname, env0);
190 if (setenv(envname, env0, 1) != 0)
191 err(EXIT_FAILURE, "setenv");
192 free(env0);