1 /* $NetBSD: expand.c,v 1.6 2013/05/06 08:02:20 skrll 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.6 2013/05/06 08:02:20 skrll 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
},
71 #endif /* !defined(__minix) */
74 expand(char *buf
, const char *execname
, int what
, size_t bl
)
81 #endif /* !defined(__minix) */
84 case 0: /* HWCAP XXX: Not yet */
85 case 1: /* ISALIST XXX: Not yet */
90 xerr(1, "execname not specified in AUX vector");
91 if ((ep
= strrchr(p
= execname
, '/')) == NULL
)
92 xerr(1, "bad execname `%s' in AUX vector", execname
);
98 case 5: /* PLATFORM */
100 if (sysctl(mib
[what
- 3], 2, name
, &len
, NULL
, 0) == -1) {
104 ep
= (p
= name
) + len
- 1;
106 #endif /* !defined(__minix) */
111 while (p
!= ep
&& bl
)
119 _rtld_expand_path(char *buf
, size_t bufsize
, const char *execname
,
120 const char *bp
, const char *ep
)
122 size_t i
, ds
= bufsize
;
127 for (p
= bp
; p
< ep
;) {
134 for (i
= 0; i
< sizeof(bltn
) / sizeof(bltn
[0]); i
++) {
135 size_t s
= bltn
[i
].namelen
;
136 const char *es
= p
+ s
;
138 if ((br
&& *es
!= '}') ||
140 isalpha((unsigned char)*es
))))
143 if (strncmp(bltn
[i
].name
, p
, s
) == 0) {
144 size_t ls
= expand(dp
, execname
, i
, ds
);
166 main(int argc
, char *argv
[])
171 for (i
= 1; i
< argc
; i
++) {
172 char *p
= argv
[i
], *ep
= argv
[i
] + strlen(p
);
173 size_t n
= _rtld_expand_path(buf
, sizeof(buf
), argv
[0], p
, ep
);