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