1 /* $NetBSD: expand.c,v 1.5 2008/04/28 20:23:03 martin Exp $ */
4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: expand.c,v 1.5 2008/04/28 20:23:03 martin Exp $");
38 #include <sys/sysctl.h>
45 size_t _rtld_expand_path(char *, size_t, const char *, const char *,
56 #define ADD(a) { #a, sizeof(#a) - 1 },
57 ADD(HWCAP
) /* SSE, MMX, etc */
58 ADD(ISALIST
) /* XXX */
59 ADD(ORIGIN
) /* dirname argv[0] */
60 ADD(OSNAME
) /* uname -s */
61 ADD(OSREL
) /* uname -r */
62 ADD(PLATFORM
) /* uname -p */
66 static int mib
[3][2] = {
67 { CTL_KERN
, KERN_OSTYPE
},
68 { CTL_KERN
, KERN_OSRELEASE
},
69 { CTL_HW
, HW_MACHINE_ARCH
},
74 expand(char *buf
, const char *execname
, int what
, size_t bl
)
82 case 0: /* HWCAP XXX: Not yet */
83 case 1: /* ISALIST XXX: Not yet */
88 xerr(1, "execname not specified in AUX vector");
89 if ((ep
= strrchr(p
= execname
, '/')) == NULL
)
90 xerr(1, "bad execname `%s' in AUX vector", execname
);
96 case 5: /* PLATFORM */
98 if (sysctl(mib
[what
- 3], 2, name
, &len
, NULL
, 0) == -1) {
102 ep
= (p
= name
) + len
- 1;
109 while (p
!= ep
&& bl
)
117 _rtld_expand_path(char *buf
, size_t bufsize
, const char *execname
,
118 const char *bp
, const char *ep
)
120 size_t i
, ds
= bufsize
;
125 for (p
= bp
; p
< ep
;) {
132 for (i
= 0; i
< sizeof(bltn
) / sizeof(bltn
[0]); i
++) {
133 size_t s
= bltn
[i
].namelen
;
134 const char *es
= p
+ s
;
136 if ((br
&& *es
!= '}') ||
138 isalpha((unsigned char)*es
))))
141 if (strncmp(bltn
[i
].name
, p
, s
) == 0) {
142 size_t ls
= expand(dp
, execname
, i
, ds
);
164 main(int argc
, char *argv
[])
169 for (i
= 1; i
< argc
; i
++) {
170 char *p
= argv
[i
], *ep
= argv
[i
] + strlen(p
);
171 size_t n
= _rtld_expand_path(buf
, sizeof(buf
), argv
[0], p
, ep
);