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