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 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "archive_platform.h" 27 __FBSDID("$FreeBSD: src/lib/libarchive/archive_util.c,v 1.18 2008/05/26 17:00:22 kientzle Exp $"); 28 29 #ifdef HAVE_SYS_TYPES_H 30 #include <sys/types.h> 31 #endif 32 #ifdef HAVE_STDLIB_H 33 #include <stdlib.h> 34 #endif 35 #ifdef HAVE_STRING_H 36 #include <string.h> 37 #endif 38 39 #include "archive.h" 40 #include "archive_private.h" 41 #include "archive_string.h" 42 43 #if ARCHIVE_VERSION_NUMBER < 3000000 44 /* These disappear in libarchive 3.0 */ 45 /* Deprecated. */ 46 int 47 archive_api_feature(void) 48 { 49 return (ARCHIVE_API_FEATURE); 50 } 51 52 /* Deprecated. */ 53 int 54 archive_api_version(void) 55 { 56 return (ARCHIVE_API_VERSION); 57 } 58 59 /* Deprecated synonym for archive_version_number() */ 60 int 61 archive_version_stamp(void) 62 { 63 return (archive_version_number()); 64 } 65 66 /* Deprecated synonym for archive_version_string() */ 67 const char * 68 archive_version(void) 69 { 70 return (archive_version_string()); 71 } 72 #endif 73 74 int 75 archive_version_number(void) 76 { 77 return (ARCHIVE_VERSION_NUMBER); 78 } 79 80 const char * 81 archive_version_string(void) 82 { 83 return (ARCHIVE_VERSION_STRING); 84 } 85 86 int 87 archive_errno(struct archive *a) 88 { 89 return (a->archive_error_number); 90 } 91 92 const char * 93 archive_error_string(struct archive *a) 94 { 95 96 if (a->error != NULL && *a->error != '\0') 97 return (a->error); 98 else 99 return ("(Empty error message)"); 100 } 101 102 103 int 104 archive_format(struct archive *a) 105 { 106 return (a->archive_format); 107 } 108 109 const char * 110 archive_format_name(struct archive *a) 111 { 112 return (a->archive_format_name); 113 } 114 115 116 int 117 archive_compression(struct archive *a) 118 { 119 return (a->compression_code); 120 } 121 122 const char * 123 archive_compression_name(struct archive *a) 124 { 125 return (a->compression_name); 126 } 127 128 129 /* 130 * Return a count of the number of compressed bytes processed. 131 */ 132 int64_t 133 archive_position_compressed(struct archive *a) 134 { 135 return (a->raw_position); 136 } 137 138 /* 139 * Return a count of the number of uncompressed bytes processed. 140 */ 141 int64_t 142 archive_position_uncompressed(struct archive *a) 143 { 144 return (a->file_position); 145 } 146 147 void 148 archive_clear_error(struct archive *a) 149 { 150 archive_string_empty(&a->error_string); 151 a->error = NULL; 152 } 153 154 void 155 archive_set_error(struct archive *a, int error_number, const char *fmt, ...) 156 { 157 va_list ap; 158 #ifdef HAVE_STRERROR_R 159 char errbuff[512]; 160 #endif 161 char *errp; 162 163 a->archive_error_number = error_number; 164 if (fmt == NULL) { 165 a->error = NULL; 166 return; 167 } 168 169 va_start(ap, fmt); 170 archive_string_vsprintf(&(a->error_string), fmt, ap); 171 if (error_number > 0) { 172 archive_strcat(&(a->error_string), ": "); 173 #ifdef HAVE_STRERROR_R 174 #ifdef STRERROR_R_CHAR_P 175 errp = strerror_r(error_number, errbuff, sizeof(errbuff)); 176 #else 177 strerror_r(error_number, errbuff, sizeof(errbuff)); 178 errp = errbuff; 179 #endif 180 #else 181 /* Note: this is not threadsafe! */ 182 errp = strerror(error_number); 183 #endif 184 archive_strcat(&(a->error_string), errp); 185 } 186 a->error = a->error_string.s; 187 va_end(ap); 188 } 189 190 void 191 archive_copy_error(struct archive *dest, struct archive *src) 192 { 193 dest->archive_error_number = src->archive_error_number; 194 195 archive_string_copy(&dest->error_string, &src->error_string); 196 dest->error = dest->error_string.s; 197 } 198 199 void 200 __archive_errx(int retvalue, const char *msg) 201 { 202 static const char *msg1 = "Fatal Internal Error in libarchive: "; 203 write(2, msg1, strlen(msg1)); 204 write(2, msg, strlen(msg)); 205 write(2, "\n", 1); 206 exit(retvalue); 207 } 208