tImproved metaserver error reporting - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 0bc279db8ad5c1ec9856ea8135ee3959249ffb5a
(DIR) parent a09e6292bf62e8174a499e147c5d9f276ed2b466
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Fri, 12 Oct 2001 19:35:27 +0000
Improved metaserver error reporting
Diffstat:
M src/curses_client.c | 4 ++--
M src/error.c | 36 +++++++++++++++++++++----------
M src/error.h | 8 +++++---
M src/gtk_client.c | 11 +++++------
M src/message.c | 34 +++++++++++++++++++++++++------
M src/network.c | 121 ++++++++++++++-----------------
M src/network.h | 10 +++++-----
M src/serverside.c | 36 +++++++++++++++++++------------
8 files changed, 145 insertions(+), 115 deletions(-)
---
(DIR) diff --git a/src/curses_client.c b/src/curses_client.c
t@@ -237,7 +237,7 @@ static gboolean SelectServerFromMetaServer(Player *Play,GString *errstr) {
refresh();
if (!OpenMetaHttpConnection(&MetaConn)) {
- g_string_assign_error(errstr,&MetaConn->NetBuf.error);
+ g_string_assign_error(errstr,MetaConn->NetBuf.error);
CloseHttpConnection(MetaConn);
return FALSE;
}
t@@ -265,7 +265,7 @@ static gboolean SelectServerFromMetaServer(Player *Play,GString *errstr) {
}
if (!DoneOK && HandleHttpCompletion(MetaConn)) {
if (IsHttpError(MetaConn)) {
- g_string_assign_error(errstr,&MetaConn->NetBuf.error);
+ g_string_assign_error(errstr,MetaConn->NetBuf.error);
CloseHttpConnection(MetaConn);
return FALSE;
}
(DIR) diff --git a/src/error.c b/src/error.c
t@@ -35,17 +35,31 @@
#include "error.h"
#include "nls.h"
-void ClearError(LastError *error) {
- error->type=NULL;
+void FreeError(LastError *error) {
+ if (!error) return;
+ if (error->type && error->type->FreeErrorData) {
+ (*error->type->FreeErrorData)(error);
+ } else {
+ g_free(error->data);
+ }
+ g_free(error);
}
-gboolean IsError(LastError *error) {
- return (error->type!=NULL);
-}
+LastError *NewError(ErrorType *type,gint code,gpointer data) {
+ LastError *error;
-void SetError(LastError *error,ErrorType *type,gint code) {
+ error = g_new0(LastError,1);
error->type=type;
error->code=code;
+ error->data=data;
+
+ return error;
+}
+
+void SetError(LastError **error,ErrorType *type,gint code,gpointer data) {
+ if (!error) return;
+ if (*error) FreeError(*error);
+ *error = NewError(type,code,data);
}
void LookupErrorCode(GString *str,gint code,ErrTable *table,
t@@ -69,7 +83,7 @@ void CustomAppendError(GString *str,LastError *error) {
LookupErrorCode(str,error->code,CustomErrStr,_("Internal error code %d"));
}
-static ErrorType ETCustom = { CustomAppendError };
+static ErrorType ETCustom = { CustomAppendError,NULL };
ErrorType *ET_CUSTOM = &ETCustom;
/* "errno" error handling */
t@@ -77,7 +91,7 @@ void ErrnoAppendError(GString *str,LastError *error) {
g_string_append(str,strerror(error->code));
}
-static ErrorType ETErrno = { ErrnoAppendError };
+static ErrorType ETErrno = { ErrnoAppendError,NULL };
ErrorType *ET_ERRNO = &ETErrno;
#ifdef CYGWIN
t@@ -110,7 +124,7 @@ void WinsockAppendError(GString *str,LastError *error) {
LookupErrorCode(str,error->code,WSAErrStr,_("Network error code %d"));
}
-static ErrorType ETWinsock = { WinsockAppendError };
+static ErrorType ETWinsock = { WinsockAppendError,NULL };
ErrorType *ET_WINSOCK = &ETWinsock;
/* Standard Win32 "GetLastError" handling */
t@@ -124,7 +138,7 @@ void Win32AppendError(GString *str,LastError *error) {
LocalFree(lpMsgBuf);
}
-static ErrorType ETWin32 = { Win32AppendError };
+static ErrorType ETWin32 = { Win32AppendError,NULL };
ErrorType *ET_WIN32 = &ETWin32;
#else
t@@ -141,7 +155,7 @@ void HErrnoAppendError(GString *str,LastError *error) {
LookupErrorCode(str,error->code,DNSErrStr,_("Name server error code %d"));
}
-static ErrorType ETHErrno = { HErrnoAppendError };
+static ErrorType ETHErrno = { HErrnoAppendError,NULL };
ErrorType *ET_HERRNO = ÐErrno;
#endif /* CYGWIN */
(DIR) diff --git a/src/error.h b/src/error.h
t@@ -31,11 +31,13 @@
struct _LastError;
typedef struct _ErrorType {
void (*AppendErrorString)(GString *str,struct _LastError *error);
+ void (*FreeErrorData)(struct _LastError *error);
} ErrorType;
typedef struct _LastError {
gint code;
ErrorType *type;
+ gpointer data;
} LastError;
extern ErrorType *ET_CUSTOM,*ET_ERRNO;
t@@ -54,9 +56,9 @@ typedef struct _ErrTable {
gchar *string;
} ErrTable;
-void ClearError(LastError *error);
-gboolean IsError(LastError *error);
-void SetError(LastError *error,ErrorType *type,gint code);
+void FreeError(LastError *error);
+LastError *NewError(ErrorType *type,gint code,gpointer data);
+void SetError(LastError **error,ErrorType *type,gint code,gpointer data);
void LookupErrorCode(GString *str,gint code,ErrTable *table,
gchar *fallbackstr);
void g_string_assign_error(GString *str,LastError *error);
(DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c
t@@ -1945,10 +1945,10 @@ static void ConnectError(struct StartGameStruct *widgets,gboolean meta) {
gchar *text;
LastError *error;
- if (meta) error=&widgets->MetaConn->NetBuf.error;
- else error=&ClientData.Play->NetBuf.error;
+ if (meta) error=widgets->MetaConn->NetBuf.error;
+ else error=ClientData.Play->NetBuf.error;
- if (!IsError(error)) return;
+ if (!error) return;
neterr = g_string_new("");
g_string_assign_error(neterr,error);
t@@ -2108,9 +2108,9 @@ static void HandleMetaSock(gpointer data,gint socket,
NBStatus oldstatus;
NBSocksStatus oldsocks;
-g_print("HandleMetaSock: read %d, write %d\n",
+/*g_print("HandleMetaSock: read %d, write %d\n",
condition&GDK_INPUT_READ,
- condition&GDK_INPUT_WRITE);
+ condition&GDK_INPUT_WRITE);*/
widgets=(struct StartGameStruct *)data;
if (!widgets->MetaConn) return;
t@@ -3201,7 +3201,6 @@ static void DestroyAuthDialog(GtkWidget *window,gpointer data) {
oldsocks = widgets->MetaConn->NetBuf.sockstat;
if (!SetHttpAuthentication(conn,GPOINTER_TO_INT(proxy),username,password)) {
- g_print("FIXME: Connect error on setauth\n");
MetaDone(widgets);
} else {
DisplayConnectStatus(widgets,TRUE,oldstatus,oldsocks);
(DIR) diff --git a/src/message.c b/src/message.c
t@@ -303,6 +303,29 @@ gboolean WritePlayerDataToWire(Player *Play) {
return WriteDataToWire(&Play->NetBuf);
}
+typedef enum {
+ MEC_INTERNAL,
+ MEC_BADREPLY
+} MetaErrorCode;
+
+static void MetaAppendError(GString *str,LastError *error) {
+ switch (error->code) {
+ case MEC_INTERNAL:
+ g_string_sprintfa(str,_("Internal metaserver error \"%s\""),
+ (gchar *)error->data);
+ break;
+ case MEC_BADREPLY:
+ g_string_sprintfa(str,_("Bad metaserver reply \"%s\""),
+ (gchar *)error->data);
+ break;
+ default:
+ g_string_sprintfa(str,_("Unknown metaserver error code %d"),error->code);
+ break;
+ }
+}
+
+static ErrorType ETMeta = { MetaAppendError, NULL };
+
gboolean OpenMetaHttpConnection(HttpConnection **conn) {
gchar *query;
gboolean retval;
t@@ -330,7 +353,6 @@ gboolean HandleWaitingMetaServerData(HttpConnection *conn,GSList **listpt,
NewServer=g_new0(ServerData,1);
NewServer->Name=ReadHttpResponse(conn);
- g_print("Server name %s read from metaserver\n",NewServer->Name);
msg=ReadHttpResponse(conn);
NewServer->Port=atoi(msg); g_free(msg);
NewServer->Version=ReadHttpResponse(conn);
t@@ -349,12 +371,11 @@ gboolean HandleWaitingMetaServerData(HttpConnection *conn,GSList **listpt,
msg=ReadHttpResponse(conn);
if (!msg) return FALSE;
if (strlen(msg)>=14 && strncmp(msg,"FATAL ERROR:",12)==0) {
- g_warning("Metaserver error: %s",&msg[13]);
- g_free(msg);
+ SetError(&conn->NetBuf.error,&ETMeta,MEC_INTERNAL,g_strdup(&msg[13]));
*doneOK=FALSE;
return FALSE;
} else if (strncmp(msg,"MetaServer:",11)!=0) {
- g_warning("Bad reply from metaserver: %s",msg);
+ SetError(&conn->NetBuf.error,&ETMeta,MEC_BADREPLY,g_strdup(msg));
g_free(msg);
*doneOK=FALSE;
return FALSE;
t@@ -700,14 +721,15 @@ gboolean SetupNetwork(GString *errstr) {
/* file descriptor for the newly-opened socket. TRUE is returned. If the */
/* connection fails, FALSE is returned, and errstr (if non-NULL) is filled */
/* with a descriptive error message. */
- LastError err;
+ LastError *err;
Network=Client=Server=FALSE;
if (StartConnect(&ClientSock,ServerName,Port,FALSE,&err)) {
Client=Network=TRUE;
return TRUE;
} else {
- if (errstr) g_string_assign_error(errstr,&err);
+ if (errstr) g_string_assign_error(errstr,err);
+ FreeError(err);
return FALSE;
}
}
(DIR) diff --git a/src/network.c b/src/network.c
t@@ -115,18 +115,10 @@ void SetBlocking(int sock,gboolean blocking) {
#endif /* CYGWIN */
-static gboolean FinishConnect(int fd,LastError *error);
+static gboolean FinishConnect(int fd,LastError **error);
static void NetBufCallBack(NetworkBuffer *NetBuf) {
if (NetBuf && NetBuf->CallBack) {
-g_print("status = %d, read = %d, write = %d\n",
-NetBuf->status,
-NetBuf->status!=NBS_PRECONNECT,
- (NetBuf->status==NBS_CONNECTED &&
- NetBuf->WriteBuf.DataPresent) ||
- (NetBuf->status==NBS_SOCKSCONNECT &&
- NetBuf->negbuf.DataPresent) ||
- NetBuf->WaitConnect);
(*NetBuf->CallBack)(NetBuf,NetBuf->status!=NBS_PRECONNECT,
(NetBuf->status==NBS_CONNECTED &&
NetBuf->WriteBuf.DataPresent) ||
t@@ -173,7 +165,7 @@ void InitNetworkBuffer(NetworkBuffer *NetBuf,char Terminator,char StripChar,
NetBuf->socks = socks;
NetBuf->host = NULL;
NetBuf->userpasswd = NULL;
- ClearError(&NetBuf->error);
+ NetBuf->error = NULL;
}
void SetNetworkBufferCallBack(NetworkBuffer *NetBuf,NBCallBack CallBack,
t@@ -253,6 +245,8 @@ void ShutdownNetworkBuffer(NetworkBuffer *NetBuf) {
FreeConnBuf(&NetBuf->WriteBuf);
FreeConnBuf(&NetBuf->negbuf);
+ FreeError(NetBuf->error); NetBuf->error=NULL;
+
g_free(NetBuf->host);
InitNetworkBuffer(NetBuf,NetBuf->Terminator,NetBuf->StripChar,NetBuf->socks);
t@@ -329,7 +323,7 @@ static void SocksAppendError(GString *str,LastError *error) {
LookupErrorCode(str,error->code,SocksErrStr,_("SOCKS error code %d"));
}
-static ErrorType ETSocks = { SocksAppendError };
+static ErrorType ETSocks = { SocksAppendError,NULL };
typedef enum {
HEC_TRIESEX = 1,
t@@ -379,11 +373,11 @@ static void HTTPAppendError(GString *str,LastError *error) {
}
}
-static ErrorType ETHTTP = { HTTPAppendError };
+static ErrorType ETHTTP = { HTTPAppendError,NULL };
static gboolean Socks5UserPasswd(NetworkBuffer *NetBuf) {
if (!NetBuf->userpasswd) {
- SetError(&NetBuf->error,&ETSocks,SEC_NOMETHODS);
+ SetError(&NetBuf->error,&ETSocks,SEC_NOMETHODS,NULL);
return FALSE;
} else {
/* Request a username and password (the callback function should in turn
t@@ -401,14 +395,14 @@ gboolean SendSocks5UserPasswd(NetworkBuffer *NetBuf,gchar *user,
ConnBuf *conn;
if (!user || !password) {
- SetError(&NetBuf->error,&ETSocks,SEC_USERCANCEL);
+ SetError(&NetBuf->error,&ETSocks,SEC_USERCANCEL,NULL);
return FALSE;
}
conn=&NetBuf->negbuf;
addlen = 3 + strlen(user) + strlen(password);
addpt = ExpandWriteBuffer(conn,addlen);
if (!addpt || strlen(user)>255 || strlen(password)>255) {
- SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF);
+ SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL);
return FALSE;
}
addpt[0] = 1; /* Subnegotiation version code */
t@@ -444,7 +438,7 @@ static gboolean Socks5Connect(NetworkBuffer *NetBuf) {
addlen = hostlen + 7;
addpt = ExpandWriteBuffer(conn,addlen);
if (!addpt) {
- SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF);
+ SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL);
return FALSE;
}
addpt[0] = 5; /* SOCKS version 5 */
t@@ -480,9 +474,9 @@ g_print("Handling SOCKS5 reply\n");
retval=FALSE;
g_print("FIXME: Reply from SOCKS5 server: %d %d\n",data[0],data[1]);
if (data[0]!=5) {
- SetError(&NetBuf->error,&ETSocks,SEC_VERSION);
+ SetError(&NetBuf->error,&ETSocks,SEC_VERSION,NULL);
} else if (data[1]!=0 && data[1]!=2) {
- SetError(&NetBuf->error,&ETSocks,SEC_NOMETHODS);
+ SetError(&NetBuf->error,&ETSocks,SEC_NOMETHODS,NULL);
} else {
g_print("FIXME: Using SOCKS5 method %d\n",data[1]);
if (data[1]==SM_NOAUTH) {
t@@ -498,9 +492,9 @@ g_print("Handling SOCKS5 reply\n");
if (data) {
retval=FALSE;
if (data[0]!=5) {
- SetError(&NetBuf->error,&ETSocks,SEC_VERSION);
+ SetError(&NetBuf->error,&ETSocks,SEC_VERSION,NULL);
} else if (data[1]!=0) {
- SetError(&NetBuf->error,&ETSocks,SEC_AUTHFAILED);
+ SetError(&NetBuf->error,&ETSocks,SEC_AUTHFAILED,NULL);
} else {
retval=Socks5Connect(NetBuf);
}
t@@ -513,13 +507,13 @@ g_print("FIXME: SOCKS5 connect reply\n");
retval=FALSE;
addrtype = data[3];
if (data[0]!=5) {
- SetError(&NetBuf->error,&ETSocks,SEC_VERSION);
+ SetError(&NetBuf->error,&ETSocks,SEC_VERSION,NULL);
} else if (data[1]>8) {
- SetError(&NetBuf->error,&ETSocks,SEC_UNKNOWN);
+ SetError(&NetBuf->error,&ETSocks,SEC_UNKNOWN,NULL);
} else if (data[1]!=0) {
- SetError(&NetBuf->error,&ETSocks,data[1]);
+ SetError(&NetBuf->error,&ETSocks,data[1],NULL);
} else if (addrtype!=1 && addrtype!=3 && addrtype!=4) {
- SetError(&NetBuf->error,&ETSocks,SEC_ADDRTYPE);
+ SetError(&NetBuf->error,&ETSocks,SEC_ADDRTYPE,NULL);
} else {
retval=TRUE;
replylen = 6;
t@@ -545,16 +539,16 @@ g_print("FIXME: SOCKS5 connect reply\n");
if (data) {
retval=FALSE;
if (data[0]!=0) {
- SetError(&NetBuf->error,&ETSocks,SEC_REPLYVERSION);
+ SetError(&NetBuf->error,&ETSocks,SEC_REPLYVERSION,NULL);
} else {
if (data[1]==90) {
NetBuf->status = NBS_CONNECTED;
NetBufCallBack(NetBuf); /* status has changed */
retval=TRUE;
} else if (data[1]>=SEC_REJECT && data[1]<=SEC_IDMISMATCH) {
- SetError(&NetBuf->error,&ETSocks,data[1]);
+ SetError(&NetBuf->error,&ETSocks,data[1],NULL);
} else {
- SetError(&NetBuf->error,&ETSocks,SEC_UNKNOWN);
+ SetError(&NetBuf->error,&ETSocks,SEC_UNKNOWN,NULL);
}
}
g_free(data);
t@@ -743,7 +737,7 @@ gboolean ReadDataFromWire(NetworkBuffer *NetBuf) {
while(1) {
if (CurrentPosition>=conn->Length) {
if (conn->Length==MAXREADBUF) {
- SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF);
+ SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL);
return FALSE; /* drop connection */
}
if (conn->Length==0) conn->Length=256; else conn->Length*=2;
t@@ -756,11 +750,11 @@ gboolean ReadDataFromWire(NetworkBuffer *NetBuf) {
#ifdef CYGWIN
int Error = WSAGetLastError();
if (Error==WSAEWOULDBLOCK) break;
- else { SetError(&NetBuf->error,ET_WINSOCK,Error); return FALSE; }
+ else { SetError(&NetBuf->error,ET_WINSOCK,Error,NULL); return FALSE; }
#else
if (errno==EAGAIN) break;
else if (errno!=EINTR) {
- SetError(&NetBuf->error,ET_ERRNO,errno);
+ SetError(&NetBuf->error,ET_ERRNO,errno,NULL);
return FALSE;
}
#endif
t@@ -768,7 +762,6 @@ gboolean ReadDataFromWire(NetworkBuffer *NetBuf) {
return FALSE;
} else {
CurrentPosition+=BytesRead;
-g_print("%d bytes read from wire\n",BytesRead);
conn->DataPresent=CurrentPosition;
}
}
t@@ -814,13 +807,13 @@ void QueueMessageForSend(NetworkBuffer *NetBuf,gchar *data) {
if (addpt==conn->Data) NetBufCallBack(NetBuf);
}
-static struct hostent *LookupHostname(gchar *host,LastError *error) {
+static struct hostent *LookupHostname(gchar *host,LastError **error) {
struct hostent *he;
if ((he=gethostbyname(host))==NULL) {
#ifdef CYGWIN
- if (error) SetError(error,ET_WINSOCK,WSAGetLastError());
+ if (error) SetError(error,ET_WINSOCK,WSAGetLastError(),NULL);
#else
- if (error) SetError(error,ET_HERRNO,h_errno);
+ if (error) SetError(error,ET_HERRNO,h_errno,NULL);
#endif
}
return he;
t@@ -850,7 +843,7 @@ gboolean StartSocksNegotiation(NetworkBuffer *NetBuf,gchar *RemoteHost,
addlen=2+num_methods;
addpt = ExpandWriteBuffer(conn,addlen);
if (!addpt) {
- SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF);
+ SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL);
return FALSE;
}
addpt[0] = 5; /* SOCKS version 5 */
t@@ -881,12 +874,12 @@ gboolean StartSocksNegotiation(NetworkBuffer *NetBuf,gchar *RemoteHost,
bufsize=0;
WNetGetUser(NULL,username,&bufsize);
if (GetLastError()!=ERROR_MORE_DATA) {
- SetError(&NetBuf->error,ET_WIN32,GetLastError());
+ SetError(&NetBuf->error,ET_WIN32,GetLastError(),NULL);
return FALSE;
} else {
username=g_malloc(bufsize);
if (WNetGetUser(NULL,username,&bufsize)!=NO_ERROR) {
- SetError(&NetBuf->error,ET_WIN32,GetLastError());
+ SetError(&NetBuf->error,ET_WIN32,GetLastError(),NULL);
return FALSE;
}
}
t@@ -907,7 +900,7 @@ g_print("username %s\n",pwd->pw_name);
addpt = ExpandWriteBuffer(conn,addlen);
if (!addpt) {
- SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF);
+ SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL);
return FALSE;
}
t@@ -936,7 +929,7 @@ static gboolean WriteBufToWire(NetworkBuffer *NetBuf,ConnBuf *conn) {
int CurrentPosition,BytesSent;
if (!conn->Data || !conn->DataPresent) return TRUE;
if (conn->Length==MAXWRITEBUF) {
- SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF);
+ SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL);
return FALSE;
}
CurrentPosition=0;
t@@ -947,16 +940,15 @@ static gboolean WriteBufToWire(NetworkBuffer *NetBuf,ConnBuf *conn) {
#ifdef CYGWIN
int Error=WSAGetLastError();
if (Error==WSAEWOULDBLOCK) break;
- else { SetError(&NetBuf->error,ET_WINSOCK,Error); return FALSE; }
+ else { SetError(&NetBuf->error,ET_WINSOCK,Error,NULL); return FALSE; }
#else
if (errno==EAGAIN) break;
else if (errno!=EINTR) {
- SetError(&NetBuf->error,ET_ERRNO,errno);
+ SetError(&NetBuf->error,ET_ERRNO,errno,NULL);
return FALSE;
}
#endif
} else {
-g_print("%d bytes written to wire\n",BytesSent);
CurrentPosition+=BytesSent;
}
}
t@@ -973,10 +965,8 @@ gboolean WriteDataToWire(NetworkBuffer *NetBuf) {
/* TRUE on success, or FALSE if the buffer's maximum length is */
/* reached, or the remote end has closed the connection. */
if (NetBuf->status==NBS_SOCKSCONNECT) {
-g_print("Writing negbuf\n");
return WriteBufToWire(NetBuf,&NetBuf->negbuf);
} else {
-g_print("Writing WriteBuf\n");
return WriteBufToWire(NetBuf,&NetBuf->WriteBuf);
}
}
t@@ -1084,10 +1074,6 @@ void CloseHttpConnection(HttpConnection *conn) {
g_free(conn);
}
-gboolean IsHttpError(HttpConnection *conn) {
- return IsError(&conn->NetBuf.error);
-}
-
gboolean SetHttpAuthentication(HttpConnection *conn,gboolean proxy,
gchar *user,gchar *password) {
gchar **ptuser,**ptpassword;
t@@ -1190,13 +1176,11 @@ static void ParseHtmlHeader(gchar *line,HttpConnection *conn) {
}
} else if (g_strcasecmp(split[0],"WWW-Authenticate:")==0 &&
conn->StatusCode==HEC_AUTHREQ) {
- g_print("FIXME: Authentication %s required\n",split[1]);
StartHttpAuth(conn,FALSE,split[1]);
/* Proxy-Authenticate is, strictly speaking, an HTTP/1.1 thing, but some
HTTP/1.0 proxies seem to support it anyway */
} else if (g_strcasecmp(split[0],"Proxy-Authenticate:")==0 &&
conn->StatusCode==HEC_PROXYAUTH) {
- g_print("FIXME: Proxy authentication %s required\n",split[1]);
StartHttpAuth(conn,TRUE,split[1]);
}
}
t@@ -1237,7 +1221,7 @@ gboolean HandleHttpCompletion(HttpConnection *conn) {
gpointer CallBackData;
NBUserPasswd userpasswd;
gboolean retry=FALSE;
- LastError *error;
+ LastError **error;
error=&conn->NetBuf.error;
t@@ -1249,12 +1233,11 @@ gboolean HandleHttpCompletion(HttpConnection *conn) {
}
if (conn->Tries>=5) {
- SetError(error,ÐTTP,HEC_TRIESEX);
+ SetError(error,ÐTTP,HEC_TRIESEX,NULL);
return TRUE;
}
if (conn->RedirHost) {
- g_print("Following redirect to %s\n",conn->RedirHost);
g_free(conn->HostName); g_free(conn->Query);
conn->HostName = conn->RedirHost;
conn->Query = conn->RedirQuery;
t@@ -1263,12 +1246,10 @@ gboolean HandleHttpCompletion(HttpConnection *conn) {
retry = TRUE;
}
if (conn->StatusCode==HEC_AUTHREQ && conn->user && conn->password) {
- g_print("Trying again with authentication\n");
retry = TRUE;
}
if (conn->StatusCode==HEC_PROXYAUTH && conn->proxyuser &&
conn->proxypassword) {
- g_print("Trying again with proxy authentication\n");
retry = TRUE;
}
t@@ -1284,28 +1265,32 @@ gboolean HandleHttpCompletion(HttpConnection *conn) {
return FALSE;
}
} else if (conn->StatusCode>=300) {
- SetError(error,ÐTTP,conn->StatusCode);
+ SetError(error,ÐTTP,conn->StatusCode,NULL);
}
return TRUE;
}
-int CreateTCPSocket(LastError *error) {
+gboolean IsHttpError(HttpConnection *conn) {
+ return (conn->NetBuf.error!=NULL);
+}
+
+int CreateTCPSocket(LastError **error) {
int fd;
fd=socket(AF_INET,SOCK_STREAM,0);
if (fd==SOCKET_ERROR && error) {
#ifdef CYGWIN
- SetError(error,ET_WINSOCK,WSAGetLastError());
+ SetError(error,ET_WINSOCK,WSAGetLastError(),NULL);
#else
- SetError(error,ET_ERRNO,errno);
+ SetError(error,ET_ERRNO,errno,NULL);
#endif
}
return fd;
}
-gboolean BindTCPSocket(int sock,unsigned port,LastError *error) {
+gboolean BindTCPSocket(int sock,unsigned port,LastError **error) {
struct sockaddr_in bindaddr;
int retval;
t@@ -1318,9 +1303,9 @@ gboolean BindTCPSocket(int sock,unsigned port,LastError *error) {
if (retval==SOCKET_ERROR && error) {
#ifdef CYGWIN
- SetError(error,ET_WINSOCK,WSAGetLastError());
+ SetError(error,ET_WINSOCK,WSAGetLastError(),NULL);
#else
- SetError(error,ET_ERRNO,errno);
+ SetError(error,ET_ERRNO,errno,NULL);
#endif
}
t@@ -1328,7 +1313,7 @@ gboolean BindTCPSocket(int sock,unsigned port,LastError *error) {
}
gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort,
- gboolean NonBlocking,LastError *error) {
+ gboolean NonBlocking,LastError **error) {
struct sockaddr_in ClientAddr;
struct hostent *he;
t@@ -1350,10 +1335,10 @@ gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort,
#ifdef CYGWIN
int errcode=WSAGetLastError();
if (errcode==WSAEWOULDBLOCK) return TRUE;
- else if (error) SetError(error,ET_WINSOCK,errcode);
+ else if (error) SetError(error,ET_WINSOCK,errcode,NULL);
#else
if (errno==EINPROGRESS) return TRUE;
- else if (error) SetError(error,ET_ERRNO,errno);
+ else if (error) SetError(error,ET_ERRNO,errno,NULL);
#endif
CloseSocket(*fd); *fd=-1;
return FALSE;
t@@ -1363,13 +1348,13 @@ gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort,
return TRUE;
}
-gboolean FinishConnect(int fd,LastError *error) {
+gboolean FinishConnect(int fd,LastError **error) {
int errcode;
#ifdef CYGWIN
errcode = WSAGetLastError();
if (errcode==0) return TRUE;
else {
- if (error) { SetError(error,ET_WINSOCK,errcode); }
+ if (error) { SetError(error,ET_WINSOCK,errcode,NULL); }
return FALSE;
}
#else
t@@ -1385,7 +1370,7 @@ gboolean FinishConnect(int fd,LastError *error) {
}
if (errcode==0) return TRUE;
else {
- if (error) { SetError(error,ET_ERRNO,errcode); }
+ if (error) { SetError(error,ET_ERRNO,errcode,NULL); }
return FALSE;
}
#endif /* CYGWIN */
(DIR) diff --git a/src/network.h b/src/network.h
t@@ -108,7 +108,7 @@ struct _NetworkBuffer {
SOCKS5 authentication */
gchar *host; /* If non-NULL, the host to connect to */
unsigned port; /* If non-NULL, the port to connect to */
- LastError error; /* Any error from the last operation */
+ LastError *error; /* Any error from the last operation */
};
/* Keeps track of the progress of an HTTP connection */
t@@ -185,17 +185,17 @@ gboolean OpenHttpConnection(HttpConnection **conn,gchar *HostName,
gchar *Method,gchar *Query,
gchar *Headers,gchar *Body);
void CloseHttpConnection(HttpConnection *conn);
-gboolean IsHttpError(HttpConnection *conn);
gchar *ReadHttpResponse(HttpConnection *conn);
gboolean SetHttpAuthentication(HttpConnection *conn,gboolean proxy,
gchar *user,gchar *password);
void SetHttpAuthFunc(HttpConnection *conn,HCAuthFunc authfunc,gpointer data);
gboolean HandleHttpCompletion(HttpConnection *conn);
+gboolean IsHttpError(HttpConnection *conn);
-int CreateTCPSocket(LastError *error);
-gboolean BindTCPSocket(int sock,unsigned port,LastError *error);
+int CreateTCPSocket(LastError **error);
+gboolean BindTCPSocket(int sock,unsigned port,LastError **error);
gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort,
- gboolean NonBlocking,LastError *error);
+ gboolean NonBlocking,LastError **error);
void StartNetworking(void);
void StopNetworking(void);
(DIR) diff --git a/src/serverside.c b/src/serverside.c
t@@ -142,7 +142,7 @@ static gboolean MetaConnectError(HttpConnection *conn) {
GString *errstr;
if (!IsHttpError(conn)) return FALSE;
errstr=g_string_new("");
- g_string_assign_error(errstr,&MetaConn->NetBuf.error);
+ g_string_assign_error(errstr,MetaConn->NetBuf.error);
dopelog(1,_("Failed to connect to metaserver at %s:%u (%s)"),
MetaServer.Name,MetaServer.Port,errstr->str);
g_string_free(errstr,TRUE);
t@@ -648,7 +648,8 @@ gboolean ReadServerKey(GString *LineBuf,gboolean *EndOfLine) {
}
void StartServer() {
- struct sockaddr_in ServerAddr;
+ LastError *sockerr;
+ GString *errstr;
#ifndef CYGWIN
struct sigaction sact;
#endif
t@@ -670,22 +671,29 @@ void StartServer() {
Network=TRUE;
FirstServer=NULL;
ClientMessageHandlerPt=NULL;
- ListenSock=socket(AF_INET,SOCK_STREAM,0);
+ ListenSock=CreateTCPSocket(&sockerr);
if (ListenSock==SOCKET_ERROR) {
-/* FIXME
-MessageBox(NULL,"Cannot create socket",NULL,MB_OK); */
- perror("create socket"); exit(1);
+ errstr=g_string_new("");
+ g_string_assign_error(errstr,sockerr);
+ g_log(NULL,G_LOG_LEVEL_CRITICAL,
+ _("Cannot create server (listening) socket (%s) Aborting."),
+ errstr->str);
+ g_string_free(errstr,TRUE);
+ FreeError(sockerr);
+ exit(1);
}
SetReuse(ListenSock);
SetBlocking(ListenSock,FALSE);
-
- ServerAddr.sin_family=AF_INET;
- ServerAddr.sin_port=htons(Port);
- ServerAddr.sin_addr.s_addr=INADDR_ANY;
- memset(ServerAddr.sin_zero,0,sizeof(ServerAddr.sin_zero));
- if (bind(ListenSock,(struct sockaddr *)&ServerAddr,
- sizeof(struct sockaddr)) == SOCKET_ERROR) {
- perror("bind socket"); exit(1);
+
+ if (!BindTCPSocket(ListenSock,Port,&sockerr)) {
+ errstr=g_string_new("");
+ g_string_assign_error(errstr,sockerr);
+ g_log(NULL,G_LOG_LEVEL_CRITICAL,
+ _("Cannot listen on port %u (%s) Aborting."),
+ Port,errstr->str);
+ g_string_free(errstr,TRUE);
+ FreeError(sockerr);
+ exit(1);
}
/* Initial startup message for the server */