#include #include #include #include "../global.h" #include "shared_cs_util.h" #include "shared_file_util.h" #include "shared_bb_examview.h" static void print_head(const char *title, FILE *fp) { fprintf(fp, "\n" "\n" "\n" "\n" "UNREGISTERED\n" "This is the title\n" " \n" " 6\n" "\n"); fprintf(fp, "%s\n", title); fprintf(fp, "\n" "0\n" "0\n" " 1\n" " 1\n" "\n" " \n" " \n" "\n" "\n"); } static void print_question(XML_QUESTION *quest, FILE *fp) { int i; if(strcmp(quest->type, "tf") ==0 || strcmp(quest->type, "mc") ==0 || strcmp(quest->type, "bk") == 0) { fprintf(fp, "\n"); fprintf(fp, "0\n"); fprintf(fp, " \n", quest->quest); if(strcmp(quest->type, "tf") ==0 || strcmp(quest->type, "mc") ==0) fprintf(fp, " 1\n"); else fprintf(fp, " 2\n"); for(i =0; ichoices[i].one_choice) { fprintf(fp, " \n"); fprintf(fp, " \n",quest->choices[i].one_choice); if(strcmp(quest->type, "bk") ==0) fprintf(fp, " \n",1); else fprintf(fp, " \n",quest->choices[i].correct); fprintf(fp, " \n"); fprintf(fp, " \n"); } } fprintf(fp, "\n"); } } static void print_footer(FILE *fp) { fprintf(fp, "\n" " \n" " \n" " \n" " Multiple-choice exercise\n" " Choose the correct answer for each question.\n" " Correct!\n" " Sorry! Try again.\n" " nextpage.htm\n" " 0\n" " 25%%\n" " 1\n" " 0\n" " 0\n" " 1\n" " 0\n" " 3\n" " 0\n" " \n" " \n" " Your score is \n" ":-)\n" " X\n" " Questions answered correctly first time: \n" " Remaining time:\n" " Start reading\n" " Show reading again\n" " Your time is over!\n" " Click on the button to see the reading.\n" " =>\n" " <=\n" " Index\n" " 1\n" " 1\n" " 1\n" " index.htm\n" " \n" " Geneva,Arial\n" " #ffffff\n" " #000033\n" " #bbbbee\n" " #000000\n" " #0000ff\n" " #0000cc\n" " #000066\n" " http://your.server.address/cgi-bin/FormMail.pl\n" " you@yourplace.com\n" " Please enter your name:\n" " Questions answered correctly first time: \n" " Check\n" " OK\n" " \n" " \n" " \n"); } static void write_cgi_file (FILE *infp, off_t size, char *filepath) { #define CHUNKSIZE 2048 FILE *outfp; int bytes_read; int bytes_left; char buffer[CHUNKSIZE]; int fd; snprintf(filepath, MAX_PATH +1, "%s/CGI_DATA_xml_XXXXXX", "../tmp"); fd = mkstemp (filepath); if(fd == -1) cs_critical_error (ERR_MKSTEMP_FAILED, ""); close(fd); change_mkstemp_permission(filepath); /*shared_file_util.c */ outfp = fopen (filepath, "w"); if (!outfp) cs_critical_error (ERR_FOPEN_WRITE_FAILED, filepath); bytes_left = size; bytes_read = CHUNKSIZE; while (bytes_left) { if (bytes_left < CHUNKSIZE) bytes_read = bytes_left; if (fread (buffer, bytes_read, 1, infp) != 1) cs_critical_error(ERR_FREAD_FAILED, ""); bytes_left -= bytes_read; if (fwrite (buffer, bytes_read, 1, outfp) != 1) cs_critical_error (ERR_FWRITE_FAILED, filepath); } fclose (outfp); #undef CHUNKSIZE } static void get_orig_fname (const char *full_orig_name, char *orig_fname) { char *temp_fname; char *ptr; int chars_to_copy; char *extension; temp_fname = (char *) malloc(strlen(full_orig_name) + 1); if(!temp_fname) cs_critical_error(ERR_MALLOC_FAILED, ""); /* Depending on the browser and the OS, full_orig_name might contain ** paths that are separated by backslashes, by forward slashes, or ** no path info at all. We need to get just the filename... **/ ptr = strrchr (full_orig_name, '\\'); /* look for a backslash from the end of the string */ if (ptr) /* found, then ... */ strcpy (temp_fname, ptr + 1); /* filename is to right of the backslash */ else /* no backslash found */ { ptr = strrchr (full_orig_name, '/'); /* look for a forward slash */ if (ptr) /* found, then ... */ strcpy (temp_fname, ptr + 1); /* filename is to right of forward slash */ else /* no backslash or forward slashes found */ strcpy (temp_fname, full_orig_name); /* entire string is the filename */ } /* If the filename is longer than allowed, we must shorten it ** If possible, we'll preserve the file's extension **/ if(strlen(temp_fname) > MAX_FILENAME) { extension = strrchr(temp_fname, '.'); /* find start of file extension */ /* If no file extension found, or the file extension is as large as we allow ** for an entire filename, simply truncate the filename **/ if(!extension || (extension && (strlen(extension) >= MAX_FILENAME) )) { *(temp_fname + MAX_FILENAME) = '\0'; /*simply shorten the filename */ strncpy(orig_fname, temp_fname, MAX_FILENAME + 1); } else /* preserve the file extension, but truncate the rest of the file */ { chars_to_copy = MAX_FILENAME - strlen(extension); *(temp_fname + chars_to_copy) = '\0'; snprintf(orig_fname,MAX_FILENAME + 1, "%s%s", temp_fname, extension); } } else /** filename was not too long */ strncpy(orig_fname, temp_fname, MAX_FILENAME + 1); /* make double-sure the file is truncated ! */ *(orig_fname + MAX_FILENAME) = '\0'; free(temp_fname); } void get_xml_file( char *xml_org_file, char *unique_fname) { FILE *fp; char path[MAX_PATH +1]; struct stat buf; cs_get_required_parameter("xml_file", path, MAX_PATH +1); fp = cgi_filehandle(global_cgi, "xml_file"); if(fstat(fileno(fp), &buf)) cs_critical_error(ERR_STAT_FAILED, path); if(buf.st_size == 0) cs_critical_error(ERR_EMPTY_FILE, path); get_orig_fname (path, xml_org_file); write_cgi_file(fp, buf.st_size, unique_fname); } void xml_to_jbc ( QUEST_LIST *list, char *jbc_file) { FILE *fp; int fd; snprintf(jbc_file, MAX_PATH +1, "%s/CGI_DATA_jbc_XXXXXX", "../tmp"); fd = mkstemp (jbc_file); if(fd == -1) cs_critical_error (ERR_MKSTEMP_FAILED,"" ); close(fd); change_mkstemp_permission(jbc_file); /*shared_file_util.c */ fp = fopen (jbc_file, "w"); if(!fp) cs_critical_error (ERR_MKSTEMP_FAILED, ""); print_head(list->title, fp); for(list->current = list->head; list->current; list->current = list->current->next) print_question(list->current, fp); print_footer(fp); fclose(fp); } void send_jbc_file(const char *jbc_file, const char *org_file) { char jbc_org_filename[MAX_PATH +1]; char *ptr; FILE *fp; struct stat buf; char *buffer; ptr = strchr(org_file, '.'); if(ptr) *ptr = '\0'; snprintf(jbc_org_filename, MAX_PATH +1, "%s.jbc", org_file); if(stat(jbc_file, &buf)) cs_critical_error (ERR_STAT_FAILED, ""); buffer = (char *) malloc( (buf.st_size +1) * sizeof(char)); if(!buffer) cs_critical_error (ERR_MALLOC_FAILED, ""); fp = fopen(jbc_file, "r"); if(!fp) cs_critical_error(ERR_FOPEN_READ_FAILED, ""); if (fread (buffer, buf.st_size, 1, fp) != 1) cs_critical_error (ERR_FREAD_FAILED, ""); fclose(fp); printf ("Content-type:application/octet-stream\n"); printf ("Content-disposition: attachment; filename=\"%s\"\n", jbc_org_filename); printf("Content-length: %ld\n\n", (long)buf.st_size); if(fwrite(buffer, buf.st_size, 1, stdout) != 1) cs_critical_error (ERR_FWRITE_FAILED, ""); free(buffer); unlink(jbc_file); } void dat_to_jbc ( QUEST_LIST *list, char *jbc_file) { FILE *fp; fp = fopen (jbc_file, "w"); if(!fp) cs_critical_error (ERR_FOPEN_WRITE_FAILED, jbc_file); print_head(list->title, fp); for(list->current = list->head; list->current; list->current = list->current->next) print_question(list->current, fp); print_footer(fp); fclose(fp); } XML_QUESTION * initialize() { XML_QUESTION *ptr; int i; ptr = (XML_QUESTION*)malloc(sizeof(XML_QUESTION)); ptr->quest = 0; ptr->feedback =0; ptr->next =0; for(i = 0; i < MAX_CHOICE; i++) { ptr->choices[i].one_choice = 0; ptr->choices[i].id = 0; ptr->choices[i].correct =0; } return ptr; } void free_xml_data_list(QUEST_LIST *list) { XML_QUESTION *ptr; int i; list->current = list->head; while(list->current) { ptr = list->current; if(ptr->quest) free(ptr->quest); if(ptr->feedback) free(ptr->feedback); for(i =0; ichoices[i].one_choice) free(ptr->choices[i].one_choice); if(ptr->choices[i].id) free(ptr->choices[i].id); } list->current = list->current->next; free(ptr); } if(list->title) free(list->title); free(list); }