diff --git a/config/pcksources.cfg b/config/pcksources.cfg new file mode 100644 index 00000000..fb82c022 --- /dev/null +++ b/config/pcksources.cfg @@ -0,0 +1,3 @@ +// list of package source servers (only add servers you trust!) + +addpckserver de582.ispfr.net/cube/ diff --git a/source/codeblocks/AssaultCube.cbp b/source/codeblocks/AssaultCube.cbp index 46522317..d29da961 100644 --- a/source/codeblocks/AssaultCube.cbp +++ b/source/codeblocks/AssaultCube.cbp @@ -65,6 +65,7 @@ + diff --git a/source/include/curl/curl.h b/source/include/curl/curl.h new file mode 100644 index 00000000..ccc3ff63 --- /dev/null +++ b/source/include/curl/curl.h @@ -0,0 +1,1757 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: curl.h,v 1.331 2007-10-15 18:32:01 patrickm Exp $ + ***************************************************************************/ + +/* If you have problems, all libcurl docs and details are found here: + http://curl.haxx.se/libcurl/ +*/ + +#include "curlver.h" /* the libcurl version defines */ + +#include +#include + +/* The include stuff here below is mainly for time_t! */ +#ifdef vms +# include +# include +#else +# include +# include +#endif /* defined (vms) */ + +typedef void CURL; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Decorate exportable functions for Win32 DLL linking. + * This avoids using a .def file for building libcurl.dll. + */ +#if (defined(WIN32) || defined(_WIN32)) && !defined(CURL_STATICLIB) +#if defined(BUILDING_LIBCURL) +#define CURL_EXTERN __declspec(dllexport) +#else +#define CURL_EXTERN __declspec(dllimport) +#endif +#else + +#ifdef CURL_HIDDEN_SYMBOLS +/* + * This definition is used to make external definitions visibile in the + * shared library when symbols are hidden by default. It makes no + * difference when compiling applications whether this is set or not, + * only when compiling the library. + */ +#define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +#define CURL_EXTERN +#endif +#endif + +/* + * We want the typedef curl_off_t setup for large file support on all + * platforms. We also provide a CURL_FORMAT_OFF_T define to use in *printf + * format strings when outputting a variable of type curl_off_t. + * + * Note: "pocc -Ze" is MSVC compatibily mode and this sets _MSC_VER! + */ + +#if (defined(_MSC_VER) && !defined(__POCC__)) || (defined(__LCC__) && defined(WIN32)) +/* MSVC */ +#ifdef _WIN32_WCE + typedef long curl_off_t; +#define CURL_FORMAT_OFF_T "%ld" +#else + typedef signed __int64 curl_off_t; +#define CURL_FORMAT_OFF_T "%I64d" +#endif +#else /* (_MSC_VER && !__POCC__) || (__LCC__ && WIN32) */ +#if (defined(__GNUC__) && defined(WIN32)) || defined(__WATCOMC__) +/* gcc on windows or Watcom */ + typedef long long curl_off_t; +#define CURL_FORMAT_OFF_T "%I64d" +#else /* GCC or Watcom on Windows */ +#if defined(__ILEC400__) +/* OS400 C compiler. */ + typedef long long curl_off_t; +#define CURL_FORMAT_OFF_T "%lld" +#else /* OS400 C compiler. */ + +/* "normal" POSIX approach, do note that this does not necessarily mean that + the type is >32 bits, see the SIZEOF_CURL_OFF_T define for that! */ + typedef off_t curl_off_t; + +/* Check a range of defines to detect large file support. On Linux it seems + none of these are set by default, so if you don't explicitly switches on + large file support, this define will be made for "small file" support. */ +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 0 /* to prevent warnings in the check below */ +#define UNDEF_FILE_OFFSET_BITS +#endif +#ifndef FILESIZEBITS +#define FILESIZEBITS 0 /* to prevent warnings in the check below */ +#define UNDEF_FILESIZEBITS +#endif + +#if defined(_LARGE_FILES) || (_FILE_OFFSET_BITS > 32) || (FILESIZEBITS > 32) \ + || defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) + /* For now, we assume at least one of these to be set for large files to + work! */ +#define CURL_FORMAT_OFF_T "%lld" +#else /* LARGE_FILE support */ +#define CURL_FORMAT_OFF_T "%ld" +#endif +#endif /* OS400 C compiler. */ +#endif /* GCC or Watcom on Windows */ +#endif /* (_MSC_VER && !__POCC__) || (__LCC__ && WIN32) */ + +#ifdef UNDEF_FILE_OFFSET_BITS +/* this was defined above for our checks, undefine it again */ +#undef _FILE_OFFSET_BITS +#endif + +#ifdef UNDEF_FILESIZEBITS +/* this was defined above for our checks, undefine it again */ +#undef FILESIZEBITS +#endif + +#if defined(_WIN32) && !defined(WIN32) +/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we + make this adjustment to catch this. */ +#define WIN32 1 +#endif + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \ + !defined(__CYGWIN__) || defined(__MINGW32__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#else + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on system that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || defined(__minix) +#include +#endif + +#ifndef _WIN32_WCE +#include +#endif +#ifndef __WATCOMC__ +#include +#endif +#include +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#ifdef WIN32 +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ +// 2011nov05: flowtron +// avoid conflict with /usr/include/unistd.h (l.275ff here) +// typedef __socklen_t socklen_t; +#ifndef __socklen_t_defined +typedef int socklen_t; +// original line was: +//typedef int socklen_t; +#endif + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist* contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ +#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ +#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ +#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer + do not free in formfree */ +#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer + do not free in formfree */ +#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */ +#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */ + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ +}; + +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + socklen_t addrlen; + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +#ifndef CURL_NO_OLDIES + /* not used since 7.10.8, will be removed in a future release */ +typedef int (*curl_passwd_callback)(void *clientp, + const char *prompt, + char *buffer, + int buflen); +#endif + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_OBSOLETE4, /* 4 - NOT USED */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_OBSOLETE10, /* 10 - NOT USED */ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_OBSOLETE12, /* 12 - NOT USED */ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_OBSOLETE16, /* 16 - NOT USED */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - could open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* noone should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_OBSOLETE4 + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, + CURLPROXY_SOCKS4 = 4, + CURLPROXY_SOCKS5 = 5 +} curl_proxytype; + +#define CURLAUTH_NONE 0 /* nothing */ +#define CURLAUTH_BASIC (1<<0) /* Basic (default) */ +#define CURLAUTH_DIGEST (1<<1) /* Digest */ +#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ +#define CURLAUTH_NTLM (1<<3) /* NTLM */ +#define CURLAUTH_ANY ~0 /* all types set */ +#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURL_ERROR_SIZE 256 + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif +/* + * Figure out if we can use the ## operator, which is supported by ISO/ANSI C + * and C++. Some compilers support it without setting __STDC__ or __cplusplus + * so we need to carefully check for them too. We don't use configure-checks + * for these since we want these headers to remain generic and working for all + * platforms. + */ +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +#ifdef CURL_ISOCPP +#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(FILE, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, OBJECTPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, OBJECTPOINT, 4), + + /* "name:password" to use when fetching. */ + CINIT(USERPWD, OBJECTPOINT, 5), + + /* "name:password" to use with proxy. */ + CINIT(PROXYUSERPWD, OBJECTPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, OBJECTPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(INFILE, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was succcessful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referer page (needed by some CGIs) */ + CINIT(REFERER, OBJECTPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, OBJECTPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, OBJECTPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, OBJECTPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct HttpPost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, OBJECTPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, OBJECTPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(WRITEHEADER, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, OBJECTPOINT, 31), + + /* What version to specifly try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), + + /* HTTP request, for odd commands like DELETE, TRACE and others */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + /* Pass a pointer to string of the output using full variable-replacement + as described elsewhere. */ + CINIT(WRITEINFO, OBJECTPOINT, 40), + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* return bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the progress callback */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), + + /* We want the referer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, OBJECTPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, OBJECTPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, OBJECTPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + /* What policy to use when closing connections when the cache is filled + up */ + CINIT(CLOSEPOLICY, LONG, 72), + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, OBJECTPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, OBJECTPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects + are OK within this time, then fine... This only aborts the connect + phase. [Only works on unix-style/SIGALRM operating systems] */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, OBJECTPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specificly switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, OBJECTPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, OBJECTPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, OBJECTPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, OBJECTPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands (Wesley Laxton)*/ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, OBJECTPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_SOCKS4 and CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. */ + CINIT(ENCODING, OBJECTPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentionally send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specificly switch on or off the FTP engine's use of the EPRT command ( it + also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, OBJECTPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise + CURLFTPSSL_CONTROL - SSL for the control connection or fail + CURLFTPSSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), + + /* feed cookies into cookie engine */ + CINIT(COOKIELIST, OBJECTPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the appliction even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Obey RFC 2616/10.3.2 and keep POSTs as POSTs after a 301 */ + CINIT(POST301, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_WRITEDATA CURLOPT_FILE +#define CURLOPT_READDATA CURLOPT_INFILE +#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + +#ifdef __BEOS__ +#include +#endif + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details */ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CURLFORM_LASTENTRY /* the last unusued */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanved function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 30 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internaly to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + +typedef void CURLSH; + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* out of memory */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify shich data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basicly all programs ever, that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ +#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ +#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ +#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ +#define CURL_VERSION_CONV (1<<12) /* character conversions are + supported */ + +/* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +#endif /* __CURL_CURL_H */ diff --git a/source/include/curl/curlver.h b/source/include/curl/curlver.h new file mode 100644 index 00000000..8aaca7b0 --- /dev/null +++ b/source/include/curl/curlver.h @@ -0,0 +1,67 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: curlver.h,v 1.32 2007-09-13 21:06:19 bagder Exp $ + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.17.1" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 17 +#define LIBCURL_VERSION_PATCH 1 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. +*/ +#define LIBCURL_VERSION_NUM 0x071101 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in CVS, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "Mon Oct 29 14:49:22 UTC 2007" + +#endif /* __CURL_CURLVER_H */ diff --git a/source/include/curl/easy.h b/source/include/curl/easy.h new file mode 100644 index 00000000..b5867200 --- /dev/null +++ b/source/include/curl/easy.h @@ -0,0 +1,81 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: easy.h,v 1.13 2004/11/09 14:02:58 giva Exp $ + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistant connections cannot + * be transfered. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/include/curl/mprintf.h b/source/include/curl/mprintf.h new file mode 100644 index 00000000..cf265232 --- /dev/null +++ b/source/include/curl/mprintf.h @@ -0,0 +1,80 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: mprintf.h,v 1.15 2007-08-07 12:44:38 patrickm Exp $ + ***************************************************************************/ + +#include +#include /* needed for FILE */ + +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef _MPRINTF_REPLACE +# undef printf +# undef fprintf +# undef sprintf +# undef vsprintf +# undef snprintf +# undef vprintf +# undef vfprintf +# undef vsnprintf +# undef aprintf +# undef vaprintf +# define printf curl_mprintf +# define fprintf curl_mfprintf +#ifdef CURLDEBUG +/* When built with CURLDEBUG we define away the sprintf() functions since we + don't want internal code to be using them */ +# define sprintf sprintf_was_used +# define vsprintf vsprintf_was_used +#else +# define sprintf curl_msprintf +# define vsprintf curl_mvsprintf +#endif +# define snprintf curl_msnprintf +# define vprintf curl_mvprintf +# define vfprintf curl_mvfprintf +# define vsnprintf curl_mvsnprintf +# define aprintf curl_maprintf +# define vaprintf curl_mvaprintf +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/source/include/curl/multi.h b/source/include/curl/multi.h new file mode 100644 index 00000000..eada5e7a --- /dev/null +++ b/source/include/curl/multi.h @@ -0,0 +1,346 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: multi.h,v 1.44 2007-05-30 20:04:44 bagder Exp $ + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void CURLM; + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,number) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + number +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/source/include/curl/stdcheaders.h b/source/include/curl/stdcheaders.h new file mode 100644 index 00000000..024413ac --- /dev/null +++ b/source/include/curl/stdcheaders.h @@ -0,0 +1,34 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: stdcheaders.h,v 1.8 2004/01/07 09:19:34 bagder Exp $ + ***************************************************************************/ + +#include + +size_t fread (void *, size_t, size_t, FILE *); +size_t fwrite (const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif diff --git a/source/include/curl/types.h b/source/include/curl/types.h new file mode 100644 index 00000000..d37d6ae9 --- /dev/null +++ b/source/include/curl/types.h @@ -0,0 +1 @@ +/* not used */ diff --git a/source/lib/libcurl.lib b/source/lib/libcurl.lib new file mode 100644 index 00000000..6008097d Binary files /dev/null and b/source/lib/libcurl.lib differ diff --git a/source/lib/winmm.lib b/source/lib/winmm.lib new file mode 100644 index 00000000..32abfa30 Binary files /dev/null and b/source/lib/winmm.lib differ diff --git a/source/lib/wldap32.lib b/source/lib/wldap32.lib new file mode 100644 index 00000000..584eb313 Binary files /dev/null and b/source/lib/wldap32.lib differ diff --git a/source/lib/ws2_32.lib b/source/lib/ws2_32.lib new file mode 100644 index 00000000..03ee176f Binary files /dev/null and b/source/lib/ws2_32.lib differ diff --git a/source/src/Makefile b/source/src/Makefile index 933e20b4..37312112 100644 --- a/source/src/Makefile +++ b/source/src/Makefile @@ -17,12 +17,12 @@ MV=mv ifneq (,$(findstring MINGW,$(PLATFORM))) WINDRES= windres CLIENT_INCLUDES= $(INCLUDES) -I../include -CLIENT_LIBS= -mwindows -L../lib -lSDL -lSDL_image -lzdll -lopengl32 -lenet -lOpenAL32 -llibvorbisfile -llibintl -lws2_32 -lwinmm +CLIENT_LIBS= -mwindows -L../lib -lSDL -lSDL_image -lzdll -lopengl32 -lenet -lOpenAL32 -llibvorbisfile -llibintl -lws2_32 -lwinmm -lcurl else USRLIB=$(shell if [ -e /usr/lib64 ]; then echo "/usr/lib64"; else echo "/usr/lib"; fi) override CXXFLAGS+= -rdynamic CLIENT_INCLUDES= $(INCLUDES) -I/usr/include `sdl-config --cflags` -idirafter ../include -CLIENT_LIBS= -L../enet/.libs -lenet -L$(USRLIB) -lX11 `sdl-config --libs` -lSDL_image -lz -lGL -lopenal -lvorbisfile +CLIENT_LIBS= -L../enet/.libs -lenet -L$(USRLIB) -lX11 `sdl-config --libs` -lSDL_image -lz -lGL -lopenal -lvorbisfile -lcurl endif CLIENT_OBJS= \ @@ -157,12 +157,11 @@ else client: libenet $(CLIENT_OBJS) $(CXX) $(CXXFLAGS) -o ac_client $(CLIENT_OBJS) $(CLIENT_LIBS) +server: libenet $(SERVER_OBJS) server: libenet $(SERVER_OBJS) $(CXX) $(CXXFLAGS) -o ac_server $(SERVER_OBJS) $(SERVER_LIBS) master: libenet $(MASTER_OBJS) - $(CXX) $(CXXFLAGS) -o ac_master $(MASTER_OBJS) $(SERVER_LIBS) - -client_install: client + $(CXX) $(CXXFLAGS) -o ac_master $(MASTER_OBJS) $(SERVER_LIBS)client_install: client install -d ../../bin_unix/ install -m755 ac_client ../../bin_unix/$(PLATFORM_PREFIX)_client #ifneq (,$(STRIP)) diff --git a/source/src/audiomanager.cpp b/source/src/audiomanager.cpp index b0122f1c..55514884 100644 --- a/source/src/audiomanager.cpp +++ b/source/src/audiomanager.cpp @@ -225,19 +225,19 @@ int audiomanager::addsound(char *name, int vol, int maxuses, bool loop, vectorload()) conoutf("\f3failed to load sample %s", buf->name); + if(!buf->load(trydl) && !trydl) conoutf("\f3failed to load sample %s", buf->name); } -void audiomanager::preloadmapsounds() +void audiomanager::preloadmapsounds(bool trydl) { loopv(ents) { entity &e = ents[i]; - if(e.type==SOUND) preloadmapsound(e); + if(e.type==SOUND) preloadmapsound(e, trydl); } } diff --git a/source/src/client.cpp b/source/src/client.cpp index 5f89e1a1..7b9dbca6 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -207,13 +207,11 @@ void disconnect(int onlyclean, int async) } #endif if(!onlyclean) localconnect(); - if(identexists("onDisconnect")) { defformatstring(ondisconnect)("onDisconnect %d", -1); execute(ondisconnect); - } -} + }} void trydisconnect() { @@ -788,12 +786,23 @@ void sendmap(char *mapname) conoutf(_("sending map %s to server..."), mapname); } -void getmap() +void getmap(char *name) { - conoutf(_("requesting map from server...")); - packetbuf p(10, ENET_PACKET_FLAG_RELIABLE); - putint(p, SV_RECVMAP); - sendpackettoserv(2, p.finalize()); + if((!name || !*name) + || (connected && !strcmp(name, getclientmap())) ) + { + conoutf(_("requesting map from server...")); + packetbuf p(10, ENET_PACKET_FLAG_RELIABLE); + putint(p, SV_RECVMAP); + sendpackettoserv(2, p.finalize()); + } + else + { + defformatstring(package)("packages/maps/%s.cgz", name); + requirepackage(PCK_MAP, package); + if(downloadpackages()) conoutf("map %s installed successfully", name); + else conoutf("\f3map download failed."); + } } void deleteservermap(char *mapname) @@ -853,7 +862,7 @@ void rewinddemo(int *seconds) } COMMAND(sendmap, "s"); -COMMAND(getmap, ""); +COMMAND(getmap, "s"); COMMAND(deleteservermap, "s"); COMMAND(resetsecuremaps, ""); COMMAND(securemap, "s"); @@ -861,3 +870,201 @@ COMMAND(getdemo, "is"); COMMAND(listdemos, ""); COMMANDN(setmr, setminutesremaining, "i"); COMMANDN(rewind, rewinddemo, "i"); + +// packages auto - downloader + +// arrays +vector pckservers; +hashtable pendingpackages; + +// cubescript + +void resetpckservers() +{ + pckservers.deletecontents(); +} + +void addpckserver(char *addr) +{ + pckserver *srcserver = new pckserver(); + srcserver->addr = newstring(addr); + srcserver->pending = true; + pckservers.add(srcserver); +} + +COMMAND(resetpckservers, ""); +COMMAND(addpckserver, "s"); + +// cURL / Network + +bool havecurl = false, canceldownloads = false; + +void setupcurl() +{ + if(curl_global_init(CURL_GLOBAL_NOTHING)) conoutf(_("\f3could not init cURL, content downloads not available")); + else + { + havecurl = true; + execfile("config/pcksources.cfg"); + } +} + +static size_t write_callback(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + return fwrite(ptr, size, nmemb, stream); +} + +int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +{ + package *pck = (package *)clientp; + loadingscreen(_("downloading...\n%s %.0f/%.0f KB (%.1f%%)\n(ESC to cancel)"), pck->name, dlnow/double(1000.0), dltotal/double(1000.0), dltotal == 0 ? 0 : (dlnow/dltotal * double(100.0))); + if(interceptkey(SDLK_ESCAPE)) + { + canceldownloads = true; + loadingscreen(); + return 1; + } + return 0; +} + +int processdownload(package *pck) +{ + if(!pck->pending) + { + switch(pck->type) + { + case PCK_TEXTURE: case PCK_AUDIO: + { + preparedir(pck->name); + // with textures/sounds, the image/audio file itself is sent. Just need to copy it from the temporary file + if(!copyfile(path("tmp", true), pck->name)) conoutf(_("\f3failed to install %s"), pck->name); + break; + } + + case PCK_MAP: case PCK_MAPMODEL: + { + const char *p = path("tmp", true); + addzip(p, pck->name, NULL, true, pck->type); + break; + } + + case PCK_SKYBOX: + { + const char *p = path("tmp", true); + char *fname = newstring(pck->name), *ls = strrchr(fname, '/'); + if(ls) *ls = '\0'; + addzip(p, fname, NULL, true, pck->type); + break; + } + + default: + conoutf(_("could not install package %s"), pck->name); + break; + } + delfile(path("tmp", true)); + } + return 0; +} + +// download a package +double dlpackage(package *pck) +{ + if(!pck || !pck->source) return false; + FILE *outfile = fopen(path("tmp", true), "wb"); + string req; + sprintf(req, "%s/%s%s", pck->source->addr, pck->name, (pck->type==PCK_MAP || pck->type==PCK_MAPMODEL || pck->type==PCK_SKYBOX) ? ".zip" : ""); + conoutf(_("downloading %s from %s ..."), pck->name, pck->source->addr); + + int result, httpresult = 0; + double dlsize; + pck->curl = curl_easy_init(); + curl_easy_setopt(pck->curl, CURLOPT_URL, req); + curl_easy_setopt(pck->curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(pck->curl, CURLOPT_WRITEDATA, outfile); + curl_easy_setopt(pck->curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(pck->curl, CURLOPT_PROGRESSFUNCTION, progress_callback); + curl_easy_setopt(pck->curl, CURLOPT_PROGRESSDATA, pck); + curl_easy_setopt(pck->curl, CURLOPT_CONNECTTIMEOUT, 10); // generous timeout for Bukz ;) + result = curl_easy_perform(pck->curl); + curl_easy_getinfo(pck->curl, CURLINFO_RESPONSE_CODE, &httpresult); + curl_easy_getinfo(pck->curl, CURLINFO_SIZE_DOWNLOAD, &dlsize); + curl_easy_cleanup(pck->curl); + pck->curl = NULL; + fclose(outfile); + + pck->pending = false; + if(result == CURLE_OPERATION_TIMEDOUT || result == CURLE_COULDNT_RESOLVE_HOST) + { + // mark source unresponsive + pck->source->responsive = false; + conoutf(_("\f3could not connect to %s"), pck->source->addr); + + // try to find another source + pckserver *source = NULL; + loopv(pckservers) if(pckservers[i]->responsive) { source = pckservers[i]; break; } + if(!source) + { + conoutf(_("\f3no more servers to connect to")); + canceldownloads = true; + return 0; + } + + // update all packages + enumerate(pendingpackages, package *, pack, + { + pack->source = source; + }); + + pck->pending = true; + + return dlpackage(pck); // retry current + } + if(!result && httpresult == 200) processdownload(pck); + else if(result == CURLE_ABORTED_BY_CALLBACK) conoutf(_("\f3download cancelled")); + else conoutf(_("\f2request for %s failed (cURL %d, HTTP %d)"), req, result, httpresult); + return (!result && httpresult == 200) ? dlsize : 0; +} + +int downloadpackages() +{ + double total = 0; + enumerate(pendingpackages, package *, pck, + { + if(!canceldownloads) + { + if(connected) c2skeepalive(); // try to avoid time out + total += dlpackage(pck); + } + pendingpackages.remove(pck->name); + delete pck; + }); + canceldownloads = false; + return (int)total; +} + +bool requirepackage(int type, const char *path) +{ + if(!havecurl || canceldownloads || type < 0 || type >= PCK_NUM || pendingpackages.access(path)) return false; + + package *pck = new package; + pck->name = unixpath(newstring(path)); + pck->type = type; + loopv(pckservers) if(pckservers[i]->responsive) { pck->source = pckservers[i]; break; } + if(!pck->source) { conoutf(_("\f3no responsive source server found, can't download")); return false; } + pck->pending = true; + + pendingpackages.access(pck->name, pck); + + return true; +} + + +void writepcksourcecfg() +{ + stream *f = openfile(path("config/pcksources.cfg", true), "w"); + if(!f) return; + f->printf("// list of package source servers (only add servers you trust!)\n"); + loopv(pckservers) f->printf("\naddpckserver %s", pckservers[i]->addr); + f->printf("\n"); + delete f; +} \ No newline at end of file diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 58c3870e..d6a0a84c 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -1111,10 +1111,9 @@ void showmapstats() } COMMAND(showmapstats, ""); -VARP(showmodedescriptions, 0, 1, 1); - -void startmap(const char *name, bool reset) // called just after a map load +VARP(showmodedescriptions, 0, 1, 1);extern bool canceldownloads;void startmap(const char *name, bool reset) // called just after a map load { + canceldownloads = false; copystring(clientmap, name); sendmapidenttoserver = true; // Added by Rick diff --git a/source/src/entity.h b/source/src/entity.h index bee118dd..e8824271 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -648,3 +648,24 @@ inline const char *killmessage(int gun, bool gib = false) return killmessages[gib?1:0][gun]; } + +struct pckserver +{ + char *addr; + bool pending, responsive; + + pckserver() : addr(NULL), pending(false), responsive(true) {} +}; + +enum { PCK_TEXTURE, PCK_SKYBOX, PCK_MAPMODEL, PCK_AUDIO, PCK_MAP, PCK_NUM }; + +struct package +{ + char *name; + int type; + bool pending; + pckserver *source; + CURL *curl; + + package() : name(NULL), type(-1), pending(false), source(NULL), curl(NULL) {} +}; diff --git a/source/src/main.cpp b/source/src/main.cpp index aa44612f..48b6dd6c 100644 --- a/source/src/main.cpp +++ b/source/src/main.cpp @@ -34,6 +34,7 @@ void quit() // normal exit extern void writeinitcfg(); writeinitcfg(); writeservercfg(); + writepcksourcecfg(); if(resetcfg) deletecfg(); else writecfg(); cleanup(NULL); @@ -1125,6 +1126,9 @@ int main(int argc, char **argv) notexture = noworldtexture = textureload("packages/misc/notexture.jpg"); if(!notexture) fatal("could not find core textures (hint: run AssaultCube from the parent of the bin directory)"); + nomodel = loadmodel("misc/gib01", -1); //FIXME: need actual placeholder model + if(!notexture) fatal("could not find core models"); + initlog("console"); per_idents = false; // Main font file, all other font files execute from here. @@ -1202,6 +1206,9 @@ int main(int argc, char **argv) initlog("models"); preload_playermodels(); preload_hudguns(); + initlog("curl"); + setupcurl(); + preload_entmodels(); initlog("docs"); diff --git a/source/src/openal.cpp b/source/src/openal.cpp index a55a9a36..db9505a1 100644 --- a/source/src/openal.cpp +++ b/source/src/openal.cpp @@ -254,7 +254,7 @@ sbuffer::~sbuffer() unload(); } -bool sbuffer::load() +bool sbuffer::load(bool trydl) { if(!name) return false; if(id) return true; @@ -264,79 +264,94 @@ bool sbuffer::load() { const char *exts[] = { "", ".wav", ".ogg" }; string filepath; - loopi(sizeof(exts)/sizeof(exts[0])) + loopk(2) { - formatstring(filepath)("packages/audio/%s%s", name, exts[i]); - stream *f = openfile(path(filepath), "rb"); - if(!f) continue; - - size_t len = strlen(filepath); - if(len >= 4 && !strcasecmp(filepath + len - 4, ".ogg")) + loopi(sizeof(exts)/sizeof(exts[0])) { - OggVorbis_File oggfile; - if(!ov_open_callbacks(f, &oggfile, NULL, 0, oggcallbacks)) + formatstring(filepath)("packages/audio/%s%s", name, exts[i]); + stream *f = openfile(path(filepath), "rb"); + if(!f && k>0 && trydl) // only try donwloading after trying all extensions { - vorbis_info *info = ov_info(&oggfile, -1); + requirepackage(PCK_AUDIO, filepath); + bool skip = false; + loopj(sizeof(exts)/sizeof(exts[0])) if(strstr(name, exts[j])) skip = true; // don't try extensions if name already has a known extension + if(skip) break; + continue; + } + if(!f) continue; - const size_t BUFSIZE = 32*1024; - vector buf; - int bitstream; - long bytes; - - do + size_t len = strlen(filepath); + if(len >= 4 && !strcasecmp(filepath + len - 4, ".ogg")) + { + OggVorbis_File oggfile; + if(!ov_open_callbacks(f, &oggfile, NULL, 0, oggcallbacks)) { - char buffer[BUFSIZE]; - bytes = ov_read(&oggfile, buffer, BUFSIZE, isbigendian(), 2, 1, &bitstream); - loopi(bytes) buf.add(buffer[i]); - } while(bytes > 0); + vorbis_info *info = ov_info(&oggfile, -1); - alBufferData(id, info->channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16, buf.getbuf(), buf.length(), info->rate); - ov_clear(&oggfile); + const size_t BUFSIZE = 32*1024; + vector buf; + int bitstream; + long bytes; + + do + { + char buffer[BUFSIZE]; + bytes = ov_read(&oggfile, buffer, BUFSIZE, isbigendian(), 2, 1, &bitstream); + loopi(bytes) buf.add(buffer[i]); + } while(bytes > 0); + + alBufferData(id, info->channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16, buf.getbuf(), buf.length(), info->rate); + ov_clear(&oggfile); + } + else + { + delete f; + continue; + } } else { + SDL_AudioSpec wavspec; + uint32_t wavlen; + uint8_t *wavbuf; + + if(!SDL_LoadWAV_RW(f->rwops(), 1, &wavspec, &wavbuf, &wavlen)) + { + SDL_ClearError(); + continue; + } + + ALenum format; + switch(wavspec.format) // map wav header to openal format + { + case AUDIO_U8: + case AUDIO_S8: + format = wavspec.channels==2 ? AL_FORMAT_STEREO8 : AL_FORMAT_MONO8; + break; + case AUDIO_U16: + case AUDIO_S16: + format = wavspec.channels==2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; + break; + default: + SDL_FreeWAV(wavbuf); + delete f; + unload(); + return false; + } + + alBufferData(id, format, wavbuf, wavlen, wavspec.freq); + SDL_FreeWAV(wavbuf); delete f; - continue; - } - } - else - { - SDL_AudioSpec wavspec; - uint32_t wavlen; - uint8_t *wavbuf; - if(!SDL_LoadWAV_RW(f->rwops(), 1, &wavspec, &wavbuf, &wavlen)) - { - SDL_ClearError(); - continue; - } - - ALenum format; - switch(wavspec.format) // map wav header to openal format - { - case AUDIO_U8: - case AUDIO_S8: - format = wavspec.channels==2 ? AL_FORMAT_STEREO8 : AL_FORMAT_MONO8; - break; - case AUDIO_U16: - case AUDIO_S16: - format = wavspec.channels==2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; - break; - default: - SDL_FreeWAV(wavbuf); - delete f; + if(ALERR) + { unload(); return false; + }; } - alBufferData(id, format, wavbuf, wavlen, wavspec.freq); - SDL_FreeWAV(wavbuf); - delete f; - - if(ALERR) break; + return true; } - - return true; } } unload(); // loading failed diff --git a/source/src/platform.h b/source/src/platform.h index 0c9f79aa..89f5e09c 100644 --- a/source/src/platform.h +++ b/source/src/platform.h @@ -71,3 +71,8 @@ #include #endif + +#ifndef CURL_STATICLIB +#define CURL_STATICLIB +#endif +#include "curl/curl.h" diff --git a/source/src/protos.h b/source/src/protos.h index b8673487..ae5b45d1 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -312,20 +312,26 @@ extern SDL_Surface *creatergbsurface(int width, int height); extern SDL_Surface *creatergbasurface(int width, int height); extern SDL_Surface *forcergbsurface(SDL_Surface *os); extern SDL_Surface *forcergbasurface(SDL_Surface *os); -extern Texture *textureload(const char *name, int clamp = 0, bool mipmap = true, bool canreduce = false, float scale = 1.0f); -extern Texture *lookuptexture(int tex, Texture *failtex = notexture); +extern Texture *textureload(const char *name, int clamp = 0, bool mipmap = true, bool canreduce = false, float scale = 1.0f, bool trydl = false); +extern Texture *lookuptexture(int tex, Texture *failtex = notexture, bool trydl = false); extern bool reloadtexture(Texture &t); extern bool reloadtexture(const char *name); extern void reloadtextures(); Texture *createtexturefromsurface(const char *name, SDL_Surface *s); extern void blitsurface(SDL_Surface *dst, SDL_Surface *src, int x, int y); +void loadsky(char *basename, bool reload); -static inline Texture *lookupworldtexture(int tex) -{ return lookuptexture(tex, noworldtexture); } +static inline Texture *lookupworldtexture(int tex, bool trydl = true) +{ return lookuptexture(tex, noworldtexture, trydl); } extern float skyfloor; extern void draw_envbox(int fogdist); +extern void setupcurl(); +extern bool requirepackage(int type, const char *path); +extern int downloadpackages(); +extern void writepcksourcecfg(); + extern int maxtmus; extern void inittmus(); extern void resettmu(int n); @@ -369,7 +375,7 @@ extern void c2skeepalive(); extern void neterr(const char *s); extern int getclientnum(); extern void changeteam(int team, bool respawn = true); // deprecated? -extern void getmap(); +extern void getmap(char *name = NULL); extern void newteam(char *name); extern bool securemapcheck(const char *map, bool msg = true); extern int getbuildtype(); @@ -705,11 +711,12 @@ extern void clearmodelbatches(); extern mapmodelinfo &getmminfo(int i); extern int findanim(const char *name); extern void loadskin(const char *dir, const char *altdir, Texture *&skin); -extern model *loadmodel(const char *name, int i = -1); +extern model *nomodel; +extern model *loadmodel(const char *name, int i = -1, bool trydl = false); extern void preload_playermodels(); extern void preload_entmodels(); extern void preload_hudguns(); -extern void preload_mapmodels(); +extern void preload_mapmodels(bool trydl = false); extern void renderclients(); extern void renderclient(playerent *d); extern void renderclient(playerent *d, const char *mdlname, const char *vwepname, int tex = 0); diff --git a/source/src/rendermodel.cpp b/source/src/rendermodel.cpp index 90416e93..671bb3d2 100644 --- a/source/src/rendermodel.cpp +++ b/source/src/rendermodel.cpp @@ -94,6 +94,7 @@ void mapmodel(int *rad, int *h, int *zoff, char *snap, char *name) mmi.rad = *rad; mmi.h = *h; mmi.zoff = *zoff; + mmi.m = NULL; formatstring(mmi.name)("mapmodels/%s", name); } @@ -110,7 +111,7 @@ COMMAND(mapmodelreset, ""); hashtable mdllookup; model *nomodel = NULL; -model *loadmodel(const char *name, int i) +model *loadmodel(const char *name, int i, bool trydl) { if(!name) { @@ -136,15 +137,28 @@ model *loadmodel(const char *name, int i) { delete m; loadingmodel = NULL; + if(trydl) + { + defformatstring(dl)("packages/models/%s", name); + requirepackage(PCK_MAPMODEL, dl); + } + else + { + mdllookup.access(newstring(name), nomodel); + conoutf("\f3failed to load model %s", name); + } } } popscontext(); if(!loadingmodel) { - conoutf(_("failed to load model %s"), name); - if(!nomodel) nomodel = new md2("nomodel"); - m = nomodel; - mdllookup.access(newstring(name), m); + if(!trydl) + { + conoutf(_("failed to load model %s"), name); + if(!nomodel) nomodel = new md2("nomodel"); + m = nomodel; + mdllookup.access(newstring(name), m); + } } else mdllookup.access(m->name(), m); loadingmodel = NULL; @@ -550,14 +564,14 @@ void preload_entmodels() } } -void preload_mapmodels() +void preload_mapmodels(bool trydl) { loopv(ents) { entity &e = ents[i]; if(e.type!=MAPMODEL || !mapmodels.inrange(e.attr2)) continue; - if(!loadmodel(NULL, e.attr2)) continue; - if(e.attr4) lookuptexture(e.attr4); + loadmodel(NULL, e.attr2, trydl); + if(e.attr4) lookuptexture(e.attr4, notexture, trydl); } } diff --git a/source/src/sound.h b/source/src/sound.h index c277bca2..6dce0ce5 100644 --- a/source/src/sound.h +++ b/source/src/sound.h @@ -160,7 +160,7 @@ public: sbuffer(); ~sbuffer(); - bool load(); + bool load(bool trydl = false); void unload(); }; @@ -389,8 +389,8 @@ public: // init & setup void initsound(); - void preloadmapsound(entity &e); - void preloadmapsounds(); + void preloadmapsound(entity &e, bool trydl = false); + void preloadmapsounds(bool trydl = false); void applymapsoundchanges(); // configuration diff --git a/source/src/stream.cpp b/source/src/stream.cpp index 1e326b32..8658ca7f 100644 --- a/source/src/stream.cpp +++ b/source/src/stream.cpp @@ -74,6 +74,12 @@ char *path(char *s) return s; } +char *unixpath(char *s) +{ + for(char *t = s; (t = strchr(t, '\\')); *t++ = '/'); + return s; +} + char *path(const char *s, bool copy) { static string tmp; @@ -304,6 +310,38 @@ bool delfile(const char *path) return !remove(path); } +bool copyfile(const char *source, const char *destination) +{ + FILE *from = fopen(source, "rb"); + FILE *dest = fopen(destination, "wb"); + + if(!from || !dest) return false; + size_t len; + uchar buf[1024]; + while((len = fread(&buf, sizeof(uchar), 1024, from))) + { + fwrite(&buf, sizeof(uchar), len, dest); + } + fclose(from); + fclose(dest); + return true; +} + +bool preparedir(const char *destination) +{ + string dir; + copystring(dir, parentdir(destination)); + vector dirs; + while(!fileexists(dir, "r")) + { + dirs.add(newstring(dir)); + copystring(dir, parentdir(dir)); + } + + loopvrev(dirs) if(!createdir(dirs[i])) return false; + return true; +} + #ifndef STANDALONE static int rwopsseek(SDL_RWops *rw, int offset, int whence) { diff --git a/source/src/texture.cpp b/source/src/texture.cpp index e468fc8e..59630518 100644 --- a/source/src/texture.cpp +++ b/source/src/texture.cpp @@ -354,7 +354,7 @@ bool silent_texture_load = false; VARFP(hirestextures, 0, 1, 1, initwarning("texture resolution", INIT_LOAD)); bool uniformtexres = !hirestextures; -GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp = 0, bool mipmap = true, bool canreduce = false, float scale = 1.0f) +GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp = 0, bool mipmap = true, bool canreduce = false, float scale = 1.0f, bool trydl = false) { const char *file = texname; if(texname[0]=='<') @@ -377,6 +377,11 @@ GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp = delete z; } if(!s) s = IMG_Load(findfile(file, "rb")); + if(!s && trydl) + { + requirepackage(PCK_TEXTURE, file); + return 0; + } if(!s) { if(!silent_texture_load) conoutf("couldn't load texture %s", texname); return 0; } s = fixsurfaceformat(s); Uint8 x = 0; @@ -420,7 +425,7 @@ GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp = // each texture slot can have multiple texture frames, of which currently only the first is used // additional frames can be used for various shaders -Texture *textureload(const char *name, int clamp, bool mipmap, bool canreduce, float scale) +Texture *textureload(const char *name, int clamp, bool mipmap, bool canreduce, float scale, bool trydl) { string pname; copystring(pname, name); @@ -428,7 +433,7 @@ Texture *textureload(const char *name, int clamp, bool mipmap, bool canreduce, f Texture *t = textures.access(pname); if(t) return t; int xs, ys, bpp; - GLuint id = loadsurface(pname, xs, ys, bpp, clamp, mipmap, canreduce, scale); + GLuint id = loadsurface(pname, xs, ys, bpp, clamp, mipmap, canreduce, scale, trydl); if(!id) return notexture; char *key = newstring(pname); t = &textures[key]; @@ -497,7 +502,7 @@ void texture(char *scale, char *name) COMMAND(texturereset, ""); COMMAND(texture, "fs"); -Texture *lookuptexture(int tex, Texture *failtex) +Texture *lookuptexture(int tex, Texture *failtex, bool trydl) { Texture *t = failtex; if(slots.inrange(tex)) @@ -506,10 +511,13 @@ Texture *lookuptexture(int tex, Texture *failtex) if(!s.loaded) { defformatstring(pname)("packages/textures/%s", s.name); - s.tex = textureload(pname, 0, true, true, s.scale); + s.tex = textureload(pname, 0, true, true, s.scale, trydl); + if(!trydl) + { if(s.tex==notexture) s.tex = failtex; s.loaded = true; } + } if(s.tex) t = s.tex; } return t; @@ -546,20 +554,27 @@ void reloadtextures() } Texture *sky[6] = {NULL, NULL, NULL, NULL, NULL, NULL}; +static string skybox; -void loadsky(char *basename) +void loadsky(char *basename, bool reload) { const char *side[] = { "lf", "rt", "ft", "bk", "dn", "up" }; + if(reload) basename = skybox; + else copystring(skybox, basename); loopi(6) { defformatstring(name)("packages/%s_%s.jpg", basename, side[i]); sky[i] = textureload(name, 3); - if(!sky[i]) conoutf("could not load sky texture: %s", name); + if(sky[i] == notexture && !reload) + { + defformatstring(dl)("packages/%s", basename); + requirepackage(PCK_SKYBOX, dl); + break; + } } } -COMMAND(loadsky, "s"); - +COMMANDF(loadsky, "s", (char *name) { loadsky(name, false); intret(0); }); void loadnotexture(char *c) { noworldtexture = notexture; // reset to default diff --git a/source/src/tools.cpp b/source/src/tools.cpp index 0a02819e..a65c4628 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -45,20 +45,16 @@ mapstats *loadmapstats(const char *filename, bool getlayout) stream *f = opengzfile(filename, "rb"); if(!f) return NULL; memset(&s.hdr, 0, sizeof(header)); - if(f->read(&s.hdr, sizeof(header)-sizeof(int)*16-sizeof(char)*128)!=sizeof(header)-sizeof(int)*16-sizeof(char)*128 || (strncmp(s.hdr.head, "CUBE", 4) && strncmp(s.hdr.head, "ACMP",4))) { delete f; return NULL; } + if(f->read(&s.hdr, sizeof(header)-sizeof(int)*16)!=sizeof(header)-sizeof(int)*16 || (strncmp(s.hdr.head, "CUBE", 4) && strncmp(s.hdr.head, "ACMP",4))) { delete f; return NULL; } lilswap(&s.hdr.version, 4); if(s.hdr.version>MAPVERSION || s.hdr.numents > MAXENTITIES || (s.hdr.version>=4 && f->read(&s.hdr.waterlevel, sizeof(int)*16)!=sizeof(int)*16)) { delete f; return NULL; } - if(s.hdr.version>=7 && f->read(&s.hdr.mediareq, sizeof(char)*128)!=sizeof(char)*128) { delete f; return NULL; } + if((s.hdr.version==7 || s.hdr.version==8) && !f->seek(sizeof(char)*128, SEEK_CUR)) { delete f; return NULL; } if(s.hdr.version>=4) { lilswap(&s.hdr.waterlevel, 1); lilswap(&s.hdr.maprevision, 2); } else s.hdr.waterlevel = -100000; - if(s.hdr.version<7) - { - copystring(s.hdr.mediareq, "", 128);//s.hdr.mediareq[0] = '\0'; - } entity e; enttypes = new uchar[s.hdr.numents]; entposs = new short[s.hdr.numents * 3]; diff --git a/source/src/tools.h b/source/src/tools.h index ae21df25..0fe897cf 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -897,6 +897,7 @@ extern const char *asctime(); extern const char *numtime(); extern char *path(char *s); extern char *path(const char *s, bool copy); +extern char *unixpath(char *s); extern const char *behindpath(const char *s); extern const char *parentdir(const char *directory); extern bool fileexists(const char *path, const char *mode); @@ -916,6 +917,10 @@ extern bool listdir(const char *dir, const char *ext, vector &files); extern int listfiles(const char *dir, const char *ext, vector &files); extern int listzipfiles(const char *dir, const char *ext, vector &files); extern bool delfile(const char *path); +extern bool copyfile(const char *source, const char *destination); +extern bool preparedir(const char *destination); +extern bool addzip(const char *name, const char *mount = NULL, const char *strip = NULL, bool extract = false, int type = -1); +extern bool removezip(const char *name); extern struct mapstats *loadmapstats(const char *filename, bool getlayout); extern bool cmpb(void *b, int n, enet_uint32 c); extern bool cmpf(char *fn, enet_uint32 c); diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 61599485..96abd6fa 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -1701,6 +1701,4 @@ void checkweaponstate() { checkweaponswitch(); checkakimbo(); - - // TODO : here we need to check properly that the spectated player weapon has finished to reload... -} +} \ No newline at end of file diff --git a/source/src/world.cpp b/source/src/world.cpp index d2582605..c272a452 100644 --- a/source/src/world.cpp +++ b/source/src/world.cpp @@ -499,7 +499,6 @@ bool empty_world(int factor, bool force) // main empty world creation routine else { copystring(hdr.maptitle, "Untitled Map by Unknown", 128); - copystring(hdr.mediareq, "", 128); // MediaPack hdr.waterlevel = -100000; hdr.ambient = 0; setwatercolor(); diff --git a/source/src/world.h b/source/src/world.h index 67a7472a..41e819ac 100644 --- a/source/src/world.h +++ b/source/src/world.h @@ -32,7 +32,7 @@ enum // hardcoded texture numbers DEFAULT_CEIL }; -#define MAPVERSION 8 // bump if map format changes, see worldio.cpp +#define MAPVERSION 9 // bump if map format changes, see worldio.cpp struct header // map file format header { @@ -48,7 +48,7 @@ struct header // map file format header int maprevision; int ambient; int reserved[12]; - char mediareq[128]; // new since version 7 (flowtron) // actually a maximum of 124 will ever be used (24*5+4) + //char mediareq[128]; // version 7 and 8 only. }; struct mapstats diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index 4c2d65b9..90c00fb4 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -11,7 +11,6 @@ void backup(char *name, char *backupname) } static string cgzname, ocgzname, bakname, pcfname, mcfname, omcfname; -static string reqmpak; // required media pack const char *setnames(const char *name) { @@ -200,184 +199,6 @@ uchar *readmcfggz(char *name, int *size, int *sizegz) VAR(advancemaprevision, 1, 1, 100); -void checkmapdependencies(bool silent = false, bool details = false) // find required MediaPack (s) for current map -{ - if(!silent) conoutf("checking map dependencies"); - static hashtable mufpaths; - hashtable usedmods; - string goodname, modname, allmods; - // well, the "goodname" can still contain the users home-dir - #define USEFILENAME(fmtp2f,fname,count) \ - { \ - defformatstring(basename)(fmtp2f, fname); \ - copystring(goodname, findfile(path(basename), "r")); \ - int *n = mufpaths.access(goodname); \ - if(!n) { n = &mufpaths.access(newstring(goodname), -1); if(fileexists(goodname, "r")) *n = 0; } \ - if(*n >= 0) *n += count; \ - const char *pt = strstr(goodname, basename); \ - copystring(modname, goodname, pt - goodname + 1); \ - if(goodname != pt && !usedmods.access(modname)) usedmods.access(newstring(modname), 0); \ - } - // skybox textures - loopi(6) - { - extern Texture *sky[]; - Texture *t = sky[i]; - if(t == notexture) { if(!silent) conoutf("sky texture %d doesn't exist", i); } - else USEFILENAME("%s", t->name, 1); - } - // map textures (cubes & models) - int texuse[256] = { 0 }; - loopj(ssize - 2) - { - loopk(ssize - 2) - { - if(SOLID(S(j + 1, k + 1)) && texuse[S(j + 1, k + 1)->wtex] && SOLID(S(j, k + 1)) && SOLID(S(j + 1, k)) && SOLID(S(j + 2, k + 1)) && SOLID(S(j + 1, k + 2))) continue; // no side visible - sqr *s = S(j + 1, k + 1); - char ttexuse[256] = { 0 }; - ttexuse[s->wtex] = 1; - if(!SOLID(s)) ttexuse[s->utex] = ttexuse[s->ftex] = ttexuse[s->ctex] = 1; - loopi(256) texuse[i] += ttexuse[i]; - } - } - extern vector mapmodels; - loopv(ents) if(ents[i].type == MAPMODEL && mapmodels.inrange(ents[i].attr2) && ents[i].attr4) texuse[ents[i].attr4]++; - int used = 0; - loopi(256) if(texuse[i]) - { - Texture *t = lookuptexture(i); - if(t == notexture) { if(!silent) conoutf("texture slot %3d doesn't exist (used %d times)", i, texuse[i]); } - else - { - used++; - USEFILENAME("%s", t->name, texuse[i]); - } - - } - if(!silent) conoutf("used: %d texture slots", used); - // mapmodels - int mmuse[256] = { 0 }; - used = 0; - loopv(ents) if(ents[i].type == MAPMODEL) mmuse[ents[i].attr2]++; - loopi(256) if(mmuse[i]) - { - if(!mapmodels.inrange(i)) { if(!silent) conoutf("mapmodel slot %3d doesn't exist (used %d times)", i, mmuse[i]); } - else - { - used++; - USEFILENAME("packages/models/%s", mapmodels[i].name, mmuse[i]); - } - } - if(!silent) conoutf("used: %d mapmodel slots", used); - // sounds - int msuse[128] = { 0 }; - used = 0; - loopv(ents) if(ents[i].type == SOUND && ents[i].attr1 >= 0) msuse[ents[i].attr1]++; - loopi(128) if(msuse[i]) - { - if(!mapsounds.inrange(i)) { if(!silent) conoutf("mapsound slot %3d doesn't exist (used %d times)", i, msuse[i]); } - else if(mapsounds[i].buf && mapsounds[i].buf->name) - { - used++; - USEFILENAME("packages/audio/%s", mapsounds[i].buf->name, msuse[i]); - } - } - if(!silent) conoutf("used: %d mapsound slots", used); - // used mods - int usedm = 0; - allmods[0] = '\0'; - enumeratek(usedmods, const char *, key, concatformatstring(allmods, "%s%s",*allmods ? ", " : "", key); delete key; usedm++); - extern string clientmap; - if(!silent) conoutf("used: %s%s %d total packages (%s.cfg)", allmods, usedm ? ", " : "", usedm, clientmap); - // mediapacks - int usedf = mufpaths.numelems; - int *packn = new int[usedf]; - loopi(usedf) packn[i] = -2; // -2: unset, -1: local-only, 0: release, 1..n: i in loopv(mpdefs) - int idx; - copystring(reqmpak, ""); - reqmpak[0] = '\0'; - // First check releasefiles - int mpfl; - char* acrfc = loadfile("config/releasefiles.cfg", &mpfl, "r"); - if(acrfc) - { - idx = -1; - enumeratek(mufpaths, const char *, key, - idx++; - if(packn[idx]==-2) - { - char* p = strstr(acrfc, key); - if(p) packn[idx] = 0; - } - ); - } - else conoutf("ERROR: your installation is missing the file config/releasefiles.cfg - please do a CLEAN re-install!"); // even if silent == true - // Now check MediaPack definition files - vector mpdefs; - listfiles("packages/mediapack", "txt", mpdefs); - int usedmpaks = 0; - loopvj(mpdefs) - { - bool usethis = false; - int mpfl; - defformatstring(p2mpdf)("packages/mediapack/%s.txt", mpdefs[j]); - char* mpfc = loadfile(p2mpdf, &mpfl, "r"); - if(mpfc) - { - if(!silent) conoutf("found mediapack %s [%d]", mpdefs[j], mpfl); - idx = -1; - enumeratek(mufpaths, const char *, key, - idx++; - if(packn[idx]==-2) - { - const char* gp = strstr(key, "packages/"); - if(gp) - { - const char* fp = strstr(mpfc, gp); - if(fp) - { - packn[idx] = j + 1; - if(!usethis) - { - formatstring(reqmpak)("%s%s%s", reqmpak, reqmpak[0]=='\0'?"":",", mpdefs[j]); - if(++usedmpaks > 0) usethis = true; // these packs are already on the system - if(usedmpaks>25) conoutf("this map requires too many mediapacks."); // even if silent == true - } - } - } - } - ) - } - } - idx = -1; - if(!silent && details) - { - conoutf("mediapack details:"); - // packn[idx]==0?"release": - enumeratek(mufpaths, const char *, key, idx++; if(packn[idx]!=0) conoutf("%3d: %s : %d : %s", idx, key, packn[idx], packn[idx]<0?"LOCAL":mpdefs[packn[idx]-1]); ); - } - if(usedmpaks>0) conoutf("this map requires the following %d mediapack%s: %s", usedmpaks, usedmpaks==1?"":"s", reqmpak); - else - { - if(hdr.mediareq[0] && !silent) - { - char sep[] = ","; - char *pch; - pch = strtok (hdr.mediareq,sep); - while (pch != NULL) - { - conoutf("http://assault.cubers.net/cgi/mediapack.do?mpid=%s", pch); - //conoutf("http://www.26things.com/mrx/get.php?mpid=%s", pch); - pch = strtok (NULL, sep); - } - } - } - enumeratek(mufpaths, const char *, key, mufpaths.remove(key)); // don't report false positives next time round - delete[] packn; -} - -COMMANDF(checkmapdependencies, "i", (int *i) { checkmapdependencies(false, *i!=0); }); - VARP(mapbackupsonsave, 0, 1, 1); void save_world(char *mname) @@ -388,8 +209,6 @@ void save_world(char *mname) toptimize(); setnames(mname); if(mapbackupsonsave) backup(cgzname, bakname); - checkmapdependencies(true); - copystring(hdr.mediareq, reqmpak, 128); stream *f = opengzfile(cgzname, "wb"); if(!f) { conoutf("could not write map to %s", cgzname); return; } strncpy(hdr.head, "ACMP", 4); // ensure map now declares itself as an AssaultCube map, even if imported as CUBE @@ -507,13 +326,13 @@ bool load_world(char *mname) // still supports all map formats that have if(!f) { conoutf("\f3could not read map %s", cgzname); return false; } header tmp; memset(&tmp, 0, sizeof(header)); - if(f->read(&tmp, sizeof(header)-sizeof(int)*16-sizeof(char)*128)!=sizeof(header)-sizeof(int)*16-sizeof(char)*128) { conoutf("\f3while reading map: header malformatted"); delete f; return false; } + if(f->read(&tmp, sizeof(header)-sizeof(int)*16)!=sizeof(header)-sizeof(int)*16) { conoutf("\f3while reading map: header malformatted"); delete f; return false; } lilswap(&tmp.version, 4); if(strncmp(tmp.head, "CUBE", 4)!=0 && strncmp(tmp.head, "ACMP",4)!=0) { conoutf("\f3while reading map: header malformatted"); delete f; return false; } if(tmp.version>MAPVERSION) { conoutf("\f3this map requires a newer version of AssaultCube"); delete f; return false; } if(tmp.sfactorLARGEST_FACTOR || tmp.numents > MAXENTITIES) { conoutf("\f3illegal map size"); delete f; return false; } if(tmp.version>=4 && f->read(&tmp.waterlevel, sizeof(int)*16)!=sizeof(int)*16) { conoutf("\f3while reading map: header malformatted"); delete f; return false; } - if(tmp.version>=7 && f->read(&tmp.mediareq, sizeof(char)*128)!=sizeof(char)*128) { conoutf("\f3while reading map: header malformatted"); delete f; return false; } + if((tmp.version==7 || tmp.version==8) && !f->seek(sizeof(char)*128, SEEK_CUR)) { conoutf("\f3while reading map: header malformatted"); delete f; return false; } hdr = tmp; loadingscreen("%s", hdr.maptitle); resetmap(); @@ -529,17 +348,6 @@ bool load_world(char *mname) // still supports all map formats that have hdr.waterlevel = -100000; hdr.ambient = 0; } - if(hdr.version<7) hdr.mediareq[0] = '\0'; - else - { - if(hdr.mediareq[0]) - { - conoutf("this map requires the following mediapacks: %s", hdr.mediareq); // TODO: check for client meeting these requirements - hint: listfiles - conoutf("to get a set of URLs to download them please run \f2checkmapdependencies\f5 manually."); - } - //else conoutf("this map works with the vanilla release"); - // TODO: output the requirements into a file for easy user-retrieval & -action - needs a base-URL where we will hold the mediapacks - } ents.shrink(0); loopi(3) numspawn[i] = 0; loopi(2) numflagspawn[i] = 0; @@ -701,17 +509,44 @@ bool load_world(char *mname) // still supports all map formats that have popscontext(); c2skeepalive(); + watch.start(); - loopi(256) if(texuse[i]) lookupworldtexture(i); - printf("loaded textures (%d milliseconds)\n", watch.stop()); + loopi(256) if(texuse[i]) lookupworldtexture(i, true); + int texloadtime = watch.stop(); + + c2skeepalive(); + + watch.start(); + preload_mapmodels(true); + int mdlloadtime = watch.stop(); + + c2skeepalive(); + + watch.start(); + audiomgr.preloadmapsounds(true); + int audioloadtime = watch.stop(); + + c2skeepalive(); + + watch.start(); + int downloaded = downloadpackages(); + if(downloaded > 0) printf("downloaded content (%d KB in %d seconds)\n", downloaded/1000, watch.stop()/1000); + + c2skeepalive(); + + loadsky(NULL, true); + + watch.start(); + loopi(256) if(texuse[i]) lookupworldtexture(i, false); + printf("loaded textures (%d milliseconds)\n", texloadtime+watch.stop()); c2skeepalive(); watch.start(); - preload_mapmodels(); - printf("loaded mapmodels (%d milliseconds)\n", watch.stop()); + preload_mapmodels(false); + printf("loaded mapmodels (%d milliseconds)\n", mdlloadtime+watch.stop()); c2skeepalive(); watch.start(); - audiomgr.preloadmapsounds(); - printf("loaded mapsounds (%d milliseconds)\n", watch.stop()); + audiomgr.preloadmapsounds(false); + printf("loaded mapsounds (%d milliseconds)\n", audioloadtime+watch.stop()); c2skeepalive(); defformatstring(startmillis)("%d", millis_()); @@ -720,155 +555,4 @@ bool load_world(char *mname) // still supports all map formats that have return true; } -COMMANDN(savemap, save_world, "s"); - -// FIXME - remove this before release -COMMANDF(setmaprevision, "i", (int *rev) { hdr.maprevision = *rev; }); - -#define MAPDEPFILENAME "mapdependencies.txt" -void listmapdependencies(char *mapname) // print map dependencies to file -{ - static hashtable sumpaths; - hashtable usedmods; - string fullname, modname, allmods; - - #define ADDFILENAME(prefix, fname, count) \ - { \ - defformatstring(basename)(prefix, fname); \ - copystring(fullname, findfile(basename, "r")); \ - int *n = sumpaths.access(fullname); \ - if(!n) { n = &sumpaths.access(newstring(fullname), -1); if(fileexists(fullname, "r")) *n = 0; } \ - if(*n >= 0) *n += count; \ - const char *pt = strstr(fullname, basename); \ - copystring(modname, fullname, pt - fullname + 1); \ - if(fullname != pt && !usedmods.access(modname)) usedmods.access(newstring(modname), 0); \ - } - - if(multiplayer()) return; - stream *f = openfile(MAPDEPFILENAME, "a"); - if(!f) { conoutf("\f3could not append to %s", MAPDEPFILENAME); return; } - if(!mapname || !*mapname) - { // print summary - vector allres; - enumeratek(sumpaths, const char *, key, allres.add(key)); - allres.sort(stringsort); - f->printf("used resources total:\n"); - loopv(allres) f->printf(" used %6d times: \"%s\"\n", *sumpaths.access(allres[i]), allres[i]); - enumeratek(sumpaths, const char *, key, delete key); - sumpaths.clear(); - f->printf(" %d files used\n\n\n", allres.length()); - } - else if(load_world(mapname)) - { // print map deps - filtertext(fullname, hdr.maptitle, 1); - f->printf("-- --:-- -- -- --\n map: %s\n %s\nspawns: FFA %d\tCLA %2d RVSF %2d\tflags: %d+%d\n size: %d : %8d\trevision: %d\n-- --:-- -- -- --\n", - cgzname, fullname, - numspawn[2], numspawn[0], numspawn[1], - numflagspawn[0], numflagspawn[1], - sfactor, maploaded, - hdr.maprevision - ); - loopi(6) - { - extern Texture *sky[]; - Texture *t = sky[i]; - if(t == notexture) f->printf(" sky texture %d doesn't exist\n", i); - else - { - ADDFILENAME("%s", t->name, 1); - f->printf(" sky texture %d, \"%s\"\n", i, fullname); - } - } - int texuse[256] = { 0 }; - loopj(ssize - 2) - { - loopk(ssize - 2) - { - if(SOLID(S(j + 1, k + 1)) && texuse[S(j + 1, k + 1)->wtex] && SOLID(S(j, k + 1)) && SOLID(S(j + 1, k)) && SOLID(S(j + 2, k + 1)) && SOLID(S(j + 1, k + 2))) continue; // no side visible - sqr *s = S(j + 1, k + 1); - char ttexuse[256] = { 0 }; - ttexuse[s->wtex] = 1; - if(!SOLID(s)) ttexuse[s->utex] = ttexuse[s->ftex] = ttexuse[s->ctex] = 1; - loopi(256) texuse[i] += ttexuse[i]; - } - } - extern vector mapmodels; - loopv(ents) if(ents[i].type == MAPMODEL && mapmodels.inrange(ents[i].attr2) && ents[i].attr4) texuse[ents[i].attr4]++; - int used = 0; - loopi(256) if(texuse[i]) - { - Texture *t = lookuptexture(i); - if(t == notexture) f->printf(" texture slot %3d doesn't exist (used %d times)\n", i, texuse[i]); - else - { - used++; - ADDFILENAME("%s", t->name, texuse[i]); - f->printf(" texture slot %3d used %5d times, \"%s\"\n", i, texuse[i], fullname); - } - } - f->printf(" used: %d texture slots\n", used); - // mapmodels - int mmuse[256] = { 0 }; - used = 0; - loopv(ents) if(ents[i].type == MAPMODEL) mmuse[ents[i].attr2]++; - loopi(256) if(mmuse[i]) - { - if(!mapmodels.inrange(i)) f->printf(" mapmodel slot %3d doesn't exist (used %d times)\n", i, mmuse[i]); - else - { - used++; - ADDFILENAME("packages/models/%s", mapmodels[i].name, mmuse[i]); - f->printf(" mapmodel slot %3d used %4d times, \"%s\"\n", i, mmuse[i], fullname); - } - } - f->printf(" used: %d mapmodel slots\n", used); - // sounds - int msuse[128] = { 0 }; - used = 0; - loopv(ents) if(ents[i].type == SOUND && ents[i].attr1 >= 0) msuse[ents[i].attr1]++; - loopi(128) if(msuse[i]) - { - if(!mapsounds.inrange(i)) f->printf(" mapsound slot %3d doesn't exist (used %d times)\n", i, msuse[i]); - else if(mapsounds[i].buf && mapsounds[i].buf->name) - { - used++; - ADDFILENAME("packages/audio/%s", mapsounds[i].buf->name, msuse[i]); - f->printf(" mapsound slot %3d used %4d times, \"%s\"\n", i, msuse[i], fullname); - } - } - f->printf(" used: %d mapsound slots\n", used); - - int usedm = 0; - allmods[0] = '\0'; - enumeratek(usedmods, const char *, key, concatformatstring(allmods, "%s%s",*allmods ? ", " : "", key); delete key; usedm++); - pushscontext(IEXC_MAPCFG); // untrusted altogether - per_idents = false; - neverpersist = true; - execfile(mcfname); - f->printf(" used: %s%s %d total packages (%s.cfg)\n", allmods, usedm ? ", " : "", usedm, mapname); - if(usedm) conoutf(" used: %s (%s.cfg) in %s", allmods, mapname, mapname); - neverpersist = false; - per_idents = true; - popscontext(); - f->printf("\n\n"); - } - delete f; -} - -COMMAND(listmapdependencies, "s"); - -void listmapdependencies_all(int *sure) -{ - if(*sure != 42 || multiplayer()) return; - - stream *f = openfile(MAPDEPFILENAME, "w"); - delete f; - vector files; - listfiles("packages/maps", "cgz", files); - listfiles("packages/maps/official", "cgz", files); - files.sort(stringsort); - conoutf("%d maps to go...", files.length()); - loopv(files) listmapdependencies(files[i]); - listmapdependencies(NULL); -} -COMMAND(listmapdependencies_all, "i"); +COMMANDN(savemap, save_world, "s"); \ No newline at end of file diff --git a/source/src/zip.cpp b/source/src/zip.cpp index c9ff1769..c8ecbdd3 100644 --- a/source/src/zip.cpp +++ b/source/src/zip.cpp @@ -22,7 +22,7 @@ struct zipfileheader { uint signature; ushort version, needversion, flags, compression, modtime, moddate; - uint crc32, compressedsize, uncompressedsize; + uint crc32, compressedsize, uncompressedsize; ushort namelength, extralength, commentlength, disknumber, internalattribs; uint externalattribs, offset; }; @@ -43,9 +43,9 @@ struct zipfile zipfile() : name(NULL), header(0), offset(~0U), size(0), compressedsize(0) { } - ~zipfile() - { - DELETEA(name); + ~zipfile() + { + DELETEA(name); } }; @@ -57,9 +57,10 @@ struct ziparchive FILE *data; hashtable files; int openfiles; + int type; zipstream *owner; - ziparchive() : name(NULL), data(NULL), files(512), openfiles(0), owner(NULL) + ziparchive() : name(NULL), data(NULL), files(512), openfiles(0), type(-1), owner(NULL) { } ~ziparchive() @@ -85,9 +86,9 @@ static bool findzipdirectory(FILE *f, zipdirectoryheader &hdr) if(next + carry < ZIP_DIRECTORY_SIZE || fseek(f, offset, SEEK_SET) < 0 || (int)fread(buf, 1, next, f) != next) return false; len = next + carry; uchar *search = &buf[next-1]; - for(; search >= buf; search--) if(*(uint *)search == signature) break; + for(; search >= buf; search--) if(*(uint *)search == signature) break; if(search >= buf) { src = search; break; } - } + } if(&buf[len] - src < ZIP_DIRECTORY_SIZE) return false; @@ -149,7 +150,7 @@ static bool readzipdirectory(const char *archname, FILE *f, int entries, int off pname[namelen] = '\0'; path(pname); char *name = newstring(pname); - + zipfile &f = files.add(); f.name = name; f.header = hdr.offset; @@ -206,18 +207,36 @@ static bool checkprefix(vector &files, const char *prefix, int prefixle return true; } -static void mountzip(ziparchive &arch, vector &files, const char *mountdir, const char *stripdir) +bool extractzipfile(ziparchive *a, zipfile *f, const char *name); + +bool fitspackage(char *filename, int type) +{ + char *extension = strrchr(filename, '.'); + ++extension; + switch(type) + { + case PCK_MAPMODEL: return !strcmp(extension, "md2") || !strcmp(extension, "md3") + || !strcmp(extension, "cfg") || !strcmp(extension, "txt") + || !strcmp(extension, "jpg") || !strcmp(extension, "png"); + case PCK_MAP: return !strcmp(extension, "cgz") || !strcmp(extension, "cfg"); + case PCK_SKYBOX: return !strcmp(extension, "jpg") || !strcmp(extension, "png"); + default: return true; + } +} + +static void mountzip(ziparchive &arch, vector &files, const char *mountdir, const char *stripdir, bool extract) { string packagesdir = "packages/"; path(packagesdir); int striplen = stripdir ? (int)strlen(stripdir) : 0; + if(arch.type == PCK_MAP) mountdir = "packages/maps/"; if(!mountdir && !stripdir) loopv(files) { zipfile &f = files[i]; const char *foundpackages = strstr(f.name, packagesdir); if(foundpackages) { - if(foundpackages > f.name) + if(foundpackages > f.name) { stripdir = f.name; striplen = foundpackages - f.name; @@ -239,7 +258,8 @@ static void mountzip(ziparchive &arch, vector &files, const char *mount if(!mountdir) mountdir = "packages/maps/"; break; } - } + mountdir = "packages/maps/"; + } } string mdir = "", fname; if(mountdir) @@ -256,26 +276,32 @@ static void mountzip(ziparchive &arch, vector &files, const char *mount zipfile &mf = arch.files[mname]; mf = f; mf.name = mname; + + if(extract) + { + if(fitspackage(fname, arch.type)) extractzipfile(&arch, &f, fname); + else conoutf("\f3could not extract \"%s\" : file extension not supported", fname); + } } } -bool addzip(const char *name, const char *mount = NULL, const char *strip = NULL) +bool addzip(const char *name, const char *mount, const char *strip, bool extract, int type) { string pname; copystring(pname, name); path(pname); - int plen = (int)strlen(pname); - if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip"); + /*int plen = (int)strlen(pname); + if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");*/ - ziparchive *exists = findzip(pname); - if(exists) + /*ziparchive *exists = findzip(pname); + if(exists) { conoutf("already added zip %s", pname); return true; - } - + }*/ + FILE *f = fopen(findfile(pname, "rb"), "rb"); - if(!f) + if(!f) { conoutf("could not open file %s", pname); return false; @@ -288,24 +314,24 @@ bool addzip(const char *name, const char *mount = NULL, const char *strip = NULL fclose(f); return false; } - + ziparchive *arch = new ziparchive; arch->name = newstring(pname); arch->data = f; - mountzip(*arch, files, mount, strip); - archives.add(arch); - - conoutf("added zip %s", pname); + arch->type = type; + mountzip(*arch, files, mount, strip, extract); + if(!extract) archives.add(arch); + else delete arch; return true; -} - +} + bool removezip(const char *name) { string pname; copystring(pname, name); path(pname); - int plen = (int)strlen(pname); - if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip"); + /*int plen = (int)strlen(pname); + if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");*/ ziparchive *exists = findzip(pname); if(!exists) { @@ -317,8 +343,8 @@ bool removezip(const char *name) conoutf("zip %s has open files", pname); return false; } - conoutf("removed zip %s", exists->name); - archives.removeobj(exists); + //conoutf("removed zip %s", exists->name); + archives.removeobj(exists); delete exists; return true; } @@ -416,11 +442,11 @@ struct zipstream : stream { switch(whence) { - case SEEK_END: pos += info->offset + info->size; break; + case SEEK_END: pos += info->offset + info->size; break; case SEEK_CUR: pos += reading; break; case SEEK_SET: pos += info->offset; break; default: return false; - } + } pos = clamp(pos, long(info->offset), long(info->offset + info->size)); arch->owner = NULL; if(fseek(arch->data, pos, SEEK_SET) < 0) return false; @@ -429,10 +455,10 @@ struct zipstream : stream ended = false; return true; } - + switch(whence) { - case SEEK_END: pos += info->size; break; + case SEEK_END: pos += info->size; break; case SEEK_CUR: pos += zfile.total_out; break; case SEEK_SET: break; default: return false; @@ -443,7 +469,7 @@ struct zipstream : stream reading = info->offset + info->compressedsize; zfile.next_in += zfile.avail_in; zfile.avail_in = 0; - zfile.total_in = info->compressedsize; + zfile.total_in = info->compressedsize; arch->owner = NULL; ended = false; return true; @@ -451,7 +477,7 @@ struct zipstream : stream if(pos < 0) return false; if(pos >= (long)zfile.total_out) pos -= zfile.total_out; - else + else { if(zfile.next_in && zfile.total_in <= uint(zfile.next_in - buf)) { @@ -491,7 +517,7 @@ struct zipstream : stream if(fseek(arch->data, reading, SEEK_SET) < 0) { stopreading(); return 0; } arch->owner = this; } - + int n = (int)fread(buf, 1, min(len, int(info->size + info->offset - reading)), arch->data); reading += n; if(n < len) ended = true; @@ -504,7 +530,7 @@ struct zipstream : stream { if(!zfile.avail_in) readbuf(BUFSIZE); int err = inflate(&zfile, Z_NO_FLUSH); - if(err != Z_OK) + if(err != Z_OK) { if(err == Z_STREAM_END) ended = true; else @@ -514,13 +540,33 @@ struct zipstream : stream #endif stopreading(); } - break; + break; } } return len - zfile.avail_out; } }; +bool extractzipfile(ziparchive *a, zipfile *f, const char *name) +{ + zipstream *s = new zipstream; + FILE *target; + defformatstring(fname)("%s", findfile(name, "wb")); + preparedir(fname); + bool error = false; + if(s->open(a, f) && (target = fopen(fname, "wb"))) + { + size_t len; + uchar copybuf[1024]; + while((len = s->read(copybuf, 1024))) fwrite(copybuf, 1, len, target); + } + else error = true; + if(error) conoutf("failed to extract zip file %s from archive %s", fname, a->name); + if(target) fclose(target); + delete s; + return !error; +} + stream *openzipfile(const char *name, const char *mode) { for(; *mode; mode++) if(*mode=='w' || *mode=='a') return NULL; diff --git a/source/vcpp/cube.sln b/source/vcpp/cube.sln index 92829966..613716f8 100644 --- a/source/vcpp/cube.sln +++ b/source/vcpp/cube.sln @@ -1,6 +1,7 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cube", "cube.vcproj", "{1FAF5BB4-C49A-4124-9F23-188528BAE7C8}" + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cube", "cube.vcxproj", "{1FAF5BB4-C49A-4124-9F23-188528BAE7C8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/source/vcpp/cube.vcproj b/source/vcpp/cube.vcproj index 1bf49516..e4c811ac 100644 --- a/source/vcpp/cube.vcproj +++ b/source/vcpp/cube.vcproj @@ -84,7 +84,7 @@ />