Annotation of capa/capa51/pProj/capaCgiUtils.c, revision 1.18
1.18 ! albertel 1: /* Most of the web output generation routines.
! 2: Copyright (C) 1992-2000 Michigan State University
! 3:
! 4: The CAPA system is free software; you can redistribute it and/or
! 5: modify it under the terms of the GNU Library General Public License as
! 6: published by the Free Software Foundation; either version 2 of the
! 7: License, or (at your option) any later version.
! 8:
! 9: The CAPA system is distributed in the hope that it will be useful,
! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! 12: Library General Public License for more details.
! 13:
! 14: You should have received a copy of the GNU Library General Public
! 15: License along with the CAPA system; see the file COPYING. If not,
! 16: write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
! 17: Boston, MA 02111-1307, USA. */
! 18:
1.1 albertel 19: /* ===================================================================== */
20: /* ===================================================================== */
21: #include <stdio.h>
22: #include <ctype.h>
23: #ifndef NO_STDLIB_H
24: #include <stdlib.h>
25: #else
26: char *getenv();
27: #endif
28: #include <stdio.h>
29:
30: #include "capaToken.h"
31: #include "capaParser.h"
32: #include "capaCommon.h"
33: #include "ranlib.h"
34:
35: #ifdef _MAIN_PROGRAM_
36: #undef _MAIN_PROGRAM_
37: #endif
38:
39: #include "capaCGI.h"
40:
41: void getword
42: CAPA_ARG((char *word, char *line, char stop))
43: {
44: int x = 0,y;
45:
46: for(x=0;((line[x]) && (line[x] != stop));x++)
47: word[x] = line[x];
48:
49: word[x] = '\0';
50: if(line[x]) ++x;
51: y=0;
52:
53: while((line[y++] = line[x++]));
54: }
55:
56: char *makeword
57: CAPA_ARG((char *line, char stop))
58: {
59: int x = 0,y;
60: char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));
61:
62: for(x=0;((line[x]) && (line[x] != stop));x++)
63: word[x] = line[x];
64:
65: word[x] = '\0';
66: if(line[x]) ++x;
67: y=0;
68:
69: while((line[y++] = line[x++]));
70: return word;
71: }
72:
73: char *fmakeword
74: CAPA_ARG((FILE *f,char stop,int * cl))
75: {
76: int wsize;
77: char *word;
78: int ll;
79:
80: wsize = 102400;
81: ll=0;
82: word = (char *) malloc(sizeof(char) * (wsize + 1));
83:
84: while(1) {
85: word[ll] = (char)fgetc(f);
86: if(ll==wsize) {
87: word[ll+1] = '\0';
88: wsize+=102400;
89: word = (char *)realloc(word,sizeof(char)*(wsize+1));
90: }
91: --(*cl);
92: if((word[ll] == stop) || (feof(f)) || (!(*cl))) {
93: if(word[ll] != stop) ll++;
94: word[ll] = '\0';
95: return word;
96: }
97: ++ll;
98: }
99: }
100:
101: char x2c
102: CAPA_ARG((char *what))
103: {
104: register char digit;
105:
106: digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
107: digit *= 16;
108: digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
109: return(digit);
110: }
111:
112: void unescape_url
113: CAPA_ARG((char *url))
114: {
115: register int x,y;
116:
117: for(x=0,y=0;url[y];++x,++y) {
118: if((url[x] = url[y]) == '%') {
119: url[x] = x2c(&url[y+1]);
120: y+=2;
121: }
122: }
123: url[x] = '\0';
124: }
125:
126: void plustospace
127: CAPA_ARG((char *str))
128: {
129: register int x;
130:
131: for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' ';
132: }
133:
134: int rind
135: CAPA_ARG((char *s,char c))
136: {
137: register int x;
138: for(x=strlen(s) - 1;x != -1; x--)
139: if(s[x] == c) return x;
140: return -1;
141: }
142:
143: int getline
144: CAPA_ARG((char *s,int n,FILE *f))
145: {
146: register int i=0;
147:
148: while(1) {
149: s[i] = (char)fgetc(f);
150:
151: if(s[i] == CR)
152: s[i] = fgetc(f);
153:
154: if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
155: s[i] = '\0';
156: return (feof(f) ? 1 : 0);
157: }
158: ++i;
159: }
160: }
161:
162: void send_fd
163: CAPA_ARG((FILE *f, FILE *fd))
164: {
165: char c;
166:
167: while (1) {
168: c = fgetc(f);
169: if(feof(f)) return;
170: fputc(c,fd);
171: }
172: }
173:
174: int ind
175: CAPA_ARG((char *s,char c))
176: {
177: register int x;
178:
179: for(x=0;s[x];x++)
180: if(s[x] == c) return x;
181:
182: return -1;
183: }
184:
185: void escape_shell_cmd
186: CAPA_ARG((char *cmd))
187: {
188: register int x,y,l;
189:
190: l=strlen(cmd);
191: for(x=0;cmd[x];x++) {
192: if(ind("&;`'\"|*?~<>^()[]{}$\\",cmd[x]) != -1){
193: for(y=l+1;y>x;y--)
194: cmd[y] = cmd[y-1];
195: l++; /* length has been increased */
196: cmd[x] = '\\';
197: x++; /* skip the character */
198: }
199: }
200: }
201:
202: /* ========================================== Updated according to Frank Wolfs
203: description on July 7 1997 */
204: char *c_getpath
205: CAPA_ARG((FILE *f))
206: {
207: register int c;
208: register int idx;
209: char tmp_string[MAX_BUFFER_SIZE];
210: char *new_string;
211:
212: idx = 0;
213: tmp_string[0]='\0';
214: c_ignorewhite(f);
215: do {
216: c = getc(f);
217: tmp_string[idx] = c;
218: idx++;
219: } while (isalnum(c) || c == '{' || c == '}' || c == '-' || c == '\\' ||
220: c == '^' || c == '_' || c == '/' || c == '.' || c == ':' ||
221: c == '+' || c == '*' || c == '#' || c == '!' || c == '=' ||
222: c == ';' || c == '$' || c == '(' || c == ')' || c == '[' ||
223: c == ']' || c == '?' || c == '>' || c == '<' || c == ',');
224: ungetc(c,f); idx--;
225: tmp_string[idx] = 0;
226: new_string = (char *)malloc( (idx+1)*sizeof(char) );
227: strncpy(new_string,tmp_string, (idx+1) );
228: return (new_string);
229: }
230:
231: /* ------------------------------------------------------------------------- */
232:
233: void web_printheader(FILE *out)
234: {
235: FILE *header;
236: char *buf[MAX_BUFFER_SIZE];
237: int amt=0;
238:
239: if ((capa_access("HTMLheader",F_OK|R_OK)!=-1) &&
240: (NULL!=(header=fopen("HTMLheader","r")))) {
241: while(0 < (amt=fread(buf,1,MAX_BUFFER_SIZE,header))) {
242: fwrite(buf,1,amt,out);
243: }
244: fclose(header);
245: } else {
246: fprintf(out,"<HTML><HEAD>\n");
247: fprintf(out,"<BODY BGCOLOR=\"#FFFFFF\" LINK=\"#0000EE\" VLINK=\"#EE1100\">\n");
248: }
249: }
250:
251: void web_printfooter(FILE *out)
252: {
253: FILE *footer;
254: char *buf[MAX_BUFFER_SIZE];
255: int amt=0;
256:
257: if ((capa_access("HTMLfooter",F_OK|R_OK)!=-1) &&
258: (NULL!=(footer=fopen("HTMLfooter","r")))) {
259: while(0 < (amt=fread(buf,1,MAX_BUFFER_SIZE,footer))) {
260: fwrite(buf,1,amt,out);
261: }
262: fclose(footer);
263: } else {
264: fprintf(out,"</BODY></HTML>\n");
265: }
266: }
267:
268: int web_getclassdir
269: CAPA_ARG((char **cpath_p, char **cown_p, char *class))
270: {
271: FILE *fp;
272: char filename[FILE_NAME_LENGTH];
273: char *cname_p;
274: int done;
275: char c;
276:
277: sprintf(filename,"class.conf");
278: if ((fp=fopen(filename,"r"))==NULL) {
279: sprintf(filename,"../class.conf");
280: if ((fp=fopen(filename,"r"))==NULL) {
281: fprintf(stdout,"<!-- Error: can't open %s --> \n",filename); fflush(stdout);
282: return (2);
283: }
284: }
285: do {
286: c_ignorewhite(fp);
287: c = getc(fp); ungetc(c,fp);
288: if( c != EOF ) {
289: cname_p = c_getword(fp);
290: *cpath_p = c_getpath(fp);
291: *cown_p = c_getword(fp);
292: throwaway_line(fp);
293: if( ! strcasecmp(cname_p, class) ) {
294: done = 1;
295: } else {
296: free(cname_p); free(*cpath_p); free(*cown_p);
297: done = 0;
298: }
299: } else {
300: done = 1;
301: }
302: } while ( ! done );
303: fclose(fp);
304: free(cname_p);
305: return (1);
306: }
307:
308: int web_log(log_str)char *log_str;
309: {
310: FILE *fp;
311: char filename[FILE_NAME_LENGTH];
312:
313: sprintf(filename,"web_access.log");
314: if ((fp=fopen(filename,"a"))==NULL) {
315: return -1;
316: }
317: flockstream(fp);
318: fprintf(fp,"%s",log_str);fflush(fp);
319: funlockstream(fp);
320: fclose(fp);
321: return 0;
322: }
323:
324: int w_log_timing(student_number,set,section,log_string)
325: char student_number[MAX_STUDENT_NUMBER+1];
326: int set;
327: int section;
328: char *log_string;
329: {
330: char filename[FILE_NAME_LENGTH],
331: *ct;
332: FILE *fp;
333: time_t t;
334:
335: sprintf(filename,"records/webtiming%d.log",set);
336: if ((fp=fopen(filename,"a"))==NULL) {
337: return (-1);
338: }
339: /* CREATE LOG ENTRY */
340: time(&t);
341: ct=ctime(&t);
342: ct[ strlen(ct)-1 ]=0; /* Trash newline */
343: fprintf(fp,"%s %s %s\n",student_number,ct,log_string); fflush(fp);
344: fclose(fp);
345: return (0);
346: }
347:
348: int w_log_attempt(student_number,set,log_string)
349: char student_number[MAX_STUDENT_NUMBER+1];
350: int set;
351: char *log_string;
352: {
353: char filename[FILE_NAME_LENGTH],
354: *ct;
355: FILE *fp;
356: time_t t;
357:
358: sprintf(filename,"records/weblog%d.db",set);
359: if ((fp=fopen(filename,"a"))==NULL) {
360: return (-1);
361: }
362:
363: /* CREATE LOG ENTRY */
364: time(&t);
365: ct=ctime(&t);
366: ct[ strlen(ct)-1 ]=0; /* Trash newline */
367: fprintf(fp,"%s %s %s\n",student_number,ct,log_string); fflush(fp);
368: fclose(fp);
369: return (0);
370: }
371:
372: int w_log_submissions(student_number,set,log_string)
373: char student_number[MAX_STUDENT_NUMBER+1];
374: int set;
375: char *log_string;
376: {
377: char filename[FILE_NAME_LENGTH],timeStr[FILE_NAME_LENGTH],buf2[MAX_BUFFER_SIZE];
378: FILE *fp;
379: time_t t;
380: struct tm *tmtime;
381: int do_log_submissions=1,result;
382: char buf[MAX_BUFFER_SIZE];
383:
384: result=read_capa_config("do_log_submissions",buf);
385: if (result != 0 && result != -1)
386: if (strcasecmp(buf2,"no")==0)
387: do_log_submissions=0;
388: if (!do_log_submissions) return 0;
389:
390: sprintf(filename,"records/websubmissions%d.db",set);
391: if ((fp=fopen(filename,"a"))==NULL) {
392: return (-1);
393: }
394:
395: /* CREATE LOG ENTRY */
396: time(&t);
397: tmtime=localtime(&t);
398: strftime(timeStr,FILE_NAME_LENGTH,"%d/%m %X",tmtime);
399: /*ct[ strlen(ct)-1 ]=0;*/ /* Trash newline */
400: protect_log_string(log_string);
401: fprintf(fp,"%s\t%s\t%s\n",student_number,timeStr,log_string); fflush(fp);
402: fclose(fp);
403: return (0);
404: }
405:
406:
407: void w_get_responses(int x,int q_idx,char* submissions_str)
408: {
409: int leng, sub_idx;
410: char buf[MAX_BUFFER_SIZE];
411: if( !strncmp(g_entries[x].name,"INPUT",5) ) {
412: if( index(g_entries[x].name, ',' ) == NULL ) { /* only one answer */
413: sscanf(g_entries[x].name,"INPUT%d",&q_idx);
414: if( q_idx > 0 && q_idx < MAX_PROBLEM_CNT ) {
415: if ( ! is_all_ws(g_entries[x].val) ) {
416: g_stu_ans_pp[q_idx] = (StudentAnswer_t *)capa_malloc(sizeof(StudentAnswer_t),1);
417: (g_stu_ans_pp[q_idx])->a_idx = 1;
418: (g_stu_ans_pp[q_idx])->a_str = strsave(g_entries[x].val);
419: (g_stu_ans_pp[q_idx])->a_next = NULL;
420: trim_response_ws((g_stu_ans_pp[q_idx])->a_str);
421: }
422: leng = strlen( g_entries[x].val );
423: if ( leng > 0 ) {
424: sprintf(buf,"%d\t%s\t",q_idx,g_entries[x].val);
425: strcat(submissions_str,buf);
426: }
427: }
428: } else { /* this answer belongs to /AND answers */
429: sscanf(g_entries[x].name,"INPUT%d,%d",&q_idx,&sub_idx);
430: if( q_idx > 0 && q_idx < MAX_PROBLEM_CNT ) {
431: if ( ! is_all_ws(g_entries[x].val) ) {
432: StudentAnswer_t *sa_p;
433: sa_p = (StudentAnswer_t *)capa_malloc(sizeof(StudentAnswer_t),1);
434: sa_p->a_idx = sub_idx;
435: sa_p->a_str = strsave(g_entries[x].val);
436: sa_p->a_next = NULL;
1.10 albertel 437: trim_response_ws(sa_p->a_str);
1.1 albertel 438: if( g_stu_ans_pp[q_idx] == NULL ) {
439: g_stu_ans_pp[q_idx] = sa_p;
440: } else {
441: StudentAnswer_t *sb_p;
442: for(sb_p=g_stu_ans_pp[q_idx]; sb_p->a_next; sb_p=sb_p->a_next);
443: sb_p->a_next = sa_p;
444: }
445: }
446: leng = strlen( g_entries[x].val );
447: if ( leng > 0 ) {
448: sprintf(buf,"%d\t%s\t",q_idx,g_entries[x].val);
449: strcat(submissions_str,buf);
450: }
451: }
452: }
453: }
454: if( !strncmp(g_entries[x].name,"LAST",4) ) {
455: StudentAnswer_t *sa_p;
456: if( index(g_entries[x].name, ',' ) == NULL ) { /* only one answer */
457: sscanf(g_entries[x].name,"LAST%d",&q_idx);
458: if( q_idx > 0 && q_idx < MAX_PROBLEM_CNT ) {
459: sa_p = (StudentAnswer_t *)capa_malloc(sizeof(StudentAnswer_t),1);
460: sa_p->a_idx = 1;
461: sa_p->a_str = strsave(g_entries[x].val);
462: sa_p->a_next = NULL;
463: g_last_ans_pp[q_idx] = sa_p;
464: }
465: } else {
466: sscanf(g_entries[x].name,"LAST%d,%d",&q_idx,&sub_idx);
467: if( q_idx > 0 && q_idx < MAX_PROBLEM_CNT ) {
468: sa_p = (StudentAnswer_t *)capa_malloc(sizeof(StudentAnswer_t),1);
469: sa_p->a_idx = sub_idx;
470: sa_p->a_str = strsave(g_entries[x].val);
471: sa_p->a_next = NULL;
472: if( g_last_ans_pp[q_idx] == NULL) {
473: g_last_ans_pp[q_idx] = sa_p;
474: } else {
475: StudentAnswer_t *sb_p;
476: for(sb_p=g_last_ans_pp[q_idx]; sb_p->a_next; sb_p=sb_p->a_next);
477: sb_p->a_next = sa_p;
478: }
479: }
480: }
481: }
482: }
483:
484: /* ========================================================================= */
485: /* Check in: Class name (CLASS)
486: Student Number (SNUM)
487: CAPA ID (CAPAID)
488: M=1
489: Try set: Class name (CLASS)
490: Student Number (SNUM)
491: CAPA ID (CAPAID)
492: First question to print (STARTNUM)
493: M=2
494: View previous: Class name (CLASS)
495: Student Number (SNUM)
496: CAPA ID (CAPAID)
497: First question to print (STARTNUM)
498: View set (VSET)
499: M=3
500: Set summary:
501:
502: --------------------------------------------------------------------------- */
503:
504: int w_get_input()
505: {
506: register int x,m=0;
507: int cl, q_idx, result = 1;
508: T_header header;
509: char log_str[MAX_BUFFER_SIZE],buf[MAX_BUFFER_SIZE];
510: char submissions_str[MAX_BUFFER_SIZE];
511: time_t curtime;
512: char *time_str,*UNKNOWN="UNKNOWN";
513: int error=0;
514: char *envPtr=NULL,*envPtr2=NULL;
515: #ifdef CGI_DBUG
516: fprintf(g_cgi,"Entered get_input()\n"); fflush(g_cgi);
517: #endif /* CGI_DBUG */
518:
519: envPtr=getenv("REQUEST_METHOD");
520: if(!envPtr) {
521: fprintf(stdout,"Enviroment variable REQUEST_METHOD not set.\n");
522: fprintf(stdout,"CAPA is improperly installed or run, please let your \
523: instructor know about this error.\n");
524: fprintf(stdout,"No tries have been deducted for the last submission.\n");
525: error |= 1;
526: return error;
527: }
528: if(strcmp(envPtr,"POST")) {
529: fprintf(stdout,"This script should be referenced with a METHOD of POST.\n");
530: fprintf(stdout,"CAPA is improperly installed or run, please let your \
531: instructor know about this error.\n");
532: fprintf(stdout,"No tries have been deducted for the last submission.\n");
533: fflush(stdout);
534: #ifdef CGI_DBUG
535: fprintf(g_cgi,"Request_method is not POST\n"); fflush(g_cgi);
536: #endif /* CGI_DBUG */
537: error |= 2; return (error);
538: }
539:
540: envPtr=getenv("CONTENT_TYPE");
541: if(!envPtr) {
542: fprintf(stdout,"Enviroment variable CONTENT_TYPE not set.\n");
543: fprintf(stdout,"CAPA is improperly installed or run, please let your \
544: instructor know about this error.\n");
545: fprintf(stdout,"No tries have been deducted for the last submission.\n");
546: fflush(stdout);
547: error |= 4;
548: return error;
549: }
550: if(strncmp(envPtr,"application/x-www-form-urlencoded",33)) {
551: fprintf(stdout,"This script can only be used to decode form results. \n");
552: fprintf(stdout,"CAPA is improperly installed or run, please let your \
553: instructor know about this error.\n");
554: fprintf(stdout,"No tries have been deducted for the last submission.\n");
555: fflush(stdout);
556: #ifdef CGI_DBUG
557: fprintf(g_cgi,"CONTENT_TYPE is not application/x-www-form-urlencoded\n"); fflush(g_cgi);
558: #endif /* CGI_DBUG */
559: error |= 8; return (error);
560: }
561:
562: envPtr=getenv("CONTENT_LENGTH");
563: if(!envPtr) {
564: fprintf(stdout,"Enviroment variable CONTENT_LENGTH not set.\n");
565: fprintf(stdout,"CAPA is improperly installed or run, please let your \
566: instructor know about this error.\n");
567: fprintf(stdout,"No tries have been deducted for the last submission.\n");
568: error |= 16;
569: return error;
570: }
571: cl = atoi(envPtr);
572: #ifdef CGI_DBUG
573: fprintf(g_cgi,"CONTENT_LENGTH is %d\n",cl); fflush(g_cgi);
574: #endif /* CGI_DBUG */
575: for(x=0;cl && (!feof(stdin));x++) {
576: m=x;
577: g_entries[x].val = fmakeword(stdin,'&',&cl);
578: plustospace(g_entries[x].val);
579: unescape_url(g_entries[x].val);
580: g_entries[x].name = makeword(g_entries[x].val,'=');
581: }
582: /* ---------------------------------------------------- */
583: g_entered_pin = 0; g_run_mode =0;
584: submissions_str[0]='\0';
585: for(x=0; x <= m; x++) {
586: if( !strcmp(g_entries[x].name,"CLASS") ) {
587: strncpy(g_class_name,g_entries[x].val,MAX_CLASS_CHAR);
588: }
589: if( !strcmp(g_entries[x].name,"M") ) { /* run mode */
590: sscanf(g_entries[x].val,"%d",&g_run_mode);
591: }
592: if( !strcmp(g_entries[x].name,"STARTNUM")) {
593: sscanf(g_entries[x].val,"%d",&g_start_question);
594: }
595: if( !strcmp(g_entries[x].name,"SNUM") ) {
596: strncpy(g_student_number,g_entries[x].val,MAX_STUDENT_NUMBER+4);
597: }
598: if( !strcmp(g_entries[x].name,"CAPAID") ) {
599: sscanf(g_entries[x].val,"%d",&g_entered_pin);
600: }
601: if( !strcmp(g_entries[x].name,"SET") ) {
602: sscanf(g_entries[x].val,"%d",&g_set);
603: }
604: if( !strcmp(g_entries[x].name,"VSET") ) {
605: if (g_entries[x].val[0] == '\0') {
606: g_vset=0;
607: } else {
608: sscanf(g_entries[x].val,"%d",&g_vset);
609: }
610: }
611: if( !strcmp(g_entries[x].name,"KND") ) {
612: sscanf(g_entries[x].val,"%d",&g_skind);
613: }
614: w_get_responses(x,q_idx,submissions_str);
615: free(g_entries[x].val);
616: free(g_entries[x].name);
617: }
618:
619: #ifdef CGI_DBUG
620: fprintf(g_cgi,"DONE: Parse input\n"); fflush(g_cgi);
621: #endif /* CGI_DBUG */
622: /* --------------------------------------------------------- */
623: /* if( strcasecmp(g_prog_name,"capacheckin") == 0 ) { */
624: if( g_run_mode == M_CHECKIN ) { /* capa_checkin */
625: time(&curtime); time_str = ctime(&curtime);
626: time_str[ strlen(time_str)-1 ] = 0;
627: envPtr=getenv("REMOTE_HOST");
628: if(!envPtr) {
629: fprintf(stdout,"<!-- Enviroment variable REMOTE_HOST not set.-->\n");
630: envPtr=getenv("REMOTE_ADDR");
631: if(!envPtr) {
632: fprintf(stdout,"<!-- Enviroment variable REMOTE_ADDR not set.-->\n");
633: envPtr=UNKNOWN;
634: error |= 32;
635: }
636: }
637: #ifdef CGI_DBUG
638: fprintf(g_cgi,"DONE: REMOTE_HOST\n"); fflush(g_cgi);
639: #endif /* CGI_DBUG */
640:
641: envPtr2=getenv("HTTP_USER_AGENT");
642: if(!envPtr2) {
643: fprintf(stdout,"<!-- Enviroment variable HTTP_USER_AGENT not set. -->\n");
644: envPtr2=UNKNOWN;
645: error |= 64;
646: }
647: sprintf(log_str,"%s\t%s\t%s\t%s\t%s\n",g_class_name,g_student_number,time_str,envPtr,envPtr2);
648: if (web_log(log_str) == -1 ) {
649: fprintf(stdout,"Unable to log access to the system. Please notify instructor\n.");
650: fprintf(stdout,"No tries have been deducted for the last submission.\n");
651: error |= 128;
652: return error;
653: }
654:
655: }
656: #if defined(NeXT)
657: getwd(g_cwd);
658: #else
659: getcwd(g_cwd,255);
660: #endif
661: web_getclassdir(&g_cpath, &g_cowner, g_class_name);
662: sprintf(g_class_fullpath,"%s/%s",g_cpath,g_class_name);
663: #ifdef CGI_DBUG
664: fprintf(g_cgi,"DONE: getclassdir() [%s]\n",g_class_fullpath); fflush(g_cgi);
665: #endif /* CGI_DBUG */
666: if( !capa_access(g_class_fullpath, F_OK) == 0 ) {
667: fprintf(stdout,"ACCESS: could not access the class directory [%s]!\n",g_class_fullpath);
668: fprintf(stdout,"Please exit the web browser and try accessing the system again\n");
669: fprintf(stdout,"No tries have been deducted for the last submission.\n");
670: fflush(stdout);
671: sprintf(log_str,"Failed to access class dir, g_class_fullpath: %s\tg_cpath: %s\tg_class_name: %s\tg_cowner: %s\tg_cwd: %s\t",
672: g_class_fullpath,g_cpath,g_class_name,g_cowner,g_cwd);
673: if (web_log(log_str) == -1 ) {
674: fprintf(stdout,"Unable to log access to the system. Please notify instructor\n.");
675: fflush(stdout);
676: error |= 256;
677: return error;
678: }
679: #ifdef CGI_DBUG
680: fprintf(g_cgi,"NO ACCESS: cannot access() [%s]\n",g_class_fullpath); fflush(g_cgi);
681: #endif /* CGI_DBUG */
682: error |= 512;
683: return (error);
684: }
685: /* ---------------------------------------------------- */
686: /* change working directory to the class */
687: /* ---------------------------------------------------- */
688: chdir(g_class_fullpath); /* before performing any capa*() calls */
689: #ifdef CGI_DBUG
690: fprintf(g_cgi,"DONE cd to [%s]\n",g_class_fullpath); fflush(g_cgi);
691: #endif /* CGI_DBUG */
692:
693: /* Now in proper directory, can log submissions */
694: if ( g_run_mode == M_CHECKANS) {
695: if (w_log_submissions(g_student_number,g_set,submissions_str) == -1 ) {
696: fprintf(stdout,"Unable to log submissions. Please notify instructor\n.");
697: fprintf(stdout,"No tries have been deducted for the last submission.\n");
698: error |= 1024;
699: return error;
700: }
701: }
702:
703: result=read_capa_config("capaweb_cgibin_path",buf);
704: if (result != 0 && result != -1) {
705: g_cgibin_path=capa_malloc(strlen(buf)+1,1);
706: strcpy(g_cgibin_path,buf);
707: } else {
708: g_cgibin_path=capa_malloc(strlen("capa-bin")+1,1);
709: strcpy(g_cgibin_path,"capa-bin");
710: }
711:
712: if( g_entered_pin != 0 ) {
713: g_login_set = capa_PIN(g_student_number,999,g_entered_pin);
714: #ifdef CGI_DBUG
715: fprintf(g_cgi,"Succeed in login to set %d with pin %d\n",g_login_set,g_entered_pin); fflush(g_cgi);
716: #endif /* CGI_DBUG */
717: /* ----------------------------------------------------
718: printf("Your entered capa id %d, login to set %d\n", g_entered_pin, g_login_set);
719: printf("The real capa id for %s is %d\n",g_student_number,capa_PIN(g_student_number,1,0));
720: ---------------------------------------------------- */
721:
722: } else {
723: fprintf(stdout,"CAPA ID entered was zero, this is not valid.\n");
724: fprintf(stdout,"No tries have been deducted for the last submission.\n");
725: fflush(stdout);
726: error |= 2048; return (error);
727: }
728:
729: if (!g_login_set) {
730: fprintf(stdout,"The student ID (%s) or CAPA ID (%d) that you entered \
731: is not listed for the class (%s) that you have selected. Please check that \
732: you have selected the correct class on the CAPA logon page and that the \
733: student ID and CAPA ID are correct.\n",
734: g_student_number, g_entered_pin, g_class_name);
735: fflush(stdout);
736: #ifdef CGI_DBUG
737: fprintf(g_cgi,"CAPA ID or student number is not valid.\n");
738: fflush(g_cgi);
739: #endif /* CGI_DBUG */
740: error |= 4096; return (error);
741: } else {
742: if ( g_login_set > 99 ) {
743: fprintf(stdout,"The student ID (%s) or CAPA ID (%d) that you entered \
744: is not listed for the class (%s) that you have selected. Please check that \
745: you have selected the correct class on the CAPA logon page and that the \
746: student ID and CAPA ID are correct.\n",
747: g_student_number, g_entered_pin, g_class_name);
748: fflush(stdout);
749: #ifdef CGI_DBUG
750: fprintf(g_cgi,"CAPA ID is not valid.\n"); fflush(g_cgi);
751: #endif /* CGI_DBUG */
752: error |= 8192; return (error);
753: }
754: if(g_login_set < g_vset ) {
755: fprintf(stdout,"Your CAPA ID (for set %d) does not allow you to view set %d.\n",g_login_set, g_vset);
756: fflush(stdout);
757: #ifdef CGI_DBUG
758: fprintf(g_cgi,"Login set %d is less than view set %d.\n",g_login_set,g_vset); fflush(g_cgi);
759: #endif /* CGI_DBUG */
760: error |= 16384; return (error);
761: }
762: chdir(g_class_fullpath); /* again, to make sure */
763:
764: if ( capa_get_student(g_student_number,&g_student_data) == 0 ) {
765: fprintf(stdout,"Entered student id is not in the class list.\n");
766: fprintf(stdout,"Please check that have selected the correct class \
767: and have entered you student id correctly.\n");
768: fflush(stdout);
769: #ifdef CGI_DBUG
770: fprintf(g_cgi,"get_student(): Student id not in the classl file.\n"); fflush(g_cgi);
771: #endif /* CGI_DBUG */
772: error |= 32768; return (error);
773: } else {
774: time(&curtime);
775: if (capa_get_header(&header, g_login_set)) {
776: fprintf(stdout,"This problem set is not ready yet.\n");
777: fflush(stdout);
778:
779: #ifdef CGI_DBUG
780: fprintf(g_cgi,"get_header(): Problem set not ready.\n"); fflush(g_cgi);
781: #endif /* CGI_DBUG */
782: error |= 65536; return (error);
783: }
784: capa_mfree(header.weight);
785: capa_mfree(header.partial_credit);
786: /* ===> if (compare_datetime(curtime,header.open_date) < 0 ) { */
787: if( capa_check_date(CHECK_OPEN_DATE,g_student_number,
788: g_student_data.s_sec,g_login_set) < 0 ) {
789: fprintf(stdout,"This set(%d) is not yet open. Please try back later.\n",g_login_set);
790: fflush(stdout);
791: #ifdef CGI_DBUG
792: fprintf(g_cgi,"check_date(): Problem set not open.\n");
793: fflush(g_cgi);
794: #endif /* CGI_DBUG */
795: error |= 131072; return (error);
796: }
797: }
798: }
799: return (error);
800: }
801:
1.13 albertel 802: void append_qtext_addbr(new_str) char *new_str;
803: {
804: int ii,jj,len;
805: char *br_added;
806: if (new_str==NULL) return;
807: len=strlen(new_str);
808: br_added=capa_malloc(len*5,sizeof(char));
809: for (ii=0,jj=0;ii<len;ii++) {
810: if (new_str[ii] == '\n') {
811: br_added[jj]='<';jj++;br_added[jj]='b';jj++;br_added[jj]='r';jj++;
812: br_added[jj]='>';jj++;br_added[jj]='\n';jj++;
813: } else {
814: br_added[jj]=new_str[ii];jj++;
815: }
816: }
817: br_added[jj]='\0';
818: append_qtext(br_added);
819: capa_mfree(br_added);
820: }
821: void append_qtext_addbr2(new_str) char *new_str;
822: {
823: char *br="<br>\n";
824: char single[2];
825: int ii,len;
826: single[0]='\0';single[1]='\0';
827: if (new_str==NULL) return;
828: len=strlen(new_str);
829: for (ii=0;ii<len;ii++) {
830: if (new_str[ii] == '\n') {
831: append_qtext(br);
832: } else {
833: single[0]=new_str[ii];
834: append_qtext(single);
835: }
836: }
837: }
1.1 albertel 838: /* ============================================================================= */
839: void append_qtext(new_str) char *new_str;
840: {
841: int ii,len;
842: if (new_str==NULL) return;
843: len=strlen(new_str);
844: #ifdef CGI_DBUG
845: fprintf(g_cgi,"before: len %d; g_qchar_cnt %d; g_qsize %d\n",
846: len,g_qchar_cnt,g_qsize);
847: fflush(g_cgi);
848: #endif /* CGI_DBUG */
1.13 albertel 849: if (g_qchar_cnt+len>g_qsize-3) {
1.1 albertel 850: char *temp_text;
851: g_qsize=(g_qchar_cnt+len)*2;
852: temp_text=capa_malloc(g_qsize,sizeof(char));
853: strncpy(temp_text,g_question_txt,g_qchar_cnt);
1.13 albertel 854: temp_text[g_qchar_cnt]='\0';
1.1 albertel 855: capa_mfree(g_question_txt);
856: g_question_txt=temp_text;
1.13 albertel 857: /*
858: g_qsize=(g_qchar_cnt+len)*2;
859: g_question_txt=realloc(g_question_txt,g_qsize);
860: */
1.1 albertel 861: }
862: for(ii=0;ii<len;ii++) {
863: g_question_txt[g_qchar_cnt+ii]=new_str[ii];
864: }
865: g_qchar_cnt += len;
1.13 albertel 866: g_question_txt[g_qchar_cnt]='\0';
1.1 albertel 867: #ifdef CGI_DBUG
1.11 albertel 868: fprintf(g_cgi,"after: len %d; g_qchar_cnt %d; g_qsize %d; strlen(g_question_txt):%d\n",len,g_qchar_cnt,g_qsize,strlen(g_question_txt));
1.1 albertel 869: fflush(g_cgi);
870: #endif /* CGI_DBUG */
871: }
872: void append_stext(new_str) char *new_str;
873: {
874: int ii,len;
875: if (new_str==NULL) return;
876: len=strlen(new_str);
877: #ifdef CGI_DBUG
878: fprintf(g_cgi,"appending status{%s}\nlen %d; g_schar_cnt %d; g_ssize %d\n",
879: new_str,len,g_schar_cnt,g_ssize);
880: fflush(g_cgi);
881: #endif /* CGI_DBUG */
1.11 albertel 882: if (g_schar_cnt+len>g_ssize-2) {
1.1 albertel 883: char *temp_text;
884: g_ssize=(g_schar_cnt+len)*2;
885: temp_text=capa_malloc(g_ssize,sizeof(char));
886: strncpy(temp_text,g_status_txt,g_schar_cnt);
887: capa_mfree(g_status_txt);
888: g_status_txt=temp_text;
889: }
890: for(ii=0;ii<len;ii++) {
891: g_status_txt[g_schar_cnt+ii]=new_str[ii];
892: }
893: g_schar_cnt += len;
894: g_status_txt[g_schar_cnt+1]='\0';
895: #ifdef CGI_DBUG
896: fprintf(g_cgi,"len %d; g_schar_cnt %d; g_ssize %d\n",len,g_schar_cnt,g_ssize);
897: fflush(g_cgi);
898: #endif /* CGI_DBUG */
899: }
900: /* ============================================================================= */
901: /* ------------------------------------------------------------
902: printf("ENV<br>\n");
903: printf("SERVER_PROTOCOL:%s<br>",getenv("SERVER_PROTOCOL"));
904: printf("PATH_INFO:%s<br>",getenv("PATH_INFO"));
905: printf("PATH_TRANSLATED:%s<br>\n",getenv("PATH_TRANSLATED"));
906: printf("SCRIPT_NAME:%s<br>\n",getenv("SCRIPT_NAME"));
907: printf("QUERY_STRING:%s<br>\n",getenv("QUERY_STRING"));
908: printf("REMOTE_HOST:%s<br>\n",getenv("REMOTE_HOST"));
909: printf("REMOTE_USER:%s<br>\n",getenv("REMOTE_USER"));
910: printf("REMOTE_IDENT:%s<br>\n",getenv("REMOTE_IDENT"));
911: printf("USER_AGENT:%s<br>\n",getenv("USER_AGENT"));
912: printf("HTTP_USER_AGENT:%s<br>\n",getenv("HTTP_USER_AGENT"));
913: ------------------------------------------------------------
914: */
915:
916: /* ------------------------------------------------------ */
917: /* A class directory must have */
918: /* records/ */
919: /* */
920: /* returns: 0 structure is correct, but no set.db files */
921: /* -1 structure is not correct */
922: /* >=1 the last set.db */
923:
924: int
925: check_class_get_maxset(dir_path) char *dir_path;
926: {
927: char f_name[1024];
928: int set;
929:
930: if( capa_access(dir_path, F_OK) == 0 ) { /* class dir exists */
931: sprintf(f_name,"%s/records",dir_path);
932: if( capa_access(f_name, F_OK) == 0 ) { /* class/records dir exists */
933: for(set = 1; ; set++ ) {
934: sprintf(f_name,"%s/records/set%d.db",dir_path,set);
935: if(capa_access(f_name, F_OK) == -1 ) break;
936: }
937: set--;
938: } else {
939: set = -1;
940: }
941: } else {
942: set = -1;
943: }
944: return (set);
945: }
946:
947: /* ------------------------------------------------------------------------- */
948: /* Get Exam and Quiz Path */
949: /* return 0, 1, 2, 3 */
950: /* 0: Neither exist */
951: /* 1: Exam.path exists */
952: /* 2: Quiz.path exists */
953: /* 3: Both Exam.path and Quiz.path exists */
954: /* ------------------------------------------------------------------------- */
955: int
956: check_exam_quiz_path()
957: {
958: char buf[MAX_BUFFER_SIZE];
959: int result = 0, configResult=0;
960:
961: configResult=read_capa_config("exam_path",buf);
962: if (configResult != 0 && configResult != -1) {
963: g_exam_set = check_class_get_maxset(buf);
964: if(g_exam_set > 0 ) {
965: result = 1;
966: sprintf(g_exam_path,buf);
967: }
968: }
969: configResult=read_capa_config("quiz_path",buf);
970: if (configResult != 0 && configResult != -1) {
971: g_quiz_set = check_class_get_maxset(buf);
972: if(g_quiz_set > 0 ) {
973: result = (result | 2);
974: sprintf(g_quiz_path,buf);
975: }
976: }
977: return (result);
978: }
979:
980:
981: int
982: check_termscore_option()
983: {
984: char buf[MAX_BUFFER_SIZE];
985: int result = 0, configResult=0;
986:
987: configResult=read_capa_config("term_score_applet",buf);
988: if (configResult != 0 && configResult != -1) {
989: fprintf(stdout,"<!-- term_score_applet is in capa.config file -->\n");
990: if (strcasecmp(buf,"yes")==0) {
991: fprintf(stdout,"<!-- term_score_applet is YES -->\n");
992: result=1;
993: }
994: }
995: return (result);
996: }
997:
998:
999:
1000:
1001: /* ============================================================================= */
1002: void
1003: print_mainmenu(class,sn,pin)char *class; char *sn;int pin;
1004: {
1005: char buf[MAX_BUFFER_SIZE];
1006: int outcome,configResult,term_summary_button=1;
1007: char *serverName;
1008:
1009: serverName=getenv("SERVER_NAME");
1010: if (!serverName) {
1011: fprintf(stdout,"Enviroment variable SERVER_NAME not set.\n");
1012: fprintf(stdout,"Unable to complete actions.\n");
1013: return;
1014: }
1015:
1016: fprintf(stdout,"<TITLE>%s main menu</TITLE>\n",g_class_name);
1017: fprintf(stdout,"<h3>%s</h3><br>\n",g_student_name);
1018: fprintf(stdout,"<menu>\n");
1019: fprintf(stdout,"<li><form method=\"get\" action=\"http://%s/CAPA/help.html\">",serverName);
1020: fprintf(stdout,"<input type=\"submit\" value=\"Help\" ></form>\n");
1021:
1022: fprintf(stdout,"<li><form method=\"post\" ");
1023: /* fprintf(stdout," target=\"right_frame\" "); */
1024: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
1025: fprintf(stdout,"%s\n", buf);
1026: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",class);
1027: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",sn);
1028: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",pin);
1029: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_TRYSET);
1030: fprintf(stdout,"<input type=\"hidden\" name=\"STARTNUM\" value=\"%d\">\n",1);
1031: fprintf(stdout,"<input type=\"submit\" value=\"Try current set\" ></form>\n");
1032:
1033: fprintf(stdout,"<li><form method=\"post\" ");
1034: /* fprintf(stdout," target=\"right_frame\" "); */
1035: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
1036: fprintf(stdout,"%s\n", buf);
1037: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",class);
1038: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",sn);
1039: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",pin);
1040: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_VIEWPREV);
1041: fprintf(stdout,"<input type=\"hidden\" name=\"STARTNUM\" value=\"%d\">\n",1);
1042: fprintf(stdout,"<input type=\"submit\" value=\"View previous set:\" >");
1043: fprintf(stdout,"<b> set:</b><input name=\"VSET\" value=\"\" size=4></form>\n");
1044:
1045: /*Term Summary*/
1046: configResult=read_capa_config("term_summary_button",buf);
1047: if (configResult != 0 && configResult != -1 ) {
1048: if (strcasecmp(buf,"no")==0) {
1049: term_summary_button=0;
1050: }
1051: }
1052: if (term_summary_button) {
1053: fprintf(stdout,"<li><form method=\"post\" ");
1054: /* fprintf(stdout," target=\"right_frame\" "); */
1055: sprintf(buf,"action=\"http://%s/%s/capahtml\">",serverName,g_cgibin_path);
1056: fprintf(stdout,"%s\n", buf);
1057: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",class);
1058: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",sn);
1059: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",pin);
1060: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_VIEWSUMM);
1061: fprintf(stdout,"<input type=\"submit\" value=\"Display term summary\" ></form>\n");
1062: }
1063:
1064: outcome = check_exam_quiz_path();
1065: if( outcome & 1 ) { /* exam summary */
1066: fprintf(stdout,"<li><form method=\"post\" ");
1067: /* fprintf(stdout," target=\"right_frame\" "); */
1068: sprintf(buf,"action=\"http://%s/%s/capahtml\">",serverName,g_cgibin_path);
1069: fprintf(stdout,"%s\n", buf);
1070: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",class);
1071: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",sn);
1072: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",pin);
1073: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_EXAMSUMM);
1074: fprintf(stdout,"<input type=\"submit\" value=\"Display Exam summary\" ></form>\n");
1075: }
1076: if( outcome & 2 ) { /* Quiz summary */
1077: fprintf(stdout,"<li><form method=\"post\" ");
1078: /* fprintf(stdout," target=\"right_frame\" "); */
1079: sprintf(buf,"action=\"http://%s/%s/capahtml\">",serverName,g_cgibin_path);
1080: fprintf(stdout,"%s\n", buf);
1081: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",class);
1082: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",sn);
1083: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",pin);
1084: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\" >\n",M_QUIZSUMM );
1085: fprintf(stdout,"<input type=\"submit\" value=\"Display Quiz summary\" ></form>\n");
1086: }
1087: outcome = check_termscore_option();
1.6 albertel 1088: fprintf(stdout,"<!-- Outcome of check_termscore_option()=%d -->\n",outcome);
1.1 albertel 1089: /*Termscore Button*/
1090: if( outcome ) {
1091: fprintf(stdout,"<li><form method=\"post\" ");
1.7 albertel 1092: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
1.1 albertel 1093: fprintf(stdout,"%s\n", buf);
1094: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",class);
1095: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",sn);
1096: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",pin);
1097: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\" >\n",M_TERMSCORE );
1098: fprintf(stdout,"<input type=\"submit\" value=\"Extrapolate Term score\" ></form>\n");
1099: }
1100: /*Exit Button*/
1101: fprintf(stdout,"<TD><form method=\"get\" action=\"http://%s/CAPA/class.html\">",serverName);
1102: fprintf(stdout,"<input type=\"button\" value=\"Exit\" onclick=\"window.close()\"></form></TD>");
1103:
1104: fprintf(stdout,"</menu>\n"); fflush(stdout);
1105:
1106: }
1107:
1108: /* ====================================================================================== */
1109: void
1110: print_page_header(mode,num_quest) int mode;int num_quest;
1111: {
1.2 albertel 1112: char buf[MAX_BUFFER_SIZE], discussdir[MAX_BUFFER_SIZE];
1.1 albertel 1113: char *serverName;
1114: int configResult,term_summary_button=1;
1115:
1.11 albertel 1116: buf[0]='\0';
1117: discussdir[0]='\0';
1.1 albertel 1118: serverName=getenv("SERVER_NAME");
1119: if (!serverName) {
1120: fprintf(stdout,"Enviroment variable SERVER_NAME not set.\n");
1121: fprintf(stdout,"Unable to complete actions.\n");
1122: return;
1123: }
1124:
1125: /* now done in the .qz file
1126: fprintf(stdout,"<TITLE>%s set%d</TITLE>",g_class_name,g_login_set);
1127: if( mode == VIEW_PREVIOUS_MODE ) {
1128: fprintf(stdout,"<H2>%s set%d</H2>\n",g_class_name,g_vset);
1129: } else {
1130: fprintf(stdout,"<H2>%s set%d</H2>\n",g_class_name,g_login_set);
1131: }
1132: fprintf(stdout,"<H3>%s</H3>\n",g_student_data.s_nm);
1133: */
1134:
1135: fprintf(stdout,"<A NAME=\"TOP\"></A>");
1136: fprintf(stdout,"<TABLE cellpadding=0 cellspacing=0 border=0>\n<TR><TD>");
1137:
1138:
1139: /*Term summary button*/
1140: configResult=read_capa_config("term_summary_button",buf);
1141: if (configResult != 0 && configResult != -1 ) {
1142: if (strcasecmp(buf,"no")==0) {
1143: term_summary_button=0;
1144: }
1145: }
1146: #ifdef CGI_DBUG
1147: fprintf(g_cgi,"buf: %s\ntermsum: %d\n",buf,term_summary_button); fflush(g_cgi);
1148: #endif /* CGI_DBUG */
1149:
1150: if (term_summary_button) {
1151: fprintf(stdout,"<form method=\"post\" ");
1152: sprintf(buf,"action=\"http://%s/%s/capahtml\">",serverName,g_cgibin_path);
1153: fprintf(stdout,"%s\n", buf);
1154: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",g_class_name);
1155: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",g_student_number);
1156: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",g_entered_pin);
1157: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_VIEWSUMM);
1158: fprintf(stdout,"<input type=\"submit\" value=\"Term summary\" ></form></TD>\n");
1159: }
1160:
1161: /*Exit Button*/
1162: fprintf(stdout,"<TD><form method=\"get\" action=\"http://%s/CAPA/class.html\">",serverName);
1163: fprintf(stdout,"<input type=\"button\" value=\"Exit\" onclick=\"window.close()\"></form></TD>");
1164: /*help button*/
1165: if (mode != VIEW_PREVIOUS_MODE) {
1166: fprintf(stdout,"<TD><form method=\"get\" action=\"http://%s/CAPA/help.html\">",serverName);
1167: fprintf(stdout,"<input type=\"submit\" value=\"Help\"></form></TD>");
1168: }
1169:
1170: /*Reload button*/
1171: fprintf(stdout,"<TD><form method=\"post\" ");
1172: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
1173: fprintf(stdout,"%s\n", buf);
1174: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",g_class_name);
1175: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",g_student_number);
1176: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",g_entered_pin);
1177: fprintf(stdout,"<input type=\"hidden\" name=\"STARTNUM\" value=\"%d\">\n",g_start_question);
1178: if (mode == VIEW_PREVIOUS_MODE ) {
1179: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_VIEWPREV);
1180: fprintf(stdout,"<input type=\"hidden\" name=\"VSET\" value=\"%d\" size=4>\n",g_vset);
1181: } else {
1182: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_TRYSET);
1183: }
1184: fprintf(stdout,"<input type=\"submit\" value=\"Reload\" >\n</form></TD>");
1185: #ifdef NOT_DEFINED
1186: /* Next Button */
1187: if ( (!(g_num_questions_per_page==ALL_QUESTIONS)) &&
1188: ((g_num_questions_per_page+g_start_question)<num_quest)) {
1189: fprintf(stdout,"<TD><form method=\"post\" ");
1190: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
1191: fprintf(stdout,"%s\n", buf);
1192: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",g_class_name);
1193: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",g_student_number);
1194: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",g_entered_pin);
1195: fprintf(stdout,"<input type=\"hidden\" name=\"STARTNUM\" value=\"%d\">\n",g_start_question+g_num_questions_per_page);
1196: if (mode == VIEW_PREVIOUS_MODE ) {
1197: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_VIEWPREV);
1198: fprintf(stdout,"<input type=\"hidden\" name=\"VSET\" value=\"%d\" size=4>\n",g_vset);
1199: } else {
1200: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_TRYSET);
1201: }
1202: fprintf(stdout,"<input type=\"submit\" value=\"Next Page\" >\n</form></TD>");
1203: }
1204:
1205: /* Previous Button */
1206: if ( (!(g_num_questions_per_page==ALL_QUESTIONS)) && (g_start_question > 1)) {
1207: fprintf(stdout,"<TD><form method=\"post\" ");
1208: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
1209: fprintf(stdout,"%s\n", buf);
1210: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",g_class_name);
1211: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",g_student_number);
1212: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",g_entered_pin);
1213: fprintf(stdout,"<input type=\"hidden\" name=\"STARTNUM\" value=\"%d\">\n",g_start_question-g_num_questions_per_page);
1214: if (mode == VIEW_PREVIOUS_MODE ) {
1215: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_VIEWPREV);
1216: fprintf(stdout,"<input type=\"hidden\" name=\"VSET\" value=\"%d\" size=4>\n",g_vset);
1217: } else {
1218: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_TRYSET);
1219: }
1220: fprintf(stdout,"<input type=\"submit\" value=\"Previous Page\" >\n</form></TD>");
1221: }
1222: #endif
1223: /* Goto Button */
1224: if (!(g_num_questions_per_page==ALL_QUESTIONS)) {
1225: int idx,numquest;
1226: T_header header;
1227: fprintf(stdout,"<TD><form method=\"post\" ");
1228: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
1229: fprintf(stdout,"%s\n", buf);
1230: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",g_class_name);
1231: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",g_student_number);
1232: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",g_entered_pin);
1233: fprintf(stdout,"<input type=\"submit\" value=\"Goto\" >");
1234: fprintf(stdout,"<b>Problem:</b><input name=\"STARTNUM\" value=\"\" size=4>\n");
1235: if (mode == VIEW_PREVIOUS_MODE ) {
1236: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_VIEWPREV);
1237: fprintf(stdout,"<input type=\"hidden\" name=\"VSET\" value=\"%d\" size=4>\n",g_vset);
1238: } else {
1239: fprintf(stdout,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_TRYSET);
1240: }
1241:
1242: if (!capa_get_header(&header, g_login_set)) {
1243: numquest=atoi(header.num_questions);
1244: capa_mfree(header.weight);
1245: capa_mfree(header.partial_credit);
1246: for(idx=0;idx<numquest;idx++) {
1247: preserve_last_answer(idx,1);
1248: }
1249: }
1250: fprintf(stdout,"</form></TD>");
1.2 albertel 1251: }
1252:
1253: /*Discuss Button*/
1254:
1255: sprintf(discussdir,"%s/discussion/%d",g_class_fullpath,g_login_set);
1256: if ( access(discussdir,F_OK) == 0 ) {
1257: fprintf(stdout,"<TD><form method=\"post\" ");
1258: sprintf(buf,"action=\"http://%s/%s/%s/capadiscuss\">",serverName,g_cgibin_path,g_cowner);
1259: fprintf(stdout,"%s\n", buf);
1260: fprintf(stdout,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",g_class_name);
1261: fprintf(stdout,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",g_student_number);
1262: fprintf(stdout,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",g_entered_pin);
1263: fprintf(stdout,"<input type=\"hidden\" name=\"SETID\" value=\"%d\">\n",g_login_set);
1264: fprintf(stdout,"<input type=\"submit\" value=\"Discuss\" >\n</form></TD>");
1.1 albertel 1265: }
1266:
1267: fprintf(stdout,"\n</TR></TABLE>\n");
1268: fflush(stdout);
1269: }
1270:
1271: void create_status_line(int mode,int question_cnt, T_entry* entry)
1272: {
1273: char buf[MAX_BUFFER_SIZE];
1274: int idx,configResult,status_line_length;
1275:
1276: configResult=read_capa_config("web_status_line_length",buf);
1277: if (configResult != 0 && configResult != -1 ) {
1278: if (sscanf(buf,"%d",&status_line_length)==0) {
1279: status_line_length=question_cnt;
1280: }
1281: } else {
1282: status_line_length=question_cnt;
1283: }
1284:
1285: append_stext("<TABLE cellpadding=0 cellspacing=0 border=0><TR>");
1286: append_stext("<TD><b><u>Go to problem</u> </b></TD><TD></TD>");
1287: for(idx=0; idx < status_line_length;idx++ ) {
1288: sprintf(buf,"<TD ALIGN=center VALIGN=bottom>[%d]</TD>",idx+1);
1289: append_stext(buf);
1290: }
1291: for(idx = 0; idx < question_cnt; idx++ ) {
1292: if ( !(idx%status_line_length) ) {
1293: sprintf(buf,"</TR><TR><TD ALIGN=left>%d-%d</TD><TD ALIGN=right>Status: </TD>",
1294: idx+1,idx+status_line_length);
1295: append_stext(buf);
1296: }
1297: if ((idx >= g_start_question-1) &&
1298: (((g_num_questions_per_page == ALL_QUESTIONS)) ||
1299: (idx < (g_start_question+g_num_questions_per_page-1)))) {
1300: sprintf(buf,"<TD ALIGN=center VALIGN=bottom><A href=\"#P%d\">",idx+1);
1301: } else {
1302: sprintf(buf,"<TD ALIGN=center VALIGN=bottom>");
1303: }
1304: append_stext(buf);
1305: if ( (mode == CHECK_ANSWER_MODE) && g_log_string[idx] == '-') {
1306: if (g_inhibit_response && (entry->answers[idx]!='-')) {
1307: sprintf(buf,"A");
1308: } else {
1309: sprintf(buf,"%c",entry->answers[idx]);
1310: }
1311: } else {
1312: if (g_inhibit_response && (entry->answers[idx]!='-')) {
1313: sprintf(buf,"<b>A</b>");
1314: } else {
1315: if ( mode == CHECK_ANSWER_MODE ) {
1316: sprintf(buf,"<b>%c</b>",g_log_string[idx]);
1317: } else {
1318: sprintf(buf,"<b>%c</b>",entry->answers[idx]);
1319: }
1320: }
1321: }
1322: append_stext(buf);
1323: if ((idx >= g_start_question-1) &&
1324: (((g_num_questions_per_page == ALL_QUESTIONS)) ||
1325: (idx < (g_start_question+g_num_questions_per_page-1)))) {
1326: sprintf(buf,"</A></TD>");
1327: } else {
1328: sprintf(buf,"</TD>");
1329: }
1330: append_stext(buf);
1331: }
1332: append_stext("</TR></TABLE>\n");
1333: }
1334:
1335: /* -------------------------------- called by try set, view previous, check answer */
1336: void
1337: print_quizz(class_dir,c_owner,class,sn,pin,set,mode)
1338: char *class_dir; char *c_owner;char *class;char *sn;int pin;int set;int mode;
1339: {
1340: extern int Parsemode_f;
1341: extern char *StartText_p;
1342: extern char *EndText_p;
1343: Problem_t *first_prob, *prob_idx;
1344: int result, question_idx, question_cnt, idx, view_assignment_after_due=1;
1345: int q_leng, display_ans=1, configResult;
1346: int view_assignments_after_due=1;
1347: char buf[MAX_BUFFER_SIZE];
1348: char class_fullpath[FILE_NAME_LENGTH];
1349: T_entry entry;
1350: T_header header;
1351: long offset;
1352: double a;
1353: char cmp_ans[MAX_BUFFER_SIZE],date_str[DATE_BUFFER];
1354: time_t curtime;
1355: char *serverName;
1.13 albertel 1356: char *c_ans;
1.1 albertel 1357:
1358: serverName=getenv("SERVER_NAME");
1359: if (!serverName) {
1360: fprintf(stdout,"Enviroment variable SERVER_NAME not set.\n");
1361: fprintf(stdout,"Unable to complete actions.\n");
1362: return;
1363: }
1364:
1365: sprintf(class_fullpath,"%s/%s",class_dir,class);
1366:
1367: /*
1368: chdir(class_fullpath);
1369: */
1370: #ifdef CGI_DBUG
1371: fprintf(g_cgi,"enter print_quizz() %s, mode:%d\n",class_fullpath,mode); fflush(g_cgi);
1372: #endif /* CGI_DBUG */
1373:
1374: /* get configuration options */
1375: configResult=read_capa_config("num_questions_per_page",buf);
1376: if (configResult != 0 && configResult != -1 ) {
1377: if (sscanf(buf,"%d",&g_num_questions_per_page)==0) {
1378: g_num_questions_per_page=ALL_QUESTIONS;
1379: }
1380: } else {
1381: g_num_questions_per_page=ALL_QUESTIONS;
1382: }
1383:
1384: view_assignments_after_due=capa_check_option(OPTION_VIEW_PROBLEMS_AFTER_DUE,
1385: set,g_student_data.s_sec);
1386: if (view_assignments_after_due < 0 ) view_assignments_after_due=1;
1387: g_inhibit_response=capa_check_option(OPTION_INHIBIT_RESPONSE,set,g_student_data.s_sec);
1388: if (g_inhibit_response < 0 ) g_inhibit_response=0;
1389:
1390: #ifdef CGI_DBUG
1391: fprintf(g_cgi,"Set %d, Section%d, ViewAssign? %d, Inhibit Resp? %d\n",set,
1392: g_student_data.s_sec,view_assignments_after_due,
1393: g_inhibit_response);
1394: fflush(g_cgi);
1395: #endif /* CGI_DBUG */
1396:
1397: time(&curtime);
1398: offset=capa_get_entry(&entry,sn,set); /* <-------- capa*() call ---- */
1399: if( mode == VIEW_PREVIOUS_MODE ) {
1400: if( view_assignment_after_due ) {
1401: if( capa_check_date(CHECK_OPEN_DATE,g_student_number,
1402: g_student_data.s_sec,set) < 0 ) {
1403: append_qtext("This set is not yet open.\n");
1404: return ;
1405: }
1406: } else {
1407: if( (capa_check_date(CHECK_ANS_DATE,g_student_number,
1408: g_student_data.s_sec,set) < 0) &&
1409: (capa_check_date(CHECK_DUE_DATE,g_student_number,
1410: g_student_data.s_sec,set) > 0) ) {
1411: append_qtext("This set is not yet available to be viewed.\n");
1412: return ;
1413: }
1414: }
1415: if( capa_check_date(CHECK_ANS_DATE,g_student_number,
1416: g_student_data.s_sec,set) < 0 ) {
1417: display_ans = 0;
1418: }
1419: }
1420: g_passdue = 0;
1421: if( mode == CHECK_ANSWER_MODE ||
1422: ( (!view_assignment_after_due) && mode == TRY_SET_MODE)) {
1423: if( capa_check_date(CHECK_DUE_DATE,g_student_number,
1424: g_student_data.s_sec,set) > 0 ) {
1425: capa_get_date(CHECK_DUE_DATE,g_student_number,
1426: g_student_data.s_sec,set,date_str);
1427: sprintf(buf,"SORRY, the due date was: %s\n",date_str);
1428: append_qtext(buf);
1429: g_passdue = 1;
1430: }
1431: }
1432:
1.17 albertel 1433: if ((mode==CHECK_ANSWER_MODE) || (mode== TRY_SET_MODE) || (mode==VIEW_PREVIOUS_MODE))
1.1 albertel 1434: capa_set_login_time(g_student_number,set);
1435:
1436: capa_get_header(&header,set);
1437:
1438: sscanf(header.num_questions,"%d",&question_cnt);
1439: print_page_header(mode,question_cnt);
1440:
1441: #ifdef CGI_DBUG
1442: fprintf(g_cgi,"DONE page header\n"); fflush(g_cgi);
1443: #endif /* CGI_DBUG */
1444:
1445: if(offset < 0 ) offset = - offset;
1446:
1447: Parsemode_f = HTML_MODE; /* WEB_MODE */
1448: result = capa_parse(set, &first_prob, sn, &question_cnt,NULL); /* <-- capa*() call */
1449:
1450: #ifdef CGI_DBUG
1451: fprintf(g_cgi,"DONE capa_parse() [%d], pass due=%d\n",result,g_passdue); fflush(g_cgi);
1452: #endif /* CGI_DBUG */
1453:
1454: if (StartText_p) printf(StartText_p);
1455:
1456: #ifdef CGI_DBUG
1457: fprintf(g_cgi,"DONE Start Text\n"); fflush(g_cgi);
1458: #endif /* CGI_DBUG */
1459:
1460: if ( result != 0 ) {
1461: if( !g_passdue ) {
1.12 albertel 1462: append_qtext("<FORM NAME=\"CAPA\" method=\"post\" ");
1.1 albertel 1463: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,
1464: g_cgibin_path,c_owner);
1465: append_qtext(buf);
1466: sprintf(buf,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",class); append_qtext(buf);
1467: sprintf(buf,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",sn); append_qtext(buf);
1468: sprintf(buf,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",pin); append_qtext(buf);
1469: sprintf(buf,"<input type=\"hidden\" name=\"SET\" value=\"%d\">\n",set); append_qtext(buf);
1470: sprintf(buf,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_CHECKANS); append_qtext(buf);
1471: sprintf(buf,"<input type=\"hidden\" name=\"STARTNUM\" value=\"%d\">\n",g_start_question); append_qtext(buf);
1472: append_qtext("\n<OL>\n");
1473: }
1474:
1475: for(idx=0;idx<question_cnt;idx++) { /* prepare log string and new database entry */
1476: g_new_answerdb[idx] = entry.answers[idx];
1477: g_log_string[idx] = '-';
1478: sscanf(entry.tries + 3*idx,"%d,",&(g_tried[idx]) );
1479: }
1480: g_new_answerdb[question_cnt]=0; g_log_string[question_cnt]=0;
1481: prob_idx = first_prob;
1482: for( question_idx = 0; question_idx < question_cnt;
1483: question_idx++,prob_idx = prob_idx->next ) {
1484: #ifdef CGI_DBUG
1485: fprintf(g_cgi,"quetion_idx: %d, g_start_question:%d, g_num_que: %d\n",
1486: question_idx,g_start_question,g_num_questions_per_page); fflush(g_cgi);
1487: #endif /* CGI_DBUG */
1488: if ((question_idx < g_start_question-1)
1489: ||
1490: (((!(g_num_questions_per_page == ALL_QUESTIONS))
1491: &&
1492: (question_idx >= (g_start_question+g_num_questions_per_page-1))))) {
1493: preserve_last_answer(question_idx,0);
1494: continue;
1495: }
1496: if( !g_passdue ) {
1497: sprintf(buf,"<A NAME=\"P%d\"></A>",question_idx+1); append_qtext(buf);
1498: /* if (!((question_idx == (g_start_question-1)) || (question_idx == 0))) {
1499: append_qtext("<A href=\"#TOP\">Top</A>");
1500: sprintf(buf," <A href=\"#P%d\">Next</A>",question_idx+2); append_qtext(buf);
1501: }*/
1.4 albertel 1502: if (prob_idx->question != NULL) {
1503: q_leng = strlen(prob_idx->question);
1504: if ( !prob_idx->show_br ) {
1505: append_qtext(prob_idx->question);
1506: } else {
1.13 albertel 1507: append_qtext_addbr(prob_idx->question);
1508: /*
1.4 albertel 1509: for(idx=0;idx<q_leng;idx++) {
1.13 albertel 1510: if ( g_qchar_cnt+2 > g_qsize-2 ) {
1.4 albertel 1511: char *temp_text;
1.13 albertel 1512: g_qsize=(g_qchar_cnt+2)*2;
1.4 albertel 1513: temp_text=capa_malloc(g_qsize,sizeof(char));
1514: strncpy(temp_text,g_question_txt,g_qsize);
1515: capa_mfree(g_question_txt);
1516: g_question_txt=temp_text;
1517: }
1518: g_question_txt[g_qchar_cnt]=prob_idx->question[idx];
1519: g_qchar_cnt++;
1520: if(prob_idx->question[idx] == '\n' ) {
1521: append_qtext("<br>\n");
1522: }
1.1 albertel 1523: }
1.13 albertel 1524: */
1.1 albertel 1525: }
1526: }
1527: }
1528: if(mode == VIEW_PREVIOUS_MODE) { /* VIEW_PREVIOUS_MODE */
1.13 albertel 1529: /*
1.1 albertel 1530: if( prob_idx->ans_type == ANSWER_IS_FLOAT ) {
1531: a = (double)atof(prob_idx->answer);
1532: sprintf(cmp_ans,prob_idx->ans_fmt, a);
1533: } else {
1.13 albertel 1534: if ( prob_idx->ans_type == ANSWER_IS_SUBJECTIVE) {
1535: strcpy(cmp_ans,"Subjective Answer");
1536: } else {
1537: if (prob_idx->answer) {
1538: strcpy(cmp_ans,prob_idx->answer);
1539: } else {
1540: strcpy(cmp_ans,"No Answer");
1541: }
1542: }
1.1 albertel 1543: }
1544: if( prob_idx->ans_unit ) {
1545: sprintf(buf,"<p><tt><b>Answer:</b> %s %s</tt><br>\n",cmp_ans, prob_idx->unit_str);
1546: } else {
1547: sprintf(buf,"<p><tt><b>Answer:</b> %s</tt><br>\n",cmp_ans);
1548: }
1.13 albertel 1549: */
1.14 albertel 1550: if( display_ans ) {
1.13 albertel 1551: c_ans=answers_string(ANSWER_STRING_MODE, prob_idx);
1552: sprintf(buf,"<p><tt><b>Answer:</b> %s</tt><br>",c_ans);
1.1 albertel 1553: append_qtext(buf);
1.13 albertel 1554: capa_mfree(c_ans);
1.1 albertel 1555: if ( prob_idx->explain) {
1556: sprintf(buf,"<p><b>Explanation: </b>\n<p>%s<br>\n",prob_idx->explain);
1557: append_qtext(buf);
1558: }
1.14 albertel 1559: }
1.13 albertel 1560: } else { /* could be TRY_SET_MODE, CHECK_ANSWER_MODE */
1.1 albertel 1561: if( g_passdue ) {
1562: get_response(header.partial_credit[question_idx],entry.answers[question_idx],question_idx,prob_idx);
1563: }else{
1564: if (g_inhibit_response) {
1565: print_inhibited_response(header.partial_credit[question_idx],entry.answers[question_idx],question_idx,prob_idx);
1566: } else {
1567: print_response(header.partial_credit[question_idx],entry.answers[question_idx],question_idx,prob_idx);
1568: }
1569: append_qtext("<br>\n");
1570: if( (g_tried[question_idx] >= prob_idx->show_hint) ||
1571: (entry.answers[question_idx]=='Y') ||
1572: (entry.answers[question_idx]=='y')) {
1573: if( prob_idx->hint ) {
1574: sprintf(buf,"<p><B>Hint: </B>%s\n<br>\n", prob_idx->hint);
1575: append_qtext(buf);
1576: }
1577: }
1578: }
1579: }
1580: } /* ------------------------------------- end displaying each problem */
1581: append_qtext("\n</OL>\n");
1582: if( EndText_p ) append_qtext(EndText_p);
1583: free_problems(first_prob);
1.13 albertel 1584: free_units();
1.1 albertel 1585: #ifdef CGI_DBUG
1586: fprintf(g_cgi,"End display each problem\n"); fflush(g_cgi);
1587: #endif /* CGI_DBUG */
1588:
1589: if( mode == CHECK_ANSWER_MODE ) { /* update the record database */
1590: if( !g_passdue ) {
1591: for(idx=0;idx<question_cnt;idx++){
1592: if( g_new_answerdb[idx] != entry.answers[idx]) {
1593: entry.answers[idx] = g_new_answerdb[idx];
1594: }
1595: if(g_tried[idx] < 10 ) {
1596: entry.tries[3*idx] = ' ';
1597: entry.tries[3*idx+1] = g_tried[idx] + '0';
1598: if(idx < question_cnt-1) entry.tries[3*idx+2] = ',';
1599: } else {
1600: entry.tries[3*idx] = (int)(g_tried[idx]/10) + '0';
1601: entry.tries[3*idx+1] = (g_tried[idx] % 10) + '0';
1602: if(idx < question_cnt-1) entry.tries[3*idx+2] = ',';
1603: }
1604: }
1605: capa_set_entry(&entry,sn,set,offset); /* <-------- capa*() call */
1606:
1607: #ifdef CGI_DBUG
1608: fprintf(g_cgi,"DONE set db entry\n"); fflush(g_cgi);
1609: #endif /* CGI_DBUG */
1610:
1611: create_status_line(mode,question_cnt,&entry);
1612: }
1613: if (w_log_attempt(g_student_number,set,g_log_string) == -1 ) {
1614: fprintf(stdout,"<BOLD>Unable to log attempt. Please notify instructor.</BOLD>\n");
1615: }
1616: }
1617: #ifdef CGI_DBUG
1618: fprintf(g_cgi,"DONE check answer mode\n"); fflush(g_cgi);
1619: #endif /* CGI_DBUG */
1620:
1621: if( (mode == TRY_SET_MODE && !g_passdue) ||
1622: mode == VIEW_PREVIOUS_MODE) {
1623: create_status_line(mode,question_cnt,&entry);
1624: }
1625:
1626: if( !g_passdue ) {
1627: sprintf(buf,"</ul></form>\n"); append_qtext(buf);
1628: }
1629: }
1630: }
1631:
1.8 albertel 1632: /*if the assignment is passedue we come here to get what the answer was just in case*/
1.1 albertel 1633: void
1634: get_response(char pcr,char u_db,int q_idx,Problem_t *p)
1635: {
1636: if( pcr == '0' || p->ans_type==ANSWER_IS_SUBJECTIVE ) { /* not hand-graded question */
1637: switch(u_db) { /* what's from the user record */
1638: case 'Y': break;
1639: case 'y': break;
1640: case '-':
1641: if(g_stu_ans_pp[q_idx+1] != NULL ) log_user_ans(q_idx,p);
1642: break;
1643: case 'E':
1644: case 'e': break;
1645: case 'n': break;
1646: case 'N':
1647: case '0': case '1': case '2': case '3': case '4':
1648: case '5': case '6': case '7': case '8': case '9':
1649: if(g_stu_ans_pp[q_idx+1] != NULL ) log_user_ans(q_idx,p);
1650: break;
1651: default:
1652: break;
1653: }
1654: }
1655: }
1656:
1657: void display_last_answer(int q_idx)
1658: {
1659: char buf[MAX_BUFFER_SIZE];
1660: StudentAnswer_t *sa_p;
1661: #ifdef CGI_DBUG
1662: fprintf(g_cgi,"Enter display_last_answer() [%d]\n",q_idx); fflush(g_cgi);
1663: #endif /* CGI_DBUG */
1664: if(g_stu_ans_pp[q_idx+1] != NULL) {
1665: sa_p=g_stu_ans_pp[q_idx+1];
1666: } else {
1667: if (g_last_ans_pp[q_idx+1] != NULL) {
1668: sa_p=g_last_ans_pp[q_idx+1];
1669: } else {
1670: return;
1671: }
1672: }
1673: if (sa_p->a_next == NULL) {
1674: sprintf(buf,"<input type=\"hidden\" name=\"LAST%02d\" value=\"%s\">\n",
1675: q_idx+1,sa_p->a_str);
1676: append_qtext(buf);
1677: sprintf(buf," <b>Last Answer:</b> %s\n",sa_p->a_str);
1678: append_qtext(buf);
1679: } else {
1680: while(sa_p) {
1681: sprintf(buf,"<input type=\"hidden\" name=\"LAST%02d,%02d\" value=\"%s\">\n",
1682: q_idx+1,sa_p->a_idx,sa_p->a_str);
1683: append_qtext(buf);
1684: sprintf(buf," <b>Last Answer %d:</b> %s\n",sa_p->a_idx,sa_p->a_str);
1685: append_qtext(buf);
1686: sa_p=sa_p->a_next;
1687: }
1688: }
1689: }
1690:
1691: void preserve_last_answer(int q_idx,int print)
1692: {
1693: char buf[MAX_BUFFER_SIZE];
1694: StudentAnswer_t *sa_p;
1695: #ifdef CGI_DBUG
1696: fprintf(g_cgi,"Enter preserve_last_answer() [%d]\n",q_idx); fflush(g_cgi);
1697: #endif /* CGI_DBUG */
1698: if(g_stu_ans_pp[q_idx+1] != NULL) {
1699: sa_p=g_stu_ans_pp[q_idx+1];
1700: } else {
1701: if (g_last_ans_pp[q_idx+1] != NULL) {
1702: sa_p=g_last_ans_pp[q_idx+1];
1703: } else {
1704: return;
1705: }
1706: }
1707: if (sa_p->a_next == NULL) {
1708: sprintf(buf,"<input type=\"hidden\" name=\"LAST%02d\" value=\"%s\">\n",
1709: q_idx+1,sa_p->a_str);
1710: if (print) printf(buf); else append_qtext(buf);
1711: } else {
1712: while(sa_p) {
1713: sprintf(buf,"<input type=\"hidden\" name=\"LAST%02d,%02d\" value=\"%s\">\n",
1714: q_idx+1,sa_p->a_idx,sa_p->a_str);
1715: if (print) printf(buf); else append_qtext(buf);
1716: sa_p=sa_p->a_next;
1717: }
1718: }
1719: }
1720:
1721: void display_last_subjective(int q_idx)
1722: {
1723: char *buf;
1724: char *answer;
1725: #ifdef CGI_DBUG
1726: fprintf(g_cgi,"Enter display_last_subjective() [%d]\n",q_idx); fflush(g_cgi);
1727: #endif /* CGI_DBUG */
1728: answer=capa_get_subjective(g_login_set,q_idx+1,g_student_number);
1729: if (answer==NULL) return;
1730: #ifdef CGI_DBUG
1731: fprintf(g_cgi,"Found answer %s\n",answer); fflush(g_cgi);
1732: #endif /* CGI_DBUG */
1733: buf=capa_malloc(MAX_BUFFER_SIZE+strlen(answer),1);
1734: /* don't need to stick in a last since we always get it from the files */
1735: /* sprintf(buf,"<input type=\"hidden\" name=\"LAST%02d\" value=\"%s\">\n",q_idx+1,answer);*/
1736: append_qtext(buf);
1737: append_qtext("<b>Current Submission:</b><br>\n");
1738: append_qtext("<TABLE BORDER=1 CELLSPACING=0>\n<TR><TD>\n");
1739: append_qtext("<PRE>");
1740: append_qtext(answer);
1741: append_qtext("</PRE>");
1742: append_qtext("</TD></TR></TABLE>\n");
1743: capa_mfree(buf);
1744: capa_mfree(answer);
1745: }
1746:
1747: void create_answer_area(Problem_t *p,int q_idx)
1748: {
1.4 albertel 1749: int ii=0;
1.1 albertel 1750: char buf[MAX_BUFFER_SIZE];
1.4 albertel 1751: AnswerInfo_t *ai;
1.1 albertel 1752: #ifdef CGI_DBUG
1753: fprintf(g_cgi,"Enter create_answer_area() [%d]\n",q_idx); fflush(g_cgi);
1754: #endif /* CGI_DBUG */
1755:
1756: if ( p->ans_type==ANSWER_IS_SUBJECTIVE ) {
1757: display_last_subjective(q_idx);
1758: }
1759: if ( p->show_ans_box ) {
1760: if ( p->ans_op == ANS_AND ) {
1.4 albertel 1761: if (p->ans_type == ANSWER_IS_FORMULA) {
1762: /* first answer is stored in p, the rest are linked off of p->ans_list */
1.1 albertel 1763: sprintf(buf,"<p><B>Answer %d of %d:</B><input size=80 name=\"INPUT%02d,%02d\" value=\"\">\n",ii+1,p->ans_cnt,q_idx+1,ii+1);
1.4 albertel 1764: } else {
1765: sprintf(buf,"<p><B>Answer %d of %d:</B><input name=\"INPUT%02d,%02d\" value=\"\">\n",ii+1,p->ans_cnt,q_idx+1,ii+1);
1766: }
1767: append_qtext(buf);
1768: for(ii=1, ai=p->ans_list;ii<p->ans_cnt;ai=ai->ans_next,ii++) {
1769: if (ai->ans_type == ANSWER_IS_FORMULA) {
1770: sprintf(buf,"<p><B>Answer %d of %d:</B><input size=80 name=\"INPUT%02d,%02d\" value=\"\">\n",ii+1,p->ans_cnt,q_idx+1,ii+1);
1.1 albertel 1771: } else {
1772: sprintf(buf,"<p><B>Answer %d of %d:</B><input name=\"INPUT%02d,%02d\" value=\"\">\n",ii+1,p->ans_cnt,q_idx+1,ii+1);
1773: }
1774: append_qtext(buf);
1775: }
1776: } else { /* single answer, or /OR answers, or subjective answer */
1777: if (p->ans_type == ANSWER_IS_SUBJECTIVE ) {
1778: sprintf(buf,"<p><B>Answer:</B><br><TEXTAREA name=\"INPUT%02d\" rows=\"15\" cols=\"80\"></TEXTAREA>\n",q_idx+1);
1779: } else {
1780: if (p->ans_type == ANSWER_IS_FORMULA) {
1781: sprintf(buf,"<p><B>Answer:</B><input size=80 name=\"INPUT%02d\" value=\"\">\n",q_idx+1);
1782: } else {
1783: sprintf(buf,"<p><B>Answer:</B><input name=\"INPUT%02d\" value=\"\">\n",q_idx+1);
1784: }
1785: }
1786: append_qtext(buf);
1787: }
1788: }
1789: append_qtext("<input type=\"submit\" value=\"Submit All Answers\" >\n");
1790: if ( p->ans_type!=ANSWER_IS_SUBJECTIVE ) {
1791: display_last_answer(q_idx);
1792: }
1793: }
1794:
1795: void
1796: print_response(char pcr,char u_db,int q_idx,Problem_t *p)
1797: {
1798: int a_tpe;
1799: char *c_ans,*response,*answered="Answered",*nycorrect="Not yet correct";
1800: int t_tpe;
1801: double tol;
1802: int sig_l;
1803: int sig_u;
1804: char *a_fmt, *c_answer_str;
1805: int tries;
1806:
1807: char buf[MAX_BUFFER_SIZE];
1808:
1809: a_tpe = p->ans_type;
1810: c_ans = p->answer;
1811: t_tpe = p->tol_type;
1812: tol = p->tolerance;
1813: sig_l = p->sig_lbound;
1814: sig_u = p->sig_ubound;
1815: a_fmt = p->ans_fmt;
1816: tries = p->tries;
1817: response=nycorrect;
1818:
1819: #ifdef CGI_DBUG
1820: fprintf(g_cgi,"Enter print_response() [%c]\n",u_db); fflush(g_cgi);
1821: #endif /* CGI_DBUG */
1822: if( pcr == '0' || a_tpe==ANSWER_IS_SUBJECTIVE ) { /* not hand-graded question */
1823: switch(u_db) { /* this is from the user record */
1824: case 'Y':
1825: c_answer_str = answers_string(ANSWER_STRING_MODE, p);
1826: sprintf(buf,"<p><tt>Correct, computer gets: %s</tt>\n", c_answer_str);
1827: append_qtext(buf);
1828: capa_mfree((char *)c_answer_str);
1829: break;
1830: case 'y':
1831: append_qtext("<p><tt>Hand-graded Correct</tt>\n");
1832: break;
1833: case '-':
1834: if(g_stu_ans_pp[q_idx+1] == NULL ) {
1835: create_answer_area(p,q_idx);
1836: } else {
1837: check_user_ans(q_idx,p);
1838: }
1839: break;
1840: case 'E':
1841: case 'e': append_qtext("<p><tt>Excused</tt>\n"); break;
1842: case 'n': append_qtext("<p><tt>Hand-graded Incorrect</tt>\n"); break;
1843: case '0': case '1': case '2': case '3': case '4':
1844: case '5': case '6': case '7': case '8': case '9':
1845: response=answered;
1846: case 'N':
1847: if(g_stu_ans_pp[q_idx+1] == NULL ) {
1848: if( g_tried[q_idx] < tries) {
1849: create_answer_area(p,q_idx);
1850: if( tries - g_tried[q_idx] == 1) {
1851: sprintf(buf,"<br><tt>%s, ONE try left!!</tt>\n",response);
1852: }else{
1853: sprintf(buf,"<br><tt>%s, tries %d/%d</tt>\n",response,
1854: g_tried[q_idx],tries);
1855: }
1856: append_qtext(buf);
1857: }else{
1858: if (p->ans_type==ANSWER_IS_SUBJECTIVE)
1859: display_last_answer(q_idx);
1860: else
1861: display_last_subjective(q_idx);
1862: append_qtext("<br><tt>No more tries.</tt>\n");
1863: }
1864: } else { /* answering this question */
1865: if( g_tried[q_idx] < tries) {
1866: check_user_ans(q_idx,p);
1867: } else {
1868: if (p->ans_type==ANSWER_IS_SUBJECTIVE)
1869: display_last_answer(q_idx);
1870: else
1871: display_last_subjective(q_idx);
1872: append_qtext("<br><tt>No more tries.</tt>\n");
1873: }
1874: }
1875: break;
1876: }
1877: } else {
1878: append_qtext("<p><tt>Question to be Graded Manually.</tt>\n");
1879:
1880: }
1881:
1882: }
1883:
1884: void
1885: print_inhibited_response(char pcr,char u_db,int q_idx,Problem_t *p)
1886: {
1887: int a_tpe;
1888: char *c_ans;
1889: int t_tpe;
1890: double tol;
1891: int sig_l;
1892: int sig_u;
1893: char *a_fmt;
1894: int tries;
1895: char buf[MAX_BUFFER_SIZE];
1896:
1897: a_tpe = p->ans_type;
1898: c_ans = p->answer;
1899: t_tpe = p->tol_type;
1900: tol = p->tolerance;
1901: sig_l = p->sig_lbound;
1902: sig_u = p->sig_ubound;
1903: a_fmt = p->ans_fmt;
1904: tries = p->tries;
1905:
1906: #ifdef CGI_DBUG
1907: fprintf(g_cgi,"Enter print_inhibited_response() [%c]\n",u_db); fflush(g_cgi);
1908: #endif /* CGI_DBUG */
1909:
1910: if( pcr == '0' || a_tpe==ANSWER_IS_SUBJECTIVE ) { /* not hand-graded question */
1911: switch(u_db) { /* this is from the user record */
1912: case '-':
1913: if(g_stu_ans_pp[q_idx+1] == NULL ) {
1914: create_answer_area(p,q_idx);
1915: } else {
1916: check_inhibited_user_ans(q_idx,p);
1917: }
1918: break;
1919: case 'Y': case 'y':
1920: case 'E': case 'e':
1921: case 'n': case 'N':
1922: case '0': case '1': case '2': case '3': case '4':
1923: case '5': case '6': case '7': case '8': case '9':
1924: if(g_stu_ans_pp[q_idx+1] == NULL ) {
1925: if( g_tried[q_idx] < tries) {
1926: create_answer_area(p,q_idx);
1927: if( tries - g_tried[q_idx] == 1) {
1928: append_qtext("<br><tt>Answered, ONE try left!!</tt>\n");
1929: }else{
1930: sprintf(buf,"<br><tt>Answered, tries %d/%d</tt>\n",g_tried[q_idx],tries);
1931: append_qtext(buf);
1932: }
1933: }else{
1934: if (p->ans_type==ANSWER_IS_SUBJECTIVE)
1935: display_last_answer(q_idx);
1936: else
1937: display_last_subjective(q_idx);
1938: append_qtext("<br><tt>Answered,No more tries.</tt>\n");
1939: }
1940: } else { /* answering this question */
1941: if( g_tried[q_idx] < tries) {
1942: check_inhibited_user_ans(q_idx,p);
1943: } else {
1944: if (p->ans_type==ANSWER_IS_SUBJECTIVE)
1945: display_last_answer(q_idx);
1946: else
1947: display_last_subjective(q_idx);
1948: append_qtext("<br><tt>Answered, No more tries.</tt>\n");
1949: }
1950: }
1951: break;
1952: }
1953: } else {
1954: append_qtext("<p><tt>Question to be Graded Manually.</tt>\n");
1955: }
1956: }
1957:
1958: /* returns a -1 if there were not enough answers, otherwise the number of responses
1.5 albertel 1959: for the question is returned
1960: !!!!!AS A SIDEEFFECT IT ALSO CROPS ANSWERS TO ANSWER_STRING_LENG!!!!!!!
1961: */
1.1 albertel 1962: int gather_answers(char ***ans,int q_idx,Problem_t *p)
1963: {
1964: int cnt;
1965: if(p->ans_op==ANS_AND) {
1966: int i; StudentAnswer_t *sa_p;
1.13 albertel 1967: *ans=(char**)capa_malloc(p->ans_cnt,sizeof(char*));
1.1 albertel 1968: sa_p= g_stu_ans_pp[q_idx+1];
1969: for(i=0;((i<p->ans_cnt)&&(sa_p));i++){
1970: ans[0][i]=sa_p->a_str;
1.5 albertel 1971: if ((strlen(ans[0][i])+1) > ANSWER_STRING_LENG) ans[0][i][ANSWER_STRING_LENG]='\0';
1.1 albertel 1972: sa_p=sa_p->a_next;
1973: }
1974: cnt=p->ans_cnt;
1975: if (i<p->ans_cnt) return -1;
1976: } else {
1.13 albertel 1977: *ans=(char**)capa_malloc(p->ans_cnt,sizeof(char*));
1.1 albertel 1978: ans[0][0]=g_stu_ans_pp[q_idx+1]->a_str;
1.5 albertel 1979: if ((strlen(ans[0][0])+1) > ANSWER_STRING_LENG) ans[0][0][ANSWER_STRING_LENG]='\0';
1.1 albertel 1980: cnt=1;
1981: }
1982: return cnt;
1983: }
1984:
1.8 albertel 1985: /*logging user's answer when it is passed due.*/
1.1 albertel 1986: void
1987: log_user_ans(int q_idx,Problem_t *p)
1988: {
1989: char **ans;
1.13 albertel 1990: char *error;
1.1 albertel 1991: int cnt;
1992: if (p->ans_type==ANSWER_IS_SUBJECTIVE) {
1.8 albertel 1993: /*capa_set_subjective(g_login_set,q_idx+1,g_student_number,
1994: g_stu_ans_pp[q_idx+1]->a_str);*/
1.1 albertel 1995: } else {
1996: if (-1 != (cnt=gather_answers(&ans,q_idx,p))) {
1.13 albertel 1997: switch( capa_check_answers(p,ans,cnt,&error) ) {
1.1 albertel 1998: case EXACT_ANS: g_log_string[q_idx]='Y'; break;
1999: case APPROX_ANS: g_log_string[q_idx]='Y'; break;
1.13 albertel 2000: case SIG_FAIL: g_log_string[q_idx]='S'; capa_mfree(error); break;
2001: case UNIT_FAIL: g_log_string[q_idx]='U'; capa_mfree(error); break;
2002: case UNIT_NOTNEEDED: g_log_string[q_idx]='U'; capa_mfree(error); break;
1.1 albertel 2003: case NO_UNIT: g_log_string[q_idx]='u'; break;
2004: case BAD_FORMULA: g_log_string[q_idx]='F'; break;
2005: case INCORRECT: g_log_string[q_idx]='N'; break;
1.13 albertel 2006: case WANTED_NUMERIC: g_log_string[q_idx]='s'; break;
1.1 albertel 2007: }
2008: }
2009: }
2010: }
2011:
2012: void submit_subjective(int q_idx,Problem_t *p)
2013: {
2014: char buf[MAX_BUFFER_SIZE];
2015: if (capa_set_subjective(g_login_set,q_idx+1,g_student_number,
2016: g_stu_ans_pp[q_idx+1]->a_str)<0){
2017: sprintf(buf,"<p><tt>Falied to record last submission.</tt><br>\n");
2018: g_tried[q_idx]--;
2019: } else {
2020: sprintf(buf,"<p><tt>Current submission recorded.</tt><br>\n");
2021: g_new_answerdb[q_idx] = '0';
2022: g_log_string[q_idx]='A';
2023: }
2024: append_qtext(buf);
2025: if (g_tried[q_idx]<p->tries) {
2026: create_answer_area(p,q_idx);
2027: if( p->tries - g_tried[q_idx] == 1) {
2028: append_qtext("<br><tt>ONE try left</tt>\n");
2029: }else{
2030: sprintf(buf,"<br><tt>tries %d/%d</tt>\n",g_tried[q_idx],p->tries);
2031: append_qtext(buf);
2032: }
2033: }else{
2034: display_last_answer(q_idx);
2035: append_qtext("<br><tt>No more tries.</tt>\n");
2036: }
2037: }
2038:
2039: void
2040: check_user_ans(int q_idx,Problem_t *p)
2041: {
2042: int a_tpe,cnt;
2043: char *c_ans,**ans;
2044: int t_tpe;
2045: double tol;
2046: int sig_l;
2047: int sig_u;
2048: char *a_fmt;
2049: int tries;
2050: char buf[MAX_BUFFER_SIZE];
1.13 albertel 2051: char *error;
2052:
1.1 albertel 2053: a_tpe = p->ans_type;
2054: t_tpe = p->tol_type;
2055: tol = p->tolerance;
2056: sig_l = p->sig_lbound;
2057: sig_u = p->sig_ubound;
2058: a_fmt = p->ans_fmt;
2059: tries = p->tries;
2060:
2061: #ifdef CGI_DBUG
2062: fprintf(g_cgi,"Enter check_user_ans() anstype=%d\n",a_tpe); fflush(g_cgi);
2063: #endif /* CGI_DBUG */
2064:
2065: g_tried[q_idx]++;
2066:
2067: #ifdef CGI_DBUG
2068: fprintf(g_cgi,"Call capa_check_answer() with [%s]\n",g_stu_ans_pp[q_idx+1]->a_str); fflush(g_cgi);
2069: #endif /* CGI_DBUG */
2070: if (a_tpe==ANSWER_IS_SUBJECTIVE) {
2071: submit_subjective(q_idx,p);
2072: return;
2073: }
1.5 albertel 2074:
1.1 albertel 2075: cnt=gather_answers(&ans,q_idx,p);
2076: if (cnt == -1) {
2077: g_tried[q_idx]--;
2078: create_answer_area(p,q_idx);
2079: if( (tries - g_tried[q_idx]) == 1 ) {
2080: append_qtext("<br><tt>Not all answers submitted, ONE try left!!</tt>\n");
2081: }else{
2082: sprintf(buf,"<br><tt>Not all answers submitted, tries %d/%d.</tt>\n",
2083: g_tried[q_idx],tries);
2084: append_qtext(buf);
2085: }
2086: return;
2087: }
2088:
1.13 albertel 2089: switch( capa_check_answers(p,ans,cnt,&error) ) {
1.1 albertel 2090: case EXACT_ANS:
2091: case APPROX_ANS:
2092: c_ans=answers_string(ANSWER_STRING_MODE, p);
2093: sprintf(buf,"<p><tt>Yes, Computer gets: %s</tt>\n", c_ans);
2094: append_qtext(buf);
2095: g_new_answerdb[q_idx] = 'Y';
2096: g_log_string[q_idx]='Y';
2097: capa_mfree(c_ans);
2098: break;
1.13 albertel 2099: case WANTED_NUMERIC:
2100: create_answer_area(p,q_idx);
2101: g_tried[q_idx]--; /* don't count as a try */
2102: sprintf(buf,"<br><tt>This question expects a numeric answer, tries %d/%d.</tt>\n",g_tried[q_idx],tries);
2103: append_qtext(buf);
2104: g_new_answerdb[q_idx] = 'N';
2105: g_log_string[q_idx]='s';
2106: break;
1.1 albertel 2107: case SIG_FAIL:
2108: create_answer_area(p,q_idx);
2109: g_tried[q_idx]--; /* don't count as a try */
1.13 albertel 2110: sprintf(buf,"<br><tt>Please adjust significant figures, you provided %s significant figures, tries %d/%d.</tt>\n",error,g_tried[q_idx],tries);
1.1 albertel 2111: append_qtext(buf);
1.13 albertel 2112: capa_mfree(error);
1.1 albertel 2113: g_new_answerdb[q_idx] = 'N';
2114: g_log_string[q_idx]='S';
2115: break;
2116: case UNIT_FAIL:
2117: create_answer_area(p,q_idx);
2118: g_tried[q_idx]--; /* don't count as a try */
1.13 albertel 2119: sprintf(buf,"<br><tt>Units incorrect, Computer reads units as %s, tries %d/%d.</tt>\n",error,g_tried[q_idx],tries);
2120: capa_mfree(error);
1.1 albertel 2121: append_qtext(buf);
2122: g_new_answerdb[q_idx] = 'N';
2123: g_log_string[q_idx]='U';
2124: break;
2125: case UNIT_NOTNEEDED:
2126: create_answer_area(p,q_idx);
2127: g_tried[q_idx]--; /* don't count as a try */
2128: if(tries > 0) {
1.13 albertel 2129: sprintf(buf,"<br><tt>Only a number required, Computer reads units of %s, tries %d/%d.</tt>\n",error,g_tried[q_idx],tries);
1.1 albertel 2130: append_qtext(buf);
2131: }
1.13 albertel 2132: capa_mfree(error);
1.1 albertel 2133: g_new_answerdb[q_idx] = 'N';
2134: g_log_string[q_idx]='U';
2135: break;
2136: case NO_UNIT:
2137: create_answer_area(p,q_idx);
2138: g_tried[q_idx]--; /* don't count as a try */
2139: sprintf(buf,"<br><tt>Units required, tries %d/%d.</tt>\n",g_tried[q_idx],tries);
2140: append_qtext(buf);
2141: g_new_answerdb[q_idx] = 'N';
2142: g_log_string[q_idx]='u';
2143: break;
2144: case BAD_FORMULA:
2145: create_answer_area(p,q_idx);
2146: g_tried[q_idx]--; /* don't count as a try */
2147: sprintf(buf,"<br><tt>Unable to understand formula, tries %d/%d.</tt>\n",g_tried[q_idx],tries);
2148: append_qtext(buf);
2149: g_new_answerdb[q_idx] = 'N';
2150: g_log_string[q_idx]='F';
2151: break;
2152: case INCORRECT:
2153: if( g_tried[q_idx] < tries ) {
2154: create_answer_area(p,q_idx);
2155: if( (tries - g_tried[q_idx]) == 1 ) {
2156: append_qtext("<br><tt>Incorrect, ONE try left!!</tt>\n");
2157: }else{
2158: sprintf(buf,"<br><tt>Incorrect, tries %d/%d.</tt>\n",g_tried[q_idx],tries);
2159: append_qtext(buf);
2160: }
2161: } else {
2162: display_last_answer(q_idx);
2163: append_qtext("<br><tt>Incorrect, no more tries.</tt>\n");
2164: }
2165: g_new_answerdb[q_idx] = 'N';
2166: g_log_string[q_idx]='N';
2167: break;
2168: }
2169: }
2170:
2171: void
2172: check_inhibited_user_ans(int q_idx,Problem_t *p)
2173: {
2174: int a_tpe,cnt;
2175: char *c_ans,**ans;
2176: int t_tpe;
2177: double tol;
2178: int sig_l;
2179: int sig_u;
2180: char *a_fmt;
2181: int tries;
2182: char buf[MAX_BUFFER_SIZE];
1.13 albertel 2183: char *error;
2184:
1.1 albertel 2185: a_tpe = p->ans_type;
2186: c_ans = p->answer;
2187: t_tpe = p->tol_type;
2188: tol = p->tolerance;
2189: sig_l = p->sig_lbound;
2190: sig_u = p->sig_ubound;
2191: a_fmt = p->ans_fmt;
2192: tries = p->tries;
2193:
2194: #ifdef CGI_DBUG
2195: fprintf(g_cgi,"Enter check_inhibited_user_ans() anstype=%d\n",a_tpe); fflush(g_cgi);
2196: #endif /* CGI_DBUG */
2197:
2198: g_tried[q_idx]++;
2199:
2200: #ifdef CGI_DBUG
2201: fprintf(g_cgi,"Call capa_check_answer() with [%s]\n",g_stu_ans_pp[q_idx+1]->a_str);
2202: fflush(g_cgi);
2203: #endif /* CGI_DBUG */
2204: if (a_tpe==ANSWER_IS_SUBJECTIVE) {
2205: submit_subjective(q_idx,p);
2206: return;
2207: }
2208:
2209: cnt=gather_answers(&ans,q_idx,p);
2210: if (cnt == -1) {
2211: g_tried[q_idx]--;
2212: create_answer_area(p,q_idx);
2213: if( (tries - g_tried[q_idx]) == 1 ) {
2214: append_qtext("<br><tt>Not all answers submitted, ONE try left!!</tt>\n");
2215: }else{
2216: sprintf(buf,"<br><tt>Not all answers submitted, tries %d/%d.</tt>\n",
2217: g_tried[q_idx],tries);
2218: append_qtext(buf);
2219: }
2220: return;
2221: }
2222:
1.13 albertel 2223: switch( capa_check_answers(p,ans,cnt,&error) ) {
1.1 albertel 2224: case EXACT_ANS:
2225: case APPROX_ANS:
2226: g_new_answerdb[q_idx] = 'Y';
2227: g_log_string[q_idx]='Y';
2228: break;
1.13 albertel 2229: case WANTED_NUMERIC:
2230: g_new_answerdb[q_idx] = 'N';
2231: g_log_string[q_idx]='s';
2232: break;
1.1 albertel 2233: case SIG_FAIL:
2234: g_new_answerdb[q_idx] = 'N';
2235: g_log_string[q_idx]='S';
1.13 albertel 2236: capa_mfree(error);
1.1 albertel 2237: break;
2238: case UNIT_FAIL:
2239: g_new_answerdb[q_idx] = 'N';
2240: g_log_string[q_idx]='U';
1.13 albertel 2241: capa_mfree(error);
1.1 albertel 2242: break;
2243: case UNIT_NOTNEEDED:
2244: g_new_answerdb[q_idx] = 'N';
2245: g_log_string[q_idx]='U';
1.13 albertel 2246: capa_mfree(error);
1.1 albertel 2247: break;
2248: case NO_UNIT:
2249: g_new_answerdb[q_idx] = 'N';
2250: g_log_string[q_idx]='u';
2251: break;
2252: case BAD_FORMULA:
2253: g_new_answerdb[q_idx] = 'N';
2254: g_log_string[q_idx]='F';
2255: break;
2256: case INCORRECT:
2257: g_new_answerdb[q_idx] = 'N';
2258: g_log_string[q_idx]='N';
2259: break;
2260: }
2261:
2262: if( g_tried[q_idx] < tries ) {
2263: create_answer_area(p,q_idx);
2264: if( (tries - g_tried[q_idx]) == 1 ) {
2265: append_qtext("<br><tt>Answered, ONE try left!!</tt>\n");
2266: }else{
2267: sprintf(buf,"<br><tt>Answered, tries %d/%d.</tt>\n",g_tried[q_idx],tries);
2268: append_qtext(buf);
2269: }
2270: } else {
2271: display_last_answer(q_idx);
2272: append_qtext("<br><tt>Answered, no more tries.</tt>\n");
2273: }
2274: }
2275:
2276: void /* RETURNS: (nothing) */
2277: print_summary(class_dir,class,student_number,pin,set)
2278: char *class_dir;char *class;char *student_number;int pin;int set;
2279: { /* LOCAL VARIABLES: */
2280: int set_idx, /* Set counter */
2281: i, /* Question counter */
2282: set_score, /* Score on a set */
2283: term_score=0, /* Total points received */
2284: term_valid=0, /* Total points possible */
1.4 albertel 2285: result,
2286: tot_num_sets=0;
1.1 albertel 2287: T_entry entry; /* Database entry for a set */
2288: char buf[MAX_BUFFER_SIZE]; /* Output line buffer */
2289: char buf2[MAX_BUFFER_SIZE]; /* Output line buffer */
2290: T_header header; /* Problem set header */
2291: int question_cnt,valid_wgt, rate,configResult,
2292: status_line_length=DEFAULT_STATUS_LINE_LENGTH,row;
2293: char class_fullpath[ONE_K],*serverName;
2294:
2295: serverName=getenv("SERVER_NAME");
2296: if (!serverName) {
2297: fprintf(stdout,"Enviroment variable SERVER_NAME not set.\n");
2298: fprintf(stdout,"Unable to complete actions.\n");
2299: return;
2300: }
1.4 albertel 2301: printf("<!--print_summary-->");
1.1 albertel 2302: sprintf(class_fullpath,"%s/%s",class_dir,class);
2303: chdir(class_fullpath);
2304: configResult=read_capa_config("web_status_line_length",buf);
2305: if (configResult != 0 && configResult != -1 ) {
2306: if (sscanf(buf,"%d",&status_line_length)==0) {
2307: status_line_length=DEFAULT_STATUS_LINE_LENGTH;
2308: }
2309: } else {
2310: status_line_length=DEFAULT_STATUS_LINE_LENGTH;
2311: }
2312:
2313: printf("<TABLE>\n<TR><TD></TD>\n");
2314: for(i=0;i<status_line_length;i++) {
2315: printf("<TD align=center valign=bottom>%d</TD>\n",i+1);
2316: }
2317: printf("</TR>");
2318:
2319: for (set_idx=1; set_idx<=set; set_idx++) {
2320: g_inhibit_response=capa_check_option(OPTION_INHIBIT_RESPONSE,set_idx,
2321: g_student_data.s_sec);
1.4 albertel 2322: if (g_inhibit_response > 0) {
2323: printf("<!-- Set %d is inhibited -->\n",set_idx);
2324: continue;
2325: }
2326: if ( capa_check_date(CHECK_OPEN_DATE,g_student_number,
2327: g_student_data.s_sec,set_idx) < 0 ){
2328: printf("<!-- Set %d is not open -->\n",set_idx);
2329: continue;
2330: }
1.1 albertel 2331:
2332: if (capa_get_header(&header,set_idx)) return;
1.4 albertel 2333: tot_num_sets++;
1.1 albertel 2334: capa_get_entry(&entry,student_number,set_idx);
2335: sscanf(header.num_questions,"%d", &(question_cnt) );
2336: valid_wgt = 0; set_score = 0;
2337: header.weight[question_cnt] = '\0';
2338: header.partial_credit[question_cnt] = '\0';
2339: for (i=0; i<question_cnt; i++) {
2340: valid_wgt += (header.weight[i] - '0');
2341: if((entry.answers[i]=='Y') || (entry.answers[i]=='y'))
2342: set_score += (header.weight[i]-'0');
2343: if((entry.answers[i]=='E') || (entry.answers[i]=='e'))
2344: valid_wgt -= (header.weight[i] - '0');
2345: if((entry.answers[i]>='0') && (entry.answers[i]<='9'))
2346: set_score += (entry.answers[i] - '0');
2347: }
2348: term_valid += valid_wgt;
2349: term_score += set_score;
2350:
2351: if( valid_wgt != 0 ) {
2352: rate = 100*set_score / valid_wgt;
2353: printf("<TR><TD nowrap align=center valign=bottom>set <B>%d</B>, %d/%d(%d %%) </TD>",set_idx,set_score,valid_wgt,rate);
2354: } else {
2355: printf("<TR><TD nowrap align=center valign=bottom>set <B>%d</B>, 0/0(0 %%) </TD>",set_idx);
2356: }
2357: for(row=0;row<=(question_cnt/status_line_length);row++) {
2358: for(i=(row*status_line_length);
2359: ((i<question_cnt)&&(i<((row+1)*status_line_length))); i++) {
2360: if (i != 0 && (!(i%status_line_length))) { printf("</TR><TD></TD>"); }
2361: printf("<TD align=center valign=bottom><tt>%c</tt></TD>\n",entry.answers[i]);
2362: }
2363: printf("</TR>\n<TR><TD></TD>");
2364: for(i=(row*status_line_length);
2365: ((i<question_cnt)&&(i<((row+1)*status_line_length))); i++) {
2366: if (i != 0 && (!(i%status_line_length))) { printf("</TR><TD></TD>"); }
2367: printf("<TD align=center valign=bottom><tt>%c</tt></TD>\n",header.weight[i]);
2368: }
2369: }
2370: printf("</TR>");
2371: capa_mfree(header.weight);
2372: capa_mfree(header.partial_credit);
2373: }
2374: printf("\n</TABLE>\n<hr>\n");
2375: /* SHOW TOTALS */
2376: /* if capalogin_show_summary_score is set to none don't show it */
1.4 albertel 2377: if (term_valid > 0) {
2378: sprintf(buf,"%d sets, total = %3d/%3d (%d%%)\n", tot_num_sets, term_score, term_valid, 100*term_score/term_valid);
2379: } else {
2380: sprintf(buf,"%d sets, total = %3d/%3d\n", tot_num_sets, term_score, term_valid);
2381: }
1.1 albertel 2382: result=read_capa_config("capalogin_show_summary_score",buf2);
2383: if (result != 0 && result != -1) {
2384: if (strcasecmp(buf2,"none")==0) {
2385: } else {
2386: printf("%s",buf);
2387: }
2388: } else {
2389: printf("%s",buf);
2390: }
2391:
2392: printf("<TABLE cellpadding=0 cellspacing=0 border=0>\n<TR><TD>");
2393: printf("<form method=\"post\" ");
2394: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
2395: printf("%s\n", buf);
2396: printf("<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",g_class_name);
2397: printf("<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",g_student_number);
2398: printf("<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",g_entered_pin);
2399: printf("<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_CHECKIN);
2400: printf("<input type=\"submit\" value=\"Main menu\" ></form></TD>\n");
2401: printf("<TD><form method=\"get\" action=\"http://%s/CAPA/class.html\">",serverName);
2402: printf("<input type=\"button\" value=\"Exit\" onclick=\"window.close()\"></form></TD>");
2403: printf("\n</TABLE>\n");
2404: }
2405:
2406:
2407: void
2408: process_mode(int mode) {
2409:
2410: #ifdef CGI_DBUG
2411: fprintf(g_cgi,"entered process_mode[%d]\n",mode); fflush(g_cgi);
2412: #endif /* CGI_DBUG */
2413: g_qchar_cnt=g_schar_cnt=0;
2414: g_qsize=TEXT_BUF_SIZE*sizeof(char);
2415: g_ssize=STATUS_BUF_SIZE*sizeof(char);
2416: g_question_txt=capa_malloc(TEXT_BUF_SIZE,sizeof(char));
2417: g_status_txt =capa_malloc(STATUS_BUF_SIZE,sizeof(char));
2418: #ifdef CGI_DBUG
2419: fprintf(g_cgi,"alloced everything\n"); fflush(g_cgi);
2420: #endif /* CGI_DBUG */
2421: if( mode == VIEW_PREVIOUS_MODE ) {
2422: print_quizz(g_cpath,g_cowner,g_class_name,g_student_number, g_entered_pin, g_vset,mode);
2423: } else if( mode == TRY_SET_MODE ) {
2424: print_quizz(g_cpath,g_cowner,g_class_name,g_student_number, g_entered_pin, g_login_set,mode);
2425: } else {
2426: print_quizz(g_cpath,g_cowner,g_class_name,g_student_number,g_entered_pin,g_login_set,CHECK_ANSWER_MODE);
2427: }
2428: g_status_txt[g_schar_cnt]=0;
2429: g_question_txt[g_qchar_cnt]=0;
2430: if( g_schar_cnt != 0 ) {
2431: fprintf(stdout,"%s",g_status_txt);
2432: #ifdef CGI_DBUG
2433: fprintf(g_cgi,"print status [%s]\n",g_status_txt); fflush(g_cgi);
2434: #endif /* CGI_DBUG */
2435: }
2436: if( g_qchar_cnt != 0) {
2437: fprintf(stdout,"%s",g_question_txt);
2438: #ifdef CGI_DBUG
2439: fprintf(g_cgi,"print question [%s]\n",g_question_txt); fflush(g_cgi);
2440: #endif /* CGI_DBUG */
2441: }
2442: if( g_schar_cnt != 0 ) {
2443: fprintf(stdout,"%s",g_status_txt);
2444: }
2445: fflush(stdout);
2446: capa_mfree(g_status_txt);
2447: capa_mfree(g_question_txt);
2448:
2449: }
2450:
2451: /* mode could be exam summary, show or not show percentage */
2452: /* quiz summary, show or not show percentage */
2453: void
2454: process_summary(int mode)
2455: {
2456: int outcome;
2457: int i, len;
2458: char *c_name;
2459: char c_path[512];
2460:
2461: outcome = check_exam_quiz_path();
2462: if( (mode == M_EXAMSUMM) && (outcome & 1) ) { /* exam summary */
2463: c_name = rindex(g_exam_path,'/');
2464: c_name++;
2465: i = strlen(c_name);
2466: len = strlen(g_exam_path) - i - 1;
2467: for(i=0;i<len;i++) {
2468: c_path[i]=g_exam_path[i];
2469: }
2470: c_path[len]=0;
2471: print_summary(c_path,c_name,g_student_number, g_entered_pin, g_exam_set);
2472: }
2473: if( (mode == M_QUIZSUMM) && (outcome & 2) ) { /* quiz summary */
2474: c_name = rindex(g_quiz_path,'/');
2475: c_name++;
2476: i = strlen(c_name);
2477: len = strlen(g_quiz_path) - i - 1;
2478: for(i=0;i<len;i++) {
2479: c_path[i]=g_quiz_path[i];
2480: }
2481: c_path[len]=0;
2482: print_summary(c_path,c_name,g_student_number, g_entered_pin, g_quiz_set);
2483: }
2484:
2485: }
2486:
2487: /* ---------------- JAVA TScore.class page print out ----------------- */
2488: void /* RETURNS: (nothing) */
2489: print_termscore_page(class_dir,class,student_number,pin,set,out)
2490: char *class_dir;char *class;char *student_number;int pin;int set; /* student login set */
2491: FILE *out;
2492: { /* LOCAL VARIABLES: */
2493: int set_idx, /* Set counter */
2494: i, /* Question counter */
2495: set_score, /* Score on a set */
2496: term_score=0, /* Total points received */
1.3 albertel 2497: term_valid=0; /* Total points possible */
1.1 albertel 2498: T_entry entry; /* Database entry for a set */
2499: char buf[MAX_BUFFER_SIZE]; /* Output line buffer */
2500: T_header header; /* Problem set header */
1.3 albertel 2501: int question_cnt,valid_wgt,configResult;
1.1 albertel 2502: char class_fullpath[ONE_K],*serverName;
2503: int hw_c, hw_r, qz_c, qz_r, fs, homework_count, quiz_count;
2504: float hw_w, qz_w, ex_w, fe_w, pc_w;
2505: int idx, entry_count, tmp_len;
2506: float *S, *F;
1.7 albertel 2507: int *X; /* array controlling whether to extrapolate scores */
1.3 albertel 2508: char *capa_server;
1.7 albertel 2509: int max_set[4], width=600,height=750; /* width and height of applet*/
1.1 albertel 2510: char **c_path_pp;
1.3 albertel 2511:
2512: /*Unused Vars
2513: char buf2[MAX_BUFFER_SIZE];
2514: char *qz_p, *ex_p, *epc_p;
2515: int ex_c, epc_c, result;
2516: int rate, status_line_length=DEFAULT_STATUS_LINE_LENGTH,row;
2517: */
2518:
1.1 albertel 2519: serverName=getenv("SERVER_NAME");
2520: if (!serverName) {
2521: fprintf(out,"Enviroment variable SERVER_NAME not set.\n");
2522: fprintf(out,"Unable to complete actions.\n");
2523: return;
2524: }
2525:
2526: sprintf(class_fullpath,"%s/%s",class_dir,class);
2527: chdir(class_fullpath);
2528:
2529: /*
2530: change the working director to the major homework directory and begin to
2531: read off the remaining path informations from this capa.config file
2532: homework_path =
2533: quiz_path =
2534: exam_path =
2535: correction_path =
2536: homework_weight = 0.3
2537: quiz_weight = 0.7
2538: exam_weight = 0.3
2539: final_weight = 0.35
2540: correction_weight = 0.3
2541: final_exam_set_number = 4
2542: homework_count = 12
2543: quiz_count = 24
2544:
2545: */
2546:
2547: configResult=read_capa_config("capa_server",buf);
2548: if (configResult != 0 && configResult != -1 ) {
2549: tmp_len = strlen(buf) + 1;
2550: capa_server = (char *)capa_malloc( tmp_len, sizeof(char));
2551: sprintf(capa_server,"%s",buf);
2552: } else { /* if capa_server is not set then we won't do anything further */
2553: fprintf(out,"Parameter: capa_server in capa.config file are not properly set.\n");
2554: return ;
2555: }
2556: if( get_termscore_params(&hw_w,&qz_w,&ex_w,&fe_w,&pc_w,&homework_count,&quiz_count,&fs) == -1 ) {
2557: fprintf(out,"Parameters in capa.config file are not properly set.\n");
2558: fprintf(out," such as homework_weight, quiz_weight, exam_weight, final_weight, correction_weight.\n");
2559:
2560: return;
2561: }
1.7 albertel 2562:
2563: get_tscore_width_height(&width,&height);
2564:
1.1 albertel 2565: c_path_pp = (char **)capa_malloc( 4, sizeof(char *));
2566: tmp_len = strlen(class_fullpath) + 1;
2567: c_path_pp[0] = (char *)capa_malloc(tmp_len,sizeof(char));
2568: sprintf(c_path_pp[0],"%s",class_fullpath); /* c_path_pp[0] should always be there */
2569:
2570: entry_count = fs*2 + 1;
2571: S = (float *)capa_malloc( ((fs+1)*2), sizeof(float));
2572: F = (float *)capa_malloc( ((fs+1)*2), sizeof(float));
2573: X = (int *)capa_malloc( ((fs+1)*2), sizeof(int));
2574:
2575: max_set[0] = set; /* the login set number */
2576: hw_c = max_set[0];
2577: hw_r = homework_count - set;
2578:
2579:
2580: configResult=read_capa_config("quiz_path",buf);
2581: if (configResult != 0 && configResult != -1 ) {
2582: tmp_len = strlen(buf)+1;
2583: c_path_pp[1] = (char *)capa_malloc(tmp_len,sizeof(char));
2584: sprintf(c_path_pp[1],"%s",buf);
2585: max_set[1] = check_class_get_maxset(c_path_pp[1]);
2586: if( max_set[1] <= 0 ) {
2587: /* should we continue ? */
2588: max_set[1] = 1;
2589: X[1] = 1;
2590: }
2591: qz_c = max_set[1];
2592: qz_r = quiz_count - max_set[1];
2593: } else { /* if quiz_path is not in capa.config, then we will skip quizz */
2594: qz_c = 0;
2595: qz_r = 0;
2596: }
2597:
2598:
2599: configResult=read_capa_config("exam_path",buf);
2600: if (configResult != 0 && configResult != -1 ) {
2601: tmp_len = strlen(buf)+1;
2602: c_path_pp[2] = (char *)capa_malloc( (tmp_len),sizeof(char));
2603: sprintf(c_path_pp[2],"%s",buf);
2604: max_set[2] = check_class_get_maxset(c_path_pp[2]);
1.7 albertel 2605: printf("<!-- for %s max_set %d -->\n",c_path_pp[2],max_set[2]);
1.1 albertel 2606: if( max_set[2] <= 0 ) {
1.7 albertel 2607: /* no sets */
2608: max_set[2] = 0;
2609: }
2610: /* start extrapolation with sets that don't yet exist */
2611: for(idx=2+(max_set[2]*2);idx <= (fs*2); idx++) {
1.1 albertel 2612: X[idx] = 1;
2613: }
2614: } else { /* if exam_path is not in capa.config, then skip exams */
2615: fs = 0;
2616: }
2617: configResult=read_capa_config("correction_path",buf);
2618: if (configResult != 0 && configResult != -1 ) {
2619: tmp_len = strlen(buf)+1;
2620: c_path_pp[3] = (char *)capa_malloc(tmp_len,sizeof(char));
2621: sprintf(c_path_pp[3],"%s",buf);
2622: max_set[3] = check_class_get_maxset(c_path_pp[3]);
2623: if( max_set[3] <= 0 ) {
2624: /* should we continue ? */
2625: max_set[3] = 0;
2626:
2627: }
2628: } else { /* if correction_path is not in capa.config, then skip corrections */
2629: pc_w = 0.0;
2630: }
2631:
2632:
2633:
2634: for( idx = 0; idx < 4; idx++) {
2635: if( c_path_pp[idx] != NULL ) {
2636: chdir(c_path_pp[idx]);
2637: term_score=0;
2638: term_valid=0;
2639: for (set_idx=1; set_idx<=max_set[idx]; set_idx++) {
2640: if (capa_get_header(&header,set_idx)) return;
2641: capa_get_entry(&entry,student_number,set_idx);
2642: sscanf(header.num_questions,"%d", &(question_cnt) );
2643: valid_wgt = 0; set_score = 0;
2644: header.weight[question_cnt] = '\0';
2645: header.partial_credit[question_cnt] = '\0';
2646: for (i=0; i<question_cnt; i++) {
2647: valid_wgt += (header.weight[i] - '0');
2648: if((entry.answers[i]=='Y') || (entry.answers[i]=='y'))
2649: set_score += (header.weight[i]-'0');
2650: if((entry.answers[i]=='E') || (entry.answers[i]=='e'))
2651: valid_wgt -= (header.weight[i] - '0');
2652: if((entry.answers[i]>='0') && (entry.answers[i]<='9'))
2653: set_score += (entry.answers[i] - '0');
2654: }
2655: term_valid += valid_wgt;
2656: term_score += set_score;
2657: capa_mfree(header.weight);
2658: capa_mfree(header.partial_credit);
1.7 albertel 2659: printf("<!-- %s %d %d -->\n",c_path_pp[idx],set_score,valid_wgt);
1.1 albertel 2660: if(idx==2) { /* exam sets */
2661: S[set_idx*2] = (float)set_score;
2662: F[set_idx*2] = (float)valid_wgt;
1.7 albertel 2663: if (valid_wgt == 0) {
2664: X[set_idx*2] = 1;
2665: } else {
2666: X[set_idx*2] = 0;
2667: }
1.1 albertel 2668: }
2669: if(idx==3) { /* correction sets */
2670: S[set_idx*2+1] = (float)set_score;
2671: F[set_idx*2+1] = (float)valid_wgt;
1.7 albertel 2672: if (valid_wgt == 0 ) {
2673: X[set_idx*2+1] = 1;
2674: } else {
2675: X[set_idx*2+1] = 0;
2676: }
1.1 albertel 2677: }
2678: }
2679: if( (idx == 0) || (idx==1) ) { /* homeworks and quizzes */
2680: S[idx] = (float)term_score;
2681: F[idx] = (float)term_valid;
2682: X[idx] = 1;
2683: }
2684: }
2685: }
2686:
2687:
2688:
2689:
2690: fprintf(out,"<CENTER>\n");
1.12 albertel 2691: fprintf(out,"<APPLET CODE=TScore.class CODEBASE=\"http://%s/CAPA/\" width=%d height=%d>\n",capa_server,width,height);
1.1 albertel 2692: fprintf(out,"<PARAM NAME=\"HW_W\" VALUE=\"%f\">\n", hw_w);
2693: fprintf(out,"<PARAM NAME=\"QZ_W\" VALUE=\"%f\">\n", qz_w);
2694: fprintf(out,"<PARAM NAME=\"EX_W\" VALUE=\"%f\">\n", ex_w);
2695: fprintf(out,"<PARAM NAME=\"FE_W\" VALUE=\"%f\">\n", fe_w);
2696: fprintf(out,"<PARAM NAME=\"PC_W\" VALUE=\"%f\">\n", pc_w);
2697: fprintf(out,"<PARAM NAME=\"HW_C\" VALUE=\"%d\">\n", hw_c);
2698: fprintf(out,"<PARAM NAME=\"HW_R\" VALUE=\"%d\">\n", hw_r);
2699: fprintf(out,"<PARAM NAME=\"FS\" VALUE=\"%d\">\n", fs);
2700: fprintf(out,"<PARAM NAME=\"QZ_C\" VALUE=\"%d\">\n", qz_c);
2701: fprintf(out,"<PARAM NAME=\"QZ_R\" VALUE=\"%d\">\n", qz_r);
2702:
2703:
2704: for(idx=0;idx<entry_count;idx++) {
2705: fprintf(out,"<PARAM NAME=\"S%d\" VALUE=\"%f\">\n",idx,S[idx]);
2706: fprintf(out,"<PARAM NAME=\"F%d\" VALUE=\"%f\">\n",idx,F[idx]);
2707: fprintf(out,"<PARAM NAME=\"X%d\" VALUE=\"%d\">\n",idx,X[idx]);
2708: }
2709:
2710: fprintf(out,"</APPLET> </CENTER>\n");
2711:
2712: fprintf(out,"<TABLE cellpadding=0 cellspacing=0 border=0>\n<TR><TD>");
2713: fprintf(out,"<form method=\"post\" ");
2714: sprintf(buf,"action=\"http://%s/%s/%s/capasbin\">",serverName,g_cgibin_path,g_cowner);
2715: fprintf(out,"%s\n", buf);
2716: fprintf(out,"<input type=\"hidden\" name=\"CLASS\" value=\"%s\">\n",g_class_name);
2717: fprintf(out,"<input type=\"hidden\" name=\"SNUM\" value=\"%s\">\n",g_student_number);
2718: fprintf(out,"<input type=\"hidden\" name=\"CAPAID\" value=\"%d\">\n",g_entered_pin);
2719: fprintf(out,"<input type=\"hidden\" name=\"M\" value=\"%d\">\n",M_CHECKIN);
2720: fprintf(out,"<input type=\"submit\" value=\"Main menu\" ></form></TD>\n");
2721: fprintf(out,"<TD><form method=\"get\" action=\"http://%s/CAPA/class.html\">",serverName);
2722: fprintf(out,"<input type=\"button\" value=\"Exit\" onclick=\"window.close()\"></form></TD>");
2723: fprintf(out,"\n</TABLE>\n");
2724:
2725: capa_mfree((char *)S);
2726: capa_mfree((char *)F);
2727: capa_mfree((char *)X);
2728: for(idx=0;idx<4;idx++) {
2729: if( c_path_pp[idx] != NULL ) capa_mfree((char *)c_path_pp[idx]);
2730: }
2731: capa_mfree((char *)c_path_pp);
2732: capa_mfree((char *)capa_server);
2733: }
2734:
1.9 albertel 2735: void
1.7 albertel 2736: get_tscore_width_height(width,height)
2737: int *width;int *height;
2738: {
2739: char buf[MAX_BUFFER_SIZE];
2740: int configResult;
2741:
2742: configResult=read_capa_config("tscore_width",buf);
2743: if (configResult != 0 && configResult != -1 ) {
2744: sscanf(buf,"%d", width);
2745: if (*width <= 0 ) { *width = DEFAULT_WIDTH; }
2746: } else {
2747: printf("<!-- tscore_width not found. %d-->\n",configResult);
2748: }
2749: configResult=read_capa_config("tscore_height",buf);
2750: if (configResult != 0 && configResult != -1 ) {
2751: sscanf(buf,"%d", height);
2752: if (*height <= 0 ) { *height = DEFAULT_HEIGHT; }
2753: } else {
2754: printf("<!-- tscore_height not found. %d-->\n",configResult);
2755: }
2756: }
1.1 albertel 2757:
2758: int
2759: get_termscore_params(hw,qw,ew,fw,pw,hc,qc,fs)
2760: float *hw;float *qw;float *ew;float *fw;float *pw;
2761: int *hc;int *qc;int *fs;
2762: {
2763: char buf[MAX_BUFFER_SIZE]; /* Output line buffer */
2764: int hw_c, qz_c, fe_s;
2765: float hw_w, qz_w, ex_w, fe_w, pc_w;
2766: int configResult;
2767:
2768: configResult=read_capa_config("homework_weight",buf);
2769: if (configResult != 0 && configResult != -1 ) {
2770: sscanf(buf,"%f", &hw_w);
1.15 albertel 2771: if(hw_w < 0.0 ) {
1.1 albertel 2772: hw_w = DEFAULT_HW_W;
2773: }
2774: } else {
2775: return (-1);
2776: }
2777: configResult=read_capa_config("quiz_weight",buf);
2778: if (configResult != 0 && configResult != -1 ) {
2779: sscanf(buf,"%f", &qz_w);
1.15 albertel 2780: if(qz_w < 0.0 ) {
1.1 albertel 2781: qz_w = DEFAULT_QZ_W;
2782: }
2783: } else {
2784: return (-1);
2785: }
2786: configResult=read_capa_config("exam_weight",buf);
2787: if (configResult != 0 && configResult != -1 ) {
2788: sscanf(buf,"%f", &ex_w);
1.15 albertel 2789: if(ex_w < 0.0 ) {
1.1 albertel 2790: ex_w = DEFAULT_EX_W;
2791: }
2792: } else {
2793: return (-1);
2794: }
2795: configResult=read_capa_config("final_weight",buf);
2796: if (configResult != 0 && configResult != -1 ) {
2797: sscanf(buf,"%f", &fe_w);
1.15 albertel 2798: if(fe_w < 0.0 ) {
1.1 albertel 2799: fe_w = DEFAULT_FE_W;
2800: }
2801: } else {
2802: return (-1);
2803: }
2804: configResult=read_capa_config("correction_weight",buf);
2805: if (configResult != 0 && configResult != -1 ) {
2806: sscanf(buf,"%f", &pc_w);
1.15 albertel 2807: if(pc_w < 0.0 ) {
1.1 albertel 2808: pc_w = DEFAULT_PC_W;
2809: }
2810: } else {
2811: return (-1);
2812: }
2813: configResult=read_capa_config("final_exam_set_number",buf);
2814: if (configResult != 0 && configResult != -1 ) {
2815: sscanf(buf,"%d", &fe_s);
2816: if(fe_s <= 0 ) {
2817: fe_s = DEFAULT_FE_NUMBER;
2818: }
2819: } else {
2820: return (-1);
2821: }
2822: configResult=read_capa_config("homework_count",buf);
2823: if (configResult != 0 && configResult != -1 ) {
2824: sscanf(buf,"%d", &hw_c);
2825: if(hw_c <= 0 ) {
2826: hw_c = DEFAULT_HW_COUNT;
2827: }
2828: } else {
2829: return (-1);
2830: }
2831: configResult=read_capa_config("quiz_count",buf);
2832: if (configResult != 0 && configResult != -1 ) {
2833: sscanf(buf,"%d", &qz_c);
2834: if(qz_c <= 0 ) {
2835: qz_c = DEFAULT_QZ_COUNT;
2836: }
2837: } else {
2838: return (-1);
2839: }
2840: *hw = hw_w; *qw = qz_w; *ew = ex_w; *fw = fe_w; *pw = pc_w;
2841: *hc = hw_c; *qc = qz_c; *fs = fe_s;
2842: return (0);
2843:
2844: }
2845:
2846: /* =================================================================================================== */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>