1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm 26228753Smm#include "archive_platform.h" 27229592Smm__FBSDID("$FreeBSD$"); 28228753Smm 29228753Smm#ifdef HAVE_SYS_TYPES_H 30228753Smm#include <sys/types.h> 31228753Smm#endif 32228753Smm 33228753Smm#include <stdio.h> 34228753Smm#ifdef HAVE_STDLIB_H 35228753Smm#include <stdlib.h> 36228753Smm#endif 37228753Smm#ifdef HAVE_STRING_H 38228753Smm#include <string.h> 39228753Smm#endif 40228753Smm#ifdef HAVE_UNISTD_H 41228753Smm#include <unistd.h> 42228753Smm#endif 43228753Smm#if defined(_WIN32) && !defined(__CYGWIN__) 44228753Smm#include <windows.h> 45228753Smm#include <winbase.h> 46228753Smm#endif 47228753Smm 48228753Smm#include "archive_private.h" 49228753Smm 50228753Smmstatic void 51228753Smmerrmsg(const char *m) 52228753Smm{ 53228753Smm size_t s = strlen(m); 54228753Smm ssize_t written; 55228753Smm 56228753Smm while (s > 0) { 57228753Smm written = write(2, m, strlen(m)); 58228753Smm if (written <= 0) 59228753Smm return; 60228753Smm m += written; 61228753Smm s -= written; 62228753Smm } 63228753Smm} 64228753Smm 65228753Smmstatic void 66228753Smmdiediedie(void) 67228753Smm{ 68228753Smm#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG) 69228753Smm /* Cause a breakpoint exception */ 70228753Smm DebugBreak(); 71228753Smm#endif 72228753Smm abort(); /* Terminate the program abnormally. */ 73228753Smm} 74228753Smm 75228753Smmstatic const char * 76228753Smmstate_name(unsigned s) 77228753Smm{ 78228753Smm switch (s) { 79228753Smm case ARCHIVE_STATE_NEW: return ("new"); 80228753Smm case ARCHIVE_STATE_HEADER: return ("header"); 81228753Smm case ARCHIVE_STATE_DATA: return ("data"); 82228753Smm case ARCHIVE_STATE_EOF: return ("eof"); 83228753Smm case ARCHIVE_STATE_CLOSED: return ("closed"); 84228753Smm case ARCHIVE_STATE_FATAL: return ("fatal"); 85228753Smm default: return ("??"); 86228753Smm } 87228753Smm} 88228753Smm 89228753Smm 90228753Smmstatic void 91228753Smmwrite_all_states(unsigned int states) 92228753Smm{ 93228753Smm unsigned int lowbit; 94228753Smm 95228753Smm /* A trick for computing the lowest set bit. */ 96228753Smm while ((lowbit = states & (1 + ~states)) != 0) { 97228753Smm states &= ~lowbit; /* Clear the low bit. */ 98228753Smm errmsg(state_name(lowbit)); 99228753Smm if (states != 0) 100228753Smm errmsg("/"); 101228753Smm } 102228753Smm} 103228753Smm 104228753Smm/* 105228753Smm * Check magic value and current state; bail if it isn't valid. 106228753Smm * 107228753Smm * This is designed to catch serious programming errors that violate 108228753Smm * the libarchive API. 109228753Smm */ 110228753Smmvoid 111228753Smm__archive_check_magic(struct archive *a, unsigned int magic, 112228753Smm unsigned int state, const char *function) 113228753Smm{ 114228753Smm if (a->magic != magic) { 115228753Smm errmsg("INTERNAL ERROR: Function "); 116228753Smm errmsg(function); 117228753Smm errmsg(" invoked with invalid struct archive structure.\n"); 118228753Smm diediedie(); 119228753Smm } 120228753Smm 121228753Smm if (state == ARCHIVE_STATE_ANY) 122228753Smm return; 123228753Smm 124228753Smm if ((a->state & state) == 0) { 125228753Smm errmsg("INTERNAL ERROR: Function '"); 126228753Smm errmsg(function); 127228753Smm errmsg("' invoked with archive structure in state '"); 128228753Smm write_all_states(a->state); 129228753Smm errmsg("', should be in state '"); 130228753Smm write_all_states(state); 131228753Smm errmsg("'\n"); 132228753Smm diediedie(); 133228753Smm } 134228753Smm} 135