From 89b88d27b20641e04cd1c2714c299d8908822b54 Mon Sep 17 00:00:00 2001 From: swhite Date: Tue, 6 Apr 2004 17:45:14 +0000 Subject: Regarding Cactus bug report 1632 "HTTPD contains buffer overflows" 1) Got rid of most strcat/sprintf into automatic array, replaced with a String module that allocates dynamic memory on the heap. 2) Went a long way toward initializing all variables. 3) Tested: Ran two copies with same parfile except different port, one with my changes, one with original. Went through different kinds of pages by hand, checked by eye. 4) Tried to make HTML XHTML 1.0-compliant. Checked with Amaya. One problem: How to deal with raw less-than characters, etc. Made a function to convert them to HTML Character Entities, but isn't clear this will work properly in the forms. So I left these symbols in the forms. 5) Also checked with more primitive browsers, lynx and dillo. 6) Marked a few instances of questionable code with 'SW' To do ----- Document a few new functions, esp. in Content.c git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/HTTPD/trunk@187 1faa4e14-9dd3-4be0-9f0e-ffe519881164 --- src/Authorisation.c | 57 +-- src/Content.c | 971 +++++++++++++++++++++++++++------------------------- src/Cookies.c | 62 ++-- src/Groups.c | 156 +++++---- src/Headers.c | 235 +++++++------ src/Parameters.c | 798 +++++++++++++++++++++--------------------- src/Redirect.c | 70 ++-- src/SString.c | 442 ++++++++++++++++++++++++ src/SString.h | 125 +++++++ src/SStringHTML.c | 40 +++ src/SStringHTML.h | 45 +++ src/SStringIO.h | 39 +++ src/Server.c | 114 ++---- src/Sockets.c | 38 +- src/Steer.c | 53 +-- src/Thorns.c | 191 +++++------ src/http.c | 111 ++---- src/http_Content.h | 12 +- src/http_Request.h | 4 + src/make.code.defn | 5 +- 20 files changed, 2101 insertions(+), 1467 deletions(-) create mode 100644 src/SString.c create mode 100644 src/SString.h create mode 100644 src/SStringHTML.c create mode 100644 src/SStringHTML.h create mode 100644 src/SStringIO.h 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 = -"\nError 401: Not Authorized\ -You are not authorized to access this page\n\n"; +"\nError 401: Not Authorized\n\n" +"\nYou are not authorized to access this page\n\n\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, "
  • " ); + ConcatDecimal(message, time ); + ConcatCString(message, " " ); + ConcatCString(message, units ); + ConcatCString(message, "
  • \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,"Running CACTUS Status Information\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "\n\n"); + Send_HTTP(request, "Running CACTUS Status Information\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); + Send_HTTP(request, "\n\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, "
    Active Thorns:\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
    %s\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,"

    Active Thorns:

    \n"); + for(i=0; i < nthorns; i++) + if (CCTK_IsThornActive(thorns[i])) + { + ConcatCString( menu,""); + ConcatCString( menu, thorns[i]); + ConcatCString( menu,"
    \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,"
    \n" - "\"Cactus\"
    \n"); + Send_HTTP(request, + "
    \n" + "\"Cactus\"
    \n"); - HTTP_Write(request, message, strlen(message)); - - CCTK_RunTitle(4098,title); + CCTK_GetRunTitleString(title); /* Some blurb */ - sprintf(message, "
    " - "
    \n" - "\n" - "\n" - "\n" - "\n" - "
    \n" - "

    %s

    \n" - "

    This browser is connected to a Cactus simulation which " - "contains a web server thorn. This thorn provides information " - " and control for the simulation.

    \n" - "\n" - "\n" - "
    \n" - "

    Before controlling any features of the simulation, users " - "must authenticate.

    \n" - "
    \n" - "
    \n",title); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "
    \n" - "\n" - "\n" - "\n\n
    \n"); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, + "
    \n" + "\n" + "\n" + "\n" + "\n" + "
    \n" + "

    "); + Concat(message, title ); + ConcatCString(message, + "

    \n" + "

    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.

    \n" + "\n" + "\n" + "
    \n" + "

    Before controlling any features of the simulation, users \n" + "must authenticate.

    \n" + "
    \n" + "
    \n" + "
    \n"); + + Send_HTTP_String(request, message ); + + Send_HTTP(request, + "\n" + "\n" + "\n" - "\n" + "\n" - "\n" - "
    \n"); /* AVAILABLE OPTIONS */ if(ContentLinks) { - strcpy(message, - "

    Available options:

    \n" - "
    \n"); + SetToCString(message, + "

    Available options:

    \n" + "
    \n"); for(hlink = ContentLinks; hlink; hlink=hlink->next) { - sprintf(message, - "%s
    %s
    %s \n", - message, hlink->URL, hlink->name, hlink->description); - + ConcatCString(message, "
    URL ); + ConcatCString(message, "\">" ); + ConcatCString(message, hlink->name ); + ConcatCString(message, "
    \n
    " ); + ConcatCString(message, hlink->description ); + ConcatCString(message, "
    \n" ); } - sprintf(message,"%s
    \n",message); - HTTP_Write(request, message, strlen(message)); + ConcatCString(message, "
    \n" ); + Send_HTTP_String(request, message ); } - strcpy(message, - "
    \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "\n"); /* CONFIGURATION DETAILS */ - sprintf(message, + SetToCString(message, "

    Simulation:

    \n" "
      \n" - "
    • Flesh version %s
    • \n" - "
    • Flesh compiled on %s" - " at %s
    • \n", - CCTK_FullVersion(),CCTK_CompileDate(),CCTK_CompileTime()); - - HTTP_Write(request, message, strlen(message)); + "
    • Flesh version "); + ConcatCString(message, CCTK_FullVersion() ); + ConcatCString(message, + "
    • \n" + "
    • Flesh compiled on "); + ConcatCString(message, CCTK_CompileDate() ); + ConcatCString(message, + "\n" + " at "); + ConcatCString(message, CCTK_CompileTime() ); + ConcatCString(message, + "
    • \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,"
    • Time since start up\n
        "); + SetToCString(message, "
      • Time since start up\n
          "); if (millenia) { - sprintf(message, - "%s
        • %d millenia\n",message,millenia); + TimeListItem( message, millenia, "millenia" ); } if (years) { - sprintf(message, - "%s
        • %d years\n",message,years); + TimeListItem( message, years, "years" ); } if (months) { - sprintf(message, - "%s
        • %d months\n",message,months); + TimeListItem( message, months, "months" ); } if (weeks) { - sprintf(message, - "%s
        • %d weeks\n",message,weeks); + TimeListItem( message, weeks, "weeks" ); } if (days) { - sprintf(message, - "%s
        • %d days\n",message,days); + TimeListItem( message, days, "days" ); } if (hours) { - sprintf(message, - "%s
        • %d hours\n",message,hours); + TimeListItem( message, hours, "hours" ); } if (minutes) { - sprintf(message, - "%s
        • %d minutes\n",message,minutes); + TimeListItem( message, minutes, "minutes" ); } if (seconds) { - sprintf(message, - "%s
        • %d seconds\n",message,seconds); + TimeListItem( message, seconds, "seconds" ); } - strcat(message,"
      • Parameter filename "); - HTTP_Write(request, message, strlen(message)); + ConcatCString(message, "
    • \n
    • Parameter filename " ); + 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,"\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "
    • \n"); if (cctkGH && cctkGH->cctk_iteration) { - strcpy(message,"
    • Estimated time per iteration:
        "); - sprintf(message,"%s
      • %f seconds
      ", - message,CCTK_RunTime()/(double)cctkGH->cctk_iteration); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "
    • Estimated time per iteration:
        \n"); + ConcatCString(message, "
      • "); + ConcatDouble(message, CCTK_RunTime()/(double)cctkGH->cctk_iteration ); + ConcatCString(message, " seconds
    • \n"); - strcpy(message,"
    • Estimated time to completion:
        "); + Send_HTTP_String(request, message ); + + SetToCString(message, "
      • Estimated time to completion:\n
          "); if (cctk_final_time%d millenia\n",message,millenia); + TimeListItem( message, millenia, "millenia" ); } if (years) { - sprintf(message, - "%s
        • %d years\n",message,years); + TimeListItem( message, years, "years" ); } if (months) { - sprintf(message, - "%s
        • %d months\n",message,months); + TimeListItem( message, months, "months" ); } if (weeks) { - sprintf(message, - "%s
        • %d weeks\n",message,weeks); + TimeListItem( message, months, "months" ); } if (days) { - sprintf(message, - "%s
        • %d days\n",message,days); + TimeListItem( message, days, "days" ); } if (hours) { - sprintf(message, - "%s
        • %d hours\n",message,hours); + TimeListItem( message, hours, "hours" ); } if (minutes) { - sprintf(message, - "%s
        • %d minutes\n",message,minutes); + TimeListItem( message, minutes, "minutes" ); } if (seconds) { - sprintf(message, - "%s
        • %d seconds\n",message,seconds); + TimeListItem( message, seconds, "seconds" ); } - strcat(message,"
        "); + ConcatCString(message, "
    • \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, - "
    • Single processor run
    • \n" - "
    • Running on %s
    • \n",host); + SetToCString(message, "
    • Single processor run
    • \n" + "
    • Running on " ); + ConcatCString(message, host); + ConcatCString(message, "
    • \n"); } else { - sprintf(message, - "
    • Multiprocessor run on %d CPUs
    • \n" - "
    • Processor 0 running on %s
    • \n", - CCTK_nProcs(cctkGH),host); + SetToCString(message, "
    • Multiprocessor run on " ); + ConcatDecimal(message, CCTK_nProcs(cctkGH)); + ConcatCString(message, " CPUs
    • \n" + "
    • Processor 0 running on "); + ConcatCString(message, host); + ConcatCString(message, "
    • \n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message ); user = getenv ("USER"); if (user) { - sprintf(message, "
    • Started by %s
    • \n",user); + SetToCString(message, "
    • Started by "); + ConcatCString(message, user); + ConcatCString(message, "
    • \n"); + Send_HTTP_String(request, message ); } - HTTP_Write(request, message, strlen(message)); - strcpy(message,"
    "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "\n"); /* Finish table started by blurb */ - strcpy(message, - "
    \n" - "\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "
    \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, "Cactus Control and Status Page\n"); - - HTTP_Write(request, message, strlen(message)); - HTTP_ContentHeader(cctkGH, 0,4098,message,NULL); + Send_HTTP(request, "\n"); + Send_HTTP(request, "Cactus Control and Status Page\n"); - strcat(message, "

    Control and Status Page

    "); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "

    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.

    "); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "\n\n"); + + SetHTML_ContentHeader(cctkGH, 0,message,NULL); - strcpy(message, - "
    \n" - "
    \n"); + ConcatCString(message, "

    Control and Status Page

    \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message, - "

    Run Control

    \n" - "

    Select if the run should be paused, running normally, or terminated." - " You may also single step to the next iteration.

    "); + Send_HTTP(request, + "

    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.

    \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "
    \n" + "\n"); - strcpy(message, - "\n" - "\n"); + Send_HTTP(request, + "

    Run Control

    \n" + "

    Select if the run should be paused, running normally, " + "or terminated.\n" + " You may also single step to the next iteration.

    \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "
    \n" + "\n"); - sprintf(message, - "\n", - pause ? "checked" : ""); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, + "\n"); + Send_HTTP_String(request, message); - sprintf(message, - "\n", - pause ? "" : "checked"); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, + "\n"); + Send_HTTP_String(request, message); - strcpy(message, - "\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "\n"); - strcpy(message, - "\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "\n"); - strcpy(message, - "
    PAUSE PAUSE RUN RUN TERMINATE TERMINATE
    \n" - "\n" - "\n" - "\n" - "
    \n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "

    Run Until

    \n" - "

    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.

    "); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "\n"); - - sprintf(message,"%s" - "" - "\n" - "\n", message, until_it, until_it_active ? "checked" : ""); - sprintf(message,"%s" - "" - "\n" - "\n", message, until_time, until_time_active ? "checked" : ""); - sprintf(message,"%s" - "" - "\n" - "\n", message, until_expression, until_expression_active ? "checked" : ""); - - strcat(message,"
    Iteration
    Time
    Expression
    \n"); + Send_HTTP(request, + "\n" + "\n" + "\n" + "\n" + "\n" + "
    \n"); + + Send_HTTP(request, + "

    Run Until

    \n" + "

    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.

    \n"); + + SetToCString(message, + "\n"); + + ConcatCString(message,"" + "\n" + "\n" + "\n"); + ConcatCString(message, + "" + "\n" + "\n" + "\n"); + ConcatCString(message, + "\n" + "\n" + "\n" + "\n"); + + ConcatCString(message,"
    Iteration
    Time
    Expression
    \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message, - "\n" - "
    \n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "\n" + "\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,"Running CACTUS Status Information : Terminated\n"); + Send_HTTP(request, "\n"); + Send_HTTP(request, "Running CACTUS Status Information : Terminated\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, "\n\n"); - strcpy(message, "

    Simulation Home Page

    "); + /* 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, "

    Simulation Home Page

    \n"); /* Some blurb */ - strcpy(message, "
    " - "
    " - "

    Simulation web server:

    " - "

    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

    " - "

    Depending on which other thorns are active, there may be additional " - "features available, such as the viewing and downloading of output files

    "); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "
    \n" + "
    \n" + "

    Simulation web server:

    \n" + "

    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

    \n" + "

    Depending on which other thorns are active, there may be \n" + "additional features available, such as the viewing and \n" + "downloading of output files

    \n"); /* CONFIGURATION DETAILS */ - sprintf(message, "

    Simulation:

    " - "
    • Flesh version %s" - "
    • \n" - "
    • Flesh compiled on " - __DATE__ " at "__TIME__ "
    • \n" - ,CCTK_FullVersion()); + SetToCString(message, + "

      Simulation:

      \n" + "
      • Flesh version "); + ConcatCString(message, CCTK_FullVersion() ); + ConcatCString(message, + "
      • \n" + "
      • Flesh compiled on __DATE__ \n" + "at __TIME__
      • \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); if (cctkGH) { if (CCTK_nProcs(cctkGH) == 1) { - strcpy(message,"
      • Single processor run
      • "); + SetToCString(message,"
      • Single processor run
      • \n"); } else { - sprintf(message,"
      • Multiprocessor run on %d CPUs
      • ", - CCTK_nProcs(cctkGH)); + SetToCString(message,"
      • Multiprocessor run on "); + ConcatDecimal( message, CCTK_nProcs(cctkGH) ); + ConcatCString( message, " CPUs
      • \n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); } - strcpy(message,"
      "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"
    \n"); - /******************************************************************************/ + /************************************************************************/ /* NEW COLUMN */ - strcpy(message, "
    "); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, ""); - /*******************************************************************************/ + /************************************************************************/ /* CURRENT STATE OF SIMULATION */ if (cctkGH) { - sprintf(message, "

    Current state:

    " - "
    • Physical time %f" - "\n" - "
    • Iteration number %d" - "
    • \n", - cctkGH->cctk_time, - cctkGH->cctk_iteration); + SetToCString(message, + "

      Current state:

      \n" + "
      • Physical time "); + ConcatDouble(message, cctkGH->cctk_time ); + ConcatCString(message, + "
      • \n" + "
      • Iteration number "); + ConcatDecimal(message, cctkGH->cctk_iteration ); + ConcatCString(message, "
      • \n"); } else { - strcpy(message, "
      • Current cactus state is unknown
      • \n"); + SetToCString(message, "
      • Current cactus state is unknown
      • \n"); } - HTTP_Write(request, message, strlen(message)); - - strcpy(message, "
      • This Cactus run is over.
      • \n"); - - HTTP_Write(request, message, strlen(message)); - - strcpy(message, "
      "); + Send_HTTP_String(request, message); + Send_HTTP(request, "
    • This Cactus run is over.
    • \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "
    "); /* 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, "

    Compiled thorns:

    " - "

    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 " - "red

    " - "
      \n"); + SetToCString(message, + "

      Compiled thorns:

      \n" + "

      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 red

      \n" + "
        \n"); for(i=0; i < nthorns; i++) { - strcat(message, "
      • "); + ConcatCString(message, "
      • "); if (CCTK_IsThornActive(thorns[i])) { - sprintf(message,"%s%s\n", message, thorns[i]); + ConcatCString(message, " "); + ConcatCString(message, thorns[i]); + ConcatCString(message, " "); } else { - sprintf(message, "%s%s\n", message, thorns[i]); + ConcatCString(message, thorns[i]); } + ConcatCString(message, "
      • \n"); } - strcat(message, "
      \n"); + ConcatCString(message, "
    \n"); free(thorns); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); /* Finish table started by blurb */ - strcpy(message, "
    "); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "
    \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, "About Cactus Server\n"); - HTTP_ContentHeader(cctkGH,0,4098,message,NULL); - strcat(message,""); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "\nAbout Cactus Server\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - strcpy(message, "
    "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "\n\n"); + SetHTML_ContentHeader(cctkGH,0,message,NULL); + Send_HTTP_String(request, message); - strcpy(message, "

    About this Web Server

    "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "

    About this Web Server

    \n"); - strcpy(message, "

    These web pages are served by a simulation " - "which is using the Cactus Code and Computational ToolKit, " + SetToCString(message, "

    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.

    " - "

    The HTTPD module, or thorn " - "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.

    " - "

    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.

    "); + " portable and \n" + "modular programming environment for HPC.

    \n" + "

    The HTTPD module, or thorn " + "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.

    \n" + "

    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.

    \n"); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP_String(request, message); - strcpy(message, "

    For more information about Cactus, visit our " - "permanent home page at " - "www.cactuscode.org

    "); + SetToCString(message, "

    For more information about Cactus, visit our " + "permanent home page at \n" + "www.cactuscode.org

    \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, "Cookie Test\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "Cookie Test\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, "\n\n"); - strcat(message, "

    Cookie Test

    "); + SetHTML_ContentHeader(cctkGH,0,message,NULL); + Send_HTTP_String(request, message); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "

    Cookie Test

    \n"); - strcpy(message, "
    "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "
    "); value = HTTP_HeaderValue(request, "Cookie"); - sprintf(message, "

    Cookie was '%s'

    \n", value); + SetToCString(message, "

    Cookie was '"); + ConcatCString(message, value); + ConcatCString(message, "'

    \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); value2 = HTTP_CookieGet(request,"user3"); - sprintf(message, "

    Cookie from decoder was '%s'

    \n", value2); + SetToCString(message, "

    Cookie from decoder was '"); + ConcatCString(message, value2); + ConcatCString(message, "'

    \n"); free(value2); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message,"
    "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"\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,"\n"); + Send_HTTP(request,"Cactus Simulation Group Information\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - /* Start the page */ - strcpy(message,"Cactus Simulation Group Information\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"\n\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, "

    Groups and Grid Variables

    " - "

    These pages describe the grid variables and groups " - "active in this simulation.

    "); - retval = HTTP_Write(request, message, strlen(message)); - - sprintf(message,"

    This simulation contains %d groups, and %d variables, " - "set in %d-space dimensions. Groups for which storage is " - "currently assigned are written in red. " + retval = Send_HTTP(request, "

    Groups and Grid Variables

    \n" + "

    These pages describe the grid variables and groups \n" + "active in this simulation.

    \n"); + + SetToCString(message, + "

    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 red. \n" "The numbers in square brackets are the group and variable indices." - "

    ", - CCTK_NumGroups(),CCTK_NumVars(), - CCTK_MaxDim()); - retval = HTTP_Write(request, message, strlen(message)); + "

    \n"); + retval = Send_HTTP_String(request, message); - strcpy(message,"
    \n"); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP(request,"\n"); - strcpy(message,"
    " + retval = Send_HTTP(request,"
    \n" + "
    \n" "" - ""); - retval = HTTP_Write(request, message, strlen(message)); + "\n"); for(i=0; i < ngroups; i++) { - strcpy(message,""); + SetToCString(message,""); groupname = CCTK_GroupName(i); if (CCTK_QueryGroupStorageI(cctkGH,i)) { - sprintf(message,"%s " - "\n", message, i, groupname); + ConcatCString(message, " \n"); } else { - sprintf(message,"%s \n", - message, i, groupname); - } + ConcatCString(message, " \n"); + } free(groupname); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); /* Group Description */ - sprintf(message,""); + Send_HTTP(request,""); nvars = CCTK_NumVarsInGroupI(i); - strcat(message,""); - HTTP_Write(request, message, strlen(message)); + ConcatCString(message,""); + Send_HTTP_String(request, message); - /* - strcpy(message,"",message); - HTTP_Write(request, message, strlen(message)); - */ } - strcpy(message,"
    GroupsGroup PropertiesVariables
    Variables
    [%d] %s["); + ConcatDecimal(message, i); + ConcatCString(message, "] "); + ConcatCString(message, groupname); + ConcatCString(message, "[%d] %s["); + ConcatDecimal(message, i); + ConcatCString(message, "] "); + ConcatCString(message, groupname); + ConcatCString(message, ""); + SetToCString(message, ""); - 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
    (%d bytes)", message, - CCTK_VarTypeName(gdata.vartype),CCTK_VarTypeSize(gdata.vartype)); + ConcatCString(message, " " ); + ConcatCString(message, CCTK_VarTypeName(gdata.vartype) ); + ConcatCString(message, "
    \n("); + ConcatDecimal(message, CCTK_VarTypeSize(gdata.vartype)); + ConcatCString(message, " bytes)"); if (!(CCTK_GroupTypeI(i) == CCTK_SCALAR)) { - sprintf(message,"%s
    Dimension %d",message,gdata.dim); - sprintf(message, "%s
    Timelevels %d",message, gdata.numtimelevels); + ConcatCString(message, "
    \nDimension "); + ConcatDecimal(message, gdata.dim); + ConcatCString(message, "
    \nTimelevels "); + ConcatDecimal(message, gdata.numtimelevels); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); } - strcpy(message,"
    "); + SetToCString(message,"
    "); for(j=CCTK_FirstVarIndexI(i); j < CCTK_FirstVarIndexI(i)+nvars; j++) { - sprintf(message,"%s
    [%d] %s\n", message, j, CCTK_VarName(j) ); + ConcatCString(message, "[" ); + ConcatDecimal(message, j); + ConcatCString(message, "] " ); + ConcatCString(message, CCTK_VarName(j) ); + ConcatCString(message, "
    \n" ); } - strcat(message,"
    "); - if (CCTK_GroupTypeI(i) == CCTK_SCALAR) - { - for(j=CCTK_FirstVarIndexI(i); j < CCTK_FirstVarIndexI(i)+nvars; j++) - { - sprintf(message,"%s " - "
    ", - message,j,watch[j] ? "checked" : "unchecked"); - } - } - else - { - strcat(message," "); - } - sprintf(message,"%s
    \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"\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 = -"\n" -"\n" -"
    " -"\"Cactus\"" -"" -"
    " -"\n"; +static const char *cactus_styles = +"\n"; static const char *cactus_footer = -"
    \n" -"\n" -"\n" -"

    \n" -"\n" -"" -"
    \n" -"
    \n" -"
    " -"Cactus Web Interface by The Cactus Team
    \n" -"About this Server" -"
    " -"\n"; - +"\n\n" +"\n\n" +"\n\n" +"\n" +"

    \n" +"" +"\"www.CactusCode.org\"\n" +"" +"Cactus Web Interface by \n" +"The Cactus Team
    \n" +"About this Server\n" +"
    \n" +"\n" +"\n"; + +static const char * cactus_doctype = +"\n" +"\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, + "\n" + "\n" + "
    \n" + "

    Master Run Page

    \n"); + } if(ContentLinks) { - strcpy(quicklinks,"
    Options:"); + SetToCString( quicklinks,"

    Options:

    \n"); for(link = ContentLinks; link; link=link->next) { - sprintf(quicklinks, - "%s
    %s
    \n", - quicklinks, link->URL, link->name); - + ConcatCString(quicklinks, "URL); + ConcatCString(quicklinks, "\">"); + ConcatCString(quicklinks, link->name); + ConcatCString(quicklinks, "
    \n"); } - - sprintf(quicklinks,"%s
    \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, - "\n" - "\n" - "
    \n" - "\n" - "\n" - "\n\n
    \n"); - strcat(header, "Master Run Page\n"); - sprintf(header,"%s\n" - "\n
    \n" - "
    Environment:\n" - "
    Time: %s\n" - "
    Date: %s\n" - "
    \n", - header,currenttime,currentdate); - sprintf(header, - "%s
    \n" - "
    Simulation:\n" - "
    %s\n" - "
    %s\n" - "
    Iteration: %d\n" - "
    Physical time: %4.2f\n" - "
    \n" - ,header,title,file, - GH ? GH->cctk_iteration : 0 , GH ? GH->cctk_time : 0); + ConcatCString( header, + "\n" + "

    Environment:

    \n" + "Time: "); + ConcatCString( header, currenttime ); + ConcatCString( header, + "
    \n" + "Date: " ); + ConcatCString( header, currentdate ); + ConcatCString( header, + "
    \n" ); + ConcatCString( header, + "

    Simulation:

    \n" + ""); + Concat( header, title ); + ConcatCString( header, + "
    \n" + ""); + ConcatCString( header, file ); + ConcatCString( header, + "
    \n" + "Iteration: "); + ConcatDecimal( header, GH ? GH->cctk_iteration : 0 ); + ConcatCString( header, + "
    \nPhysical time: "); + ConcatFormattedDouble( header, 4, 2, GH ? GH->cctk_time : 0 ); + ConcatCString( header, + "
    \n"); if (ContentLinks) { - strcat(header,quicklinks); + Concat( header, quicklinks); } - strcat(header,"
    \n"); if (menu) { - strcat(header,"
    \n"); - strcat(header,menu); - strcat(header,"
    \n"); + Concat( header, menu); } - /* Online links */ - /* - sprintf(header,"%s\n" - "
    " - "
    On-Line:\n" - "
    Cactus Homepage\n" - "
    Users Guide\n" - "
    Cactus Helpdesk\n" - "
    \n", - header,currenttime,currentdate); - */ - - strcat(header,"
    \n"); - } - else - { - sprintf(header,"%s",cactus_mainheader); + ConcatCString( header, + "\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, "Cactus Parameters Request\n"); - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"\n"); - HTTP_Write(request, message, strlen(message)); - - HTTP_ContentHeader(cctkGH,0,4098,message,NULL); - HTTP_Write(request, message, strlen(message)); - - strcpy(message, "
    "); - HTTP_Write(request, message, strlen(message)); - - strcpy(message, - "

    Check/Modify Parameters

    \n" - "

    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 steerable

    \n" - "

    Parameters can be viewed for all Active Thorns, 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

    \n" - "

    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.

    \n" - "" - "\n"); - - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "Cactus Parameters Request\n"); + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); + Truncate( message, 0 ); + + Send_HTTP(request, "\n\n\n"); + + SetHTML_ContentHeader(cctkGH,0,message,NULL); + Send_HTTP_String(request, message); + + Send_HTTP(request, + "

    Check/Modify Parameters

    \n" + "

    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 steerable

    \n" + "

    Parameters can be viewed for all Active Thorns, 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

    \n" + "

    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.

    \n" + "
    \n" + "
    Thorn NameImplementation
    \n" + "\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, - "\n" - "\n" - "\n" - "\n", - thorn, thorn,CCTK_ThornImplementation(thorn)); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "\n\n\n\n"); + Send_HTTP_String(request, message); } } - strcpy(message,"
    Thorn NameImplementation
    %s%s
    "); + ConcatCString(message, thorn); + ConcatCString(message, ""); + ConcatCString(message, CCTK_ThornImplementation(thorn)); + ConcatCString(message, "
    "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"
    "); /* 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, - "Cactus Parameters Request : %s\n", thorn); + SetToCString(message, "\nCactus Parameters Request : "); + ConcatCString(message, thorn); + ConcatCString(message, "\n"); + Send_HTTP_String(request, message ); + + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); + Truncate( message, 0 ); + + Send_HTTP(request, "\n\n"); - HTTP_Write(request, message, strlen(message)); if (CCTK_NumCompiledThorns()>0) { - strcpy(menu,"
    Parameters:\n"); + SetToCString(menu, "

    Parameters:

    \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
    %s\n", - menu,menuthorn, menuthorn); + ConcatCString(menu, " "); + ConcatCString(menu, menuthorn); + ConcatCString(menu, "
    \n"); } } - HTTP_ContentHeader(cctkGH,0,4098,message,menu); - strcat(message,""); - HTTP_Write(request, message, strlen(message)); + SetHTML_ContentHeader(cctkGH,0,message,menu); + Send_HTTP_String(request, message); if (!CCTK_IsThornActive(thorn)) { - sprintf(message," Thorn %s is not active !!!
    \n",thorn); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, " Thorn "); + ConcatCString(message, thorn); + ConcatCString(message, " is not active !!!
    \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, - "

    Check/Modify Parameters

    " - "

    Thorn %s

    \n", - thorn); - strcat(message, - "

    Parameters in Cactus can be either fixed or steerable. " - "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.

    \n" - "

    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.

    " - "
    \n"); - - HTTP_Write(request, message, strlen(message)); + SetToCString(message, + "

    Check/Modify Parameters

    \n" + "

    Thorn "); + ConcatCString(message, thorn); + ConcatCString(message, + "

    \n"); + ConcatCString(message, + "

    Parameters in Cactus can be either fixed or steerable. \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.

    \n" + "

    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.

    " + "\n"); + + Send_HTTP_String(request, message); + Send_HTTP(request, "
    \n"); if(!readonly ) { - sprintf(message,"
    ",thorn); - HTTP_Write(request, message, strlen(message)); + SetToCString(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,"

    Steerable Parameters

    "); + ConcatCString(message,"

    Steerable Parameters

    \n"); if (readonly) { - strcat(message,"

    The following parameters are steerable, " - "but you do not have authorisation to change them. " + ConcatCString(message, + "

    The following parameters are steerable, " + "but you do not have authorisation to change them. \n" "To change parameters you must first register on the " "Simulation Control Page." - "

    "); + "

    \n"); } - strcat(message,""); + ConcatCString(message, + "
    \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\n" - "\n" - "\n\n" + "\n" - "\n" - "\n", - message,pData->thorn,pData->name, - pData->name,pData->name, - param_bool ? "checked" : "", pData->name, - param_bool ? "" : "checked",pData->description,pData->defval); + "No \nname); + ConcatCString(message, "\" "); + ConcatCString(message, param_bool ? "" : "checked=\"checked\""); + ConcatCString(message, " value=\"0\" />" + "\n" + "\n" + "\n"); } else if (pData->type == PARAMETER_KEYWORD) { /* Steerable keyword */ CCTK_ParameterGet(pData->name,thorn,¶m_type); - sprintf(message,"%s\n" - "\n" - "\n\n"); + ConcatCString(message,"\n" - "\n" - "\n", - message,pData->description,pData->defval); + ConcatCString(message,"\n"); + ConcatCString(message,"\n\n\n"); } else { /* Steerable nonboolean */ - sprintf(message, - "%s\n" - "\n" - "\n" - "\n\n", - message, pData->thorn, pData->name, - pData->name, pData->name, - value, pData->description,pData->defval); + ConcatCString(message, "\n\n" + "\n" + "\n\n"); } } else { /* Steerable but no authority */ - sprintf(message, - "%s\n" - "\n", - message, pData->thorn, pData->name, - pData->name, value, pData->description,pData->defval); + ConcatCString(message, "\n\n"); } } free (value); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); } if (nsteerable>0) { - strcpy(message, "
    " - "%s" - "Yes " + ConcatCString(message, "
    thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, "" + "Yes \nname); + ConcatCString(message, "\" "); + ConcatCString(message, param_bool ? "checked=\"checked\"" : ""); + ConcatCString(message, " value=\"1\" />" " " - "No " - "%s (%s)
    "); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp ); + ConcatCString(message, " ("); + ConcatCString(message, pData->defval); + ConcatCString(message, ")
    " - "%s\n", - message,pData->thorn,pData->name,pData->name); - sprintf(message,"%s
    thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, " \n"); - sprintf(message,"%s%s (%s)
    "); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, " ("); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, ")
    " - "%s" - "%s (%s)
    thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, "name); + ConcatCString(message, "\" value=\""); + ConcatCString(message, value); + ConcatCString(message, "\" />"); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, " ("); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, ")
    " - "%s%s" - "%s (%s)
    thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, ""); + ConcatCString(message, value); + ConcatCString(message, ""); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, " ("); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, ")
    \n"); + Send_HTTP(request, "
    \n"); } else { - strcpy(message, "

    This thorn has no steerable parameters.

    \n"); + Send_HTTP(request, "

    This thorn has no steerable parameters.

    \n"); } - HTTP_Write(request, message, strlen(message)); if(!readonly && nsteerable>0) { - strcpy(message, - "\n" - "\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "\n" + "\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,"

    Fixed Parameters

    " - ""); + ConcatCString(message,"

    Fixed Parameters

    \n" + "
    "); } nfixed++; @@ -601,51 +636,54 @@ static int ThornParameterPage(const cGH *cctkGH, httpRequest *request, void *dat strcmp(pData->name,"encryption_scheme"))) { - sprintf(message, - "%s\n" - "\n" - "\n" - "\n" - "\n", - message, pData->thorn, pData->name, - pData->name, value, pData->description,pData->defval); + ConcatCString(message, "\n\n" + "\n\n\n"); } } free(value); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); } if (nfixed>0) { - strcpy(message, "
    " - "%s%s%s (%s)
    thorn); + ConcatCString(message, "/"); + ConcatCString(message, pData->name); + ConcatCString(message, "\">"); + ConcatCString(message, pData->name); + ConcatCString(message, ""); + ConcatCString(message, value); + ConcatCString(message, ""); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, " ("); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, ")
    \n"); + Send_HTTP(request, "\n"); } else { - strcpy(message, "

    This thorn has no fixed parameters.

    \n"); + Send_HTTP(request, "

    This thorn has no fixed parameters.

    \n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, "\n"); } - strcpy(message,"
    "); - - 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, "\n"); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "Cactus Parameter Request : "); + ConcatCString(message, pData->name); + ConcatCString(message, "\n"); - /* Start the page */ - sprintf(message, - "Cactus Parameter Request : %s" - "\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,"\n\n"); /* Menu for this page */ @@ -783,26 +777,39 @@ static int ParameterPage(const cGH *cctkGH, httpRequest *request, void *data) { if (first==1) { - sprintf(menu,"
    %s:\n",pDataWalk->thorn); + ConcatCString(menu,"

    "); + ConcatCString(menu, pDataWalk->thorn); + ConcatCString(menu, ":

    \n"); } first = 0; - sprintf(menu, - "%s
    %s\n", - menu,pDataWalk->thorn,pDataWalk->name,pDataWalk->name); + ConcatCString(menu, " thorn); + ConcatCString(menu, "/"); + ConcatCString(menu, pDataWalk->name); + ConcatCString(menu, "\">"); + ConcatCString(menu, pDataWalk->name); + ConcatCString(menu, "
    \n"); } - HTTP_ContentHeader(cctkGH,0,4098,message,menu); - HTTP_Write(request, message, strlen(message)); - - sprintf(message,"

    %s: %s

    \n",pData->thorn,pData->name); - HTTP_Write(request, message, strlen(message)); - - sprintf(message, - "

    Return to all parameters for this " - "thorn.

    ", - CCTK_ThornImplementation(pData->thorn)); - - HTTP_Write(request, message, strlen(message)); + SetHTML_ContentHeader(cctkGH,0,message,menu); + Send_HTTP_String(request, message); + + SetToCString(message,"

    "); + ConcatCString(message, pData->thorn); + ConcatCString(message, ": "); + ConcatCString(message, pData->name); + ConcatCString(message, "

    \n"); + Send_HTTP_String(request, message); + + SetToCString(message, + "
    Return to all parameters for this \n" + "thorn)); + ConcatCString(message, + "\">thorn.
    "); + + 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,"
    \n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "" - "\n" - "\n" - "\n" - "" - "" - "\n" - "\n" - "", - pData->name,pData->thorn,CCTK_ThornImplementation(pData->thorn), - value,pData->description,pData->defval); - HTTP_Write(request, message, strlen(message)); - - strcpy(message,"\n\n\n\n\n\n
    Name:%s
    Thorn:%s
    Implementation:%s
    Current value:%s
    Description:%s
    Default:%s
    \n" - "Steerable:"); + SetToCString(message,"
    \n" + "\n" ); + ConcatCString(message, "\n\n\n\n" ); + ConcatCString(message, "\n\n\n\n" ); + ConcatCString(message, "\n\n\n\n" ); + ConcatCString(message, "\n\n\n\n" ); + ConcatCString(message, "\n\n\n\n" ); + ConcatCString(message, "\n\n\n"); + Send_HTTP_String(request, message); + SetToCString(message,"\n\n\n\n"); - HTTP_Write(request, message, strlen(message)); + ConcatCString(message,"\n\n"); + Send_HTTP_String(request, message); - strcpy(message,"\n" - "\n\n" + "\n\n\n"); + ConcatCString(message,"\n\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - strcpy(message,""); + ConcatCString(message,"Global\n"); break; case SCOPE_RESTRICTED : - strcat(message,"Restricted"); + ConcatCString(message,"Restricted\n"); break; case SCOPE_PRIVATE : - strcat(message,"Private"); + ConcatCString(message,"Private\n"); break; default : - strcat(message,"Not matched"); + ConcatCString(message,"Not matched\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\n" - "\n\n" + "\n\n\n"); + ConcatCString(message, "\n\n"); } - HTTP_Write(request, message, strlen(message)); + Send_HTTP_String(request, message); - sprintf(message, - "\n" - "\n" - "\n" - "\n" - "
    Name:"); + ConcatCString(message, pData->name); + ConcatCString(message, "
    Thorn:"); + ConcatCString(message, pData->thorn); + ConcatCString(message, "
    Implementation:"); + ConcatCString(message, CCTK_ThornImplementation(pData->thorn)); + ConcatCString(message, "
    Current value:"); + ConcatCString(message, value); + ConcatCString(message, "
    Description::"); + SetToEncodedHTMLCString( temp, pData->description ); + Concat(message, temp); + ConcatCString(message, "
    Default:::"); + SetToEncodedHTMLCString( temp, pData->defval ); + Concat(message, temp); + ConcatCString(message, "
    Steerable:"); 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,"
    Type:\n"); + SetToCString(message,"
    Type:"); 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,"
    Scope:"); + SetToCString(message,"
    Scope:"); switch(pData->scope) { case SCOPE_GLOBAL : - strcat(message,"Global
    \n" - "Range:" - "
    \n", - message); + ConcatCString(message, + "
    \n" + "Range:" + "
    \n" + ); } first = 0; - sprintf(message,"%s
    %s\n
    %s\n", - message,range->range,range->description); + ConcatCString(message, "
    "); + ConcatCString(message, range->range); + ConcatCString(message, "
    \n
    "); + SetToEncodedHTMLCString( temp, range->description ); + Concat(message, temp); + ConcatCString(message, "
    \n"); if (!CCTK_Equals(range->origin,pData->thorn)) { - sprintf(message,"%s
    [Extended by thorn %s]\n", - message,range->origin); + ConcatCString(message, "
    [Extended by thorn "); + ConcatCString(message, range->origin); + ConcatCString(message, "]\n"); } } if(first==0) { - strcat(message,"
    Times Set:%d
    \n", - pData->n_set); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "
    Times Set:"); + ConcatDecimal(message, pData->n_set); + ConcatCString(message, "
    \n\n"); + Send_HTTP_String(request, message); } else { - strcpy(message,"

    Hidden parameter, information is not available

    "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"

    Hidden parameter, information is not available

    \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(iServer Redirect\n"); + SetToCString(message,"Server Redirect\n"); /* Write out the main header part */ - HTTP_Write(request, message, strlen(message)); - sprintf(message,"\n", - HTTP_Master(), (unsigned int) HTTP_Port()); - HTTP_Write(request,message,strlen(message)); + Send_HTTP_String(request, message); + SetToCString(message,"\n\n\n"); + Send_HTTP_String(request,message); /* ********** Server Redirect To Master ************* */ - sprintf(message,"

    Redirect to master host=%s:%u

    \n", - HTTP_Master(), (unsigned int) HTTP_Port()); - HTTP_Write(request,message,strlen(message)); + SetToCString(message,"

    Redirect to master host="); + ConcatCString(message,HTTP_Master()); + ConcatCString(message, ":"); + ConcatDecimal(message,(unsigned int) HTTP_Port()); + ConcatCString(message, "

    \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 +#include + +#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 + +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 + + /* 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 = -"\nError 404: Not Found\ -The URI you requested could not be found\n\n"; +"\n\nError 404: Not Found\n\n" +"\nThe URI you requested could not be found\n\n\n"; static const char *notimplemented_page = -"\nError 501: Not Implemented\ -The requested method is not implemented\n\n"; +"\n\nError 501: Not Implemented\n\n" +"\nThe requested method is not implemented\n\n\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;iCactus Thorns\n"); + Send_HTTP(request,"Cactus Thorns\n"); + + SetHTML_HeadHeader( message); + Send_HTTP_String(request, message ); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"\n\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, "

    Thorns

    " - "

    These pages describe the thorns used in this simulation.

    "); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP(request, "

    Thorns

    \n" + "

    These pages describe the thorns used in this simulation.

    \n"); - strcpy(message,"
    "); - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP(request,"
    \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, - "

    Active Thorns

    \n" - "
    \n" - "" - "\n" - "\n" - "\n" - "\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "

    Active Thorns

    \n" + "
    \n" + "
    Thorn NameImplementation
    \n" + "\n" + "\n" + "\n" + "\n"); foundone++; } - sprintf(message, - "\n" - "\n" - "\n" - "\n", - thorn, thorn,CCTK_ThornImplementation(thorn)); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "\n\n\n\n"); + Send_HTTP_String(request, message); } } if (foundone) { - strcpy(message,"
    Thorn NameImplementation
    %s%s
    "); + ConcatCString(message, thorn); + ConcatCString(message, ""); + ConcatCString(message, CCTK_ThornImplementation(thorn)); + ConcatCString(message, "
    "); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"
    \n"); } - - strcpy(message,"
    "); - retval = HTTP_Write(request, message, strlen(message)); - + retval = Send_HTTP(request,""); 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, - "

    Dormant Thorns

    \n" - "
    " - "\n" - "\n" - "\n" - "\n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request, + "

    Dormant Thorns

    \n" + "
    \n" + "
    Thorn NameImplementation
    \n" + "\n" + "\n" + "\n" + "\n"); foundone++; } - sprintf(message, - "\n" - "\n" - "\n" - "\n", - thorn, CCTK_ThornImplementation(thorn)); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "\n\n\n\n"); + Send_HTTP_String(request, message); } } if (foundone) { - strcpy(message,"
    Thorn NameImplementation
    \n" - "%s%s
    \n"); + ConcatCString(message, thorn); + ConcatCString(message, ""); + ConcatCString(message, CCTK_ThornImplementation(thorn)); + ConcatCString(message, "
    \n
    \n"); - HTTP_Write(request, message, strlen(message)); + Send_HTTP(request,"
    \n\n"); } - strcpy(message,"\n\n\n"); - - retval = HTTP_Write(request, message, strlen(message)); + retval = Send_HTTP(request,"\n\n\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, - "Thorn Page : %s\n", thorn); + SetToCString(message, "\n\nThorn Page : "); + ConcatCString(message, thorn); + ConcatCString(message, "\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,"\n\n"); - strcat(message,""); - HTTP_Write(request, message, strlen(message)); + SetHTML_ContentHeader(cctkGH,0,message,NULL); - sprintf(message,"

    Thorn %s

    \n",thorn); - HTTP_Write(request, message, strlen(message)); - - sprintf(message,"

    This page will include all the information about thorn" - "%s. For now, only information about the parameters is given.

    ", - thorn); + Send_HTTP_String(request, message); - sprintf(message,"%s\n", - message,thorn); - HTTP_Write(request, message, strlen(message)); + SetToCString(message, "

    Thorn "); + ConcatCString(message, thorn); + ConcatCString(message, "

    \n"); + + Send_HTTP_String(request, message); + + SetToCString(message,"

    This page will include all the information about thorn \'"); + ConcatCString(message, thorn); + ConcatCString(message, + "\'.\n For now, only information about the parameters is given.

    \n"); + + ConcatCString(message, "\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; } diff --git a/src/http.c b/src/http.c index 58590ed..4520d73 100644 --- a/src/http.c +++ b/src/http.c @@ -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) -- cgit v1.2.3