#include #include #include #include #include "../global.h" #include "shared_cs_util.h" #include "shared_file_util.h" #include "shared_util.h" #define POTATO_SIGNATURE "Created with Hot Potatoes" #define V6_SIGNATURE "function GetUserName()" #define POTATO_FORM_START "var ResultForm =" #define POTATO_FORM_END "ResultForm += '';" #define POTATO_FORM_END2 "ResultForm += '';" #define POTATO_EXERCISE_START "ResultForm += '" #define POTATO_EXERCISE_BLANK "ResultForm += '';" //#define POTATO_GETUSERNAME_START "UserName = prompt('Please enter your name:','');" #define POTATO_GETUSERNAME_START "UserName = prompt(" #define POTATO_GETUSERNAME_END "window.location = PreviousPage;" #define POTATO_GETUSERNAME_END_V6 "history.back();" /* version 6 uses this string to end the username section */ #define MAX_EXERCISE_STRING 200 #define L66_TEST_RESULTS_WILL_BE_SAVED "'This self-test has been configured to save your scores. Your score will automatically be recorded when you have answered ALL of the questions CORRECTLY, so keep trying if you get them wrong on the first try. Do you want to continue?'" void calculate_elapsed_time(time_t elapsed_time, int *hours, int *minutes, int *seconds) { int remainder; *hours = elapsed_time / 3600; remainder = elapsed_time % 3600; *minutes = remainder / 60; *seconds = remainder % 60; } void kill_hotpotato_directory(const char *username, CONFIG_STRUCT *conf) { char dirpath[MAX_PATH + 1]; snprintf (dirpath, MAX_PATH + 1, "%speople/%s/selftest/%s", conf->course_path, username, HOTPOT_TMP_DIRNAME); kill_directory(dirpath); /* shared_file_util.c */ } void write_hotpot_result_form(const char *course, const char *key, const char *sender, const char *info_fname, const char *exercise_string, const char *original_fname, const char *system_fname, const char *action_dir, FILE *fp) { fprintf (fp, "var ResultForm = '
';\n", action_dir, "hotpotato_record"); fprintf (fp, "ResultForm += '';\n", course); fprintf (fp, "ResultForm += '';\n", key); fprintf (fp, "%s\n", exercise_string); fprintf(fp, "ResultForm += '';\n", sender); fprintf(fp, "ResultForm += '';\n", info_fname); fprintf(fp, "ResultForm += '';\n", original_fname); fprintf(fp, "ResultForm += '';\n", system_fname); fprintf(fp, "ResultForm += '';\n"); fputs("ResultForm += '';\n",fp); fputs("ResultForm += '';\n",fp); fputs("ResultForm += '';\n",fp); fputs("ResultForm += '';\n",fp); fputs("ResultForm += '
';",fp); } /* processes a CGI enabled Hot Potatoes quiz by ** substituting JavaScript code on the fly ** returns 0 if this is not a CGI enabled potato, ** else processes the file and returns a '1' **/ int process_cgi_enabled_potato(char *buffer, off_t filesize, const char *course, const char *key, const char *sender, const char *info_fname, const char *original_fname, const char *system_fname, const char *action_dir, FILE *fp) { char *ptr, *ptr2; char *start_form, *end_form, *start_username, *end_username; int brackets, skip_brackets; char exercise_string[MAX_EXERCISE_STRING + 1], temp; int version_6; /* null terminate the buffer so we can use strstr() on it. ** assumes buffer is one byte longer than the actual size of the file */ *(buffer + filesize) = '\0'; /* replace any other null characters in buffer with a space - ** we need to make sure there is only one '\0' character, and ** that character is at the end of the buffer */ for(ptr2 = buffer, ptr = strchr(ptr2,'\0'); ptr && (ptr != (buffer + filesize)); *ptr = ' ', ptr2 = ptr + 1); if(ptr != (buffer + filesize)) cs_critical_error(ERR_CANT_FIND_TERMINATING_NULL,""); if(!strstr(buffer,POTATO_SIGNATURE)) return 0; version_6 = strstr(buffer,V6_SIGNATURE)? 1: 0; start_form = strstr(buffer,POTATO_FORM_START); if(!start_form) return 0; /** try to extract the string related to the *** 'Exercise' parameter ***/ ptr = strstr(start_form,POTATO_EXERCISE_START); if(ptr) { ptr2 = strstr(ptr,POTATO_EXERCISE_END); if(ptr2) { ptr2 +=strlen(POTATO_EXERCISE_END); temp = *ptr2; *ptr2 = '\0'; strncpy(exercise_string,ptr,MAX_EXERCISE_STRING); *ptr2 = temp; strcat(exercise_string,"';"); } } if(!ptr || !ptr2) strncpy(exercise_string,POTATO_EXERCISE_BLANK, MAX_EXERCISE_STRING); end_form = strstr(start_form,POTATO_FORM_END); if(!end_form) { end_form = strstr(start_form,POTATO_FORM_END2); if(!end_form) return 0; else end_form += strlen(POTATO_FORM_END2); } else end_form += strlen(POTATO_FORM_END); /** It's possible that when the teacher posted this hot potatoes quiz, *** she obtained a copy by directly saving the *.html file from the *** Self-tests module of a classroom to a PC, then uploading it again *** to the Self-tests module. If this is the case, the *** Enter username portion of the file will have already been replaced with *** the L66_TEST_RESULTS_WILL_BE_SAVED string (#defined up top). *** *** What's done for the remainder of this function depends on whether the *** unaltered username form (as output by Hot Potatoes) is detected, or if *** we find that the username form was already processed by Manhattan **/ /*** look for the Username prompt produced directly from Hot Potatoes **/ start_username = strstr(end_form,POTATO_GETUSERNAME_START); /*** If the Hot Potatoes Username prompt is not there, and the text **** this program inserts in its place isn't there eiter, then something's wrong **** with the file. Give up. ***/ if(!start_username && !strstr(end_form, L66_TEST_RESULTS_WILL_BE_SAVED)) return 0; /*** If this is a 'virgin' Hot Potatoes quiz, find the end of the Enter Username code ***/ if(start_username) { if(version_6) { end_username = strstr(start_username,POTATO_GETUSERNAME_END_V6); /* test for version 6 */ if(!end_username) return 0; skip_brackets = 3; } else /* then this must be hot potatoes 5 */ { end_username = strstr(start_username,POTATO_GETUSERNAME_END); /* for v5 browsers */ if(!end_username) end_username = strstr(start_username,POTATO_GETUSERNAME_END_V6); /* for v6 browsers */ if(!end_username) return 0; skip_brackets = 2; } /** adjust end_username -- skip past angle brackets ***/ for(brackets=0,ptr=end_username; *ptr && (brackets < skip_brackets); ptr++) if(*ptr == '}') brackets++; if(!*ptr) return 0; end_username = ptr + 1; } if(fp == stdout) send_content_type(); /* write everything up to the start of the form ***/ if (fwrite (buffer, start_form - buffer, 1, fp) != 1) cs_critical_error (ERR_FWRITE_FAILED, ""); write_hotpot_result_form(course,key,sender,info_fname,exercise_string, original_fname,system_fname,action_dir, fp); /** If this was a virgin Hot Potatoes file **/ if(start_username) { /* write everything between the form and the get_username code */ if (fwrite (end_form , start_username - end_form, 1, fp) != 1) cs_critical_error (ERR_FWRITE_FAILED, ""); /* replace the get UserName code with this alert */ fprintf(fp,"if(!window.confirm(%s))\n" "\t{ parent.history.back(); }\n",L66_TEST_RESULTS_WILL_BE_SAVED); /* if this is version 6, we need to a closing curly brace */ if(skip_brackets == 3) fprintf(fp, "}\n"); /* write the rest of the file */ if (fwrite (end_username, (buffer + filesize) - end_username, 1, fp) != 1) cs_critical_error (ERR_FWRITE_FAILED, ""); } else /* This file was already processed by Manhattan, so just output the rest of the file */ if (fwrite (end_form , (buffer + filesize) - end_form, 1, fp) != 1) cs_critical_error (ERR_FWRITE_FAILED, ""); return 1; /*yes, this was a Hot Potato */ } #undef POTATO_SIGNATURE #undef POTATO_FORM_START #undef POTATO_FORM_END #undef POTATO_FORM_END2 #undef POTATO_GETUSERNAME_START #undef POTATO_GETUSERNAME_END #undef POTATO_EXERCISE_START #undef POTATO_EXERCISE_END #undef MAX_EXERCISE_STRING