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