summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile93
-rwxr-xr-xmake-macosx-ub.sh65
-rwxr-xr-xmisc/merge-ioq3-into-trem.sh2
-rw-r--r--src/client/cl_avi.c8
-rw-r--r--src/client/cl_cgame.c2
-rw-r--r--src/client/cl_console.c4
-rw-r--r--src/client/cl_curl.c358
-rw-r--r--src/client/cl_curl.h101
-rw-r--r--src/client/cl_keys.c3
-rw-r--r--src/client/cl_main.c131
-rw-r--r--src/client/cl_parse.c32
-rw-r--r--src/client/cl_ui.c6
-rw-r--r--src/client/client.h19
-rw-r--r--src/client/qal.c4
-rw-r--r--src/client/snd_codec_ogg.c8
-rw-r--r--src/client/snd_main.c4
-rw-r--r--src/client/snd_openal.c406
-rw-r--r--src/libcurl/curl/curl.h1563
-rw-r--r--src/libcurl/curl/curlver.h56
-rw-r--r--src/libcurl/curl/easy.h81
-rw-r--r--src/libcurl/curl/mprintf.h62
-rw-r--r--src/libcurl/curl/multi.h344
-rw-r--r--src/libcurl/curl/stdcheaders.h34
-rw-r--r--src/libcurl/curl/types.h1
-rw-r--r--src/libs/win32/libcurl.abin0 -> 253484 bytes
-rw-r--r--src/qcommon/common.c20
-rw-r--r--src/qcommon/cvar.c9
-rw-r--r--src/qcommon/files.c6
-rw-r--r--src/qcommon/q_shared.h3
-rw-r--r--src/qcommon/qcommon.h7
-rw-r--r--src/qcommon/vm_ppc_new.c16
-rw-r--r--src/renderer/tr_model.c6
-rw-r--r--src/server/server.h2
-rw-r--r--src/server/sv_client.c13
-rw-r--r--src/server/sv_init.c112
-rw-r--r--src/server/sv_main.c26
-rw-r--r--src/server/sv_snapshot.c17
-rwxr-xr-xsrc/unix/MacSupport/SLA-dmg.sh30
-rw-r--r--src/unix/MacSupport/SLA.r260
-rwxr-xr-xsrc/unix/MacSupport/ioquake3.icnsbin0 -> 35224 bytes
-rw-r--r--src/unix/unix_main.c42
-rw-r--r--src/unix/unix_net.c33
-rw-r--r--src/win32/win_shared.c21
43 files changed, 3775 insertions, 235 deletions
diff --git a/Makefile b/Makefile
index a434f2e5..44a0d810 100644
--- a/Makefile
+++ b/Makefile
@@ -95,6 +95,18 @@ ifndef USE_OPENAL_DLOPEN
USE_OPENAL_DLOPEN=0
endif
+ifndef USE_CURL
+USE_CURL=1
+endif
+
+ifndef USE_CURL_DLOPEN
+ ifeq ($(PLATFORM),mingw32)
+ USE_CURL_DLOPEN=0
+ else
+ USE_CURL_DLOPEN=1
+ endif
+endif
+
ifndef USE_CODEC_VORBIS
USE_CODEC_VORBIS=0
endif
@@ -129,13 +141,19 @@ LIBSDIR=$(MOUNT_DIR)/libs
MASTERDIR=$(MOUNT_DIR)/master
# extract version info
-VERSION=$(shell grep "#define VERSION_NUMBER" $(CMDIR)/q_shared.h | \
+VERSION=$(shell grep "\#define VERSION_NUMBER" $(CMDIR)/q_shared.h | \
sed -e 's/[^"]*"\(.*\)"/\1/')
+USE_SVN=
ifeq ($(wildcard .svn),.svn)
- SVN_VERSION=$(VERSION)_SVN$(shell LANG=C svnversion .)
-else
- SVN_VERSION=$(VERSION)
+ SVN_REV=$(shell LANG=C svnversion .)
+ ifneq ($(SVN_REV),)
+ SVN_VERSION=$(VERSION)_SVN$(SVN_REV)
+ USE_SVN=1
+ endif
+endif
+ifneq ($(USE_SVN),1)
+ SVN_VERSION=$(VERSION)
endif
@@ -179,6 +197,13 @@ ifeq ($(PLATFORM),linux)
BASE_CFLAGS += -DUSE_OPENAL_DLOPEN=1
endif
endif
+
+ ifeq ($(USE_CURL),1)
+ BASE_CFLAGS += -DUSE_CURL=1
+ ifeq ($(USE_CURL_DLOPEN),1)
+ BASE_CFLAGS += -DUSE_CURL_DLOPEN=1
+ endif
+ endif
ifeq ($(USE_CODEC_VORBIS),1)
BASE_CFLAGS += -DUSE_CODEC_VORBIS=1
@@ -241,6 +266,12 @@ ifeq ($(PLATFORM),linux)
CLIENT_LDFLAGS += -lopenal
endif
endif
+
+ ifeq ($(USE_CURL),1)
+ ifneq ($(USE_CURL_DLOPEN),1)
+ CLIENT_LDFLAGS += -lcurl
+ endif
+ endif
ifeq ($(USE_CODEC_VORBIS),1)
CLIENT_LDFLAGS += -lvorbisfile -lvorbis -logg
@@ -294,14 +325,15 @@ ifeq ($(PLATFORM),darwin)
ifeq ($(BUILD_MACOSX_UB),x86)
CC=gcc-4.0
BASE_CFLAGS += -arch i386 -DSMP \
- -isysroot /Developer/SDKs/MacOSX10.4u.sdk \
-mmacosx-version-min=10.4 \
-DMAC_OS_X_VERSION_MIN_REQUIRED=1040 -nostdinc \
-F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks \
-I/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.1/include \
-isystem /Developer/SDKs/MacOSX10.4u.sdk/usr/include
- LDFLAGS = -mmacosx-version-min=10.4 \
- -L/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.1
+ LDFLAGS = -arch i386 -mmacosx-version-min=10.4 \
+ -L/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.1 \
+ -F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks \
+ -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk
ARCH=x86
BUILD_SERVER=0
else
@@ -314,13 +346,13 @@ ifeq ($(PLATFORM),darwin)
endif
ifeq ($(ARCH),ppc)
- OPTIMIZE += -faltivec
+ OPTIMIZE += -faltivec -O3
# Carbon is required on PPC only to make a call to MakeDataExecutable
# in the PPC vm (should be a better non-Carbon way).
LDFLAGS += -framework Carbon
endif
ifeq ($(ARCH),x86)
- OPTIMIZE += -msse2
+ OPTIMIZE += -march=prescott -mfpmath=sse
# x86 vm will crash without -mstackrealign since MMX instructions will be
# used no matter what and they corrupt the frame pointer in VM calls
BASE_CFLAGS += -mstackrealign
@@ -339,6 +371,15 @@ ifeq ($(PLATFORM),darwin)
BASE_CFLAGS += -DUSE_OPENAL_DLOPEN=1
endif
endif
+
+ ifeq ($(USE_CURL),1)
+ BASE_CFLAGS += -DUSE_CURL=1
+ ifneq ($(USE_CURL_DLOPEN),1)
+ CLIENT_LDFLAGS += -lcurl
+ else
+ BASE_CFLAGS += -DUSE_CURL_DLOPEN=1
+ endif
+ endif
ifeq ($(USE_CODEC_VORBIS),1)
BASE_CFLAGS += -DUSE_CODEC_VORBIS=1
@@ -360,7 +401,7 @@ ifeq ($(PLATFORM),darwin)
#CLIENT_LDFLAGS += -L/usr/X11R6/$(LIB) -lX11 -lXext -lXxf86dga -lXxf86vm
endif
- OPTIMIZE += -O3 -ffast-math -falign-loops=16
+ OPTIMIZE += -ffast-math -falign-loops=16
ifneq ($(HAVE_VM_COMPILED),true)
BASE_CFLAGS += -DNO_VM_COMPILED
@@ -395,6 +436,13 @@ ifeq ($(PLATFORM),mingw32)
ifeq ($(USE_OPENAL),1)
BASE_CFLAGS += -DUSE_OPENAL=1 -DUSE_OPENAL_DLOPEN=1
endif
+
+ ifeq ($(USE_CURL),1)
+ BASE_CFLAGS += -DUSE_CURL=1
+ ifneq ($(USE_CURL_DLOPEN),1)
+ BASE_CFLAGS += -DCURL_STATICLIB
+ endif
+ endif
ifeq ($(USE_CODEC_VORBIS),1)
BASE_CFLAGS += -DUSE_CODEC_VORBIS=1
@@ -418,9 +466,15 @@ ifeq ($(PLATFORM),mingw32)
BINEXT=.exe
- LDFLAGS= -mwindows -lshfolder -lwsock32 -lgdi32 -lwinmm -lole32
+ LDFLAGS= -mwindows -lwsock32 -lgdi32 -lwinmm -lole32
CLIENT_LDFLAGS=
+ ifeq ($(USE_CURL),1)
+ ifneq ($(USE_CURL_DLOPEN),1)
+ CLIENT_LDFLAGS += $(LIBSDIR)/win32/libcurl.a
+ endif
+ endif
+
ifeq ($(USE_CODEC_VORBIS),1)
CLIENT_LDFLAGS += -lvorbisfile -lvorbis -logg
endif
@@ -713,6 +767,10 @@ ifeq ($(GENERATE_DEPENDENCIES),1)
endif
endif
+ifeq ($(USE_SVN),1)
+ BASE_CFLAGS += -DSVN_VERSION=\\\"$(SVN_VERSION)\\\"
+endif
+
DO_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) -o $@ -c $<
DO_SMP_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) -DSMP -o $@ -c $<
DO_BOT_CC=$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) $(BOTCFLAGS) -DBOTLIB -o $@ -c $< # $(SHLIBCFLAGS) # bk001212
@@ -829,6 +887,8 @@ Q3OBJ = \
$(B)/client/qal.o \
$(B)/client/snd_openal.o \
\
+ $(B)/client/cl_curl.o \
+ \
$(B)/client/sv_ccmds.o \
$(B)/client/sv_client.o \
$(B)/client/sv_game.o \
@@ -984,6 +1044,9 @@ endif
$(B)/client/cl_cgame.o : $(CDIR)/cl_cgame.c; $(DO_CC)
$(B)/client/cl_cin.o : $(CDIR)/cl_cin.c; $(DO_CC)
$(B)/client/cl_console.o : $(CDIR)/cl_console.c; $(DO_CC)
+ifeq ($(USE_SVN),1)
+ $(B)/client/cl_console.o : .svn/entries
+endif
$(B)/client/cl_input.o : $(CDIR)/cl_input.c; $(DO_CC)
$(B)/client/cl_keys.o : $(CDIR)/cl_keys.c; $(DO_CC)
$(B)/client/cl_main.o : $(CDIR)/cl_main.c; $(DO_CC)
@@ -1006,6 +1069,8 @@ $(B)/client/snd_codec_ogg.o : $(CDIR)/snd_codec_ogg.c; $(DO_CC)
$(B)/client/qal.o : $(CDIR)/qal.c; $(DO_CC)
$(B)/client/snd_openal.o : $(CDIR)/snd_openal.c; $(DO_CC)
+$(B)/client/cl_curl.o : $(CDIR)/cl_curl.c; $(DO_CC)
+
$(B)/client/sv_client.o : $(SDIR)/sv_client.c; $(DO_CC)
$(B)/client/sv_ccmds.o : $(SDIR)/sv_ccmds.c; $(DO_CC)
$(B)/client/sv_game.o : $(SDIR)/sv_game.c; $(DO_CC)
@@ -1021,6 +1086,9 @@ $(B)/client/cm_patch.o : $(CMDIR)/cm_patch.c; $(DO_CC)
$(B)/client/cm_polylib.o : $(CMDIR)/cm_polylib.c; $(DO_CC)
$(B)/client/cmd.o : $(CMDIR)/cmd.c; $(DO_CC)
$(B)/client/common.o : $(CMDIR)/common.c; $(DO_CC)
+ifeq ($(USE_SVN),1)
+ $(B)/client/common.o : .svn/entries
+endif
$(B)/client/cvar.o : $(CMDIR)/cvar.c; $(DO_CC)
$(B)/client/files.o : $(CMDIR)/files.c; $(DO_CC)
$(B)/client/md4.o : $(CMDIR)/md4.c; $(DO_CC)
@@ -1222,6 +1290,9 @@ $(B)/ded/cm_trace.o : $(CMDIR)/cm_trace.c; $(DO_DED_CC)
$(B)/ded/cm_patch.o : $(CMDIR)/cm_patch.c; $(DO_DED_CC)
$(B)/ded/cmd.o : $(CMDIR)/cmd.c; $(DO_DED_CC)
$(B)/ded/common.o : $(CMDIR)/common.c; $(DO_DED_CC)
+ifeq ($(USE_SVN),1)
+ $(B)/ded/common.o : .svn/entries
+endif
$(B)/ded/cvar.o : $(CMDIR)/cvar.c; $(DO_DED_CC)
$(B)/ded/files.o : $(CMDIR)/files.c; $(DO_DED_CC)
$(B)/ded/md4.o : $(CMDIR)/md4.c; $(DO_DED_CC)
diff --git a/make-macosx-ub.sh b/make-macosx-ub.sh
index a641e655..0bcee56c 100755
--- a/make-macosx-ub.sh
+++ b/make-macosx-ub.sh
@@ -1,7 +1,12 @@
#!/bin/sh
-
+APPBUNDLE=ioquake3.app
+BINARY=ioquake3.ub
+PKGINFO=APPIOQ3
+ICNS=code/unix/MacSupport/ioquake3.icns
DESTDIR=build/release-darwin-ub
BASEDIR=base
+Q3_VERSION=`grep "\#define Q3_VERSION" code/qcommon/q_shared.h | \
+ sed -e 's/.*".* \([^ ]*\)"/\1/'`;
BIN_OBJ="
build/release-darwin-ppc/tremulous.ppc
@@ -36,15 +41,57 @@ fi
(BUILD_MACOSX_UB=ppc make && BUILD_MACOSX_UB=x86 make) || exit 1;
-if [ ! -d $DESTDIR ]; then
- mkdir $DESTDIR || exit 1;
+echo "Creating .app bundle $DESTDIR/$APPBUNDLE"
+if [ ! -d $DESTDIR/$APPBUNDLE/Contents/MacOS/$BASEDIR ]; then
+ mkdir -p $DESTDIR/$APPBUNDLE/Contents/MacOS/$BASEDIR || exit 1;
+fi
+if [ ! -d $DESTDIR/$APPBUNDLE/Contents/MacOS/$MPACKDIR ]; then
+ mkdir -p $DESTDIR/$APPBUNDLE/Contents/MacOS/$MPACKDIR || exit 1;
fi
-if [ ! -d $DESTDIR/$BASEDIR ]; then
- mkdir $DESTDIR/$BASEDIR || exit 1;
+if [ ! -d $DESTDIR/$APPBUNDLE/Contents/Resources ]; then
+ mkdir -p $DESTDIR/$APPBUNDLE/Contents/Resources
fi
+cp $ICNS $DESTDIR/$APPBUNDLE/Contents/Resources/ioquake3.icns || exit 1;
+echo $PKGINFO > $DESTDIR/$APPBUNDLE/Contents/PkgInfo
+echo "
+ <?xml version=\"1.0\" encoding="UTF-8"?>
+ <!DOCTYPE plist
+ PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"
+ \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+ <plist version=\"1.0\">
+ <dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>$BINARY</string>
+ <key>CFBundleGetInfoString</key>
+ <string>ioquake3 $Q3_VERSION</string>
+ <key>CFBundleIconFile</key>
+ <string>ioquake3.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.icculus.quake3</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>ioquake3</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>$Q3_VERSION</string>
+ <key>CFBundleSignature</key>
+ <string>$PKGINFO</string>
+ <key>CFBundleVersion</key>
+ <string>$Q3_VERSION</string>
+ <key>NSExtensions</key>
+ <dict/>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+ </dict>
+ </plist>
+ " > $DESTDIR/$APPBUNDLE/Contents/Info.plist
-echo "Installing Universal Binaries in $DESTDIR"
-lipo -create -o $DESTDIR/Tremulous $BIN_OBJ
-cp $BASE_OBJ $DESTDIR/$BASEDIR/
-cp src/libs/macosx/*.dylib $DESTDIR/
+lipo -create -o $DESTDIR/$APPBUNDLE/Contents/MacOS/$BINARY $BIN_OBJ
+cp $BASE_OBJ $DESTDIR/$APPBUNDLE/Contents/MacOS/$BASEDIR/
+cp $MPACK_OBJ $DESTDIR/$APPBUNDLE/Contents/MacOS/$MPACKDIR/
+cp code/libs/macosx/*.dylib $DESTDIR/$APPBUNDLE/Contents/MacOS/
diff --git a/misc/merge-ioq3-into-trem.sh b/misc/merge-ioq3-into-trem.sh
index b7e7af1d..1bf9e00a 100755
--- a/misc/merge-ioq3-into-trem.sh
+++ b/misc/merge-ioq3-into-trem.sh
@@ -17,7 +17,7 @@ svn export . $IOQ3VERSION
cd $IOQ3VERSION
# Remove READMEs and the like
-rm -rf BUGS ChangeLog README COPYING.txt TODO id-readme.txt web/
+rm -rf BUGS ChangeLog README COPYING.txt NOTTODO TODO id-readme.txt web/
# Remove Q3 ui stuff
rm -rf ui/
diff --git a/src/client/cl_avi.c b/src/client/cl_avi.c
index 463f873c..c54e7054 100644
--- a/src/client/cl_avi.c
+++ b/src/client/cl_avi.c
@@ -2,20 +2,20 @@
===========================================================================
Copyright (C) 2005-2006 Tim Angus
-This file is part of Quake III Arena source code.
+This file is part of Tremulous.
-Quake III Arena source code is free software; you can redistribute it
+Tremulous is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
-Quake III Arena source code is distributed in the hope that it will be
+Tremulous is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
+along with Tremulous; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
diff --git a/src/client/cl_cgame.c b/src/client/cl_cgame.c
index fd7c29ed..262f6b47 100644
--- a/src/client/cl_cgame.c
+++ b/src/client/cl_cgame.c
@@ -981,7 +981,7 @@ void CL_SetCGameTime( void ) {
}
// allow pause in single player
- if ( sv_paused->integer && cl_paused->integer && com_sv_running->integer ) {
+ if ( sv_paused->integer && CL_CheckPaused() && com_sv_running->integer ) {
// paused
return;
}
diff --git a/src/client/cl_console.c b/src/client/cl_console.c
index 22a148a1..3e321394 100644
--- a/src/client/cl_console.c
+++ b/src/client/cl_console.c
@@ -516,13 +516,13 @@ void Con_DrawSolidConsole( float frac ) {
re.SetColor( g_color_table[ColorIndex(COLOR_RED)] );
- i = strlen( Q3_VERSION );
+ i = strlen( SVN_VERSION );
for (x=0 ; x<i ; x++) {
SCR_DrawSmallChar( cls.glconfig.vidWidth - ( i - x ) * SMALLCHAR_WIDTH,
- (lines-(SMALLCHAR_HEIGHT+SMALLCHAR_HEIGHT/2)), Q3_VERSION[x] );
+ (lines-(SMALLCHAR_HEIGHT+SMALLCHAR_HEIGHT/2)), SVN_VERSION[x] );
}
diff --git a/src/client/cl_curl.c b/src/client/cl_curl.c
new file mode 100644
index 00000000..246095a1
--- /dev/null
+++ b/src/client/cl_curl.c
@@ -0,0 +1,358 @@
+/*
+===========================================================================
+Copyright (C) 2006 Tony J. White (tjw@tjw.org)
+
+This file is part of Tremulous.
+
+Tremulous is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the License,
+or (at your option) any later version.
+
+Tremulous is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+
+#if USE_CURL
+#include "client.h"
+cvar_t *cl_cURLLib;
+
+#if USE_CURL_DLOPEN
+
+#if USE_SDL_VIDEO
+#include "SDL.h"
+#include "SDL_loadso.h"
+#define OBJTYPE void *
+#define OBJLOAD(x) SDL_LoadObject(x)
+#define SYMLOAD(x,y) SDL_LoadFunction(x,y)
+#define OBJFREE(x) SDL_UnloadObject(x)
+
+#elif defined _WIN32
+#include <windows.h>
+#define OBJTYPE HMODULE
+#define OBJLOAD(x) LoadLibrary(x)
+#define SYMLOAD(x,y) GetProcAddress(x,y)
+#define OBJFREE(x) FreeLibrary(x)
+
+#elif defined __linux__ || defined __FreeBSD__ || defined MACOS_X || defined __sun
+#include <dlfcn.h>
+#define OBJTYPE void *
+#define OBJLOAD(x) dlopen(x, RTLD_LAZY | RTLD_GLOBAL)
+#define SYMLOAD(x,y) dlsym(x,y)
+#define OBJFREE(x) dlclose(x)
+#else
+
+#error "Your platform has no lib loading code or it is disabled"
+#endif
+
+#if defined __linux__ || defined __FreeBSD__ || defined MACOS_X
+#include <unistd.h>
+#include <sys/types.h>
+#endif
+
+char* (*qcurl_version)(void);
+
+CURL* (*qcurl_easy_init)(void);
+CURLcode (*qcurl_easy_setopt)(CURL *curl, CURLoption option, ...);
+CURLcode (*qcurl_easy_perform)(CURL *curl);
+void (*qcurl_easy_cleanup)(CURL *curl);
+CURLcode (*qcurl_easy_getinfo)(CURL *curl, CURLINFO info, ...);
+CURL* (*qcurl_easy_duphandle)(CURL *curl);
+void (*qcurl_easy_reset)(CURL *curl);
+const char *(*qcurl_easy_strerror)(CURLcode);
+
+CURLM* (*qcurl_multi_init)(void);
+CURLMcode (*qcurl_multi_add_handle)(CURLM *multi_handle,
+ CURL *curl_handle);
+CURLMcode (*qcurl_multi_remove_handle)(CURLM *multi_handle,
+ CURL *curl_handle);
+CURLMcode (*qcurl_multi_fdset)(CURLM *multi_handle,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *exc_fd_set,
+ int *max_fd);
+CURLMcode (*qcurl_multi_perform)(CURLM *multi_handle,
+ int *running_handles);
+CURLMcode (*qcurl_multi_cleanup)(CURLM *multi_handle);
+CURLMsg *(*qcurl_multi_info_read)(CURLM *multi_handle,
+ int *msgs_in_queue);
+const char *(*qcurl_multi_strerror)(CURLMcode);
+
+static OBJTYPE cURLLib = NULL;
+
+/*
+=================
+GPA
+=================
+*/
+static void *GPA(char *str)
+{
+ void *rv;
+
+ rv = SYMLOAD(cURLLib, str);
+ if(!rv)
+ {
+ Com_Printf("Can't load symbol %s\n", str);
+ clc.cURLEnabled = qfalse;
+ return NULL;
+ }
+ else
+ {
+ Com_DPrintf("Loaded symbol %s (0x%08X)\n", str, rv);
+ return rv;
+ }
+}
+#endif /* USE_CURL_DLOPEN */
+
+/*
+=================
+CL_cURL_Init
+=================
+*/
+qboolean CL_cURL_Init()
+{
+#if USE_CURL_DLOPEN
+ if(cURLLib)
+ return qtrue;
+
+
+ Com_Printf("Loading \"%s\"...", cl_cURLLib->string);
+ if( (cURLLib = OBJLOAD(cl_cURLLib->string)) == 0 )
+ {
+#ifdef _WIN32
+ return qfalse;
+#else
+ char fn[1024];
+ getcwd(fn, sizeof(fn));
+ strncat(fn, "/", sizeof(fn));
+ strncat(fn, cl_cURLLib->string, sizeof(fn));
+
+ if( (cURLLib = OBJLOAD(fn)) == 0 )
+ {
+ return qfalse;
+ }
+#endif /* _WIN32 */
+ }
+
+ clc.cURLEnabled = qtrue;
+
+ qcurl_version = GPA("curl_version");
+
+ qcurl_easy_init = GPA("curl_easy_init");
+ qcurl_easy_setopt = GPA("curl_easy_setopt");
+ qcurl_easy_perform = GPA("curl_easy_perform");
+ qcurl_easy_cleanup = GPA("curl_easy_cleanup");
+ qcurl_easy_getinfo = GPA("curl_easy_getinfo");
+ qcurl_easy_duphandle = GPA("curl_easy_duphandle");
+ qcurl_easy_reset = GPA("curl_easy_reset");
+ qcurl_easy_strerror = GPA("curl_easy_strerror");
+
+ qcurl_multi_init = GPA("curl_multi_init");
+ qcurl_multi_add_handle = GPA("curl_multi_add_handle");
+ qcurl_multi_remove_handle = GPA("curl_multi_remove_handle");
+ qcurl_multi_fdset = GPA("curl_multi_fdset");
+ qcurl_multi_perform = GPA("curl_multi_perform");
+ qcurl_multi_cleanup = GPA("curl_multi_cleanup");
+ qcurl_multi_info_read = GPA("curl_multi_info_read");
+ qcurl_multi_strerror = GPA("curl_multi_strerror");
+
+ if(!clc.cURLEnabled)
+ {
+ CL_cURL_Shutdown();
+ Com_Printf("FAIL One or more symbols not found\n");
+ return qfalse;
+ }
+ Com_Printf("OK\n");
+
+ return qtrue;
+#else
+ clc.cURLEnabled = qtrue;
+ return qtrue;
+#endif /* USE_CURL_DLOPEN */
+}
+
+/*
+=================
+CL_cURL_Shutdown
+=================
+*/
+void CL_cURL_Shutdown( void )
+{
+ CL_cURL_Cleanup();
+#if USE_CURL_DLOPEN
+ if(cURLLib)
+ {
+ OBJFREE(cURLLib);
+ cURLLib = NULL;
+ }
+ qcurl_easy_init = NULL;
+ qcurl_easy_setopt = NULL;
+ qcurl_easy_perform = NULL;
+ qcurl_easy_cleanup = NULL;
+ qcurl_easy_getinfo = NULL;
+ qcurl_easy_duphandle = NULL;
+ qcurl_easy_reset = NULL;
+
+ qcurl_multi_init = NULL;
+ qcurl_multi_add_handle = NULL;
+ qcurl_multi_remove_handle = NULL;
+ qcurl_multi_fdset = NULL;
+ qcurl_multi_perform = NULL;
+ qcurl_multi_cleanup = NULL;
+ qcurl_multi_info_read = NULL;
+ qcurl_multi_strerror = NULL;
+#endif /* USE_CURL_DLOPEN */
+}
+
+void CL_cURL_Cleanup(void)
+{
+ if(clc.downloadCURLM) {
+ if(clc.downloadCURL) {
+ qcurl_multi_remove_handle(clc.downloadCURLM,
+ clc.downloadCURL);
+ qcurl_easy_cleanup(clc.downloadCURL);
+ }
+ qcurl_multi_cleanup(clc.downloadCURLM);
+ clc.downloadCURLM = NULL;
+ clc.downloadCURL = NULL;
+ }
+ else if(clc.downloadCURL) {
+ qcurl_easy_cleanup(clc.downloadCURL);
+ clc.downloadCURL = NULL;
+ }
+}
+
+static int CL_cURL_CallbackProgress( void *dummy, double dltotal, double dlnow,
+ double ultotal, double ulnow )
+{
+ clc.downloadSize = (int)dltotal;
+ Cvar_SetValue( "cl_downloadSize", clc.downloadSize );
+ clc.downloadCount = (int)dlnow;
+ Cvar_SetValue( "cl_downloadCount", clc.downloadCount );
+ return 0;
+}
+
+static int CL_cURL_CallbackWrite(void *buffer, size_t size, size_t nmemb,
+ void *stream)
+{
+ FS_Write( buffer, size*nmemb, ((fileHandle_t*)stream)[0] );
+ return size*nmemb;
+}
+
+void CL_cURL_BeginDownload( const char *localName, const char *remoteURL )
+{
+ clc.cURLUsed = qtrue;
+ Com_Printf("URL: %s\n", remoteURL);
+ Com_DPrintf("***** CL_cURL_BeginDownload *****\n"
+ "Localname: %s\n"
+ "RemoteURL: %s\n"
+ "****************************\n", localName, remoteURL);
+ CL_cURL_Cleanup();
+ Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL));
+ Q_strncpyz(clc.downloadName, localName, sizeof(clc.downloadName));
+ Com_sprintf(clc.downloadTempName, sizeof(clc.downloadTempName),
+ "%s.tmp", localName);
+
+ // Set so UI gets access to it
+ Cvar_Set("cl_downloadName", localName);
+ Cvar_Set("cl_downloadSize", "0");
+ Cvar_Set("cl_downloadCount", "0");
+ Cvar_SetValue("cl_downloadTime", cls.realtime);
+
+ clc.downloadBlock = 0; // Starting new file
+ clc.downloadCount = 0;
+
+ clc.downloadCURL = qcurl_easy_init();
+ if(!clc.downloadCURL) {
+ Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_easy_init() "
+ "failed\n");
+ return;
+ }
+ clc.download = FS_SV_FOpenFileWrite(clc.downloadTempName);
+ if(!clc.download) {
+ Com_Error(ERR_DROP, "CL_cURL_BeginDownload: failed to open "
+ "%s for writing\n", clc.downloadTempName);
+ return;
+ }
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, clc.download);
+ if(com_developer->integer)
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_VERBOSE, 1);
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_URL, clc.downloadURL);
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_TRANSFERTEXT, 0);
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_REFERER, va("ioQ3://%s",
+ NET_AdrToString(clc.serverAddress)));
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_USERAGENT, va("%s %s",
+ Q3_VERSION, qcurl_version()));
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEFUNCTION,
+ CL_cURL_CallbackWrite);
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, &clc.download);
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_NOPROGRESS, 0);
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSFUNCTION,
+ CL_cURL_CallbackProgress);
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSDATA, NULL);
+ qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FAILONERROR, 1);
+ clc.downloadCURLM = qcurl_multi_init();
+ if(!clc.downloadCURLM) {
+ qcurl_easy_cleanup(clc.downloadCURL);
+ clc.downloadCURL = NULL;
+ Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_multi_init() "
+ "failed\n");
+ return;
+ }
+ qcurl_multi_add_handle(clc.downloadCURLM, clc.downloadCURL);
+
+ if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) &&
+ !clc.cURLDisconnected) {
+
+ CL_AddReliableCommand("disconnect");
+ CL_WritePacket();
+ CL_WritePacket();
+ CL_WritePacket();
+ clc.cURLDisconnected = qtrue;
+ }
+}
+
+void CL_cURL_PerformDownload(void)
+{
+ CURLMcode res;
+ CURLMsg *msg;
+ int c;
+ int i = 0;
+
+ res = qcurl_multi_perform(clc.downloadCURLM, &c);
+ while(res == CURLM_CALL_MULTI_PERFORM && i < 100) {
+ res = qcurl_multi_perform(clc.downloadCURLM, &c);
+ i++;
+ }
+ if(res == CURLM_CALL_MULTI_PERFORM)
+ return;
+ msg = qcurl_multi_info_read(clc.downloadCURLM, &c);
+ if(msg == NULL) {
+ return;
+ }
+ FS_FCloseFile(clc.download);
+ if(msg->msg == CURLMSG_DONE && msg->data.result == CURLE_OK) {
+ FS_SV_Rename(clc.downloadTempName, clc.downloadName);
+ clc.downloadRestart = qtrue;
+ }
+ else {
+ long code;
+
+ qcurl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE,
+ &code);
+ Com_Error(ERR_DROP, "Download Error: %s Code: %d URL: %s",
+ qcurl_easy_strerror(msg->data.result),
+ code, clc.downloadURL);
+ }
+ *clc.downloadTempName = *clc.downloadName = 0;
+ Cvar_Set( "cl_downloadName", "" );
+ CL_NextDownload();
+}
+#endif /* USE_CURL */
diff --git a/src/client/cl_curl.h b/src/client/cl_curl.h
new file mode 100644
index 00000000..7b3f8929
--- /dev/null
+++ b/src/client/cl_curl.h
@@ -0,0 +1,101 @@
+/*
+===========================================================================
+Copyright (C) 2006 Tony J. White (tjw@tjw.org)
+
+This file is part of Tremulous.
+
+Tremulous is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the License,
+or (at your option) any later version.
+
+Tremulous is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+
+
+#ifndef __QCURL_H__
+#define __QCURL_H__
+
+extern cvar_t *cl_cURLLib;
+
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
+
+#ifdef WIN32
+#define DEFAULT_CURL_LIB "libcurl-3.dll"
+#elif defined(MACOS_X)
+#define DEFAULT_CURL_LIB "libcurl.dylib"
+#else
+#define DEFAULT_CURL_LIB "libcurl.so.3"
+#endif
+
+#if USE_LOCAL_HEADERS
+ #include "../libcurl/curl/curl.h"
+#else
+ #include <curl/curl.h>
+#endif
+
+
+#if USE_CURL_DLOPEN
+extern char* (*qcurl_version)(void);
+
+extern CURL* (*qcurl_easy_init)(void);
+extern CURLcode (*qcurl_easy_setopt)(CURL *curl, CURLoption option, ...);
+extern CURLcode (*qcurl_easy_perform)(CURL *curl);
+extern void (*qcurl_easy_cleanup)(CURL *curl);
+extern CURLcode (*qcurl_easy_getinfo)(CURL *curl, CURLINFO info, ...);
+extern void (*qcurl_easy_reset)(CURL *curl);
+extern const char *(*qcurl_easy_strerror)(CURLcode);
+
+extern CURLM* (*qcurl_multi_init)(void);
+extern CURLMcode (*qcurl_multi_add_handle)(CURLM *multi_handle,
+ CURL *curl_handle);
+extern CURLMcode (*qcurl_multi_remove_handle)(CURLM *multi_handle,
+ CURL *curl_handle);
+extern CURLMcode (*qcurl_multi_fdset)(CURLM *multi_handle,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *exc_fd_set,
+ int *max_fd);
+extern CURLMcode (*qcurl_multi_perform)(CURLM *multi_handle,
+ int *running_handles);
+extern CURLMcode (*qcurl_multi_cleanup)(CURLM *multi_handle);
+extern CURLMsg *(*qcurl_multi_info_read)(CURLM *multi_handle,
+ int *msgs_in_queue);
+extern const char *(*qcurl_multi_strerror)(CURLMcode);
+#else
+#define qcurl_version curl_version
+
+#define qcurl_easy_init curl_easy_init
+#define qcurl_easy_setopt curl_easy_setopt
+#define qcurl_easy_perform curl_easy_perform
+#define qcurl_easy_cleanup curl_easy_cleanup
+#define qcurl_easy_getinfo curl_easy_getinfo
+#define qcurl_easy_duphandle curl_easy_duphandle
+#define qcurl_easy_reset curl_easy_reset
+#define qcurl_easy_strerror curl_easy_strerror
+
+#define qcurl_multi_init curl_multi_init
+#define qcurl_multi_add_handle curl_multi_add_handle
+#define qcurl_multi_remove_handle curl_multi_remove_handle
+#define qcurl_multi_fdset curl_multi_fdset
+#define qcurl_multi_perform curl_multi_perform
+#define qcurl_multi_cleanup curl_multi_cleanup
+#define qcurl_multi_info_read curl_multi_info_read
+#define qcurl_multi_strerror curl_multi_strerror
+#endif
+
+qboolean CL_cURL_Init( void );
+void CL_cURL_Shutdown( void );
+void CL_cURL_BeginDownload( const char *localName, const char *remoteURL );
+void CL_cURL_PerformDownload( void );
+void CL_cURL_Cleanup( void );
+#endif // __QCURL_H__
diff --git a/src/client/cl_keys.c b/src/client/cl_keys.c
index 691a59e2..c65ce916 100644
--- a/src/client/cl_keys.c
+++ b/src/client/cl_keys.c
@@ -1071,7 +1071,8 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
if (!down) {
return;
}
- Con_ToggleConsole_f ();
+ Con_ToggleConsole_f ();
+ Key_ClearStates ();
return;
}
diff --git a/src/client/cl_main.c b/src/client/cl_main.c
index 808553b9..aefbab8c 100644
--- a/src/client/cl_main.c
+++ b/src/client/cl_main.c
@@ -655,6 +655,9 @@ CL_ShutdownAll
*/
void CL_ShutdownAll(void) {
+#if USE_CURL
+ CL_cURL_Shutdown();
+#endif
// clear sounds
S_DisableSounds();
// shutdown CGame
@@ -1159,6 +1162,9 @@ void CL_Vid_Restart_f( void ) {
CL_CloseAVI( );
}
+ if(clc.demorecording)
+ CL_StopRecord_f();
+
// don't let them loop during the restart
S_StopAllSounds();
// shutdown the UI
@@ -1291,6 +1297,23 @@ Called when all downloading has been completed
*/
void CL_DownloadsComplete( void ) {
+#if USE_CURL
+ // if we downloaded with cURL
+ if(clc.cURLUsed) {
+ clc.cURLUsed = qfalse;
+ CL_cURL_Shutdown();
+ if( clc.cURLDisconnected ) {
+ if(clc.downloadRestart) {
+ FS_Restart(clc.checksumFeed);
+ clc.downloadRestart = qfalse;
+ }
+ clc.cURLDisconnected = qfalse;
+ CL_Reconnect_f();
+ return;
+ }
+ }
+#endif
+
// if we downloaded files we need to restart the file system
if (clc.downloadRestart) {
clc.downloadRestart = qfalse;
@@ -1378,6 +1401,7 @@ A download completed or failed
void CL_NextDownload(void) {
char *s;
char *remoteName, *localName;
+ qboolean useCURL = qfalse;
// We are looking to start a download here
if (*clc.downloadList) {
@@ -1401,9 +1425,48 @@ void CL_NextDownload(void) {
*s++ = 0;
else
s = localName + strlen(localName); // point at the nul byte
-
- CL_BeginDownload( localName, remoteName );
-
+#if USE_CURL
+ if(!(cl_allowDownload->integer & DLF_NO_REDIRECT)) {
+ if(clc.sv_allowDownload & DLF_NO_REDIRECT) {
+ Com_Printf("WARNING: server does not "
+ "allow download redirection "
+ "(sv_allowDownload is %d)\n",
+ clc.sv_allowDownload);
+ }
+ else if(!*clc.sv_dlURL) {
+ Com_Printf("WARNING: server allows "
+ "download redirection, but does not "
+ "have sv_dlURL set\n");
+ }
+ else if(!CL_cURL_Init()) {
+ Com_Printf("WARNING: could not load "
+ "cURL library\n");
+ }
+ else {
+ CL_cURL_BeginDownload(localName, va("%s/%s",
+ clc.sv_dlURL, remoteName));
+ useCURL = qtrue;
+ }
+ }
+ else if(!(clc.sv_allowDownload & DLF_NO_REDIRECT)) {
+ Com_Printf("WARNING: server allows download "
+ "redirection, but it disabled by client "
+ "configuration (cl_allowDownload is %d)\n",
+ cl_allowDownload->integer);
+ }
+#endif /* USE_CURL */
+ if(!useCURL) {
+ if((cl_allowDownload->integer & DLF_NO_UDP)) {
+ Com_Error(ERR_DROP, "UDP Downloads are "
+ "disabled on your client. "
+ "(cl_allowDownload is %d)",
+ cl_allowDownload->integer);
+ return;
+ }
+ else {
+ CL_BeginDownload( localName, remoteName );
+ }
+ }
clc.downloadRestart = qtrue;
// move over the rest
@@ -1426,7 +1489,7 @@ and determine if we need to download them
void CL_InitDownloads(void) {
char missingfiles[1024];
- if ( !cl_allowDownload->integer )
+ if ( !(cl_allowDownload->integer & DLF_ENABLE) )
{
// autodownload is disabled on the client
// but it's possible that some referenced files on the server are missing
@@ -1911,7 +1974,7 @@ void CL_CheckTimeout( void ) {
//
// check timeout
//
- if ( ( !cl_paused->integer || !sv_paused->integer )
+ if ( ( !CL_CheckPaused() || !sv_paused->integer )
&& cls.state >= CA_CONNECTED && cls.state != CA_CINEMATIC
&& cls.realtime - clc.lastPacketTime > cl_timeout->value*1000) {
if (++cl.timeoutcount > 5) { // timeoutcount saves debugger
@@ -1924,6 +1987,22 @@ void CL_CheckTimeout( void ) {
}
}
+/*
+==================
+CL_CheckPaused
+Check whether client has been paused.
+==================
+*/
+qboolean CL_CheckPaused(void)
+{
+ // if cl_paused->modified is set, the cvar has only been changed in
+ // this frame. Keep paused in this frame to ensure the server doesn't
+ // lag behind.
+ if(cl_paused->integer || cl_paused->modified)
+ return qtrue;
+
+ return qfalse;
+}
//============================================================================
@@ -1935,19 +2014,19 @@ CL_CheckUserinfo
*/
void CL_CheckUserinfo( void ) {
// don't add reliable commands when not yet connected
- if ( cls.state < CA_CHALLENGING ) {
+ if(cls.state < CA_CHALLENGING)
return;
- }
+
// don't overflow the reliable command buffer when paused
- if ( cl_paused->integer ) {
+ if(CL_CheckPaused())
return;
- }
+
// send a reliable userinfo update if needed
- if ( cvar_modifiedFlags & CVAR_USERINFO ) {
+ if(cvar_modifiedFlags & CVAR_USERINFO)
+ {
cvar_modifiedFlags &= ~CVAR_USERINFO;
CL_AddReliableCommand( va("userinfo \"%s\"", Cvar_InfoString( CVAR_USERINFO ) ) );
}
-
}
/*
@@ -1962,6 +2041,25 @@ void CL_Frame ( int msec ) {
return;
}
+#if USE_CURL
+ if(clc.downloadCURLM) {
+ CL_cURL_PerformDownload();
+ // we can't process frames normally when in disconnected
+ // download mode since the ui vm expects cls.state to be
+ // CA_CONNECTED
+ if(clc.cURLDisconnected) {
+ cls.realFrametime = msec;
+ cls.frametime = msec;
+ cls.realtime += cls.frametime;
+ SCR_UpdateScreen();
+ S_Update();
+ Con_RunConsole();
+ cls.framecount++;
+ return;
+ }
+ }
+#endif
+
if ( cls.state == CA_DISCONNECTED && !( cls.keyCatchers & KEYCATCH_UI )
&& !com_sv_running->integer ) {
// if disconnected, bring up the menu
@@ -2273,6 +2371,12 @@ void CL_Video_f( void )
char filename[ MAX_OSPATH ];
int i, last;
+ if( !clc.demoplaying )
+ {
+ Com_Printf( "The video command can only be used when playing back demos\n" );
+ return;
+ }
+
if( Cmd_Argc( ) == 2 )
{
// explicit filename
@@ -2404,6 +2508,9 @@ void CL_Init( void ) {
cl_showMouseRate = Cvar_Get ("cl_showmouserate", "0", 0);
cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE);
+#if USE_CURL
+ cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE);
+#endif
cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0);
#ifdef MACOS_X
@@ -2718,7 +2825,7 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
Q_strncpyz( info, MSG_ReadString( msg ), MAX_INFO_STRING );
if (strlen(info)) {
if (info[strlen(info)-1] != '\n') {
- strncat(info, "\n", sizeof(info));
+ strncat(info, "\n", sizeof(info) - 1);
}
Com_Printf( "%s: %s", NET_AdrToString( from ), info );
}
diff --git a/src/client/cl_parse.c b/src/client/cl_parse.c
index 7de07e91..093893a6 100644
--- a/src/client/cl_parse.c
+++ b/src/client/cl_parse.c
@@ -220,6 +220,10 @@ void CL_ParseSnapshot( msg_t *msg ) {
newSnap.serverTime = MSG_ReadLong( msg );
+ // if we were just unpaused, we can only *now* really let the
+ // change come into effect or the client hangs.
+ cl_paused->modified = 0;
+
newSnap.messageNum = clc.serverMessageSequence;
deltaNum = MSG_ReadByte( msg );
@@ -411,6 +415,25 @@ void CL_SystemInfoChanged( void ) {
/*
==================
+CL_ParseServerInfo
+==================
+*/
+static void CL_ParseServerInfo(void)
+{
+ const char *serverInfo;
+
+ serverInfo = cl.gameState.stringData
+ + cl.gameState.stringOffsets[ CS_SERVERINFO ];
+
+ clc.sv_allowDownload = atoi(Info_ValueForKey(serverInfo,
+ "sv_allowDownload"));
+ Q_strncpyz(clc.sv_dlURL,
+ Info_ValueForKey(serverInfo, "sv_dlURL"),
+ sizeof(clc.sv_dlURL));
+}
+
+/*
+==================
CL_ParseGamestate
==================
*/
@@ -476,11 +499,18 @@ void CL_ParseGamestate( msg_t *msg ) {
// read the checksum feed
clc.checksumFeed = MSG_ReadLong( msg );
+ // parse useful values out of CS_SERVERINFO
+ CL_ParseServerInfo();
+
// parse serverId and other cvars
CL_SystemInfoChanged();
+ // stop recording now so the demo won't have an unnecessary level load at the end.
+ if(cl_autoRecordDemo->integer && clc.demorecording)
+ CL_StopRecord_f();
+
// reinitialize the filesystem if the game directory has changed
- FS_ConditionalRestart( clc.checksumFeed );
+ FS_ConditionalRestart( clc.checksumFeed );
// This used to call CL_StartHunkUsers, but now we enter the download state before loading the
// cgame
diff --git a/src/client/cl_ui.c b/src/client/cl_ui.c
index 327eaacf..caa9179f 100644
--- a/src/client/cl_ui.c
+++ b/src/client/cl_ui.c
@@ -603,10 +603,10 @@ static void CL_GetGlconfig( glconfig_t *config ) {
/*
====================
-GetClipboardData
+CL_GetClipboardData
====================
*/
-static void GetClipboardData( char *buf, int buflen ) {
+static void CL_GetClipboardData( char *buf, int buflen ) {
char *cbd;
cbd = Sys_GetClipboardData();
@@ -836,7 +836,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
return 0;
case UI_GETCLIPBOARDDATA:
- GetClipboardData( VMA(1), args[2] );
+ CL_GetClipboardData( VMA(1), args[2] );
return 0;
case UI_GETCLIENTSTATE:
diff --git a/src/client/client.h b/src/client/client.h
index ae5915db..77cf7dca 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -31,12 +31,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../cgame/cg_public.h"
#include "../game/bg_public.h"
+#if USE_CURL
+#include "cl_curl.h"
+#endif /* USE_CURL */
+
// tjw: file full of random crap that gets used to create cl_guid
#define QKEY_FILE "qkey"
#define RETRANSMIT_TIMEOUT 3000 // time between connection packet retransmits
-
// snapshots are a view of the server at a given time
typedef struct {
qboolean valid; // cleared if delta parsing was invalid
@@ -187,6 +190,16 @@ typedef struct {
fileHandle_t download;
char downloadTempName[MAX_OSPATH];
char downloadName[MAX_OSPATH];
+#ifdef USE_CURL
+ qboolean cURLEnabled;
+ qboolean cURLUsed;
+ qboolean cURLDisconnected;
+ char downloadURL[MAX_OSPATH];
+ CURL *downloadCURL;
+ CURLM *downloadCURLM;
+#endif /* USE_CURL */
+ int sv_allowDownload;
+ char sv_dlURL[MAX_CVAR_VALUE_STRING];
int downloadNumber;
int downloadBlock; // block we are waiting for
int downloadCount; // how many bytes we got
@@ -352,10 +365,12 @@ extern cvar_t *cl_aviMotionJpeg;
extern cvar_t *cl_activeAction;
extern cvar_t *cl_allowDownload;
+extern cvar_t *cl_downloadMethod;
extern cvar_t *cl_conXOffset;
extern cvar_t *cl_inGameVideo;
extern cvar_t *cl_lanForcePackets;
+extern cvar_t *cl_autoRecordDemo;
//=================================================
@@ -380,6 +395,7 @@ void CL_ReadDemoMessage( void );
demoState_t CL_DemoState( void );
int CL_DemoPos( void );
void CL_DemoName( char *buffer, int size );
+void CL_StopRecord_f( void );
void CL_InitDownloads(void);
void CL_NextDownload(void);
@@ -393,6 +409,7 @@ void CL_ShutdownRef( void );
void CL_InitRef( void );
int CL_ServerStatus( char *serverAddress, char *serverStatusString, int maxLen );
+qboolean CL_CheckPaused(void);
//
// cl_input
diff --git a/src/client/qal.c b/src/client/qal.c
index b206881f..4c04bd41 100644
--- a/src/client/qal.c
+++ b/src/client/qal.c
@@ -177,8 +177,8 @@ qboolean QAL_Init(const char *libname)
#else
char fn[1024];
getcwd(fn, sizeof(fn));
- strncat(fn, "/", sizeof(fn));
- strncat(fn, libname, sizeof(fn));
+ strncat(fn, "/", sizeof(fn) - strlen(fn) - 1);
+ strncat(fn, libname, sizeof(fn) - strlen(fn) - 1);
if( (OpenALLib = OBJLOAD(fn)) == 0 )
{
diff --git a/src/client/snd_codec_ogg.c b/src/client/snd_codec_ogg.c
index 72ece944..f13f9a8d 100644
--- a/src/client/snd_codec_ogg.c
+++ b/src/client/snd_codec_ogg.c
@@ -4,20 +4,20 @@ Copyright (C) 1999-2005 Id Software, Inc.
Copyright (C) 2005 Stuart Dalton (badcdev@gmail.com)
Copyright (C) 2005-2006 Joerg Dietrich <dietrich_joerg@gmx.de>
-This file is part of Quake III Arena source code.
+This file is part of Tremulous.
-Quake III Arena source code is free software; you can redistribute it
+Tremulous is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
-Quake III Arena source code is distributed in the hope that it will be
+Tremulous is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
+along with Tremulous; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
diff --git a/src/client/snd_main.c b/src/client/snd_main.c
index 8f09570e..eb31f2d7 100644
--- a/src/client/snd_main.c
+++ b/src/client/snd_main.c
@@ -405,9 +405,9 @@ void S_Init( void )
}
S_SoundInfo( );
- Com_Printf( "Sound intialization successful.\n" );
+ Com_Printf( "Sound initialization successful.\n" );
} else {
- Com_Printf( "Sound intialization failed.\n" );
+ Com_Printf( "Sound initialization failed.\n" );
}
}
diff --git a/src/client/snd_openal.c b/src/client/snd_openal.c
index 39a04179..6f5396c4 100644
--- a/src/client/snd_openal.c
+++ b/src/client/snd_openal.c
@@ -37,8 +37,12 @@ cvar_t *s_alSources;
cvar_t *s_alDopplerFactor;
cvar_t *s_alDopplerSpeed;
cvar_t *s_alMinDistance;
+cvar_t *s_alMaxDistance;
cvar_t *s_alRolloff;
+cvar_t *s_alGraceDistance;
cvar_t *s_alDriver;
+cvar_t *s_alDevice;
+cvar_t *s_alAvailableDevices;
cvar_t *s_alMaxSpeakerDistance;
/*
@@ -134,7 +138,11 @@ static sfxHandle_t S_AL_BufferFindFree( void )
{
// Got one
if(knownSfx[i].filename[0] == '\0')
+ {
+ if(i >= numSfx)
+ numSfx = i + 1;
return i;
+ }
}
// Shit...
@@ -155,7 +163,7 @@ static sfxHandle_t S_AL_BufferFind(const char *filename)
sfxHandle_t sfx = -1;
int i;
- for(i = 0; i < MAX_SFX; i++)
+ for(i = 0; i < numSfx; i++)
{
if(!Q_stricmp(knownSfx[i].filename, filename))
{
@@ -230,7 +238,7 @@ static qboolean S_AL_BufferEvict( void )
int i, oldestBuffer = -1;
int oldestTime = Sys_Milliseconds( );
- for( i = 0; i < MAX_SFX; i++ )
+ for( i = 0; i < numSfx; i++ )
{
if( !knownSfx[ i ].filename[ 0 ] )
continue;
@@ -404,7 +412,7 @@ void S_AL_BufferShutdown( void )
knownSfx[default_sfx].isLocked = qfalse;
// Free all used effects
- for(i = 0; i < MAX_SFX; i++)
+ for(i = 0; i < numSfx; i++)
S_AL_BufferUnload(i);
// Clear the tables
@@ -463,6 +471,9 @@ typedef struct src_s
int isLooping; // Is this a looping effect (attached to an entity)
int isTracking; // Is this object tracking it's owner
+ float curGain; // gain employed if source is within maxdistance.
+ float scaleGain; // Last gain value for this source. 0 if muted.
+
qboolean local; // Is this local (relative to the cam)
} src_t;
@@ -512,6 +523,50 @@ static void _S_AL_SanitiseVector( vec3_t v, int line )
/*
=================
+S_AL_ScaleGain
+Adapt the gain if necessary to get a quicker fadeout when the source is too far away.
+=================
+*/
+
+static void S_AL_ScaleGain(src_t *chksrc, vec3_t origin)
+{
+ float distance;
+
+ if(chksrc->local)
+ distance = VectorLength(origin);
+ else
+ distance = Distance(origin, lastListenerOrigin);
+
+ // If we exceed a certain distance, scale the gain linearly until the sound
+ // vanishes into nothingness.
+ if((distance -= s_alMaxDistance->value) > 0)
+ {
+ float scaleFactor;
+
+ if(distance >= s_alGraceDistance->value)
+ scaleFactor = 0.0f;
+ else
+ scaleFactor = 1.0f - distance / s_alGraceDistance->value;
+
+ scaleFactor *= chksrc->curGain;
+
+ if(chksrc->scaleGain != scaleFactor);
+ {
+ chksrc->scaleGain = scaleFactor;
+ // if(scaleFactor > 0.0f)
+ // Com_Printf("%f\n", scaleFactor);
+ qalSourcef(chksrc->alSource, AL_GAIN, chksrc->scaleGain);
+ }
+ }
+ else if(chksrc->scaleGain != chksrc->curGain)
+ {
+ chksrc->scaleGain = chksrc->curGain;
+ qalSourcef(chksrc->alSource, AL_GAIN, chksrc->scaleGain);
+ }
+}
+
+/*
+=================
S_AL_HearingThroughEntity
=================
*/
@@ -615,41 +670,46 @@ static void S_AL_SrcSetup(srcHandle_t src, sfxHandle_t sfx, alSrcPriority_t prio
int entity, int channel, qboolean local)
{
ALuint buffer;
+ src_t *curSource;
// Mark the SFX as used, and grab the raw AL buffer
S_AL_BufferUse(sfx);
buffer = S_AL_BufferGet(sfx);
// Set up src struct
- srcList[src].lastUsedTime = Sys_Milliseconds();
- srcList[src].sfx = sfx;
- srcList[src].priority = priority;
- srcList[src].entity = entity;
- srcList[src].channel = channel;
- srcList[src].isActive = qtrue;
- srcList[src].isLocked = qfalse;
- srcList[src].isLooping = qfalse;
- srcList[src].isTracking = qfalse;
- srcList[src].local = local;
+ curSource = &srcList[src];
+
+ curSource->lastUsedTime = Sys_Milliseconds();
+ curSource->sfx = sfx;
+ curSource->priority = priority;
+ curSource->entity = entity;
+ curSource->channel = channel;
+ curSource->isActive = qtrue;
+ curSource->isLocked = qfalse;
+ curSource->isLooping = qfalse;
+ curSource->isTracking = qfalse;
+ curSource->curGain = s_alGain->value * s_volume->value;
+ curSource->scaleGain = curSource->curGain;
+ curSource->local = local;
// Set up OpenAL source
- qalSourcei(srcList[src].alSource, AL_BUFFER, buffer);
- qalSourcef(srcList[src].alSource, AL_PITCH, 1.0f);
- qalSourcef(srcList[src].alSource, AL_GAIN, s_alGain->value * s_volume->value);
- qalSourcefv(srcList[src].alSource, AL_POSITION, vec3_origin);
- qalSourcefv(srcList[src].alSource, AL_VELOCITY, vec3_origin);
- qalSourcei(srcList[src].alSource, AL_LOOPING, AL_FALSE);
- qalSourcef(srcList[src].alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
+ qalSourcei(curSource->alSource, AL_BUFFER, buffer);
+ qalSourcef(curSource->alSource, AL_PITCH, 1.0f);
+ qalSourcef(curSource->alSource, AL_GAIN, curSource->curGain);
+ qalSourcefv(curSource->alSource, AL_POSITION, vec3_origin);
+ qalSourcefv(curSource->alSource, AL_VELOCITY, vec3_origin);
+ qalSourcei(curSource->alSource, AL_LOOPING, AL_FALSE);
+ qalSourcef(curSource->alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
if(local)
{
- qalSourcei(srcList[src].alSource, AL_SOURCE_RELATIVE, AL_TRUE);
- qalSourcef(srcList[src].alSource, AL_ROLLOFF_FACTOR, 0.0f);
+ qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, 0.0f);
}
else
{
- qalSourcei(srcList[src].alSource, AL_SOURCE_RELATIVE, AL_FALSE);
- qalSourcef(srcList[src].alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
+ qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_FALSE);
+ qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
}
}
@@ -825,6 +885,27 @@ void S_AL_UpdateEntityPosition( int entityNum, const vec3_t origin )
/*
=================
+S_AL_CheckInput
+Check whether input values from mods are out of range.
+Necessary for i.g. Western Quake3 mod which is buggy.
+=================
+*/
+static qboolean S_AL_CheckInput(int entityNum, sfxHandle_t sfx)
+{
+ if (entityNum < 0 || entityNum > MAX_GENTITIES)
+ Com_Error(ERR_DROP, "S_StartSound: bad entitynum %i", entityNum);
+
+ if (sfx < 0 || sfx >= numSfx)
+ {
+ Com_Printf(S_COLOR_RED, "ERROR: S_AL_CheckInput: handle %i out of range\n", sfx);
+ return qtrue;
+ }
+
+ return qfalse;
+}
+
+/*
+=================
S_AL_StartLocalSound
Play a local (non-spatialized) sound effect
@@ -833,6 +914,9 @@ Play a local (non-spatialized) sound effect
static
void S_AL_StartLocalSound(sfxHandle_t sfx, int channel)
{
+ if(S_AL_CheckInput(0, sfx))
+ return;
+
// Try to grab a source
srcHandle_t src = S_AL_SrcAlloc(SRCPRI_LOCAL, -1, channel);
if(src == -1)
@@ -857,6 +941,9 @@ void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx
{
vec3_t sorigin;
+ if(S_AL_CheckInput(origin ? 0 : entnum, sfx))
+ return;
+
// Try to grab a source
srcHandle_t src = S_AL_SrcAlloc(SRCPRI_ONESHOT, entnum, entchannel);
if(src == -1)
@@ -865,8 +952,6 @@ void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx
// Set up the effect
if( origin == NULL )
{
- srcList[ src ].isTracking = qtrue;
-
if( S_AL_HearingThroughEntity( entnum ) )
{
// Where the entity is the local player, play a local sound
@@ -878,6 +963,7 @@ void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx
S_AL_SrcSetup( src, sfx, SRCPRI_ONESHOT, entnum, entchannel, qfalse );
VectorCopy( entityList[ entnum ].origin, sorigin );
}
+ srcList[ src ].isTracking = qtrue;
}
else
{
@@ -887,6 +973,7 @@ void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx
S_AL_SanitiseVector( sorigin );
qalSourcefv( srcList[ src ].alSource, AL_POSITION, sorigin );
+ S_AL_ScaleGain(&srcList[src], sorigin);
// Start it playing
qalSourcePlay(srcList[src].alSource);
@@ -918,6 +1005,7 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
{
int src;
sentity_t *sent = &entityList[ entityNum ];
+ src_t *curSource;
// Do we need to allocate a new source for this entity
if( !sent->srcAllocated )
@@ -945,28 +1033,33 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
// If this is not set then the looping sound is removed
sent->loopAddedThisFrame = qtrue;
+ curSource = &srcList[src];
+
// UGH
// These lines should be called via S_AL_SrcSetup, but we
// can't call that yet as it buffers sfxes that may change
// with subsequent calls to S_AL_SrcLoop
- srcList[ src ].entity = entityNum;
- srcList[ src ].isLooping = qtrue;
- srcList[ src ].isActive = qtrue;
+ curSource->entity = entityNum;
+ curSource->isLooping = qtrue;
+ curSource->isActive = qtrue;
if( S_AL_HearingThroughEntity( entityNum ) )
{
- srcList[ src ].local = qtrue;
+ curSource->local = qtrue;
- qalSourcefv( srcList[ src ].alSource, AL_POSITION, vec3_origin );
- qalSourcefv( srcList[ src ].alSource, AL_VELOCITY, vec3_origin );
+ qalSourcefv( curSource->alSource, AL_POSITION, vec3_origin );
+ qalSourcefv( curSource->alSource, AL_VELOCITY, vec3_origin );
}
else
{
- srcList[ src ].local = qfalse;
+ curSource->local = qfalse;
- qalSourcefv( srcList[ src ].alSource, AL_POSITION, (ALfloat *)sent->origin );
- qalSourcefv( srcList[ src ].alSource, AL_VELOCITY, (ALfloat *)velocity );
+ qalSourcefv( curSource->alSource, AL_POSITION, (ALfloat *)sent->origin );
+ qalSourcefv( curSource->alSource, AL_VELOCITY, (ALfloat *)velocity );
+
}
+
+ S_AL_ScaleGain(curSource, sent->origin);
}
/*
@@ -977,6 +1070,9 @@ S_AL_AddLoopingSound
static
void S_AL_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx )
{
+ if(S_AL_CheckInput(entityNum, sfx))
+ return;
+
S_AL_SanitiseVector( (vec_t *)origin );
S_AL_SanitiseVector( (vec_t *)velocity );
S_AL_SrcLoop(SRCPRI_ENTITY, sfx, origin, velocity, entityNum);
@@ -990,6 +1086,9 @@ S_AL_AddRealLoopingSound
static
void S_AL_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx )
{
+ if(S_AL_CheckInput(entityNum, sfx))
+ return;
+
S_AL_SanitiseVector( (vec_t *)origin );
S_AL_SanitiseVector( (vec_t *)velocity );
@@ -1028,63 +1127,65 @@ void S_AL_SrcUpdate( void )
int i;
int entityNum;
ALint state;
+ src_t *curSource;
for(i = 0; i < srcCount; i++)
{
entityNum = srcList[i].entity;
+ curSource = &srcList[i];
- if(srcList[i].isLocked)
+ if(curSource->isLocked)
continue;
- if(!srcList[i].isActive)
+ if(!curSource->isActive)
continue;
// Update source parameters
if((s_alGain->modified)||(s_volume->modified))
- qalSourcef(srcList[i].alSource, AL_GAIN, s_alGain->value * s_volume->value);
- if((s_alRolloff->modified)&&(!srcList[i].local))
- qalSourcef(srcList[i].alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
+ curSource->curGain = s_alGain->value * s_volume->value;
+ if((s_alRolloff->modified)&&(!curSource->local))
+ qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
if(s_alMinDistance->modified)
- qalSourcef(srcList[i].alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
+ qalSourcef(curSource->alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
- if( srcList[ i ].isLooping )
+ if(curSource->isLooping)
{
sentity_t *sent = &entityList[ entityNum ];
// If a looping effect hasn't been touched this frame, kill it
- if( sent->loopAddedThisFrame )
+ if(sent->loopAddedThisFrame)
{
// The sound has changed without an intervening removal
- if( srcList[ i ].isActive && !sent->startLoopingSound &&
- srcList[ i ].sfx != sent->loopSfx )
+ if(curSource->isActive && !sent->startLoopingSound &&
+ curSource->sfx != sent->loopSfx)
{
- qalSourceStop( srcList[ i ].alSource );
- qalSourcei( srcList[ i ].alSource, AL_BUFFER, 0 );
+ qalSourceStop(curSource->alSource);
+ qalSourcei(curSource->alSource, AL_BUFFER, 0);
sent->startLoopingSound = qtrue;
}
- // Ths sound hasn't been started yet
- if( sent->startLoopingSound )
+ // The sound hasn't been started yet
+ if(sent->startLoopingSound)
{
- S_AL_SrcSetup( i, sent->loopSfx, sent->loopPriority,
- entityNum, -1, srcList[ i ].local );
- srcList[ i ].isLooping = qtrue;
- qalSourcei( srcList[ i ].alSource, AL_LOOPING, AL_TRUE );
- qalSourcePlay( srcList[ i ].alSource );
+ S_AL_SrcSetup(i, sent->loopSfx, sent->loopPriority,
+ entityNum, -1, curSource->local);
+ curSource->isLooping = qtrue;
+ qalSourcei(curSource->alSource, AL_LOOPING, AL_TRUE);
+ qalSourcePlay(curSource->alSource);
sent->startLoopingSound = qfalse;
}
// Update locality
- if( srcList[ i ].local)
+ if(curSource->local)
{
- qalSourcei( srcList[ i ].alSource, AL_SOURCE_RELATIVE, AL_TRUE );
- qalSourcef( srcList[ i ].alSource, AL_ROLLOFF_FACTOR, 0.0f );
+ qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, 0.0f);
}
else
{
- qalSourcei( srcList[ i ].alSource, AL_SOURCE_RELATIVE, AL_FALSE );
- qalSourcef( srcList[ i ].alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value );
+ qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_FALSE);
+ qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
}
}
else
@@ -1093,20 +1194,23 @@ void S_AL_SrcUpdate( void )
continue;
}
- // Query relativity of source, don't move if it's true
- qalGetSourcei( srcList[ i ].alSource, AL_SOURCE_RELATIVE, &state );
-
- // See if it needs to be moved
- if( srcList[ i ].isTracking && !state )
- qalSourcefv(srcList[i].alSource, AL_POSITION, entityList[entityNum].origin);
-
// Check if it's done, and flag it
- qalGetSourcei(srcList[i].alSource, AL_SOURCE_STATE, &state);
+ qalGetSourcei(curSource->alSource, AL_SOURCE_STATE, &state);
if(state == AL_STOPPED)
{
S_AL_SrcKill(i);
continue;
}
+
+ // Query relativity of source, don't move if it's true
+ qalGetSourcei(curSource->alSource, AL_SOURCE_RELATIVE, &state);
+
+ // See if it needs to be moved
+ if(curSource->isTracking && !state)
+ {
+ qalSourcefv(curSource->alSource, AL_POSITION, entityList[entityNum].origin);
+ S_AL_ScaleGain(curSource, entityList[entityNum].origin);
+ }
}
}
@@ -1290,6 +1394,7 @@ static ALuint musicSource;
static ALuint musicBuffers[NUM_MUSIC_BUFFERS];
static snd_stream_t *mus_stream;
+static snd_stream_t *intro_stream;
static char s_backgroundLoop[MAX_QPATH];
static byte decode_buffer[MUSIC_BUFFER_SIZE];
@@ -1333,6 +1438,26 @@ static void S_AL_MusicSourceFree( void )
/*
=================
+S_AL_CloseMusicFiles
+=================
+*/
+static void S_AL_CloseMusicFiles(void)
+{
+ if(intro_stream)
+ {
+ S_CodecCloseStream(intro_stream);
+ intro_stream = NULL;
+ }
+
+ if(mus_stream)
+ {
+ S_CodecCloseStream(mus_stream);
+ mus_stream = NULL;
+ }
+}
+
+/*
+=================
S_AL_StopBackgroundTrack
=================
*/
@@ -1355,9 +1480,7 @@ void S_AL_StopBackgroundTrack( void )
S_AL_MusicSourceFree();
// Unload the stream
- if(mus_stream)
- S_CodecCloseStream(mus_stream);
- mus_stream = NULL;
+ S_AL_CloseMusicFiles();
musicPlaying = qfalse;
}
@@ -1373,27 +1496,42 @@ void S_AL_MusicProcess(ALuint b)
ALenum error;
int l;
ALuint format;
+ snd_stream_t *curstream;
- if(!mus_stream)
+ if(intro_stream)
+ curstream = intro_stream;
+ else
+ curstream = mus_stream;
+
+ if(!curstream)
return;
- l = S_CodecReadStream(mus_stream, MUSIC_BUFFER_SIZE, decode_buffer);
+ l = S_CodecReadStream(curstream, MUSIC_BUFFER_SIZE, decode_buffer);
// Run out data to read, start at the beginning again
if(l == 0)
{
- S_CodecCloseStream(mus_stream);
- mus_stream = S_CodecOpenStream(s_backgroundLoop);
- if(!mus_stream)
+ S_CodecCloseStream(curstream);
+
+ // the intro stream just finished playing so we don't need to reopen
+ // the music stream.
+ if(intro_stream)
+ intro_stream = NULL;
+ else
+ mus_stream = S_CodecOpenStream(s_backgroundLoop);
+
+ curstream = mus_stream;
+
+ if(!curstream)
{
S_AL_StopBackgroundTrack();
return;
}
- l = S_CodecReadStream(mus_stream, MUSIC_BUFFER_SIZE, decode_buffer);
+ l = S_CodecReadStream(curstream, MUSIC_BUFFER_SIZE, decode_buffer);
}
- format = S_AL_Format(mus_stream->info.width, mus_stream->info.channels);
+ format = S_AL_Format(curstream->info.width, curstream->info.channels);
if( l == 0 )
{
@@ -1403,7 +1541,7 @@ void S_AL_MusicProcess(ALuint b)
qalBufferData( b, AL_FORMAT_MONO16, (void *)dummyData, 2, 22050 );
}
else
- qalBufferData(b, format, decode_buffer, l, mus_stream->info.rate);
+ qalBufferData(b, format, decode_buffer, l, curstream->info.rate);
if( ( error = qalGetError( ) ) != AL_NO_ERROR )
{
@@ -1423,27 +1561,12 @@ static
void S_AL_StartBackgroundTrack( const char *intro, const char *loop )
{
int i;
+ qboolean issame;
// Stop any existing music that might be playing
S_AL_StopBackgroundTrack();
- if ( !intro || !intro[0] ) {
- intro = loop;
- }
- if ( !loop || !loop[0] ) {
- loop = intro;
- }
-
- if((!intro || !intro[0]) && (!intro || !intro[0]))
- return;
-
- // Copy the loop over
- strncpy( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );
-
- // Open the intro
- mus_stream = S_CodecOpenStream(intro);
-
- if(!mus_stream)
+ if((!intro || !*intro) && (!loop || !*loop))
return;
// Allocate a musicSource
@@ -1451,9 +1574,32 @@ void S_AL_StartBackgroundTrack( const char *intro, const char *loop )
if(musicSourceHandle == -1)
return;
+ if (!loop || !*loop)
+ {
+ loop = intro;
+ issame = qtrue;
+ }
+ else if(intro && *intro && !strcmp(intro, loop))
+ issame = qtrue;
+ else
+ issame = qfalse;
+
+ // Copy the loop over
+ strncpy( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );
+
+ if(!issame)
+ {
+ // Open the intro and don't mind whether it succeeds.
+ // The important part is the loop.
+ intro_stream = S_CodecOpenStream(intro);
+ }
+ else
+ intro_stream = NULL;
+
mus_stream = S_CodecOpenStream(s_backgroundLoop);
if(!mus_stream)
{
+ S_AL_CloseMusicFiles();
S_AL_MusicSourceFree();
return;
}
@@ -1526,6 +1672,7 @@ static ALCcontext *alContext;
#ifdef _WIN32
#define ALDRIVER_DEFAULT "OpenAL32.dll"
+#define ALDEVICE_DEFAULT "Generic Software"
#elif defined(MACOS_X)
#define ALDRIVER_DEFAULT "/System/Library/Frameworks/OpenAL.framework/OpenAL"
#else
@@ -1674,7 +1821,11 @@ void S_AL_SoundInfo( void )
Com_Printf( " Version: %s\n", qalGetString( AL_VERSION ) );
Com_Printf( " Renderer: %s\n", qalGetString( AL_RENDERER ) );
Com_Printf( " Extensions: %s\n", qalGetString( AL_EXTENSIONS ) );
-
+ if(qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
+ {
+ Com_Printf(" Device: %s\n", qalcGetString(alDevice, ALC_DEVICE_SPECIFIER));
+ Com_Printf("Available Devices:\n%s", s_alAvailableDevices->string);
+ }
}
/*
@@ -1714,6 +1865,9 @@ S_AL_Init
qboolean S_AL_Init( soundInterface_t *si )
{
#if USE_OPENAL
+
+ qboolean enumsupport, founddev = qfalse;
+
if( !si ) {
return qfalse;
}
@@ -1725,7 +1879,9 @@ qboolean S_AL_Init( soundInterface_t *si )
s_alDopplerFactor = Cvar_Get( "s_alDopplerFactor", "1.0", CVAR_ARCHIVE );
s_alDopplerSpeed = Cvar_Get( "s_alDopplerSpeed", "2200", CVAR_ARCHIVE );
s_alMinDistance = Cvar_Get( "s_alMinDistance", "120", CVAR_CHEAT );
- s_alRolloff = Cvar_Get( "s_alRolloff", "0.8", CVAR_CHEAT );
+ s_alMaxDistance = Cvar_Get("s_alMaxDistance", "1024", CVAR_CHEAT);
+ s_alRolloff = Cvar_Get( "s_alRolloff", "2", CVAR_CHEAT);
+ s_alGraceDistance = Cvar_Get("s_alGraceDistance", "512", CVAR_CHEAT);
s_alMaxSpeakerDistance = Cvar_Get( "s_alMaxSpeakerDistance", "1024", CVAR_ARCHIVE );
s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE );
@@ -1737,8 +1893,56 @@ qboolean S_AL_Init( soundInterface_t *si )
return qfalse;
}
- // Open default device
- alDevice = qalcOpenDevice( NULL );
+ // Device enumeration support (extension is implemented reasonably only on Windows right now).
+ if((enumsupport = qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")))
+ {
+ char devicenames[1024] = "";
+ const char *devicelist;
+ const char *defaultdevice;
+ int curlen;
+
+ // get all available devices + the default device name.
+ devicelist = qalcGetString(NULL, ALC_DEVICE_SPECIFIER);
+ defaultdevice = qalcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
+
+#ifdef _WIN32
+ // check whether the default device is generic hardware. If it is, change to
+ // Generic Software as that one works more reliably with various sound systems.
+ // If it's not, use OpenAL's default selection as we don't want to ignore
+ // native hardware acceleration.
+ if(!strcmp(defaultdevice, "Generic Hardware"))
+ s_alDevice = Cvar_Get("s_alDevice", ALDEVICE_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH);
+ else
+#endif
+ s_alDevice = Cvar_Get("s_alDevice", defaultdevice, CVAR_ARCHIVE | CVAR_LATCH);
+
+ // dump a list of available devices to a cvar for the user to see.
+ while((curlen = strlen(devicelist)))
+ {
+ Q_strcat(devicenames, sizeof(devicenames), devicelist);
+ Q_strcat(devicenames, sizeof(devicenames), "\n");
+
+ // check whether the device we want to load is available at all.
+ if(!strcmp(s_alDevice->string, devicelist))
+ founddev = qtrue;
+
+ devicelist += curlen + 1;
+ }
+
+ s_alAvailableDevices = Cvar_Get("s_alAvailableDevices", devicenames, CVAR_ROM | CVAR_NORESTART);
+
+ if(!founddev)
+ {
+ Cvar_ForceReset("s_alDevice");
+ founddev = 1;
+ }
+ }
+
+ if(founddev)
+ alDevice = qalcOpenDevice(s_alDevice->string);
+ else
+ alDevice = qalcOpenDevice(NULL);
+
if( !alDevice )
{
QAL_Shutdown( );
@@ -1746,6 +1950,9 @@ qboolean S_AL_Init( soundInterface_t *si )
return qfalse;
}
+ if(enumsupport)
+ Cvar_Set("s_alDevice", qalcGetString(alDevice, ALC_DEVICE_SPECIFIER));
+
// Create OpenAL context
alContext = qalcCreateContext( alDevice, NULL );
if( !alContext )
@@ -1762,6 +1969,7 @@ qboolean S_AL_Init( soundInterface_t *si )
S_AL_SrcInit( );
// Set up OpenAL parameters (doppler, etc)
+ qalDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
qalDopplerFactor( s_alDopplerFactor->value );
qalDopplerVelocity( s_alDopplerSpeed->value );
diff --git a/src/libcurl/curl/curl.h b/src/libcurl/curl/curl.h
new file mode 100644
index 00000000..a0a04148
--- /dev/null
+++ b/src/libcurl/curl/curl.h
@@ -0,0 +1,1563 @@
+#ifndef __CURL_CURL_H
+#define __CURL_CURL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, 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.304 2006-08-04 16:08:41 giva 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 <stdio.h>
+#include <limits.h>
+
+/* The include stuff here below is mainly for time_t! */
+#ifdef vms
+# include <types.h>
+# include <time.h>
+#else
+# include <sys/types.h>
+# include <time.h>
+#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 */
+
+/* "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 /* 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
+
+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);
+
+ /* 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. */
+#define CURL_MAX_WRITE_SIZE 16384
+
+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);
+
+
+#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_URL_MALFORMAT_USER, /* 4 - NOT USED */
+ CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
+ CURLE_COULDNT_RESOLVE_HOST, /* 6 */
+ CURLE_COULDNT_CONNECT, /* 7 */
+ CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
+ CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server
+ due to lack of access - when login fails
+ this is not returned. */
+ CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 - NOT USED */
+ CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
+ CURLE_FTP_WEIRD_USER_REPLY, /* 12 */
+ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
+ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
+ CURLE_FTP_CANT_GET_HOST, /* 15 */
+ CURLE_FTP_CANT_RECONNECT, /* 16 */
+ CURLE_FTP_COULDNT_SET_BINARY, /* 17 */
+ CURLE_PARTIAL_FILE, /* 18 */
+ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
+ CURLE_FTP_WRITE_ERROR, /* 20 */
+ CURLE_FTP_QUOTE_ERROR, /* 21 */
+ CURLE_HTTP_RETURNED_ERROR, /* 22 */
+ CURLE_WRITE_ERROR, /* 23 */
+ CURLE_MALFORMAT_USER, /* 24 - NOT USED */
+ CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */
+ 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_TIMEOUTED, /* 28 - the timeout time was reached */
+ CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */
+ CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
+ CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
+ CURLE_FTP_COULDNT_GET_SIZE, /* 32 - the SIZE command failed */
+ CURLE_HTTP_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_LIBRARY_NOT_FOUND, /* 40 */
+ CURLE_FUNCTION_NOT_FOUND, /* 41 */
+ CURLE_ABORTED_BY_CALLBACK, /* 42 */
+ CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
+ CURLE_BAD_CALLING_ORDER, /* 44 - NOT USED */
+ CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
+ CURLE_BAD_PASSWORD_ENTERED, /* 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_OBSOLETE, /* 50 - NOT USED */
+ CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */
+ 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_SHARE_IN_USE, /* 57 - share is 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_FTP_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_TFTP_DISKFULL, /* 70 - out of disk space on server */
+ CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
+ CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
+ CURLE_TFTP_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 */
+ CURL_LAST /* never use! */
+} CURLcode;
+
+/* 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);
+
+/* Make a spelling correction for the operation timed-out define */
+#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+/* backwards compatibility with older names */
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#endif
+
+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)
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+/* 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
+
+/* These are just to make older programs not break: */
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+#endif
+
+#define CURL_ERROR_SIZE 256
+
+/* parameter for the CURLOPT_FTP_SSL option */
+typedef enum {
+ CURLFTPSSL_NONE, /* do not attempt to use SSL */
+ 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 */
+ CURLFTPSSL_LAST /* not an option, never use */
+} curl_ftpssl;
+
+/* 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_<name>,
+ type is one of the defined CURLOPTTYPE_<type>
+ 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__)
+ /* 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 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-private key, keep this for compatibility */
+ CINIT(SSLCERTPASSWD, OBJECTPOINT, 26),
+ /* password for the SSL private key */
+ CINIT(SSLKEYPASSWD, 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(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */
+
+ CINIT(FTPAPPEND, 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 security level, this also enables krb4 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(KRB4LEVEL, 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 becomeO BSOLETE 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(FTP_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 */
+
+ /* When doing 3rd party transfer, set the source user and password with
+ this */
+ CINIT(SOURCE_USERPWD, OBJECTPOINT, 123),
+
+ /* 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 */
+
+ /* When doing 3rd party transfer, set the source pre-quote linked list
+ of commands with this */
+ CINIT(SOURCE_PREQUOTE, OBJECTPOINT, 127),
+
+ /* When doing 3rd party transfer, set the source post-quote linked list
+ of commands with this */
+ CINIT(SOURCE_POSTQUOTE, OBJECTPOINT, 128),
+
+ /* When FTP over SSL/TLS is selected (with CURLOPT_FTP_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),
+
+ /* To make a 3rd party transfer, set the source URL with this */
+ CINIT(SOURCE_URL, OBJECTPOINT, 132),
+
+ /* When doing 3rd party transfer, set the source quote linked list of
+ commands with this */
+ CINIT(SOURCE_QUOTE, OBJECTPOINT, 133),
+
+ /* 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),
+
+ CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+ /* 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
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+#define CURLOPT_HTTPREQUEST -1
+#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT
+#define CURLOPT_MUTE -2
+#define CURLOPT_PASSWDFUNCTION -3
+#define CURLOPT_PASSWDDATA -4
+#define CURLOPT_CLOSEFUNCTION -5
+
+#define CURLOPT_SOURCE_HOST -6
+#define CURLOPT_SOURCE_PATH -7
+#define CURLOPT_SOURCE_PORT -8
+#define CURLOPT_PASV_HOST -9
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+ /* 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 <support/SupportDefs.h>
+#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_<name> */
+#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_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_THIRD
+
+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;
+
+ /* Same as '_libiconv_version' if built with HAVE_ICONV */
+ int iconv_ver_num;
+} 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/src/libcurl/curl/curlver.h b/src/libcurl/curl/curlver.h
new file mode 100644
index 00000000..1634b172
--- /dev/null
+++ b/src/libcurl/curl/curlver.h
@@ -0,0 +1,56 @@
+#ifndef __CURL_CURLVER_H
+#define __CURL_CURLVER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, 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.21 2006-06-12 07:24:14 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.15.5"
+
+/* The numeric version number is also available "in parts" by using these
+ defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 15
+#define LIBCURL_VERSION_PATCH 5
+
+/* 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 0x070f05
+
+#endif /* __CURL_CURLVER_H */
diff --git a/src/libcurl/curl/easy.h b/src/libcurl/curl/easy.h
new file mode 100644
index 00000000..b5867200
--- /dev/null
+++ b/src/libcurl/curl/easy.h
@@ -0,0 +1,81 @@
+#ifndef __CURL_EASY_H
+#define __CURL_EASY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, 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/src/libcurl/curl/mprintf.h b/src/libcurl/curl/mprintf.h
new file mode 100644
index 00000000..8d835f13
--- /dev/null
+++ b/src/libcurl/curl/mprintf.h
@@ -0,0 +1,62 @@
+#ifndef __CURL_MPRINTF_H
+#define __CURL_MPRINTF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, 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.13 2006-03-28 10:08:54 bagder Exp $
+ ***************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h> /* needed for FILE */
+
+#include "curl.h"
+
+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
+# 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
+
+#endif /* __CURL_MPRINTF_H */
diff --git a/src/libcurl/curl/multi.h b/src/libcurl/curl/multi.h
new file mode 100644
index 00000000..05aeafc7
--- /dev/null
+++ b/src/libcurl/curl/multi.h
@@ -0,0 +1,344 @@
+#ifndef __CURL_MULTI_H
+#define __CURL_MULTI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, 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.38 2006-08-04 18:53:48 danf 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.
+
+*/
+#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 <winsock2.h>
+#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(NETWARE) || defined(__NetBSD__) || defined(_MINIX)
+#include <sys/select.h>
+#endif
+
+#ifndef _WIN32_WCE
+#include <sys/socket.h>
+#endif
+#include <sys/time.h>
+#include <sys/types.h>
+#endif
+
+/*
+ * 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
+ * <curl/curl.h> 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;
+
+#ifndef curl_socket_typedef
+/* Public 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 */
+
+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
+
+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 */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+ int *running_handles);
+
+/*
+ * 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),
+
+ 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/src/libcurl/curl/stdcheaders.h b/src/libcurl/curl/stdcheaders.h
new file mode 100644
index 00000000..024413ac
--- /dev/null
+++ b/src/libcurl/curl/stdcheaders.h
@@ -0,0 +1,34 @@
+#ifndef __STDC_HEADERS_H
+#define __STDC_HEADERS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, 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 <sys/types.h>
+
+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/src/libcurl/curl/types.h b/src/libcurl/curl/types.h
new file mode 100644
index 00000000..d37d6ae9
--- /dev/null
+++ b/src/libcurl/curl/types.h
@@ -0,0 +1 @@
+/* not used */
diff --git a/src/libs/win32/libcurl.a b/src/libs/win32/libcurl.a
new file mode 100644
index 00000000..7f6ed2d7
--- /dev/null
+++ b/src/libs/win32/libcurl.a
Binary files differ
diff --git a/src/qcommon/common.c b/src/qcommon/common.c
index cc105ee8..dfbfcd0f 100644
--- a/src/qcommon/common.c
+++ b/src/qcommon/common.c
@@ -263,9 +263,6 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
code = ERR_FATAL;
}
- // make sure we can get at our local stuff
- FS_PureServerSetLoadedPaks( "", "" );
-
// if we are getting a solid stream of ERR_DROP, do an ERR_FATAL
currentTime = Sys_Milliseconds();
if ( currentTime - lastErrorTime < 100 ) {
@@ -286,20 +283,22 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
vsprintf (com_errorMessage,fmt,argptr);
va_end (argptr);
- if ( code != ERR_DISCONNECT && code != ERR_NEED_CD ) {
+ if (code != ERR_DISCONNECT && code != ERR_NEED_CD)
Cvar_Set("com_errorMessage", com_errorMessage);
- }
- if ( code == ERR_SERVERDISCONNECT ) {
+ if (code == ERR_DISCONNECT || code == ERR_SERVERDISCONNECT) {
CL_Disconnect( qtrue );
CL_FlushMemory( );
+ // make sure we can get at our local stuff
+ FS_PureServerSetLoadedPaks("", "");
com_errorEntered = qfalse;
longjmp (abortframe, -1);
- } else if ( code == ERR_DROP || code == ERR_DISCONNECT ) {
+ } else if (code == ERR_DROP) {
Com_Printf ("********************\nERROR: %s\n********************\n", com_errorMessage);
SV_Shutdown (va("Server crashed: %s", com_errorMessage));
CL_Disconnect( qtrue );
CL_FlushMemory( );
+ FS_PureServerSetLoadedPaks("", "");
com_errorEntered = qfalse;
longjmp (abortframe, -1);
} else if ( code == ERR_NEED_CD ) {
@@ -312,6 +311,7 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
} else {
Com_Printf("Server didn't have CD\n" );
}
+ FS_PureServerSetLoadedPaks("", "");
longjmp (abortframe, -1);
} else {
CL_Shutdown ();
@@ -2279,7 +2279,7 @@ Com_Init
void Com_Init( char *commandLine ) {
char *s;
- Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, __DATE__ );
+ Com_Printf( "%s %s %s\n", SVN_VERSION, PLATFORM_STRING, __DATE__ );
if ( setjmp (abortframe) ) {
Sys_Error ("Error during initialization");
@@ -2523,9 +2523,9 @@ int Com_ModifyMsec( int msec ) {
// dedicated servers don't want to clamp for a much longer
// period, because it would mess up all the client's views
// of time.
- if ( msec > 500 ) {
+ if (com_sv_running->integer && msec > 500)
Com_Printf( "Hitch warning: %i msec frame time\n", msec );
- }
+
clampTime = 5000;
} else
if ( !com_sv_running->integer ) {
diff --git a/src/qcommon/cvar.c b/src/qcommon/cvar.c
index a4af1af0..4340dcc4 100644
--- a/src/qcommon/cvar.c
+++ b/src/qcommon/cvar.c
@@ -452,6 +452,15 @@ void Cvar_Reset( const char *var_name ) {
Cvar_Set2( var_name, NULL, qfalse );
}
+/*
+============
+Cvar_ForceReset
+============
+*/
+void Cvar_ForceReset(const char *var_name)
+{
+ Cvar_Set2(var_name, NULL, qtrue);
+}
/*
============
diff --git a/src/qcommon/files.c b/src/qcommon/files.c
index 15e183a4..ac73a0a8 100644
--- a/src/qcommon/files.c
+++ b/src/qcommon/files.c
@@ -2706,7 +2706,7 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
================
FS_Shutdown
-Frees all resources and closes all files
+Frees all resources.
================
*/
void FS_Shutdown( qboolean closemfp ) {
@@ -2819,10 +2819,6 @@ static void FS_Startup( const char *gameName ) {
if (fs_basepath->string[0]) {
FS_AddGameDirectory( fs_basepath->string, gameName );
}
-#ifdef MACOS_X
- // allow .app bundles to be placed along side base dir
- FS_AddGameDirectory( ".", gameName );
-#endif
// fs_homepath is somewhat particular to *nix systems, only add if relevant
// NOTE: same filtering below for mods and basegame
if (fs_basepath->string[0] && Q_stricmp(fs_homepath->string,fs_basepath->string)) {
diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h
index 8d84b3f7..f7a8b43e 100644
--- a/src/qcommon/q_shared.h
+++ b/src/qcommon/q_shared.h
@@ -29,6 +29,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define VERSION_NUMBER "1.1.0"
#define Q3_VERSION "tremulous " VERSION_NUMBER
+#ifndef SVN_VERSION
+#define SVN_VERSION Q3_VERSION
+#endif
#define CLIENT_WINDOW_TITLE "Tremulous " VERSION_NUMBER
#define CLIENT_WINDOW_ICON "Tremulous"
#define CONSOLE_WINDOW_TITLE "Tremulous " VERSION_NUMBER " console"
diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h
index bf20536d..478cd5d5 100644
--- a/src/qcommon/qcommon.h
+++ b/src/qcommon/qcommon.h
@@ -481,6 +481,7 @@ void Cvar_CommandCompletion( void(*callback)(const char *s) );
// callback with each valid string
void Cvar_Reset( const char *var_name );
+void Cvar_ForceReset(const char *var_name);
void Cvar_SetCheatState( void );
// reset all testing vars to a safe value
@@ -1096,4 +1097,10 @@ extern huffman_t clientHuffTables;
#define CL_ENCODE_START 12
#define CL_DECODE_START 4
+// flags for sv_allowDownload and cl_allowDownload
+#define DLF_ENABLE 1
+#define DLF_NO_REDIRECT 2
+#define DLF_NO_UDP 4
+#define DLF_NO_DISCONNECT 8
+
#endif // _QCOMMON_H_
diff --git a/src/qcommon/vm_ppc_new.c b/src/qcommon/vm_ppc_new.c
index a731d653..79fc506f 100644
--- a/src/qcommon/vm_ppc_new.c
+++ b/src/qcommon/vm_ppc_new.c
@@ -158,32 +158,38 @@ typedef enum {
#define RG_EA r14
// The deepest value I saw in the Quake3 games was 9.
-#define OP_STACK_MAX_DEPTH 12
+#define OP_STACK_MAX_DEPTH 16
-// These are all volatile and thus must be saved
-// upon entry to the VM code.
+// These are all volatile and thus must be saved upon entry to the VM code.
+// NOTE: These are General Purpose Registers (GPR) numbers like the
+// R_ definitions in the regNums_t enum above (31 is the max)
static int opStackIntRegisters[OP_STACK_MAX_DEPTH] =
{
16, 17, 18, 19,
20, 21, 22, 23,
- 24, 25, 26, 27
+ 24, 25, 26, 27,
+ 28, 29, 30, 31
};
static unsigned int *opStackLoadInstructionAddr[OP_STACK_MAX_DEPTH];
// We use different registers for the floating point
// operand stack (these are volatile in the PPC ABI)
+// NOTE: these are Floating Point Register (FPR) numbers, not
+// General Purpose Register (GPR) numbers
static int opStackFloatRegisters[OP_STACK_MAX_DEPTH] =
{
0, 1, 2, 3,
4, 5, 6, 7,
- 8, 9, 10, 11
+ 8, 9, 10, 11,
+ 12, 13, 14, 15
};
static int opStackRegType[OP_STACK_MAX_DEPTH] =
{
0, 0, 0, 0,
0, 0, 0, 0,
+ 0, 0, 0, 0,
0, 0, 0, 0
};
diff --git a/src/renderer/tr_model.c b/src/renderer/tr_model.c
index b59ff3b4..8fdd0adb 100644
--- a/src/renderer/tr_model.c
+++ b/src/renderer/tr_model.c
@@ -653,9 +653,9 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
for(j = 0; j < surf->numTriangles; j++)
{
- tri->indexes[0] = curtri->indexes[0];
- tri->indexes[1] = curtri->indexes[1];
- tri->indexes[2] = curtri->indexes[2];
+ tri->indexes[0] = LittleLong(curtri->indexes[0]);
+ tri->indexes[1] = LittleLong(curtri->indexes[1]);
+ tri->indexes[2] = LittleLong(curtri->indexes[2]);
tri++;
curtri++;
diff --git a/src/server/server.h b/src/server/server.h
index fd49da7b..4d73038e 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -169,6 +169,7 @@ typedef struct client_s {
netchan_buffer_t **netchan_end_queue;
int oldServerTime;
+ qboolean csUpdated[MAX_CONFIGSTRINGS+1];
} client_t;
//=============================================================================
@@ -272,6 +273,7 @@ void SV_MasterGameStat( const char *data );
//
void SV_SetConfigstring( int index, const char *val );
void SV_GetConfigstring( int index, char *buffer, int bufferSize );
+void SV_UpdateConfigstrings( client_t *client );
void SV_SetUserinfo( int index, const char *val );
void SV_GetUserinfo( int index, char *buffer, int bufferSize );
diff --git a/src/server/sv_client.c b/src/server/sv_client.c
index 794f32a8..e128b579 100644
--- a/src/server/sv_client.c
+++ b/src/server/sv_client.c
@@ -462,6 +462,10 @@ void SV_ClientEnterWorld( client_t *client, usercmd_t *cmd ) {
Com_DPrintf( "Going from CS_PRIMED to CS_ACTIVE for %s\n", client->name );
client->state = CS_ACTIVE;
+ // resend all configstrings using the cs commands since these are
+ // no longer sent when the client is CS_PRIMED
+ SV_UpdateConfigstrings( client );
+
// set up the entity for the client
clientNum = client - svs.clients;
ent = SV_GentityNum( clientNum );
@@ -643,7 +647,9 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg )
}
// We open the file here
- if ( !sv_allowDownload->integer || idPack || unreferenced ||
+ if ( !(sv_allowDownload->integer & DLF_ENABLE) ||
+ (sv_allowDownload->integer & DLF_NO_UDP) ||
+ idPack || unreferenced ||
( cl->downloadSize = FS_SV_FOpenFileRead( cl->downloadName, &cl->download ) ) <= 0 ) {
// cannot auto-download file
if(unreferenced)
@@ -660,7 +666,10 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg )
else {
Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload id pk3 file \"%s\"", cl->downloadName);
}
- } else if ( !sv_allowDownload->integer ) {
+ }
+ else if ( !(sv_allowDownload->integer & DLF_ENABLE) ||
+ (sv_allowDownload->integer & DLF_NO_UDP) ) {
+
Com_Printf("clientDownload: %d : \"%s\" download disabled", cl - svs.clients, cl->downloadName);
if (sv_pure->integer) {
Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n"
diff --git a/src/server/sv_init.c b/src/server/sv_init.c
index 0099e63f..293b31c9 100644
--- a/src/server/sv_init.c
+++ b/src/server/sv_init.c
@@ -23,6 +23,81 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "server.h"
+
+/*
+===============
+SV_SendConfigstring
+
+Creates and sends the server command necessary to update the CS index for the
+given client
+===============
+*/
+static void SV_SendConfigstring(client_t *client, int index)
+{
+ int maxChunkSize = MAX_STRING_CHARS - 24;
+ int len;
+
+ len = strlen(sv.configstrings[index]);
+
+ if( len >= maxChunkSize ) {
+ int sent = 0;
+ int remaining = len;
+ char *cmd;
+ char buf[MAX_STRING_CHARS];
+
+ while (remaining > 0 ) {
+ if ( sent == 0 ) {
+ cmd = "bcs0";
+ }
+ else if( remaining < maxChunkSize ) {
+ cmd = "bcs2";
+ }
+ else {
+ cmd = "bcs1";
+ }
+ Q_strncpyz( buf, &sv.configstrings[index][sent],
+ maxChunkSize );
+
+ SV_SendServerCommand( client, "%s %i \"%s\"\n", cmd,
+ index, buf );
+
+ sent += (maxChunkSize - 1);
+ remaining -= (maxChunkSize - 1);
+ }
+ } else {
+ // standard cs, just send it
+ SV_SendServerCommand( client, "cs %i \"%s\"\n", index,
+ sv.configstrings[index] );
+ }
+}
+
+/*
+===============
+SV_UpdateConfigstrings
+
+Called when a client goes from CS_PRIMED to CS_ACTIVE. Updates all
+Configstring indexes that have changed while the client was in CS_PRIMED
+===============
+*/
+void SV_UpdateConfigstrings(client_t *client)
+{
+ int index;
+
+ for( index = 0; index <= MAX_CONFIGSTRINGS; index++ ) {
+ // if the CS hasn't changed since we went to CS_PRIMED, ignore
+ if(!client->csUpdated[index])
+ continue;
+
+ // do not always send server info to all clients
+ if ( index == CS_SERVERINFO && client->gentity &&
+ (client->gentity->r.svFlags & SVF_NOSERVERINFO) ) {
+ continue;
+ }
+ SV_SendConfigstring(client, index);
+ client->csUpdated[index] = qfalse;
+ }
+}
+
/*
===============
SV_SetConfigstring
@@ -31,7 +106,6 @@ SV_SetConfigstring
*/
void SV_SetConfigstring (int index, const char *val) {
int len, i;
- int maxChunkSize = MAX_STRING_CHARS - 24;
client_t *client;
if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
@@ -57,48 +131,23 @@ void SV_SetConfigstring (int index, const char *val) {
// send the data to all relevent clients
for (i = 0, client = svs.clients; i < sv_maxclients->integer ; i++, client++) {
- if ( client->state < CS_PRIMED ) {
+ if ( client->state < CS_ACTIVE ) {
+ if ( client->state == CS_PRIMED )
+ client->csUpdated[ index ] = qtrue;
continue;
}
// do not always send server info to all clients
if ( index == CS_SERVERINFO && client->gentity && (client->gentity->r.svFlags & SVF_NOSERVERINFO) ) {
continue;
}
+
len = strlen( val );
- if( len >= maxChunkSize ) {
- int sent = 0;
- int remaining = len;
- char *cmd;
- char buf[MAX_STRING_CHARS];
-
- while (remaining > 0 ) {
- if ( sent == 0 ) {
- cmd = "bcs0";
- }
- else if( remaining < maxChunkSize ) {
- cmd = "bcs2";
- }
- else {
- cmd = "bcs1";
- }
- Q_strncpyz( buf, &val[sent], maxChunkSize );
-
- SV_SendServerCommand( client, "%s %i \"%s\"\n", cmd, index, buf );
-
- sent += (maxChunkSize - 1);
- remaining -= (maxChunkSize - 1);
- }
- } else {
- // standard cs, just send it
- SV_SendServerCommand( client, "cs %i \"%s\"\n", index, val );
- }
+ SV_SendConfigstring(client, index);
}
}
}
-
-
/*
===============
SV_GetConfigstring
@@ -561,6 +610,7 @@ void SV_Init (void) {
sv_zombietime = Cvar_Get ("sv_zombietime", "2", CVAR_TEMP );
sv_allowDownload = Cvar_Get ("sv_allowDownload", "0", CVAR_SERVERINFO);
+ Cvar_Get ("sv_dlURL", "", CVAR_SERVERINFO | CVAR_ARCHIVE);
sv_master[0] = Cvar_Get ("sv_master1", MASTER_SERVER_NAME, 0 );
sv_master[1] = Cvar_Get ("sv_master2", "", CVAR_ARCHIVE );
sv_master[2] = Cvar_Get ("sv_master3", "", CVAR_ARCHIVE );
diff --git a/src/server/sv_main.c b/src/server/sv_main.c
index c84e5ac3..2dc5a778 100644
--- a/src/server/sv_main.c
+++ b/src/server/sv_main.c
@@ -129,6 +129,10 @@ void SV_AddServerCommand( client_t *client, const char *cmd ) {
// return;
// }
+ // do not send commands until the gamestate has been sent
+ if( client->state < CS_PRIMED )
+ return;
+
client->reliableSequence++;
// if we would be losing an old command that hasn't been acknowledged,
// we must drop the connection
@@ -186,9 +190,6 @@ void QDECL SV_SendServerCommand(client_t *cl, const char *fmt, ...) {
// send the data to all relevent clients
for (j = 0, client = svs.clients; j < sv_maxclients->integer ; j++, client++) {
- if ( client->state < CS_PRIMED ) {
- continue;
- }
SV_AddServerCommand( client, (char *)message );
}
}
@@ -784,7 +785,15 @@ void SV_Frame( int msec ) {
return;
}
- if ( !com_sv_running->integer ) {
+ if (!com_sv_running->integer)
+ {
+ if(com_dedicated->integer)
+ {
+ // Block indefinitely until something interesting happens
+ // on STDIN.
+ NET_Sleep(-1);
+ }
+
return;
}
@@ -797,7 +806,14 @@ void SV_Frame( int msec ) {
if ( sv_fps->integer < 1 ) {
Cvar_Set( "sv_fps", "10" );
}
- frameMsec = 1000 / sv_fps->integer ;
+
+ frameMsec = 1000 / sv_fps->integer * com_timescale->value;
+ // don't let it scale below 1ms
+ if(frameMsec < 1)
+ {
+ Cvar_Set("timescale", va("%f", sv_fps->integer / 1000.0f));
+ frameMsec = 1;
+ }
sv.timeResidual += msec;
diff --git a/src/server/sv_snapshot.c b/src/server/sv_snapshot.c
index 75da32b0..47471ba5 100644
--- a/src/server/sv_snapshot.c
+++ b/src/server/sv_snapshot.c
@@ -559,7 +559,7 @@ static int SV_RateMsec( client_t *client, int messageSize ) {
rate = sv_minRate->integer;
}
- rateMsec = ( messageSize + HEADER_RATE_BYTES ) * 1000 / rate;
+ rateMsec = ( messageSize + HEADER_RATE_BYTES ) * 1000 / rate * com_timescale->value;
return rateMsec;
}
@@ -588,31 +588,30 @@ void SV_SendMessageToClient( msg_t *msg, client_t *client ) {
// TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=491
// added sv_lanForceRate check
if ( client->netchan.remoteAddress.type == NA_LOOPBACK || (sv_lanForceRate->integer && Sys_IsLANAddress (client->netchan.remoteAddress)) ) {
- client->nextSnapshotTime = svs.time + (1000/sv_fps->integer);
+ client->nextSnapshotTime = svs.time + (1000.0 / sv_fps->integer * com_timescale->value);
return;
}
// normal rate / snapshotMsec calculation
- rateMsec = SV_RateMsec( client, msg->cursize );
+ rateMsec = SV_RateMsec(client, msg->cursize);
- if ( rateMsec < client->snapshotMsec ) {
+ if ( rateMsec < client->snapshotMsec * com_timescale->value) {
// never send more packets than this, no matter what the rate is at
- rateMsec = client->snapshotMsec;
+ rateMsec = client->snapshotMsec * com_timescale->value;
client->rateDelayed = qfalse;
} else {
client->rateDelayed = qtrue;
}
- client->nextSnapshotTime = svs.time + rateMsec;
+ client->nextSnapshotTime = svs.time + rateMsec * com_timescale->value;
// don't pile up empty snapshots while connecting
if ( client->state != CS_ACTIVE ) {
// a gigantic connection message may have already put the nextSnapshotTime
// more than a second away, so don't shorten it
// do shorten if client is downloading
- if ( !*client->downloadName && client->nextSnapshotTime < svs.time + 1000 ) {
- client->nextSnapshotTime = svs.time + 1000;
- }
+ if (!*client->downloadName && client->nextSnapshotTime < svs.time + 1000 * com_timescale->value)
+ client->nextSnapshotTime = svs.time + 1000 * com_timescale->value;
}
}
diff --git a/src/unix/MacSupport/SLA-dmg.sh b/src/unix/MacSupport/SLA-dmg.sh
new file mode 100755
index 00000000..51c6e429
--- /dev/null
+++ b/src/unix/MacSupport/SLA-dmg.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# This script appends a SLA.r (Software License Agreement) resource to a .dmg
+#
+# usage is './SLA-dmg.sh SLA.r /path/to/ioquake3.dmg'
+#
+
+if [ "x$1" = "x" ] || [ "x$2" = "x"]; then
+ echo "usage: ./SLA-dmg.sh SLAFILE DMGFILE"
+ exit 1;
+fi
+
+if [ ! -r $1 ]; then
+ echo "$1 is not a readable .r file"
+ exit 1;
+fi
+if [ ! -w $2 ]; then
+ echo "$2 is not writable .dmg file"
+ exit 1;
+fi
+
+hdiutil convert -format UDCO -o tmp.dmg $2 || exit 1
+hdiutil unflatten tmp.dmg || exit 1
+/Developer/Tools/Rez /Developer/Headers/FlatCarbon/*.r $1 -a -o tmp.dmg \
+ || exit 1
+hdiutil flatten tmp.dmg || exit 1
+hdiutil internet-enable -yes tmp.dmg || exit 1
+mv tmp.dmg $2 || (echo "Could not copy tmp.dmg to $2" && exit 1)
+rm tmp.dmg
+echo "SLA $1 successfully added to $2"
diff --git a/src/unix/MacSupport/SLA.r b/src/unix/MacSupport/SLA.r
new file mode 100644
index 00000000..e5edaf0e
--- /dev/null
+++ b/src/unix/MacSupport/SLA.r
@@ -0,0 +1,260 @@
+data 'LPic' (5000) {
+ $"0002 0011 0003 0001 0000 0000 0002 0000"
+ $"0008 0003 0000 0001 0004 0000 0004 0005"
+ $"0000 000E 0006 0001 0005 0007 0000 0007"
+ $"0008 0000 0047 0009 0000 0034 000A 0001"
+ $"0035 000B 0001 0020 000C 0000 0011 000D"
+ $"0000 005B 0004 0000 0033 000F 0001 000C"
+ $"0010 0000 000B 000E 0000"
+};
+
+
+data 'TEXT' (5002, "English") {
+"LIMITED USE SOFTWARE LICENSE AGREEMENT\n"
+"\n"
+"\n"
+"\n"
+"This Limited Use Software License Agreement (the \"Agreement\") is a legal"
+"agreement between you, the end-user, and Id Software, Inc. (\"ID\"). BY"
+"CONTINUING THE INSTALLATION OF THIS GAME DEMO PROGRAM ENTITLED QUAKE III:"
+"ARENA (THE \"SOFTWARE\"), BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING"
+"OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM OR"
+"OTHER STORAGE, YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS "
+"AGREEMENT.\n"
+"\n"
+"\n"
+"\n"
+"1. Grant of License. Subject to the terms and provisions of this"
+"Agreement, ID grants to you the non-exclusive and limited right to use the"
+"Software only in executable or object code form. The term \"Software\""
+"includes all elements of the Software, including, without limitation, data"
+"files and screen displays. You are not receiving any ownership or"
+"proprietary right, title or interest in or to the Software or the "
+"copyright, trademarks, or other rights related thereto. For purposes of"
+"this section, \"use\" means loading the Software into RAM and/or onto "
+"computer hard drive, as well as installation of the Software on a hard"
+"disk or other storage device and means the uses permitted in section 3."
+"hereinbelow. You agree that the Software will not be shipped,"
+"transferred or exported into any country in violation of the U.S. Export"
+"Administration Act (or any other law governing such matters) by you or"
+"anyone at your direction and that you will not utilize and will not"
+"authorize anyone to utilize, in any other manner, the Software in"
+"violation of any applicable law. The Software may not be downloaded"
+"or otherwise exported or exported into (or to a national or resident"
+"of) any country to which the U.S. has embargoed goods or to anyone"
+"or into any country who/which are prohibited, by applicable law, from"
+"receiving such property."
+"\n"
+"\n"
+"\n"
+"2. Prohibitions. You, either directly or indirectly, shall not do"
+"any of the following acts:"
+"\n"
+"\n"
+"\n"
+"a. rent the Software;"
+"\n"
+"\n"
+"\n"
+"b. sell the Software;"
+"\n"
+"\n"
+"\n"
+"c. lease or lend the Software;"
+"\n"
+"\n"
+"\n"
+"d. offer the Software on a \"pay-per-play\" basis;"
+"\n"
+"\n"
+"\n"
+"e. distribute the Software (except as permitted by section 3."
+"hereinbelow);"
+"\n"
+"\n"
+"\n"
+"f. in any other manner and through any medium whatsoever"
+"commercially exploit the Software or use the Software for any commercial"
+"purpose;"
+"\n"
+"\n"
+"\n"
+"g. disassemble, reverse engineer, decompile, modify or alter the"
+"Software including, without limitation, creating or developing extra or"
+"add-on levels for the Software;"
+"\n"
+"\n"
+"\n"
+"h. translate the Software;"
+"\n"
+"\n"
+"\n"
+"i. reproduce or copy the Software (except as permitted by section"
+"3. hereinbelow);"
+"\n"
+"\n"
+"\n"
+"j. publicly display the Software;"
+"\n"
+"\n"
+"\n"
+"k. prepare or develop derivative works based upon the Software; or"
+"\n"
+"\n"
+"\n"
+"l. remove or alter any legal notices or other markings or "
+"legends, such as trademark and copyright notices, affixed on or within"
+"the Software."
+"\n"
+"\n"
+"\n"
+"3. Permitted Distribution and Copying. So long as this Agreement"
+"accompanies each copy you make of the Software, and so long as you fully"
+"comply, at all times, with this Agreement, ID grants to you the"
+"non-exclusive and limited right to copy the Software and to distribute "
+"such copies of the Software free of charge for non-commercial purposes "
+"which shall include the free of charge distribution of copies of the"
+"Software as mounted on the covers of magazines; provided, however, you"
+"shall not copy or distribute the Software in any infringing manner or"
+"in any manner which violates any law or third party right and you shall"
+"not distribute the Software together with any material which is "
+"infringing, libelous, defamatory, obscene, false, misleading, or "
+"otherwise illegal or unlawful. You agree to label conspicuously as "
+"\"SHAREWARE\" or \"DEMO\" each CD or other non-electronic copy of the "
+"Software that you make and distribute. ID reserves all rights not"
+"granted in this Agreement. You shall not commercially distribute the"
+"Software unless you first enter into a separate contract with ID, a"
+"copy of which you may request, but which ID may decline to execute."
+"For more information visit www.quake3arena.com."
+"\n"
+"\n"
+"\n"
+"4. Intellectual Property Rights. The Software and all copyrights,"
+"trademarks and all other conceivable intellectual property rights related"
+"to the Software are owned by ID and are protected by United States"
+"copyright laws, international treaty provisions and all applicable law,"
+"such as the Lanham Act. You must treat the Software like any other"
+"copyrighted material, as required by 17 U.S.C., §101 et seq. and othen"
+"applicable law. You agree to use your best efforts to see that any user"
+"of the Software licensed hereunder complies with this Agreement. You"
+"agree that you are receiving a copy of the Software by license only"
+"and not by sale and that the \"first sale\" doctrine of 17 U.S.C. §10"
+"does not apply to your receipt or use of the Software."
+"\n"
+"\n"
+"\n"
+"5. NO WARRANTIES. ID DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR"
+"IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF"
+"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE WITH RESPECT TO THE"
+"SOFTWARE. ID DOES NOT WARRANT THAT THE OPERATION OF THE SOFTWARE WILL BE"
+"UNINTERRUPTED OR ERROR FREE OR THAT THE SOFTWARE WILL MEET YOUR SPECIFIC"
+"REQUIREMENTS. ADDITIONAL STATEMENTS SUCH AS PRESENTATIONS, WHETHER ORAL"
+"OR WRITTEN, DO NOT CONSTITUTE WARRANTIES BY ID AND SHOULD NOT BE RELIED"
+"UPON. THIS SECTION 5. SHALL SURVIVE CANCELLATION OR TERMINATION OF THIS"
+"AGREEMENT."
+"\n"
+"\n"
+"\n"
+"6. Governing Law, Venue, Indemnity and Liability Limitation. This"
+"Agreement shall be construed in accordance with and governed by the"
+"applicable laws of the State of Texas and applicable United States federal"
+"law. Copyright and other proprietary matters will be governed by United"
+"States laws and international treaties. Exclusive venue for all"
+"litigation regarding this Agreement shall be in Dallas County, Texas"
+"and you agree to submit to the jurisdiction of the courts in Dallas,"
+"Texas for any such litigation. You agree to indemnify, defend and hold"
+"harmless ID and ID's officers, employees, directors, agents, licensees"
+"(excluding you), successors and assigns from and against all losses,"
+"lawsuits, damages, causes of action and claims relating to and/or"
+"arising from your breach of this Agreement. You agree that your"
+"unauthorized use of the Software, or any part thereof, may immediately"
+"and irreparably damage ID such that ID could not be adequately"
+"compensated solely by a monetary award and that at ID's option ID shall"
+"be entitled to an injunctive order, in addition to all other available"
+"remedies including a monetary award, appropriately restraining and/or"
+"prohibiting such unauthorized use without the necessity of ID posting"
+"bond or other security. IN ANY CASE, ID AND ID'S OFFICERS, EMPLOYEES,"
+"DIRECTORS, AGENTS, LICENSEES, SUBLICENSEES, SUCCESSORS AND ASSIGNS"
+"SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS,"
+"SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT, PUNITIVE OR OTHER SIMILAR"
+"DAMAGES ARISING FROM ANY ALLEGED CLAIM FOR BREACH OF WARRANTY, BREACH"
+"OF CONTRACT, NEGLIGENCE, STRICT PRODUCT LIABILITY, OR OTHER LEGAL"
+"THEORY EVEN IF ID OR ITS AGENT HAVE BEEN ADVISED OF THE POSSIBILITY"
+"OF SUCH DAMAGES OR EVEN IF SUCH DAMAGES ARE FORESEEABLE, OR LIABLE"
+"FOR ANY CLAIM BY ANY OTHER PARTY. Some jurisdictions do not allow"
+"the exclusion or limitation of incidental or consequential damages,"
+"so the above limitation or exclusion may not apply to you. This"
+"Section 6. shall survive cancellation or termination of this Agreement."
+"\n"
+"\n"
+"\n"
+"7. U.S. Government Restricted Rights. To the extent applicable,"
+"the United States Government shall only have those rights to use the"
+"Software as expressly stated and expressly limited and restricted in"
+"this Agreement, as provided in 48 C.F.R. §§ 227.7201 through 227.7204,"
+"inclusive."
+"\n"
+"\n"
+"\n"
+"8. General Provisions. Neither this Agreement nor any part or"
+"portion hereof shall be assigned or sublicensed by you. ID may assign its"
+"rights under this Agreement in ID's sole discretion. Should any provision"
+"of this Agreement be held to be void, invalid, unenforceable or illegal by"
+"a court of competent jurisdiction, the validity and enforceability of the"
+"other provisions shall not be affected thereby. If any provision is"
+"determined to be unenforceable by a court of competent jurisdiction, you"
+"agree to a modification of such provision to provide for enforcement of"
+"the provision's intent, to the extent permitted by applicable law."
+"Failure of ID to enforce any provision of this Agreement shall not"
+"constitute or be construed as a waiver of such provision or of the right"
+"to enforce such provision. Immediately upon your failure to comply with"
+"or breach of any term or provision of this Agreement, THIS AGREEMENT"
+"AND YOUR LICENSE SHALL AUTOMATICALLY TERMINATE, WITHOUT NOTICE, AND ID"
+"MAY PURSUE ALL RELIEF AND REMEDIES AGAINST YOU WHICH ARE AVAILABLE UNDER"
+"APPLICABLE LAW AND/OR THIS AGREEMENT. In the event this Agreement is"
+"terminated, you shall have no right to use the Software, in any manner,"
+"and you shall immediately destroy all copies of the Software in your"
+"possession, custody or control."
+"\n"
+"\n"
+"\n"
+"YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND THIS"
+"AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE INSTALLATION OF THE"
+"SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING"
+"THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE OR RAM, YOU AGREE TO BE BOUND"
+"BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU FURTHER AGREE THAT,"
+"EXCEPT FOR WRITTEN SEPARATE AGREEMENTS BETWEEN ID AND YOU, THIS "
+"AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE RIGHTS AND"
+"LIABILITIES OF THE PARTIES HERETO. THIS AGREEMENT SUPERSEDES ALL PRIOR"
+"ORAL AGREEMENTS, PROPOSALS OR UNDERSTANDINGS, AND ANY OTHER"
+"COMMUNICATIONS BETWEEN ID AND YOU RELATING TO THE SUBJECT MATTER OF"
+"THIS AGREEMENT."
+"\n"
+};
+
+resource 'STR#' (5002, "English") {
+ { /* array StringArray: 9 elements */
+ /* [1] */
+ "English",
+ /* [2] */
+ "Agree",
+ /* [3] */
+ "Disagree",
+ /* [4] */
+ "Print",
+ /* [5] */
+ "Save...",
+ /* [6] */
+ "IMPORTANT - Read this License Agreement carefully before clicking on "
+ "the \"Agree\" button. By clicking on the \"Agree\" button, you agree "
+ "to be bound by the terms of the License Agreement.",
+ /* [7] */
+ "Software License Agreement",
+ /* [8] */
+ "This text cannot be saved. This disk may be full or locked, or the file "
+ "may be locked.",
+ /* [9] */
+ "Unable to print. Make sure you have selected a printer."
+ }
+};
+
diff --git a/src/unix/MacSupport/ioquake3.icns b/src/unix/MacSupport/ioquake3.icns
new file mode 100755
index 00000000..30e3b673
--- /dev/null
+++ b/src/unix/MacSupport/ioquake3.icns
Binary files differ
diff --git a/src/unix/unix_main.c b/src/unix/unix_main.c
index eb815685..e399140c 100644
--- a/src/unix/unix_main.c
+++ b/src/unix/unix_main.c
@@ -1237,7 +1237,7 @@ void Sys_ANSIColorify( const char *msg, char *buffer, int bufferSize )
if( msg[ i ] == '\n' )
{
Com_sprintf( tempBuffer, 7, "%c[0m\n", 0x1B );
- strncat( buffer, tempBuffer, bufferSize );
+ strncat( buffer, tempBuffer, bufferSize - 1);
i++;
}
else if( msg[ i ] == Q_COLOR_ESCAPE )
@@ -1259,7 +1259,7 @@ void Sys_ANSIColorify( const char *msg, char *buffer, int bufferSize )
if( escapeCode )
{
Com_sprintf( tempBuffer, 7, "%c[%sm", 0x1B, escapeCode );
- strncat( buffer, tempBuffer, bufferSize );
+ strncat( buffer, tempBuffer, bufferSize - 1);
}
i++;
@@ -1268,7 +1268,7 @@ void Sys_ANSIColorify( const char *msg, char *buffer, int bufferSize )
else
{
Com_sprintf( tempBuffer, 7, "%c", msg[ i++ ] );
- strncat( buffer, tempBuffer, bufferSize );
+ strncat( buffer, tempBuffer, bufferSize - 1);
}
}
}
@@ -1383,8 +1383,42 @@ void Sys_ParseArgs( int argc, char* argv[] ) {
}
}
+#ifdef MACOS_X
+/*
+=================
+Sys_EscapeAppBundle
+
+Discovers if passed dir is suffixed with the directory structure of a
+Mac OS X .app bundle. If it is, the .app directory structure is stripped off
+the end and the result is returned. If not, dir is returned untouched.
+
+=================
+*/
+char *Sys_StripAppBundle(char *dir)
+{
+ static char cwd[MAX_OSPATH];
+
+ Q_strncpyz(cwd, dir, sizeof(cwd));
+ if(strcmp(basename(cwd), "MacOS"))
+ return dir;
+ Q_strncpyz(cwd, dirname(cwd), sizeof(cwd));
+ if(strcmp(basename(cwd), "Contents"))
+ return dir;
+ Q_strncpyz(cwd, dirname(cwd), sizeof(cwd));
+ if(!strstr(basename(cwd), ".app"))
+ return dir;
+ Q_strncpyz(cwd, dirname(cwd), sizeof(cwd));
+ return cwd;
+}
+#endif /* MACOS_X */
+
#ifndef DEFAULT_BASEDIR
-# define DEFAULT_BASEDIR Sys_DefaultCDPath()
+ #ifdef MACOS_X
+ // if run from an .app bundle, we want to also search its containing dir
+ #define DEFAULT_BASEDIR Sys_StripAppBundle(Sys_DefaultCDPath())
+ #else
+ #define DEFAULT_BASEDIR Sys_DefaultCDPath()
+ #endif
#endif
#include "../client/client.h"
diff --git a/src/unix/unix_net.c b/src/unix/unix_net.c
index d89e766a..31d27c8d 100644
--- a/src/unix/unix_net.c
+++ b/src/unix/unix_net.c
@@ -649,19 +649,40 @@ char *NET_ErrorString (void)
// sleeps msec or until net socket is ready
void NET_Sleep(int msec)
{
- struct timeval timeout;
+ struct timeval timeout;
fd_set fdset;
extern qboolean stdin_active;
+ int highestfd = 0;
- if (!ip_socket || !com_dedicated->integer)
+ if (!com_dedicated->integer)
return; // we're not a server, just run full speed
FD_ZERO(&fdset);
if (stdin_active)
+ {
FD_SET(0, &fdset); // stdin is processed too
- FD_SET(ip_socket, &fdset); // network socket
- timeout.tv_sec = msec/1000;
- timeout.tv_usec = (msec%1000)*1000;
- select(ip_socket+1, &fdset, NULL, NULL, &timeout);
+ highestfd = 1;
+ }
+ if(ip_socket)
+ {
+ FD_SET(ip_socket, &fdset); // network socket
+ if(ip_socket >= highestfd)
+ highestfd = ip_socket + 1;
+ }
+
+ if(highestfd)
+ {
+ if(msec >= 0)
+ {
+ timeout.tv_sec = msec/1000;
+ timeout.tv_usec = (msec%1000)*1000;
+ select(highestfd, &fdset, NULL, NULL, &timeout);
+ }
+ else
+ {
+ // Block indefinitely
+ select(highestfd, &fdset, NULL, NULL, NULL);
+ }
+ }
}
diff --git a/src/win32/win_shared.c b/src/win32/win_shared.c
index ca7644ba..5ed7770c 100644
--- a/src/win32/win_shared.c
+++ b/src/win32/win_shared.c
@@ -288,15 +288,32 @@ char *Sys_GetCurrentUser( void )
char *Sys_DefaultHomePath(void) {
TCHAR szPath[MAX_PATH];
static char path[MAX_OSPATH];
+ FARPROC qSHGetFolderPath;
+ HMODULE shfolder = LoadLibrary("shfolder.dll");
+
+ if(shfolder == NULL) {
+ Com_Printf("Unable to load SHFolder.dll\n");
+ return NULL;
+ }
- if( !SUCCEEDED( SHGetFolderPath( NULL, CSIDL_LOCAL_APPDATA,
- NULL, 0, szPath ) ) )
+ qSHGetFolderPath = GetProcAddress(shfolder, "SHGetFolderPathA");
+ if(qSHGetFolderPath == NULL)
{
+ Com_Printf("Unable to find SHGetFolderPath in SHFolder.dll\n");
+ FreeLibrary(shfolder);
+ return NULL;
+ }
+ if( !SUCCEEDED( qSHGetFolderPath( NULL, CSIDL_APPDATA,
+ NULL, 0, szPath ) ) )
+ {
+ Com_Printf("Unable to detect CSIDL_APPDATA\n");
+ FreeLibrary(shfolder);
return NULL;
}
Q_strncpyz( path, szPath, sizeof(path) );
Q_strcat( path, sizeof(path), "\\Tremulous" );
+ FreeLibrary(shfolder);
if( !CreateDirectory( path, NULL ) )
{
if( GetLastError() != ERROR_ALREADY_EXISTS )