text: /*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2009 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.0 of the PHP license,       |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_0.txt.                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  |                                                                      |
  |                        **** WARNING ****                             |
  |                                                                      |
  | This module makes use of unRAR - free utility for RAR archives.      |
  | Its license states that you MUST NOT use its code to develop         |
  | a RAR (WinRAR) compatible archiver.                                  |
  | Please, read unRAR license for full information.                     |
  | unRAR & RAR copyrights are owned by Eugene Roshal                    |
  +----------------------------------------------------------------------+
  | Author: Antony Dovgal <tony@daylessday.org>                          |
  | Author: Gustavo Lopes <cataphract@php.net>                           |
  +----------------------------------------------------------------------+
  */
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  #include <php.h>
  #include <zend_exceptions.h>
  #include "php_rar.h"
  
  #if PHP_VERSION_ID >= 70100
  	#define PORT_70_FAKE_SCOPE fake_scope
  #else
  	#define PORT_70_FAKE_SCOPE scope
  #endif
  
  /* {{{ Globals with external linkage */
  zend_class_entry *rarexception_ce_ptr;
  /* }}} */
  
  /* Functions with external linkage {{{ */
  /* Functions with external linkage {{{ */
  int _rar_handle_error(int errcode TSRMLS_DC) /* {{{ */
  {
  	return _rar_handle_error_ex("", errcode TSRMLS_CC);
  }
  /* }}} */
  
  int _rar_handle_error_ex(const char *preamble, int errcode TSRMLS_DC) /* {{{ */
  {
  	const char *err = _rar_error_to_string(errcode);
  
  	if (err == NULL) {
  		return SUCCESS;
  	}
  
  	if (_rar_using_exceptions(TSRMLS_C)) {
  		zend_throw_exception_ex(rarexception_ce_ptr, errcode TSRMLS_CC,
  			"unRAR internal error: %s%s", preamble, err);
  	}
  	else {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s%s", preamble, err);
  	}
  	return FAILURE;
  }
  /* }}} */
  
  /* Errors not related to the unRAR library */
  void _rar_handle_ext_error(const char *format TSRMLS_DC, ...) /* {{{ */
  {
  	va_list arg;
  	char *message;
  
  #if defined(ZTS) && PHP_MAJOR_VERSION < 7
  	va_start(arg, TSRMLS_C);
  #else
  	va_start(arg, format);
  #endif
  	vspprintf(&message, 0, format, arg);
  	va_end(arg);
  
  	if (_rar_using_exceptions(TSRMLS_C))
  		zend_throw_exception(rarexception_ce_ptr, message, -1L TSRMLS_CC);
  	else
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message);
  	efree(message);
  }
  /* }}} */
  
  int _rar_using_exceptions(TSRMLS_D)
  {
  	zval *pval;
  
  	zend_class_entry *old_scope = EG(PORT_70_FAKE_SCOPE);
  	EG(PORT_70_FAKE_SCOPE) = rarexception_ce_ptr;
  
  	pval = zend_read_static_property(rarexception_ce_ptr, "usingExceptions",
  		sizeof("usingExceptions") -1, (zend_bool) 1 TSRMLS_CC);
  
  	EG(PORT_70_FAKE_SCOPE) = old_scope;
  
  #if PHP_MAJOR_VERSION < 7
  	assert(Z_TYPE_P(pval) == IS_BOOL);
  	return Z_BVAL_P(pval);
  #else
  	assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
  	return Z_TYPE_P(pval) == IS_TRUE;
  #endif
  }
  
  /* returns a string or NULL if not an error */
  const char * _rar_error_to_string(int errcode) /* {{{ */
  {
  	const char *ret;
  	switch (errcode) {
  		case 0:
  			/* no error */
  		case 1:
  			/* no error (comment completely read) */
  		case ERAR_END_ARCHIVE:
  			/* no error */
  			ret = NULL;
  			break;
  		case ERAR_NO_MEMORY:
  			ret = "ERAR_NO_MEMORY (not enough memory)";
  			break;
  		case ERAR_BAD_DATA:
  			ret = "ERAR_BAD_DATA";
  			break;
  		case ERAR_BAD_ARCHIVE:
  			ret = "ERAR_BAD_ARCHIVE";
  			break;
  		case ERAR_UNKNOWN_FORMAT:
  			ret = "ERAR_UNKNOWN_FORMAT";
  			break;
  		case ERAR_EOPEN:
  			ret = "ERAR_EOPEN (file open error)";
  			break;
  		case ERAR_ECREATE:
  			ret = "ERAR_ECREATE";
  			break;
  		case ERAR_ECLOSE:
  			ret = "ERAR_ECLOSE (error closing file)";
  			break;
  		case ERAR_EREAD:
  			ret = "ERAR_EREAD";
  			break;
  		case ERAR_EWRITE:
  			ret = "ERAR_EWRITE";
  			break;
  		case ERAR_SMALL_BUF:
  			ret = "ERAR_SMALL_BUF";
  			break;
  		case ERAR_UNKNOWN:
  			ret = "ERAR_UNKNOWN (unknown RAR error)";
  			break;
  		case ERAR_MISSING_PASSWORD:
  			ret = "ERAR_MISSING_PASSWORD (password needed but not specified)";
  			break;
  		default:
  			ret = "unknown RAR error (should not happen)";
  			break;
  	}
  	return ret;
  }
  /* }}} */
  /* }}} */
  
  /* {{{ proto bool RarException::setUsingExceptions(using_exceptions)
     Set whether exceptions are to be used */
  PHP_METHOD(rarexception, setUsingExceptions)
  {
  	zend_bool argval;
  	int result;
  
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &argval) == FAILURE ) {
  		return;
  	}
  
  	result = zend_update_static_property_bool(rarexception_ce_ptr,
  		"usingExceptions", sizeof("usingExceptions") -1,
  		(long) argval TSRMLS_CC);
  
  	if (result == FAILURE) {
  		php_error_docref(NULL TSRMLS_CC, E_WARNING,
  			"Could not set error handling mode. "
  			"This is a bug, please report it.");
  		return;
  	}
  }
  /* }}} */
  
  /* {{{ proto bool RarException::isUsingExceptions()
     Return whether exceptions are being used */
  PHP_METHOD(rarexception, isUsingExceptions)
  {
  #if PHP_MAJOR_VERSION < 7
  	zval **pval;
  #else
  	zval *pval;
  #endif
  
  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE ) {
  		return;
  	}
  
  	/* or zend_read_static_property, which calls zend_std_get... after chg scope */
  #if PHP_VERSION_ID < 50399
  	pval = zend_std_get_static_property(rarexception_ce_ptr, "usingExceptions",
  		sizeof("usingExceptions") -1, (zend_bool) 0 TSRMLS_CC);
  #elif PHP_MAJOR_VERSION < 7
  	pval = zend_std_get_static_property(rarexception_ce_ptr, "usingExceptions",
  		sizeof("usingExceptions") -1, (zend_bool) 0, NULL TSRMLS_CC);
  #else
  	zend_string *prop_name =
  		zend_string_init("usingExceptions", sizeof("usingExceptions") - 1, 0);
  	pval = zend_std_get_static_property(rarexception_ce_ptr, prop_name,
  		(zend_bool) 0);
  	zend_string_release(prop_name);
  #endif
  	/* property always exists */
  	assert(pval != NULL);
  #if PHP_MAJOR_VERSION < 7
  	assert(Z_TYPE_PP(pval) == IS_BOOL);
  	RETURN_ZVAL(*pval, 0, 0);
  #else
  	assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
  	RETURN_ZVAL(pval, 0, 0);
  #endif
  }
  /* }}} */
  
  /* {{{ arginfo */
  ZEND_BEGIN_ARG_INFO_EX(arginfo_rarexception_sue, 0, 0, 1)
  	ZEND_ARG_INFO(0, using_exceptions)
  ZEND_END_ARG_INFO()
  
  ZEND_BEGIN_ARG_INFO(arginfo_rarexception_void, 0)
  ZEND_END_ARG_INFO()
  /* }}} */
  
  static zend_function_entry php_rarexception_class_functions[] = {
  	PHP_ME(rarexception,	setUsingExceptions,	arginfo_rarexception_sue,	ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
  	PHP_ME(rarexception,	isUsingExceptions,	arginfo_rarexception_void,	ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
  	{NULL, NULL, NULL}
  };
  
  void minit_rarerror(TSRMLS_D) /* {{{ */
  {
  	zend_class_entry ce;
  
  	INIT_CLASS_ENTRY(ce, "RarException", php_rarexception_class_functions);
  #if PHP_MAJOR_VERSION < 7
  	rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
  		zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
  #else
  	rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
  		zend_exception_get_default(TSRMLS_C));
  #endif
  	rarexception_ce_ptr->ce_flags |= ZEND_ACC_FINAL;
  	zend_declare_property_bool(rarexception_ce_ptr, "usingExceptions",
  		sizeof("usingExceptions") -1, 0L /* FALSE */,
  		ZEND_ACC_STATIC TSRMLS_CC);
  }
  /* }}} */
  
  #ifdef __cplusplus
  }
  #endif
  