mirror of
https://github.com/openNDS/openNDS.git
synced 2026-05-04 03:01:32 -04:00
import of nodogsplash-0.9_beta6.tar.gz
This commit is contained in:
@@ -3370,7 +3370,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
NODOGSPLASH_MAJOR_VERSION=0
|
||||
NODOGSPLASH_MINOR_VERSION=9_beta4
|
||||
NODOGSPLASH_MINOR_VERSION=9_beta6
|
||||
NODOGSPLASH_VERSION=$NODOGSPLASH_MAJOR_VERSION.$NODOGSPLASH_MINOR_VERSION
|
||||
|
||||
|
||||
|
||||
2
configure
vendored
2
configure
vendored
@@ -3370,7 +3370,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
NODOGSPLASH_MAJOR_VERSION=0
|
||||
NODOGSPLASH_MINOR_VERSION=9_beta4
|
||||
NODOGSPLASH_MINOR_VERSION=9_beta6
|
||||
NODOGSPLASH_VERSION=$NODOGSPLASH_MAJOR_VERSION.$NODOGSPLASH_MINOR_VERSION
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ AC_PROG_CXX
|
||||
AC_SUBST(BUILDROOT)
|
||||
|
||||
NODOGSPLASH_MAJOR_VERSION=0
|
||||
NODOGSPLASH_MINOR_VERSION=9_beta4
|
||||
NODOGSPLASH_MINOR_VERSION=9_beta6
|
||||
NODOGSPLASH_VERSION=$NODOGSPLASH_MAJOR_VERSION.$NODOGSPLASH_MINOR_VERSION
|
||||
|
||||
AC_SUBST(NODOGSPLASH_MAJOR_VERSION)
|
||||
|
||||
829
libhttpd/api.c
829
libhttpd/api.c
@@ -64,72 +64,72 @@ char *httpdUrlDecode(char *str) {
|
||||
|
||||
char *httpdRequestMethodName(request *r)
|
||||
{
|
||||
static char tmpBuf[255];
|
||||
static char tmpBuf[255];
|
||||
|
||||
switch(r->request.method)
|
||||
{
|
||||
case HTTP_GET: return("GET");
|
||||
case HTTP_POST: return("POST");
|
||||
default:
|
||||
snprintf(tmpBuf,255,"Invalid method '%d'",
|
||||
r->request.method);
|
||||
return(tmpBuf);
|
||||
}
|
||||
switch(r->request.method)
|
||||
{
|
||||
case HTTP_GET: return("GET");
|
||||
case HTTP_POST: return("POST");
|
||||
default:
|
||||
snprintf(tmpBuf,255,"Invalid method '%d'",
|
||||
r->request.method);
|
||||
return(tmpBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
httpVar *httpdGetVariableByName(request *r, char *name)
|
||||
{
|
||||
httpVar *curVar;
|
||||
httpVar *curVar;
|
||||
|
||||
curVar = r->variables;
|
||||
while(curVar)
|
||||
{
|
||||
if (strcmp(curVar->name, name) == 0)
|
||||
return(curVar);
|
||||
curVar = curVar->nextVariable;
|
||||
}
|
||||
return(NULL);
|
||||
curVar = r->variables;
|
||||
while(curVar)
|
||||
{
|
||||
if (strcmp(curVar->name, name) == 0)
|
||||
return(curVar);
|
||||
curVar = curVar->nextVariable;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
httpVar *httpdGetVariableByPrefix(request *r, char *prefix)
|
||||
{
|
||||
httpVar *curVar;
|
||||
httpVar *curVar;
|
||||
|
||||
if (prefix == NULL)
|
||||
return(r->variables);
|
||||
curVar = r->variables;
|
||||
while(curVar)
|
||||
{
|
||||
if (strncmp(curVar->name, prefix, strlen(prefix)) == 0)
|
||||
return(curVar);
|
||||
curVar = curVar->nextVariable;
|
||||
}
|
||||
return(NULL);
|
||||
if (prefix == NULL)
|
||||
return(r->variables);
|
||||
curVar = r->variables;
|
||||
while(curVar)
|
||||
{
|
||||
if (strncmp(curVar->name, prefix, strlen(prefix)) == 0)
|
||||
return(curVar);
|
||||
curVar = curVar->nextVariable;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
httpVar *httpdGetVariableByPrefixedName(request *r, char *prefix, char *name)
|
||||
{
|
||||
httpVar *curVar;
|
||||
int prefixLen;
|
||||
httpVar *curVar;
|
||||
int prefixLen;
|
||||
|
||||
if (prefix == NULL)
|
||||
return(r->variables);
|
||||
curVar = r->variables;
|
||||
prefixLen = strlen(prefix);
|
||||
while(curVar)
|
||||
if (prefix == NULL)
|
||||
return(r->variables);
|
||||
curVar = r->variables;
|
||||
prefixLen = strlen(prefix);
|
||||
while(curVar)
|
||||
{
|
||||
if (strncmp(curVar->name, prefix, prefixLen) == 0 &&
|
||||
strcmp(curVar->name + prefixLen, name) == 0)
|
||||
{
|
||||
if (strncmp(curVar->name, prefix, prefixLen) == 0 &&
|
||||
strcmp(curVar->name + prefixLen, name) == 0)
|
||||
{
|
||||
return(curVar);
|
||||
}
|
||||
curVar = curVar->nextVariable;
|
||||
return(curVar);
|
||||
}
|
||||
return(NULL);
|
||||
curVar = curVar->nextVariable;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -137,159 +137,164 @@ httpVar *httpdGetNextVariableByPrefix(curVar, prefix)
|
||||
httpVar *curVar;
|
||||
char *prefix;
|
||||
{
|
||||
if(curVar)
|
||||
curVar = curVar->nextVariable;
|
||||
while(curVar)
|
||||
{
|
||||
if (strncmp(curVar->name, prefix, strlen(prefix)) == 0)
|
||||
return(curVar);
|
||||
curVar = curVar->nextVariable;
|
||||
}
|
||||
return(NULL);
|
||||
if(curVar)
|
||||
curVar = curVar->nextVariable;
|
||||
while(curVar)
|
||||
{
|
||||
if (strncmp(curVar->name, prefix, strlen(prefix)) == 0)
|
||||
return(curVar);
|
||||
curVar = curVar->nextVariable;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
int httpdAddVariable(request *r, char *name, char *value)
|
||||
{
|
||||
httpVar *curVar, *lastVar, *newVar;
|
||||
httpVar *curVar, *lastVar, *newVar;
|
||||
|
||||
while(*name == ' ' || *name == '\t')
|
||||
name++;
|
||||
newVar = malloc(sizeof(httpVar));
|
||||
bzero(newVar, sizeof(httpVar));
|
||||
newVar->name = strdup(name);
|
||||
newVar->value = strdup(value);
|
||||
lastVar = NULL;
|
||||
curVar = r->variables;
|
||||
while(curVar)
|
||||
while(*name == ' ' || *name == '\t')
|
||||
name++;
|
||||
newVar = malloc(sizeof(httpVar));
|
||||
bzero(newVar, sizeof(httpVar));
|
||||
newVar->name = strdup(name);
|
||||
newVar->value = strdup(value);
|
||||
lastVar = NULL;
|
||||
curVar = r->variables;
|
||||
while(curVar)
|
||||
{
|
||||
if (strcmp(curVar->name, name) != 0)
|
||||
{
|
||||
if (strcmp(curVar->name, name) != 0)
|
||||
{
|
||||
lastVar = curVar;
|
||||
curVar = curVar->nextVariable;
|
||||
continue;
|
||||
}
|
||||
while(curVar)
|
||||
{
|
||||
lastVar = curVar;
|
||||
curVar = curVar->nextValue;
|
||||
}
|
||||
lastVar->nextValue = newVar;
|
||||
return(0);
|
||||
lastVar = curVar;
|
||||
curVar = curVar->nextVariable;
|
||||
continue;
|
||||
}
|
||||
if (lastVar)
|
||||
lastVar->nextVariable = newVar;
|
||||
else
|
||||
r->variables = newVar;
|
||||
return(0);
|
||||
while(curVar)
|
||||
{
|
||||
lastVar = curVar;
|
||||
curVar = curVar->nextValue;
|
||||
}
|
||||
lastVar->nextValue = newVar;
|
||||
return(0);
|
||||
}
|
||||
if (lastVar)
|
||||
lastVar->nextVariable = newVar;
|
||||
else
|
||||
r->variables = newVar;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void httpd_storeData(request *r, char *query) {
|
||||
_httpd_storeData(r,query);
|
||||
}
|
||||
|
||||
|
||||
httpd *httpdCreate(host, port)
|
||||
char *host;
|
||||
int port;
|
||||
{
|
||||
httpd *new;
|
||||
int sock,
|
||||
opt;
|
||||
struct sockaddr_in addr;
|
||||
httpd *new;
|
||||
int sock,
|
||||
opt;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/*
|
||||
** Create the handle and setup it's basic config
|
||||
*/
|
||||
new = malloc(sizeof(httpd));
|
||||
if (new == NULL)
|
||||
return(NULL);
|
||||
bzero(new, sizeof(httpd));
|
||||
new->port = port;
|
||||
if (host == HTTP_ANY_ADDR)
|
||||
new->host = HTTP_ANY_ADDR;
|
||||
else
|
||||
new->host = strdup(host);
|
||||
new->content = (httpDir*)malloc(sizeof(httpDir));
|
||||
bzero(new->content,sizeof(httpDir));
|
||||
new->content->name = strdup("");
|
||||
/*
|
||||
** Create the handle and setup it's basic config
|
||||
*/
|
||||
new = malloc(sizeof(httpd));
|
||||
if (new == NULL)
|
||||
return(NULL);
|
||||
bzero(new, sizeof(httpd));
|
||||
new->port = port;
|
||||
if (host == HTTP_ANY_ADDR)
|
||||
new->host = HTTP_ANY_ADDR;
|
||||
else
|
||||
new->host = strdup(host);
|
||||
new->content = (httpDir*)malloc(sizeof(httpDir));
|
||||
bzero(new->content,sizeof(httpDir));
|
||||
new->content->name = strdup("");
|
||||
|
||||
/*
|
||||
** Setup the socket
|
||||
*/
|
||||
/*
|
||||
** Setup the socket
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
{
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
int err;
|
||||
{
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
int err;
|
||||
|
||||
wVersionRequested = MAKEWORD( 2, 2 );
|
||||
wVersionRequested = MAKEWORD( 2, 2 );
|
||||
|
||||
err = WSAStartup( wVersionRequested, &wsaData );
|
||||
err = WSAStartup( wVersionRequested, &wsaData );
|
||||
|
||||
/* Found a usable winsock dll? */
|
||||
if( err != 0 )
|
||||
return NULL;
|
||||
/* Found a usable winsock dll? */
|
||||
if( err != 0 )
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
** Confirm that the WinSock DLL supports 2.2.
|
||||
** Note that if the DLL supports versions greater
|
||||
** than 2.2 in addition to 2.2, it will still return
|
||||
** 2.2 in wVersion since that is the version we
|
||||
** requested.
|
||||
*/
|
||||
/*
|
||||
** Confirm that the WinSock DLL supports 2.2.
|
||||
** Note that if the DLL supports versions greater
|
||||
** than 2.2 in addition to 2.2, it will still return
|
||||
** 2.2 in wVersion since that is the version we
|
||||
** requested.
|
||||
*/
|
||||
|
||||
if( LOBYTE( wsaData.wVersion ) != 2 ||
|
||||
HIBYTE( wsaData.wVersion ) != 2 ) {
|
||||
if( LOBYTE( wsaData.wVersion ) != 2 ||
|
||||
HIBYTE( wsaData.wVersion ) != 2 ) {
|
||||
|
||||
/*
|
||||
** Tell the user that we could not find a usable
|
||||
** WinSock DLL.
|
||||
*/
|
||||
WSACleanup( );
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
** Tell the user that we could not find a usable
|
||||
** WinSock DLL.
|
||||
*/
|
||||
WSACleanup( );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The WinSock DLL is acceptable. Proceed. */
|
||||
}
|
||||
/* The WinSock DLL is acceptable. Proceed. */
|
||||
}
|
||||
#endif
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
free(new);
|
||||
return(NULL);
|
||||
}
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
free(new);
|
||||
return(NULL);
|
||||
}
|
||||
# ifdef SO_REUSEADDR
|
||||
opt = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int));
|
||||
opt = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int));
|
||||
# endif
|
||||
new->serverSock = sock;
|
||||
bzero(&addr, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
if (new->host == HTTP_ANY_ADDR)
|
||||
{
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr.sin_addr.s_addr = inet_addr(new->host);
|
||||
}
|
||||
addr.sin_port = htons((u_short)new->port);
|
||||
if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0)
|
||||
{
|
||||
close(sock);
|
||||
free(new);
|
||||
return(NULL);
|
||||
}
|
||||
listen(sock, 128);
|
||||
new->startTime = time(NULL);
|
||||
return(new);
|
||||
new->serverSock = sock;
|
||||
bzero(&addr, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
if (new->host == HTTP_ANY_ADDR)
|
||||
{
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr.sin_addr.s_addr = inet_addr(new->host);
|
||||
}
|
||||
addr.sin_port = htons((u_short)new->port);
|
||||
if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0)
|
||||
{
|
||||
close(sock);
|
||||
free(new);
|
||||
return(NULL);
|
||||
}
|
||||
listen(sock, 128);
|
||||
new->startTime = time(NULL);
|
||||
return(new);
|
||||
}
|
||||
|
||||
void httpdDestroy(server)
|
||||
httpd *server;
|
||||
{
|
||||
if (server == NULL)
|
||||
return;
|
||||
if (server->host)
|
||||
free(server->host);
|
||||
free(server);
|
||||
if (server == NULL)
|
||||
return;
|
||||
if (server->host)
|
||||
free(server->host);
|
||||
free(server);
|
||||
}
|
||||
|
||||
|
||||
@@ -298,73 +303,73 @@ request *httpdGetConnection(server, timeout)
|
||||
httpd *server;
|
||||
struct timeval *timeout;
|
||||
{
|
||||
int result;
|
||||
fd_set fds;
|
||||
struct sockaddr_in addr;
|
||||
size_t addrLen;
|
||||
char *ipaddr;
|
||||
request *r;
|
||||
int result;
|
||||
fd_set fds;
|
||||
struct sockaddr_in addr;
|
||||
size_t addrLen;
|
||||
char *ipaddr;
|
||||
request *r;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(server->serverSock, &fds);
|
||||
result = 0;
|
||||
while(result == 0)
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(server->serverSock, &fds);
|
||||
result = 0;
|
||||
while(result == 0)
|
||||
{
|
||||
result = select(server->serverSock + 1, &fds, 0, 0, timeout);
|
||||
if (result < 0)
|
||||
{
|
||||
result = select(server->serverSock + 1, &fds, 0, 0, timeout);
|
||||
if (result < 0)
|
||||
{
|
||||
server->lastError = -1;
|
||||
return(NULL);
|
||||
}
|
||||
if (timeout != 0 && result == 0)
|
||||
{
|
||||
return(NULL);
|
||||
server->lastError = 0;
|
||||
}
|
||||
if (result > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
server->lastError = -1;
|
||||
return(NULL);
|
||||
}
|
||||
/* Allocate request struct */
|
||||
r = (request *)malloc(sizeof(request));
|
||||
if (r == NULL) {
|
||||
server->lastError = -3;
|
||||
return(NULL);
|
||||
if (timeout != 0 && result == 0)
|
||||
{
|
||||
return(NULL);
|
||||
server->lastError = 0;
|
||||
}
|
||||
memset((void *)r, 0, sizeof(request));
|
||||
/* Get on with it */
|
||||
bzero(&addr, sizeof(addr));
|
||||
addrLen = sizeof(addr);
|
||||
r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr,
|
||||
&addrLen);
|
||||
ipaddr = inet_ntoa(addr.sin_addr);
|
||||
if (ipaddr)
|
||||
strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN);
|
||||
else
|
||||
*r->clientAddr = 0;
|
||||
r->readBufRemain = 0;
|
||||
r->readBufPtr = NULL;
|
||||
if (result > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Allocate request struct */
|
||||
r = (request *)malloc(sizeof(request));
|
||||
if (r == NULL) {
|
||||
server->lastError = -3;
|
||||
return(NULL);
|
||||
}
|
||||
memset((void *)r, 0, sizeof(request));
|
||||
/* Get on with it */
|
||||
bzero(&addr, sizeof(addr));
|
||||
addrLen = sizeof(addr);
|
||||
r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr,
|
||||
&addrLen);
|
||||
ipaddr = inet_ntoa(addr.sin_addr);
|
||||
if (ipaddr)
|
||||
strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN);
|
||||
else
|
||||
*r->clientAddr = 0;
|
||||
r->readBufRemain = 0;
|
||||
r->readBufPtr = NULL;
|
||||
|
||||
/*
|
||||
** Check the default ACL
|
||||
*/
|
||||
if (server->defaultAcl)
|
||||
/*
|
||||
** Check the default ACL
|
||||
*/
|
||||
if (server->defaultAcl)
|
||||
{
|
||||
if (httpdCheckAcl(server, r, server->defaultAcl)
|
||||
== HTTP_ACL_DENY)
|
||||
{
|
||||
if (httpdCheckAcl(server, r, server->defaultAcl)
|
||||
== HTTP_ACL_DENY)
|
||||
{
|
||||
httpdEndRequest(r);
|
||||
server->lastError = 2;
|
||||
return(NULL);
|
||||
}
|
||||
httpdEndRequest(r);
|
||||
server->lastError = 2;
|
||||
return(NULL);
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** N.B.: Functionality removed when not needed for nodogsplash.
|
||||
/** N.B.: Functionality removed when not desired for nodogsplash.
|
||||
* See #if 0 / #endif deletions below. --P. Kube
|
||||
*/
|
||||
int httpdReadRequest(httpd *server, request *r)
|
||||
@@ -580,44 +585,44 @@ int httpdReadRequest(httpd *server, request *r)
|
||||
|
||||
void httpdEndRequest(request *r)
|
||||
{
|
||||
_httpd_freeVariables(r->variables);
|
||||
shutdown(r->clientSock,2);
|
||||
close(r->clientSock);
|
||||
free(r);
|
||||
_httpd_freeVariables(r->variables);
|
||||
shutdown(r->clientSock,2);
|
||||
close(r->clientSock);
|
||||
free(r);
|
||||
}
|
||||
|
||||
|
||||
void httpdFreeVariables(request *r)
|
||||
{
|
||||
_httpd_freeVariables(r->variables);
|
||||
_httpd_freeVariables(r->variables);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void httpdDumpVariables(request *r)
|
||||
{
|
||||
httpVar *curVar,
|
||||
*curVal;
|
||||
httpVar *curVar,
|
||||
*curVal;
|
||||
|
||||
curVar = r->variables;
|
||||
while(curVar)
|
||||
curVar = r->variables;
|
||||
while(curVar)
|
||||
{
|
||||
printf("Variable '%s'\n", curVar->name);
|
||||
curVal = curVar;
|
||||
while(curVal)
|
||||
{
|
||||
printf("Variable '%s'\n", curVar->name);
|
||||
curVal = curVar;
|
||||
while(curVal)
|
||||
{
|
||||
printf("\t= '%s'\n",curVal->value);
|
||||
curVal = curVal->nextValue;
|
||||
}
|
||||
curVar = curVar->nextVariable;
|
||||
printf("\t= '%s'\n",curVal->value);
|
||||
curVal = curVal->nextValue;
|
||||
}
|
||||
curVar = curVar->nextVariable;
|
||||
}
|
||||
}
|
||||
|
||||
void httpdSetFileBase(server, path)
|
||||
httpd *server;
|
||||
char *path;
|
||||
{
|
||||
strncpy(server->fileBasePath, path, HTTP_MAX_URL);
|
||||
strncpy(server->fileBasePath, path, HTTP_MAX_URL);
|
||||
}
|
||||
|
||||
|
||||
@@ -629,34 +634,34 @@ int httpdAddFileContent(server, dir, name, indexFlag, preload, path)
|
||||
int indexFlag;
|
||||
char *path;
|
||||
{
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = strdup(name);
|
||||
newEntry->type = HTTP_FILE;
|
||||
newEntry->indexFlag = indexFlag;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
if (*path == '/')
|
||||
{
|
||||
/* Absolute path */
|
||||
newEntry->path = strdup(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Path relative to base path */
|
||||
newEntry->path = malloc(strlen(server->fileBasePath) +
|
||||
strlen(path) + 2);
|
||||
snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
|
||||
server->fileBasePath, path);
|
||||
}
|
||||
return(0);
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = strdup(name);
|
||||
newEntry->type = HTTP_FILE;
|
||||
newEntry->indexFlag = indexFlag;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
if (*path == '/')
|
||||
{
|
||||
/* Absolute path */
|
||||
newEntry->path = strdup(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Path relative to base path */
|
||||
newEntry->path = malloc(strlen(server->fileBasePath) +
|
||||
strlen(path) + 2);
|
||||
snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
|
||||
server->fileBasePath, path);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -667,34 +672,34 @@ int httpdAddWildcardContent(server, dir, preload, path)
|
||||
int (*preload)();
|
||||
char *path;
|
||||
{
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = NULL;
|
||||
newEntry->type = HTTP_WILDCARD;
|
||||
newEntry->indexFlag = HTTP_FALSE;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
if (*path == '/')
|
||||
{
|
||||
/* Absolute path */
|
||||
newEntry->path = strdup(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Path relative to base path */
|
||||
newEntry->path = malloc(strlen(server->fileBasePath) +
|
||||
strlen(path) + 2);
|
||||
snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
|
||||
server->fileBasePath, path);
|
||||
}
|
||||
return(0);
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = NULL;
|
||||
newEntry->type = HTTP_WILDCARD;
|
||||
newEntry->indexFlag = HTTP_FALSE;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
if (*path == '/')
|
||||
{
|
||||
/* Absolute path */
|
||||
newEntry->path = strdup(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Path relative to base path */
|
||||
newEntry->path = malloc(strlen(server->fileBasePath) +
|
||||
strlen(path) + 2);
|
||||
snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
|
||||
server->fileBasePath, path);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -704,16 +709,16 @@ int httpdAddC404Content(server, function)
|
||||
httpd *server;
|
||||
void (*function)();
|
||||
{
|
||||
if (!server->handle404) {
|
||||
server->handle404 = (http404*)malloc(sizeof(http404));
|
||||
}
|
||||
if (!server->handle404) {
|
||||
server->handle404 = (http404*)malloc(sizeof(http404));
|
||||
}
|
||||
|
||||
if (!server->handle404) {
|
||||
return(-1);
|
||||
}
|
||||
if (!server->handle404) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
server->handle404->function = function;
|
||||
return(0);
|
||||
server->handle404->function = function;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int httpdAddCContent(server, dir, name, indexFlag, preload, function)
|
||||
@@ -723,22 +728,22 @@ int httpdAddCContent(server, dir, name, indexFlag, preload, function)
|
||||
int (*preload)();
|
||||
void (*function)();
|
||||
{
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = strdup(name);
|
||||
newEntry->type = HTTP_C_FUNCT;
|
||||
newEntry->indexFlag = indexFlag;
|
||||
newEntry->function = function;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
return(0);
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = strdup(name);
|
||||
newEntry->type = HTTP_C_FUNCT;
|
||||
newEntry->indexFlag = indexFlag;
|
||||
newEntry->function = function;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -748,22 +753,22 @@ int httpdAddCWildcardContent(server, dir, preload, function)
|
||||
int (*preload)();
|
||||
void (*function)();
|
||||
{
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = NULL;
|
||||
newEntry->type = HTTP_C_WILDCARD;
|
||||
newEntry->indexFlag = HTTP_FALSE;
|
||||
newEntry->function = function;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
return(0);
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = NULL;
|
||||
newEntry->type = HTTP_C_WILDCARD;
|
||||
newEntry->indexFlag = HTTP_FALSE;
|
||||
newEntry->function = function;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int httpdAddStaticContent(server, dir, name, indexFlag, preload, data)
|
||||
@@ -773,109 +778,103 @@ int httpdAddStaticContent(server, dir, name, indexFlag, preload, data)
|
||||
int (*preload)();
|
||||
char *data;
|
||||
{
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
httpDir *dirPtr;
|
||||
httpContent *newEntry;
|
||||
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = strdup(name);
|
||||
newEntry->type = HTTP_STATIC;
|
||||
newEntry->indexFlag = indexFlag;
|
||||
newEntry->data = data;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
return(0);
|
||||
dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
|
||||
newEntry = malloc(sizeof(httpContent));
|
||||
if (newEntry == NULL)
|
||||
return(-1);
|
||||
bzero(newEntry,sizeof(httpContent));
|
||||
newEntry->name = strdup(name);
|
||||
newEntry->type = HTTP_STATIC;
|
||||
newEntry->indexFlag = indexFlag;
|
||||
newEntry->data = data;
|
||||
newEntry->preload = preload;
|
||||
newEntry->next = dirPtr->entries;
|
||||
dirPtr->entries = newEntry;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void httpdSendHeaders(request *r)
|
||||
{
|
||||
_httpd_sendHeaders(r, 0, 0);
|
||||
void httpdSendHeaders(request *r) {
|
||||
_httpd_sendHeaders(r, 0, 0);
|
||||
}
|
||||
|
||||
void httpdSetResponse(request *r, char *msg)
|
||||
{
|
||||
strncpy(r->response.response, msg, HTTP_MAX_URL);
|
||||
void httpdSetResponse(request *r, char *msg) {
|
||||
strncpy(r->response.response, msg, HTTP_MAX_URL);
|
||||
}
|
||||
|
||||
void httpdSetContentType(request *r, char *type)
|
||||
{
|
||||
strcpy(r->response.contentType, type);
|
||||
void httpdSetContentType(request *r, char *type) {
|
||||
strcpy(r->response.contentType, type);
|
||||
}
|
||||
|
||||
|
||||
void httpdAddHeader(request *r, char *msg)
|
||||
{
|
||||
strcat(r->response.headers,msg);
|
||||
if (msg[strlen(msg) - 1] != '\n')
|
||||
strcat(r->response.headers,"\n");
|
||||
void httpdAddHeader(request *r, char *msg) {
|
||||
strcat(r->response.headers,msg);
|
||||
if (msg[strlen(msg) - 1] != '\n')
|
||||
strcat(r->response.headers,"\n");
|
||||
}
|
||||
|
||||
void httpdSetCookie(request *r, char *name, char *value)
|
||||
{
|
||||
char buf[HTTP_MAX_URL];
|
||||
void httpdSetCookie(request *r, char *name, char *value) {
|
||||
char buf[HTTP_MAX_URL];
|
||||
|
||||
snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value);
|
||||
httpdAddHeader(r, buf);
|
||||
snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value);
|
||||
httpdAddHeader(r, buf);
|
||||
}
|
||||
|
||||
void httpdOutput(request *r, char *msg)
|
||||
{
|
||||
char buf[HTTP_MAX_LEN],
|
||||
varName[80],
|
||||
*src,
|
||||
*dest;
|
||||
int count;
|
||||
void httpdOutput(request *r, char *msg) {
|
||||
char buf[HTTP_MAX_LEN],
|
||||
varName[80],
|
||||
*src,
|
||||
*dest;
|
||||
int count;
|
||||
|
||||
src = msg;
|
||||
dest = buf;
|
||||
count = 0;
|
||||
while(*src && count < HTTP_MAX_LEN)
|
||||
src = msg;
|
||||
dest = buf;
|
||||
count = 0;
|
||||
while(*src && count < HTTP_MAX_LEN)
|
||||
{
|
||||
if (*src == '$')
|
||||
{
|
||||
if (*src == '$')
|
||||
{
|
||||
char *cp,
|
||||
*tmp;
|
||||
int count2;
|
||||
httpVar *curVar;
|
||||
char *cp,
|
||||
*tmp;
|
||||
int count2;
|
||||
httpVar *curVar;
|
||||
|
||||
tmp = src + 1;
|
||||
cp = varName;
|
||||
count2 = 0;
|
||||
while(*tmp&&(isalnum(*tmp)||*tmp == '_')&&count2 < 80)
|
||||
{
|
||||
*cp++ = *tmp++;
|
||||
count2++;
|
||||
}
|
||||
*cp = 0;
|
||||
curVar = httpdGetVariableByName(r,varName);
|
||||
if (curVar)
|
||||
{
|
||||
strcpy(dest, curVar->value);
|
||||
dest = dest + strlen(dest);
|
||||
count += strlen(dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest++ = '$';
|
||||
strcpy(dest, varName);
|
||||
dest += strlen(varName);
|
||||
count += 1 + strlen(varName);
|
||||
}
|
||||
src = src + strlen(varName) + 1;
|
||||
continue;
|
||||
}
|
||||
*dest++ = *src++;
|
||||
count++;
|
||||
}
|
||||
*dest = 0;
|
||||
r->response.responseLength += strlen(buf);
|
||||
if (r->response.headersSent == 0)
|
||||
httpdSendHeaders(r);
|
||||
_httpd_net_write( r->clientSock, buf, strlen(buf));
|
||||
tmp = src + 1;
|
||||
cp = varName;
|
||||
count2 = 0;
|
||||
while(*tmp&&(isalnum(*tmp)||*tmp == '_')&&count2 < 80)
|
||||
{
|
||||
*cp++ = *tmp++;
|
||||
count2++;
|
||||
}
|
||||
*cp = 0;
|
||||
curVar = httpdGetVariableByName(r,varName);
|
||||
if (curVar)
|
||||
{
|
||||
strcpy(dest, curVar->value);
|
||||
dest = dest + strlen(dest);
|
||||
count += strlen(dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest++ = '$';
|
||||
strcpy(dest, varName);
|
||||
dest += strlen(varName);
|
||||
count += 1 + strlen(varName);
|
||||
}
|
||||
src = src + strlen(varName) + 1;
|
||||
continue;
|
||||
}
|
||||
*dest++ = *src++;
|
||||
count++;
|
||||
}
|
||||
*dest = 0;
|
||||
r->response.responseLength += strlen(buf);
|
||||
if (r->response.headersSent == 0)
|
||||
httpdSendHeaders(r);
|
||||
_httpd_net_write( r->clientSock, buf, strlen(buf));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -192,6 +192,8 @@ int httpdAddStaticContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),char*));
|
||||
int httpdAddWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),char*));
|
||||
int httpdAddCWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),void(*)()));
|
||||
int httpdAddVariable __ANSI_PROTO((request*, char*, char*));
|
||||
void httpd_storeData __ANSI_PROTO((request*, char*));
|
||||
|
||||
request *httpdGetConnection __ANSI_PROTO((httpd*, struct timeval*));
|
||||
int httpdReadRequest __ANSI_PROTO((httpd*, request*));
|
||||
int httpdCheckAcl __ANSI_PROTO((httpd*, request *, httpAcl*));
|
||||
|
||||
@@ -673,10 +673,9 @@ static unsigned char isAcceptable[96] =
|
||||
/* Bit 0 xalpha -- see HTFile.h
|
||||
** Bit 1 xpalpha -- as xalpha but with plus.
|
||||
** Bit 2 ... path -- as xpalpha but with /
|
||||
** N.B.: changed to disallow space, /
|
||||
*/
|
||||
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||
{ 0,0,0,0,0,0,0,0,0,0,7,0,0,7,7,0, /* 2x !"#$%&'()*+,-./ */
|
||||
{ 7,0,0,0,0,0,0,0,0,0,7,0,0,7,7,0, /* 2x !"#$%&'()*+,-./ */
|
||||
7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */
|
||||
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */
|
||||
@@ -688,7 +687,6 @@ static unsigned char isAcceptable[96] =
|
||||
static char *hex = "0123456789ABCDEF";
|
||||
|
||||
|
||||
/*TODO: fix so spaces are encoded as + */
|
||||
char *_httpd_escape(str)
|
||||
char *str;
|
||||
{
|
||||
@@ -697,9 +695,11 @@ char *_httpd_escape(str)
|
||||
char * q;
|
||||
char * result;
|
||||
int unacceptable = 0;
|
||||
for(p=str; *p; p++)
|
||||
if (!ACCEPTABLE((unsigned char)*p))
|
||||
for(p=str; *p; p++) {
|
||||
if (!ACCEPTABLE((unsigned char)*p)) {
|
||||
unacceptable +=2;
|
||||
}
|
||||
}
|
||||
result = (char *) malloc(p-str + unacceptable + 1);
|
||||
bzero(result,(p-str + unacceptable + 1));
|
||||
|
||||
@@ -710,18 +710,20 @@ char *_httpd_escape(str)
|
||||
for(q=result, p=str; *p; p++) {
|
||||
unsigned char a = *p;
|
||||
if (!ACCEPTABLE(a)) {
|
||||
*q++ = '%'; /* Means hex commming */
|
||||
*q++ = '%'; /* Means hex coming */
|
||||
*q++ = hex[a >> 4];
|
||||
*q++ = hex[a & 15];
|
||||
}
|
||||
else *q++ = *p;
|
||||
} else if (a == ' ') {
|
||||
*q++ = '+'; /* space becomes + */
|
||||
} else {
|
||||
*q++ = *p;
|
||||
}
|
||||
}
|
||||
*q++ = 0; /* Terminate */
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _httpd_sanitiseUrl(url)
|
||||
char *url;
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ FirewallRuleSet authenticated-users {
|
||||
}
|
||||
# end FirewallRuleSet authenticated-users
|
||||
|
||||
# FirewallRuleSet: to-router
|
||||
# FirewallRuleSet: users-to-router
|
||||
#
|
||||
# Control access to the router itself from the GatewayInterface.
|
||||
# These rules are inserted at the beginning of the
|
||||
@@ -155,32 +155,16 @@ FirewallRuleSet users-to-router {
|
||||
|
||||
# ClientForceTimeout 360
|
||||
|
||||
# Parameter: AuthenticatorAddress
|
||||
# Default: none
|
||||
#
|
||||
# If you are using another server to do authentication
|
||||
# (for example password authentication) specify its IP address here.
|
||||
|
||||
# AuthenticatorAddress 192.168.1.1
|
||||
|
||||
# Parameter: AuthenticatorPort
|
||||
# Default: 80
|
||||
#
|
||||
# If you are using another server to do authentication
|
||||
# (for example password authentication) specify its port here.
|
||||
|
||||
# AuthenticatorPort 80
|
||||
|
||||
# Parameter: AuthenticateImmediately
|
||||
# Default: no
|
||||
#
|
||||
# Set to yes (or true or 1), to immediately authenticate users
|
||||
# who make a http port 80 request on the GatewayInterface (i.e.
|
||||
# do not serve a splash page or any authentication server).
|
||||
# do not serve a splash page or redirect to any remote authenticator;
|
||||
# just redirect to the user's request, or to RedirectURL if set).
|
||||
|
||||
# AuthenticateImmediately no
|
||||
|
||||
|
||||
# Parameter: BlockedMACList
|
||||
# Default: none
|
||||
#
|
||||
|
||||
25
src/conf.c
25
src/conf.c
@@ -71,8 +71,9 @@ typedef enum {
|
||||
oGatewayInterface,
|
||||
oGatewayAddress,
|
||||
oGatewayPort,
|
||||
oAuthenticatorAddress,
|
||||
oAuthenticatorPort,
|
||||
oRemoteAuthenticatorAddress,
|
||||
oRemoteAuthenticatorPort,
|
||||
oRemoteAuthenticatorPath,
|
||||
oHTTPDMaxConn,
|
||||
oWebRoot,
|
||||
oSplashPage,
|
||||
@@ -111,8 +112,9 @@ static const struct {
|
||||
{ "gatewayinterface", oGatewayInterface },
|
||||
{ "gatewayaddress", oGatewayAddress },
|
||||
{ "gatewayport", oGatewayPort },
|
||||
{ "authenticatoraddress", oAuthenticatorAddress },
|
||||
{ "authenticatorport", oAuthenticatorPort },
|
||||
{ "remoteauthenticatoraddress", oRemoteAuthenticatorAddress },
|
||||
{ "remoteauthenticatorport", oRemoteAuthenticatorPort },
|
||||
{ "remoteauthenticatorpath", oRemoteAuthenticatorPath },
|
||||
{ "webroot", oWebRoot },
|
||||
{ "splashpage", oSplashPage },
|
||||
{ "imagesdir", oImagesDir },
|
||||
@@ -159,8 +161,8 @@ config_init(void) {
|
||||
config.gw_interface = NULL;
|
||||
config.gw_address = NULL;
|
||||
config.gw_port = DEFAULT_GATEWAYPORT;
|
||||
config.authenticator_address = NULL;
|
||||
config.authenticator_port = DEFAULT_AUTHENTICATORPORT;
|
||||
config.remote_auth_address = NULL;
|
||||
config.remote_auth_port = DEFAULT_REMOTE_AUTH_PORT;
|
||||
config.webroot = DEFAULT_WEBROOT;
|
||||
config.splashpage = DEFAULT_SPLASHPAGE;
|
||||
config.imagesdir = DEFAULT_IMAGESDIR;
|
||||
@@ -571,11 +573,14 @@ config_read(char *filename) {
|
||||
case oGatewayPort:
|
||||
sscanf(p1, "%d", &config.gw_port);
|
||||
break;
|
||||
case oAuthenticatorAddress:
|
||||
config.authenticator_address = safe_strdup(p1);
|
||||
case oRemoteAuthenticatorAddress:
|
||||
config.remote_auth_address = safe_strdup(p1);
|
||||
break;
|
||||
case oAuthenticatorPort:
|
||||
sscanf(p1, "%d", &config.authenticator_port);
|
||||
case oRemoteAuthenticatorPort:
|
||||
sscanf(p1, "%d", &config.remote_auth_port);
|
||||
break;
|
||||
case oRemoteAuthenticatorPath:
|
||||
config.remote_auth_path = safe_strdup(p1);
|
||||
break;
|
||||
case oFirewallRuleSet:
|
||||
parse_firewall_ruleset(p1, fd, filename, &linenum);
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#define DEFAULT_MAXCLIENTS 20
|
||||
#define DEFAULT_GATEWAYNAME "NoDogSplash"
|
||||
#define DEFAULT_GATEWAYPORT 2050
|
||||
#define DEFAULT_AUTHENTICATORPORT 80
|
||||
#define DEFAULT_REMOTE_AUTH_PORT 80
|
||||
#define DEFAULT_CHECKINTERVAL 60
|
||||
#define DEFAULT_CLIENTTIMEOUT 10
|
||||
#define DEFAULT_CLIENTFORCEOUT 360
|
||||
@@ -112,8 +112,9 @@ typedef struct {
|
||||
char *gw_interface; /**< @brief Interface we will accept connections on */
|
||||
char *gw_address; /**< @brief Internal IP address for our web server */
|
||||
int gw_port; /**< @brief Port the webserver will run on */
|
||||
char *authenticator_address; /**< @brief IP address for custom web server */
|
||||
int authenticator_port; /**< @brief Port the custom webserver will run on */
|
||||
char *remote_auth_address; /**< @brief IP address for remote auth */
|
||||
int remote_auth_port; /**< @brief Port the remote auth listens on */
|
||||
char *remote_auth_path; /**< @brief Path for remote auth cgi */
|
||||
char *webroot; /**< @brief Directory containing splash pages, etc. */
|
||||
char *splashpage; /**< @brief Name of main splash page */
|
||||
char *imagesdir; /**< @brief Subdir of webroot containing .png .gif files etc */
|
||||
|
||||
273
src/http.c
273
src/http.c
@@ -176,7 +176,6 @@ http_nodogsplash_footer(request *r) {
|
||||
|
||||
|
||||
/** The 404 handler is one way a client can first hit nodogsplash.
|
||||
* Adds the client to the client list and serves the splash page.
|
||||
*/
|
||||
void
|
||||
http_nodogsplash_callback_404(httpd *webserver, request *r) {
|
||||
@@ -189,7 +188,6 @@ http_nodogsplash_callback_404(httpd *webserver, request *r) {
|
||||
|
||||
|
||||
/** The index handler is one way a client can first hit nodogsplash.
|
||||
* Adds the client to the client list and serves the splash page.
|
||||
*/
|
||||
void
|
||||
http_nodogsplash_callback_index(httpd *webserver, request *r) {
|
||||
@@ -200,32 +198,40 @@ http_nodogsplash_callback_index(httpd *webserver, request *r) {
|
||||
http_nodogsplash_first_contact(r);
|
||||
}
|
||||
|
||||
/** The index handler is one way a client can first hit nodogsplash.
|
||||
* Adds the client to the client list and serves the splash page.
|
||||
/** Respond to attempted access from a preauthenticated client.
|
||||
* Add the client to the client list and serves the splash page.
|
||||
*/
|
||||
void
|
||||
http_nodogsplash_first_contact(request *r) {
|
||||
t_client *client;
|
||||
char *authtarget;
|
||||
t_auth_target *authtarget;
|
||||
s_config *config;
|
||||
|
||||
config = config_get_config();
|
||||
|
||||
client = http_nodogsplash_add_client(r);
|
||||
|
||||
/* http_nodogsplash_add_client() should log and return null on error */
|
||||
if(!client) return;
|
||||
|
||||
authtarget =
|
||||
http_nodogsplash_make_authtarget(client->token,
|
||||
r->request.host,
|
||||
r->request.path);
|
||||
|
||||
if(config->authenticate_immediately) {
|
||||
authtarget = http_nodogsplash_encode_authtarget(r,client->token);
|
||||
http_nodogsplash_redirect(r,authtarget);
|
||||
free(authtarget);
|
||||
http_nodogsplash_callback_action(r,authtarget,AUTH_MAKE_AUTHENTICATED);
|
||||
} else {
|
||||
http_nodogsplash_serve_splash(r,client->token);
|
||||
/* TODO: If RemoteAuthenticator is set,
|
||||
* use http_nodogsplash_encode_remote_auth() to construct a URL
|
||||
* and redirect to it instead of serving splash page
|
||||
*/
|
||||
http_nodogsplash_serve_splash(r,authtarget);
|
||||
}
|
||||
|
||||
http_nodogsplash_free_authtarget(authtarget);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_report_warning(request *r, char *msg) {
|
||||
debug(LOG_WARNING, msg);
|
||||
@@ -234,33 +240,39 @@ _report_warning(request *r, char *msg) {
|
||||
http_nodogsplash_footer(r);
|
||||
}
|
||||
|
||||
/** The multipurpose handler */
|
||||
/** The multipurpose authentication action handler
|
||||
*/
|
||||
void
|
||||
http_nodogsplash_callback_action(request *r, t_authaction action) {
|
||||
http_nodogsplash_callback_action(request *r,
|
||||
t_auth_target *authtarget,
|
||||
t_authaction action) {
|
||||
t_client *client;
|
||||
char *mac;
|
||||
char *ip;
|
||||
char *redir = NULL;
|
||||
char *clienttoken = NULL;
|
||||
char *requesttoken = NULL;
|
||||
char *requesttoken = authtarget->token;
|
||||
char *redir = authtarget->redir;
|
||||
s_config *config;
|
||||
|
||||
config = config_get_config();
|
||||
|
||||
/* Get components of path in request */
|
||||
http_nodogsplash_decode_authtarget(r, &requesttoken, &redir);
|
||||
|
||||
ip = r->clientAddr;
|
||||
|
||||
if(!requesttoken) {
|
||||
debug(LOG_WARNING, "No token in request from ip %s", ip);
|
||||
return;
|
||||
}
|
||||
if(!redir) {
|
||||
debug(LOG_WARNING, "No redirect in request from ip %s", ip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(mac = arp_get(ip))) {
|
||||
/* We could not get their MAC address */
|
||||
|
||||
debug(LOG_WARNING, "Failed to retrieve MAC address for ip %s", ip);
|
||||
http_nodogsplash_header(r, "Nodogsplash Error");
|
||||
httpdOutput(r, "Failed to retrieve your MAC address.");
|
||||
http_nodogsplash_footer(r);
|
||||
free(requesttoken);
|
||||
free(redir);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -277,17 +289,10 @@ http_nodogsplash_callback_action(request *r, t_authaction action) {
|
||||
httpdOutput(r, "You are not on the client list.");
|
||||
http_nodogsplash_footer(r);
|
||||
free(mac);
|
||||
free(requesttoken);
|
||||
free(redir);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We have a client */
|
||||
/* If there is a redir in the config, use it instead of redir in this request */
|
||||
if(config->redirectURL) {
|
||||
free(redir);
|
||||
redir = safe_strdup(config->redirectURL);
|
||||
}
|
||||
|
||||
/* Do we have a client token? */
|
||||
if(!clienttoken) {
|
||||
@@ -296,8 +301,6 @@ http_nodogsplash_callback_action(request *r, t_authaction action) {
|
||||
httpdOutput(r, "No token available.");
|
||||
http_nodogsplash_footer(r);
|
||||
free(mac);
|
||||
free(requesttoken);
|
||||
free(redir);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -315,7 +318,7 @@ http_nodogsplash_callback_action(request *r, t_authaction action) {
|
||||
case AUTH_MAKE_DEAUTHENTICATED:
|
||||
auth_client_action(ip,mac,action);
|
||||
http_nodogsplash_header(r, "Nodogsplash Deny");
|
||||
httpdOutput(r, "OK, see you later!");
|
||||
httpdOutput(r, "Authentication revoked.");
|
||||
http_nodogsplash_footer(r);
|
||||
break;
|
||||
default:
|
||||
@@ -331,8 +334,6 @@ http_nodogsplash_callback_action(request *r, t_authaction action) {
|
||||
http_nodogsplash_footer(r);
|
||||
}
|
||||
free(mac);
|
||||
free(redir);
|
||||
free(requesttoken);
|
||||
free(clienttoken);
|
||||
|
||||
}
|
||||
@@ -340,17 +341,23 @@ http_nodogsplash_callback_action(request *r, t_authaction action) {
|
||||
/** The auth handler registers the client as authenticated, and redirects their web request */
|
||||
void
|
||||
http_nodogsplash_callback_auth(httpd *webserver, request *r) {
|
||||
t_auth_target *authtarget;
|
||||
|
||||
http_nodogsplash_callback_action ( r, AUTH_MAKE_AUTHENTICATED );
|
||||
|
||||
/* Get info we need from request */
|
||||
authtarget = http_nodogsplash_decode_authtarget(r);
|
||||
http_nodogsplash_callback_action (r,authtarget,AUTH_MAKE_AUTHENTICATED );
|
||||
http_nodogsplash_free_authtarget(authtarget);
|
||||
}
|
||||
|
||||
/** The deny handler removes the client from the client list */
|
||||
void
|
||||
http_nodogsplash_callback_deny(httpd *webserver, request *r) {
|
||||
t_auth_target *authtarget;
|
||||
|
||||
http_nodogsplash_callback_action ( r, AUTH_MAKE_DEAUTHENTICATED );
|
||||
|
||||
/* Get info we need from request */
|
||||
authtarget = http_nodogsplash_decode_authtarget(r);
|
||||
http_nodogsplash_callback_action (r,authtarget,AUTH_MAKE_DEAUTHENTICATED );
|
||||
http_nodogsplash_free_authtarget(authtarget);
|
||||
}
|
||||
|
||||
|
||||
@@ -375,7 +382,6 @@ http_nodogsplash_add_client(request *r) {
|
||||
debug(LOG_WARNING, "Failed to retrieve MAC address for ip %s", r->clientAddr);
|
||||
}
|
||||
|
||||
|
||||
LOCK_CLIENT_LIST();
|
||||
|
||||
if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
|
||||
@@ -394,19 +400,23 @@ http_nodogsplash_add_client(request *r) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
http_nodogsplash_decode_authtarget(request *r, char **token, char **redir) {
|
||||
t_auth_target *
|
||||
http_nodogsplash_decode_authtarget(request *r) {
|
||||
char *enccopy, *p1, *p2;
|
||||
httpVar *var;
|
||||
t_auth_target *authtarget;
|
||||
|
||||
/* Make a copy of encoded path because we will modify it */
|
||||
enccopy = safe_strdup(r->request.path);
|
||||
/* enccopy should have the form: /<directory>/<rest>,
|
||||
* where <directory> has had its effect already so we ignore it here,
|
||||
* and where <rest> has been httpdUrlEncoded.
|
||||
* where <directory> has had its effect already in determining which
|
||||
* callback is procesing the request, so we ignore it here,
|
||||
* and where <rest> is a string encoding variables and values in the
|
||||
* usual way.
|
||||
* (See http_nodogsplash_encode_authtarget() for details.)
|
||||
* So, here we find <rest> and httpdUrlDecode it,
|
||||
* to see that <rest> has the form: <requesttoken>/<redir>
|
||||
* So, here we find <rest> and store variable/value pairs in the request,
|
||||
* to find values of token and redir.
|
||||
*/
|
||||
p1 = strchr(enccopy,'/'); /* initial slash */
|
||||
if(!p1) { _report_warning(r,"Malformed action request: first"); free(enccopy); return; }
|
||||
@@ -414,61 +424,142 @@ http_nodogsplash_decode_authtarget(request *r, char **token, char **redir) {
|
||||
p1 = strchr(p1,'/'); /* second slash */
|
||||
if(!p1) { _report_warning(r,"Malformed action request: second"); free(enccopy); return; }
|
||||
p1++;
|
||||
/* httpdUrlDecode the rest. This recovers slashes, among other things. */
|
||||
p1 = httpdUrlDecode(p1); /* Note: this decodes in-place */
|
||||
/* now look for <requesttoken>/<redir> */
|
||||
p2 = strchr(p1,'/'); /* third slash */
|
||||
if(!p2) { _report_warning(r,"Malformed action request: third"); free(enccopy); return; }
|
||||
*p2 = '\0';
|
||||
/* p1 now pointing at terminated token; allocate a copy */
|
||||
*token = safe_strdup(p1);
|
||||
p2++;
|
||||
/* p2 now pointing at decoded redirect; allocate a copy */
|
||||
safe_asprintf(redir,"http://%s",p2);
|
||||
httpd_storeData(r,p1);
|
||||
|
||||
authtarget = http_nodogsplash_make_authtarget_from_request(r);
|
||||
free(enccopy);
|
||||
return authtarget;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to a string encoding a URL which when served will authenticate
|
||||
* a client.
|
||||
* Caller must free.
|
||||
* Allocate and return a pointer to a t_auth_target struct encoding information
|
||||
* needed to eventually authenticate a client.
|
||||
* The struct should be freed by http_nodogsplash_free_authtarget().
|
||||
*/
|
||||
char *
|
||||
http_nodogsplash_encode_authtarget(request *r, char *token) {
|
||||
char *encodedthp, *tokenhostpath, *authtarget;
|
||||
s_config *config;
|
||||
t_auth_target*
|
||||
http_nodogsplash_make_authtarget(char* token, char* redirhost, char* redirpath) {
|
||||
|
||||
t_auth_target* authtarget;
|
||||
s_config *config;
|
||||
|
||||
config = config_get_config();
|
||||
|
||||
safe_asprintf(&tokenhostpath,"%s/%s%s", token, r->request.host, r->request.path);
|
||||
/* We httpdUrlEncode() the concatenation of token, host, path.
|
||||
* (host and path are ultimately for the redirect after authentication.)
|
||||
* This requires a modified version of libhttpd's httpdUrlEncode()
|
||||
* which encodes slashes (as well as the usual things).
|
||||
* This is because we must have an
|
||||
* authtarget that looks like a top-level directory and a file in it.
|
||||
* (Similarly for denytarget.)
|
||||
* Slashes will be recovered when we httpdUrlDecode() in
|
||||
* http_nodogsplash_callback_action().
|
||||
*/
|
||||
encodedthp = httpdUrlEncode(tokenhostpath); /* malloc's */
|
||||
safe_asprintf(&authtarget, "http://%s:%d/%s/%s",
|
||||
config->gw_address, config->gw_port, config->authdir, encodedthp);
|
||||
free(tokenhostpath);
|
||||
free(encodedthp);
|
||||
|
||||
authtarget = safe_malloc(sizeof(t_auth_target));
|
||||
memset(authtarget, 0, sizeof(t_auth_target));
|
||||
authtarget->ip = safe_strdup(config->gw_address);
|
||||
authtarget->port = config->gw_port;
|
||||
authtarget->authdir = safe_strdup(config->authdir);
|
||||
authtarget->denydir = safe_strdup(config->denydir);
|
||||
authtarget->token = safe_strdup(token);
|
||||
if(config->redirectURL) {
|
||||
debug(LOG_DEBUG,"Client requested http://%s%s, substituting %s",
|
||||
redirhost,redirpath,config->redirectURL);
|
||||
authtarget->redir = safe_strdup(config->redirectURL);
|
||||
} else {
|
||||
safe_asprintf(&(authtarget->redir),"http://%s%s",redirhost,redirpath);
|
||||
}
|
||||
|
||||
return authtarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate and return a pointer to a t_auth_target struct encoding information
|
||||
* needed to eventually authenticate a client.
|
||||
* The struct should be freed by http_nodogsplash_free_authtarget().
|
||||
*/
|
||||
t_auth_target*
|
||||
http_nodogsplash_make_authtarget_from_request(request *r) {
|
||||
|
||||
t_auth_target* authtarget;
|
||||
httpVar* var;
|
||||
|
||||
authtarget = safe_malloc(sizeof(t_auth_target));
|
||||
memset(authtarget, 0, sizeof(t_auth_target));
|
||||
|
||||
var = httpdGetVariableByName(r,"tok");
|
||||
authtarget->token = safe_strdup(var->value);
|
||||
var = httpdGetVariableByName(r,"redir");
|
||||
authtarget->redir = safe_strdup(var->value);
|
||||
|
||||
return authtarget;
|
||||
}
|
||||
|
||||
|
||||
/* Given a client request, serve the splash page from its file. */
|
||||
|
||||
void
|
||||
http_nodogsplash_serve_splash(request *r, char *token) {
|
||||
http_nodogsplash_free_authtarget(t_auth_target* authtarget) {
|
||||
|
||||
if(authtarget->ip) free(authtarget->ip);
|
||||
if(authtarget->authdir) free(authtarget->authdir);
|
||||
if(authtarget->denydir) free(authtarget->denydir);
|
||||
if(authtarget->token) free(authtarget->token);
|
||||
if(authtarget->redir) free(authtarget->redir);
|
||||
free(authtarget);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to a URL string
|
||||
* which when served will authenticate a client.
|
||||
* Caller must free.
|
||||
*/
|
||||
char *
|
||||
http_nodogsplash_encode_authtarget(t_auth_target *authtarget) {
|
||||
char *encodedredir, *encodedtoken, *encodedauthtarget;
|
||||
|
||||
/* URL encode the redirect URL and the token */
|
||||
encodedredir = httpdUrlEncode(authtarget->redir); /* malloc's */
|
||||
encodedtoken = httpdUrlEncode(authtarget->token); /* malloc's */
|
||||
|
||||
safe_asprintf(&encodedauthtarget, "http://%s:%d/%s/tok=%s&redir=%s",
|
||||
authtarget->ip,
|
||||
authtarget->port,
|
||||
authtarget->authdir,
|
||||
encodedtoken,
|
||||
encodedredir);
|
||||
|
||||
free(encodedredir);
|
||||
free(encodedtoken);
|
||||
return encodedauthtarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to a URL string for a remote authenticator.
|
||||
* Information passed to the remote cgi variable-value arguments.
|
||||
* Caller must free.
|
||||
*/
|
||||
char *
|
||||
http_nodogsplash_encode_remote_auth(t_auth_target *authtarget) {
|
||||
char *encodedredir, *url;
|
||||
s_config *config;
|
||||
|
||||
config = config_get_config();
|
||||
encodedredir = httpdUrlEncode(authtarget->redir); /* malloc's */
|
||||
safe_asprintf(&url,"http://%s:d/%s?ip=%s&pt=%d&auth=%s&deny=%s&tok=%s&redir=%s",
|
||||
config->remote_auth_address,
|
||||
config->remote_auth_port,
|
||||
config->remote_auth_path,
|
||||
authtarget->ip,
|
||||
authtarget->port,
|
||||
authtarget->authdir,
|
||||
authtarget->denydir,
|
||||
authtarget->token,
|
||||
encodedredir);
|
||||
free(encodedredir);
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
/* Given a client request, pipe the splash page from the splash page file. */
|
||||
void
|
||||
http_nodogsplash_serve_splash(request *r, t_auth_target *authtarget) {
|
||||
char *redirectURL;
|
||||
char line [MAX_BUF];
|
||||
char *splashfilename, *authtarget, *denytarget, *imagesdir;
|
||||
char *splashfilename, *authtargetstr, *imagesdir;
|
||||
char *encodedthp, *tokenhostpath;
|
||||
FILE *fd;
|
||||
|
||||
s_config *config;
|
||||
|
||||
|
||||
@@ -477,17 +568,11 @@ http_nodogsplash_serve_splash(request *r, char *token) {
|
||||
|
||||
httpdAddVariable(r,"gatewayname",config->gw_name);
|
||||
|
||||
/* Get auth and deny targets. */
|
||||
authtarget = http_nodogsplash_encode_authtarget(r,token);
|
||||
httpdAddVariable(r,"authtarget",authtarget);
|
||||
free(authtarget);
|
||||
/* Get auth target as a string */
|
||||
authtargetstr = http_nodogsplash_encode_authtarget(authtarget);
|
||||
httpdAddVariable(r,"authtarget",authtargetstr);
|
||||
free(authtargetstr);
|
||||
|
||||
/*
|
||||
denytarget = http_nodogsplash_encode_deyntarget(r,token);
|
||||
httpdAddVariable(r,"denytarget",denytarget);
|
||||
free(denytarget);
|
||||
*/
|
||||
|
||||
safe_asprintf(&imagesdir, "/%s", config->imagesdir);
|
||||
httpdAddVariable(r,"imagesdir",imagesdir);
|
||||
free(imagesdir);
|
||||
|
||||
29
src/http.h
29
src/http.h
@@ -27,9 +27,22 @@
|
||||
#ifndef _HTTP_H_
|
||||
#define _HTTP_H_
|
||||
|
||||
#include "auth.h"
|
||||
#include "httpd.h"
|
||||
#include "client_list.h"
|
||||
|
||||
/**
|
||||
* Define parts of an authentication target.
|
||||
*/
|
||||
typedef struct _auth_target_t {
|
||||
char *ip; /**< @brief IP of auth server */
|
||||
int port; /**< @brief Port of auth server */
|
||||
char *authdir; /**< @brief Auth dir */
|
||||
char *denydir; /**< @brief Deny dir */
|
||||
char *token; /**< @brief Client token */
|
||||
char *redir; /**< @brief Client redirect target */
|
||||
} t_auth_target;
|
||||
|
||||
/**@brief Callback for libhttpd, serves nodogsplash splash page */
|
||||
void http_nodogsplash_callback_404(httpd *webserver, request *r);
|
||||
/**@brief Callback for libhttpd, serves nodogsplash splash page */
|
||||
@@ -38,18 +51,26 @@ void http_nodogsplash_callback_index(httpd *webserver, request *r);
|
||||
void http_nodogsplash_callback_auth(httpd *webserver, request *r);
|
||||
/**@brief Callback for libhttpd, denies a client for nodogsplash */
|
||||
void http_nodogsplash_callback_deny(httpd *webserver, request *r);
|
||||
/**@brief The multipurpose authentication action handler */
|
||||
void http_nodogsplash_callback_action(request *r, t_auth_target *authtarget, t_authaction action);
|
||||
/**@brief Add client identified in request to client list. */
|
||||
t_client* http_nodogsplash_add_client(request *r);
|
||||
/**@brief Serve a 307 Temporary Redirect */
|
||||
void http_nodogsplash_redirect(request *r, char *url);
|
||||
/**@brief Serve the splash page from its file */
|
||||
void http_nodogsplash_serve_splash(request *r, char *token);
|
||||
void http_nodogsplash_serve_splash(request *r, t_auth_target *authtarget);
|
||||
/**@brief Handle initial contact from client */
|
||||
void http_nodogsplash_first_contact(request *r);
|
||||
/**@brief Decode token and redirect URL from a request */
|
||||
void http_nodogsplash_decode_authtarget(request *r, char **token, char **redir);
|
||||
t_auth_target* http_nodogsplash_decode_authtarget(request *r);
|
||||
/**@brief Malloc and return a string that is the authenticating URL */
|
||||
char* http_nodogsplash_encode_authtarget(request *r, char *token);
|
||||
char* http_nodogsplash_encode_authtarget(t_auth_target *authtarget);
|
||||
/**@brief Malloc and return a t_auth_target struct encoding info */
|
||||
t_auth_target* http_nodogsplash_make_authtarget(char* token, char* redirhost, char* redirpath);
|
||||
/**@brief Malloc and return a t_auth_target struct encoding info */
|
||||
t_auth_target* http_nodogsplash_make_authtarget_from_request(request *r);
|
||||
/**@brief Free a t_auth_target struct */
|
||||
void http_nodogsplash_free_authtarget(t_auth_target* authtarget);
|
||||
/**@brief Allocate and return a random string of 8 hex digits
|
||||
suitable as an authentication token */
|
||||
char * http_make_auth_token();
|
||||
@@ -58,4 +79,6 @@ void http_nodogsplash_header(request *r, char *title);
|
||||
/** @brief Sends HTML footer to web browser */
|
||||
void http_nodogsplash_footer(request *r);
|
||||
|
||||
|
||||
|
||||
#endif /* _HTTP_H_ */
|
||||
|
||||
19
src/util.c
19
src/util.c
@@ -306,10 +306,21 @@ char * get_status_text() {
|
||||
config->gw_address, config->gw_port);
|
||||
len = strlen(buffer);
|
||||
|
||||
snprintf((buffer + len), (sizeof(buffer) - len), "Splashpage: %s/%s\n",
|
||||
config->webroot, config->splashpage);
|
||||
len = strlen(buffer);
|
||||
if(config->authenticate_immediately) {
|
||||
snprintf((buffer + len), (sizeof(buffer) - len), "Authenticate immediately: yes\n");
|
||||
len = strlen(buffer);
|
||||
|
||||
} else {
|
||||
snprintf((buffer + len), (sizeof(buffer) - len), "Splashpage: %s/%s\n",
|
||||
config->webroot, config->splashpage);
|
||||
len = strlen(buffer);
|
||||
}
|
||||
|
||||
if(config->redirectURL) {
|
||||
snprintf((buffer + len), (sizeof(buffer) - len), "Redirect URL: %s\n",
|
||||
config->redirectURL);
|
||||
len = strlen(buffer);
|
||||
}
|
||||
|
||||
snprintf((buffer + len), (sizeof(buffer) - len), "Traffic control: %s\n", config->traffic_control ? "yes" : "no");
|
||||
len = strlen(buffer);
|
||||
@@ -405,7 +416,7 @@ char * get_status_text() {
|
||||
uptime -= minutes * 60;
|
||||
seconds = uptime;
|
||||
|
||||
snprintf((buffer + len), (sizeof(buffer) - len), "Active time: %ud %uh %um %us\n", days, hours, minutes, seconds);
|
||||
snprintf((buffer + len), (sizeof(buffer) - len), " Active time: %ud %uh %um %us\n", days, hours, minutes, seconds);
|
||||
len = strlen(buffer);
|
||||
|
||||
snprintf((buffer + len), (sizeof(buffer) - len), " Token: %s\n", first->token ? first->token : "none");
|
||||
|
||||
Reference in New Issue
Block a user