diff options
-rw-r--r-- | src/Authorisation.c | 57 | ||||
-rw-r--r-- | src/Content.c | 971 | ||||
-rw-r--r-- | src/Cookies.c | 62 | ||||
-rw-r--r-- | src/Groups.c | 156 | ||||
-rw-r--r-- | src/Headers.c | 235 | ||||
-rw-r--r-- | src/Parameters.c | 798 | ||||
-rw-r--r-- | src/Redirect.c | 70 | ||||
-rw-r--r-- | src/SString.c | 442 | ||||
-rw-r--r-- | src/SString.h | 125 | ||||
-rw-r--r-- | src/SStringHTML.c | 40 | ||||
-rw-r--r-- | src/SStringHTML.h | 45 | ||||
-rw-r--r-- | src/SStringIO.h | 39 | ||||
-rw-r--r-- | src/Server.c | 114 | ||||
-rw-r--r-- | src/Sockets.c | 38 | ||||
-rw-r--r-- | src/Steer.c | 53 | ||||
-rw-r--r-- | src/Thorns.c | 191 | ||||
-rw-r--r-- | src/http.c | 111 | ||||
-rw-r--r-- | src/http_Content.h | 12 | ||||
-rw-r--r-- | src/http_Request.h | 4 | ||||
-rw-r--r-- | src/make.code.defn | 5 |
20 files changed, 2101 insertions, 1467 deletions
diff --git a/src/Authorisation.c b/src/Authorisation.c index cde3786..b0c4723 100644 --- a/src/Authorisation.c +++ b/src/Authorisation.c @@ -27,6 +27,7 @@ #include "http_Request.h" #include "http_Auth.h" +#include "http_SString.h" #include "base64.h" @@ -93,11 +94,8 @@ int HTTP_AuthAddUser(const char *database, const char *password, const char *encryption_scheme) { - int retcode; - uHash *this_database; - - retcode = -1; - this_database = NULL; + int retcode = -1; + uHash *this_database = NULL; /* Create the master database if necessary */ if(!AuthDatabase) @@ -124,10 +122,6 @@ int HTTP_AuthAddUser(const char *database, } } } - else - { - retcode = -1; - } /* Now add the user to the database */ if(this_database) @@ -167,24 +161,19 @@ int HTTP_AuthenticateBasic(httpRequest *request, char *user, int length) { - int retval; + int retval = -1; - const char *value; - char *auth_string; + char *auth_string = NULL; char *token; - int decoded_size; - char decoded[DECODED_SIZE+1]; + int decoded_size = 0; + char decoded[DECODED_SIZE+1] = {'\0'}; - char *password; - - int authorised; - - value = HTTP_HeaderValue(request, "Authorization"); + char *password = NULL; - auth_string = NULL; + int authorised = 0; - authorised = 0; + const char *value = HTTP_HeaderValue(request, "Authorization"); /* Null terminate the user string */ if(user && length > 0) @@ -235,10 +224,6 @@ int HTTP_AuthenticateBasic(httpRequest *request, { retval = 0; } - else - { - retval = -1; - } } else { @@ -274,11 +259,11 @@ static int AddUser(uHash *database, const char *password, const char *encryption_scheme) { - int retcode; - struct httpUserData *this_user; + int retcode = -1; /* Does this user already exist ? */ - this_user = (struct httpUserData *)Util_HashData(database, strlen(name), name, 0); + struct httpUserData * this_user = (struct httpUserData *)Util_HashData( + database, strlen(name), name, 0); if(!this_user) { @@ -293,10 +278,6 @@ static int AddUser(uHash *database, retcode = Util_HashStore(database, strlen(name), name, 0, (void *)this_user); } - else - { - retcode = -1; - } } else { @@ -331,20 +312,18 @@ static int VerifyPassword(const char *database, const char *user, const char *password) { - int retcode; - uHash *this_database; - struct httpUserData *data; - - retcode = 0; + int retcode = 0; if(AuthDatabase) { /* Does this database exist ? */ - this_database = (uHash *)Util_HashData(AuthDatabase, strlen(database), database, 0); + uHash *this_database = (uHash *)Util_HashData(AuthDatabase, + strlen(database), database, 0); if(this_database) { - data = (struct httpUserData *) Util_HashData(this_database, strlen(user), user, 0); + struct httpUserData *data = (struct httpUserData *) Util_HashData( + this_database, strlen(user), user, 0); if(data) { diff --git a/src/Content.c b/src/Content.c index 2cf34a7..425b9f2 100644 --- a/src/Content.c +++ b/src/Content.c @@ -40,10 +40,13 @@ #include "cctk_Arguments.h" #include "cctk_Parameters.h" +#include "http_SString.h" + static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusConnect_HTTPD_Content_c) +#define EMPTYSTRING {'\0'} /******************************************************************** ********************* Local Data Types *********************** ********************************************************************/ @@ -103,11 +106,10 @@ int HTTPi_RegisterParameterPages(void); struct httpLink *ContentLinks = NULL; static const char *notauthorized_page = -"<HTML>\n<HEAD><TITLE>Error 401: Not Authorized</TITLE></HEAD>\ -<BODY>You are not authorized to access this page</BODY>\n<HTML>\n"; +"<html>\n<title>Error 401: Not Authorized</title>\n</head>\n" +"<body>\nYou are not authorized to access this page\n</body>\n<html>\n"; -#define USER_LENGTH 255 /******************************************************************** ********************* External Routines ********************** ********************************************************************/ @@ -212,12 +214,10 @@ int HTTP_ContentLink(const char *URL, const char *description, int flags) { - int retval; - struct httpLink *hlink; + int retval = -1; struct httpLink *last; struct httpLink *current; - - hlink = (struct httpLink *)malloc(sizeof(struct httpLink)); + struct httpLink *hlink = (struct httpLink *)malloc(sizeof(struct httpLink)); if(hlink) { @@ -243,10 +243,6 @@ int HTTP_ContentLink(const char *URL, retval = 0; } - else - { - retval = -1; - } return retval; } @@ -297,146 +293,211 @@ static int CompareStrings(const void *string1, const void *string2) @endhistory @@*/ +int +Send_HTTP( httpRequest * request, const char * message ) +{ + return HTTP_Write(request, message, strlen(message)); +} + +int +Send_HTTP_String( httpRequest *request, const String * message ) +{ + return Send_HTTP(request, GetBuffer( message ) ); +} + +void +SendHTTP_OK_Header( httpRequest *request ) +{ + /* Status message */ + Send_HTTP(request, "HTTP/1.0 200 OK\r\n"); + + /* Content-Type */ + Send_HTTP(request, "Content-Type: text/html\r\n"); + Send_HTTP(request, "\r\n"); +} + +void +SSUtil_SplitFilename(const char **dir,const char **file, const String *message) +{ + Util_SplitFilename((char **)dir,(char **)file,GetBuffer(message)); +} + +static void +TimeListItem( String *message, int time, const char *units ) +{ + ConcatCString(message, " <li><span class=\"hilite\">" ); + ConcatDecimal(message, time ); + ConcatCString(message, "</span> " ); + ConcatCString(message, units ); + ConcatCString(message, "</li>\n" ); +} + +void +CCTK_GetRunTitleString( String *s ) +{ + char buf[1024] = EMPTYSTRING; + CCTK_RunTitle(sizeof(buf)-1,buf); + SetToCString( s, buf ); +} + +void +CCTK_GetParameterFilenameString( String *name ) +{ + char buf[1024] = EMPTYSTRING; + CCTK_ParameterFilename(sizeof(buf)-1,buf); + SetToCString( name, buf ); +} + static int MainPage(const cGH *cctkGH, httpRequest *request, void *data) { DECLARE_CCTK_PARAMETERS - int retval; - char message[10098]; - char title[4098]; - char menu[4098]; - char *dir; - char *file; - char *user; - struct httpLink *hlink; + int retval = -1; + String *message = String_New(); + String *title = String_New(); + String *menu = String_New(); + const char *dir = NULL; + const char *file = NULL; + char *user = NULL; + struct httpLink *hlink = NULL; int seconds,minutes,hours,days,weeks,months,years,millenia; - char host[HOSTLENGTH+1]; + char host[HOSTLENGTH+1] = EMPTYSTRING; /* avoid compiler warning about unused parameter */ data = data; - /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); - - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + SendHTTP_OK_Header( request ); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - strcpy(message,"<HTML><HEAD><TITLE>Running CACTUS Status Information</TITLE>\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "<html>\n<head>\n"); + Send_HTTP(request, "<title>Running CACTUS Status Information</title>\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); + Send_HTTP(request, "</head>\n<body>\n"); /* Write out the main header part */ /* LIST COMPILED THORNS */ { int i; - int nthorns; - const char **thorns; - - nthorns = CCTK_NumCompiledThorns(); - thorns = (const char **)malloc(nthorns * sizeof(char *)); - for(i=0; i < nthorns; i++) + int nthorns = CCTK_NumCompiledThorns(); + if( nthorns > 0 ) { - thorns[i] = CCTK_CompiledThorn (i); - } - qsort(thorns, nthorns, sizeof(char *), CompareStrings); - - strcpy(menu, "<DT> <B>Active Thorns:</B>\n"); - for(i=0; i < nthorns; i++) - { - if (CCTK_IsThornActive(thorns[i])) + const char **thorns = (const char **)malloc(nthorns * sizeof(char *)); + if( thorns != NULL ) { - sprintf(menu,"%s<DT><A HREF=\"/Thorns/%s/\">%s</A>\n", - menu, thorns[i], thorns[i]); + for(i=0; i < nthorns; i++) + thorns[i] = CCTK_CompiledThorn (i); + + qsort(thorns, nthorns, sizeof(char *), CompareStrings); + + SetToCString( menu,"<h3>Active Thorns:</h3>\n"); + for(i=0; i < nthorns; i++) + if (CCTK_IsThornActive(thorns[i])) + { + ConcatCString( menu,"<a href=\"/Thorns/"); + ConcatCString( menu, thorns[i]); + ConcatCString( menu,"/\">"); + ConcatCString( menu, thorns[i]); + ConcatCString( menu,"</a><br />\n"); + } + free(thorns); } } - free(thorns); } - HTTP_ContentHeader(cctkGH, 0, 10096, message, menu); - HTTP_Write(request, message, strlen(message)); + SetHTML_ContentHeader(cctkGH, 0, message, menu); + Send_HTTP_String(request, message ); - strcpy(message,"<CENTER>\n" - "<IMG SRC=\"/Images/wwwcactuscodeorg.jpg\"" - " ALT=\"Cactus\" BORDER=0></CENTER>\n"); + Send_HTTP(request, + "<div class=\"banner\">\n" + "<img src=\"/Images/wwwcactuscodeorg.jpg\"" + " alt=\"Cactus\" /></div>\n"); - HTTP_Write(request, message, strlen(message)); - - CCTK_RunTitle(4098,title); + CCTK_GetRunTitleString(title); /* Some blurb */ - sprintf(message, "<br>" - "<CENTER>\n" - "<TABLE WIDTH=60%%>\n" - "<TR>\n" - "<TD ALIGN=CENTER>\n" - "<H2>%s</H2>\n" - "<P>This browser is connected to a Cactus simulation which " - "contains a web server thorn. This thorn provides information " - " and control for the simulation.</P>\n" - "<TABLE CELLPADDING=15>\n" - "<TR>\n" - "<TD ALIGN=CENTER BGCOLOR=#E5FFA2>\n" - "<P><B>Before controlling any features of the simulation, users " - "must <A HREF=\"/control.html\">authenticate</A>.</B></P>\n" - "</TD></TR></TABLE>\n" - "</TD>\n" - "</TR>\n" - "</TABLE>\n",title); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "<CENTER>\n" - "<TABLE CELLPADDING=10>\n" - "<TR>\n" - "<TD VALIGN=TOP>\n"); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, + "<div class=\"centered\">\n" + "<table width=\"60%\">\n" + "<tr>\n" + "<td>\n" + "<h2>"); + Concat(message, title ); + ConcatCString(message, + "</h2>\n" + "<p>This browser is connected to a Cactus simulation which \n" + "contains a web server thorn. This thorn provides information \n" + " and control for the simulation.</p>\n" + "<table cellpadding=\"15\">\n" + "<tr>\n" + "<td class=\"authenticate\">\n" + "<p><strong>Before controlling any features of the simulation, users \n" + "must <a href=\"/control.html\">authenticate</a>.</strong></p>\n" + "</td></tr></table>\n" + "</td>\n" + "</tr>\n" + "</table>\n" + "</div>\n"); + + Send_HTTP_String(request, message ); + + Send_HTTP(request, + "<table cellpadding=\"10\">\n" + "<tr>\n" + "<td>\n"); /* AVAILABLE OPTIONS */ if(ContentLinks) { - strcpy(message, - "<H3>Available options:</H3>\n" - "<dl>\n"); + SetToCString(message, + "<h3>Available options:</h3>\n" + "<dl>\n"); for(hlink = ContentLinks; hlink; hlink=hlink->next) { - sprintf(message, - "%s<dt> <A HREF=\"%s\">%s</a> <dd>%s \n", - message, hlink->URL, hlink->name, hlink->description); - + ConcatCString(message, "<dt> <a href=\""); + ConcatCString(message, hlink->URL ); + ConcatCString(message, "\">" ); + ConcatCString(message, hlink->name ); + ConcatCString(message, "</a> </dt>\n<dd>" ); + ConcatCString(message, hlink->description ); + ConcatCString(message, "</dd>\n" ); } - sprintf(message,"%s</dl>\n",message); - HTTP_Write(request, message, strlen(message)); + ConcatCString(message, "</dl>\n" ); + Send_HTTP_String(request, message ); } - strcpy(message, - "</TD>\n" - "<TD VALIGN=TOP>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "</td>\n" + "<td>\n"); /* CONFIGURATION DETAILS */ - sprintf(message, + SetToCString(message, "<h3>Simulation:</h3>\n" "<ul>\n" - "<li>Flesh version <FONT COLOR=RED> %s</FONT></li>\n" - "<li>Flesh compiled on <FONT COLOR=RED>%s</FONT>" - " at <FONT COLOR=RED>%s</font></li>\n", - CCTK_FullVersion(),CCTK_CompileDate(),CCTK_CompileTime()); - - HTTP_Write(request, message, strlen(message)); + "<li>Flesh version <span class=\"hilite\"> "); + ConcatCString(message, CCTK_FullVersion() ); + ConcatCString(message, + "</span></li>\n" + "<li>Flesh compiled on <span class=\"hilite\">"); + ConcatCString(message, CCTK_CompileDate() ); + ConcatCString(message, + "</span>\n" + " at <span class=\"hilite\">"); + ConcatCString(message, CCTK_CompileTime() ); + ConcatCString(message, + "</span></li>\n"); + + Send_HTTP_String(request, message ); seconds = CCTK_RunTime(); minutes = seconds/60; @@ -454,66 +515,59 @@ static int MainPage(const cGH *cctkGH, httpRequest *request, void *data) millenia=years/1000; years=years-millenia*1000; - strcpy(message,"<li>Time since start up\n<ul>"); + SetToCString(message, "<li>Time since start up\n<ul>"); if (millenia) { - sprintf(message, - "%s <li><font color=red>%d</font> millenia\n",message,millenia); + TimeListItem( message, millenia, "millenia" ); } if (years) { - sprintf(message, - "%s <li><font color=red>%d</font> years\n",message,years); + TimeListItem( message, years, "years" ); } if (months) { - sprintf(message, - "%s <li><font color=red>%d</font> months\n",message,months); + TimeListItem( message, months, "months" ); } if (weeks) { - sprintf(message, - "%s <li><font color=red>%d</font> weeks\n",message,weeks); + TimeListItem( message, weeks, "weeks" ); } if (days) { - sprintf(message, - "%s <li><font color=red>%d</font> days\n",message,days); + TimeListItem( message, days, "days" ); } if (hours) { - sprintf(message, - "%s <li><font color=red>%d</font> hours\n",message,hours); + TimeListItem( message, hours, "hours" ); } if (minutes) { - sprintf(message, - "%s <li><font color=red>%d</font> minutes\n",message,minutes); + TimeListItem( message, minutes, "minutes" ); } if (seconds) { - sprintf(message, - "%s <li><font color=red>%d</font> seconds\n",message,seconds); + TimeListItem( message, seconds, "seconds" ); } - strcat(message,"</ul><li>Parameter filename <font color=red>"); - HTTP_Write(request, message, strlen(message)); + ConcatCString(message, "</ul></li>\n<li> Parameter filename <span class=\"parfile\">" ); + Send_HTTP_String(request, message ); - CCTK_ParameterFilename(4098,message); - Util_SplitFilename(&dir,&file,message); - HTTP_Write(request, file, strlen(file)); + CCTK_GetParameterFilenameString(message); + SSUtil_SplitFilename(&dir,&file,message); + Send_HTTP(request, file); - strcpy(message,"</font>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</span></li>\n"); if (cctkGH && cctkGH->cctk_iteration) { - strcpy(message,"<li>Estimated time per iteration:<UL> "); - sprintf(message,"%s <LI><font color=red>%f</font> seconds</UL>", - message,CCTK_RunTime()/(double)cctkGH->cctk_iteration); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<li>Estimated time per iteration:<ul>\n"); + ConcatCString(message, " <li><span class=\"hilite\">"); + ConcatDouble(message, CCTK_RunTime()/(double)cctkGH->cctk_iteration ); + ConcatCString(message, "</span> seconds</li></ul></li>\n"); - strcpy(message,"<li>Estimated time to completion:<UL> "); + Send_HTTP_String(request, message ); + + SetToCString(message, "<li>Estimated time to completion:\n<ul>"); if (cctk_final_time<cctk_initial_time) { @@ -544,48 +598,40 @@ static int MainPage(const cGH *cctkGH, httpRequest *request, void *data) if (millenia) { - sprintf(message, - "%s <li><font color=red>%d</font> millenia\n",message,millenia); + TimeListItem( message, millenia, "millenia" ); } if (years) { - sprintf(message, - "%s <li><font color=red>%d</font> years\n",message,years); + TimeListItem( message, years, "years" ); } if (months) { - sprintf(message, - "%s <li><font color=red>%d</font> months\n",message,months); + TimeListItem( message, months, "months" ); } if (weeks) { - sprintf(message, - "%s <li><font color=red>%d</font> weeks\n",message,weeks); + TimeListItem( message, months, "months" ); } if (days) { - sprintf(message, - "%s <li><font color=red>%d</font> days\n",message,days); + TimeListItem( message, days, "days" ); } if (hours) { - sprintf(message, - "%s <li><font color=red>%d</font> hours\n",message,hours); + TimeListItem( message, hours, "hours" ); } if (minutes) { - sprintf(message, - "%s <li><font color=red>%d</font> minutes\n",message,minutes); + TimeListItem( message, minutes, "minutes" ); } if (seconds) { - sprintf(message, - "%s <li><font color=red>%d</font> seconds\n",message,seconds); + TimeListItem( message, seconds, "seconds" ); } - strcat(message,"</UL>"); + ConcatCString(message, "</ul></li>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message ); } Util_GetHostName(host,HOSTLENGTH); @@ -593,41 +639,44 @@ static int MainPage(const cGH *cctkGH, httpRequest *request, void *data) if (CCTK_nProcs(cctkGH) == 1) { - sprintf(message, - "<li>Single processor run</li>\n" - "<li>Running on <FONT COLOR=RED>%s</FONT></li>\n",host); + SetToCString(message, "<li>Single processor run</li>\n" + "<li>Running on <span class=\"hilite\">" ); + ConcatCString(message, host); + ConcatCString(message, "</span></li>\n"); } else { - sprintf(message, - " <li>Multiprocessor run on %d CPUs</li>\n" - " <li>Processor 0 running on <FONT COLOR=RED>%s</FONT></li>\n", - CCTK_nProcs(cctkGH),host); + SetToCString(message, " <li>Multiprocessor run on " ); + ConcatDecimal(message, CCTK_nProcs(cctkGH)); + ConcatCString(message, " CPUs</li>\n" + " <li>Processor 0 running on <span class=\"hilite\">"); + ConcatCString(message, host); + ConcatCString(message, "</span></li>\n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message ); user = getenv ("USER"); if (user) { - sprintf(message, " <li> Started by <FONT COLOR=RED>%s</FONT></li>\n",user); + SetToCString(message, " <li> Started by <span class=\"hilite\">"); + ConcatCString(message, user); + ConcatCString(message, "</span></li>\n"); + Send_HTTP_String(request, message ); } - HTTP_Write(request, message, strlen(message)); - strcpy(message,"</UL>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</ul>\n"); /* Finish table started by blurb */ - strcpy(message, - "</TD>\n" - "</TR>\n" - "</TABLE>\n" - "</CENTER>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</td>\n</tr>\n</table>\n\n"); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH, 0, 4096, message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH, 0, message); + retval = Send_HTTP_String(request, message ); + + String_Delete( message ); + String_Delete( title ); + String_Delete( menu ); return retval; } @@ -657,10 +706,9 @@ static int MainPage(const cGH *cctkGH, httpRequest *request, void *data) @@*/ static int RegisterImages(void) { - struct httpStaticPage *image; - struct httpStaticPage *image2; - - image = (struct httpStaticPage *)malloc(sizeof(struct httpStaticPage)); + struct httpStaticPage *image2 = NULL; + struct httpStaticPage *image + = (struct httpStaticPage *)malloc(sizeof(struct httpStaticPage)); if(image) { @@ -709,37 +757,35 @@ static int RegisterImages(void) @@*/ static int ShowStaticPage(const cGH *cctkGH, httpRequest *request, void *data) { - int retval; - char message[1024]; - struct httpStaticPage *page; + int retval = -1; /* avoid compiler warning about unused parameter */ cctkGH = cctkGH; if(data) { - page = (struct httpStaticPage *)data; + struct httpStaticPage *page = (struct httpStaticPage *)data; + String *message = String_New(); - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "HTTP/1.0 200 OK\r\n"); - sprintf(message,"Content-Length: %d\r\nContent-Type: %s\r\n\r\n", page->length, page->mime_type); + SetToCString(message, "Content-Length: "); + ConcatDecimal(message, page->length ); + ConcatCString(message, "\r\nContent-Type: "); + ConcatCString(message, page->mime_type ); + ConcatCString(message, "\r\n\r\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); retval = HTTP_Write(request, page->page, page->length); - } - else - { - retval = -1; - } + String_Delete( message ); + } return retval; } - +#define USER_LENGTH 255 /*@@ @routine ControlPage @date Sun Sep 17 14:37:59 2000 @@ -758,142 +804,155 @@ static int ControlPage(const cGH *cctkGH, httpRequest *request, void *data) { DECLARE_CCTK_PARAMETERS - char message[4098]; - - int notauthorised; + int notauthorised = 0; + char thisuser[USER_LENGTH+1] = EMPTYSTRING; - char thisuser[USER_LENGTH+1]; + data = data; /* avoid compiler warning about unused parameter */ - /* avoid compiler warning about unused parameter */ - data = data; - - notauthorised = HTTP_AuthenticateBasic(request, "user", thisuser, USER_LENGTH); + notauthorised = HTTP_AuthenticateBasic(request, "user", thisuser, + sizeof(thisuser)); if(!notauthorised) { /* Ok the person is authorised. */ if(request->n_arguments == 0) { + String *message = String_New(); /* No arguments, so just display the page */ - strcpy(message,"HTTP/1.0 200 Ok\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"HTTP/1.0 200 Ok\r\n"); - strcpy(message,"WWW-Authenticate: Basic realm=\"Cactus Control\"\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"WWW-Authenticate: Basic realm=\"Cactus Control\"\r\n"); HTTP_CookieSend(request,"user", thisuser, "/", NULL, NULL, 0); - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"Content-Type: text/html\r\n\r\n"); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - strcpy(message, "<HTML><HEAD><TITLE>Cactus Control and Status Page</TITLE>\n"); - - HTTP_Write(request, message, strlen(message)); - HTTP_ContentHeader(cctkGH, 0,4098,message,NULL); + Send_HTTP(request, "<html><head>\n"); + Send_HTTP(request, "<title>Cactus Control and Status Page</title>\n"); - strcat(message, "<center><h1>Control and Status Page</h1></center>"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "<P>This page is the control center for interacting with" - " the current simulation. It is possible to steer certain" - " parameters, as well as pause, restart, or terminate the" - " simulation.</P>"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</head>\n<body>\n"); + + SetHTML_ContentHeader(cctkGH, 0,message,NULL); - strcpy(message, - "<CENTER>\n" - "<FORM action=\"/control.html\" method=\"GET\">\n"); + ConcatCString(message, "<h1>Control and Status Page</h1>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message, - "<H4> Run Control </H4>\n" - "<p> Select if the run should be paused, running normally, or terminated." - " You may also single step to the next iteration.</p>"); + Send_HTTP(request, + "<p>This page is the control center for interacting with\n" + " the current simulation. It is possible to steer certain\n" + " parameters, as well as pause, restart, or terminate the" + " simulation.</p>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "<div class=\"centered\">\n" + "<form action=\"/control.html\" method=\"get\">\n"); - strcpy(message, - "<TABLE BORDER= 0 CELLSPACING=5 CELLPADDING=5>\n" - "<TR>\n"); + Send_HTTP(request, + "<h4> Run Control </h4>\n" + "<p> Select if the run should be paused, running normally, " + "or terminated.\n" + " You may also single step to the next iteration.</p>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "<table class=\"controls\" cellspacing=\"5\" cellpadding=\"5\">\n" + "<tr>\n"); - sprintf(message, - "<TD align=left valign=center><INPUT type=\"radio\" name=\"runstate\" %s value=\"PAUSE\"> PAUSE</TD>\n", - pause ? "checked" : ""); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, + "<td><input type=\"radio\" name=\"runstate\" "); + ConcatCString(message, pause ? "checked=\"checked\"" : ""); + ConcatCString(message, + " value=\"PAUSE\" /> PAUSE</td>\n"); + Send_HTTP_String(request, message); - sprintf(message, - "<TD align=left valign=center><INPUT type=\"radio\" name=\"runstate\" %s value=\"RUN\"> RUN</TD>\n", - pause ? "" : "checked"); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, + "<td><input type=\"radio\" name=\"runstate\" "); + ConcatCString(message, pause ? "checked=\"checked\"" : ""); + ConcatCString(message, + " value=\"RUN\" /> RUN</td>\n"); + Send_HTTP_String(request, message); - strcpy(message, - "<TD align=left valign=center><INPUT type=\"radio\" name=\"runstate\" value=\"TERMINATE\"> TERMINATE</TD>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "<td><input type=\"radio\" name=\"runstate\" " + "value=\"TERMINATE\" /> TERMINATE</td>\n"); - strcpy(message, - "<TD align=left valign=center><INPUT type=\"submit\" name=\"step\" value=\"STEP\"></TD>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "<td><input type=\"submit\" name=\"step\" " + "value=\"STEP\" /></td>\n"); - strcpy(message, - "</TR></TABLE>\n" - "<TABLE>\n" - "<TR><TD><INPUT type=\"submit\" value=\"OK\"></TD><TD> <INPUT type=\"reset\"></TD>\n" - "</TR>\n" - "</TABLE>\n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "<H4> Run Until </H4>\n" - "<p> The following parameters allow you to select an iteration number" - " or physical time at which the code will pause.\n" - " You may also choose to pause if a particular expression made up" - " of grid scalars, simulation time and iteration is true. \n" - " Note that even if 'run' is selected above, the settings here have" - " precedence. </p>"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "<TABLE>\n"); - - sprintf(message,"%s<TR><TD>Iteration</TD>" - "<TD><INPUT type=\"text\" value=\"%d\" name=\"iteration\"></TD>" - "<TD><INPUT type=\"checkbox\" value=\"yes\" %s name=\"until_it_active\"></TD>\n" - "</TR>\n", message, until_it, until_it_active ? "checked" : ""); - sprintf(message,"%s<TR><TD>Time</TD>" - "<TD><INPUT type=\"text\" value=\"%f\" name=\"time\"></TD>" - "<TD><INPUT type=\"checkbox\" value=\"yes\" %s name=\"until_time_active\"></TD>\n" - "</TR>\n", message, until_time, until_time_active ? "checked" : ""); - sprintf(message,"%s<TR><TD>Expression</TD>" - "<TD><INPUT type=\"text\" value=\"%s\" name=\"expression\"></TD>" - "<TD><INPUT type=\"checkbox\" value=\"yes\" %s name=\"until_expression_active\"></TD>\n" - "</TR>\n", message, until_expression, until_expression_active ? "checked" : ""); - - strcat(message,"</TABLE>\n"); + Send_HTTP(request, + "</tr></table>\n" + "<table>\n" + "<tr><td><input type=\"submit\" value=\"OK\" /></td>\n" + "<td> <input type=\"reset\" /></td>\n" + "</tr>\n" + "</table>\n"); + + Send_HTTP(request, + "<h4> Run Until </h4>\n" + "<p> The following parameters allow you to select an iteration\n" + "number or physical time at which the code will pause.\n" + " You may also choose to pause if a particular expression made up\n" + " of grid scalars, simulation time and iteration is true. \n" + " Note that even if 'run' is selected above, the settings here have" + " precedence. </p>\n"); + + SetToCString(message, + "<table>\n"); + + ConcatCString(message,"<tr><td>Iteration</td>" + "<td><input type=\"text\" value=\""); + ConcatDecimal(message, until_it ); + ConcatCString(message, + "\" name=\"iteration\" /></td>\n" + "<td><input type=\"checkbox\" value=\"yes\" "); + ConcatCString(message, until_it_active ? "checked=\"checked\"" : "" ); + ConcatCString(message, + " name=\"until_it_active\" /></td>\n" + "</tr>\n"); + ConcatCString(message, + "<tr><td>Time</td>" + "<td><input type=\"text\" value=\""); + ConcatDouble(message, until_time ); + ConcatCString(message, + "\" name=\"time\" /></td>\n" + "<td><input type=\"checkbox\" value=\"yes\" "); + ConcatCString(message, until_time_active ? "checked=\"checked\"" : "" ); + ConcatCString(message, + " name=\"until_time_active\" /></td>\n" + "</tr>\n"); + ConcatCString(message, + "<tr><td>Expression</td>\n" + "<td><input type=\"text\" value=\""); + ConcatCString(message, until_expression ); + ConcatCString(message, + "\" name=\"expression\" /></td>\n" + "<td><input type=\"checkbox\" value=\"yes\" "); + ConcatCString(message, until_expression_active ? " checked=\"checked\"" : "" ); + ConcatCString(message, + " name=\"until_expression_active\" /></td>\n" + "</tr>\n"); + + ConcatCString(message,"</table>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message, - "</FORM>\n" - "</CENTER>\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "</form>\n" + "</div>\n"); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH, 0, 4098, message); - HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH, 0, message); + Send_HTTP_String(request, message); + + String_Delete( message ); } else { @@ -904,24 +963,17 @@ static int ControlPage(const cGH *cctkGH, httpRequest *request, void *data) else { /* Not authorised */ - strcpy(message,"HTTP/1.0 401 Unauthorized\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"HTTP/1.0 401 Unauthorized\r\n"); - strcpy(message,"WWW-Authenticate: Basic realm=\"Cactus Control\"\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"WWW-Authenticate: Basic realm=\"Cactus Control\"\r\n"); HTTP_CookieCancel(request,"user", "/"); - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"Content-Type: text/html\r\n\r\n"); - HTTP_Write(request, notauthorized_page, strlen(notauthorized_page)); + Send_HTTP(request, notauthorized_page); } - return 0; } @@ -942,8 +994,8 @@ static int ControlPage(const cGH *cctkGH, httpRequest *request, void *data) static int ControlSet(const cGH *cctkGH, httpRequest *request) { DECLARE_CCTK_PARAMETERS - char message[4098]; - const char *value; + String *message = String_New(); + const char *value = NULL; /* What is the runstate ? */ value = HTTP_ArgumentValue(request,"runstate"); @@ -1074,22 +1126,27 @@ static int ControlSet(const cGH *cctkGH, httpRequest *request) /**************************************************************************** **************** Now redirect the browser to the normal page *************** */ + /* SW: I don't think this is working right. On my browsers, it just + * displays the ControlTerminationPage, with the following lines + * of text rendered at the bottom. */ /* Status message */ if(request->http_major_version < 1 || (request->http_major_version == 1 && request->http_minor_version < 1)) { /* Older browsers don't understand 303 */ - strcpy(message,"HTTP/1.0 302 Found\r\n"); + SetToCString(message,"HTTP/1.0 302 Found\r\n"); } else { - strcpy(message,"HTTP/1.0 303 See Other\r\n"); + SetToCString(message,"HTTP/1.0 303 See Other\r\n"); } - sprintf(message, "%sLocation: /control.html\r\n\r\n", message); + ConcatCString(message, "Location: /control.html\r\n\r\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); + + String_Delete( message ); return 0; } @@ -1110,121 +1167,109 @@ static int ControlSet(const cGH *cctkGH, httpRequest *request) @@*/ static int ControlTerminationPage(const cGH *cctkGH, httpRequest *request) { - int retval; - char message[4098]; - - /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); - - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + int retval = -1; + String *message = String_New(); + SendHTTP_OK_Header( request ); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - strcpy(message,"<HTML><HEAD><TITLE>Running CACTUS Status Information : Terminated</TITLE>\n"); + Send_HTTP(request, "<html><head>\n"); + Send_HTTP(request, "<title>Running CACTUS Status Information : Terminated</title>\n"); - HTTP_Write(request, message, strlen(message)); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - /* Write out the main header part */ - HTTP_ContentHeader(cctkGH,1,4098,message,NULL); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</head>\n<body>\n"); - strcpy(message, "<center><h1>Simulation Home Page</h1></center>"); + /* Write out the main header part */ + SetHTML_ContentHeader(cctkGH,1,message,NULL); + Send_HTTP_String(request, message); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "<h1>Simulation Home Page</h1>\n"); /* Some blurb */ - strcpy(message, "<br>" - "<center><table cellspacing=5 cellpadding=5 border=0><tr><td valign=top>" - "<h3>Simulation web server:</h3>" - "<p>This browser is connected to a Cactus simulation which contains " - "a web server thorn. This thorn allows you to monitor the simulation, " - "and view and change parameters</p>" - "<p>Depending on which other thorns are active, there may be additional " - "features available, such as the viewing and downloading of output files</p>"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "<div class=\"centered\">\n" + "<table cellspacing=\"5\" cellpadding=\"5\" border=\"0\"><tr><td>\n" + "<h3>Simulation web server:</h3>\n" + "<p>This browser is connected to a Cactus simulation which \n" + "contains a web server thorn. This thorn allows you to monitor \n" + "the simulation,\n" + "and view and change parameters</p>\n" + "<p>Depending on which other thorns are active, there may be \n" + "additional features available, such as the viewing and \n" + "downloading of output files</p>\n"); /* CONFIGURATION DETAILS */ - sprintf(message, "<h3>Simulation:</h3>" - "<ul><li>Flesh version <FONT COLOR=RED>%s" - "</FONT></li>\n" - "<li>Flesh compiled on <FONT COLOR=RED>" - __DATE__ "</FONT> at <FONT COLOR=RED>"__TIME__ "</font></li>\n" - ,CCTK_FullVersion()); + SetToCString(message, + "<h3>Simulation:</h3>\n" + "<ul> <li>Flesh version <span class=\"hilite\"> "); + ConcatCString(message, CCTK_FullVersion() ); + ConcatCString(message, + "</span></li>\n" + "<li>Flesh compiled on <span class=\"hilite\"> __DATE__ </span>\n" + "at <span class=\"hilite\"> __TIME__ </span></li>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); if (cctkGH) { if (CCTK_nProcs(cctkGH) == 1) { - strcpy(message,"<li>Single processor run</li>"); + SetToCString(message,"<li>Single processor run</li>\n"); } else { - sprintf(message," <li>Multiprocessor run on %d CPUs</li>", - CCTK_nProcs(cctkGH)); + SetToCString(message," <li>Multiprocessor run on "); + ConcatDecimal( message, CCTK_nProcs(cctkGH) ); + ConcatCString( message, " CPUs</li>\n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); } - strcpy(message,"</UL>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"</ul>\n"); - /******************************************************************************/ + /************************************************************************/ /* NEW COLUMN */ - strcpy(message, "</td><td valign=top>"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</td><td>"); - /*******************************************************************************/ + /************************************************************************/ /* CURRENT STATE OF SIMULATION */ if (cctkGH) { - sprintf(message, "<H3> Current state:</h3> " - "<ul><li>Physical time <FONT COLOR=RED>%f" - "</FONT>\n" - "<li>Iteration number <FONT COLOR=RED>%d" - "</FONT></li>\n", - cctkGH->cctk_time, - cctkGH->cctk_iteration); + SetToCString(message, + "<h3> Current state:</h3> \n" + "<ul><li>Physical time <span class=\"hilite\"> "); + ConcatDouble(message, cctkGH->cctk_time ); + ConcatCString(message, + "</span></li> \n" + "<li>Iteration number <span class=\"hilite\"> "); + ConcatDecimal(message, cctkGH->cctk_iteration ); + ConcatCString(message, "</li>\n"); } else { - strcpy(message, "<li>Current cactus state is unknown</li>\n"); + SetToCString(message, "<li>Current cactus state is unknown</li>\n"); } - HTTP_Write(request, message, strlen(message)); - - strcpy(message, "<li>This Cactus run is over.</li>\n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message, "</ul>"); + Send_HTTP_String(request, message); + Send_HTTP(request, "<li>This Cactus run is over.</li>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</ul>"); /* LIST COMPILED THORNS */ - { int i; - int nthorns; - const char **thorns; - - nthorns = CCTK_NumCompiledThorns(); - - thorns = (const char **)malloc(nthorns * sizeof(char *)); + int nthorns = CCTK_NumCompiledThorns(); + const char **thorns = (const char **)malloc(nthorns * sizeof(char *)); for(i=0; i < nthorns; i++) { @@ -1234,42 +1279,45 @@ static int ControlTerminationPage(const cGH *cctkGH, httpRequest *request) /* Sort the thorns */ qsort(thorns, nthorns, sizeof(char *), CompareStrings); - strcpy(message, "<h3>Compiled thorns:</h3>" - "<p>This list shows all thorns compiled into the executable, " - "those thorns which have been activated in the parameter " - "file for this simulation are shown in " - "<font color=red>red</font></p>" - "<UL>\n"); + SetToCString(message, + "<h3>Compiled thorns:</h3>\n" + "<p>This list shows all thorns compiled into the executable; those \n" + "thorns which have been activated in the parameter file for this \n" + "simulation are shown in <span class=\"hilite\">red</span></p>\n" + "<ul>\n"); for(i=0; i < nthorns; i++) { - strcat(message, "<LI>"); + ConcatCString(message, "<li>"); if (CCTK_IsThornActive(thorns[i])) { - sprintf(message,"%s<FONT COLOR=red>%s</FONT>\n", message, thorns[i]); + ConcatCString(message, " <span class=\"hilite\">"); + ConcatCString(message, thorns[i]); + ConcatCString(message, " </span>"); } else { - sprintf(message, "%s%s\n", message, thorns[i]); + ConcatCString(message, thorns[i]); } + ConcatCString(message, "</li>\n"); } - strcat(message, "</UL>\n"); + ConcatCString(message, "</ul>\n"); free(thorns); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); /* Finish table started by blurb */ - strcpy(message, "</td></tr></table>"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</td></tr></table>\n"); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH,0,4098,message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH,0,message); + retval = Send_HTTP_String(request, message); + + String_Delete( message ); return retval; } @@ -1289,12 +1337,12 @@ static int ControlTerminationPage(const cGH *cctkGH, httpRequest *request) @@*/ int HTTP_ContentSendFromFile(httpRequest *request, int filedes) { - int bytes_sent; - int n_bytes; - char buffer[4098]; + int bytes_sent = 0; + int n_bytes = 0; + char buffer[4098] = EMPTYSTRING; bytes_sent = 0; - while((n_bytes = read(filedes, buffer,4098)) > 0) + while((n_bytes = read(filedes, buffer,sizeof(buffer))) > 0) { HTTP_Write(request, buffer, n_bytes); bytes_sent += n_bytes; @@ -1309,7 +1357,6 @@ int HTTP_ContentSendFromFile(httpRequest *request, int filedes) } - /*@@ @routine AboutPage @date Sun Sep 17 2000 @@ -1322,60 +1369,54 @@ int HTTP_ContentSendFromFile(httpRequest *request, int filedes) @@*/ static int AboutPage(const cGH *cctkGH, httpRequest *request, void *data) { - int retval; - char message[4098]; + int retval = -1; + String *message = String_New(); /* avoid compiler warning about unused parameter */ data = data; - /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); - - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + SendHTTP_OK_Header( request ); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - strcpy(message, "<HTML><HEAD><TITLE>About Cactus Server</TITLE></HEAD>\n"); - HTTP_ContentHeader(cctkGH,0,4098,message,NULL); - strcat(message,"<BODY>"); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<html><head>\n<title>About Cactus Server</title>\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - strcpy(message, "<center>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</head>\n<body>\n"); + SetHTML_ContentHeader(cctkGH,0,message,NULL); + Send_HTTP_String(request, message); - strcpy(message, "<h1>About this Web Server</h1>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "<h1>About this Web Server</h1>\n"); - strcpy(message, "</center><p>These web pages are served by a simulation " - "which is using the Cactus Code and Computational ToolKit, " + SetToCString(message, "<p>These web pages are served by a simulation \n" + "which is using the Cactus Code and Computational ToolKit, \n" "a freely available, parallel, collaborative," - " portable and " - "modular programming environment for HPC.</p>" - "<p>The HTTPD module, or <i>thorn</i> " - "which is serving these pages" - " can be added to any Cactus application to provide on-line " - "monitoring and control of simulations from any web browser.</p>" - "<p>This HTTPD server and thorn interface has been designed and " - "and implemented by Tom Goodale, based on the original idea and " - "implementation by Werner Benger.</p>"); + " portable and \n" + "modular programming environment for HPC.</p>\n" + "<p>The HTTPD module, or <dfn>thorn</dfn> " + "which is serving these pages\n" + " can be added to any Cactus application to provide on-line \n" + "monitoring and control of simulations from any web browser.</p>\n" + "<p>This HTTPD server and thorn interface has been designed and \n" + "and implemented by Tom Goodale, based on the original idea and \n" + "implementation by Werner Benger.</p>\n"); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP_String(request, message); - strcpy(message, "<p>For more information about Cactus, visit our " - "permanent home page at " - "<a href=\"http://www.cactuscode.org\">www.cactuscode.org</a></p>"); + SetToCString(message, "<p>For more information about Cactus, visit our " + "permanent home page at \n" + "<a href=\"http://www.cactuscode.org\">www.cactuscode.org</a></p>\n"); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP_String(request, message); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH,0,4098,message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH,0,message); + retval = Send_HTTP_String(request, message); + String_Delete( message); return retval; } @@ -1397,18 +1438,16 @@ static int AboutPage(const cGH *cctkGH, httpRequest *request, void *data) @@*/ static int CookieTestPage(const cGH *cctkGH, httpRequest *request, void *data) { - int retval; - char message[4098]; - const char *value; - char *value2; + int retval = -1; + String *message = String_New(); + const char *value = NULL; + char *value2 = NULL; /* avoid compiler warning about unused parameter */ data = data; /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"HTTP/1.0 200 OK\r\n"); /* Cookie */ HTTP_CookieSend(request, "user1", "foobar4", NULL,NULL,NULL,0); @@ -1419,45 +1458,49 @@ static int CookieTestPage(const cGH *cctkGH, httpRequest *request, void *data) HTTP_CookieSend(request, "user4", "foobar1", NULL,NULL,NULL,0); - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"Content-Type: text/html\r\n\r\n"); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - strcpy(message, "<HTML><HEAD><TITLE>Cookie Test</TITLE>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "<html><head><title>Cookie Test</title>\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - HTTP_ContentHeader(cctkGH,0,4098,message,NULL); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</head>\n<body>\n"); - strcat(message, "<center><h1>Cookie Test</h1></center>"); + SetHTML_ContentHeader(cctkGH,0,message,NULL); + Send_HTTP_String(request, message); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "<h1>Cookie Test</h1>\n"); - strcpy(message, "<center>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "<div class=\"centered\">"); value = HTTP_HeaderValue(request, "Cookie"); - sprintf(message, "<p>Cookie was '%s'</p>\n", value); + SetToCString(message, "<p>Cookie was '"); + ConcatCString(message, value); + ConcatCString(message, "'</p>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); value2 = HTTP_CookieGet(request,"user3"); - sprintf(message, "<p>Cookie from decoder was '%s'</p>\n", value2); + SetToCString(message, "<p>Cookie from decoder was '"); + ConcatCString(message, value2); + ConcatCString(message, "'</p>\n"); free(value2); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message,"</center>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"</div>\n"); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH,0,4098,message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH,0,message); + retval = Send_HTTP_String(request, message); + String_Delete( message ); return retval; } diff --git a/src/Cookies.c b/src/Cookies.c index 9e0f6d1..f4cf36d 100644 --- a/src/Cookies.c +++ b/src/Cookies.c @@ -17,6 +17,8 @@ #include "http_Request.h" #include "http_Cookies.h" +#define STRING_NAMESPACE 1 +#include "SString.h" static const char *rcsid = "$Header$"; @@ -64,34 +66,41 @@ int HTTP_CookieSend(httpRequest *request, const char *expires, int secure) { - char message[8000]; + String *message = String_New(); - sprintf(message, "Set-Cookie: %s=%s", name, value); + SetToCString(message, "Set-Cookie: "); + ConcatCString(message, name); + ConcatCString(message, "="); + ConcatCString(message, value); if(path) { - sprintf(message, "%s; path=%s", message, path); + ConcatCString(message, "; path="); + ConcatCString(message, path); } if(domain) { - sprintf(message,"%s; domain=%s", message, domain); + ConcatCString(message, "; domain="); + ConcatCString(message, domain); } if(expires) { - sprintf(message,"%s; expires=%s", message, expires); + ConcatCString(message, "; expires="); + ConcatCString(message, expires); } if(secure) { - sprintf(message,"%s; secure", message); + ConcatCString(message, "; secure"); } - strcat(message, "\r\n"); + ConcatCString(message, "\r\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); + String_Delete( message ); return 0; } @@ -113,23 +122,26 @@ int HTTP_CookieCancel(httpRequest *request, const char *name, const char *path) { - char message[8000]; + String *message = String_New(); /* Clear the value */ - sprintf(message, "Set-Cookie: %s=", name); + SetToCString(message, "Set-Cookie: "); + ConcatCString(message, name); + ConcatCString(message, "="); if(path) { - sprintf(message, "%s; path=%s", message, path); + ConcatCString(message, "; path="); + ConcatCString(message, path); } /* Pick a date in the past */ - sprintf(message,"%s; expires Sun Sep 17 21:57:45 CEST 2000", message); + ConcatCString(message, "; expires Sun Sep 17 21:57:45 CEST 2000"); + ConcatCString(message, "\r\n"); - strcat(message, "\r\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); + String_Delete( message ); return 0; } @@ -150,22 +162,14 @@ int HTTP_CookieCancel(httpRequest *request, char *HTTP_CookieGet(httpRequest *request, const char *name) { - char *retval; - const char *header; - char *position; - char *copy; - char *start; - + char *retval = NULL; /* Get the cookie header */ - header = HTTP_HeaderValue(request,"Cookie"); - - retval = NULL; + const char *header = HTTP_HeaderValue(request,"Cookie"); if(header) { - copy = Util_Strdup(header); - - position = copy; + char *copy = Util_Strdup(header); + char *position = copy; /* Search for name=value */ while((position = strstr(position, name)) != NULL) @@ -173,7 +177,7 @@ char *HTTP_CookieGet(httpRequest *request, position += strlen(name); if(*position == '=') { - start = position+1; + char *start = position+1; position=strstr(start, ";"); @@ -185,11 +189,9 @@ char *HTTP_CookieGet(httpRequest *request, break; } } - free(copy); } - return retval; } diff --git a/src/Groups.c b/src/Groups.c index de46bad..08a54ad 100644 --- a/src/Groups.c +++ b/src/Groups.c @@ -19,6 +19,8 @@ #include "http_Request.h" #include "http_Content.h" +#include "http_SString.h" + static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusConnect_HTTPD_Groups_c) @@ -96,7 +98,7 @@ int HTTPi_RegisterGroupsPages(void) static int GroupsPage(const cGH *cctkGH, httpRequest *request, void *data) { int retval; - char message[4098]; + String *message = String_New(); int i,j; int ngroups,nvars; cGroup gdata; @@ -105,140 +107,142 @@ static int GroupsPage(const cGH *cctkGH, httpRequest *request, void *data) /* avoid compiler warning about unused parameter */ data = data; - /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); + SendHTTP_OK_Header( request ); - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); + /* Start the page */ + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"<html><head>\n"); + Send_HTTP(request,"<title>Cactus Simulation Group Information</title>\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - /* Start the page */ - strcpy(message,"<HTML><HEAD><TITLE>Cactus Simulation Group Information</TITLE>\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"</head>\n<body>\n"); /* HTTP_Write out the header part. */ - HTTP_ContentHeader(cctkGH,0,strlen(message),message,NULL); + SetHTML_ContentHeader(cctkGH,0,message,NULL); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP_String(request, message); ngroups = CCTK_NumGroups(); - strcpy(message, "<center><h1>Groups and Grid Variables</h1></center>" - "<p>These pages describe the grid variables and groups " - "active in this simulation.</p>"); - retval = HTTP_Write(request, message, strlen(message)); - - sprintf(message,"<p>This simulation contains %d groups, and %d variables, " - "set in %d-space dimensions. Groups for which storage is " - "currently assigned are written in <font color=red>red</font>. " + retval = Send_HTTP(request, "<h1>Groups and Grid Variables</h1>\n" + "<p>These pages describe the grid variables and groups \n" + "active in this simulation.</p>\n"); + + SetToCString(message, + "<p>This simulation contains "); + ConcatDecimal(message, CCTK_NumGroups()); + ConcatCString(message, + " groups, and "); + ConcatDecimal(message, CCTK_NumVars()); + ConcatCString(message, + " variables, " + "set in "); + ConcatDecimal(message, CCTK_MaxDim()); + ConcatCString(message, + "-space dimensions. \nGroups for which storage is currently\n" + "assigned are written in <span class=\"hilite\">red</span>. \n" "The numbers in square brackets are the group and variable indices." - "</p>", - CCTK_NumGroups(),CCTK_NumVars(), - CCTK_MaxDim()); - retval = HTTP_Write(request, message, strlen(message)); + "</p>\n"); + retval = Send_HTTP_String(request, message); - strcpy(message,"<FORM action=\"/Groups.html\" method=\"GET\">\n"); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP(request,"<form action=\"/Groups.html\" method=\"get\">\n"); - strcpy(message,"<center><table width=100%% cellpadding=5 " - "cellspacing=5 BGCOLOR=\"#E9F4D3\">" + retval = Send_HTTP(request,"<div class=\"centered\">\n" + "<table class=\"groups\" width=\"100%\" cellpadding=\"5\" " + "cellspacing=\"5\">\n" "<tr><th>Groups</th><th>Group Properties</th>" - "<th>Variables</th></tr>"); - retval = HTTP_Write(request, message, strlen(message)); + "<th>Variables</th></tr>\n"); for(i=0; i < ngroups; i++) { - strcpy(message,"<tr valign=top halign=left>"); + SetToCString(message,"<tr>"); groupname = CCTK_GroupName(i); if (CCTK_QueryGroupStorageI(cctkGH,i)) { - sprintf(message,"%s <td>[%d] <font color=red>%s</font></td>" - "\n", message, i, groupname); + ConcatCString(message, " <td>["); + ConcatDecimal(message, i); + ConcatCString(message, "] <span class=\"hilite\">"); + ConcatCString(message, groupname); + ConcatCString(message, "</span></td>\n"); } else { - sprintf(message,"%s <td VALIGN=TOP ALIGN=LEFT>[%d] %s</td>\n", - message, i, groupname); - } + ConcatCString(message, " <td>["); + ConcatDecimal(message, i); + ConcatCString(message, "] "); + ConcatCString(message, groupname); + ConcatCString(message, "</td>\n"); + } free(groupname); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); /* Group Description */ - sprintf(message,"<td>"); + SetToCString(message, "<td>"); - if (CCTK_GroupData(i,&gdata)>-1) + if (CCTK_GroupData(i,&gdata) > -1) { switch (CCTK_GroupTypeI(i)) { case CCTK_SCALAR: - strcat(message,"Grid scalar"); + ConcatCString(message,"Grid scalar"); break; case CCTK_ARRAY: - strcat(message,"Grid array"); + ConcatCString(message,"Grid array"); break; case CCTK_GF: - strcat(message,"Grid function"); + ConcatCString(message,"Grid function"); break; } - sprintf(message, "%s %s <br>(%d bytes)", message, - CCTK_VarTypeName(gdata.vartype),CCTK_VarTypeSize(gdata.vartype)); + ConcatCString(message, " " ); + ConcatCString(message, CCTK_VarTypeName(gdata.vartype) ); + ConcatCString(message, " <br />\n("); + ConcatDecimal(message, CCTK_VarTypeSize(gdata.vartype)); + ConcatCString(message, " bytes)"); if (!(CCTK_GroupTypeI(i) == CCTK_SCALAR)) { - sprintf(message,"%s <br>Dimension %d",message,gdata.dim); - sprintf(message, "%s <br>Timelevels %d",message, gdata.numtimelevels); + ConcatCString(message, " <br />\nDimension "); + ConcatDecimal(message, gdata.dim); + ConcatCString(message, " <br />\nTimelevels "); + ConcatDecimal(message, gdata.numtimelevels); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); } - strcpy(message,"</td>"); + Send_HTTP(request,"</td>"); nvars = CCTK_NumVarsInGroupI(i); - strcat(message,"<TD VALIGN=TOP ALIGN=LEFT><DL>"); + SetToCString(message,"<td>"); for(j=CCTK_FirstVarIndexI(i); j < CCTK_FirstVarIndexI(i)+nvars; j++) { - sprintf(message,"%s <DT>[%d] %s\n", message, j, CCTK_VarName(j) ); + ConcatCString(message, "[" ); + ConcatDecimal(message, j); + ConcatCString(message, "] " ); + ConcatCString(message, CCTK_VarName(j) ); + ConcatCString(message, "<br />\n" ); } - strcat(message,"</DL></TD></TR>"); - HTTP_Write(request, message, strlen(message)); + ConcatCString(message,"</td></tr>"); + Send_HTTP_String(request, message); - /* - strcpy(message,"<TD align=center valign=center>"); - if (CCTK_GroupTypeI(i) == CCTK_SCALAR) - { - for(j=CCTK_FirstVarIndexI(i); j < CCTK_FirstVarIndexI(i)+nvars; j++) - { - sprintf(message,"%s " - "<INPUT type=\"checkbox\" name=\"var%d\" %s value=\"1\"><br>", - message,j,watch[j] ? "checked" : "unchecked"); - } - } - else - { - strcat(message," "); - } - sprintf(message,"%s </TD></TR>",message); - HTTP_Write(request, message, strlen(message)); - */ } - strcpy(message,"</TABLE></FORM></center>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"</table></div></form>\n"); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH,0,strlen(message),message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH,0,message); + retval = Send_HTTP_String(request, message); + + String_Delete( message ); return retval; } diff --git a/src/Headers.c b/src/Headers.c index 17cd140..d143f60 100644 --- a/src/Headers.c +++ b/src/Headers.c @@ -42,46 +42,86 @@ struct httpLink ********************* Other Routine Prototypes ********************* ********************************************************************/ -int HTTP_ContentHeader(const cGH *GH, int choice, int len, char *header, char *menu); -int HTTP_ContentFooter(const cGH *GH, int choice, int len, char *footer); /******************************************************************** ********************* Local Data ***************************** ********************************************************************/ -#define TITLE_ARRAY_SIZE 100 - -static const char *cactus_mainheader = -"</HEAD>\n" -"<BODY BGCOLOR=\"#FFFFFF\"" -" link=\"#1B831D\" vlink=\"#768000\" alink=\"#00FF00\">\n" -"<center><A HREF=\"http://www.cactuscode.org/\">" -"<img src=\"/Images/wwwcactuscodeorg.jpg\"" -" alt=\"Cactus\" BORDER=0></A>" -"</A>" -"<table width=70% border=0><tr><td>" -"\n"; +static const char *cactus_styles = +"<style type=\"text/css\">\n" +" body { color: black; background-color: white; }\n" +" h1, h2 { text-align: center; }\n" +" dfn { font-style: italic; }\n" +" td { vertical-align: top; }\n" +" a:link { color: #1B831D; }\n" +" a:visited { color: #768000; }\n" +" a:active { color: green; }\n" +" td.menu { color: black; background-color: #E5FFA2; \n" +" text-align: left; vertical-align: top; width: 20ex; \n" +" font-size: small; }\n" +" td.menu h2 { font-weight: normal; font-size: medium; \n" +" text-align: left; margin-top: 0; } \n" +" td.menu h3 { font-weight: bold; font-size: small; \n" +" margin-top: 1.2em; margin-bottom: 0; } \n" +" td.menu span.simulation_name { font-style: italic; } \n" +" td.menu kbd { font-family: monospace; font-style: normal; } \n" +" .controls td { text-align: left; vertical-align: middle; } \n" +" .params th { text-align: right; } \n" +" .params td { text-align: center; vertical-align: middle; } \n" +" .params td.description { font-size: small; } \n" +" table.groups { background-color: #E9F4D3; } \n" +" .groups td { text-align: left; } \n" +" .paramtable td { text-align: left; vertical-align: middle; } \n" +" .paramtable td.description { font-size: small; } \n" +" .thornparams th { text-align: right; } \n" +" .thorns td { text-align: left; } \n" +" .footer td { font-size: small; vertical-align: top; } \n" +" .footer td.by { text-align: right; } \n" +" .footer img { border: 0; } \n" +" div.banner, div.centered { text-align: center; } \n" +" div.banner table { margin: auto; } \n" +" div.banner img { border: 0; } \n" +" div.centered table { margin: auto; } \n" +" td.authenticate { text-align: center; background-color: #E5FFA2; }\n" +" span.hilite { color: red; } \n" +"</style>\n"; static const char *cactus_footer = -"</table>\n" -"<TABLE WIDTH=100%% BORDER=0>\n" -"<tr><td colspan=2><HR NOSHADE SIZE=1></td></tr>\n" -"<tr><td align=left valign=top>\n" -"<SMALL>\n" -"<A HREF=\"http://www.cactuscode.org\">" -"<IMG SRC=\"/Images/www.gif\" BORDER=0></A><BR>\n" -"</SMALL>\n" -"</TD><TD ALIGN=RIGHT VALIGN=TOP><SMALL>" -"Cactus Web Interface by <A HREF=\"mailto:cactusmaint@cactuscode.org\">The Cactus Team</A><BR>\n" -"<A HREF=\"/About.html\"><i>About this Server</i></A>" -"</SMALL></TD></TR></TABLE>" -"</BODY></HTML>\n"; - +"\n</td></tr>\n" +"\n<tr><td colspan=\"2\">\n" +"\n<table class=\"footer\" width=\"100%\" border=\"0\">\n" +"<tr><td colspan=\"2\"><hr /></td></tr>\n" +"<tr><td>\n" +"<a href=\"http://www.cactuscode.org\">" +"<img src=\"/Images/www.gif\" alt=\"www.CactusCode.org\" /></a>\n" +"</td><td class=\"by\">" +"Cactus Web Interface by \n" +"<a href=\"mailto:cactusmaint@cactuscode.org\">The Cactus Team</a><br />\n" +"<a href=\"/About.html\"><em>About this Server</em></a>\n" +"</td></tr></table>\n" +"</td></tr></table>\n" +"</body></html>\n"; + +static const char * cactus_doctype = +"<?xml version=\"1.0\" encoding=\"ISO-8859-15\"?>\n" +"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" +" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"; /******************************************************************** ********************* External Routines ********************** ********************************************************************/ +#define EMPTYSTRING { '\0' } +#define STRING_NAMESPACE +#include "SString.h" +void SetHTML_HeadHeader( String *header) +{ + SetToCString( header, cactus_styles ); +} +void SetHTML_Doctype( String *header) +{ + SetToCString( header, cactus_doctype ); +} /*@@ @routine HTTP_ContentHeader @date Sat Sep 16 15:22:59 2000 @@ -96,105 +136,100 @@ static const char *cactus_footer = @endhistory @@*/ -int HTTP_ContentHeader(const cGH *GH, int choice, int len, char *header, char *menu) +extern void CCTK_GetRunTitleString( String *s ); + +int SetHTML_ContentHeader(const cGH *GH, int choice, + String *header, const String *menu) { - char title[TITLE_ARRAY_SIZE]; - char parfile[200]; - char currentdate[50]; - char currenttime[50]; - char quicklinks[1524]; + String *title = String_New(); + String *quicklinks = String_New(); + char parfile[200] = EMPTYSTRING; + char currentdate[50] = EMPTYSTRING; + char currenttime[50] = EMPTYSTRING; struct httpLink *link; char *file; char *dir; + Truncate( header,0); - /* avoid compiler warning about unused parameter */ - len = len; + if (choice == 0) + { + ConcatCString( header, + "<table cellpadding=\"10\" width=\"100%\" border=\"0\">\n" + "<tr>\n" + "<td class=\"menu\" valign=\"top\">\n" + "<h2><a href=\"/\">Master Run Page</a></h2>\n"); + } if(ContentLinks) { - strcpy(quicklinks,"<dl><dt><b>Options:</b>"); + SetToCString( quicklinks,"<h3>Options:</h3>\n"); for(link = ContentLinks; link; link=link->next) { - sprintf(quicklinks, - "%s<dt> <A HREF=\"%s\">%s</a></dt>\n", - quicklinks, link->URL, link->name); - + ConcatCString(quicklinks, "<a href=\""); + ConcatCString(quicklinks, link->URL); + ConcatCString(quicklinks, "\">"); + ConcatCString(quicklinks, link->name); + ConcatCString(quicklinks, "</a><br />\n"); } - - sprintf(quicklinks,"%s</dl>\n",quicklinks); } if (choice == 0) { /* Find strings needed for nonmain-page headers */ - CCTK_RunTitle(TITLE_ARRAY_SIZE,title); - CCTK_ParameterFilename(200,parfile); + CCTK_GetRunTitleString(title); + CCTK_ParameterFilename(sizeof(parfile),parfile); Util_SplitFilename(&dir,&file,parfile); - Util_CurrentDate(50,currentdate); - Util_CurrentTime(50,currenttime); + Util_CurrentDate(sizeof(currentdate),currentdate); + Util_CurrentTime(sizeof(currenttime),currenttime); /* Build the header */ - sprintf( header, - "</HEAD>\n" - "<BODY BGCOLOR=\"#FFFFFF\" link=\"#1B831D\" " - "vlink=\"#768000\" alink=\"#00FF00\">\n" - "<center>\n" - "<table cellpadding=10 width=100%% border=0>\n" - "<tr>\n" - "<td bgcolor=#E5FFA2 valign=top align=left width=20%%>\n"); - strcat(header, "<A HREF=\"/\">Master Run Page</A>\n"); - sprintf(header,"%s\n" - "<small>\n<dl>\n" - "<dt><b>Environment:</b>\n" - "<dt>Time: %s\n" - "<dt>Date: %s\n" - "</dl></small>\n", - header,currenttime,currentdate); - sprintf(header, - "%s <small><dl>\n" - "<dt><b>Simulation:</b>\n" - "<dt><i>%s</i>\n" - "<dt><tt>%s</tt>\n" - "<dt>Iteration: %d\n" - "<dt>Physical time: %4.2f\n" - "</dl>\n" - ,header,title,file, - GH ? GH->cctk_iteration : 0 , GH ? GH->cctk_time : 0); + ConcatCString( header, + "\n" + "<h3>Environment:</h3>\n" + "Time: "); + ConcatCString( header, currenttime ); + ConcatCString( header, + "<br />\n" + "Date: " ); + ConcatCString( header, currentdate ); + ConcatCString( header, + "<br />\n" ); + ConcatCString( header, + "<h3>Simulation:</h3>\n" + "<span class=\"simulation_name\">"); + Concat( header, title ); + ConcatCString( header, + "</span><br />\n" + "<kbd>"); + ConcatCString( header, file ); + ConcatCString( header, + "</kbd><br />\n" + "Iteration: "); + ConcatDecimal( header, GH ? GH->cctk_iteration : 0 ); + ConcatCString( header, + "<br />\nPhysical time: "); + ConcatFormattedDouble( header, 4, 2, GH ? GH->cctk_time : 0 ); + ConcatCString( header, + "<br />\n"); if (ContentLinks) { - strcat(header,quicklinks); + Concat( header, quicklinks); } - strcat(header,"</small>\n"); if (menu) { - strcat(header,"<dl><small>\n"); - strcat(header,menu); - strcat(header,"</dl></small>\n"); + Concat( header, menu); } - /* Online links */ - /* - sprintf(header,"%s\n" - "<small><dl>" - "<dt><b>On-Line:</b>\n" - "<dt><A HREF=\"http://www.cactuscode.org\" TARGET=\"newpage\">Cactus Homepage</A>\n" - "<dt><A HREF=\"http://www.cactuscode.org/Documentation/UsersGuide_html/\" TARGET=\"newpage\">Users Guide</A>\n" - "<dt><A HREF=\"mailto:cactusmaint@cactuscode.org\">Cactus Helpdesk</A>\n" - "</dl></small>\n", - header,currenttime,currentdate); - */ - - strcat(header,"</td>\n<td valign=top>\n"); - } - else - { - sprintf(header,"%s",cactus_mainheader); + ConcatCString( header, + "</td>\n<td>\n\n"); } - return strlen(header); + String_Delete( quicklinks ); + String_Delete( title ); + return Length(header); } @@ -212,13 +247,13 @@ int HTTP_ContentHeader(const cGH *GH, int choice, int len, char *header, char *m @endhistory @@*/ -int HTTP_ContentFooter(const cGH *GH, int choice, int len, char *footer) +int SetHTML_ContentFooter(const cGH *GH, int choice, String *footer) { /* avoid compiler warnings about unused parameters */ GH = GH; choice = choice; - len = len; - strcpy(footer,cactus_footer); - return strlen(footer); + Truncate( footer, 0 ); + SetToCString(footer,cactus_footer); + return Length(footer); } diff --git a/src/Parameters.c b/src/Parameters.c index f9e2c5a..17cc3d5 100644 --- a/src/Parameters.c +++ b/src/Parameters.c @@ -34,6 +34,9 @@ #include "cctk_Arguments.h" #include "cctk_Parameters.h" +#define STRING_NAMESPACE 1 +#include "SStringHTML.h" + static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusConnect_HTTPD_Parameters_c) @@ -144,6 +147,34 @@ int HTTPi_RegisterParameterPages(void) ********************************************************************/ +static void +SendHTTP_Redirect_Header( httpRequest *request ) +{ + /* Now redirect the browser to the normal page */ + /* Status message */ + if(request->http_major_version < 1 || + (request->http_major_version == 1 && request->http_minor_version < 1)) + { + /* Older browsers don't understand 303 */ + Send_HTTP(request,"HTTP/1.0 302 Found\r\n"); + } + else + { + Send_HTTP(request,"HTTP/1.0 303 See Other\r\n"); + } +} + +static void +SendHTTP_Uauthorized_Header( httpRequest *request ) +{ + Send_HTTP(request,"HTTP/1.0 401 Unauthorized\r\n"); + + Send_HTTP(request,"WWW-Authenticate: Basic realm=\"foo\"\r\n"); + + Send_HTTP(request,"Content-Type: text/html\r\n\r\n"); + +} + /****************************************************************************** ***************************** Parameter Pages ******************************** ******************************************************************************/ @@ -168,53 +199,46 @@ int HTTPi_RegisterParameterPages(void) @@*/ static int MainParameterPage(const cGH *cctkGH, httpRequest *request, void *data) { - int retval; - char message[4098]; + int retval = -1; + String *message = String_New(); int i; - const char *thorn; + const char *thorn = NULL; /* avoid compiler warning about unused parameter */ data = data; - /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); - - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + SendHTTP_OK_Header( request ); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - strcpy(message, "<HTML><HEAD><TITLE>Cactus Parameters Request</TITLE>\n"); - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"<HTML>\n"); - HTTP_Write(request, message, strlen(message)); - - HTTP_ContentHeader(cctkGH,0,4098,message,NULL); - HTTP_Write(request, message, strlen(message)); - - strcpy(message, "<center>"); - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "<center><H1>Check/Modify Parameters</H1></center>\n" - "</center><p>From this page you can check the values \n" - "of all parameters for the \n" - "simulation, and modify any parameters which have been designated as <i>steerable</i></p>\n" - "<p>Parameters can be viewed for all <i>Active Thorns</i>, that is, for thorns which \n" - "have been activated in the parameter file for the simulation. \n" - "Select one of the active thorns for this simulation from the list below to \n" - "view all of its parameters</p>\n" - "<p>Steerable parameters can be identified by the presence of a form input box, \n" - "to change the value of a parameter, simply edit the value in the box and press \n" - " the submit button to register the new values.</p><center>\n" - "<table cellspacing=5 cellpadding=5 border=0\n>" - "<tr><th>Thorn Name</th><th>Implementation</th></TR>\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "<html><head><title>Cactus Parameters Request</title>\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); + Truncate( message, 0 ); + + Send_HTTP(request, "\n</head>\n<body>\n"); + + SetHTML_ContentHeader(cctkGH,0,message,NULL); + Send_HTTP_String(request, message); + + Send_HTTP(request, + "<h1>Check/Modify Parameters</h1>\n" + "<p>From this page you can check the values of all parameters for \n" + "the simulation, and modify any parameters which have been \n" + "designated as <i>steerable</i></p>\n" + "<p>Parameters can be viewed for all <i>Active Thorns</i>, that is,\n" + "for thorns which have been activated in the parameter file for the\n" + " simulation. \n" + "Select one of the active thorns for this simulation from the list \n" + "below to view all of its parameters</p>\n" + "<p>Steerable parameters can be identified by the presence of a \n" + "form input box, to change the value of a parameter, simply edit \n" + "the value in the box and press the submit button to register the \n" + "new values.</p>\n" + "<div class=\"centered\">\n" + "<table cellspacing=\"5\" cellpadding=\"5\">\n" + "<tr><th>Thorn Name</th><th>Implementation</th></tr>\n"); for (i = 0; i < CCTK_NumCompiledThorns (); i++) { @@ -222,25 +246,26 @@ static int MainParameterPage(const cGH *cctkGH, httpRequest *request, void *data if (CCTK_IsThornActive (thorn)) { - sprintf(message, - "<TR>\n" - "<TD VALIGN=TOP ALIGN=CENTER><A HREF=\"/Parameters/%s/\">%s</A></td>\n" - "<TD VALIGN=TOP ALIGN=CENTER>%s</TD>\n" - "</TR>\n", - thorn, thorn,CCTK_ThornImplementation(thorn)); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<tr>\n<td><a href=\"/Parameters/"); + ConcatCString(message, thorn); + ConcatCString(message, "/\">"); + ConcatCString(message, thorn); + ConcatCString(message, "</a></td>\n<td>"); + ConcatCString(message, CCTK_ThornImplementation(thorn)); + ConcatCString(message, "</td>\n</tr>\n"); + Send_HTTP_String(request, message); } } - strcpy(message,"</table></center>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"</table></div>"); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH, 0, 4098, message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH, 0, message); + retval = Send_HTTP_String(request, message); + String_Delete( message ); return retval; } @@ -270,15 +295,16 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat { int retval=0; int i; - char message[4098]; - char menu[4098]; + String * message = String_New(); + String * menu = String_New(); + String * temp = String_New(); const char *thorn, *menuthorn; int first; const cParamData *pData; t_range *range; char *value; const httpArg *argument; - char user[USER_LENGTH+1]; + char user[USER_LENGTH+1] = EMPTYSTRING; int notauthorised; int readonly; @@ -307,62 +333,24 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat while((argument = HTTP_ArgumentWalk(request, first)) != NULL) { first = 0; - fprintf(stderr, "Setting %s::%s to %s\n", thorn, argument->arg, argument->value); + fprintf(stderr, "Setting %s::%s to %s\n", thorn, argument->arg, + argument->value); HTTP_SteerQueue(thorn, argument->arg, argument->value); } - - /* Now redirect the browser to the normal page */ - /* Status message */ - if(request->http_major_version < 1 || - (request->http_major_version == 1 && request->http_minor_version < 1)) - { - /* Older browsers don't understand 303 */ - strcpy(message,"HTTP/1.0 302 Found\r\n"); - } - else - { - strcpy(message,"HTTP/1.0 303 See Other\r\n"); - } - - sprintf(message, "%sLocation: /Parameters/%s/\r\n\r\n", message, thorn); - - HTTP_Write(request, message, strlen(message)); } - else - { - /* Redirect the browser to the normal page */ - /* Status message */ - if(request->http_major_version < 1 || - (request->http_major_version == 1 && request->http_minor_version < 1)) - { - /* Older browsers don't understand 303 */ - strcpy(message,"HTTP/1.0 302 Found\r\n"); - } - else - { - strcpy(message,"HTTP/1.0 303 See Other\r\n"); - } + SendHTTP_Redirect_Header( request ); - sprintf(message, "%sLocation: /Parameters/%s/\r\n\r\n", message, thorn); + ConcatCString(message, "Location: /Parameters/"); + ConcatCString(message, thorn); + ConcatCString(message, "/\r\n\r\n"); - HTTP_Write(request, message, strlen(message)); - } + Send_HTTP_String(request, message); } else { - strcpy(message,"HTTP/1.0 401 Unauthorized\r\n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"WWW-Authenticate: Basic realm=\"foo\"\r\n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + SendHTTP_Uauthorized_Header( request ); - HTTP_Write(request, notauthorized_page, strlen(notauthorized_page)); + Send_HTTP(request, notauthorized_page); } } @@ -370,24 +358,27 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat { /* Display the page. */ /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); - - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); + SendHTTP_OK_Header( request ); - HTTP_Write(request, message, strlen(message)); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - sprintf(message, - "<HTML><HEAD><TITLE>Cactus Parameters Request : %s</TITLE></HEAD>\n", thorn); + SetToCString(message, "<html><head>\n<title>Cactus Parameters Request : "); + ConcatCString(message, thorn); + ConcatCString(message, "</title>\n"); + Send_HTTP_String(request, message ); + + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); + Truncate( message, 0 ); + + Send_HTTP(request, "</head>\n<body>\n"); - HTTP_Write(request, message, strlen(message)); if (CCTK_NumCompiledThorns()>0) { - strcpy(menu,"<DT><B>Parameters:</B>\n"); + SetToCString(menu, "<h3>Parameters:</h3>\n"); } /* Menu for this page */ for (i = 0; i < CCTK_NumCompiledThorns (); i++) @@ -395,47 +386,54 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat menuthorn = CCTK_CompiledThorn (i); if (CCTK_IsThornActive (menuthorn)) { - sprintf(menu, - "%s<DT> <A HREF=\"/Parameters/%s/\">%s</A>\n", - menu,menuthorn, menuthorn); + ConcatCString(menu, " <a href=\"/Parameters/"); + ConcatCString(menu, menuthorn); + ConcatCString(menu, "/\">"); + ConcatCString(menu, menuthorn); + ConcatCString(menu, "</a><br />\n"); } } - HTTP_ContentHeader(cctkGH,0,4098,message,menu); - strcat(message,"<BODY>"); - HTTP_Write(request, message, strlen(message)); + SetHTML_ContentHeader(cctkGH,0,message,menu); + Send_HTTP_String(request, message); if (!CCTK_IsThornActive(thorn)) { - sprintf(message,"<B> Thorn %s is not active !!!</B><BR>\n",thorn); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<strong> Thorn "); + ConcatCString(message, thorn); + ConcatCString(message, " is not active !!!</strong><br />\n"); + Send_HTTP_String(request, message); } else { /* Send table of available parameters for given thorn */ /* Steerable parameters can be edited in a FORM. */ - sprintf(message, - "<center><H1>Check/Modify Parameters</H1>" - "<H2>Thorn %s</H2></center>\n", - thorn); - strcat(message, - "<p>Parameters in Cactus can be either <i>fixed</i> or <i>steerable</i>. " - "Steerable parameters are those which can be modified during a " - "simulation" - "To change steerable parameters, edit the values and press \n" - " the submit button." - "Before applying the new parameter value, Cactus will check that" - " the parameter lies in the allowed range. Note that there" - " is currently no log of parameters which have been modified.</p>\n" - "<p>The tables below show the parameter name, current value and description." - "The default value of each parameter is shown in brackets at the end of the description.</p>" - "<center>\n"); - - HTTP_Write(request, message, strlen(message)); + SetToCString(message, + "<h1>Check/Modify Parameters</h1>\n" + "<h2>Thorn "); + ConcatCString(message, thorn); + ConcatCString(message, + "</h2>\n"); + ConcatCString(message, + "<p>Parameters in Cactus can be either <dfn>fixed</dfn> or <dfn>steerable</dfn>. \n" + "Steerable parameters are those which can be modified during a simulation.\n" + "To change steerable parameters, edit the values and press " + " the submit button.\n" + "Before applying the new parameter value, Cactus will check that the\n" + "parameter lies in the allowed range. \nNote that there" + " is currently no log of parameters which have been modified.</p>\n" + "<p>The tables below show the parameter name, current value and description.\n" + "The default value of each parameter is shown in brackets at the end of the description.</p>" + "\n"); + + Send_HTTP_String(request, message); + Send_HTTP(request, "<div class=\"centered\">\n"); if(!readonly ) { - sprintf(message,"<FORM ACTION=\"/Parameters/%s/\">",thorn); - HTTP_Write(request, message, strlen(message)); + SetToCString(message,"<form action=\"/Parameters/"); + ConcatCString(message, thorn); + ConcatCString(message, "/\">\n"); + Send_HTTP_String(request, message); } /* Walk through all steerable parameters of given implementation. */ @@ -444,7 +442,7 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat while(CCTK_ParameterWalk(first, thorn, NULL, &pData) == 0) { first = 0; - strcpy(message,""); + Truncate(message,0); value = CCTK_ParameterValString (pData->name, pData->thorn); if(value) @@ -454,16 +452,18 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat if (nsteerable == 0) { - strcat(message,"<h2>Steerable Parameters</h2>"); + ConcatCString(message,"<h2>Steerable Parameters</h2>\n"); if (readonly) { - strcat(message,"<p><i>The following parameters are steerable, " - "but you do not have authorisation to change them. " + ConcatCString(message, + "<p><em>The following parameters are steerable, " + "but you do not have authorisation to change them. \n" "To change parameters you must first register on the " "<a href=\"/control.html\">Simulation Control Page</a>." - "</i></p>"); + "</em></p>\n"); } - strcat(message,"<table cellpadding=5 cellspacing=5>"); + ConcatCString(message, + "<table class=\"paramtable\" cellpadding=\"5\" cellspacing=\"5\">\n"); } nsteerable++; @@ -474,102 +474,137 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat /* Steerable boolean */ param_bool = *((const CCTK_INT *)CCTK_ParameterGet(pData->name,thorn,¶m_type)); - sprintf(message, - "%s<TR>\n" - "<TD ALIGN=LEFT VALIGN=CENTER>" - "<A HREF=\"/Parameters/%s/%s\">%s</A></TD>\n" - "<TD ALIGN=LEFT VALIGN=CENTER>" - "Yes <INPUT TYPE=\"RADIO\" NAME=\"%s\" %s VALUE=\"1\">" + ConcatCString(message, "<tr>\n<td><a href=\"/Parameters/"); + ConcatCString(message, pData->thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, "</a></td>\n" + "<td>" + "Yes \n<input type=\"radio\" name=\""); + ConcatCString(message, pData->name); + ConcatCString(message, "\" "); + ConcatCString(message, param_bool ? "checked=\"checked\"" : ""); + ConcatCString(message, " value=\"1\" />" " " - "No <INPUT type=\"RADIO\" name=\"%s\" %s VALUE=\"0\">" - "</TD>\n" - "<TD><SMALL>%s (%s)</SMALL></TD>\n" - "</TR>\n", - message,pData->thorn,pData->name, - pData->name,pData->name, - param_bool ? "checked" : "", pData->name, - param_bool ? "" : "checked",pData->description,pData->defval); + "No \n<input type=\"radio\" name=\""); + ConcatCString(message, pData->name); + ConcatCString(message, "\" "); + ConcatCString(message, param_bool ? "" : "checked=\"checked\""); + ConcatCString(message, " value=\"0\" />" + "</td>\n" + "<td class=\"description\">"); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp ); + ConcatCString(message, " ("); + ConcatCString(message, pData->defval); + ConcatCString(message, ")</td>\n" + "</tr>\n"); } else if (pData->type == PARAMETER_KEYWORD) { /* Steerable keyword */ CCTK_ParameterGet(pData->name,thorn,¶m_type); - sprintf(message,"%s<TR>\n" - "<TD ALIGN=LEFT VALIGN=CENTER>" - "<A HREF=\"/Parameters/%s/%s\">%s</A></TD>\n" - "<TD ALIGN=LEFT VALIGN=CENTER>\n", - message,pData->thorn,pData->name,pData->name); - sprintf(message,"%s <SELECT name=%s size=1>\n", - message,pData->name); + ConcatCString(message,"<tr>\n<td><a href=\"/Parameters/"); + ConcatCString(message, pData->thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, "</a></td>\n"); + ConcatCString(message,"<td> <select name=\""); + ConcatCString(message, pData->name); + ConcatCString(message, "\" size=\"1\">\n"); for(range = pData->range; range ; range = range->next) { if (CCTK_Equals(value,range->range)) { - sprintf(message,"%s<OPTION SELECTED>%s\n", - message, range->range); + ConcatCString(message, "<option selected>"); + ConcatCString(message, range->range); + ConcatCString(message, "\n"); } else { - sprintf(message,"%s<OPTION>%s\n", - message,range->range); + ConcatCString(message, "<option>"); + ConcatCString(message, range->range); + ConcatCString(message, "\n"); } } - strcat(message,"</SELECT>\n"); - sprintf(message,"%s</TD>\n" - "<TD><SMALL>%s (%s)</SMALL></TD>\n" - "</TR>\n", - message,pData->description,pData->defval); + ConcatCString(message,"</select>\n"); + ConcatCString(message,"</td>\n<td class=\"description\">"); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, " ("); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, ")</td>\n</tr>\n"); } else { /* Steerable nonboolean */ - sprintf(message, - "%s<TR>\n" - "<TD align=left valign=center>" - "<A HREF=\"/Parameters/%s/%s\">%s</A></TD>\n" - "<TD align=left valign=center>" - "<INPUT TYPE=TEXT NAME=\"%s\" VALUE=\"%s\"></TD>\n" - "<TD><SMALL>%s (%s)</SMALL></TD>\n</TR>\n", - message, pData->thorn, pData->name, - pData->name, pData->name, - value, pData->description,pData->defval); + ConcatCString(message, "<tr>\n<td><a href=\"/Parameters/"); + ConcatCString(message, pData->thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, "</a></td>\n" + "<td><input type=\"text\" name=\""); + ConcatCString(message, pData->name); + ConcatCString(message, "\" value=\""); + ConcatCString(message, value); + ConcatCString(message, "\" /></td>\n" + "<td class=\"description\">"); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, " ("); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, ")</td>\n</tr>\n"); } } else { /* Steerable but no authority */ - sprintf(message, - "%s<TR><TD align=left valign=center>" - "<A HREF=\"/Parameters/%s/%s\">%s</A></TD>\n" - "<TD align=left valign=center>%s</TD><TD>" - "<SMALL>%s (%s)</SMALL></TD></TR>\n", - message, pData->thorn, pData->name, - pData->name, value, pData->description,pData->defval); + ConcatCString(message, "<tr><td><a href=\"/Parameters/"); + ConcatCString(message, pData->thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, "</a></td>\n<td>"); + ConcatCString(message, value); + ConcatCString(message, "</td><td class=\"description\">"); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, " ("); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, ")</td></tr>\n"); } } free (value); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); } if (nsteerable>0) { - strcpy(message, "</TABLE>\n"); + Send_HTTP(request, "</table>\n"); } else { - strcpy(message, "<P>This thorn has no steerable parameters.</P>\n"); + Send_HTTP(request, "<p>This thorn has no steerable parameters.</p>\n"); } - HTTP_Write(request, message, strlen(message)); if(!readonly && nsteerable>0) { - strcpy(message, - "<INPUT TYPE=SUBMIT VALUE=\"Update all parameters\">\n" - "</FORM>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "<input type=\"submit\" value=\"Update all parameters\" />\n" + "</form>\n"); } @@ -579,7 +614,7 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat while(CCTK_ParameterWalk(first, thorn, NULL, &pData) == 0) { first = 0; - strcpy(message,""); + Truncate(message,0); value = CCTK_ParameterValString (pData->name, pData->thorn); if(value) @@ -589,8 +624,8 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat if (nfixed == 0) { - strcat(message,"<h2>Fixed Parameters</h2>" - "<table cellpadding=5 cellspacing=5>"); + ConcatCString(message,"<h2>Fixed Parameters</h2>\n" + "<table class=\"paramtable\" cellpadding=\"5\" cellspacing=\"5\">"); } nfixed++; @@ -601,51 +636,54 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat strcmp(pData->name,"encryption_scheme"))) { - sprintf(message, - "%s<TR>\n" - "<TD align=left valign=center>" - "<A HREF=\"/Parameters/%s/%s\">%s</A></TD>\n" - "<TD>%s</TD>\n" - "<TD><SMALL>%s (%s)</SMALL></TD>\n" - "</TR>\n", - message, pData->thorn, pData->name, - pData->name, value, pData->description,pData->defval); + ConcatCString(message, "<tr>\n<td><a href=\"/Parameters/"); + ConcatCString(message, pData->thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, "</a></td>\n" + "<td>"); + ConcatCString(message, value); + ConcatCString(message, "</td>\n<td class=\"description\">"); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, " ("); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, ")</td>\n</tr>\n"); } } free(value); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); } if (nfixed>0) { - strcpy(message, "</TABLE>\n"); + Send_HTTP(request, "</table>\n"); } else { - strcpy(message, "<p>This thorn has no fixed parameters.</p>\n"); + Send_HTTP(request, "<p>This thorn has no fixed parameters.</p>\n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "</div>\n"); } - strcpy(message,"</center>"); - - HTTP_Write(request, message, strlen(message)); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH, 0, 4098, message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH, 0, message); + retval = Send_HTTP_String(request, message); } /* n_arguments > 0 */ - + String_Delete( message ); + String_Delete( menu ); + String_Delete( temp ); return retval; } - - - /*@@ @routine ParameterPage @date Thu Sep 21 15:13:55 2000 @@ -664,25 +702,19 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat static int ParameterPage(const cGH *cctkGH, httpRequest *request, void *data) { int retval=0; - char message[10000]; - char menu[10000]; + String * message = String_New(); + String * menu = String_New(); + String * temp = String_New(); int first; - const cParamData *pData; + const cParamData *pData = (cParamData *)data; const cParamData *pDataWalk=NULL; t_range *range; char *value; const httpArg *argument; - char user[USER_LENGTH+1]; - - int notauthorised; - int readonly; - - - pData = (cParamData *)data; - - notauthorised = HTTP_AuthenticateBasic(request, "user", user, USER_LENGTH); - - readonly = notauthorised; + char user[USER_LENGTH+1] = EMPTYSTRING; + int notauthorised = HTTP_AuthenticateBasic(request, "user", user, + USER_LENGTH); + int readonly = notauthorised; if(request->n_arguments > 0) { @@ -697,84 +729,46 @@ static int ParameterPage(const cGH *cctkGH, httpRequest *request, void *data) while((argument = HTTP_ArgumentWalk(request, first)) != NULL) { first = 0; - fprintf(stderr, "Setting %s::%s to %s\n", pData->thorn, argument->arg, argument->value); + fprintf(stderr, "Setting %s::%s to %s\n", pData->thorn, + argument->arg, argument->value); HTTP_SteerQueue(pData->thorn, argument->arg, argument->value); } - - /* Now redirect the browser to the normal page */ - /* Status message */ - if(request->http_major_version < 1 || - (request->http_major_version == 1 && request->http_minor_version < 1)) - { - /* Older browsers don't understand 303 */ - strcpy(message,"HTTP/1.0 302 Found\r\n"); - } - else - { - strcpy(message,"HTTP/1.0 303 See Other\r\n"); - } - - sprintf(message, "%sLocation: /Parameters/%s/\r\n\r\n", message, pData->thorn); - - HTTP_Write(request, message, strlen(message)); } - else - { - /* Redirect the browser to the normal page */ - /* Status message */ - if(request->http_major_version < 1 || - (request->http_major_version == 1 && request->http_minor_version < 1)) - { - /* Older browsers don't understand 303 */ - strcpy(message,"HTTP/1.0 302 Found\r\n"); - } - else - { - strcpy(message,"HTTP/1.0 303 See Other\r\n"); - } - - sprintf(message, "%sLocation: /Parameters/%s/\r\n\r\n", message, pData->thorn); + SendHTTP_Redirect_Header( request ); + ConcatCString(message, "Location: /Parameters/"); + ConcatCString(message, pData->thorn); + ConcatCString(message, "/\r\n\r\n"); - HTTP_Write(request, message, strlen(message)); - } + Send_HTTP_String(request, message); } else { - strcpy(message,"HTTP/1.0 401 Unauthorized\r\n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"WWW-Authenticate: Basic realm=\"foo\"\r\n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + SendHTTP_Uauthorized_Header( request ); - HTTP_Write(request, notauthorized_page, strlen(notauthorized_page)); + Send_HTTP(request, notauthorized_page); } - } else { /* Display the page. */ - /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); + SendHTTP_OK_Header( request ); - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); + /* Start the page */ + Send_HTTP(request, "<html><head>\n"); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<title>Cactus Parameter Request : "); + ConcatCString(message, pData->name); + ConcatCString(message, "</title>\n"); - /* Start the page */ - sprintf(message, - "<HTML><HEAD><TITLE>Cactus Parameter Request : %s</TITLE>" - "</HEAD>\n", pData->name); + Send_HTTP_String(request, message); - HTTP_Write(request, message, strlen(message)); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); + Truncate( message, 0 ); + + Send_HTTP(request,"</head>\n<body>\n"); /* Menu for this page */ @@ -783,26 +777,39 @@ static int ParameterPage(const cGH *cctkGH, httpRequest *request, void *data) { if (first==1) { - sprintf(menu,"<DT><B>%s:</B>\n",pDataWalk->thorn); + ConcatCString(menu,"<h3>"); + ConcatCString(menu, pDataWalk->thorn); + ConcatCString(menu, ":</h3>\n"); } first = 0; - sprintf(menu, - "%s <DT> <A HREF=\"/Parameters/%s/%s\">%s</A>\n", - menu,pDataWalk->thorn,pDataWalk->name,pDataWalk->name); + ConcatCString(menu, " <a href=\"/Parameters/"); + ConcatCString(menu, pDataWalk->thorn); + ConcatCString(menu, "/"); + ConcatCString(menu, pDataWalk->name); + ConcatCString(menu, "\">"); + ConcatCString(menu, pDataWalk->name); + ConcatCString(menu, "</a><br />\n"); } - HTTP_ContentHeader(cctkGH,0,4098,message,menu); - HTTP_Write(request, message, strlen(message)); - - sprintf(message,"<CENTER><H1>%s: %s</H1></CENTER>\n",pData->thorn,pData->name); - HTTP_Write(request, message, strlen(message)); - - sprintf(message, - "<CENTER><P>Return to all parameters for this " - "<A HREF=\"Parameters/%s\">thorn</A>.</P></CENTER> ", - CCTK_ThornImplementation(pData->thorn)); - - HTTP_Write(request, message, strlen(message)); + SetHTML_ContentHeader(cctkGH,0,message,menu); + Send_HTTP_String(request, message); + + SetToCString(message,"<h1>"); + ConcatCString(message, pData->thorn); + ConcatCString(message, ": "); + ConcatCString(message, pData->name); + ConcatCString(message, "</h1>\n"); + Send_HTTP_String(request, message); + + SetToCString(message, + "<div class=\"centered\">Return to all parameters for this \n" + "<a href=\"Parameters/"); + ConcatCString(message, + CCTK_ThornImplementation(pData->thorn)); + ConcatCString(message, + "\">thorn</a>.</div> "); + + Send_HTTP_String(request, message); value = CCTK_ParameterValString (pData->name, pData->thorn); @@ -813,155 +820,150 @@ static int ParameterPage(const cGH *cctkGH, httpRequest *request, void *data) strcmp(pData->name,"encryption_scheme"))) { - sprintf(message,"<CENTER><TABLE CELLPADDING=5 CELLSPACING=5 " - " BORDER=1 NOSHADE>\n" - "<TR>\n" - "<TD ALIGN=RIGHT VALIGN=TOP><B>Name:</B></TD>\n" - "<TD>%s</TD>\n" - "</TR>\n" - "<TR>\n" - "<TD ALIGN=RIGHT VALIGN=TOP><B>Thorn:</B></TD>\n" - "<TD>%s</TD>\n" - "</TR>\n" - "<TR>\n" - "<TD ALIGN=RIGHT VALIGN=TOP><B>Implementation:</B></TD>\n" - "<TD>%s</TD>\n" - "</TR>\n" - "<TR>\n" - "<TD ALIGN=RIGHT VALIGN=TOP><B>Current value:</B></TD>\n" - "<TD>%s</TD>\n" - "</TR>" - "<TR>\n" - "<TD ALIGN=RIGHT VALIGN=TOP><B>Description:</B></TD>\n" - "<TD>%s</TD>\n" - "</TR>" - "<TR>" - "<TD ALIGN=RIGHT VALIGN=TOP><B>Default:</B></TD>\n" - "<TD>%s</TD>\n" - "</TR>", - pData->name,pData->thorn,CCTK_ThornImplementation(pData->thorn), - value,pData->description,pData->defval); - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"<TR>\n<TD ALIGN=RIGHT VALIGN=TOP>\n" - "<B>Steerable:</B></TD>\n<TD>"); + SetToCString(message,"<div class=\"centered\">\n" + "<table class=\"thornparams\" cellpadding=\"5\" cellspacing=\"5\" " + " border=\"1\">\n" ); + ConcatCString(message, "<tr>\n<th>Name:</th>\n<td>"); + ConcatCString(message, pData->name); + ConcatCString(message, "</td>\n</tr>\n" ); + ConcatCString(message, "<tr>\n<th>Thorn:</th>\n<td>"); + ConcatCString(message, pData->thorn); + ConcatCString(message, "</td>\n</tr>\n" ); + ConcatCString(message, "<tr>\n<th>Implementation:</th>\n<td>"); + ConcatCString(message, CCTK_ThornImplementation(pData->thorn)); + ConcatCString(message, "</td>\n</tr>\n" ); + ConcatCString(message, "<tr>\n<th>Current value:</th>\n<td>"); + ConcatCString(message, value); + ConcatCString(message, "</td>\n</tr>\n" ); + ConcatCString(message, "<tr>\n<th>Description::</th>\n<td>"); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, "</td>\n</tr>\n" ); + ConcatCString(message, "<tr>\n<th>Default:::</th>\n<td>"); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, "</td>\n</tr>"); + Send_HTTP_String(request, message); + SetToCString(message,"<tr>\n<th>Steerable:</th>\n<td>"); switch(pData->steerable) { case CCTK_STEERABLE_ALWAYS : - strcat(message,"Always"); + ConcatCString(message,"Always"); break; case CCTK_STEERABLE_NEVER : - strcat(message,"Never"); + ConcatCString(message,"Never"); break; case CCTK_STEERABLE_RECOVER : - strcat(message,"Recovery"); + ConcatCString(message,"Recovery"); break; default : - strcat(message,"Not matched"); + ConcatCString(message,"Not matched"); } - strcat(message,"</TD>\n</TR>\n"); - HTTP_Write(request, message, strlen(message)); + ConcatCString(message,"</td>\n</tr>\n"); + Send_HTTP_String(request, message); - strcpy(message,"<TR>\n" - "<TD ALIGN=RIGHT VALIGN=TOP><B>Type:</B></TD>\n<TD>\n"); + SetToCString(message,"<tr>\n" + "<th>Type:</th>\n<td>"); switch(pData->type) { case PARAMETER_BOOLEAN : - strcat(message,"Boolean"); + ConcatCString(message,"Boolean"); break; case PARAMETER_REAL : - strcat(message,"Real"); + ConcatCString(message,"Real"); break; case PARAMETER_INTEGER : - strcat(message,"Integer"); + ConcatCString(message,"Integer"); break; case PARAMETER_SENTENCE : - strcat(message,"Sentence"); + ConcatCString(message,"Sentence"); break; case PARAMETER_STRING : - strcat(message,"String"); + ConcatCString(message,"String"); break; case PARAMETER_KEYWORD : - strcat(message,"Keyword"); + ConcatCString(message,"Keyword"); break; default : - strcat(message,"Not matched"); + ConcatCString(message,"Not matched"); } - strcat(message,"</TD>\n</TR>\n"); + ConcatCString(message,"</td>\n</tr>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message,"<TR><TD ALIGN=RIGHT VALIGN=TOP><B>Scope:</B></TD><TD>"); + SetToCString(message,"<tr><th>Scope:</th><td>"); switch(pData->scope) { case SCOPE_GLOBAL : - strcat(message,"Global</TD></TR>"); + ConcatCString(message,"Global</td></tr>\n"); break; case SCOPE_RESTRICTED : - strcat(message,"Restricted</TD></TR>"); + ConcatCString(message,"Restricted</td></tr>\n"); break; case SCOPE_PRIVATE : - strcat(message,"Private</TD></TR>"); + ConcatCString(message,"Private</td></tr>\n"); break; default : - strcat(message,"Not matched</TD></TR>"); + ConcatCString(message,"Not matched</td></tr>\n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message,""); + Truncate(message,0); first = 1; for(range = pData->range; range ; range = range->next) { if (first==1) { - sprintf(message, - "%s<TR>\n" - "<TD ALIGN=RIGHT VALIGN=TOP>\n" - "<B>Range:</B>" - "</TD>\n<TD><DL>\n", - message); + ConcatCString(message, + "<tr>\n" + "<th>\n" + "Range:" + "</th>\n<td><dl>\n" + ); } first = 0; - sprintf(message,"%s<DT>%s\n<DD>%s\n", - message,range->range,range->description); + ConcatCString(message, "<dt>"); + ConcatCString(message, range->range); + ConcatCString(message, "</dt>\n<dd>"); + SetToEncodedHTMLCString( temp, range->description ); + Concat(message, temp); + ConcatCString(message, "</dd>\n"); if (!CCTK_Equals(range->origin,pData->thorn)) { - sprintf(message,"%s<BR>[Extended by thorn %s]\n", - message,range->origin); + ConcatCString(message, "<br />[Extended by thorn "); + ConcatCString(message, range->origin); + ConcatCString(message, "]\n"); } } if(first==0) { - strcat(message,"</DL></TD>\n</TR>\n"); + ConcatCString(message, "</dl></td>\n</tr>\n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - sprintf(message, - "<TR>\n" - "<TD ALIGN=RIGHT VALIGN=TOP><B>Times Set:</B></TD>\n" - "<TD>%d</TD>\n" - "</TR>\n" - "</TABLE></CENTER>\n", - pData->n_set); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<tr>\n<th>Times Set:</th>\n<td>"); + ConcatDecimal(message, pData->n_set); + ConcatCString(message, "</td>\n</tr>\n</table>\n</div>\n"); + Send_HTTP_String(request, message); } else { - strcpy(message,"<p>Hidden parameter, information is not available</p>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"<p>Hidden parameter, information is not available</p>\n"); } /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH, 0, 4098, message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH, 0, message); + retval = Send_HTTP_String(request, message); } - + String_Delete( message ); + String_Delete( menu ); + String_Delete( temp ); return retval; } diff --git a/src/Redirect.c b/src/Redirect.c index 32cee44..56141cf 100644 --- a/src/Redirect.c +++ b/src/Redirect.c @@ -26,6 +26,7 @@ #include "http_Content.h" #include "http_Redirect.h" +#include "http_SString.h" static const char *rcsid = "$Header$"; @@ -72,31 +73,27 @@ static char httpmaster[1024]; @@*/ +#define ADDRLEN 1024 + int HTTP_SetupRedirect(int port, int queue_size, int hunt) { - int retval; + int retval = 0; /* should not hunt */ int i; - char hostnm[1024]; + char hostnm[ADDRLEN] = EMPTYSTRING; char *alladdr; - int addrlen; - int nprocs; - int proc; - - addrlen = 1024; - nprocs = CCTK_nProcs(NULL); - proc = CCTK_MyProc(NULL); - retval = 0; + int nprocs = CCTK_nProcs(NULL); + int proc = CCTK_MyProc(NULL); #ifdef HTTPD_DEBUG CCTK_INFO("enter setup redirect------------"); #endif - memset(hostnm,0,addrlen); - Util_GetHostName(hostnm, addrlen); - alladdr = (char *) calloc (addrlen, nprocs); + memset(hostnm,0,sizeof(hostnm)); + Util_GetHostName(hostnm, sizeof(hostnm)); + alladdr = (char *) calloc (sizeof(hostnm), nprocs); #ifdef CCTK_MPI { /* push stack */ @@ -104,8 +101,8 @@ int HTTP_SetupRedirect(int port, CCTK_INFO("all gather"); #endif - MPI_Allgather(hostnm,addrlen,MPI_CHAR, - alladdr,addrlen,MPI_CHAR, + MPI_Allgather(hostnm,sizeof(hostnm),MPI_CHAR, + alladdr,sizeof(hostnm),MPI_CHAR, MPI_COMM_WORLD); #ifdef HTTPD_DEBUG CCTK_INFO("collected"); @@ -125,7 +122,7 @@ int HTTP_SetupRedirect(int port, #ifdef HTTPD_DEBUG printf("Cycle through %u\n",i); #endif - if(!strcmp(alladdr+i*addrlen,hostnm)) + if(!strcmp(alladdr+i*sizeof(hostnm),hostnm)) { /* we matched addresses */ if(i<proc || i==0) @@ -288,36 +285,35 @@ static void RegisterRedirect(void) static int RedirectPage(const cGH *cctkGH, httpRequest *request, void *data) { - int retval; - char message[1024]; + int retval = -1; + String *message = String_New(); /* avoid compiler warning about unused parameter */ data = data; - /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); - - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + SendHTTP_OK_Header(request); /* Start the page */ - strcpy(message,"<HTML><HEAD><TITLE>Server Redirect</TITLE>\n"); + SetToCString(message,"<html><head><title>Server Redirect</title>\n"); /* Write out the main header part */ - HTTP_Write(request, message, strlen(message)); - sprintf(message,"<META http-equiv=\"refresh\" content=\"1; URL=http://%s:%u\"></HEAD><body>\n", - HTTP_Master(), (unsigned int) HTTP_Port()); - HTTP_Write(request,message,strlen(message)); + Send_HTTP_String(request, message); + SetToCString(message,"<meta http-equiv=\"refresh\" content=\"1; URL=http://"); + ConcatCString(message,HTTP_Master()); + ConcatCString(message, ":"); + ConcatDecimal(message,(unsigned int) HTTP_Port()); + ConcatCString(message, "\" />\n</head>\n<body>\n"); + Send_HTTP_String(request,message); /* ********** Server Redirect To Master ************* */ - sprintf(message,"<p><h1>Redirect to master host=%s:%u</h1><p>\n", - HTTP_Master(), (unsigned int) HTTP_Port()); - HTTP_Write(request,message,strlen(message)); + SetToCString(message,"<h1>Redirect to master host="); + ConcatCString(message,HTTP_Master()); + ConcatCString(message, ":"); + ConcatDecimal(message,(unsigned int) HTTP_Port()); + ConcatCString(message, "</h1>\n"); + Send_HTTP_String(request,message); - HTTP_ContentFooter(cctkGH, 0, sizeof (message), message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH, 0, message); + retval = Send_HTTP_String(request, message); + String_Delete( message ); return retval; } diff --git a/src/SString.c b/src/SString.c new file mode 100644 index 0000000..bf7c953 --- /dev/null +++ b/src/SString.c @@ -0,0 +1,442 @@ + /*@@ + @file SString.c + @date 02.04.2004 + @author Steve White + @desc Module for generic operations on strings + @enddesc + @version $Header$ + @@*/ + +#include "SString.h" +#include "SStringIO.h" + +#include <string.h> +#include <stdlib.h> + +#ifndef MIN +#define MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#endif +#ifndef MAX +#define MAX( a, b ) ( (a) > (b) ? (a) : (b) ) +#endif + +typedef enum { MAKE_NULL_ALLOC, NEW_NULL_ALLOC, BUFFER_NULL_ALLOC } +SSTRING_ERROR; +static void String_HandleSeriousError( SSTRING_ERROR ); + +typedef struct String_tag +{ + size_t length; + SSCHAR *chars; +} String_placeholder; + +static SSCHAR kLineEndChar = '\n'; + +static SSBOOL BufferForThisManyChars( String *s, size_t size ); + +size_t +StringLength( const String * s ) +{ + return s->length; +} + +const SSCHAR * +StringGetBuffer( const String * s ) +{ + return s->chars; +} +/* + * Returns 0 if index is not in the string + */ +SSCHAR +StringNthChar( const String * s, size_t n ) +{ + if( n < s->length ) + return s->chars[n]; + else + return '\0'; +} + +String * +String_New() +{ + String *s = (String *)calloc( 1, sizeof( String ) ); + if( s != NULL ) + BufferForThisManyChars( s, 0 ); + else + String_HandleSeriousError( NEW_NULL_ALLOC ); + + return s; +} + +String * +String_Make( const SSCHAR * c_string ) +{ + String *s = (String *)calloc( 1, sizeof( String ) ); + if( s != NULL ) + { + if( c_string != NULL ) + { + size_t len = strlen( c_string ); + s->chars = strdup( c_string ); + s->length = len; + } + else + BufferForThisManyChars( s, 0 ); + } + else + String_HandleSeriousError( MAKE_NULL_ALLOC ); + return s; +} + +/* note this is a little ambiguous. + * needs to be made clear this makes a new string + */ +String * +String_Copy( const String * other ) +{ + return StringSetToCString( String_New(), StringGetBuffer( other ) ); +} + +void +String_Delete( String * s ) +{ + if( s != NULL ) + free( s->chars ); + free( s ); +} + +String * +StringTruncate( String * s, size_t n ) +{ + if( n < s->length ) + { + s->chars[n] = '\0'; + s->length = n; + } + return s; +} + +String * +StringSetNthChar( String * s, size_t n, SSCHAR c ) +{ + if( n < s->length ) + { + if( c == '\0' ) + StringTruncate( s, n ); + else + s->chars[n] = c; + } + return s; +} +/* Allocates if there is no buffer + * Re-allocates (without changing remaining string) if there is a buffer + * Puts a null char at the location of the corresponding size + * DOES NOT pad with zeros, or initialize the buffer beyond this + */ +SSBOOL +BufferForThisManyChars( String *s, size_t size ) +{ + const size_t blocksize = sizeof( SSCHAR ) * ( size + 1 ); + + if( s->chars == NULL ) + s->chars = (SSCHAR *)malloc( blocksize ); + else if( s->length < size ) + s->chars = (SSCHAR *)realloc( s->chars, blocksize ); + else if( s->length > ( size << 1 ) ) /* Don't resize if larger + but in ballpark */ + { + s->length = 0; + s->chars = (SSCHAR *)malloc( blocksize ); + } + + if( s->chars != NULL ) + { + s->length = size; + if( s->chars != NULL ) + s->chars[size] = '\0'; + } + else + String_HandleSeriousError( BUFFER_NULL_ALLOC ); + + return s->chars != NULL; +} + +String * +StringSetToCString( String * s, const SSCHAR *c_string ) +{ + return StringSetToBuffer( s, c_string, strlen( c_string ) ); +} + +String * +StringConcatCString( String * s, const SSCHAR *c_string ) +{ + const size_t orig_len = s->length; + if( BufferForThisManyChars( s, orig_len + strlen( c_string ) ) ) + { + strcpy( s->chars + orig_len, c_string ); + } + return s; +} + +String * +StringSetToBuffer( String * s, const SSCHAR *buf, size_t len ) +{ + if( s != NULL && buf != NULL ) + { + if( BufferForThisManyChars( s, len ) ) + { + strncpy( s->chars, buf, len ); + s->chars[ len ] = '\0'; + } + } + return s; +} + +String * +StringSet( String * s, const String * other ) +{ + return StringSetToCString( s, StringGetBuffer( other ) ); +} + +String * +StringSetSubString( String * s, const String * other, + size_t first, size_t last ) +{ + const size_t other_length = other->length; + const size_t veryFirst = MIN( MIN( first, last ), other_length ), + veryLast = MIN( MAX( first, last ), other_length ), + length = ( veryLast + 1 ) - veryFirst; + + return StringSetToBuffer( s, other->chars + veryFirst, length ); +} + +/* + * Last argument 'position' is both input and output. + * Specifies where to begin search: pass 0 to search whole string + * On output, is position where char was found. + */ +SSBOOL +StringFindChar( const String *s, SSCHAR theChar, size_t * position ) +{ + SSCHAR * charPtr; + + if( s->length > 0 + && position + && *position < s->length + && ( charPtr = (SSCHAR *)strchr( s->chars + *position, theChar ) ) + != NULL ) + { + *position = ( charPtr - s->chars ) / sizeof( SSCHAR ); + return TRUE; + } + return FALSE; +} + +SSBOOL +StringFindSubString( const String * s, const String * other, + size_t * position ) +{ + SSCHAR * charPtr; + + if( s->length >= other->length + && position + && *position < s->length + && s->length > 0 + && other->length > 0 + && ( charPtr = (SSCHAR *)strstr( s->chars + *position, other->chars ) ) + != NULL ) + { + *position = ( charPtr - s->chars ) / sizeof( SSCHAR ); + return TRUE; + } + return FALSE; +} + +SSBOOL +StringEquals( const String * a, const String * b ) +{ + if( a->length > 0 ) + return strncmp( a->chars, b->chars, a->length ) == 0; + else if( b->length == 0 ) + return TRUE; + + return FALSE; +} + +int +StringCompare( const String * a, const String * b ) +{ + const size_t length = MIN( a->length, b->length ); + + if( length > 0 ) + return strncmp( a->chars, b->chars, length ) <= 0; + else if( b->chars == 0 ) + return TRUE; + + return FALSE; +} + +String * +StringInsert( String * s, const String * other, size_t position ) +{ + const size_t oldLength = s->length, otherLength = other->length; + String *old = String_Copy( s ); + + if( otherLength > 0 + && position <= oldLength + && BufferForThisManyChars( s, oldLength + otherLength ) ) + { + if( position != 0 ) + strncpy( s->chars, old->chars, position ); + + strncpy( s->chars + position, other->chars, otherLength ); + + if( position < oldLength ) + strncpy( s->chars + position + otherLength, + old->chars + position, oldLength - position ); + s->chars[s->length] = '\0'; + } + String_Delete( old ); + + return s; +} + +String * +StringInsertCString( String * s, const char * c_string, size_t position ) +{ + String *other = String_Make( c_string ); + StringInsert( s, other, position ); + String_Delete( other ); + return s; +} +/* + * What to do if position is off end of string? We do nothing + */ +String * +StringInsertChar( String * s, SSCHAR c, size_t position ) +{ + if( position <= s->length ) + { + BufferForThisManyChars( s, s->length + 1 ); + if( position + 2 < s->length ) + { + s->chars[s->length] = '\0'; + memmove( s->chars + position + 1, s->chars + position, + s->length - 1 - position ); + s->chars[position] = c; + } + } + return s; +} + +String * +StringDeleteChar( String * s, size_t position ) +{ + return StringDeleteRange( s, position, position ); +} + +String * +StringDeleteRange( String * s, size_t begin, size_t end ) +{ + if( begin <= end && end < s->length ) + { + if( end + 1 < s->length ) + { + memmove( s->chars + begin, s->chars + end + 1, + ( s->length - end ) - 1 ); + } + s->length -= end - begin; + s->chars[s->length] = '\0'; + } + return s; +} + +String * +StringConcat( String * s, const String * other ) +{ + return StringInsert( s, other, s->length ); +} + +/* + * On unix the default \n works; on the Mac, you might want \r + */ +void +String_SetLineEndCharacter( SSCHAR c ) +{ + kLineEndChar = c; +} + +String * +StringReadToEndOfLine( String * s, FILE * file ) +{ + return StringReadToDelimiter( s, file, kLineEndChar ); +} + +String * +StringReadToDelimiter( String * s, FILE * file, SSCHAR delim ) +{ + int next; + + while( ( next = fgetc( file ) ) != EOF + && (SSCHAR)next != delim ) + StringInsertChar( s, (SSCHAR)next, s->length ); + + return s; +} + +void +StringPrint( const String * s ) +{ + fprintf( stdout, "%s", s->chars ); +} + +void +StringPrintToFile( const String * s, FILE * file ) +{ + fprintf( file, "%s", s->chars ); +} + +void +StringFormatPrint( const String * s, const SSCHAR *format ) +{ + fprintf( stdout, format, s->chars ); +} + +void +StringFormatPrintToFile( const String * s, const SSCHAR *format, FILE * file ) +{ + fprintf( file, format, s->chars ); +} + +#define DECIMALBUFSIZE 64 +String * +StringConcatDecimal( String * s, long d ) +{ + char buf[DECIMALBUFSIZE] = { '\0' }; + snprintf( buf, sizeof( buf ), "%ld", d ); + return StringConcatCString( s, buf ); +} + +String * +StringConcatDouble( String * s, double d ) +{ + char buf[DECIMALBUFSIZE] = { '\0' }; + snprintf( buf, sizeof( buf ), "%f", d ); + return StringConcatCString( s, buf ); +} + +String * +StringConcatFormattedDouble( String * s, int ndigits, int ndec, double d ) +{ + char buf[DECIMALBUFSIZE] = { '\0' }; + snprintf( buf, sizeof( buf ), "%*.*f", ndigits, ndec, d ); + return StringConcatCString( s, buf ); +} + +void +String_HandleSeriousError( SSTRING_ERROR e ) +{ + /* to be filled in on a per-implementation basis */ +} + diff --git a/src/SString.h b/src/SString.h new file mode 100644 index 0000000..1ff5445 --- /dev/null +++ b/src/SString.h @@ -0,0 +1,125 @@ + /*@@ + @file SString.h + @date 02.04.2004 + @author Steve White + @desc Module for generic operations on strings + @enddesc + @version $Header$ + @@*/ +#ifndef _SSTRING_H +#define _SSTRING_H + +#include <stddef.h> + +typedef enum { FALSE, TRUE } SSBOOL; +typedef char SSCHAR; + +typedef struct String_tag String; + /* String creation and deletion */ +String *String_New(); +String *String_Copy( const String *other ); +String *String_Make( const SSCHAR *other ); +void String_Delete( String * ); + /* Copying */ +String * StringSet( String *dest, const String *source ); +String * StringSetSubString( String *dest, const String *source, + size_t first, size_t last ); + /* Number of characters in string */ +size_t StringLength( const String * ); + /* Accessors */ +SSCHAR StringNthChar( const String *, size_t n ); +String * StringSetNthChar( String *, size_t n, SSCHAR c ); +String * StringTruncate( String *, size_t n ); + /* Conversion to and from C string */ +String * StringSetToCString( String *s, const SSCHAR *c_str ); +String * StringConcatCString( String *s, const SSCHAR *c_str ); +String * StringInsertCString( String * s, const char * c_str, + size_t position ); +String * StringSetToBuffer( String *s, const SSCHAR *buf, + size_t len ); +const SSCHAR * StringGetBuffer( const String * s ); + /* Searching */ +SSBOOL StringFindSubString( const String *s, const String *substr, + size_t *position ); +SSBOOL StringFindChar( const String *s, SSCHAR theChar, + size_t *position ); + /* Comparison */ +SSBOOL StringEquals( const String *a, const String *b ); +int StringCompare( const String *a, const String *b ); + /* Insertion and Concatenation */ +String * StringInsert( String * s, const String * other, size_t pos ); +String * StringInsertChar( String * s, SSCHAR c, size_t pos ); +String * StringDeleteChar( String * s, size_t pos ); +String * StringDeleteRange( String * s, size_t begin, size_t end ); +String * StringConcat( String * s, const String * other); + /* Trim */ +String * StringTrimHead( const String *s, size_t pos ); +String * StringTrimTail( const String *s, size_t pos ); + /* Printing to stdout */ +void StringPrint( const String *str ); +void StringFormatPrint( const String *str, const SSCHAR *format ); + /* For line reading and writing */ +void String_SetLineEndCharacter( SSCHAR c ); + /* String conversions */ +String * StringConcatDecimal( String *str, long int d ); +String * StringConcatHex( String *str, long int d ); +String * StringConcatOctal( String *str, long int d ); +String * StringConcatDouble( String *str, double d ); +String * StringConcatFormattedDouble( String *str, int ndigits, + int ndecimals, double d ); + +/* A poor man's namespace for the String module */ +#ifdef STRING_NAMESPACE + +#define Set( a, b ) \ + StringSet( a, b ) +#define SetToCString( a, b ) \ + StringSetToCString( a, b ) +#define InsertCString( a, b, c ) \ + StringInsertCString( a, b, c ) +#define ConcatCString( a, b ) \ + StringConcatCString( a, b ) +#define SetToBuffer( a, b ) \ + StringSetToBuffer( a, b ) +#define GetBuffer( a ) \ + StringGetBuffer( a ) +#define Length( p ) \ + StringLength( p ) +#define NthChar( s, n ) \ + StringNthChar( s, n ) +#define SetNthChar( s, n, c ) \ + StringSetNthChar( s, n, c ) +#define Truncate( s, n ) \ + StringTruncate( s, n ) +#define FindSubString( s, c, p ) \ + StringFindSubString( s, c, p ) +#define FindChar( s, c, p ) \ + StringFindChar( s, c, p ) +#define Compare( a, b ) \ + StringCompare( a, b ) +#define AreEqual( a, b ) \ + StringsAreEqual( a, b ) +#define Insert( a, b, p ) \ + StringInsert( a, b, p ) +#define InsertChar( a, b, p ) \ + StringInsertChar( a, b, p ) +#define Concat( a, b ) \ + StringConcat( a, b ) +#define Print( a ) \ + StringPrint( a ) +#define FormatPrint( a, s ) \ + StringFormatPrint( a, s ) +#define ConcatDecimal( a, s ) \ + StringConcatDecimal( a, s ) +#define ConcatHex( a, s ) \ + StringConcatHex( a, s ) +#define ConcatOctal( a, s ) \ + StringConcatOctal( a, s ) +#define ConcatDouble( a, s ) \ + StringConcatDouble( a, s ) +#define ConcatFormattedDouble( a, f, f2, s ) \ + StringConcatFormattedDouble( a, f, f2, s ) + +#endif + +#endif diff --git a/src/SStringHTML.c b/src/SStringHTML.c new file mode 100644 index 0000000..5d4951a --- /dev/null +++ b/src/SStringHTML.c @@ -0,0 +1,40 @@ + /*@@ + @file SStringHTML.c + @date 02.04.2004 + @author Steve White + @desc Extension to Strings module with function specific to HTML + @enddesc + @version $Header$ + @@*/ +#include "SStringHTML.h" + +static String * +StringReplaceCharWithCString( String * str, SSCHAR c, const SSCHAR *cstr ); + +String * +StringSetToEncodedHTMLCString( String * str, const SSCHAR *c ) +{ + return StringEncodeHTML( StringSetToCString( str, c ) ); +} + +String * +StringEncodeHTML( String * str ) +{ + StringReplaceCharWithCString( str, '&', "&" ); + StringReplaceCharWithCString( str, '<', "<" ); + StringReplaceCharWithCString( str, '>', ">" ); + return str; +} + +String * +StringReplaceCharWithCString( String * str, SSCHAR c, const SSCHAR *cstr ) +{ + size_t position = 0; + while( StringFindChar( str, c, &position ) ) + { + StringDeleteChar( str, position ); + StringInsertCString( str, cstr, position ); + position ++; + } + return str; +} diff --git a/src/SStringHTML.h b/src/SStringHTML.h new file mode 100644 index 0000000..6749ac8 --- /dev/null +++ b/src/SStringHTML.h @@ -0,0 +1,45 @@ + /*@@ + @file SStringHTML.h + @date 02.04.2004 + @author Steve White + @desc Extension to Strings module with function specific to HTML + @enddesc + @version $Header$ + @@*/ +#ifndef _SSTRINGHTML_H +#define _SSTRINGHTML_H + +#include "SString.h" + +/* +const String * StringHTMLBodyTag = StringHTMLBeginTag( BODY, NULL ); +const String * StringHTMLBodyEndTag = StringHTMLEndTag( BODY, NULL ); +String * StringSGMLEntity( SGMLEntityNum n ); +*/ + +/* At least encode unsafe ASCII according to rfc1738.html + * < > & # % " ' space tab { } | \ ^ ~ ] [ ` ? ; : , @ = + * as well as 80-FF 00-1F and 7F + * should be changed to %nn where nn is the hex representation of + * the ASCII value. + * + * If move to bigger characters will have to encode more. + * */ +String * StringSetToEncodedURLCString( String * str, const char *c ); +String * StringEncodeURL( String * str ); + +/* Replace < > & with character entities + * */ +String * StringSetToEncodedHTMLCString( String * str, const char *c ); +String * StringEncodeHTML( String * str ); + +#ifdef STRING_NAMESPACE + +#define EncodeHTML( s ) \ + StringEncodeHTML( s ) +#define SetToEncodedHTMLCString( s, c ) \ + StringSetToEncodedHTMLCString( s, c ) + +#endif + +#endif diff --git a/src/SStringIO.h b/src/SStringIO.h new file mode 100644 index 0000000..0d79c28 --- /dev/null +++ b/src/SStringIO.h @@ -0,0 +1,39 @@ + /*@@ + @file SStringIO.h + @date 02.04.2004 + @author Steve White + @desc Extensions to Strings module involvint file IO + @enddesc + @version $Header$ + @@*/ +#ifndef _SSTRINGIO_H +#define _SSTRINGIO_H + +#include "SString.h" +#include <stdio.h> + + /* File utilities */ +String * StringReadToDelimiter( String *str, FILE * file, char delim ); +String * StringReadToEndOfLine( String *str, FILE * is ); +String * StringReadLine( String *str, FILE * is ); + +void StringPrintToFile( const String *str, FILE * is ); +void StringFormatPrintToFile( const String *str, const char *format, + FILE * is ); + +#ifdef STRING_NAMESPACE + +#define ReadToDelimiter( a, f, d ) \ + StringReadToDelimiter( a, f, d ) +#define ReadToEndOfLine( a, f ) \ + StringReadToEndOfLine( a, f ) +#define ReadLine( a, f ) \ + StringReadLine( a, f ) +#define PrintToFile( a, f ) \ + StringPrintToFile( a, f ) +#define FormatPrintToFile( a, s, f ) \ + StringFormatPrintToFile( a, s, f ) + +#endif + +#endif diff --git a/src/Server.c b/src/Server.c index d274915..85116db 100644 --- a/src/Server.c +++ b/src/Server.c @@ -27,6 +27,8 @@ #include "http_Steer.h" #include "http_Expression.h" +#define STRING_NAMESPACE 1 +#include "SString.h" static const char *rcsid = "$Header$"; @@ -67,12 +69,12 @@ static double evaluator(const char *name, void *data); static uHash *pages = NULL; static const char *notfound_page = -"<HTML>\n<HEAD><TITLE>Error 404: Not Found</TITLE></HEAD>\ -<BODY>The URI you requested could not be found</BODY>\n</HTML>\n"; +"<html>\n<head>\n<title>Error 404: Not Found</title>\n</head>\n" +"<body>\nThe URI you requested could not be found\n</body>\n</html>\n"; static const char *notimplemented_page = -"<HTML>\n<HEAD><TITLE>Error 501: Not Implemented</TITLE></HEAD>\ -<BODY>The requested method is not implemented</BODY>\n<HTML>\n"; +"<html>\n<head>\n<title>Error 501: Not Implemented</title>\n</head>\n" +"<body>\nThe requested method is not implemented\n</body>\n<html>\n"; #define INITIAL_SIZE 16 @@ -97,31 +99,21 @@ static const char *notimplemented_page = int HTTP_RequestGET(cGH *cctkGH, httpRequest *request) { + int retval = -1; httpPage *pagedata; - int retval; - char message[1024]; if((pagedata = FindPage(request->uri, &(request->residual)))) { retval = pagedata->function(cctkGH, request, pagedata->data); } - else - { - retval = -1; - } if(retval < 0) { - strcpy(message,"HTTP/1.0 404 Not Found\r\n"); + Send_HTTP(request,"HTTP/1.0 404 Not Found\r\n"); - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"Content-Type: text/html\r\n\r\n"); + Send_HTTP(request,"Content-Type: text/html\r\n\r\n"); - HTTP_Write(request, message, strlen(message)); - - - HTTP_Write(request, notfound_page, strlen(notfound_page)); + Send_HTTP(request, notfound_page); } return retval; @@ -143,22 +135,13 @@ int HTTP_RequestGET(cGH *cctkGH, httpRequest *request) @@*/ int HTTP_RequestUnsupported(cGH *cctkGH, httpRequest *request) { - char message[1024]; - + cctkGH = cctkGH; /* avoid compiler warning about unused parameter */ - /* avoid compiler warning about unused parameter */ - cctkGH = cctkGH; + Send_HTTP(request,"HTTP/1.0 501 Not Implemented\r\n"); - strcpy(message,"HTTP/1.0 501 Not Implemented\r\n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"Content-Type: text/html\r\n\r\n"); + Send_HTTP(request,"Content-Type: text/html\r\n\r\n"); - HTTP_Write(request, message, strlen(message)); - - - HTTP_Write(request, notimplemented_page, strlen(notimplemented_page)); + Send_HTTP(request, notimplemented_page ); return 0; } @@ -179,7 +162,7 @@ int HTTP_RequestUnsupported(cGH *cctkGH, httpRequest *request) @@*/ int HTTP_RegisterPage(const char *path, int (*function)(const cGH *, httpRequest *, void *), void *data) { - int retval; + int retval = -1; httpPage *pagedata; @@ -192,7 +175,6 @@ int HTTP_RegisterPage(const char *path, int (*function)(const cGH *, httpRequest if(Util_HashData(pages, strlen(path), path, 0)) { fprintf(stderr, "Page %s already exists\n", path); - retval = -1; } else { @@ -229,12 +211,11 @@ int HTTP_RegisterPage(const char *path, int (*function)(const cGH *, httpRequest int HTTP_UpdateState(cGH *cctkGH, httpState *state) { DECLARE_CCTK_PARAMETERS - int stepping; + int stepping = single_step; static int steering = 1; static int last_steered = -1; - stepping = single_step; state->paused = (! stepping) && (pause || (cctkGH && ((until_it_active && StatusUntilIt(cctkGH)) || @@ -333,9 +314,7 @@ int HTTP_Terminate(cGH *cctkGH) @@*/ static httpPage *CreatePageData(int (*function)(const cGH *, httpRequest *, void *), void *data) { - httpPage *pagedata; - - pagedata = (httpPage *)malloc(sizeof(httpPage)); + httpPage *pagedata = (httpPage *)malloc(sizeof(httpPage)); if(pagedata) { @@ -362,32 +341,27 @@ static httpPage *CreatePageData(int (*function)(const cGH *, httpRequest *, void @@*/ static httpPage *FindPage(char *path, char **residual) { - httpPage *pagedata; - char *position; - char *temp; - - pagedata = NULL; + httpPage *pagedata = NULL; #ifdef HTTP_DEBUG printf ("Searching for '%s'\n", path); #endif - if(pages) + if(pages && path) { + String *temp = String_New(); /* Check for index.html */ - if(path[strlen(path)-1] == '/') + if(strlen(path) == 0 || strcmp( path, "/") == 0 ) { #ifdef HTTP_DEBUG printf("Looking for '%sindex.html'\n", path); #endif - temp = (char *)malloc(strlen(path)+11); - - sprintf(temp,"%sindex.html", path); + SetToCString( temp, path); + ConcatCString( temp,"index.html"); - pagedata = Util_HashData(pages, strlen(temp), temp, 0); + pagedata = Util_HashData(pages, Length(temp), GetBuffer(temp), 0); *residual = NULL; - free(temp); } else if((pagedata = Util_HashData(pages, strlen(path), path, 0))) { @@ -399,19 +373,17 @@ static httpPage *FindPage(char *path, char **residual) #ifdef HTTP_DEBUG printf("Looking for '%s/index.html'\n", path); #endif - temp = (char *)malloc(strlen(path)+12); - - sprintf(temp,"%s/index.html", path); + SetToCString( temp, path); + ConcatCString( temp,"/index.html"); - pagedata = Util_HashData(pages, strlen(temp), temp, 0); + pagedata = Util_HashData(pages, Length(temp), GetBuffer(temp), 0); *residual = NULL; - free(temp); } - - if(!pagedata) + if(!pagedata && strlen( path ) > 0) { + char *position; /* Ok, now cycle through. Know it doesn't end with a slash */ for(position = path+strlen(path)-1; position >= path; position--) { @@ -428,10 +400,8 @@ static httpPage *FindPage(char *path, char **residual) } } } - } - else - { - pagedata = NULL; + String_Delete( temp ); + temp = NULL; } return pagedata; @@ -502,13 +472,12 @@ static int StatusUntilExpression (cGH *cctkGH) DECLARE_CCTK_PARAMETERS static char *parsed_expression = NULL; static int times_set = -1; - int new_times_set; - int retval; + int retval = 0; char *copy; /* See if we need to parse the expression again. */ - new_times_set = CCTK_ParameterQueryTimesSet("until_expression", + int new_times_set = CCTK_ParameterQueryTimesSet("until_expression", CCTK_THORNSTRING); if(new_times_set > times_set) @@ -532,11 +501,6 @@ static int StatusUntilExpression (cGH *cctkGH) /* Free the copy */ free(copy); } - else - { - retval = 0; - } - return retval; } @@ -558,16 +522,12 @@ static int StatusUntilExpression (cGH *cctkGH) @@*/ static double evaluator(const char *expression, void *data) { - double retval; - cGH *cctkGH; + double retval = 0.0; + cGH *cctkGH = (cGH *)data; void *pointer; - int varindex; int vartype; + int varindex = CCTK_VarIndex(expression); - cctkGH = (cGH *)data; - - - varindex = CCTK_VarIndex(expression); if(varindex > -1) { vartype = CCTK_VarTypeI(varindex); @@ -587,7 +547,7 @@ static double evaluator(const char *expression, void *data) break; default : fprintf(stderr, "Unsupported variable type %d\n", vartype); - retval = 0; + retval = 0.0; } } else if(CCTK_Equals(expression,"time")) diff --git a/src/Sockets.c b/src/Sockets.c index f11b12e..60aee22 100644 --- a/src/Sockets.c +++ b/src/Sockets.c @@ -117,8 +117,8 @@ static unsigned long int httpport = 0; @@*/ int HTTP_SetupServer(int port, int queue_size, int hunt) { - char hostname[1025]; - unsigned int realport; + char hostname[1025] = {'\0'}; + unsigned int realport = 0; /* Some systems need special logic for starting up TCP. */ Socket_InitializeSocketLayer (); @@ -131,7 +131,7 @@ int HTTP_SetupServer(int port, int queue_size, int hunt) exit (EXIT_FAILURE); } - Util_GetHostName(hostname, 1024); + Util_GetHostName(hostname, sizeof(hostname)); httpport = hunt ? realport : (unsigned long int) port; @@ -284,21 +284,17 @@ int HTTP_Poll(cGH *cctkGH, long sec, long usec) @@*/ int HTTP_Write(httpRequest *request, const char *buffer, size_t count) { - int retval; - size_t bytes_sent; + int retval = -1; + size_t bytes_sent = 0; size_t halfcount; - httpSocket *connection; - int done; + httpSocket *connection = (httpSocket *)request->connection; + int done = 0; int tmp; fd_set this_set; - connection = (httpSocket *)request->connection; - if(connection->state == open) { FD_ZERO (&this_set); - done = 0; - bytes_sent = 0; while(!done) { /* Try and send the data. Make sure we don't get a SIGPIPE if the @@ -396,11 +392,7 @@ int HTTP_Write(httpRequest *request, const char *buffer, size_t count) { done = 1; } - }; - } - else - { - retval = -1; + } } #ifdef HTTP_DEBUG @@ -433,11 +425,9 @@ int HTTP_Write(httpRequest *request, const char *buffer, size_t count) @@*/ int HTTP_Read(httpRequest *request, char *buffer, size_t count) { - int retval; + int retval = -1; - httpSocket *connection; - - connection = (httpSocket *)request->connection; + httpSocket *connection = (httpSocket *)request->connection; if(connection->state == open) { @@ -448,10 +438,6 @@ int HTTP_Read(httpRequest *request, char *buffer, size_t count) fprintf (stderr, "Read: `%.*s'\n", retval, buffer); #endif } - else - { - retval = -1; - } return retval; } @@ -494,9 +480,7 @@ unsigned long int HTTP_Port(void) @@*/ static httpSocket *SocketCreate(unsigned long int filedes) { - httpSocket *this; - - this = (httpSocket *)malloc(sizeof (httpSocket)); + httpSocket *this = (httpSocket *)malloc(sizeof (httpSocket)); if(this) { diff --git a/src/Steer.c b/src/Steer.c index 4433187..8556777 100644 --- a/src/Steer.c +++ b/src/Steer.c @@ -84,12 +84,9 @@ static pthread_mutex_t steer_mutex = PTHREAD_MUTEX_INITIALIZER; @@*/ int HTTP_SteerQueue(const char *thorn, const char *parameter, const char *value) { - int retval; - int buffer_length; - int parameter_length; - char *tmp; - - retval = 0; + int retval = -1; + int buffer_length = 0; + int parameter_length = 0; #ifdef CCTK_PTHREADS pthread_mutex_lock(&steer_mutex); @@ -102,7 +99,7 @@ int HTTP_SteerQueue(const char *thorn, const char *parameter, const char *value) if(buffer_length+parameter_length+1 > queuebuffer_size) { - tmp = (char *)realloc(queuebuffer, buffer_length+parameter_length+1); + char *tmp = (char *)realloc(queuebuffer, buffer_length+parameter_length+1); if(tmp) { @@ -110,10 +107,6 @@ int HTTP_SteerQueue(const char *thorn, const char *parameter, const char *value) queuebuffer_size = buffer_length+parameter_length+1; retval = 0; } - else - { - retval = -1; - } } if(!retval) @@ -182,9 +175,9 @@ int HTTP_SteerDispatch(void) static int CommunicateBuffer(void) { #ifdef CCTK_MPI - int rank; - int nprocs; - int buffer_size; + int rank = 0; + int nprocs = 1; + int buffer_size = 0; CCTK_INT8 transmit_buffer_size; /* Work out how many processes there are. */ @@ -287,24 +280,18 @@ static int CommunicateBuffer(void) @@*/ static int SteerParameters(void) { - int retval; - - char *token; - char *thorn; - char *parameter; - char *value; - - retval = 0; + int retval = 0; + char *value = NULL; if(queuebuffer) { - token = strtok(queuebuffer, "\n"); + char *token = strtok(queuebuffer, "\n"); while(token) { - thorn = token; + char *thorn = token; - parameter = strchr(token, ':'); + char *parameter = strchr(token, ':'); if(parameter) { @@ -379,16 +366,14 @@ static int SteerParameters(void) static void ByteSwap(void *buf,int nelements,int elementsize) { #ifndef WORDS_BIGENDIAN - char *buffer; + char *buffer=(char *)buf; int i; int s,d; - - buffer=(char *)buf; for(i=0;i<nelements;i++,buffer+=elementsize) { /* do the swap thing on each element */ - for(s=0,d=elementsize-1;s<d;s++,d--) + for(s=0, d=elementsize-1; s < d; s++,d--) { char c=buffer[s]; buffer[s]=buffer[d]; @@ -403,12 +388,10 @@ static void ByteSwap(void *buf,int nelements,int elementsize) int CCTK_ParameterSet(char *parameter, char *thorn, char *value) { - int rank; + int rank = 0; #ifdef CCTK_MPI MPI_Comm_rank(MPI_COMM_WORLD, &rank); -#else - rank = 0; #endif fprintf(stderr, "%d - %s::%s='%s'\n", rank, thorn, parameter, value); @@ -419,8 +402,8 @@ int CCTK_ParameterSet(char *parameter, char *thorn, char *value) int main(int argc, char *argv[]) { int i; - int rank; - char value[20]; + int rank = 0; + char value[20] = {'\0'}; #ifdef CCTK_MPI MPI_Init(&argc, &argv); @@ -428,8 +411,6 @@ int main(int argc, char *argv[]) #ifdef CCTK_MPI MPI_Comm_rank(MPI_COMM_WORLD, &rank); -#else - rank = 0; #endif for(i = 0; i < 6; i++) diff --git a/src/Thorns.c b/src/Thorns.c index 7394998..05ca112 100644 --- a/src/Thorns.c +++ b/src/Thorns.c @@ -62,10 +62,11 @@ int HTTPi_RegisterThornPages(void); @endhistory @@*/ +#define THORN_NAME_MAXLENGTH (27+20) int HTTPi_RegisterThornPages(void) { int i; - char pagename[27+20]; /* Thorns have maximum length */ + char pagename[THORN_NAME_MAXLENGTH]; char *namecopy; const char *thorn; @@ -82,7 +83,7 @@ int HTTPi_RegisterThornPages(void) sprintf(pagename,"/Thorns/%s", thorn); - namecopy = Util_Strdup(thorn); + namecopy = Util_Strdup(thorn); /*SW isn't this a memory leak?*/ HTTP_RegisterPage(pagename, ThornPage, namecopy); } @@ -112,43 +113,37 @@ int HTTPi_RegisterThornPages(void) static int ThornMainPage(const cGH *cctkGH, httpRequest *request, void *data) { int i; - int retval; + int retval = -1; int foundone; const char *thorn; - char message[4098]; + String *message = String_New(); /* avoid compiler warning about unused parameter */ data = data; - /* Status message */ - strcpy(message,"HTTP/1.0 200 OK\r\n"); - - HTTP_Write(request, message, strlen(message)); - - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); - + SendHTTP_OK_Header( request ); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - strcpy(message,"<HTML><HEAD><TITLE>Cactus Thorns</TITLE>\n"); + Send_HTTP(request,"<html><head><title>Cactus Thorns</title>\n"); + + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"</head>\n<body>\n"); - /* HTTP_Write out the header part. */ + /* Send_HTTP_String out the header part. */ - HTTP_ContentHeader(cctkGH,0,strlen(message),message,NULL); + SetHTML_ContentHeader(cctkGH,0,message,NULL); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP_String(request, message); - strcpy(message, "<center><h1>Thorns</h1></center>" - "<p>These pages describe the thorns used in this simulation.</p>"); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP(request, "<h1>Thorns</h1>\n" + "<p>These pages describe the thorns used in this simulation.</p>\n"); - strcpy(message,"<TABLE><TR><TD VALIGN=TOP ALIGN=LEFT>"); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP(request,"<table><tr><td>\n"); foundone = 0; for (i = 0; i < CCTK_NumCompiledThorns (); i++) @@ -158,37 +153,33 @@ static int ThornMainPage(const cGH *cctkGH, httpRequest *request, void *data) { if (!foundone) { - strcpy(message, - "<H2>Active Thorns</H2>\n" - "<CENTER>\n" - "<TABLE ALIGN=TOP cellspacing=0 cellpadding=5 border=0\n>" - "<TR>\n" - "<TH ALIGN=LEFT>Thorn Name</TH>\n" - "<TH ALIGN=LEFT>Implementation</TH>\n" - "</TR>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "<h2>Active Thorns</h2>\n" + "<div class=\"center\">\n" + "<table class=\"thorns\" cellspacing=\"0\" cellpadding=\"5\">\n" + "<tr>\n" + "<th>Thorn Name</th>\n" + "<th>Implementation</th>\n" + "</tr>\n"); foundone++; } - sprintf(message, - "<TR>\n" - "<TD VALIGN=TOP ALIGN=LEFT><A HREF=\"/Thorns/%s/\">%s</A></td>\n" - "<TD VALIGN=TOP ALIGN=LEFT>%s</TD>\n" - "</TR>\n", - thorn, thorn,CCTK_ThornImplementation(thorn)); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<tr>\n<td><a href=\"/Thorns/"); + ConcatCString(message, thorn); + ConcatCString(message, "/\">"); + ConcatCString(message, thorn); + ConcatCString(message, "</a></td>\n<td>"); + ConcatCString(message, CCTK_ThornImplementation(thorn)); + ConcatCString(message, "</td>\n</tr>\n"); + Send_HTTP_String(request, message); } } if (foundone) { - strcpy(message,"</TABLE></CENTER>"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"</table></div>\n"); } - - strcpy(message,"</TD><TD ALIGN=LEFT VALIGN=TOP>"); - retval = HTTP_Write(request, message, strlen(message)); - + retval = Send_HTTP(request,"</td><td>"); foundone = 0; for (i = 0; i < CCTK_NumCompiledThorns (); i++) @@ -199,44 +190,40 @@ static int ThornMainPage(const cGH *cctkGH, httpRequest *request, void *data) if (!foundone) { - strcpy(message, - "<H2>Dormant Thorns</H2>\n" - "<CENTER><TABLE CELL SPACING=0 cellpadding=5 border=0\n>" - "<TR>\n" - "<TH ALIGN=LEFT>Thorn Name</TH>\n" - "<TH ALIGN=LEFT>Implementation</TH>\n" - "</TR>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "<h2>Dormant Thorns</h2>\n" + "<div class=\"centered\">\n" + "<table class=\"thorns\" cellspacing=\"0\" cellpadding=\"5\">\n" + "<tr>\n" + "<th>Thorn Name</th>\n" + "<th>Implementation</th>\n" + "</tr>\n"); foundone++; } - sprintf(message, - "<TR>\n" - "<TD VALIGN=TOP ALIGN=LEFT>\n" - "%s</td>\n" - "<TD VALIGN=TOP ALIGN=LEFT>%s</TD>\n" - "</TR>\n", - thorn, CCTK_ThornImplementation(thorn)); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<tr>\n<td>\n"); + ConcatCString(message, thorn); + ConcatCString(message, "</td>\n<td>"); + ConcatCString(message, CCTK_ThornImplementation(thorn)); + ConcatCString(message, "</td>\n</tr>\n"); + Send_HTTP_String(request, message); } } if (foundone) { - strcpy(message,"</TABLE>\n</CENTER>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"</table>\n</div>\n"); } - strcpy(message,"</TD>\n</TR>\n</TABLE>\n"); - - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP(request,"</td>\n</tr>\n</table>\n"); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH,0,strlen(message),message); - retval = HTTP_Write(request, message, strlen(message)); + SetHTML_ContentFooter(cctkGH,0,message); + retval = Send_HTTP_String(request, message); + String_Delete( message ); return retval; } @@ -259,49 +246,53 @@ static int ThornMainPage(const cGH *cctkGH, httpRequest *request, void *data) static int ThornPage(const cGH *cctkGH, httpRequest *request, void *data) { int retval=0; - char message[4098]; - const char *thorn; - - thorn = (const char *)data; - - strcpy(message,"HTTP/1.0 200 OK\r\n"); + String *message = String_New(); + const char *thorn = (const char *)data; - HTTP_Write(request, message, strlen(message)); + SendHTTP_OK_Header(request); - /* Content-Type */ - strcpy(message,"Content-Type: text/html\r\n\r\n"); - - HTTP_Write(request, message, strlen(message)); + SetHTML_Doctype( message ); + Send_HTTP_String(request, message); /* Start the page */ - sprintf(message, - "<HTML><HEAD><TITLE>Thorn Page : %s</TITLE></HEAD>\n", thorn); + SetToCString(message, "<html>\n<head>\n<title>Thorn Page : "); + ConcatCString(message, thorn); + ConcatCString(message, "</title>\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - HTTP_ContentHeader(cctkGH,0,4098,message,NULL); + Send_HTTP(request,"</head>\n<body>\n"); - strcat(message,"<BODY>"); - HTTP_Write(request, message, strlen(message)); + SetHTML_ContentHeader(cctkGH,0,message,NULL); - sprintf(message,"<CENTER><H1>Thorn %s</H1></CENTER>\n",thorn); - HTTP_Write(request, message, strlen(message)); - - sprintf(message,"<P>This page will include all the information about thorn" - "%s. For now, only information about the parameters is given.</p>", - thorn); + Send_HTTP_String(request, message); - sprintf(message,"%s<UL>\n" - "<LI><A HREF=\"/Parameters/%s\">Parameters</A>\n" - "</UL>\n", - message,thorn); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "<h1>Thorn "); + ConcatCString(message, thorn); + ConcatCString(message, "</h1>\n"); + + Send_HTTP_String(request, message); + + SetToCString(message,"<p>This page will include all the information about thorn \'"); + ConcatCString(message, thorn); + ConcatCString(message, + "\'.\n For now, only information about the parameters is given.</p>\n"); + + ConcatCString(message, "<ul>\n" + "<li><a href=\"/Parameters/"); + ConcatCString(message, thorn ); + ConcatCString(message, "\">Parameters</a></li>\n" + "</ul>\n"); + Send_HTTP_String(request, message); /* Write out the footer part. */ - HTTP_ContentFooter(cctkGH, 0, 4098, message); - retval = HTTP_Write(request, message, strlen(message)); - + SetHTML_ContentFooter(cctkGH, 0, message); + retval = Send_HTTP_String(request, message); + + String_Delete( message ); return retval; } @@ -73,6 +73,7 @@ static void DestroyArgument(httpArg *argument); #define INITIAL_SIZE 16 #define MAXMSG 2048 +#define EMPTY_STRING {'\0'} /******************************************************************** ********************* External Routines ********************** @@ -94,32 +95,24 @@ static void DestroyArgument(httpArg *argument); @@*/ int HTTP_ReadFromClient(cGH *cctkGH, void *connection) { - int retval; - int keepalive; - char inbuffer[MAXMSG]; - int nbytes; - httpRequest request; - int request_buffer_length; - char *request_buffer; - char *tmp; + int retval = -1; + int keepalive = 0; + char inbuffer[MAXMSG] = EMPTY_STRING; + httpRequest request = BLANK_HTTPREQUEST; + int request_buffer_length = 0; + char *request_buffer = NULL; struct timeval timeout = {1, 0}; - - int found_eoh; - int failure_count; + int found_eoh = 0; + int failure_count = 0; InitialiseRequest(&request); request.connection = connection; - found_eoh = 0; - failure_count = 0; - request_buffer_length = 0; - request_buffer = NULL; - while(! found_eoh) { - nbytes = HTTP_Read(&request, inbuffer, MAXMSG); + int nbytes = HTTP_Read(&request, inbuffer, MAXMSG); if (nbytes < 0) { @@ -148,7 +141,7 @@ int HTTP_ReadFromClient(cGH *cctkGH, void *connection) /* Reallocate space for buffer. * Add space for one extra char so can null-terminate to allow string search. */ - tmp = (char *)realloc(request_buffer, (request_buffer_length+nbytes+1)*sizeof(char)); + char *tmp = (char *)realloc(request_buffer, (request_buffer_length+nbytes+1)*sizeof(char)); if(tmp) { request_buffer = tmp; @@ -187,10 +180,6 @@ int HTTP_ReadFromClient(cGH *cctkGH, void *connection) keepalive = DealWithRequest(cctkGH, &request, request_buffer, request_buffer_length); } - else - { - keepalive = 0; - } if(keepalive) { @@ -225,29 +214,17 @@ int HTTP_ReadFromClient(cGH *cctkGH, void *connection) @@*/ const char *HTTP_ArgumentValue(const httpRequest *request, const char *arg) { - const char *retval; - - const httpArg *value; - if(request->arguments) { - value = (httpArg *)Util_HashData(request->arguments, strlen(arg), arg, 0); + const httpArg *value = (httpArg *)Util_HashData(request->arguments, strlen(arg), arg, 0); if(value) { - retval = value->value; - } - else - { - retval = NULL; + return value->value; } } - else - { - retval = NULL; - } - return retval; + return NULL; } /*@@ @@ -295,7 +272,6 @@ const httpArg *HTTP_ArgumentWalk(httpRequest *request, int first) const char *HTTP_HeaderValue(const httpRequest *request, const char *header) { struct httpHeader *header_line; - const char *value; if(request->headers) { @@ -303,19 +279,11 @@ const char *HTTP_HeaderValue(const httpRequest *request, const char *header) if(header_line) { - value = header_line->line; - } - else - { - value = NULL; + return header_line->line; } } - else - { - value = NULL; - } - return value; + return NULL; } /******************************************************************** @@ -338,11 +306,10 @@ const char *HTTP_HeaderValue(const httpRequest *request, const char *header) @@*/ static char *NextLine(char *buffer, int *start, int size) { - char *line; - int found; + char *line = NULL; + int found = 0; char *pos; - found = 0; for(pos = buffer + *start; pos-buffer < size-1; pos++) { if(*pos == '\r' && *(pos+1) == '\n') @@ -360,7 +327,6 @@ static char *NextLine(char *buffer, int *start, int size) } else { - line = NULL; *start = size+1; } @@ -384,27 +350,19 @@ static char *NextLine(char *buffer, int *start, int size) static int DealWithRequest(cGH *cctkGH, httpRequest *request, char *buffer, int bufsize) { char *line; - char *tmp; - int start; - char *method; - char *request_uri; - char *http_version; + char *tmp = buffer; + int start = 0; + char *method = NULL; + char *request_uri = NULL; + char *http_version = NULL; DECLARE_CCTK_PARAMETERS - tmp = buffer; - #ifdef HTTP_DEBUG printf("Dealing with request\n"); #endif - start = 0; - line = NextLine(tmp, &start, bufsize); - method = NULL; - request_uri = NULL; - http_version = NULL; - if(line) { method = line; @@ -542,15 +500,10 @@ static int DealWithRequest(cGH *cctkGH, httpRequest *request, char *buffer, int @@*/ static int AddHeader(httpRequest *request, const char *line) { - int keylength; - char *value; - char *temp; + int keylength = -1; struct httpHeader *header_line; - - keylength = -1; - /* Split the string */ - value = strchr(line, ':'); + char *value = strchr(line, ':'); if(value) { @@ -582,7 +535,7 @@ static int AddHeader(httpRequest *request, const char *line) if(header_line) { - temp = (char *)realloc(header_line->line, strlen(header_line->line)+strlen(value)+2); + char *temp = (char *)realloc(header_line->line, strlen(header_line->line)+strlen(value)+2); if(temp) { @@ -636,10 +589,8 @@ static int StripArgs(httpRequest *request, char *request_uri) { char *position; char *token; - char *value; httpArg *argument; httpArg *stored; - httpArg *last; /* Do we have arguments ? */ if((position = strchr(request_uri, '?'))) { @@ -656,7 +607,7 @@ static int StripArgs(httpRequest *request, char *request_uri) while(token) { - value = strchr(token, '='); + char *value = strchr(token, '='); if(value) { @@ -672,6 +623,7 @@ static int StripArgs(httpRequest *request, char *request_uri) if(argument) { + httpArg *last = NULL; argument->next = NULL; argument->all_next = NULL; argument->arg = Util_Strdup(token); @@ -684,10 +636,11 @@ static int StripArgs(httpRequest *request, char *request_uri) /* Find the last one on the list */ for(; stored; stored = stored->next) { - last = stored; + last = stored; } /* Append to local list */ + /* SW it isn't perfecty obvious this non NULL */ last->next = argument; } else @@ -822,9 +775,7 @@ static void Decode(char *string) { char *position; char *to; - char hexadecimal[3]; - - hexadecimal[2] = 0; + char hexadecimal[3] = {0, 0, 0}; for(position=string, to=position; *position; position++, to++) { diff --git a/src/http_Content.h b/src/http_Content.h index 40c2777..bfac5d7 100644 --- a/src/http_Content.h +++ b/src/http_Content.h @@ -13,6 +13,11 @@ #define HTTP_QUICKLINK 1 +#define STRING_NAMESPACE 1 +#include "SString.h" + +#define EMPTYSTRING {'\0'} + #ifdef __cplusplus extern "C" { @@ -26,8 +31,11 @@ int HTTP_ContentLink(const char *URL, int HTTP_ContentSendFromFile(httpRequest *request, int filedes); -int HTTP_ContentHeader(const cGH *cctkGH, int choice, int len, char *mess, char *menu); -int HTTP_ContentFooter(const cGH *cctkGH, int choice, int len, char *mess); +int SetHTML_ContentHeader(const cGH *cctkGH, int choice, String *mess, + const String *menu); +int SetHTML_ContentFooter(const cGH *cctkGH, int choice, String *mess); + +void SendHTTP_OK_Header(httpRequest *request); #ifdef __cplusplus } diff --git a/src/http_Request.h b/src/http_Request.h index 02cb600..e74e756 100644 --- a/src/http_Request.h +++ b/src/http_Request.h @@ -62,6 +62,8 @@ typedef struct } httpRequest; +#define BLANK_HTTPREQUEST {NULL, 0, NULL, NULL, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + #ifdef __cplusplus extern "C" { @@ -78,6 +80,8 @@ const char *HTTP_HeaderValue(const httpRequest *request, const char *header); int HTTP_Write(httpRequest *request, const char *buffer, size_t count); int HTTP_Read(httpRequest *request, char *buffer, size_t count); +int Send_HTTP( httpRequest *request, const char * message ); + unsigned long int HTTP_Port(void); #ifdef __cplusplus diff --git a/src/make.code.defn b/src/make.code.defn index a94f11e..506d792 100644 --- a/src/make.code.defn +++ b/src/make.code.defn @@ -17,11 +17,14 @@ COOKIES_SRC = Cookies.c REDIRECTION_SRC = Redirect.c +STRINGS_SRC = SString.c SStringHTML.c + SRCS = $(MISC_SRC) \ $(SERVER_SRC) \ $(CONTENT_SRC) \ $(STEERING_SRC) \ $(AUTHENTICATION_SRC) \ $(COOKIES_SRC) \ - $(REDIRECTION_SRC) + $(REDIRECTION_SRC) \ + $(STRINGS_SRC) |