sys/vfs/hammer2: Remove obsolete comments for unused/reserved ondisk fields
[dragonfly.git] / stand / boot / common / rel_open.c
blob1e7030e244598dc4f503c4e951002219e9b76feb
1 /*
2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
34 * $DragonFly: src/sys/boot/common/rel_open.c,v 1.2 2008/09/04 17:30:52 swildner Exp $
37 #include <stand.h>
38 #include <string.h>
40 #include "bootstrap.h"
42 char *DirBase;
44 COMMAND_SET(cd, "cd", "Change directory", command_chdir);
46 static int
47 command_chdir(int ac, char **av)
49 int result;
51 if (ac == 1) {
52 result = chdir(getenv("base"));
53 } else if (ac == 2) {
54 result = chdir(av[1]);
55 } else {
56 sprintf(command_errbuf, "usage: cd [<directory>]");
57 result = CMD_ERROR;
59 return result;
62 COMMAND_SET(optcd, "optcd",
63 "Change directory; ignore exit status", command_optchdir);
65 static int
66 command_optchdir(int ac, char **av)
68 if (ac == 1) {
69 chdir(getenv("base"));
70 } else if (ac == 2) {
71 chdir(av[1]);
72 } else {
73 sprintf(command_errbuf, "usage: optcd [<directory>]");
75 return(CMD_OK);
78 int
79 chdir(const char *path)
81 struct stat st;
82 char *base;
83 char *p;
84 char *b;
85 char *s;
86 char *w;
87 int len;
88 int dlen;
89 int res;
91 if (DirBase == NULL)
92 DirBase = strdup("/");
94 len = strlen(path);
95 if (path[0] == '/') {
96 base = malloc(len + 2); /* room for trailing / */
97 bcopy(path, base, len + 1);
98 } else {
99 while (len && path[len-1] == '/')
100 --len;
101 dlen = strlen(DirBase);
102 base = malloc(dlen + len + 2); /* room for trailing / */
103 bcopy(DirBase, base, dlen);
104 bcopy(path, base + dlen, len);
105 base[dlen + len] = 0;
108 if (stat(base, &st) == 0 && S_ISDIR(st.st_mode)) {
109 p = b = w = s = base;
110 while (*s) {
111 if (*s == '/') {
112 if (s - b == 2 && b[0] == '.' && b[1] == '.') {
113 w = p;
114 } else {
115 p = b;
116 b = s + 1;
118 while (s[1] == '/')
119 ++s;
121 *w = *s;
122 ++w;
123 ++s;
125 if (s - b == 2 && b[0] == '.' && b[1] == '.')
126 w = p;
127 while (w > base && w[-1] == '/')
128 --w;
129 *w++ = '/';
130 *w = 0;
132 if (DirBase)
133 free(DirBase);
134 DirBase = base;
135 res = CMD_OK;
136 } else {
137 free(base);
138 sprintf(command_errbuf, "Unable to find directory");
139 res = CMD_ERROR;
141 return (res);
144 COMMAND_SET(pwd, "pwd", "Get current directory", command_pwd);
146 static int
147 command_pwd(int ac, char **av)
149 printf("%s\n", DirBase ? DirBase : "/");
150 return(0);
154 rel_open(const char *path, char **abspathp, int flags)
156 int fd;
157 char *ptr;
159 if (DirBase == NULL)
160 DirBase = strdup("/");
162 if (path[0] != '/') {
163 ptr = malloc(strlen(DirBase) + strlen(path) + 1);
164 sprintf(ptr, "%s%s", DirBase, path);
165 fd = open(ptr, flags);
166 if (abspathp && fd >= 0) {
167 *abspathp = ptr;
168 } else if (abspathp) {
169 *abspathp = NULL;
170 free(ptr);
171 } else {
172 free(ptr);
174 } else {
175 fd = open(path, flags);
176 if (abspathp && fd >= 0) {
177 *abspathp = strdup(path);
178 } else if (abspathp) {
179 *abspathp = NULL;
182 return(fd);
186 rel_stat(const char *path, struct stat *st)
188 char *ptr;
189 int res;
191 if (DirBase == NULL)
192 DirBase = strdup("/");
194 if (path[0] != '/') {
195 ptr = malloc(strlen(DirBase) + strlen(path) + 1);
196 sprintf(ptr, "%s%s", DirBase, path);
197 res = stat(ptr, st);
198 free(ptr);
199 } else {
200 res = stat(path, st);
202 return(res);
206 * Return the root path of (path) with the "/boot" prefix prepended if
207 * not present. This is required by the kernel after bootstrap, e.g.,
208 * kldstat(), preload_delete_name().
210 char *
211 rel_rootpath(const char *path)
213 char *rootpath;
215 if (DirBase == NULL)
216 DirBase = strdup("/");
218 if (strncmp(path, "/boot/", sizeof("/boot/")-1) == 0) {
219 rootpath = strdup(path);
220 } else if (path[0] == '/') {
221 rootpath = malloc(strlen(path) + sizeof("/boot"));
222 sprintf(rootpath, "/boot%s", path);
223 } else {
224 rootpath = malloc(strlen(DirBase) + strlen(path) +
225 sizeof("/boot"));
226 sprintf(rootpath, "/boot%s%s", DirBase, path);
229 return (rootpath);