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