xref: /freebsd/contrib/elftoolchain/ar/util.c (revision f94594b37a145b9b3e9ff31af2cd1dc3de8aa4d4)
1*3fe401a5SEd Maste /*-
2*3fe401a5SEd Maste  * Copyright (c) 2003-2007 Tim Kientzle
3*3fe401a5SEd Maste  * All rights reserved.
4*3fe401a5SEd Maste  *
5*3fe401a5SEd Maste  * Redistribution and use in source and binary forms, with or without
6*3fe401a5SEd Maste  * modification, are permitted provided that the following conditions
7*3fe401a5SEd Maste  * are met:
8*3fe401a5SEd Maste  * 1. Redistributions of source code must retain the above copyright
9*3fe401a5SEd Maste  *    notice, this list of conditions and the following disclaimer
10*3fe401a5SEd Maste  *    in this position and unchanged.
11*3fe401a5SEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
12*3fe401a5SEd Maste  *    notice, this list of conditions and the following disclaimer in the
13*3fe401a5SEd Maste  *    documentation and/or other materials provided with the distribution.
14*3fe401a5SEd Maste  *
15*3fe401a5SEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16*3fe401a5SEd Maste  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17*3fe401a5SEd Maste  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18*3fe401a5SEd Maste  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19*3fe401a5SEd Maste  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20*3fe401a5SEd Maste  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21*3fe401a5SEd Maste  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22*3fe401a5SEd Maste  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*3fe401a5SEd Maste  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24*3fe401a5SEd Maste  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*3fe401a5SEd Maste  */
26*3fe401a5SEd Maste 
27*3fe401a5SEd Maste #include <sys/queue.h>
28*3fe401a5SEd Maste #include <sys/types.h>
29*3fe401a5SEd Maste #include <sys/stat.h>
30*3fe401a5SEd Maste #include <errno.h>
31*3fe401a5SEd Maste #include <stdarg.h>
32*3fe401a5SEd Maste #include <stdio.h>
33*3fe401a5SEd Maste #include <stdlib.h>
34*3fe401a5SEd Maste #include <stdint.h>
35*3fe401a5SEd Maste #include <string.h>
36*3fe401a5SEd Maste #include <unistd.h>
37*3fe401a5SEd Maste 
38*3fe401a5SEd Maste #include "ar.h"
39*3fe401a5SEd Maste 
40*3fe401a5SEd Maste ELFTC_VCSID("$Id: util.c 3174 2015-03-27 17:13:41Z emaste $");
41*3fe401a5SEd Maste 
42*3fe401a5SEd Maste static void	bsdar_vwarnc(struct bsdar *, int code,
43*3fe401a5SEd Maste 		    const char *fmt, va_list ap);
44*3fe401a5SEd Maste static void	bsdar_verrc(struct bsdar *bsdar, int code,
45*3fe401a5SEd Maste 		    const char *fmt, va_list ap);
46*3fe401a5SEd Maste 
47*3fe401a5SEd Maste static void
bsdar_vwarnc(struct bsdar * bsdar,int code,const char * fmt,va_list ap)48*3fe401a5SEd Maste bsdar_vwarnc(struct bsdar *bsdar, int code, const char *fmt, va_list ap)
49*3fe401a5SEd Maste {
50*3fe401a5SEd Maste 
51*3fe401a5SEd Maste 	fprintf(stderr, "%s: warning: ", bsdar->progname);
52*3fe401a5SEd Maste 	vfprintf(stderr, fmt, ap);
53*3fe401a5SEd Maste 	if (code != 0)
54*3fe401a5SEd Maste 		fprintf(stderr, ": %s", strerror(code));
55*3fe401a5SEd Maste 	fprintf(stderr, "\n");
56*3fe401a5SEd Maste }
57*3fe401a5SEd Maste 
58*3fe401a5SEd Maste void
bsdar_warnc(struct bsdar * bsdar,int code,const char * fmt,...)59*3fe401a5SEd Maste bsdar_warnc(struct bsdar *bsdar, int code, const char *fmt, ...)
60*3fe401a5SEd Maste {
61*3fe401a5SEd Maste 	va_list ap;
62*3fe401a5SEd Maste 
63*3fe401a5SEd Maste 	va_start(ap, fmt);
64*3fe401a5SEd Maste 	bsdar_vwarnc(bsdar, code, fmt, ap);
65*3fe401a5SEd Maste 	va_end(ap);
66*3fe401a5SEd Maste }
67*3fe401a5SEd Maste 
68*3fe401a5SEd Maste static void
bsdar_verrc(struct bsdar * bsdar,int code,const char * fmt,va_list ap)69*3fe401a5SEd Maste bsdar_verrc(struct bsdar *bsdar, int code, const char *fmt, va_list ap)
70*3fe401a5SEd Maste {
71*3fe401a5SEd Maste 
72*3fe401a5SEd Maste 	fprintf(stderr, "%s: fatal: ", bsdar->progname);
73*3fe401a5SEd Maste 	vfprintf(stderr, fmt, ap);
74*3fe401a5SEd Maste 	if (code != 0)
75*3fe401a5SEd Maste 		fprintf(stderr, ": %s", strerror(code));
76*3fe401a5SEd Maste 	fprintf(stderr, "\n");
77*3fe401a5SEd Maste }
78*3fe401a5SEd Maste 
79*3fe401a5SEd Maste void
bsdar_errc(struct bsdar * bsdar,int code,const char * fmt,...)80*3fe401a5SEd Maste bsdar_errc(struct bsdar *bsdar, int code, const char *fmt, ...)
81*3fe401a5SEd Maste {
82*3fe401a5SEd Maste 	va_list ap;
83*3fe401a5SEd Maste 
84*3fe401a5SEd Maste 	va_start(ap, fmt);
85*3fe401a5SEd Maste 	bsdar_verrc(bsdar, code, fmt, ap);
86*3fe401a5SEd Maste 	va_end(ap);
87*3fe401a5SEd Maste 	exit(EXIT_FAILURE);
88*3fe401a5SEd Maste }
89*3fe401a5SEd Maste 
90*3fe401a5SEd Maste #define	AR_STRMODE_SIZE	12
91*3fe401a5SEd Maste const char *
bsdar_strmode(mode_t m)92*3fe401a5SEd Maste bsdar_strmode(mode_t m)
93*3fe401a5SEd Maste {
94*3fe401a5SEd Maste 	static char buf[AR_STRMODE_SIZE];
95*3fe401a5SEd Maste 
96*3fe401a5SEd Maste #if ELFTC_HAVE_STRMODE
97*3fe401a5SEd Maste 	/* Use the system's strmode(3). */
98*3fe401a5SEd Maste 	strmode(m, buf);
99*3fe401a5SEd Maste 	return buf;
100*3fe401a5SEd Maste 
101*3fe401a5SEd Maste #else
102*3fe401a5SEd Maste 	char c;
103*3fe401a5SEd Maste 
104*3fe401a5SEd Maste 	/*
105*3fe401a5SEd Maste 	 * The first character of the string denotes the type of the
106*3fe401a5SEd Maste 	 * entry.
107*3fe401a5SEd Maste 	 */
108*3fe401a5SEd Maste 	if (S_ISBLK(m))
109*3fe401a5SEd Maste 		c = 'b';
110*3fe401a5SEd Maste 	else if (S_ISCHR(m))
111*3fe401a5SEd Maste 		c = 'c';
112*3fe401a5SEd Maste 	else if (S_ISDIR(m))
113*3fe401a5SEd Maste 		c = 'd';
114*3fe401a5SEd Maste #if	defined(S_ISFIFO)
115*3fe401a5SEd Maste 	else if (S_ISFIFO(m))
116*3fe401a5SEd Maste 		c = 'p';
117*3fe401a5SEd Maste #endif
118*3fe401a5SEd Maste #if	defined(S_ISLNK)
119*3fe401a5SEd Maste 	else if (S_ISLNK(m))
120*3fe401a5SEd Maste 		c = 'l';
121*3fe401a5SEd Maste #endif
122*3fe401a5SEd Maste 	else if (S_ISREG(m))
123*3fe401a5SEd Maste 		c = '-';
124*3fe401a5SEd Maste #if	defined(S_ISSOCK)
125*3fe401a5SEd Maste 	else if (S_ISSOCK(m))
126*3fe401a5SEd Maste 		c = 's';
127*3fe401a5SEd Maste #endif
128*3fe401a5SEd Maste 	else
129*3fe401a5SEd Maste 		c = '?';
130*3fe401a5SEd Maste 	buf[0] = c;
131*3fe401a5SEd Maste 
132*3fe401a5SEd Maste 	/* The next 3 characters show permissions for the owner. */
133*3fe401a5SEd Maste 	buf[1] = (m & S_IRUSR) ? 'r' : '-';
134*3fe401a5SEd Maste 	buf[2] = m & S_IWUSR ? 'w' : '-';
135*3fe401a5SEd Maste 	if (m & S_ISUID)
136*3fe401a5SEd Maste 		c = (m & S_IXUSR) ? 's' : 'S';
137*3fe401a5SEd Maste 	else
138*3fe401a5SEd Maste 		c = (m & S_IXUSR) ? 'x' : '-';
139*3fe401a5SEd Maste 	buf[3] = c;
140*3fe401a5SEd Maste 
141*3fe401a5SEd Maste 	/* The next 3 characters describe permissions for the group. */
142*3fe401a5SEd Maste 	buf[4] = (m & S_IRGRP) ? 'r' : '-';
143*3fe401a5SEd Maste 	buf[5] = m & S_IWGRP ? 'w' : '-';
144*3fe401a5SEd Maste 	if (m & S_ISGID)
145*3fe401a5SEd Maste 		c = (m & S_IXGRP) ? 's' : 'S';
146*3fe401a5SEd Maste 	else
147*3fe401a5SEd Maste 		c = (m & S_IXGRP) ? 'x' : '-';
148*3fe401a5SEd Maste 	buf[6] = c;
149*3fe401a5SEd Maste 
150*3fe401a5SEd Maste 
151*3fe401a5SEd Maste 	/* The next 3 characters describe permissions for others. */
152*3fe401a5SEd Maste 	buf[7] = (m & S_IROTH) ? 'r' : '-';
153*3fe401a5SEd Maste 	buf[8] = m & S_IWOTH ? 'w' : '-';
154*3fe401a5SEd Maste 	if (m & S_ISVTX)	/* sticky bit */
155*3fe401a5SEd Maste 		c = (m & S_IXOTH) ? 't' : 'T';
156*3fe401a5SEd Maste 	else
157*3fe401a5SEd Maste 		c = (m & S_IXOTH) ? 'x' : '-';
158*3fe401a5SEd Maste 	buf[9] = c;
159*3fe401a5SEd Maste 
160*3fe401a5SEd Maste 	/* End the string with a blank and NUL-termination. */
161*3fe401a5SEd Maste 	buf[10] = ' ';
162*3fe401a5SEd Maste 	buf[11] = '\0';
163*3fe401a5SEd Maste 
164*3fe401a5SEd Maste 	return buf;
165*3fe401a5SEd Maste #endif	/* !ELTC_HAVE_STRMODE */
166*3fe401a5SEd Maste }
167*3fe401a5SEd Maste 
168*3fe401a5SEd Maste int
bsdar_is_pseudomember(struct bsdar * bsdar,const char * name)169*3fe401a5SEd Maste bsdar_is_pseudomember(struct bsdar *bsdar, const char *name)
170*3fe401a5SEd Maste {
171*3fe401a5SEd Maste 	/*
172*3fe401a5SEd Maste 	 * The "__.SYMDEF" member is special in the BSD format
173*3fe401a5SEd Maste 	 * variant.
174*3fe401a5SEd Maste 	 */
175*3fe401a5SEd Maste 	if (bsdar->options & AR_BSD)
176*3fe401a5SEd Maste 		return (strcmp(name, AR_SYMTAB_NAME_BSD) == 0);
177*3fe401a5SEd Maste 	else
178*3fe401a5SEd Maste 		/*
179*3fe401a5SEd Maste 		 * The names "/ " and "// " are special in the SVR4
180*3fe401a5SEd Maste 		 * variant.
181*3fe401a5SEd Maste 		 */
182*3fe401a5SEd Maste 		return (strcmp(name, AR_STRINGTAB_NAME_SVR4) == 0 ||
183*3fe401a5SEd Maste 		    strcmp(name, AR_SYMTAB_NAME_SVR4) == 0);
184*3fe401a5SEd Maste }
185