diff options
Diffstat (limited to 'src/IO.c')
-rw-r--r-- | src/IO.c | 480 |
1 files changed, 272 insertions, 208 deletions
@@ -9,31 +9,24 @@ @@*/ #include "cctk.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> +#include "cctk_Parameters.h" #include <fcntl.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif -#include "util_String.h" - #include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h" #include "http_Content.h" -/* SW Temporary, while testing the SString module*/ -#include "CactusConnect/HTTPD/src/SString.h" +#include "HTTPD_FileList.h" + +/* SW Temporary, while testing the SString module */ #include "CactusConnect/HTTPD/src/SString_Namespace.h" static const char *rcsid = "$Header$"; -CCTK_FILEVERSION(CactusConnect_HTTPDExtra_IO_c) - +CCTK_FILEVERSION(CactusConnect_HTTPDExtra_IO_c); /******************************************************************** ******************** Macro Definitions ************************ @@ -42,24 +35,9 @@ CCTK_FILEVERSION(CactusConnect_HTTPDExtra_IO_c) #define O_BINARY 0 #endif - /******************************************************************** ********************* Internal Typedefs ********************** ********************************************************************/ -struct httpuFileList -{ - struct httpuFileList *next; - char *filename; - char *linkname; - ioAdvertisedFileDesc data; -}; - -struct httpuMimeType -{ - struct httpuMimeType *next; - const char *name; -}; - /******************************************************************** ******************** Internal Routines ************************ @@ -80,9 +58,7 @@ int HTTP_util_RegisterIOPages(void); /******************************************************************** ********************* Local Data ***************************** ********************************************************************/ -static struct httpuFileList *filelist = NULL; -static struct httpuMimeType *mimetypes = NULL; - +static FileList *filelist = NULL; /*@@ @routine HTTP_util_RegisterIOPages @@ -106,20 +82,20 @@ int HTTP_util_RegisterIOPages(void) listener.advertise = IOFileListener; - IOUtil_RegisterAdvertisedFileListener (NULL, CCTK_THORNSTRING, + IOUtil_RegisterAdvertisedFileListener ( NULL, CCTK_THORNSTRING, &listener); - HTTP_RegisterPage("/Output/index.html", AdvertisedFilePage, NULL); - HTTP_RegisterPage("/Output/viewport.html", ViewportFilePage, NULL); + HTTP_RegisterPage( "/Output/index.html", AdvertisedFilePage, NULL); + HTTP_RegisterPage( "/Output/viewport.html", ViewportFilePage, NULL); - HTTP_ContentLink("/Output/index.html", "Files", + HTTP_ContentLink( "/Output/index.html", "Files", "Downloadable files", HTTP_QUICKLINK); - HTTP_ContentLink("/Output/viewport.html", "Viewport", + HTTP_ContentLink( "/Output/viewport.html", "Viewport", "Viewport for certain output files", HTTP_QUICKLINK); - HTTP_RegisterPage("/Output", SendFilePage, NULL); + HTTP_RegisterPage( "/Output", SendFilePage, NULL); return 0; } @@ -139,66 +115,115 @@ int HTTP_util_RegisterIOPages(void) static int IOFileListener(const cGH *GH, const char *filename, const ioAdvertisedFileDesc *description) { - struct httpuFileList *entry; - struct httpuMimeType *type; - char *position; + size_t position = 0; + httpFileItem *entry = (httpFileItem *)malloc( sizeof( httpFileItem)); - /* avoid compiler warning about unused parameter */ - (void) (GH + 0); - - entry = (struct httpuFileList *)malloc(sizeof(struct httpuFileList)); + (void) (GH + 0); /* avoid compiler warning about unused parameter */ if(entry) { - entry->next = NULL; - entry->filename = Util_Strdup(filename); - entry->linkname = Util_Strdup(filename); - entry->data.thorn = Util_Strdup(description->thorn); - entry->data.varname = Util_Strdup(description->varname); - entry->data.mimetype = Util_Strdup(description->mimetype); - entry->data.slice = Util_Strdup(description->slice); - entry->data.description = Util_Strdup(description->description); - - entry->next = filelist; - filelist = entry; +/* SW--HEY where does this all get deleted ? */ + String *linknameString = String_Make( filename); + entry->thorn = String_Make( description->thorn); + entry->varname = String_Make( description->varname); + entry->mimetype = String_Make( description->mimetype); + entry->slice = String_Make( description->slice); + entry->description = String_Make( description->description); + entry->filename = String_Make( filename); + entry->linkname = linknameString; + + if( filelist == NULL ) + filelist = HTTPD_FileList_New(); + AppendFile( filelist, entry ); /* Need to mangle the filename to get a decent linkname */ - for(position=entry->linkname; *position;position++) + while( FindCharFrom( linknameString, '/', &position ) ) + SetNthChar( linknameString, position, '@'); + } + + return 0; +} + +static void +IndentAndConcatCString( String *message, const char *c, int depth ) +{ + int i; + for ( i = 0; i < depth; i++ ) + ConcatCString( message, "\t" ); + ConcatCString( message, c ); +} +/* + * SW + * Build a HTML representation of the contents of filelist. + * Denis wanted variable name on the topmost level. + * This is about third iteration. Here, use tables to get nesting effect. + */ +static size_t +buildList( const FileList *list, String * message, size_t itemNo, int depth ) +{ + const size_t n = NumberOfFiles( filelist ); + size_t i = 0; + httpFileItem *lastItem = FileItem( filelist, itemNo ); + + for ( i = itemNo; i < n; i++ ) + { + httpFileItem *file = FileItem( filelist, i ); + if( depth == 0 ) { - if(*position == '/') - { - *position = '@'; - } + IndentAndConcatCString( message, "<tr>", depth ); + ConcatCString( message, "<td colspan=\"5\" class=\"variable\">" ); + Concat( message, file->varname ); + ConcatCString( message, " " ); + IndentAndConcatCString( message, "</td></tr>\n", depth ); + i = buildList( list, message, i, 1 ); } - - for(type=mimetypes; type; type=type->next) + if( depth == 1 ) { - if(!strcmp(type->name,entry->data.mimetype)) + if( Equals( file->varname, lastItem->varname ) ) { - break; + IndentAndConcatCString( message, "<tr>", depth ); + ConcatCString( message, "<td class=\"spacer\"> </td>" + "<td class=\"thorn\" colspan=\"4\">" ); + Concat( message, file->thorn ); + IndentAndConcatCString( message, "</td></tr>\n", depth ); + i = buildList( list, message, i, 2 ); } + else + break; } - - /* Keep a list of mimetypes too. */ - if(!type) + if( depth == 2 ) { - type = (struct httpuMimeType *)malloc(sizeof(struct httpuMimeType)); - - if(type) + if( Equals( file->thorn, lastItem->thorn ) + && Equals( file->varname, lastItem->varname ) ) { - type->name = Util_Strdup(description->mimetype); - - type->next = mimetypes; - mimetypes = type; + IndentAndConcatCString( message, "<tr>", depth ); + ConcatCString( message, "<td class=\"spacer\"> </td>" + "<td class=\"spacer\"> </td>\n" + "<td class=\"slice\">" ); + Concat( message, file->slice ); + + ConcatCString( message, "\n" ); + IndentAndConcatCString( message, "</td><td class=\"link\">\n", depth ); + IndentAndConcatCString( message, "<a href=\"/Output/", depth ); + Concat( message, file->linkname ); + ConcatCString( message, "\">" ); + Concat( message, file->filename ); + ConcatCString( message, "</a>\n" ); + IndentAndConcatCString( message, "</td><td class=\"desc\">\n", depth ); + IndentAndConcatCString( message, "", depth ); + Concat( message, file->description ); + ConcatCString( message, "\n" ); + IndentAndConcatCString( message, "</td></tr>\n", depth ); } + else + break; } } - - return 0; + ConcatCString( message, "\n" ); + return i - 1; } - /*@@ @routine AdvertisedFilePage @date Sun Sep 17 18:26:01 2000 @@ -211,74 +236,85 @@ static int AdvertisedFilePage(const cGH *GH, httpRequest *request, void *data) { int retval = 0; String *message = String_New(); - struct httpuFileList *list; data = data; /* avoid compiler warning about unused parameter */ HTTP_Send_OK_Header( request ); HTTP_SetDoctype( message ); - HTTP_SendString(request, message); - /* Start the page */ - HTTP_Send(request, "<html><head>\n" ); - HTTP_Send(request, "<title>Cactus Downloadable Files</title>\n"); + HTTP_SendString( request, message); + + HTTP_Send( request, "<html><head>\n" ); + HTTP_Send( request, "<title>Cactus Downloadable Files</title>\n"); HTTP_SetHeadInfo( message); - HTTP_SendString(request, message ); + HTTP_Send( request, "<style type=\"text/css\">" + "\t.files td { text-align: left; font-family: sans-serif;\n" + "\t padding-left: 1ex; padding-right: 1ex; }\n" + "\t.files td.variable { background-color: #ff9;\n" + "\t font-weight: bold; }\n" + "\t.files td.thorn { background-color: #dff;\n" + "\t color: black; }\n" + "\t.files td.slice { background-color: #fde;\n" + "\t font-family: monospace; }\n" + "\t.files td.link { \n" + " }\n" + "\t.files td.desc { background-color: #dff;\n" + "\t font-style: italic; }\n" + "\t#filescaption { border-bottom: thin black solid;\n" + "\t margin-bottom: 1em; }\n" + "\t</style>\n"); + HTTP_SendString( request, message ); - HTTP_Send(request, "</head>\n<body>\n"); + HTTP_Send( request, "</head>\n<body>\n"); - /* HTTP_Write out the header part. */ - HTTP_SetContentHeaderString(GH, 0, message, NULL); - HTTP_SendString(request, message); + HTTP_SetContentHeaderString( GH, 0, message, NULL); + HTTP_SendString( request, message); - HTTP_Send(request, "<h1>Downloadable Files</h1>"); + HTTP_Send( request, "<h1>Downloadable Files</h1>\n"); - HTTP_Send(request, + HTTP_Send( request, "<p>From this page you can download various output files \n" "from the simulation. Depending on the software available on your\n" - " local machine, you can change the browser properties to launch\n" - " files directly to visualization clients.</p> \n " - "<p>Some of these output files can be directly viewed on \n" - "a browser on the simulation \n" - "<a href=\"/Output/viewport.html\">viewport</a></p>\n" - "<p>Many IO methods have <i>steerable</i> parameters which \n" - "allow you to e.g. add fields and customise behaviour.\n" - "Depending on your authorisation, you can access the \n" - "<a href=\"/Parameters/index.html\">parameter steering page</a></p>\n" + " local machine, you can change the browser properties to launch\n" + " files directly to visualization clients.</p> \n " + "<p>Some of these output files can be directly viewed on \n" + "a browser on the simulation \n" + "<a href=\"/Output/viewport.html\">viewport</a></p>\n" + "<p>Many IO methods have <dfn>steerable</dfn> parameters which \n" + "allow you to e.g. add fields and customise behaviour.\n" + "Depending on your authorisation, you can access the \n" + "<a href=\"/Parameters/index.html\">parameter steering page</a>" + "</p>\n"); + HTTP_Send( request, "<div class=\"centered\">\n" - "<table cellspacing=\"5\" cellpadding=\"5\" rules=\"cols\">\n" - "<thead>\n" - "<tr><th>File Name</th><th>Variable</th><th>Description</th></tr>\n" - "</thead>\n<tbody>\n"); + "<table class=\"files\" id=\"filescaption\" " + "frame=\"below\" cellpadding=\"0\" cellspacing=\"0\">\n" + "<tr><td class=\"variable\">\n" + "Variable</td><td class=\"thorn\">Thorn</td>\n" + "<td class=\"slice\"> Slice</td><td class=\"file\"> File</td>\n" + "<td class=\"desc\"> Description</td></tr>\n</table>\n" + "\n" + ); - for (list = filelist; list; list = list->next) - { - SetToCString(message, "<tr><td valign=\"top\"><a href=\"/Output/" ); - ConcatCString(message, list->linkname ); - ConcatCString(message, "\">" ); - ConcatCString(message, list->filename ); - ConcatCString(message, "</a></td>" ); - ConcatCString(message, "<td valign=\"top\">" ); - ConcatCString(message, list->data.varname ); - ConcatCString(message, "</td><td valign=\"top\">" ); - ConcatCString(message, list->data.description ); - ConcatCString(message, "</td></tr>\n" ); - - HTTP_SendString(request, message); - } + Truncate( message, 0 ); + SortFilesAccordingTo( filelist, Variable_Thorn_Slice ); - HTTP_Send(request,"</tbody></table>\n</div>"); + HTTP_Send( request, "<table cellpadding=\"0\" cellspacing=\"0\"" + " class=\"files\">\n"); + buildList( filelist, message, 0, 0 ); - /* Write out the footer part. */ - HTTP_SetContentFooterString(GH, 0, message); - retval = HTTP_SendString(request, message); + HTTP_SendString( request, message); + HTTP_Send( request, "\n</table>"); + HTTP_Send( request, "\n</div>"); + + HTTP_SetContentFooterString( GH, 0, message); + retval = HTTP_SendString( request, message); String_Delete( message ); return retval; } - /*@@ @routine SendFilePage @date Sun Sep 17 18:43:40 2000 @@ -287,66 +323,71 @@ static int AdvertisedFilePage(const cGH *GH, httpRequest *request, void *data) Sends an advertised file. @enddesc @@*/ -static int SendFilePage(const cGH *GH, httpRequest *request, void *data) + +static int SendFilePage( const cGH *GH, httpRequest *request, void *data) { - struct httpuFileList *list; + int found = 0; + const size_t n = NumberOfFiles( filelist ); + size_t i; /* avoid compiler warning about unused parameters */ (void) (GH + 0); data = data; - for (list = filelist; list; list = list->next) + for( i = 0; i < n; i++ ) { - if(!strcmp(list->linkname, HTTP_Residual( request ) )) + httpFileItem *file = FileItem( filelist, i ); + + if( !CompareCString( file->linkname, HTTP_Residual( request ) )) { - int filedes; - if((filedes = open(list->filename, O_RDONLY | O_BINARY)) >= 0) + int filedes = open( GetBuffer( file->filename), O_RDONLY | O_BINARY); + if(filedes >= 0) { - HTTP_Send(request, "HTTP/1.0 200 OK\r\n"); + HTTP_Send( request, "HTTP/1.0 200 OK\r\n"); - HTTP_Send(request, "Content-Type: " ); - HTTP_Send(request, list->data.mimetype); - HTTP_Send(request, "\r\n\r\n" ); + HTTP_Send( request, "Content-Type: " ); + HTTP_SendString( request, file->mimetype); + HTTP_Send( request, "\r\n\r\n" ); - HTTP_ContentSendFromFile(request, filedes); + HTTP_ContentSendFromFile( request, filedes); - close(filedes); + close( filedes); + found = 1; } else { - HTTP_Send(request,"HTTP/1.0 500 Server Internal Error\r\n"); - - HTTP_Send(request, "Content-Type: text/html\r\n\r\n"); - HTTP_Send(request, "<html>\n<head>\n"); - HTTP_Send(request, "<title>Error 500: Internal Error</title>\n"); - HTTP_Send(request, "</head>\n<body>\n"); - HTTP_Send(request, "<div class=\"centered\"><p>Unable to open " ); - HTTP_Send(request, list->filename ); - HTTP_Send(request, "</p></div>\n"); - HTTP_Send(request, "</body>\n</html>\n" ); + HTTP_Send( request,"HTTP/1.0 500 Server Internal Error\r\n"); + + HTTP_Send( request, "Content-Type: text/html\r\n\r\n"); + HTTP_Send( request, "<html>\n<head>\n"); + HTTP_Send( request, "<title>Error 500: Internal Error</title>\n"); + HTTP_Send( request, "</head>\n<body>\n"); + HTTP_Send( request, "<div class=\"centered\"><p>Unable to open " ); + HTTP_SendString( request, file->filename ); + HTTP_Send( request, "</p></div>\n"); + HTTP_Send( request, "</body>\n</html>\n" ); } break; } } - if(!list) + if(!found) { - HTTP_Send(request,"HTTP/1.0 404 Not Found\r\n"); + HTTP_Send( request,"HTTP/1.0 404 Not Found\r\n"); - HTTP_Send(request,"Content-Type: text/html\r\n\r\n"); + HTTP_Send( request,"Content-Type: text/html\r\n\r\n"); - HTTP_Send(request, "<html>\n<head>\n" ); - HTTP_Send(request, "<title>Error 404: Not Found</title>\n" ); - HTTP_Send(request, "</head>\n<body>\n" ); - HTTP_Send(request, "<div class=\"centered\"><p>" ); - HTTP_Send(request, HTTP_URI( request ) ); - HTTP_Send(request, " does not exist</p></div>\n" ); - HTTP_Send(request, "</body>\n</html>\n" ); + HTTP_Send( request, "<html>\n<head>\n" ); + HTTP_Send( request, "<title>Error 404: Not Found</title>\n" ); + HTTP_Send( request, "</head>\n<body>\n" ); + HTTP_Send( request, "<div class=\"centered\"><p>" ); + HTTP_Send( request, HTTP_URI( request ) ); + HTTP_Send( request, " does not exist</p></div>\n" ); + HTTP_Send( request, "</body>\n</html>\n" ); } return 0; } - /*@@ @routine AdvertisedFilePage @date Sun Sep 17 18:26:01 2000 @@ -355,39 +396,58 @@ static int SendFilePage(const cGH *GH, httpRequest *request, void *data) Page to deal with advertised files. @enddesc @@*/ + static int ViewportFilePage(const cGH *GH, httpRequest *request, void *data) { + DECLARE_CCTK_PARAMETERS + int retval = 0; int foundone = 0; String *message = String_New(); - struct httpuFileList *list; + const size_t n = NumberOfFiles( filelist ); + size_t i; - /* avoid compiler warning about unused parameters */ (void) (GH + 0); - data = data; + data = data; /* avoid compiler warning about unused parameters */ - HTTP_Send_OK_Header( request ); + HTTP_Send_OK_Refresh_Header( request, viewport_refresh_seconds ); HTTP_SetDoctype( message ); - HTTP_SendString(request, message); + HTTP_SendString( request, message); - /* Start the page */ - HTTP_Send(request, "<html>\n<head>\n"); - HTTP_Send(request, "<title>Cactus Downloadable Files</title>\n"); + HTTP_Send( request, "<html>\n<head>\n"); + HTTP_Send( request, "<title>Cactus Downloadable Files</title>\n"); HTTP_SetHeadInfo( message); - HTTP_SendString(request, message ); - - HTTP_Send(request, "</head>\n<body>\n"); - /* HTTP_Write out the header part. */ - - HTTP_SetContentHeaderString(GH, 0, message, NULL); - HTTP_SendString(request, message); - - HTTP_Send(request, "<h1>Viewport</h1>\n"); - - HTTP_Send(request, + HTTP_Send( request, "<style type=\"text/css\">" + ".files td { text-align: center; vertical-align: middle;" + " font-size: smaller; font-family: sans-serif; }\n" + ".files .spacer { width: 10ex;\n" + " }\n" + ".files .variable { background-color: #ff9;\n" + " font-weight: bold; }\n" + ".files .thorn { background-color: #dff;\n" + " color: black; }\n" + ".files .slice { background-color: #fde;\n" + " font-family: monospace; }\n" + ".files .link { }\n" + ".files .desc { font-style: italic;\n" + " background-color: #dff; }\n" + ".files img { border: 0;\n" + " }\n" + "</style>\n"); + + HTTP_SendString( request, message ); + + HTTP_Send( request, "</head>\n<body>\n"); + + HTTP_SetContentHeaderString( GH, 0, message, NULL); + HTTP_SendString( request, message); + + HTTP_Send( request, "<h1>Viewport</h1>\n"); + + HTTP_Send( request, "<p>This page displays certain types of the output files \n" "from the <a href=\"/Output/index.html\">download</a> page \n" "as images (currently only JPEGs [mime type image/jpeg]).</p>\n" @@ -397,57 +457,61 @@ static int ViewportFilePage(const cGH *GH, httpRequest *request, void *data) "<a href=\"/Parameters/index.html\">parameter steering page</a></p>\n" "<div class=\"centered\">\n"); - for (list = filelist; list; list = list->next) + SortFilesAccordingTo( filelist, Variable_Thorn_Slice ); + + for ( i = 0; i < n; i++ ) { - if (CCTK_Equals(list->data.mimetype,"image/jpeg")) + httpFileItem *file = FileItem( filelist, i ); + if ( !CompareCString( file->mimetype, "image/jpeg")) { if (!foundone) { - HTTP_Send(request, - "<table cellspacing=\"5\" cellpadding=\"5\">\n" - "<tr><th>Variable<br>File Name</th>\n" - "<th>Description</th><th>Image</th></tr>\n"); + HTTP_Send( request, + "<table class=\"files\" cellspacing=\"5\" cellpadding=\"5\" " + "rules=\"groups\" >\n" + "<thead>\n<tr><th>Variable<br />Slice</th>" + "<th>Description</th><th>Image</th></tr>\n</thead>\n"); foundone = 1; } - HTTP_Send(request, "<tr>\n" ); - HTTP_Send(request, "<td valign=center><small>" ); - HTTP_Send(request, list->data.varname ); - HTTP_Send(request, "<br />\n" ); - HTTP_Send(request, "<a href=\"/Output/" ); - HTTP_Send(request, list->linkname ); - HTTP_Send(request, "\">" ); - HTTP_Send(request, list->filename ); - HTTP_Send(request, "</a>\n" ); - HTTP_Send(request, "</small></td>\n" ); - HTTP_Send(request, "<td valign=center>" ); - HTTP_Send(request, list->data.description ); - HTTP_Send(request, "</td>\n" ); - HTTP_Send(request, "<td valign=center><a href=\"/Output/" ); - HTTP_Send(request, list->linkname ); - HTTP_Send(request, "\">" ); - HTTP_Send(request, "<img border=\"0\" width=\"100\" height=\"100\" src=\"" ); - HTTP_Send(request, list->linkname ); - HTTP_Send(request, "\" />" ); - HTTP_Send(request, "</a></td>\n" ); - HTTP_Send(request, "</tr>\n" ); + HTTP_Send( request, "<tr>\n" ); + HTTP_Send( request, "<td><span class=\"variable\">" ); + HTTP_SendString( request, file->varname ); + HTTP_Send( request, "</span><br />\n" ); + HTTP_Send( request, "<span class=\"slice\">" ); + HTTP_SendString( request, file->slice ); + HTTP_Send( request, "</span>" ); + HTTP_Send( request, "</td>\n" ); + HTTP_Send( request, "<td><span class=\"desc\">" ); + HTTP_SendString( request, file->description ); + HTTP_Send( request, "</span></td>\n" ); + HTTP_Send( request, "<td class=\"linkk\"><a href=\"/Output/" ); + HTTP_SendString( request, file->linkname ); + HTTP_Send( request, "\">" ); + HTTP_Send( request, "<img width=\"100\" height=\"100\" src=\"" ); + HTTP_SendString( request, file->linkname ); + HTTP_Send( request, "\" alt=\"" ); + HTTP_SendString( request, file->linkname ); + HTTP_Send( request, "\"/>" ); + HTTP_Send( request, "</a></td>\n" ); + HTTP_Send( request, "</tr>\n" ); } } - if (!foundone) + if( foundone) + HTTP_Send( request, "</table>\n"); + else { - HTTP_Send(request, "<strong>\n<p>No viewable images registered!</p>\n" + HTTP_Send( request, "<strong>\n<p>No viewable images registered!</p>\n" "</strong>\n"); } + HTTP_Send( request, "</div>\n"); - HTTP_Send(request, "</div>\n"); - - /* Write out the footer part. */ - - HTTP_SetContentFooterString(GH, 0, message); - retval = HTTP_SendString(request, message); + HTTP_SetContentFooterString( GH, 0, message); + retval = HTTP_SendString( request, message); String_Delete( message ); + return retval; } |