Annotation of capa/capa51/pProj/capaCgiUtils.c, revision 1.19

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>