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