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 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 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 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 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 * 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 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