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