Updated cURL version.

This commit is contained in:
Asher Baker
2013-03-17 22:23:20 +00:00
parent 986aa2a477
commit 63175aa3cb
1510 changed files with 213259 additions and 161405 deletions
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
# Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,7 +18,6 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# $Id: Makefile.am,v 1.23 2008-08-07 00:29:09 yangtse Exp $
###########################################################################
AUTOMAKE_OPTIONS = foreign nostdinc
@@ -27,38 +26,39 @@ AUTOMAKE_OPTIONS = foreign nostdinc
# being currently built and tested are searched before the library which
# might possibly already be installed in the system.
#
# $(top_builddir)/include is for libcurl's generated curl/curlbuild.h file
# $(top_builddir)/include/curl for generated curlbuild.h included from curl.h
# $(top_builddir)/include for generated curlbuild.h inc. from lib/curl_setup.h
# $(top_srcdir)/include is for libcurl's external include files
# $(top_builddir)/lib is for libcurl's generated lib/config.h file
# $(top_srcdir)/lib is for libcurl's lib/setup.h and other "borrowed" files
# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file
# $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "borrowed" files
# $(top_builddir)/ares is for in-tree c-ares's generated ares_build.h file
# $(top_srcdir)/ares is for in-tree c-ares's external include files
INCLUDES = -I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_builddir)/lib \
-I$(top_srcdir)/lib
if USE_EMBEDDED_ARES
AM_CPPFLAGS = -I$(top_builddir)/include/curl \
-I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_builddir)/lib \
-I$(top_srcdir)/lib \
-I$(top_builddir)/ares \
-I$(top_srcdir)/ares
else
AM_CPPFLAGS = -I$(top_builddir)/include/curl \
-I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_builddir)/lib \
-I$(top_srcdir)/lib
endif
noinst_PROGRAMS = sws getpart sockfilt resolve tftpd
# Prevent LIBS from being used for all link targets
LIBS = $(BLANK_AT_MAKETIME)
useful = getpart.c getpart.h $(top_srcdir)/lib/strequal.c \
$(top_srcdir)/lib/base64.c $(top_srcdir)/lib/mprintf.c \
$(top_srcdir)/lib/memdebug.c $(top_srcdir)/lib/timeval.c
if DOING_NATIVE_WINDOWS
AM_CPPFLAGS += -DCURL_STATICLIB
endif
resolve_SOURCES= resolve.c util.c util.h $(useful)
resolve_LDADD = @TEST_SERVER_LIBS@
# Makefile.inc provides neat definitions
include Makefile.inc
sws_SOURCES= sws.c util.c util.h $(useful)
sws_LDADD = @TEST_SERVER_LIBS@
sockfilt_SOURCES = sockfilt.c util.c util.h $(useful) \
$(top_srcdir)/lib/inet_pton.c
sockfilt_LDADD = @TEST_SERVER_LIBS@
getpart_SOURCES= testpart.c $(useful)
# This is needed because of (unused) network debugging functions in memdebug.c
getpart_LDADD = @TEST_SERVER_LIBS@
tftpd_SOURCES = tftpd.c util.c util.h $(useful) tftp.h
tftpd_LDADD = @TEST_SERVER_LIBS@
extra_DIST = base64.pl
EXTRA_DIST = base64.pl Makefile.inc
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
noinst_PROGRAMS = getpart resolve rtspd sockfilt sws tftpd fake_ntlm
CURLX_SRCS = \
../../lib/mprintf.c \
../../lib/nonblock.c \
../../lib/strequal.c \
../../lib/strtoofft.c \
../../lib/timeval.c \
../../lib/warnless.c
CURLX_HDRS = \
../../lib/curlx.h \
../../lib/nonblock.h \
../../lib/strequal.h \
../../lib/strtoofft.h \
../../lib/timeval.h \
../../lib/warnless.h
USEFUL = \
getpart.c \
getpart.h \
server_setup.h \
../../lib/base64.c \
../../lib/curl_base64.h \
../../lib/memdebug.c \
../../lib/memdebug.h
UTIL = \
util.c \
util.h
getpart_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) \
testpart.c
getpart_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
getpart_CFLAGS = $(AM_CFLAGS)
resolve_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
resolve.c
resolve_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
resolve_CFLAGS = $(AM_CFLAGS)
rtspd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h \
rtspd.c
rtspd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
rtspd_CFLAGS = $(AM_CFLAGS)
sockfilt_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h \
sockfilt.c \
../../lib/inet_pton.c
sockfilt_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
sockfilt_CFLAGS = $(AM_CFLAGS)
sws_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h \
sws.c \
../../lib/inet_pton.c
sws_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
sws_CFLAGS = $(AM_CFLAGS)
tftpd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
server_sockaddr.h \
tftpd.c \
tftp.h
tftpd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
tftpd_CFLAGS = $(AM_CFLAGS)
fake_ntlm_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
fake_ntlm.c
fake_ntlm_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
fake_ntlm_CFLAGS = $(AM_CFLAGS)
@@ -0,0 +1,9 @@
#!/usr/bin/perl
use MIME::Base64 qw(encode_base64);
my $buf;
while(read(STDIN, $buf, 60*57)) {
my $enc = encode_base64($buf);
print "$enc";
}
@@ -0,0 +1,277 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, Mandy Wu, <[email protected]>
* Copyright (C) 2011 - 2013, Daniel Stenberg, <[email protected]>, 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.
*
***************************************************************************/
#include "server_setup.h"
/*
* This is a fake ntlm_auth, which is used for testing NTLM single-sign-on.
* When DEBUGBUILD is defined, libcurl invoke this tool instead of real winbind
* daemon helper /usr/bin/ntlm_auth. This tool will accept commands and
* responses with a pre-written string saved in test case test2005.
*/
#define ENABLE_CURLX_PRINTF
#include "curlx.h" /* from the private lib dir */
#include "getpart.h"
#include "util.h"
/* include memdebug.h last */
#include "memdebug.h"
#ifndef DEFAULT_LOGFILE
#define DEFAULT_LOGFILE "log/fake_ntlm.log"
#endif
const char *serverlogfile = DEFAULT_LOGFILE;
/*
* Returns an allocated buffer with printable representation of input
* buffer contents or returns NULL on out of memory condition.
*/
static char *printable(char *inbuf, size_t inlength)
{
char *outbuf;
char *newbuf;
size_t newsize;
size_t outsize;
size_t outincr = 0;
size_t i, o = 0;
#define HEX_FMT_STR "[0x%02X]"
#define HEX_STR_LEN 6
#define NOTHING_STR "[NOTHING]"
#define NOTHING_LEN 9
if(!inlength)
inlength = strlen(inbuf);
if(inlength) {
outincr = ((inlength/2) < (HEX_STR_LEN+1)) ? HEX_STR_LEN+1 : inlength/2;
outsize = inlength + outincr;
}
else
outsize = NOTHING_LEN + 1;
outbuf = malloc(outsize);
if(!outbuf)
return NULL;
if(!inlength) {
sprintf(&outbuf[0], "%s", NOTHING_STR);
return outbuf;
}
for(i=0; i<inlength; i++) {
if(o > outsize - (HEX_STR_LEN + 1)) {
newsize = outsize + outincr;
newbuf = realloc(outbuf, newsize);
if(!newbuf) {
free(outbuf);
return NULL;
}
outbuf = newbuf;
outsize = newsize;
}
if((inbuf[i] > 0x20) && (inbuf[i] < 0x7F)) {
outbuf[o] = inbuf[i];
o++;
}
else {
sprintf(&outbuf[o], HEX_FMT_STR, inbuf[i]);
o += HEX_STR_LEN;
}
}
outbuf[o] = '\0';
return outbuf;
}
int main(int argc, char *argv[])
{
char buf[1024];
FILE *stream;
char *filename;
int error;
char *type1_input = NULL, *type3_input = NULL;
char *type1_output = NULL, *type3_output = NULL;
size_t size = 0;
long testnum;
const char *env;
int arg = 1;
char *helper_user = (char *)"unknown";
char *helper_proto = (char *)"unknown";
char *helper_domain = (char *)"unknown";
bool use_cached_creds = FALSE;
char *msgbuf;
buf[0] = '\0';
while(argc > arg) {
if(!strcmp("--use-cached-creds", argv[arg])) {
use_cached_creds = TRUE;
arg++;
}
else if(!strcmp("--helper-protocol", argv[arg])) {
arg++;
if(argc > arg)
helper_proto = argv[arg++];
}
else if(!strcmp("--username", argv[arg])) {
arg++;
if(argc > arg)
helper_user = argv[arg++];
}
else if(!strcmp("--domain", argv[arg])) {
arg++;
if(argc > arg)
helper_domain = argv[arg++];
}
else {
puts("Usage: fake_ntlm [option]\n"
" --use-cached-creds\n"
" --helper-protocol [protocol]\n"
" --username [username]\n"
" --domain [domain]");
exit(1);
}
}
logmsg("fake_ntlm (user: %s) (proto: %s) (domain: %s) (cached creds: %s)",
helper_user, helper_proto, helper_domain,
(use_cached_creds) ? "yes" : "no");
env = getenv("CURL_NTLM_AUTH_TESTNUM");
if (env) {
char *endptr;
long lnum = strtol(env, &endptr, 10);
if((endptr != env + strlen(env)) || (lnum < 1L)) {
logmsg("Test number not valid in CURL_NTLM_AUTH_TESTNUM");
exit(1);
}
testnum = lnum;
} else {
logmsg("Test number not specified in CURL_NTLM_AUTH_TESTNUM");
exit(1);
}
env = getenv("CURL_NTLM_AUTH_SRCDIR");
if (env) {
path = env;
}
filename = test2file(testnum);
stream=fopen(filename, "rb");
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Error opening file: %s", filename);
logmsg("Couldn't open test file %ld", testnum);
exit(1);
}
else {
/* get the ntlm_auth input/output */
error = getpart(&type1_input, &size, "ntlm_auth_type1", "input", stream);
fclose(stream);
if(error || size == 0) {
logmsg("getpart() type 1 input failed with error: %d", error);
exit(1);
}
}
stream=fopen(filename, "rb");
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Error opening file: %s", filename);
logmsg("Couldn't open test file %ld", testnum);
exit(1);
}
else {
size = 0;
error = getpart(&type3_input, &size, "ntlm_auth_type3", "input", stream);
fclose(stream);
if(error || size == 0) {
logmsg("getpart() type 3 input failed with error: %d", error);
exit(1);
}
}
while(fgets(buf, sizeof(buf), stdin)) {
if(strcmp(buf, type1_input) == 0) {
stream=fopen(filename, "rb");
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Error opening file: %s", filename);
logmsg("Couldn't open test file %ld", testnum);
exit(1);
}
else {
size = 0;
error = getpart(&type1_output, &size, "ntlm_auth_type1", "output", stream);
fclose(stream);
if(error || size == 0) {
logmsg("getpart() type 1 output failed with error: %d", error);
exit(1);
}
}
printf("%s", type1_output);
fflush(stdout);
}
else if(strncmp(buf, type3_input, strlen(type3_input)) == 0) {
stream=fopen(filename, "rb");
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Error opening file: %s", filename);
logmsg("Couldn't open test file %ld", testnum);
exit(1);
}
else {
size = 0;
error = getpart(&type3_output, &size, "ntlm_auth_type3", "output", stream);
fclose(stream);
if(error || size == 0) {
logmsg("getpart() type 3 output failed with error: %d", error);
exit(1);
}
}
printf("%s", type3_output);
fflush(stdout);
}
else {
printf("Unknown request\n");
msgbuf = printable(buf, 0);
if(msgbuf) {
logmsg("invalid input: '%s'\n", msgbuf);
free(msgbuf);
}
else
logmsg("OOM formatting invalid input: '%s'\n", buf);
exit(1);
}
}
return 1;
}
+312 -144
View File
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,35 +18,35 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: getpart.c,v 1.28 2008-10-23 14:07:28 yangtse Exp $
***************************************************************************/
#include "setup.h"
#include "server_setup.h"
#include "getpart.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#define ENABLE_CURLX_PRINTF
/* make the curlx header define all printf() functions to use the curlx_*
versions instead */
#include "curlx.h" /* from the private lib dir */
/* just to please base64.h we create a fake struct */
/* just to please curl_base64.h we create a fake struct */
struct SessionHandle {
int fake;
};
#include "curl_base64.h"
#include "memory.h"
#include "curl_memory.h"
/* include memdebug.h last */
#include "memdebug.h"
#define EAT_SPACE(ptr) while( ptr && *ptr && ISSPACE(*ptr) ) ptr++
#define EAT_WORD(ptr) while( ptr && *ptr && !ISSPACE(*ptr) && \
('>' != *ptr)) ptr++
#define EAT_SPACE(p) while(*(p) && ISSPACE(*(p))) (p)++
#ifdef DEBUG
#define EAT_WORD(p) while(*(p) && !ISSPACE(*(p)) && ('>' != *(p))) (p)++
#ifdef DEBUG_GETPART
#define show(x) printf x
#else
#define show(x)
#define show(x) Curl_nop_stmt
#endif
#if defined(_MSC_VER) && defined(_DLL)
@@ -63,191 +63,359 @@ curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
# pragma warning(default:4232) /* MSVC extension, dllimport identity */
#endif
static
char *appendstring(char *string, /* original string */
char *buffer, /* to append */
size_t *stringlen, /* length of string */
size_t *stralloc, /* allocated size */
char base64) /* 1 if base64 encoded */
/*
* readline()
*
* Reads a complete line from a file into a dynamically allocated buffer.
*
* Calling function may call this multiple times with same 'buffer'
* and 'bufsize' pointers to avoid multiple buffer allocations. Buffer
* will be reallocated and 'bufsize' increased until whole line fits in
* buffer before returning it.
*
* Calling function is responsible to free allocated buffer.
*
* This function may return:
* GPE_OUT_OF_MEMORY
* GPE_END_OF_FILE
* GPE_OK
*/
static int readline(char **buffer, size_t *bufsize, FILE *stream)
{
size_t offset = 0;
size_t length;
char *newptr;
if(!*buffer) {
*buffer = malloc(128);
if(!*buffer)
return GPE_OUT_OF_MEMORY;
*bufsize = 128;
}
for(;;) {
int bytestoread = curlx_uztosi(*bufsize - offset);
if(!fgets(*buffer + offset, bytestoread, stream))
return (offset != 0) ? GPE_OK : GPE_END_OF_FILE ;
length = offset + strlen(*buffer + offset);
if(*(*buffer + length - 1) == '\n')
break;
offset = length;
if(length < *bufsize - 1)
continue;
newptr = realloc(*buffer, *bufsize * 2);
if(!newptr)
return GPE_OUT_OF_MEMORY;
*buffer = newptr;
*bufsize *= 2;
}
return GPE_OK;
}
/*
* appenddata()
*
* This appends data from a given source buffer to the end of the used part of
* a destination buffer. Arguments relative to the destination buffer are, the
* address of a pointer to the destination buffer 'dst_buf', the length of data
* in destination buffer excluding potential null string termination 'dst_len',
* the allocated size of destination buffer 'dst_alloc'. All three destination
* buffer arguments may be modified by this function. Arguments relative to the
* source buffer are, a pointer to the source buffer 'src_buf' and indication
* whether the source buffer is base64 encoded or not 'src_b64'.
*
* If the source buffer is indicated to be base64 encoded, this appends the
* decoded data, binary or whatever, to the destination. The source buffer
* may not hold binary data, only a null terminated string is valid content.
*
* Destination buffer will be enlarged and relocated as needed.
*
* Calling function is responsible to provide preallocated destination
* buffer and also to deallocate it when no longer needed.
*
* This function may return:
* GPE_OUT_OF_MEMORY
* GPE_OK
*/
static int appenddata(char **dst_buf, /* dest buffer */
size_t *dst_len, /* dest buffer data length */
size_t *dst_alloc, /* dest buffer allocated size */
char *src_buf, /* source buffer */
int src_b64) /* != 0 if source is base64 encoded */
{
size_t need_alloc, src_len;
union {
unsigned char * as_uchar;
char * as_char;
unsigned char *as_uchar;
char *as_char;
} buf64;
size_t len = strlen(buffer);
size_t needed_len = len + *stringlen + 1;
src_len = strlen(src_buf);
if(!src_len)
return GPE_OK;
buf64.as_char = NULL;
if(base64) {
/* decode the given buffer first */
len = Curl_base64_decode(buffer, &buf64.as_uchar); /* updated len */
buffer = buf64.as_char;
needed_len = len + *stringlen + 1; /* recalculate */
}
if(needed_len >= *stralloc) {
char *newptr;
size_t newsize = needed_len*2; /* get twice the needed size */
newptr = realloc(string, newsize);
if(newptr) {
string = newptr;
*stralloc = newsize;
}
else {
if(src_b64) {
/* base64 decode the given buffer */
int error = (int) Curl_base64_decode(src_buf, &buf64.as_uchar, &src_len);
if(error)
return GPE_OUT_OF_MEMORY;
src_buf = buf64.as_char;
if(!src_len || !src_buf) {
/*
** currently there is no way to tell apart an OOM condition in
** Curl_base64_decode() from zero length decoded data. For now,
** let's just assume it is an OOM condition, currently we have
** no input for this function that decodes to zero length data.
*/
if(buf64.as_char)
free(buf64.as_char);
return NULL;
return GPE_OUT_OF_MEMORY;
}
}
need_alloc = src_len + *dst_len + 1;
/* enlarge destination buffer if required */
if(need_alloc > *dst_alloc) {
size_t newsize = need_alloc * 2;
char *newptr = realloc(*dst_buf, newsize);
if(!newptr) {
if(buf64.as_char)
free(buf64.as_char);
return GPE_OUT_OF_MEMORY;
}
*dst_alloc = newsize;
*dst_buf = newptr;
}
/* memcpy to support binary blobs */
memcpy(&string[*stringlen], buffer, len);
*stringlen += len;
string[*stringlen]=0;
memcpy(*dst_buf + *dst_len, src_buf, src_len);
*dst_len += src_len;
*(*dst_buf + *dst_len) = '\0';
if(buf64.as_char)
free(buf64.as_char);
return string;
return GPE_OK;
}
const char *spitout(FILE *stream,
const char *main,
const char *sub, size_t *size)
/*
* getpart()
*
* This returns whole contents of specified XML-like section and subsection
* from the given file. This is mostly used to retrieve a specific part from
* a test definition file for consumption by test suite servers.
*
* Data is returned in a dynamically allocated buffer, a pointer to this data
* and the size of the data is stored at the addresses that caller specifies.
*
* If the returned data is a string the returned size will be the length of
* the string excluding null termination. Otherwise it will just be the size
* of the returned binary data.
*
* Calling function is responsible to free returned buffer.
*
* This function may return:
* GPE_NO_BUFFER_SPACE
* GPE_OUT_OF_MEMORY
* GPE_OK
*/
int getpart(char **outbuf, size_t *outlen,
const char *main, const char *sub, FILE *stream)
{
char buffer[8192]; /* big enough for anything */
char cmain[128]=""; /* current main section */
char csub[128]=""; /* current sub section */
# define MAX_TAG_LEN 79
char couter[MAX_TAG_LEN+1]; /* current outermost section */
char cmain[MAX_TAG_LEN+1]; /* current main section */
char csub[MAX_TAG_LEN+1]; /* current sub section */
char ptag[MAX_TAG_LEN+1]; /* potential tag */
char patt[MAX_TAG_LEN+1]; /* potential attributes */
char *buffer = NULL;
char *ptr;
char *end;
char display = 0;
char *string;
size_t stringlen=0;
size_t stralloc=256;
char base64 = 0; /* set to 1 if true */
union {
ssize_t sig;
size_t uns;
} len;
size_t bufsize = 0;
size_t outalloc = 256;
int in_wanted_part = 0;
int base64 = 0;
int error;
enum {
STATE_OUTSIDE,
STATE_OUTER,
STATE_INMAIN,
STATE_INSUB,
STATE_ILLEGAL
STATE_OUTSIDE = 0,
STATE_OUTER = 1,
STATE_INMAIN = 2,
STATE_INSUB = 3,
STATE_ILLEGAL = 4
} state = STATE_OUTSIDE;
string = malloc(stralloc);
if(!string)
return NULL;
*outlen = 0;
*outbuf = malloc(outalloc);
if(!*outbuf)
return GPE_OUT_OF_MEMORY;
*(*outbuf) = '\0';
string[0] = 0; /* zero first byte in case of no data */
couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0';
while(fgets(buffer, sizeof(buffer), stream)) {
while((error = readline(&buffer, &bufsize, stream)) == GPE_OK) {
ptr = buffer;
/* pass white spaces */
EAT_SPACE(ptr);
if('<' != *ptr) {
if(display) {
if(in_wanted_part) {
show(("=> %s", buffer));
string = appendstring(string, buffer, &stringlen, &stralloc, base64);
show(("* %s\n", buffer));
error = appenddata(outbuf, outlen, &outalloc, buffer, base64);
if(error)
break;
}
continue;
}
ptr++;
EAT_SPACE(ptr);
if('/' == *ptr) {
/* end of a section */
/*
** closing section tag
*/
ptr++;
EAT_SPACE(ptr);
end = ptr;
EAT_WORD(end);
*end = 0;
if((state == STATE_INSUB) &&
!strcmp(csub, ptr)) {
/* this is the end of the currently read sub section */
state--;
csub[0]=0; /* no sub anymore */
display=0;
}
else if((state == STATE_INMAIN) &&
!strcmp(cmain, ptr)) {
/* this is the end of the currently read main section */
state--;
cmain[0]=0; /* no main anymore */
display=0;
}
else if(state == STATE_OUTER) {
/* this is the end of the outermost file section */
state--;
}
}
else if(!display) {
/* this is the beginning of a section */
end = ptr;
EAT_WORD(end);
*end = 0;
switch(state) {
case STATE_OUTSIDE:
/* Skip over the outermost element (<testcase>), but if it turns out
to be a comment, completely ignore it below */
strcpy(cmain, ptr);
state = STATE_OUTER;
if((len.sig = end - ptr) > MAX_TAG_LEN) {
error = GPE_NO_BUFFER_SPACE;
break;
case STATE_OUTER:
strcpy(cmain, ptr);
}
memcpy(ptag, ptr, len.uns);
ptag[len.uns] = '\0';
if((STATE_INSUB == state) && !strcmp(csub, ptag)) {
/* end of current sub section */
state = STATE_INMAIN;
break;
case STATE_INMAIN:
strcpy(csub, ptr);
state = STATE_INSUB;
break;
default:
break;
}
if(!end[1] != '>') {
/* There might be attributes here. Check for those we know of and care
about. */
if(strstr(&end[1], "base64=")) {
/* rough and dirty, but "mostly" functional */
/* Treat all data as base64 encoded */
base64 = 1;
csub[0] = '\0';
if(in_wanted_part) {
/* end of wanted part */
in_wanted_part = 0;
break;
}
}
else if((STATE_INMAIN == state) && !strcmp(cmain, ptag)) {
/* end of current main section */
state = STATE_OUTER;
cmain[0] = '\0';
if(in_wanted_part) {
/* end of wanted part */
in_wanted_part = 0;
break;
}
}
else if((STATE_OUTER == state) && !strcmp(couter, ptag)) {
/* end of outermost file section */
state = STATE_OUTSIDE;
couter[0] = '\0';
if(in_wanted_part) {
/* end of wanted part */
in_wanted_part = 0;
break;
}
}
}
if(display) {
string = appendstring(string, buffer, &stringlen, &stralloc, base64);
show(("* %s\n", buffer));
else if(!in_wanted_part) {
/*
** opening section tag
*/
/* get potential tag */
end = ptr;
EAT_WORD(end);
if((len.sig = end - ptr) > MAX_TAG_LEN) {
error = GPE_NO_BUFFER_SPACE;
break;
}
memcpy(ptag, ptr, len.uns);
ptag[len.uns] = '\0';
/* ignore comments, doctypes and xml declarations */
if(('!' == ptag[0]) || ('?' == ptag[0])) {
show(("* ignoring (%s)", buffer));
continue;
}
/* get all potential attributes */
ptr = end;
EAT_SPACE(ptr);
end = ptr;
while(*end && ('>' != *end))
end++;
if((len.sig = end - ptr) > MAX_TAG_LEN) {
error = GPE_NO_BUFFER_SPACE;
break;
}
memcpy(patt, ptr, len.uns);
patt[len.uns] = '\0';
if(STATE_OUTSIDE == state) {
/* outermost element (<testcase>) */
strcpy(couter, ptag);
state = STATE_OUTER;
continue;
}
else if(STATE_OUTER == state) {
/* start of a main section */
strcpy(cmain, ptag);
state = STATE_INMAIN;
continue;
}
else if(STATE_INMAIN == state) {
/* start of a sub section */
strcpy(csub, ptag);
state = STATE_INSUB;
if(!strcmp(cmain, main) && !strcmp(csub, sub)) {
/* start of wanted part */
in_wanted_part = 1;
if(strstr(patt, "base64="))
/* bit rough test, but "mostly" functional, */
/* treat wanted part data as base64 encoded */
base64 = 1;
}
continue;
}
}
if((STATE_INSUB == state) &&
!strcmp(cmain, main) &&
!strcmp(csub, sub)) {
show(("* (%d bytes) %s\n", stringlen, buffer));
display = 1; /* start displaying */
}
else if ((*cmain == '?') || (*cmain == '!') || (*csub == '!')) {
/* Ignore comments, DOCTYPEs and XML declarations */
show(("%d ignoring (%s/%s)\n", state, cmain, csub));
state--;
if(in_wanted_part) {
show(("=> %s", buffer));
error = appenddata(outbuf, outlen, &outalloc, buffer, base64);
if(error)
break;
}
} /* while */
if(buffer)
free(buffer);
if(error != GPE_OK) {
if(error == GPE_END_OF_FILE)
error = GPE_OK;
else {
show(("%d (%s/%s): %s\n", state, cmain, csub, buffer));
display = 0; /* no display */
if(*outbuf)
free(*outbuf);
*outbuf = NULL;
*outlen = 0;
}
}
*size = stringlen;
return string;
return error;
}
@@ -1,3 +1,5 @@
#ifndef HEADER_CURL_SERVER_GETPART_H
#define HEADER_CURL_SERVER_GETPART_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -5,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <[email protected]>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,10 +20,15 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: getpart.h,v 1.3 2004/11/29 12:10:09 bagder Exp $
***************************************************************************/
const char *
spitout(FILE *stream,
const char *main,
const char *sub,
size_t *size);
#include "server_setup.h"
#define GPE_NO_BUFFER_SPACE -2
#define GPE_OUT_OF_MEMORY -1
#define GPE_OK 0
#define GPE_END_OF_FILE 1
int getpart(char **outbuf, size_t *outlen,
const char *main, const char *sub, FILE *stream);
#endif /* HEADER_CURL_SERVER_GETPART_H */
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,8 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: resolve.c,v 1.13 2008-10-28 20:03:22 danf Exp $
***************************************************************************/
#include "server_setup.h"
/* Purpose
*
@@ -30,20 +30,10 @@
* Like if 'localhost' actual exists etc.
*
*/
#include "setup.h" /* portability help from the lib directory */
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
@@ -128,8 +118,8 @@ int main(int argc, char *argv[])
else {
#ifdef ENABLE_IPV6
/* Check that the system has IPv6 enabled before checking the resolver */
int s = socket(PF_INET6, SOCK_DGRAM, 0);
if(s == -1)
curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
if(s == CURL_SOCKET_BAD)
/* an ipv6 address was requested and we can't get/use one */
rc = -1;
else {
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
#ifndef HEADER_CURL_SERVER_SETUP_H
#define HEADER_CURL_SERVER_SETUP_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, 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.
*
***************************************************************************/
#define CURL_NO_OLDIES
#include "curl_setup.h" /* portability help from the lib directory */
#endif /* HEADER_CURL_SERVER_SETUP_H */
@@ -0,0 +1,34 @@
#ifndef HEADER_CURL_SERVER_SOCKADDR_H
#define HEADER_CURL_SERVER_SOCKADDR_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, 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.
*
***************************************************************************/
#include "server_setup.h"
typedef union {
struct sockaddr sa;
struct sockaddr_in sa4;
#ifdef ENABLE_IPV6
struct sockaddr_in6 sa6;
#endif
} srvr_sockaddr_union_t;
#endif /* HEADER_CURL_SERVER_SOCKADDR_H */
+431 -86
View File
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <[email protected]>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,8 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: sockfilt.c,v 1.55 2008-10-01 17:34:25 danf Exp $
***************************************************************************/
#include "server_setup.h"
/* Purpose
*
@@ -80,27 +80,21 @@
* if no signal was being ignored or handled at all. Enjoy it!
*/
#include "setup.h" /* portability help from the lib directory */
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef _XOPEN_SOURCE_EXTENDED
/* This define is "almost" required to build on HPUX 11 */
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef USE_WINSOCK
#include <conio.h> /* for _kbhit() used in select_ws() */
#endif
#define ENABLE_CURLX_PRINTF
/* make the curlx header define all printf() functions to use the curlx_*
@@ -109,10 +103,23 @@
#include "getpart.h"
#include "inet_pton.h"
#include "util.h"
#include "server_sockaddr.h"
#include "warnless.h"
/* include memdebug.h last */
#include "memdebug.h"
#ifdef USE_WINSOCK
#undef EINTR
#define EINTR 4 /* errno.h value */
#undef EAGAIN
#define EAGAIN 11 /* errno.h value */
#undef ENOMEM
#define ENOMEM 12 /* errno.h value */
#undef EINVAL
#define EINVAL 22 /* errno.h value */
#endif
#define DEFAULT_PORT 8999
#ifndef DEFAULT_LOGFILE
@@ -122,6 +129,7 @@
const char *serverlogfile = DEFAULT_LOGFILE;
static bool verbose = FALSE;
static bool bind_only = FALSE;
#ifdef ENABLE_IPV6
static bool use_ipv6 = FALSE;
#endif
@@ -146,11 +154,29 @@ enum sockmode {
typedef RETSIGTYPE (*SIGHANDLER_T)(int);
#ifdef SIGHUP
static SIGHANDLER_T old_sighup_handler = SIG_ERR;
#endif
#ifdef SIGPIPE
static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
#endif
#ifdef SIGALRM
static SIGHANDLER_T old_sigalrm_handler = SIG_ERR;
#endif
#ifdef SIGINT
static SIGHANDLER_T old_sigint_handler = SIG_ERR;
#endif
#ifdef SIGTERM
static SIGHANDLER_T old_sigterm_handler = SIG_ERR;
#endif
#if defined(SIGBREAK) && defined(WIN32)
static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
#endif
/* var which if set indicates that the program should finish execution */
@@ -167,13 +193,13 @@ static volatile int exit_signal = 0;
static RETSIGTYPE exit_signal_handler(int signum)
{
int old_errno = ERRNO;
int old_errno = errno;
if(got_exit_signal == 0) {
got_exit_signal = 1;
exit_signal = signum;
}
(void)signal(signum, exit_signal_handler);
SET_ERRNO(old_errno);
errno = old_errno;
}
static void install_signal_handlers(void)
@@ -181,32 +207,39 @@ static void install_signal_handlers(void)
#ifdef SIGHUP
/* ignore SIGHUP signal */
if((old_sighup_handler = signal(SIGHUP, SIG_IGN)) == SIG_ERR)
logmsg("cannot install SIGHUP handler: %s", strerror(ERRNO));
logmsg("cannot install SIGHUP handler: %s", strerror(errno));
#endif
#ifdef SIGPIPE
/* ignore SIGPIPE signal */
if((old_sigpipe_handler = signal(SIGPIPE, SIG_IGN)) == SIG_ERR)
logmsg("cannot install SIGPIPE handler: %s", strerror(ERRNO));
logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
#endif
#ifdef SIGALRM
/* ignore SIGALRM signal */
if((old_sigalrm_handler = signal(SIGALRM, SIG_IGN)) == SIG_ERR)
logmsg("cannot install SIGALRM handler: %s", strerror(ERRNO));
logmsg("cannot install SIGALRM handler: %s", strerror(errno));
#endif
#ifdef SIGINT
/* handle SIGINT signal with our exit_signal_handler */
if((old_sigint_handler = signal(SIGINT, exit_signal_handler)) == SIG_ERR)
logmsg("cannot install SIGINT handler: %s", strerror(ERRNO));
logmsg("cannot install SIGINT handler: %s", strerror(errno));
else
siginterrupt(SIGINT, 1);
#endif
#ifdef SIGTERM
/* handle SIGTERM signal with our exit_signal_handler */
if((old_sigterm_handler = signal(SIGTERM, exit_signal_handler)) == SIG_ERR)
logmsg("cannot install SIGTERM handler: %s", strerror(ERRNO));
logmsg("cannot install SIGTERM handler: %s", strerror(errno));
else
siginterrupt(SIGTERM, 1);
#endif
#if defined(SIGBREAK) && defined(WIN32)
/* handle SIGBREAK signal with our exit_signal_handler */
if((old_sigbreak_handler = signal(SIGBREAK, exit_signal_handler)) == SIG_ERR)
logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
else
siginterrupt(SIGBREAK, 1);
#endif
}
static void restore_signal_handlers(void)
@@ -231,6 +264,10 @@ static void restore_signal_handlers(void)
if(SIG_ERR != old_sigterm_handler)
(void)signal(SIGTERM, old_sigterm_handler);
#endif
#if defined(SIGBREAK) && defined(WIN32)
if(SIG_ERR != old_sigbreak_handler)
(void)signal(SIGBREAK, old_sigbreak_handler);
#endif
}
/*
@@ -255,10 +292,12 @@ static ssize_t fullread(int filedes, void *buffer, size_t nbytes)
}
if(rc < 0) {
error = ERRNO;
error = errno;
if((error == EINTR) || (error == EAGAIN))
continue;
logmsg("unrecoverable read() failure: %s", strerror(error));
logmsg("reading from file descriptor: %d,", filedes);
logmsg("unrecoverable read() failure: (%d) %s",
error, strerror(error));
return -1;
}
@@ -299,10 +338,12 @@ static ssize_t fullwrite(int filedes, const void *buffer, size_t nbytes)
}
if(wc < 0) {
error = ERRNO;
error = errno;
if((error == EINTR) || (error == EAGAIN))
continue;
logmsg("unrecoverable write() failure: %s", strerror(error));
logmsg("writing to file descriptor: %d,", filedes);
logmsg("unrecoverable write() failure: (%d) %s",
error, strerror(error));
return -1;
}
@@ -392,6 +433,233 @@ static void lograw(unsigned char *buffer, ssize_t len)
logmsg("'%s'", data);
}
#ifdef USE_WINSOCK
/*
* WinSock select() does not support standard file descriptors,
* it can only check SOCKETs. The following function is an attempt
* to re-create a select() function with support for other handle types.
*
* select() function with support for WINSOCK2 sockets and all
* other handle types supported by WaitForMultipleObjectsEx().
*
* TODO: Differentiate between read/write/except for non-SOCKET handles.
*
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms687028.aspx
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms741572.aspx
*/
static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
{
long networkevents;
DWORD milliseconds, wait, idx, avail, events, inputs;
WSAEVENT wsaevent, *wsaevents;
WSANETWORKEVENTS wsanetevents;
INPUT_RECORD *inputrecords;
HANDLE handle, *handles;
curl_socket_t sock, *fdarr, *wsasocks;
int error, fds;
DWORD nfd = 0, wsa = 0;
int ret = 0;
/* check if the input value is valid */
if(nfds < 0) {
errno = EINVAL;
return -1;
}
/* check if we got descriptors, sleep in case we got none */
if(!nfds) {
Sleep((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000));
return 0;
}
/* allocate internal array for the original input handles */
fdarr = malloc(nfds * sizeof(curl_socket_t));
if(fdarr == NULL) {
errno = ENOMEM;
return -1;
}
/* allocate internal array for the internal event handles */
handles = malloc(nfds * sizeof(HANDLE));
if(handles == NULL) {
errno = ENOMEM;
return -1;
}
/* allocate internal array for the internal socket handles */
wsasocks = malloc(nfds * sizeof(curl_socket_t));
if(wsasocks == NULL) {
errno = ENOMEM;
return -1;
}
/* allocate internal array for the internal WINSOCK2 events */
wsaevents = malloc(nfds * sizeof(WSAEVENT));
if(wsaevents == NULL) {
errno = ENOMEM;
return -1;
}
/* loop over the handles in the input descriptor sets */
for(fds = 0; fds < nfds; fds++) {
networkevents = 0;
handles[nfd] = 0;
if(FD_ISSET(fds, readfds))
networkevents |= FD_READ|FD_ACCEPT|FD_CLOSE;
if(FD_ISSET(fds, writefds))
networkevents |= FD_WRITE|FD_CONNECT;
if(FD_ISSET(fds, exceptfds))
networkevents |= FD_OOB;
/* only wait for events for which we actually care */
if(networkevents) {
fdarr[nfd] = curlx_sitosk(fds);
if(fds == fileno(stdin)) {
handles[nfd] = GetStdHandle(STD_INPUT_HANDLE);
}
else if(fds == fileno(stdout)) {
handles[nfd] = GetStdHandle(STD_OUTPUT_HANDLE);
}
else if(fds == fileno(stderr)) {
handles[nfd] = GetStdHandle(STD_ERROR_HANDLE);
}
else {
wsaevent = WSACreateEvent();
if(wsaevent != WSA_INVALID_EVENT) {
error = WSAEventSelect(fds, wsaevent, networkevents);
if(error != SOCKET_ERROR) {
handles[nfd] = wsaevent;
wsasocks[wsa] = curlx_sitosk(fds);
wsaevents[wsa] = wsaevent;
wsa++;
}
else {
handles[nfd] = (HANDLE) curlx_sitosk(fds);
WSACloseEvent(wsaevent);
}
}
}
nfd++;
}
}
/* convert struct timeval to milliseconds */
if(timeout) {
milliseconds = ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000));
}
else {
milliseconds = INFINITE;
}
/* wait for one of the internal handles to trigger */
wait = WaitForMultipleObjectsEx(nfd, handles, FALSE, milliseconds, FALSE);
/* loop over the internal handles returned in the descriptors */
for(idx = 0; idx < nfd; idx++) {
handle = handles[idx];
sock = fdarr[idx];
fds = curlx_sktosi(sock);
/* check if the current internal handle was triggered */
if(wait != WAIT_FAILED && (wait - WAIT_OBJECT_0) >= idx &&
WaitForSingleObjectEx(handle, 0, FALSE) == WAIT_OBJECT_0) {
/* try to handle the event with STD* handle functions */
if(fds == fileno(stdin)) {
/* check if there is no data in the input buffer */
if(!stdin->_cnt) {
/* check if we are getting data from a PIPE */
if(!GetConsoleMode(handle, &avail)) {
/* check if there is no data from PIPE input */
if(!PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
avail = 0;
if(!avail)
FD_CLR(sock, readfds);
} /* check if there is no data from keyboard input */
else if (!_kbhit()) {
/* check if there are INPUT_RECORDs in the input buffer */
if(GetNumberOfConsoleInputEvents(handle, &events)) {
if(events > 0) {
/* remove INPUT_RECORDs from the input buffer */
inputrecords = (INPUT_RECORD*)malloc(events *
sizeof(INPUT_RECORD));
if(inputrecords) {
if(!ReadConsoleInput(handle, inputrecords,
events, &inputs))
inputs = 0;
free(inputrecords);
}
/* check if we got all inputs, otherwise clear buffer */
if(events != inputs)
FlushConsoleInputBuffer(handle);
}
}
/* remove from descriptor set since there is no real data */
FD_CLR(sock, readfds);
}
}
/* stdin is never ready for write or exceptional */
FD_CLR(sock, writefds);
FD_CLR(sock, exceptfds);
}
else if(fds == fileno(stdout) || fds == fileno(stderr)) {
/* stdout and stderr are never ready for read or exceptional */
FD_CLR(sock, readfds);
FD_CLR(sock, exceptfds);
}
else {
/* try to handle the event with the WINSOCK2 functions */
error = WSAEnumNetworkEvents(fds, NULL, &wsanetevents);
if(error != SOCKET_ERROR) {
/* remove from descriptor set if not ready for read/accept/close */
if(!(wsanetevents.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)))
FD_CLR(sock, readfds);
/* remove from descriptor set if not ready for write/connect */
if(!(wsanetevents.lNetworkEvents & (FD_WRITE|FD_CONNECT)))
FD_CLR(sock, writefds);
/* remove from descriptor set if not exceptional */
if(!(wsanetevents.lNetworkEvents & FD_OOB))
FD_CLR(sock, exceptfds);
}
}
/* check if the event has not been filtered using specific tests */
if(FD_ISSET(sock, readfds) || FD_ISSET(sock, writefds) ||
FD_ISSET(sock, exceptfds)) {
ret++;
}
}
else {
/* remove from all descriptor sets since this handle did not trigger */
FD_CLR(sock, readfds);
FD_CLR(sock, writefds);
FD_CLR(sock, exceptfds);
}
}
for(idx = 0; idx < wsa; idx++) {
WSAEventSelect(wsasocks[idx], NULL, 0);
WSACloseEvent(wsaevents[idx]);
}
free(wsaevents);
free(wsasocks);
free(handles);
free(fdarr);
return ret;
}
#define select(a,b,c,d,e) select_ws(a,b,c,d,e)
#endif /* USE_WINSOCK */
/*
sockfdp is a pointer to an established stream or CURL_SOCKET_BAD
@@ -407,7 +675,7 @@ static bool juggle(curl_socket_t *sockfdp,
fd_set fds_write;
fd_set fds_err;
curl_socket_t sockfd = CURL_SOCKET_BAD;
curl_socket_t maxfd = CURL_SOCKET_BAD;
int maxfd = -99;
ssize_t rc;
ssize_t nread_socket;
ssize_t bytes_written;
@@ -440,7 +708,7 @@ static bool juggle(curl_socket_t *sockfdp,
FD_ZERO(&fds_write);
FD_ZERO(&fds_err);
FD_SET(fileno(stdin), &fds_read);
FD_SET((curl_socket_t)fileno(stdin), &fds_read);
switch(*mode) {
@@ -450,7 +718,7 @@ static bool juggle(curl_socket_t *sockfdp,
sockfd = listenfd;
/* there's always a socket to wait for */
FD_SET(sockfd, &fds_read);
maxfd = sockfd;
maxfd = (int)sockfd;
break;
case PASSIVE_CONNECT:
@@ -464,7 +732,7 @@ static bool juggle(curl_socket_t *sockfdp,
else {
/* there's always a socket to wait for */
FD_SET(sockfd, &fds_read);
maxfd = sockfd;
maxfd = (int)sockfd;
}
break;
@@ -474,7 +742,7 @@ static bool juggle(curl_socket_t *sockfdp,
/* sockfd turns CURL_SOCKET_BAD when our connection has been closed */
if(CURL_SOCKET_BAD != sockfd) {
FD_SET(sockfd, &fds_read);
maxfd = sockfd;
maxfd = (int)sockfd;
}
else {
logmsg("No socket to read on");
@@ -494,14 +762,16 @@ static bool juggle(curl_socket_t *sockfdp,
do {
rc = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
/* select() blocking behavior call on blocking descriptors please */
rc = select(maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
if(got_exit_signal) {
logmsg("signalled to die, exiting...");
return FALSE;
}
} while((rc == -1) && ((error = SOCKERRNO) == EINTR));
} while((rc == -1) && ((error = errno) == EINTR));
if(rc < 0) {
logmsg("select() failed with error: (%d) %s",
@@ -545,9 +815,9 @@ static bool juggle(curl_socket_t *sockfdp,
else if(!memcmp("PORT", buffer, 4)) {
/* Question asking us what PORT number we are listening to.
Replies to PORT with "IPv[num]/[port]" */
sprintf((char *)buffer, "%s/%d\n", ipv_inuse, (int)port);
sprintf((char *)buffer, "%s/%hu\n", ipv_inuse, port);
buffer_len = (ssize_t)strlen((char *)buffer);
snprintf(data, sizeof(data), "PORT\n%04x\n", buffer_len);
snprintf(data, sizeof(data), "PORT\n%04zx\n", buffer_len);
if(!write_stdout(data, 10))
return FALSE;
if(!write_stdout(buffer, buffer_len))
@@ -615,17 +885,22 @@ static bool juggle(curl_socket_t *sockfdp,
if((sockfd != CURL_SOCKET_BAD) && (FD_ISSET(sockfd, &fds_read)) ) {
curl_socket_t newfd = CURL_SOCKET_BAD; /* newly accepted socket */
if(*mode == PASSIVE_LISTEN) {
/* there's no stream set up yet, this is an indication that there's a
client connecting. */
sockfd = accept(sockfd, NULL, NULL);
if(CURL_SOCKET_BAD == sockfd)
logmsg("accept() failed");
newfd = accept(sockfd, NULL, NULL);
if(CURL_SOCKET_BAD == newfd) {
error = SOCKERRNO;
logmsg("accept(%d, NULL, NULL) failed with error: (%d) %s",
sockfd, error, strerror(error));
}
else {
logmsg("====> Client connect");
if(!write_stdout("CNCT\n", 5))
return FALSE;
*sockfdp = sockfd; /* store the new socket */
*sockfdp = newfd; /* store the new socket */
*mode = PASSIVE_CONNECT; /* we have connected */
}
return TRUE;
@@ -647,7 +922,7 @@ static bool juggle(curl_socket_t *sockfdp,
return TRUE;
}
snprintf(data, sizeof(data), "DATA\n%04x\n", nread_socket);
snprintf(data, sizeof(data), "DATA\n%04zx\n", nread_socket);
if(!write_stdout(data, 10))
return FALSE;
if(!write_stdout(buffer, nread_socket))
@@ -664,11 +939,8 @@ static curl_socket_t sockdaemon(curl_socket_t sock,
unsigned short *listenport)
{
/* passive daemon style */
struct sockaddr_in me;
#ifdef ENABLE_IPV6
struct sockaddr_in6 me6;
#endif /* ENABLE_IPV6 */
int flag = 1;
srvr_sockaddr_union_t listener;
int flag;
int rc;
int totdelay = 0;
int maxretr = 10;
@@ -678,16 +950,20 @@ static curl_socket_t sockdaemon(curl_socket_t sock,
do {
attempt++;
flag = 1;
rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(void *)&flag, sizeof(flag));
if(rc) {
error = SOCKERRNO;
logmsg("setsockopt(SO_REUSEADDR) failed with error: (%d) %s",
error, strerror(error));
if(maxretr) {
rc = wait_ms(delay);
if(rc) {
/* should not happen */
error = SOCKERRNO;
logmsg("wait_ms() failed: (%d) %s", error, strerror(error));
error = errno;
logmsg("wait_ms() failed with error: (%d) %s",
error, strerror(error));
sclose(sock);
return CURL_SOCKET_BAD;
}
@@ -708,55 +984,91 @@ static curl_socket_t sockdaemon(curl_socket_t sock,
logmsg("Continuing anyway...");
}
/* When the specified listener port is zero, it is actually a
request to let the system choose a non-zero available port. */
#ifdef ENABLE_IPV6
if(!use_ipv6) {
#endif
memset(&me, 0, sizeof(me));
me.sin_family = AF_INET;
me.sin_addr.s_addr = INADDR_ANY;
me.sin_port = htons(*listenport);
rc = bind(sock, (struct sockaddr *) &me, sizeof(me));
memset(&listener.sa4, 0, sizeof(listener.sa4));
listener.sa4.sin_family = AF_INET;
listener.sa4.sin_addr.s_addr = INADDR_ANY;
listener.sa4.sin_port = htons(*listenport);
rc = bind(sock, &listener.sa, sizeof(listener.sa4));
#ifdef ENABLE_IPV6
}
else {
memset(&me6, 0, sizeof(me6));
me6.sin6_family = AF_INET6;
me6.sin6_addr = in6addr_any;
me6.sin6_port = htons(*listenport);
rc = bind(sock, (struct sockaddr *) &me6, sizeof(me6));
memset(&listener.sa6, 0, sizeof(listener.sa6));
listener.sa6.sin6_family = AF_INET6;
listener.sa6.sin6_addr = in6addr_any;
listener.sa6.sin6_port = htons(*listenport);
rc = bind(sock, &listener.sa, sizeof(listener.sa6));
}
#endif /* ENABLE_IPV6 */
if(rc) {
error = SOCKERRNO;
logmsg("Error binding socket: (%d) %s", error, strerror(error));
logmsg("Error binding socket on port %hu: (%d) %s",
*listenport, error, strerror(error));
sclose(sock);
return CURL_SOCKET_BAD;
}
if(!*listenport) {
/* The system picked a port number, now figure out which port we actually
got */
/* we succeeded to bind */
struct sockaddr_in add;
socklen_t socksize = sizeof(add);
if(getsockname(sock, (struct sockaddr *) &add,
&socksize)<0) {
/* The system was supposed to choose a port number, figure out which
port we actually got and update the listener port value with it. */
curl_socklen_t la_size;
srvr_sockaddr_union_t localaddr;
#ifdef ENABLE_IPV6
if(!use_ipv6)
#endif
la_size = sizeof(localaddr.sa4);
#ifdef ENABLE_IPV6
else
la_size = sizeof(localaddr.sa6);
#endif
memset(&localaddr.sa, 0, (size_t)la_size);
if(getsockname(sock, &localaddr.sa, &la_size) < 0) {
error = SOCKERRNO;
logmsg("getsockname() failed with error: (%d) %s",
error, strerror(error));
sclose(sock);
return CURL_SOCKET_BAD;
}
*listenport = ntohs(add.sin_port);
switch (localaddr.sa.sa_family) {
case AF_INET:
*listenport = ntohs(localaddr.sa4.sin_port);
break;
#ifdef ENABLE_IPV6
case AF_INET6:
*listenport = ntohs(localaddr.sa6.sin6_port);
break;
#endif
default:
break;
}
if(!*listenport) {
/* Real failure, listener port shall not be zero beyond this point. */
logmsg("Apparently getsockname() succeeded, with listener port zero.");
logmsg("A valid reason for this failure is a binary built without");
logmsg("proper network library linkage. This might not be the only");
logmsg("reason, but double check it before anything else.");
sclose(sock);
return CURL_SOCKET_BAD;
}
}
/* bindonly option forces no listening */
if(bind_only) {
logmsg("instructed to bind port without listening");
return sock;
}
/* start accepting connections */
rc = listen(sock, 5);
if(0 != rc) {
error = SOCKERRNO;
logmsg("listen() failed with error: (%d) %s",
error, strerror(error));
logmsg("listen(%d, 5) failed with error: (%d) %s",
sock, error, strerror(error));
sclose(sock);
return CURL_SOCKET_BAD;
}
@@ -767,14 +1079,12 @@ static curl_socket_t sockdaemon(curl_socket_t sock,
int main(int argc, char *argv[])
{
struct sockaddr_in me;
#ifdef ENABLE_IPV6
struct sockaddr_in6 me6;
#endif /* ENABLE_IPV6 */
srvr_sockaddr_union_t me;
curl_socket_t sock = CURL_SOCKET_BAD;
curl_socket_t msgsock = CURL_SOCKET_BAD;
int wrotepidfile = 0;
char *pidname= (char *)".sockfilt.pid";
bool juggle_again;
int rc;
int error;
int arg=1;
@@ -821,10 +1131,22 @@ int main(int argc, char *argv[])
#endif
arg++;
}
else if(!strcmp("--bindonly", argv[arg])) {
bind_only = TRUE;
arg++;
}
else if(!strcmp("--port", argv[arg])) {
arg++;
if(argc>arg) {
port = (unsigned short)atoi(argv[arg]);
char *endptr;
unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
if((endptr != argv[arg] + strlen(argv[arg])) ||
((ulnum != 0UL) && ((ulnum < 1025UL) || (ulnum > 65535UL)))) {
fprintf(stderr, "sockfilt: invalid --port argument (%s)\n",
argv[arg]);
return 0;
}
port = curlx_ultous(ulnum);
arg++;
}
}
@@ -833,7 +1155,15 @@ int main(int argc, char *argv[])
doing a passive server-style listening. */
arg++;
if(argc>arg) {
connectport = (unsigned short)atoi(argv[arg]);
char *endptr;
unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
if((endptr != argv[arg] + strlen(argv[arg])) ||
(ulnum < 1025UL) || (ulnum > 65535UL)) {
fprintf(stderr, "sockfilt: invalid --connect argument (%s)\n",
argv[arg]);
return 0;
}
connectport = curlx_ultous(ulnum);
arg++;
}
}
@@ -853,6 +1183,7 @@ int main(int argc, char *argv[])
" --pidfile [file]\n"
" --ipv4\n"
" --ipv6\n"
" --bindonly\n"
" --port [port]\n"
" --connect [port]\n"
" --addr [address]");
@@ -863,6 +1194,10 @@ int main(int argc, char *argv[])
#ifdef WIN32
win32_init();
atexit(win32_cleanup);
setmode(fileno(stdin), O_BINARY);
setmode(fileno(stdout), O_BINARY);
setmode(fileno(stderr), O_BINARY);
#endif
install_signal_handlers();
@@ -880,6 +1215,7 @@ int main(int argc, char *argv[])
error = SOCKERRNO;
logmsg("Error creating socket: (%d) %s",
error, strerror(error));
write_stdout("FAIL\n", 5);
goto sockfilt_cleanup;
}
@@ -889,32 +1225,33 @@ int main(int argc, char *argv[])
#ifdef ENABLE_IPV6
if(!use_ipv6) {
#endif
memset(&me, 0, sizeof(me));
me.sin_family = AF_INET;
me.sin_port = htons(connectport);
me.sin_addr.s_addr = INADDR_ANY;
memset(&me.sa4, 0, sizeof(me.sa4));
me.sa4.sin_family = AF_INET;
me.sa4.sin_port = htons(connectport);
me.sa4.sin_addr.s_addr = INADDR_ANY;
if (!addr)
addr = "127.0.0.1";
Curl_inet_pton(AF_INET, addr, &me.sin_addr);
Curl_inet_pton(AF_INET, addr, &me.sa4.sin_addr);
rc = connect(sock, (struct sockaddr *) &me, sizeof(me));
rc = connect(sock, &me.sa, sizeof(me.sa4));
#ifdef ENABLE_IPV6
}
else {
memset(&me6, 0, sizeof(me6));
me6.sin6_family = AF_INET6;
me6.sin6_port = htons(connectport);
memset(&me.sa6, 0, sizeof(me.sa6));
me.sa6.sin6_family = AF_INET6;
me.sa6.sin6_port = htons(connectport);
if (!addr)
addr = "::1";
Curl_inet_pton(AF_INET6, addr, &me6.sin6_addr);
Curl_inet_pton(AF_INET6, addr, &me.sa6.sin6_addr);
rc = connect(sock, (struct sockaddr *) &me6, sizeof(me6));
rc = connect(sock, &me.sa, sizeof(me.sa6));
}
#endif /* ENABLE_IPV6 */
if(rc) {
error = SOCKERRNO;
logmsg("Error connecting to port %hu: (%d) %s",
connectport, error, strerror(error));
write_stdout("FAIL\n", 5);
goto sockfilt_cleanup;
}
logmsg("====> Client connect");
@@ -923,8 +1260,10 @@ int main(int argc, char *argv[])
else {
/* passive daemon style */
sock = sockdaemon(sock, &port);
if(CURL_SOCKET_BAD == sock)
if(CURL_SOCKET_BAD == sock) {
write_stdout("FAIL\n", 5);
goto sockfilt_cleanup;
}
msgsock = CURL_SOCKET_BAD; /* no stream socket yet */
}
@@ -932,14 +1271,20 @@ int main(int argc, char *argv[])
if(connectport)
logmsg("Connected to port %hu", connectport);
else if(bind_only)
logmsg("Bound without listening on port %hu", port);
else
logmsg("Listening on port %hu", port);
wrotepidfile = write_pidfile(pidname);
if(!wrotepidfile)
if(!wrotepidfile) {
write_stdout("FAIL\n", 5);
goto sockfilt_cleanup;
}
while(juggle(&msgsock, sock, &mode));
do {
juggle_again = juggle(&msgsock, sock, &mode);
} while(juggle_again);
sockfilt_cleanup:
File diff suppressed because it is too large Load Diff
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,10 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: testpart.c,v 1.2 2008-02-28 00:55:06 yangtse Exp $
***************************************************************************/
#include "setup.h"
#include "server_setup.h"
#include "getpart.h"
@@ -33,15 +31,20 @@
int main(int argc, char **argv)
{
int rc;
char *part;
size_t partlen, i;
if(argc< 3) {
printf("./testpart main sub\n");
}
else {
size_t size;
unsigned int i;
const char *buffer = spitout(stdin, argv[1], argv[2], &size);
for(i=0; i< size; i++)
printf("%c", buffer[i]);
rc = getpart(&part, &partlen, argv[1], argv[2], stdin);
if(rc)
return(rc);
for(i = 0; i < partlen; i++)
printf("%c", part[i]);
free(part);
}
return 0;
}
+11 -8
View File
@@ -1,5 +1,5 @@
#ifndef __SERVER_TFTP_H
#define __SERVER_TFTP_H
#ifndef HEADER_CURL_SERVER_TFTP_H
#define HEADER_CURL_SERVER_TFTP_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,16 +20,19 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: tftp.h,v 1.5 2008-10-23 14:34:08 yangtse Exp $
***************************************************************************/
#include "server_setup.h"
/* This file is a rewrite/clone of the arpa/tftp.h file for systems without
it. */
#define SEGSIZE 512 /* data segment size */
#ifndef __GNUC__
#define __attribute__(x)
#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
# define PACKED_STRUCT __attribute__((__packed__))
#else
# define PACKED_STRUCT /*NOTHING*/
#endif
/* Using a packed struct as binary in a program is begging for problems, but
@@ -40,7 +43,7 @@ struct tftphdr {
short th_opcode; /* packet type */
unsigned short th_block; /* all sorts of things */
char th_data[1]; /* data or error string */
} __attribute__ ((__packed__));
} PACKED_STRUCT;
#define th_stuff th_block
#define th_code th_block
@@ -55,4 +58,4 @@ struct tftphdr {
#define EEXISTS 6
#define ENOUSER 7
#endif /* __SERVER_TFTP_H */
#endif /* HEADER_CURL_SERVER_TFTP_H */
File diff suppressed because it is too large Load Diff
+60 -21
View File
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <[email protected]>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,19 +18,12 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: util.c,v 1.27 2008-10-01 17:34:25 danf Exp $
***************************************************************************/
#include "setup.h" /* portability help from the lib directory */
#include "server_setup.h"
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
@@ -55,10 +48,44 @@
#include "util.h"
#include "timeval.h"
#ifdef USE_WINSOCK
#undef EINTR
#define EINTR 4 /* errno.h value */
#undef EINVAL
#define EINVAL 22 /* errno.h value */
#endif
#if defined(ENABLE_IPV6) && defined(__MINGW32__)
const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
#endif
/* This function returns a pointer to STATIC memory. It converts the given
* binary lump to a hex formatted string usable for output in logs or
* whatever.
*/
char *data_to_hex(char *data, size_t len)
{
static char buf[256*3];
size_t i;
char *optr = buf;
char *iptr = data;
if(len > 255)
len = 255;
for(i=0; i < len; i++) {
if((data[i] >= 0x20) && (data[i] < 0x7f))
*optr++ = *iptr++;
else {
sprintf(optr, "%%%02x", *iptr++);
optr+=3;
}
}
*optr=0; /* in case no sprintf() was used */
return buf;
}
void logmsg(const char *msg, ...)
{
va_list ap;
@@ -69,6 +96,8 @@ void logmsg(const char *msg, ...)
time_t sec;
struct tm *now;
char timebuf[20];
static time_t epoch_offset;
static int known_offset;
if (!serverlogfile) {
fprintf(stderr, "Error: serverlogfile not set\n");
@@ -76,8 +105,12 @@ void logmsg(const char *msg, ...)
}
tv = curlx_tvnow();
sec = tv.tv_sec;
now = localtime(&sec); /* not multithread safe but we don't care */
if(!known_offset) {
epoch_offset = time(NULL) - tv.tv_sec;
known_offset = 1;
}
sec = epoch_offset + tv.tv_sec;
now = localtime(&sec); /* not thread safe but we don't care */
snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
(int)now->tm_hour, (int)now->tm_min, (int)now->tm_sec, (long)tv.tv_usec);
@@ -86,13 +119,13 @@ void logmsg(const char *msg, ...)
vsnprintf(buffer, sizeof(buffer), msg, ap);
va_end(ap);
logfp = fopen(serverlogfile, "a");
logfp = fopen(serverlogfile, "ab");
if(logfp) {
fprintf(logfp, "%s %s\n", timebuf, buffer);
fclose(logfp);
}
else {
error = ERRNO;
error = errno;
fprintf(stderr, "fopen() failed with error: %d %s\n",
error, strerror(error));
fprintf(stderr, "Error opening file: %s\n", serverlogfile);
@@ -182,7 +215,7 @@ int wait_ms(int timeout_ms)
if(!timeout_ms)
return 0;
if(timeout_ms < 0) {
SET_SOCKERRNO(EINVAL);
errno = EINVAL;
return -1;
}
#if defined(MSDOS)
@@ -202,8 +235,8 @@ int wait_ms(int timeout_ms)
#endif /* HAVE_POLL_FINE */
if(r != -1)
break;
error = SOCKERRNO;
if(error == EINVAL)
error = errno;
if(error && (error != EINTR))
break;
pending_ms = timeout_ms - (int)curlx_tvdiff(curlx_tvnow(), initial_tv);
if(pending_ms <= 0)
@@ -221,9 +254,9 @@ int write_pidfile(const char *filename)
long pid;
pid = (long)getpid();
pidfile = fopen(filename, "w");
pidfile = fopen(filename, "wb");
if(!pidfile) {
logmsg("Couldn't write pid file: %s %s", filename, strerror(ERRNO));
logmsg("Couldn't write pid file: %s %s", filename, strerror(errno));
return 0; /* fail */
}
fprintf(pidfile, "%ld\n", pid);
@@ -240,7 +273,7 @@ void set_advisor_read_lock(const char *filename)
do {
lockfile = fopen(filename, "wb");
} while((lockfile == NULL) && ((error = ERRNO) == EINTR));
} while((lockfile == NULL) && ((error = errno) == EINTR));
if(lockfile == NULL) {
logmsg("Error creating lock file %s error: %d %s",
filename, error, strerror(error));
@@ -249,7 +282,7 @@ void set_advisor_read_lock(const char *filename)
do {
res = fclose(lockfile);
} while(res && ((error = ERRNO) == EINTR));
} while(res && ((error = errno) == EINTR));
if(res)
logmsg("Error closing lock file %s error: %d %s",
filename, error, strerror(error));
@@ -260,9 +293,15 @@ void clear_advisor_read_lock(const char *filename)
int error = 0;
int res;
/*
** Log all removal failures. Even those due to file not existing.
** This allows to detect if unexpectedly the file has already been
** removed by a process different than the one that should do this.
*/
do {
res = unlink(filename);
} while(res && ((error = ERRNO) == EINTR));
} while(res && ((error = errno) == EINTR));
if(res)
logmsg("Error removing lock file %s error: %d %s",
filename, error, strerror(error));
+6 -5
View File
@@ -1,5 +1,5 @@
#ifndef __SERVER_UTIL_H
#define __SERVER_UTIL_H
#ifndef HEADER_CURL_SERVER_UTIL_H
#define HEADER_CURL_SERVER_UTIL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,9 +20,10 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: util.h,v 1.20 2008-09-18 16:21:09 yangtse Exp $
***************************************************************************/
#include "server_setup.h"
char *data_to_hex(char *data, size_t len);
void logmsg(const char *msg, ...);
#define TEST_DATA_PATH "%s/data/test%ld"
@@ -62,4 +63,4 @@ void set_advisor_read_lock(const char *filename);
void clear_advisor_read_lock(const char *filename);
#endif /* __SERVER_UTIL_H */
#endif /* HEADER_CURL_SERVER_UTIL_H */