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