Annotation of capa/capa51/pProj/capalogin.c, revision 1.1
1.1 ! albertel 1: /* Copyright 1992-1997 Michigan State University, Board of Trustee */
! 2: /* version 4.6 */
! 3:
! 4: /* Jan 28 1997 I.T. */
! 5: /* July 23 1998 I.T. */
! 6:
! 7: #ifdef NeXT
! 8: #include <stdlib.h>
! 9: #include <objc/zone.h>
! 10: #include <mach/mach.h>
! 11: #else
! 12: #include <malloc.h>
! 13: double atof();
! 14: #endif
! 15:
! 16: #include <ctype.h>
! 17:
! 18: #ifdef TRUE
! 19: #undef TRUE
! 20: #endif
! 21: #ifdef FALSE
! 22: #undef FALSE
! 23: #endif
! 24:
! 25: #include <curses.h>
! 26:
! 27: #if defined(__alpha) || defined(linux)
! 28:
! 29: #ifdef LOGIN_DBUG
! 30:
! 31: #define NO_PIN
! 32: #define NO_DATE_CHECK
! 33: #define NO_DUP_CHECK
! 34:
! 35: #endif
! 36:
! 37: #include <curses.h>
! 38: #else
! 39: #if defined(__sun) || defined(hpux) || defined(AIX) || defined(IRIX)
! 40: #include <curses.h> /* #include <stdio.h> */
! 41: #include <math.h> /* MAXFLOAT */
! 42:
! 43: #else
! 44:
! 45: #include <bsd/curses.h>
! 46:
! 47: #endif
! 48: #endif
! 49:
! 50: #include <signal.h>
! 51: #include <time.h>
! 52: #include <math.h>
! 53: #include <string.h>
! 54: #include <unistd.h>
! 55: #include "capaToken.h"
! 56: #include "capaParser.h"
! 57: #include "capaCommon.h"
! 58:
! 59: FILE *dfp;
! 60:
! 61: #define TERM_SUMMARY 1
! 62: #define EXAM_SUMMARY 2
! 63: #define QUIZ_SUMMARY 3
! 64:
! 65: #define TRY_BOUND 99
! 66:
! 67:
! 68:
! 69:
! 70: #define TYR_SET_MENU_MACRO(xxx) { \
! 71: sprintf(aLine,"Total %d problems", num_questions); \
! 72: if(xxx) { \
! 73: mvaddstr(20,1,"Enter command M, A, #, T, or X."); mvaddstr(20,67,"COMMAND:"); \
! 74: mvaddstr(21,1,"M=go to Main Menu A=Answer T=Time RETURN=execute command"); \
! 75: } else { \
! 76: mvaddstr(20,1,"Enter command M, #, T, or X. "); mvaddstr(20,67,"COMMAND:"); \
! 77: mvaddstr(21,1,"M=go to Main Menu T=Time RETURN=execute command"); \
! 78: } \
! 79: mvaddstr(22,1, "#=go to problem # X=eXit CAPA"); \
! 80: mvaddstr(23,1,aLine); }
! 81:
! 82:
! 83: #define REVIEW_SET_MENU_MACRO() { \
! 84: sprintf(aLine,"Total %d problems", num_questions); \
! 85: mvaddstr(20,1,"Enter command M, #, or X."); mvaddstr(20,67,"COMMAND:"); \
! 86: mvaddstr(21,1,"M=go to Main Menu RETURN=execute command"); \
! 87: mvaddstr(22,1,"#=go to problem # X=eXit CAPA"); \
! 88: mvaddstr(23,1,aLine); }
! 89:
! 90: #define TYRSET_MENU( ) { \
! 91: mvaddstr(22,0,"Commands :M = Main Menu :7 = go to Problem 7 RETURN = Enter/Execute"); \
! 92: }
! 93:
! 94:
! 95: #define REVIEW_SET_MENU_MACRO() { \
! 96: sprintf(aLine,"Total %d problems", num_questions); \
! 97: mvaddstr(20,1,"Enter command M, #, or X."); mvaddstr(20,67,"COMMAND:"); \
! 98: mvaddstr(21,1,"M=go to Main Menu RETURN=execute command"); \
! 99: mvaddstr(22,1,"#=go to problem # X=eXit CAPA"); \
! 100: mvaddstr(23,1,aLine); }
! 101:
! 102:
! 103: #define DBUG_TSUMMARY 0
! 104:
! 105: #define CLEAR() clear(); refresh()
! 106: #define ADDCH(c) addch(c); refresh()
! 107: #define CLRTOEOL() clrtoeol(); refresh()
! 108: #define CR 13
! 109: #define LF 10
! 110: #define SCREEN_BUFFER_SIZE 2048
! 111:
! 112: time_t log_in_time, log_out_time;
! 113: char in_t[32], in_tty[32];
! 114: char Orig_path[FILE_NAME_LENGTH], Exam_path[FILE_NAME_LENGTH],
! 115: Quiz_path[FILE_NAME_LENGTH];
! 116: int Exam_set, Quiz_set;
! 117: int g_inhibit_response;
! 118: int g_delay; /* delay when logging out */
! 119: int g_max_delay; /* max number of minutes to wait for input, kick_out()
! 120: after this much time */
! 121: /* Note: be careful to free entry answers */
! 122:
! 123: /* ------------------------------------------------------------------------- */
! 124: /* WRITE OUTPUT (NICELY) TO THE SCREEN */
! 125: /* ------------------------------------------------------------------------- */
! 126: void /* RETURNS: (nothing) */
! 127: wrap(str) /* ARGUMENTS: */
! 128: char *str; /* Block of text to output */
! 129: { /* LOCAL VARIABLES: */
! 130: int y,x,len; /* Row,Col of screen */
! 131: int i, /* Next space */
! 132: j; /* Next char to print */
! 133: len=strlen(str);
! 134: for (i=j=0; i<len; i++) {
! 135: getyx(stdscr,y,x);
! 136: while (i<len && !isspace(str[i])) i++;
! 137: if (x+i-j > 78) addch('\n');
! 138: while (j<=i) addch(str[j++]);
! 139: }
! 140: }
! 141: int
! 142: total_lines(char *str)
! 143: {
! 144: int len, lines_cnt=1;
! 145: int i, j, x=0;
! 146:
! 147: len=strlen(str);
! 148: for(i=j=0;i<len;i++) {
! 149: while (i<len && !isspace(str[i])) i++;
! 150: if (x+i-j > 78) { lines_cnt++; x = 0; }
! 151: while (j<=i) { x++; if(str[j] == '\n') {lines_cnt++; x=0; } j++; }
! 152: }
! 153: return (lines_cnt);
! 154: }
! 155:
! 156: /* --------------------------------------------- */
! 157: /* */
! 158: #define LINES_PER_SCREEN 20
! 159:
! 160: int display_prob_scr(char *str,int scr_idx)
! 161: {
! 162: int len, lines_cnt=0;
! 163: int i,j,y=0,x=0;
! 164: int break_pt, onscreen_pr;
! 165: int second_scr=0;
! 166:
! 167: if( str != NULL ) {
! 168: lines_cnt = total_lines(str);
! 169: if( lines_cnt > LINES_PER_SCREEN ) {
! 170: second_scr = 1;
! 171: } else {
! 172: scr_idx = 1;
! 173: }
! 174: if( scr_idx == 1 ) {
! 175: break_pt = LINES_PER_SCREEN + 1;
! 176: } else { /* which line to break the problem text into two screens */
! 177: if(lines_cnt>=40) { break_pt = LINES_PER_SCREEN; } else {
! 178: if(lines_cnt==39) { break_pt = LINES_PER_SCREEN - 1; } else {
! 179: if(lines_cnt==38) { break_pt = LINES_PER_SCREEN - 2; } else {
! 180: break_pt = LINES_PER_SCREEN - 3;
! 181: }
! 182: }
! 183: }
! 184: }
! 185:
! 186: #ifdef LOGIN_DBUG
! 187: fprintf(dfp,"DISPLAY SCR IDX=%d total LineCnt=%d Line Break= %d:\n",scr_idx,lines_cnt,break_pt); fflush(dfp);
! 188: #endif
! 189:
! 190: /* start to display the text on screen */
! 191:
! 192: lines_cnt = 1; x = y =0;
! 193: len=strlen(str);
! 194: #ifdef LOGIN_DBUG
! 195: fprintf(dfp,"SCR IDX=%d,leng=%d[[\n",scr_idx,len);
! 196: fflush(dfp);
! 197: #endif
! 198: for(i=j=0;i<len;i++) {
! 199: if( ( (scr_idx==1) && (lines_cnt < break_pt)) ||
! 200: ((scr_idx==2) && (lines_cnt > break_pt) && (lines_cnt <= (break_pt+LINES_PER_SCREEN))) ) {
! 201: getyx(stdscr,y,x);
! 202: /* if (x2>=x) x=x2; else x=x2+80;*/
! 203: }
! 204: while (i<len && !isspace(str[i])) i++;
! 205: onscreen_pr = 0;
! 206: #ifdef LOGIN_DBUG
! 207: fprintf(dfp,"\n[NewWord line=%d,x=%d,i=%d,j=%d,y=%d]",lines_cnt,x,i,j,y);
! 208: #endif
! 209: if (x+i-j > 78) { /* line break */
! 210: if( (scr_idx==1) && (lines_cnt < break_pt) ) {
! 211: addch('\n'); onscreen_pr = 1;
! 212: #ifdef LOGIN_DBUG
! 213: fprintf(dfp,"\n[LineCnt=%d,x=%d,i=%d,j=%d]",lines_cnt,x,i,j);
! 214: #endif
! 215: }
! 216: if( (scr_idx==2) && (lines_cnt > break_pt) && (lines_cnt <= (break_pt+LINES_PER_SCREEN)) ) {
! 217:
! 218: addch('\n'); onscreen_pr = 1;
! 219: #ifdef LOGIN_DBUG
! 220: fprintf(dfp,"\n[LineCnt=%d,x=%d,i=%d,j=%d]",lines_cnt,x,i,j);
! 221: #endif
! 222: }
! 223: lines_cnt++;
! 224: if(onscreen_pr == 0 ) {
! 225: x=0;
! 226: }
! 227: }
! 228: while (j<=i) { /* display on screen */
! 229: onscreen_pr = 0;
! 230: if( (scr_idx==1) && (lines_cnt < break_pt) ) {
! 231: addch(str[j]); /* display that character */
! 232: onscreen_pr = 1;
! 233: #ifdef LOGIN_DBUG
! 234: fprintf(dfp,"%c",str[j]);
! 235: #endif
! 236: }
! 237: if( (scr_idx==2) && (lines_cnt > break_pt) && (lines_cnt <= (break_pt+LINES_PER_SCREEN)) ) {
! 238:
! 239: addch(str[j]); onscreen_pr = 1;
! 240: #ifdef LOGIN_DBUG
! 241: fprintf(dfp,"%c",str[j]);
! 242: #endif
! 243: }
! 244: if( str[j] == '\n' ) {
! 245:
! 246: #ifdef LOGIN_DBUG
! 247: fprintf(dfp,"<LineCnt=%d>[j=%d]",lines_cnt,j);
! 248: #endif
! 249: if(onscreen_pr == 0 ) {
! 250: x = 0;
! 251: }
! 252: lines_cnt++;
! 253: }
! 254: if(onscreen_pr == 0 ) {
! 255: x++;
! 256: }
! 257: j++;
! 258: }
! 259: }
! 260: #ifdef LOGIN_DBUG
! 261: fprintf(dfp,"\n]]"); fflush(dfp);
! 262: #endif
! 263:
! 264: }
! 265: return (second_scr);
! 266:
! 267: }
! 268:
! 269: /* ------------------------------------------------------------------------- */
! 270: /* DISPLAY FAREWELL MESSAGE WHEN USER GOT KICKED OUT */
! 271: /* ------------------------------------------------------------------------- */
! 272: void /* RETURNS: (nothing) */
! 273: #ifdef __sun
! 274: kick_out(int sig)
! 275: #else
! 276: kick_out()
! 277: #endif
! 278:
! 279: { /* LOCAL VARIABLES: */
! 280: FILE *fp; /* Goodbye file pointer */
! 281: char buf[255]; /* Input buffer */
! 282:
! 283: /* DISPLAY EXIT MESSAGE */
! 284: CLEAR();
! 285: if ((fp=fopen("goodbye.msg","r"))!=NULL) {
! 286: while (fgets(buf,255,fp))
! 287: addstr(buf);
! 288: fclose(fp);
! 289: }
! 290: sprintf(buf, "This message will last for only %d seconds.",g_delay);
! 291: mvaddstr(22,20,buf); refresh();
! 292: sleep(g_delay);
! 293: /* mypause(22,20); */
! 294:
! 295: /* CURSES RESTORATION */
! 296: resetty(); endwin();
! 297: exit(1);
! 298: }
! 299:
! 300:
! 301: /* ------------------------------------------------------------------------- */
! 302: /* GET INPUT (NICELY) FROM A PLACE ON THE SCREEN */
! 303: /* ------------------------------------------------------------------------- */
! 304: void /* RETURNS: (nothing) */
! 305: get_input(y,x,str,inmax) /* ARGUMENTS: */
! 306: int y,x; /* Row,Col of screen to start */
! 307: char *str; /* String buffer to fill in */
! 308: int inmax; /* Maximum number of characters */
! 309: { /* LOCAL VARIABLES: */
! 310: int i=0,cx,cy; /* Position in buffer */
! 311: char c; /* Input character */
! 312:
! 313: if (y && x) move(y,x);
! 314: CLRTOEOL();
! 315: cx = x; cy = y;
! 316: #if defined( __alpha) || defined(__sun)
! 317: while (1) {
! 318: alarm(g_max_delay*60);
! 319: c=getch();
! 320: if (c==10 || c==13) break;
! 321: else if (c==8 || c==16 || c==127) {
! 322: if (i>0) {
! 323: i--; cx--; echo(); move(cy,cx);
! 324: delch(); insch(' '); refresh(); noecho();
! 325: } else
! 326: beep();
! 327: } else if (i>=inmax) { beep(); } else {
! 328: str[i++] = c; cx++;
! 329: echo(); ADDCH(c); noecho();
! 330: }
! 331: }
! 332: #else
! 333: while (1) {
! 334: alarm(g_max_delay*60);
! 335: c=getch();
! 336: if (c==10 || c==13) break;
! 337: else if (c==8 || c==16 || c==127) {
! 338: if (i>0) {
! 339: i--; printf("%c %c",8,8); refresh();
! 340: } else printf("%c",7);
! 341: } else if (i>=inmax) { printf("%c",7);
! 342: } else {
! 343: str[i++] = c; ADDCH(c);
! 344: }
! 345: }
! 346: #endif
! 347: str[i]=0;
! 348: }
! 349:
! 350:
! 351: void /* RETURNS: (nothing) */
! 352: get_xinput(y,x,str,inmax)/* ARGUMENTS: */
! 353: int y,x; /* Row,Col of screen to start */
! 354: char *str; /* String buffer to fill in */
! 355: int inmax; /* Maximum number of characters */
! 356: { /* LOCAL VARIABLES: */
! 357: int i=0,cx,cy; /* Position in buffer */
! 358: char c; /* Input character */
! 359:
! 360:
! 361: for(i=0;i<inmax;i++) { move(y,x+i); ADDCH(' '); }
! 362: i=0;
! 363: if (y && x) move(y,x);refresh();
! 364: cx = x; cy = y;
! 365: #if defined( __alpha) || defined(__sun)
! 366: while (1) {
! 367: alarm(g_max_delay*60);
! 368: c=getch();
! 369: if (c==10 || c==13) break;
! 370: else if (c==8 || c==16 || c==127) {
! 371: if (i>0) {
! 372: i--; cx--; echo(); move(cy,cx);
! 373: delch(); insch(' '); refresh(); noecho();
! 374: } else
! 375: beep();
! 376: } else if (i>=inmax) { beep(); } else {
! 377: str[i++] = c; cx++;
! 378: echo(); ADDCH(c); noecho();
! 379: }
! 380: }
! 381: #else
! 382: while (1) {
! 383: alarm(g_max_delay*60);
! 384: c=getch();
! 385: if (c==10 || c==13) break;
! 386: else if (c==8 || c==16 || c==127) {
! 387: if (i>0) {
! 388: i--; printf("%c %c",8,8); refresh();
! 389: } else printf("%c",7);
! 390: } else if (i>=inmax) { printf("%c",7);
! 391: } else {
! 392: str[i++] = c; ADDCH(c);
! 393: }
! 394: }
! 395: #endif
! 396: str[i]=0;
! 397: }
! 398:
! 399: /*
! 400: void
! 401: input_pin(y,x,str,inmax)
! 402: int y,x;
! 403: char *str;
! 404: int inmax;
! 405: {
! 406: int i=0,cx,cy;
! 407: char c;
! 408:
! 409: if (y && x) move(y,x);
! 410: cx = x; cy = y;
! 411: CLRTOEOL();
! 412: #ifdef __alpha
! 413: while (1) {
! 414: c=getch();
! 415: if (c==10 || c==13) break;
! 416: else if (c==8 || c==16 || c==127) {
! 417: if (i>0) {
! 418: i--; cx--; echo(); move(cy,cx);
! 419: delch(); insch(' '); refresh(); noecho();
! 420: } else
! 421: beep();
! 422: } else if (i>=inmax) { beep(); } else {
! 423: str[i++] = c; cx++;
! 424: echo(); ADDCH('*'); noecho();
! 425: }
! 426: }
! 427: #else
! 428: while (1) {
! 429: c=getch();
! 430: if (c==10 || c==13) break;
! 431: else if (c==8 || c==16 || c==127) {
! 432: if (i>0) {
! 433: i--; printf("%c %c",8,8); refresh();
! 434: } else printf("%c",7);
! 435: } else if (i>=inmax) { printf("%c",7);
! 436: } else {
! 437: str[i++] = c; ADDCH('*');
! 438: }
! 439: }
! 440: #endif
! 441: str[i]=0;
! 442: }
! 443: */
! 444:
! 445: /* ------------------------------------------------------------------------- */
! 446: /* PAUSE UNTIL USER HITS A KEY */
! 447: /* ------------------------------------------------------------------------- */
! 448: void /* RETURNS: (nothing) */
! 449: mypause(y,x) /* ARGUMENTS: */
! 450: int y,x; /* Row,Col of screen */
! 451: { /* LOCAL VARIABLES: */
! 452: char c; /* Input character */
! 453:
! 454: mvaddstr(y,x,"Press ENTER/RETURN to continue");
! 455: get_input(y,x+30,&c,0);
! 456: }
! 457:
! 458: /* ------------------------------------------------------------------------- */
! 459: /* DISPLAY FAREWELL MESSAGE WHEN USER LOGS OUT */
! 460: /* ------------------------------------------------------------------------- */
! 461: void /* RETURNS: (nothing) */
! 462: properly_logout(student_number) /* ARGUMENTS: */
! 463: char *student_number;
! 464: { /* LOCAL VARIABLES: */
! 465: FILE *fp; /* Goodbye file pointer */
! 466: char buf[255]; /* Input buffer */
! 467: char *out_t;
! 468: char filename[FILE_NAME_LENGTH];
! 469:
! 470: /* DISPLAY EXIT MESSAGE */
! 471: CLEAR();
! 472: time(&log_out_time);
! 473: out_t=ctime(&log_out_time);
! 474: out_t[ strlen(out_t)-1 ]=0; /* Trash newline */
! 475:
! 476: sprintf(filename,"records/duration.db");
! 477: if ((fp=fopen(filename,"a"))==NULL) {
! 478: printf("Error: can't open duration file\n");
! 479: return;
! 480: }
! 481: flockstream(fp);
! 482: fprintf(fp,"%s\t%s\t%s\t%s\n",student_number,in_tty,in_t,out_t);
! 483: funlockstream(fp);
! 484: fclose(fp);
! 485:
! 486:
! 487: if ((fp=fopen("goodbye.msg","r"))!=NULL) {
! 488: while (fgets(buf,255,fp))
! 489: addstr(buf);
! 490: fclose(fp);
! 491: }
! 492: /* mypause(22,20); */
! 493: #ifndef NO_DUP_CHECK
! 494: logout_check(student_number);
! 495: #endif
! 496:
! 497: #ifndef LOGIN_DBUG
! 498: sprintf(buf, "This message will last for only %d seconds.",g_delay);
! 499: mvaddstr(22,20,buf); refresh();
! 500: sleep(g_delay);
! 501: #endif
! 502:
! 503: /* CURSES RESTORATION */
! 504: resetty(); endwin();
! 505: exit(1);
! 506: }
! 507: /* ------------------------------------------------------------------------- */
! 508: /* Forbid duplicate login */
! 509: /* ------------------------------------------------------------------------- */
! 510: void /* RETURNS: (nothing) */
! 511: dup_login_out() /* ARGUMENTS: */
! 512: { /* LOCAL VARIABLES: */
! 513: FILE *fp; /* Goodbye file pointer */
! 514: char buf[255]; /* Input buffer */
! 515:
! 516: /* DISPLAY EXIT MESSAGE */
! 517: CLEAR();
! 518: if ((fp=fopen("third-login.msg","r"))!=NULL) {
! 519: while (fgets(buf,255,fp)) addstr(buf);
! 520: fclose(fp);
! 521: }
! 522: /* mypause(22,20);*/
! 523: /* CURSES RESTORATION */
! 524: sprintf(buf, "This message will last for only %d seconds.",g_delay);
! 525: mvaddstr(22,20,buf); refresh();
! 526: sleep(g_delay);
! 527: resetty(); endwin();
! 528: exit(1);
! 529: }
! 530:
! 531: void /* RETURNS: (nothing) */
! 532: dup_login_warning()/* ARGUMENTS: */
! 533: { /* LOCAL VARIABLES: */
! 534: FILE *fp; /* Welcome file pointer */
! 535: char buf[255]; /* Input buffer */
! 536:
! 537: CLEAR();
! 538: if ((fp=fopen("second-login.msg","r"))!=NULL) {
! 539: while (fgets(buf,255,fp))
! 540: addstr(buf);
! 541: fclose(fp);
! 542: }
! 543: mypause(22,20);
! 544: }
! 545:
! 546: /* ------------------------------------------------------------------------- */
! 547: /* ALLOW USER TO LOG IN */
! 548: /* ------------------------------------------------------------------------- */
! 549: char /* RETURNS: Student number */
! 550: *login(maxset,section) /* ARGUMENTS: */
! 551: int *maxset; /* Set number */
! 552: int *section; /* Section number */
! 553: { /* LOCAL VARIABLES: */
! 554: char *student_number; /* Student number */
! 555: int guess, /* User-entered PIN */
! 556: login_set; /* Set for which PIN is valid */
! 557: int login_section = 0;
! 558: char buff[20]; /* Input buffer */
! 559: T_entry entry;
! 560: time_t curtime; /* Current time */
! 561: int leng;
! 562: T_student student_data;
! 563:
! 564: #define D_S_NUM_Y 11
! 565: #define D_S_NUM_X 13
! 566:
! 567: #define D_PIN_Y (D_S_NUM_Y + 2)
! 568: #define D_PIN_X (D_S_NUM_X + 10)
! 569: #define D_EXIT_Y (D_S_NUM_Y + 5)
! 570: #define D_EXIT_X (D_S_NUM_X + 6)
! 571: #define IN_S_NUM_Y (D_S_NUM_Y)
! 572: #define IN_S_NUM_X (D_S_NUM_X + 16)
! 573: #define IN_PIN_Y (D_PIN_Y)
! 574: #define IN_PIN_X (D_PIN_X + 9)
! 575: #define M_INVALID_Y (IN_PIN_Y + 1)
! 576: #define M_INVALID_X (IN_PIN_X)
! 577:
! 578: student_number = (char *)malloc( (MAX_STUDENT_NUMBER+4)*sizeof(char));
! 579: /* LOOP UNTIL WE ARE LEGALLY LOGGED IN */
! 580: do {
! 581: mvaddstr(D_S_NUM_Y,D_S_NUM_X,"STUDENT NUMBER: ");
! 582: mvaddstr(D_PIN_Y,D_PIN_X,"CAPA ID: ");
! 583: mvaddstr(D_EXIT_Y,D_EXIT_X,"To exit system, just hit ENTER/RETURN");
! 584:
! 585: #ifndef NO_PIN
! 586: /* LOOP UNTIL WE HAVE A STUDENT NUMBER AND PIN */
! 587: do {
! 588: #endif /* NO_PIN */
! 589:
! 590: /* LOOP UNTIL A LEGAL STUDENT NUMBER IS ENTERED */
! 591: do {
! 592: get_input(IN_S_NUM_Y,IN_S_NUM_X,buff, MAX_STUDENT_NUMBER);
! 593: #ifdef __sun
! 594: if (!strlen(buff)) kick_out(0);
! 595: #else
! 596: if (!strlen(buff)) kick_out();
! 597: #endif
! 598: sscanf(buff,"%s",student_number); leng = strlen(student_number);
! 599: } while (leng < MAX_STUDENT_NUMBER);
! 600:
! 601: #ifndef NO_PIN
! 602: get_input(IN_PIN_Y,IN_PIN_X,buff,MAX_PIN_CHAR);
! 603: #ifdef __sun
! 604: if (!strlen(buff)) kick_out(0);
! 605: #else
! 606: if (!strlen(buff)) kick_out();
! 607: #endif
! 608: sscanf(buff,"%d",&guess);
! 609: } while (guess<1);
! 610: #endif /* NO_PIN */
! 611:
! 612: student_number[strlen(student_number)] = 0;
! 613: /* VERIFY PIN */
! 614:
! 615: #ifdef NO_PIN
! 616: login_set = 1;
! 617: #else
! 618: login_set = capa_PIN(student_number,999,guess);
! 619: #endif /* No_PIN */
! 620:
! 621: #ifdef LOGIN_DBUG
! 622: fprintf(dfp,"LOGIN:S=%s,Guess=%04d,Actual Pin=%04d,set=%d\n",
! 623: student_number,guess,capa_PIN(student_number,1, 0), login_set);
! 624: fprintf(dfp," PIN=%04d,%04d,%04d,%04d,%04d\n",
! 625: capa_PIN(student_number,1, 0), capa_PIN(student_number,2, 0),capa_PIN(student_number,3, 0),
! 626: capa_PIN(student_number,4, 0), capa_PIN(student_number,5, 0));
! 627: fflush(dfp);
! 628: #endif
! 629: if (!login_set) {
! 630: mvaddstr(M_INVALID_Y,M_INVALID_X, "INVALID LOGIN ");
! 631: } else {
! 632: if ( login_set > 99 ) {
! 633: mvaddstr(M_INVALID_Y,M_INVALID_X, "INCORRECT PIN "); login_set = 0;
! 634: }
! 635: if ( capa_get_student(student_number,&student_data) == 0 ) {
! 636: mvaddstr(M_INVALID_Y,M_INVALID_X,"NO SUCH STUDENT"); login_set=0;
! 637: } else {
! 638: login_section = student_data.s_sec;
! 639: #ifdef LOGIN_DBUG
! 640: fprintf(dfp, " Student in section %d\n",login_section);fflush(dfp);
! 641: #endif
! 642: time(&curtime);
! 643: if( capa_check_date(CHECK_OPEN_DATE,student_number,
! 644: login_section,login_set) < 0 ) {
! 645: mvaddstr(M_INVALID_Y,M_INVALID_X,"NOT YET OPEN!"); login_set=0;
! 646: }
! 647: }
! 648: }
! 649: } while ( !login_set );
! 650: #ifdef LOGIN_DBUG
! 651: fprintf(dfp, "DEBUG:%s Access granted through set %d section %d\n",
! 652: student_number, login_set, login_section); fflush(dfp);
! 653: #endif
! 654: #ifndef NO_DUP_CHECK
! 655: switch( login_check(student_number)) {
! 656: case 0:
! 657: mvaddstr(M_INVALID_Y,M_INVALID_X,"CANNOT LOGIN"); dup_login_out();
! 658: break;
! 659: case 1:
! 660: mvaddstr(M_INVALID_Y,M_INVALID_X,"FIRST TIME LOGIN");
! 661: break;
! 662: case 2:
! 663: mvaddstr(M_INVALID_Y,M_INVALID_X,"SECOND TIME LOGIN"); dup_login_warning( );
! 664: break;
! 665: case -1:
! 666: #ifdef __sun
! 667: mvaddstr(M_INVALID_Y,M_INVALID_X,"FILE ERROR"); kick_out(0);
! 668: #else
! 669: mvaddstr(M_INVALID_Y,M_INVALID_X,"FILE ERROR"); kick_out();
! 670: #endif
! 671: break;
! 672: }
! 673: #endif /* NO_DUP_CHECK */
! 674: capa_get_entry(&entry,student_number,login_set);
! 675: (*maxset) = login_set;
! 676: (*section) = login_section;
! 677: capa_mfree(entry.answers);
! 678: capa_mfree(entry.tries);
! 679: return (student_number);
! 680: }
! 681:
! 682: /* ------------------------------------------------------------------------- */
! 683: /* LOG ANSWERS TO A FILE WITH TIMESTAMP */
! 684: /* ------------------------------------------------------------------------- */
! 685: int /* RETURNS: error code */
! 686: log_attempt(student_number,set,section,log_string) /* ARGUMENTS: */
! 687: char student_number[MAX_STUDENT_NUMBER+1]; /* Student number */
! 688: int set; /* Set number */
! 689: int section; /* Section number */
! 690: char *log_string; /* Answer string to log */
! 691: { /* LOCAL VARIABLES: */
! 692: char filename[FILE_NAME_LENGTH], /* Log filename buffer */
! 693: *ct; /* Current time string */
! 694: FILE *fp; /* Log file pointer */
! 695: time_t t; /* Timestamp for log */
! 696:
! 697: /* OPEN LOG FILE */
! 698:
! 699: sprintf(filename,"records/log%d.db",set);
! 700: if ((fp=fopen(filename,"a"))==NULL) {
! 701: printf("Error: can't open log file\n");
! 702: return -1;
! 703: }
! 704:
! 705: /* CREATE LOG ENTRY */
! 706: time(&t);
! 707: ct=ctime(&t);
! 708: ct[ strlen(ct)-1 ]=0; /* Trash newline */
! 709: fprintf(fp,"%s %s %s\n",student_number,ct,log_string); fflush(fp);
! 710: fclose(fp);
! 711: return 0;
! 712: }
! 713:
! 714: int log_submissions(student_number,set,log_string)
! 715: char student_number[MAX_STUDENT_NUMBER+1];
! 716: int set;
! 717: char *log_string;
! 718: {
! 719: char filename[FILE_NAME_LENGTH], timeStr[FILE_NAME_LENGTH],buf2[MAX_BUFFER_SIZE];
! 720: FILE *fp;
! 721: time_t t;
! 722: struct tm *tmtime;
! 723: int do_log_submissions=1,result;
! 724: char buf[MAX_BUFFER_SIZE];
! 725:
! 726: result=read_capa_config("do_log_submissions",buf);
! 727: if (result != 0 && result != -1) {
! 728: if (strcasecmp(buf2,"no")==0) {
! 729: do_log_submissions=0;
! 730: }
! 731: }
! 732: if (!do_log_submissions) return 0;
! 733:
! 734: sprintf(filename,"records/submissions%d.db",set);
! 735: if ((fp=fopen(filename,"a"))==NULL) {
! 736: return (-1);
! 737: }
! 738:
! 739: /* CREATE LOG ENTRY */
! 740: time(&t);
! 741: tmtime=localtime(&t);
! 742: strftime(timeStr,FILE_NAME_LENGTH,"%d/%m %X",tmtime);
! 743: /*ct[ strlen(ct)-1 ]=0;*/ /* Trash newline */
! 744: protect_log_string(log_string);
! 745: fprintf(fp,"%s\t%s\t%s\n",student_number,timeStr,log_string); fflush(fp);
! 746: fclose(fp);
! 747: return (0);
! 748: }
! 749:
! 750: #define C_FORWARD 1
! 751: #define C_EXIT 2
! 752: #define C_MENU 3
! 753: #define C_HINT 4
! 754: #define C_EXPLAIN 5
! 755: #define C_ANSWER 6
! 756: #define C_JUMP 7
! 757: #define C_DONTCARE 8
! 758: #define C_BACKWARD 9
! 759: #define C_TIME 10
! 760: #define C_NEXTSCR 11
! 761: #define C_PREVSCR 12
! 762: #define C_SUBJANS 13
! 763:
! 764: /* ------------------------------------------------------------------------- */
! 765: /* DISPLAY SUMMARY OF SCORES FOR THE TERM */
! 766: /* ------------------------------------------------------------------------- */
! 767: void /* RETURNS: (nothing) */
! 768: term_summary(student_number,set,section,type) /* ARGUMENTS: */
! 769: char *student_number; /* Student Number */
! 770: int set; /* Set number */
! 771: int *section; /* Section Number */
! 772: int type;
! 773: { /* LOCAL VARIABLES: */
! 774: int set_idx, /* Set counter */
! 775: i, /* Question counter */
! 776: tmp, /* Question correct flag */
! 777: set_score, /* Score on a set */
! 778: term_score=0, /* Total points received */
! 779: term_total=0, /* Total points possible */
! 780: result;
! 781: T_entry entry; /* Database entry for a set */
! 782: char buf[MAX_BUFFER_SIZE], buf2[MAX_BUFFER_SIZE];
! 783: T_header header; /* Problem set header */
! 784: int topset=1, /* First displayed set */
! 785: bottomset, /* Last displayed set */
! 786: done=0, /* Done flag */
! 787: line, col;
! 788: int probs_in_set[MAX_BUFFER_SIZE],/* # problem set questions */
! 789: start_at[MAX_BUFFER_SIZE],
! 790: valid_wgt[SMALL_LINE_BUFFER],
! 791: a_valid_wgt,set_start_line,
! 792: usr_command,inhibit_response;
! 793:
! 794: /* CALCULATE TERM TOTALS */
! 795: start_at[0] = -2;
! 796: probs_in_set[0]= 0;
! 797: for (set_idx=1; set_idx<=set; set_idx++) {
! 798: if (capa_get_header(&header,set_idx)) return;
! 799: capa_get_entry(&entry,student_number,set_idx);
! 800: sscanf(header.num_questions,"%d", &(probs_in_set[set_idx]) );
! 801: start_at[set_idx] = start_at[set_idx-1]+2*(1+probs_in_set[set_idx-1]/50);
! 802: if ((start_at[set_idx]%12)+2*(1+probs_in_set[set_idx]/50) > 12)
! 803: start_at[set_idx] = 12*(1+start_at[set_idx]/12);
! 804: valid_wgt[set_idx] = 0;
! 805: for (i=0; i<probs_in_set[set_idx]; i++) {
! 806: valid_wgt[set_idx] += (header.weight[i] - '0');
! 807: if((entry.answers[i]=='Y') || (entry.answers[i]=='y'))
! 808: term_score += (header.weight[i]-'0');
! 809: if((entry.answers[i]=='E') || (entry.answers[i]=='e'))
! 810: valid_wgt[set_idx] -= (header.weight[i] - '0');
! 811: if((entry.answers[i]>='0') && (entry.answers[i]<='9'))
! 812: term_score += (entry.answers[i] - '0');
! 813: }
! 814: term_total += valid_wgt[set_idx];
! 815: capa_mfree(header.weight);
! 816: capa_mfree(header.partial_credit);
! 817: capa_mfree(entry.answers);
! 818: capa_mfree(entry.tries);
! 819: }
! 820:
! 821: /* FIND TOPSET */
! 822: line = 12*(start_at[set]/12); /* Top line # of last screen */
! 823: for (topset=set; topset>1 && start_at[topset-1]>=line; topset--);
! 824:
! 825: /* SHOW HEADER */
! 826: CLEAR();
! 827: switch(type) {
! 828: case TERM_SUMMARY: mvaddstr(1,30,"TERM SUMMARY"); break;
! 829: case EXAM_SUMMARY: mvaddstr(1,30,"EXAM SUMMARY"); break;
! 830: case QUIZ_SUMMARY: mvaddstr(1,30,"QUIZ SUMMARY"); break;
! 831: }
! 832: mvaddstr(3,22," 1 2 3 4 5");
! 833: mvaddstr(4,22,"12345678901234567890123456789012345678901234567890");
! 834:
! 835: /* DISPLAY COMMAND MENU */
! 836: mvaddstr(21,1,"Enter a command from the list below and press ENTER/RETURN COMMAND:");
! 837: mvaddstr(22,1,"M =Go to main menu N =Next Page P =Prev Page");
! 838: /* mvaddstr(22,1,"X =eXit M =Go to main menu N =Next Page P =Prev Page"); */
! 839: refresh();
! 840:
! 841: /* SHOW TOTALS */
! 842: /* if capalogin_show_summary_score is set to none don't show it */
! 843: sprintf(buf,"%d sets, total=%3d/%3d (%d%%)", set, term_score, term_total,
! 844: 100*term_score/term_total);
! 845: result=read_capa_config("capalogin_show_summary_score",buf2);
! 846: if (result != 0 && result != -1) {
! 847: if (strcasecmp(buf2,"none")==0) {
! 848: } else {
! 849: mvaddstr(19,1,buf);
! 850: }
! 851: } else {
! 852: mvaddstr(19,1,buf);
! 853: }
! 854:
! 855: /* LOOP UNTIL DONE */
! 856: while (!done) {
! 857: /* PRINT 1 LINE SUMMARY PER SET */
! 858: line=5;
! 859: for (set_idx=topset; set_idx<=set; set_idx++) {
! 860: /* don't show summary for set if inhibit response is set*/
! 861: inhibit_response=capa_check_option(OPTION_INHIBIT_RESPONSE,set_idx,*section);
! 862: if (inhibit_response > 0) continue;
! 863:
! 864: set_score=0;
! 865: set_start_line=line;
! 866: /* Stop if not enough lines to summarize set */
! 867: if (line+2*(probs_in_set[set_idx]/50)>16) break;
! 868: capa_get_header(&header,set_idx);
! 869: capa_get_entry(&entry,student_number,set_idx);
! 870: a_valid_wgt = 0;
! 871: for (i=0, col=0; i<probs_in_set[set_idx]; i++) {
! 872: tmp=0; a_valid_wgt += (header.weight[i] - '0');
! 873: move(line, 22+col); addch(entry.answers[i]);
! 874: move(line+1,22+col); addch(header.weight[i]);
! 875: switch(entry.answers[i]) {
! 876: case 'Y': tmp=header.weight[i] -'0'; break; /* Answer correct */
! 877: case 'y': tmp=header.weight[i] -'0'; break; /* Grading correct */
! 878: case '-': break; /* Not answered */
! 879: case 'N': break; /* Answer incorrect */
! 880: case 'n': break; /* Grading incorrect */
! 881: case 'e': a_valid_wgt -= (header.weight[i] - '0'); break; /* Excuse */
! 882: case 'E': a_valid_wgt -= (header.weight[i] - '0'); break; /* Excuse */
! 883: default : if( entry.answers[i] >= '0' && entry.answers[i] <= '9' ) {
! 884: tmp = entry.answers[i] - '0';
! 885: }
! 886: break;
! 887: }
! 888: set_score += tmp; col++;
! 889: if (!((i+1)%50)) { line += 2; col = 0; }
! 890: }
! 891: capa_mfree(header.weight);
! 892: capa_mfree(header.partial_credit);
! 893: capa_mfree(entry.answers);
! 894: capa_mfree(entry.tries);
! 895: move(line, 22+col); CLRTOEOL();
! 896: move(line+1, 22+col); CLRTOEOL();
! 897: if(a_valid_wgt == 0) {
! 898: set_score=0;
! 899: sprintf(buf,"%3d:%3d/%3d(%3d%%) ",set_idx,set_score,a_valid_wgt,set_score);
! 900: mvaddstr(set_start_line,1,buf);
! 901: } else {
! 902: sprintf(buf,"%3d:%3d/%3d(%3d%%) ",set_idx,set_score,a_valid_wgt,100*set_score/a_valid_wgt);
! 903: mvaddstr(set_start_line,1,buf);
! 904: }
! 905: line += 2;
! 906: }
! 907: bottomset=set_idx-1;
! 908:
! 909: /* Blank out any extra lines */
! 910: if (line < 16) {
! 911: for (set_idx=line; set_idx<=16; set_idx++) {
! 912: move(set_idx,1);
! 913: CLRTOEOL();
! 914: }
! 915: }
! 916:
! 917: /* PROCESS USER COMMAND */
! 918: get_input(21,72,buf,1);
! 919: if(!strlen(buf)) { usr_command = C_FORWARD; } else {
! 920:
! 921: switch(toupper(buf[0])) {
! 922: /* case 'X': usr_command=C_EXIT; break; */
! 923: case 'M': usr_command=C_MENU; break;
! 924: case 'P': usr_command=C_BACKWARD; break;
! 925: default : usr_command=C_FORWARD; break;
! 926: }
! 927: }
! 928:
! 929:
! 930: switch(usr_command) {
! 931: case C_DONTCARE: break;
! 932: case C_FORWARD: /* Forwards */
! 933: if (bottomset<set) { topset=bottomset+1; } else { done=1; }
! 934: break;
! 935:
! 936: case C_BACKWARD: /* Backwards */
! 937: if (topset<2) break;
! 938: line = 12*(start_at[topset-1]/12); /* Top line # of prev screen */
! 939: for (; topset>1 && start_at[topset-1]>=line; topset--);
! 940: break;
! 941:
! 942: case C_MENU: /* Menu */
! 943: done=1;
! 944: break;
! 945: case C_EXIT: /* Exit */
! 946: properly_logout(student_number);
! 947: break;
! 948: default: /* Invalid command */
! 949: break;
! 950: }
! 951: }
! 952: }
! 953:
! 954: void
! 955: display_hint(char *h)
! 956: {
! 957:
! 958: CLEAR();
! 959:
! 960: wrap(h);
! 961: mypause(22,20);
! 962: }
! 963:
! 964: #define A_ROW 20
! 965: #define S_ROW 21
! 966: #define O_ROW 22
! 967: #define X_ROW 23
! 968:
! 969: #define A_COL 14
! 970: #define S_COL 46
! 971: #define H_COL 24
! 972: #define E_COL 39
! 973: #define X_COL 8
! 974: #define R_COL 57
! 975: #define U_ANS_CHAR 32
! 976:
! 977: /* =============================================================================
! 978: 0001234567890123456789012345678901234567890123456789012345678901234567890123456789
! 979: A
! 980: S1OPTION/ANSWER 12345678901234 ----- *Unanswered
! 981: O2Options :M = Main Menu :7 = go to #7 :N = Next screen RETURN = Enter/Execute
! 982: X3 :X = eXit :H = Show Hint :E = Explain RETURN = Next Problem
! 983: 0123456789012345678901234567890123456789012345678901234567890
! 984: ^ ^ ^ ^ ^ ^
! 985: X A H E S R
! 986: */
! 987: int show_prior_response(Problem_t *p,int hgr,int prev_ans,int tried,int *allow_h)
! 988: {
! 989: char *c_answer_str, tmp_str[MAX_BUFFER_SIZE];
! 990: char *response="Incorrect",*answered="Answered";
! 991: int can_answer;
! 992:
! 993: if( hgr == '0' || p->ans_type==ANSWER_IS_SUBJECTIVE) {
! 994: switch(prev_ans) {
! 995: case 'Y': can_answer=NAY; *allow_h=1;
! 996: c_answer_str = answers_string(ANSWER_STRING_MODE,p);
! 997: move(A_ROW,A_COL); clrtoeol();
! 998: mvaddstr(A_ROW,A_COL,c_answer_str); capa_mfree(c_answer_str);
! 999: move(S_ROW,S_COL); clrtoeol();
! 1000: mvaddstr(S_ROW,S_COL,"**Correct "); break;
! 1001: case 'y': can_answer=NAY; *allow_h=1;
! 1002: c_answer_str = answers_string(ANSWER_STRING_MODE,p);
! 1003: move(A_ROW,A_COL); clrtoeol();
! 1004: mvaddstr(A_ROW,A_COL,c_answer_str); capa_mfree(c_answer_str);
! 1005: move(S_ROW,S_COL); clrtoeol();
! 1006: mvaddstr(S_ROW,S_COL,"*Hand-graded Correct "); break;
! 1007: case '-': can_answer=YAK; move(S_ROW,S_COL); clrtoeol();
! 1008: mvaddstr(S_ROW,S_COL,"*Unanswered "); break;
! 1009: case 'E': can_answer=NAY; move(S_ROW,S_COL); clrtoeol();
! 1010: mvaddstr(S_ROW,S_COL,"*Excused "); break;
! 1011: case 'e': can_answer=NAY; move(S_ROW,S_COL); clrtoeol();
! 1012: mvaddstr(S_ROW,S_COL,"*Excused "); break;
! 1013: case 'n': can_answer=NAY; move(S_ROW,S_COL); clrtoeol();
! 1014: mvaddstr(S_ROW,S_COL,"*Hand-graded Incorrect "); break;
! 1015: case '0': case '1': case '2': case '3': case '4': case '5':
! 1016: case '6': case '7': case '8': case '9':
! 1017: response=answered;
! 1018: case 'N': if ( tried < p->tries ) {
! 1019: can_answer=YAK;
! 1020: if( (p->tries - tried) == 1 ) {
! 1021: sprintf(tmp_str,"*%s, ONE try left!!",response);
! 1022: } else {
! 1023: sprintf(tmp_str,"*%s, tries %2d/%2d ",response,tried,p->tries);
! 1024: }
! 1025: } else {
! 1026: can_answer=NAY;
! 1027: sprintf(tmp_str, "*%s, no more tries",response);
! 1028: }
! 1029: move(S_ROW,S_COL); clrtoeol();
! 1030: mvaddstr(S_ROW,S_COL,tmp_str);
! 1031: if( (can_answer == YAK) && (p->ans_op == ANS_AND) && (p->ans_cnt > 1)) {
! 1032: sprintf(tmp_str, " Entering answer 1 of %3d ",p->ans_cnt);
! 1033: mvaddstr(A_ROW,S_COL,tmp_str);
! 1034: }
! 1035: break;
! 1036: }
! 1037: } else { /* hand graded question */
! 1038: can_answer=NAY;
! 1039: move(S_ROW,S_COL); clrtoeol();
! 1040: mvaddstr(S_ROW,S_COL,"*Hand-graded question ");
! 1041: }
! 1042: /* ------------------------------------------------------------------ */
! 1043: if (*allow_h &&
! 1044: p->hint &&
! 1045: (
! 1046: ( p->show_hint <= tried ) ||
! 1047: ( prev_ans == 'y' ) ||
! 1048: ( prev_ans == 'Y' )
! 1049: )
! 1050: ) {
! 1051: mvaddstr(X_ROW,H_COL,":H = Show Hint");
! 1052: } else {
! 1053: *allow_h = 0;
! 1054: }
! 1055: if (p->next)
! 1056: mvaddstr(X_ROW,R_COL,"RETURN = Next Problem");
! 1057: else
! 1058: mvaddstr(X_ROW,R_COL,"RETURN = Main Menu ");
! 1059:
! 1060: return (can_answer);
! 1061:
! 1062: }
! 1063: int show_prior_inhibited_response(Problem_t *p,int hgr,int prev_ans,int tried,
! 1064: int *allow_h)
! 1065: {
! 1066: char tmp_str[MAX_BUFFER_SIZE];
! 1067: int can_answer;
! 1068:
! 1069: if( hgr == '0' ) {
! 1070: switch(prev_ans) {
! 1071: case '-': can_answer=YAK; move(S_ROW,S_COL); clrtoeol();
! 1072: mvaddstr(S_ROW,S_COL,"*Unanswered "); break;
! 1073: case 'E':
! 1074: case 'e':
! 1075: case 'n':
! 1076: case 'y':
! 1077: case 'Y':
! 1078: case 'N': if ( tried < p->tries ) {
! 1079: can_answer=YAK;
! 1080: if( (p->tries - tried) == 1 ) {
! 1081: sprintf(tmp_str,"*Answered, ONE try left!! ");
! 1082: } else {
! 1083: sprintf(tmp_str,"*Answered, tries %2d/%2d ",tried,p->tries);
! 1084: }
! 1085: } else {
! 1086: can_answer=NAY;
! 1087: sprintf(tmp_str, "*Answered, no more tries ");
! 1088: }
! 1089: move(S_ROW,S_COL); clrtoeol();
! 1090: mvaddstr(S_ROW,S_COL,tmp_str); break;
! 1091:
! 1092: }
! 1093: } else { /* hand graded question */
! 1094: can_answer=NAY;
! 1095: move(S_ROW,S_COL); clrtoeol();
! 1096: mvaddstr(S_ROW,S_COL,"*Hand-graded question ");
! 1097: }
! 1098: /* ------------------------------------------------------------------ */
! 1099: if (*allow_h && p->hint && ( p->show_hint <= tried)){
! 1100: mvaddstr(X_ROW,H_COL,":H = Show Hint");
! 1101: } else {
! 1102: *allow_h = 0;
! 1103: }
! 1104: if (p->next)
! 1105: mvaddstr(X_ROW,R_COL,"RETURN = Next Problem");
! 1106: else
! 1107: mvaddstr(X_ROW,R_COL,"RETURN = Main Menu ");
! 1108:
! 1109: return (can_answer);
! 1110:
! 1111: }
! 1112: /* -------------------------------------------- dbug --------------------- */
! 1113: void
! 1114: print_unit_components(FILE *fp,Unit_t *t)
! 1115: {
! 1116: Unit_E *ue_p;
! 1117:
! 1118: fprintf(fp," Unit::[%s] = %g * ", t->u_symbol, t->u_scale);
! 1119: for(ue_p=t->u_list; ue_p ; ue_p = ue_p->ue_nextp) {
! 1120: fprintf(fp,"(%g*%s^%g) ",ue_p->ue_scale,ue_p->ue_symbol,ue_p->ue_exp);
! 1121: }
! 1122: fprintf(fp,"\n"); fflush(fp);
! 1123:
! 1124: }
! 1125:
! 1126:
! 1127: #define ANSWER_STRING_LENG 64
! 1128: #define UNIT_STRING_LENG 64
! 1129: #define FORMAT_STRING_LENG 32
! 1130:
! 1131: /* ------------------------------------------------------------------- */
! 1132: int give_response(Problem_t *p,char **a,int cnt,int *tried,int *log_char)
! 1133: {
! 1134: int can_answer;
! 1135: char tmp_str[MAX_BUFFER_SIZE], *c_answer_str;
! 1136:
! 1137:
! 1138: switch( capa_check_answers(p,a,cnt) ) {
! 1139:
! 1140: case EXACT_ANS: move(A_ROW,S_COL); clrtoeol();
! 1141: mvaddstr(A_ROW,S_COL,"*Yes Computer gets:");
! 1142: c_answer_str = answers_string(ANSWER_STRING_MODE, p);
! 1143: move(S_ROW,S_COL); clrtoeol();
! 1144: mvaddstr(S_ROW,S_COL,c_answer_str);
! 1145: capa_mfree((char *)c_answer_str);
! 1146: *log_char='Y'; can_answer=NAY;
! 1147: if( *tried < TRY_BOUND) (*tried)++;
! 1148: break;
! 1149: case APPROX_ANS:
! 1150: move(A_ROW,S_COL); clrtoeol();
! 1151: mvaddstr(A_ROW,S_COL,"*Yes Computer gets:");
! 1152: c_answer_str = answers_string(ANSWER_STRING_MODE, p);
! 1153: if(cnt == 1 ) {
! 1154: move(S_ROW,S_COL); clrtoeol();
! 1155: mvaddstr(S_ROW,S_COL,c_answer_str);
! 1156: } else { /* more than one answer to check ANS_AND */
! 1157: move(S_ROW,S_COL); clrtoeol();
! 1158: mvaddstr(S_ROW,S_COL,"*Yes Correct Answers See Above");
! 1159: move(A_ROW,A_COL); clrtoeol();
! 1160: mvaddstr(A_ROW,A_COL,c_answer_str);
! 1161: }
! 1162: capa_mfree((char *)c_answer_str);
! 1163: *log_char='Y'; can_answer=NAY;
! 1164: if(*tried < TRY_BOUND) (*tried)++;
! 1165: break;
! 1166: case SIG_FAIL: move(S_ROW,S_COL); clrtoeol();
! 1167: mvaddstr(S_ROW,S_COL,"*Adjust Sig. Figs. ");
! 1168: *log_char='S'; can_answer=YAK;
! 1169: break;
! 1170: case UNIT_FAIL: move(S_ROW,S_COL); clrtoeol();
! 1171: mvaddstr(S_ROW,S_COL,"*Units incorrect ");
! 1172: *log_char='U'; can_answer=YAK;
! 1173: break;
! 1174: case UNIT_NOTNEEDED: move(S_ROW,S_COL); clrtoeol();
! 1175: mvaddstr(S_ROW,S_COL,"*Only a number required");
! 1176: *log_char='U'; can_answer=YAK;
! 1177: break;
! 1178: case NO_UNIT: move(S_ROW,S_COL); clrtoeol();
! 1179: mvaddstr(S_ROW,S_COL,"*Units required ");
! 1180: *log_char='u'; can_answer=YAK;
! 1181: break;
! 1182: case BAD_FORMULA:move(S_ROW,S_COL); clrtoeol();
! 1183: mvaddstr(S_ROW,S_COL,"*Unable to interpret formula");
! 1184: *log_char='F'; can_answer=YAK;
! 1185: break;
! 1186: case ANS_CNT_NOT_MATCH:
! 1187: move(S_ROW,S_COL); clrtoeol();
! 1188: mvaddstr(S_ROW,S_COL,"*Invalid number of answers");
! 1189: *log_char='C'; can_answer=YAK;
! 1190: break;
! 1191: case INCORRECT:
! 1192: if(*tried < TRY_BOUND) (*tried)++;
! 1193: if ( *tried < p->tries ) {
! 1194: can_answer=YAK;
! 1195: if( (p->tries - *tried) == 1 ) {
! 1196: sprintf(tmp_str,"*Incorrect, ONE try left!!");
! 1197: } else {
! 1198: sprintf(tmp_str,"*Incorrect, tries %2d/%2d ",*tried,p->tries);
! 1199: }
! 1200: } else {
! 1201: can_answer=NAY;
! 1202: sprintf(tmp_str, "*Incorrect, no more tries");
! 1203: }
! 1204: move(S_ROW,S_COL); clrtoeol();
! 1205: mvaddstr(S_ROW,S_COL, tmp_str);
! 1206: if( (can_answer == YAK) && (p->ans_op == ANS_AND) && (p->ans_cnt > 1) ) {
! 1207: sprintf(tmp_str, " Entering answer 1 of %3d ",p->ans_cnt);
! 1208: mvaddstr(A_ROW,S_COL,tmp_str);
! 1209: }
! 1210: *log_char='N';
! 1211: break;
! 1212: }
! 1213:
! 1214: return (can_answer);
! 1215: }
! 1216:
! 1217: int give_inhibited_response(Problem_t *p,char **a,int cnt,int *tried,int *log_char)
! 1218: {
! 1219: int can_answer;
! 1220: char tmp_str[MAX_BUFFER_SIZE];
! 1221:
! 1222:
! 1223: switch( capa_check_answers(p,a,cnt) ) {
! 1224:
! 1225:
! 1226: case EXACT_ANS: *log_char='Y'; break;
! 1227: case APPROX_ANS: *log_char='Y'; break;
! 1228: case SIG_FAIL: *log_char='S'; break;
! 1229: case UNIT_FAIL: *log_char='U'; break;
! 1230: case UNIT_NOTNEEDED: *log_char='U'; break;
! 1231: case NO_UNIT: *log_char='u'; break;
! 1232: case BAD_FORMULA:*log_char='F'; break;
! 1233: case INCORRECT: *log_char='N'; break;
! 1234: case ANS_CNT_NOT_MATCH: *log_char='C'; break;
! 1235: }
! 1236:
! 1237: if(*tried < TRY_BOUND) (*tried)++;
! 1238: if ( *tried < p->tries ) {
! 1239: can_answer=YAK;
! 1240: if( (p->tries - *tried) == 1 ) {
! 1241: sprintf(tmp_str,"*Answered, ONE try left!! ");
! 1242: } else {
! 1243: sprintf(tmp_str,"*Answered, tries %2d/%2d ",*tried,p->tries);
! 1244: }
! 1245: } else {
! 1246: can_answer=NAY;
! 1247: sprintf(tmp_str, "*Answered, no more tries ");
! 1248: }
! 1249: move(S_ROW,S_COL); clrtoeol();
! 1250: mvaddstr(S_ROW,S_COL, tmp_str);
! 1251: return (can_answer);
! 1252: }
! 1253:
! 1254: int ask_what_prob(int q_cnt, char *ans)
! 1255: {
! 1256: int not_ok=1,num,anslength,i,j;
! 1257: char buf[5],buf2[MAX_BUFFER_SIZE];
! 1258:
! 1259: move(14,35); clrtoeol();
! 1260: move(17,5); clrtoeol();
! 1261: do {
! 1262: move(14,35); clrtoeol();
! 1263: move(15,0); clrtoeol();
! 1264: mvaddstr(15,13,"What problem number:");
! 1265: move(17,0); clrtoeol();
! 1266: mvaddstr(17,16," 1 2 3 4 5");
! 1267: mvaddstr(18,16,"12345678901234567890123456789012345678901234567890");
! 1268: anslength=strlen(ans);
! 1269: for(i=0;i<=(anslength/50);i++) {
! 1270: if ( g_inhibit_response ) {
! 1271: for(j=50*i;(j<((i+1)*50))&&(j<anslength);j++) {
! 1272: if (ans[j]=='-')
! 1273: buf2[j-(50*i)]='-';
! 1274: else
! 1275: buf2[j-(50*i)]='A';
! 1276: }
! 1277: buf2[j-(50*i)]='\0';
! 1278: } else {
! 1279: strncpy(buf2,&(ans[50*i]),50);
! 1280: }
! 1281: buf2[50]='\0';
! 1282: mvaddstr(19+i,16,buf2);
! 1283: if (anslength > 50 ) {
! 1284: sprintf(buf2,"%3d-%3d",i*50+1,(i+1)*50);
! 1285: mvaddstr(19+i,5,buf2);
! 1286: }
! 1287: }
! 1288: do { get_input(15,34,buf,4); } while(!strlen(buf));
! 1289: sscanf(buf,"%d",&num);
! 1290: if (num<1 || num>q_cnt) {
! 1291: move(21,5); clrtoeol();
! 1292: mvaddstr(21,15," Error: Invalid problem number\n");
! 1293: } else {
! 1294: not_ok = 0;
! 1295: }
! 1296: } while (not_ok);
! 1297:
! 1298: return (num);
! 1299: }
! 1300:
! 1301: /* gather subjective answers from student */
! 1302:
! 1303: #define BS 8
! 1304: #define DEL 127
! 1305: #define ESC 27
! 1306:
! 1307: #define COLON 58
! 1308:
! 1309: #define EDIT_HEIGHT 21
! 1310: #define EDIT_WIDTH 80
! 1311: #define MENULINE EDIT_HEIGHT
! 1312:
! 1313: void refresh_editor (char **sbuf_pp,int cx,int cy) {
! 1314: int i;
! 1315: CLEAR();
! 1316: echo();
! 1317: mvaddstr(MENULINE,0,"Type in the answer, use up, down, left, right keys to move curser");
! 1318: mvaddstr(MENULINE+1,0,"Enter ctrl-e to exit and submit answer");
! 1319: mvaddstr(MENULINE+2,0,"Enter ctrl-f to forget answer");
! 1320: for(i=0;i<EDIT_HEIGHT;i++) { mvaddstr(i,0,sbuf_pp[i]); }
! 1321: move(cy,cx); refresh(); noecho();
! 1322: }
! 1323:
! 1324: void init_editor(char*** sbuf_pp)
! 1325: {
! 1326: int ww=EDIT_WIDTH, hh=EDIT_HEIGHT,i;
! 1327: *sbuf_pp = (char **)capa_malloc(sizeof(char *),hh);
! 1328: for(i=0;i<hh;i++) {
! 1329: (*sbuf_pp)[i] = (char *)capa_malloc(sizeof(char)*ww+1,1);
! 1330: }
! 1331: CLEAR();echo();
! 1332: mvaddstr(MENULINE,0,"Type in the answer, use up, down, left, right keys to move cursor");
! 1333: mvaddstr(MENULINE+1,0,"Enter ctrl-e to exit and submit answer");
! 1334: mvaddstr(MENULINE+2,0,"Enter ctrl-f to forget answer");
! 1335: move(0,0); refresh(); noecho();
! 1336: }
! 1337:
! 1338: void remove_character(char** sbuf_pp,int *cx,int *cy)
! 1339: {
! 1340: int sx=(*cx)-1,sy=*cy;
! 1341: char temp,*temp_p;
! 1342: if (*cx==0) {
! 1343: int abovelen,curlen,diff,i,j;
! 1344: if (*cy==0) { beep();return;}
! 1345: abovelen=strlen(sbuf_pp[(*cy-1)]);
! 1346: curlen=strlen(sbuf_pp[*cy]);
! 1347: if (abovelen > 0) sbuf_pp[(*cy)-1][abovelen-1]='\0';
! 1348: if ((abovelen+curlen) < EDIT_WIDTH) {
! 1349: strcat(sbuf_pp[(*cy)-1],sbuf_pp[*cy]);
! 1350: memset(sbuf_pp[(*cy)],'\0',EDIT_WIDTH+1);
! 1351: temp_p=sbuf_pp[*cy];
! 1352: i=*cy;
! 1353: while(i<EDIT_HEIGHT-1) {
! 1354: sbuf_pp[i]=sbuf_pp[i+1];
! 1355: echo();move(i,0);CLRTOEOL();mvaddstr(i,0,sbuf_pp[i]);noecho();
! 1356: i++;
! 1357: }
! 1358: sbuf_pp[EDIT_HEIGHT-1]=temp_p;
! 1359: echo();move(EDIT_HEIGHT-1,0);CLRTOEOL();noecho();
! 1360: } else {
! 1361: diff=EDIT_WIDTH-abovelen;
! 1362: strncat(sbuf_pp[(*cy)-1],sbuf_pp[*cy],diff);
! 1363: i=diff;j=0;
! 1364: while(sbuf_pp[*cy][i]!='\0') {
! 1365: sbuf_pp[*cy][j]=sbuf_pp[*cy][i];
! 1366: i++;j++;
! 1367: }
! 1368: memset(&(sbuf_pp[(*cy)][j]),'\0',EDIT_WIDTH+1-j);
! 1369: }
! 1370: echo();move(*cy,0); CLRTOEOL(); mvaddstr(*cy,0,sbuf_pp[*cy]);noecho();
! 1371: (*cy)--;
! 1372: echo();move(*cy,0); CLRTOEOL(); mvaddstr(*cy,0,sbuf_pp[*cy]);noecho();
! 1373: if ( EDIT_WIDTH == ((*cx)=(abovelen-1))) (*cx)--;
! 1374: if (abovelen==0) *cx=0;
! 1375: echo();move(*cy,*cx);noecho();
! 1376: } else {
! 1377: echo();move(sy,sx);noecho();
! 1378: temp=sbuf_pp[sy][sx]=sbuf_pp[sy][sx+1];
! 1379: sx++;
! 1380: while(temp!='\0') {
! 1381: echo(); ADDCH(temp); noecho();
! 1382: temp=sbuf_pp[sy][sx]=sbuf_pp[sy][sx+1];
! 1383: sx++;
! 1384: }
! 1385: echo(); ADDCH(' '); noecho();
! 1386: (*cx)--;
! 1387: }
! 1388: echo();move(*cy,*cx);noecho();
! 1389: }
! 1390:
! 1391: void break_line (char** sbuf_pp,int *cx,int *cy)
! 1392: {
! 1393: int sx=*cx,sy=*cy,i;
! 1394: if (sy < EDIT_HEIGHT-1) {
! 1395: capa_mfree(sbuf_pp[EDIT_HEIGHT-1]);
! 1396: i=EDIT_HEIGHT-1;
! 1397: while (i-1 > sy) {
! 1398: sbuf_pp[i]=sbuf_pp[i-1];
! 1399: move(i,0);CLRTOEOL();mvaddstr(i,0,sbuf_pp[i]);
! 1400: i--;
! 1401: }
! 1402: sbuf_pp[sy+1]=capa_malloc(sizeof(char)*EDIT_WIDTH+1,1);
! 1403: }
! 1404: strcat(sbuf_pp[sy+1],&(sbuf_pp[sy][sx]));
! 1405: memset(&(sbuf_pp[sy][sx]),'\0',EDIT_WIDTH+1-sx);
! 1406: *cx=0;
! 1407: (*cy)++;
! 1408: move(sy,0);CLRTOEOL();mvaddstr(sy,0,sbuf_pp[sy]);
! 1409: move(sy+1,0);CLRTOEOL();mvaddstr(sy+1,0,sbuf_pp[sy+1]);
! 1410: }
! 1411:
! 1412: /* FIXME catch funtion keys and others? */
! 1413: void handle_esc (unsigned char ca,unsigned char cb,char** sbuf_pp,int *cx,int *cy)
! 1414: {
! 1415: if( ca!='[') return;
! 1416: switch (cb) {
! 1417: case 'A':/* KEY_UP */
! 1418: if(*cy>0){
! 1419: (*cy)--;
! 1420: while(*cx>0 && sbuf_pp[*cy][(*cx)-1]=='\0') (*cx)--; /* goto end of line */
! 1421: } else {
! 1422: beep();
! 1423: }
! 1424: break;
! 1425: case 'B': /* KEY_DOWN */
! 1426: if (*cy<(EDIT_HEIGHT-1)) {
! 1427: (*cy)++;
! 1428: while(*cx>0 && sbuf_pp[*cy][(*cx)-1]=='\0') (*cx)--; /* goto end of line */
! 1429: } else {
! 1430: beep();
! 1431: }
! 1432: break;
! 1433: case 'C': /* KEY_RIGHT */
! 1434: if ( *cx<(EDIT_WIDTH-1) && sbuf_pp[*cy][(*cx)]!='\0' ) {
! 1435: (*cx)++;
! 1436: } else {
! 1437: if (*cy<(EDIT_HEIGHT-1)) {
! 1438: (*cy)++; *cx=0;
! 1439: } else {
! 1440: beep();
! 1441: }
! 1442: }
! 1443: break;
! 1444: case 'D': /* KEY_LEFT */
! 1445: if(*cx>0) {
! 1446: (*cx)--;
! 1447: } else {
! 1448: if(*cy>0) {
! 1449: (*cy)--;
! 1450: *cx=strlen(sbuf_pp[*cy]);
! 1451: if (*cx==EDIT_WIDTH) (*cx)--;
! 1452: } else {
! 1453: beep();
! 1454: }
! 1455: }
! 1456: break;
! 1457: default: beep(); return; break;
! 1458: }
! 1459: echo(); move(*cy,*cx); refresh(); noecho();
! 1460: }
! 1461:
! 1462: void handle_error (unsigned char c,char** sbuf_pp,int cx,int cy)
! 1463: {
! 1464: beep();
! 1465: }
! 1466:
! 1467: /*FIXME Slower than whale shit*/
! 1468: void insert_character(unsigned char c,char** sbuf_pp,int *cx,int *cy)
! 1469: {
! 1470: int sx=*cx,sy=*cy;
! 1471: unsigned char temp;
! 1472: while(c!='\0') {
! 1473: if (sx == EDIT_WIDTH) {
! 1474: sx=0;sy++;
! 1475: if (sy == EDIT_HEIGHT) {
! 1476: sy--;sx=EDIT_WIDTH;c='\0';break;
! 1477: }
! 1478: }
! 1479: echo(); ADDCH(c); noecho();
! 1480: temp=sbuf_pp[sy][sx];
! 1481: sbuf_pp[sy][sx]=c;
! 1482: c=temp;
! 1483: sx++;
! 1484: }
! 1485: sbuf_pp[sy][sx]=c;
! 1486: (*cx)++;
! 1487: if (*cx == EDIT_WIDTH) {
! 1488: *cx=0;(*cy)++;
! 1489: if (*cy == EDIT_HEIGHT) {
! 1490: (*cy)--;*cx=EDIT_WIDTH-1;
! 1491: }
! 1492: }
! 1493: move(*cy,*cx);refresh();
! 1494: }
! 1495:
! 1496: int handle_keystrokes_editor(char** sbuf_pp)
! 1497: {
! 1498: int done = 0, forget = 0, cx=0,cy=0;
! 1499: unsigned char c,ca,cb;
! 1500:
! 1501: while (!done) {
! 1502: move(cy,cx);refresh();
! 1503: c=getch();
! 1504: switch(c) {
! 1505: case BS: case DEL:
! 1506: remove_character(sbuf_pp,&cx,&cy);
! 1507: break;
! 1508: case CR: case LF:
! 1509: break_line(sbuf_pp,&cx,&cy);
! 1510: break;
! 1511: case ESC:
! 1512: ca=getch();cb=getch();
! 1513: handle_esc(ca,cb,sbuf_pp,&cx,&cy);
! 1514: break;
! 1515: case 5: /*ctrl-e*/
! 1516: done=1;
! 1517: break;
! 1518: case 6: /*ctrl-f*/
! 1519: done=1;
! 1520: forget=1;
! 1521: break;
! 1522: case 12:
! 1523: refresh_editor(sbuf_pp,cx,cy);
! 1524: break;
! 1525: default:
! 1526: if (c < 32 || c>126) {
! 1527: handle_error(c,sbuf_pp,cx,cy);
! 1528: } else {
! 1529: insert_character(c,sbuf_pp,&cx,&cy);
! 1530: }
! 1531: break;
! 1532: }
! 1533: }
! 1534: return forget;
! 1535: }
! 1536:
! 1537: int editor(char*** sbuf_pp)
! 1538: {
! 1539: init_editor(sbuf_pp);
! 1540: return handle_keystrokes_editor(*sbuf_pp);
! 1541: }
! 1542:
! 1543:
! 1544: int
! 1545: answer_subjective(student_number,set,section,prob)
! 1546: char *student_number;
! 1547: int set;
! 1548: int *section;
! 1549: int prob;
! 1550: {
! 1551: int i,length;
! 1552: char date_str[DATE_LENGTH];
! 1553: char **sbuf_pp,answer[(EDIT_HEIGHT*(EDIT_WIDTH+1))+1];
! 1554: char submissions_str[(EDIT_HEIGHT*(EDIT_WIDTH+1))+MAX_BUFFER_SIZE];
! 1555: time_t curtime;
! 1556:
! 1557: time(&curtime);
! 1558: if( capa_check_date(CHECK_DUE_DATE,student_number,*section,set) > 0 ) {
! 1559: capa_get_date(CHECK_DUE_DATE,student_number,*section,set,date_str);
! 1560: sprintf(answer,"Sorry, the due date was: %s",date_str);
! 1561: move(20,1); clrtobot(); addstr(answer); mypause(23,1);
! 1562: return 0;
! 1563: }
! 1564:
! 1565: if (editor(&sbuf_pp)) { return 0; }
! 1566:
! 1567: answer[0]='\0';
! 1568: for(i=0;i<EDIT_HEIGHT;i++) {
! 1569: if (strlen(sbuf_pp[i]) > 0) {
! 1570: strcat(answer,sbuf_pp[i]);
! 1571: length=strlen(answer);
! 1572: answer[length]='\n';
! 1573: answer[length+1]='\0';
! 1574: }
! 1575: capa_mfree((char *)sbuf_pp[i]);
! 1576: }
! 1577: capa_set_subjective(set,prob,student_number,answer);
! 1578: sprintf(submissions_str,"%d\t%s\t",prob,answer);
! 1579: log_submissions(student_number,set,submissions_str);
! 1580: capa_mfree((char *)sbuf_pp);
! 1581: return 1;
! 1582: }
! 1583:
! 1584: void set_entry_tries(int *tried, char *tries, int num, int num_questions) {
! 1585: if((tried[num] >=0) && (tried[num] <= TRY_BOUND) ) {
! 1586: if(tried[num] < 10 ) {
! 1587: tries[3*num] = ' ';
! 1588: tries[3*num+1] = tried[num] + '0';
! 1589: if(num < num_questions-1) tries[3*num+2] = ',';
! 1590: } else {
! 1591: tries[3*num] = (int)(tried[num]/10) + '0';
! 1592: tries[3*num+1] = (tried[num] % 10) + '0';
! 1593: if(num < num_questions-1) tries[3*num+2] = ',';
! 1594: }
! 1595: } else {
! 1596: tries[3*num] = ' ';
! 1597: tries[3*num+1] = 1 + '0';
! 1598: if(num < num_questions-1) tries[3*num+2] = ',';
! 1599: }
! 1600: }
! 1601:
! 1602: /* -------------------------------------------------------------------------- */
! 1603: /* LET THE USER ANSWER THE CURRENT PROBLEM SET QUESTIONS */
! 1604: /* -------------------------------------------------------------------------- */
! 1605: void
! 1606: try_set(student_number,set,section)
! 1607: char *student_number;
! 1608: int set;
! 1609: int *section;
! 1610: {
! 1611: char a_student_number[MAX_STUDENT_NUMBER+1];
! 1612: time_t curtime;
! 1613: T_header header;
! 1614: Problem_t *first_problem, *p;
! 1615: T_entry entry;
! 1616: char answer[256], *a_str, **ans_strs;
! 1617: int num, offset, num_questions, start_from, leng;
! 1618: char *log_string,submissions_str[MAX_BUFFER_SIZE];
! 1619: int *tried,answered;
! 1620: int scr_idx=1, display=1, second_scr, canAnswer;
! 1621: int usr_command, whereto, allow_hint=0, ex=0;
! 1622: char u_input[64], date_str[DATE_LENGTH], one_line[81];
! 1623: int log_char, i, j, allow_n, allow_p, allow_subj;
! 1624:
! 1625: strncpy(a_student_number,student_number,MAX_STUDENT_NUMBER+1);
! 1626: time(&curtime); /* Is due date past? */
! 1627: /* ---------------------------------------- check due date */
! 1628: #ifndef NO_DATE_CHECK
! 1629: /* ===> if ( compare_datetime(curtime,header.due_date) > 0) { */
! 1630: if( capa_check_date(CHECK_DUE_DATE,student_number,*section,set) > 0 ) {
! 1631: capa_get_date(CHECK_DUE_DATE,student_number,*section,set,date_str);
! 1632: sprintf(answer," Sorry, the due date was: %s",date_str);
! 1633: move(17,1); clrtoeol(); mvaddstr(17,15,answer); mypause(19,17);
! 1634: return;
! 1635: }
! 1636: #ifdef LOGIN_DBUG
! 1637: fprintf(dfp,"Tryset():(sec=%d,set=%d)[%s]\n",*section,set,date_str); fflush(dfp);
! 1638: #endif /* LOGIN_DBUG */
! 1639: #endif /* NO_DATE_CHECK */
! 1640:
! 1641: offset=capa_get_entry(&entry,student_number,set);
! 1642: capa_get_header(&header,set);
! 1643: if (offset<0) offset = -offset; /* newly created entry */
! 1644:
! 1645: #ifdef LOGIN_DBUG
! 1646: fprintf(dfp,"P set=%d,SN=%s,ANS=%s,TRY=%s\n",set,a_student_number,entry.answers,entry.tries); fflush(dfp);
! 1647: #endif
! 1648: num = capa_parse(set,&first_problem,a_student_number,&num_questions,NULL);
! 1649:
! 1650: #ifdef LOGIN_DBUG
! 1651: fprintf(dfp,"ParseSource:=%d\n",num); fflush(dfp);
! 1652: #endif /* LOGIN_DBUG */
! 1653:
! 1654: /* DEBUGGING: make sure num_questions is plausible */
! 1655: if (num_questions>1000 || num_questions<=0) properly_logout(student_number);
! 1656:
! 1657: start_from=ask_what_prob(num_questions,entry.answers);
! 1658:
! 1659: /* initialize log string to all '-' */
! 1660: tried = (int *)capa_malloc(num_questions+1,sizeof(int));
! 1661: log_string = (char *)capa_malloc(num_questions+1,sizeof(char));
! 1662: for (num=0; num<num_questions; num++) {
! 1663: log_string[num]='-';
! 1664: sscanf(entry.tries + 3*num,"%d,",&(tried[num]) );
! 1665: }
! 1666: log_string[num_questions]=0;
! 1667: capa_set_login_time(student_number,set);
! 1668: for (num=0,p=first_problem; p; ){
! 1669: if( start_from > 1 ) {
! 1670: num=start_from-1;
! 1671: for (p=first_problem; start_from > 1 && p->next; start_from--)
! 1672: p=p->next;
! 1673: start_from = 0;
! 1674: }
! 1675: if (display) {
! 1676: /* DISPLAY QUESTION */
! 1677: CLEAR();
! 1678: second_scr = display_prob_scr(p->question,scr_idx);
! 1679: allow_subj = 0;
! 1680: if( p->ans_type == ANSWER_IS_SUBJECTIVE ) {
! 1681: allow_subj = 1;
! 1682: move(A_ROW,A_COL); clrtoeol();
! 1683: mvaddstr(A_ROW,A_COL,"Enter :A to answer subjective question");
! 1684: }
! 1685: mvaddstr(S_ROW,0,"OPTION/ANSWER");
! 1686: mvaddstr(O_ROW,0,"Options :M = Main Menu :7 = go to # 7");
! 1687: allow_n = allow_p = 0;
! 1688: if( second_scr && (scr_idx == 1) ) {
! 1689: mvaddstr(O_ROW,E_COL,":N = Next screen");
! 1690: allow_n=1;
! 1691: }
! 1692: if( second_scr && (scr_idx == 2) ) {
! 1693: mvaddstr(O_ROW,E_COL,":P = Prev screen");
! 1694: allow_p=1;
! 1695: }
! 1696:
! 1697: mvaddstr(O_ROW,R_COL,"RETURN = Enter/Execute");
! 1698:
! 1699: if (g_inhibit_response ) {
! 1700: canAnswer = show_prior_inhibited_response(p,header.partial_credit[num],entry.answers[num],tried[num],&allow_hint);
! 1701: } else {
! 1702: canAnswer = show_prior_response(p,header.partial_credit[num],entry.answers[num],tried[num],&allow_hint);
! 1703: }
! 1704:
! 1705: }
! 1706: mvaddstr(X_ROW,X_COL,":X = eXit");
! 1707:
! 1708: /* <= */
! 1709:
! 1710:
! 1711:
! 1712: get_xinput(S_ROW,A_COL,u_input,U_ANS_CHAR);
! 1713: display=0; usr_command=C_DONTCARE;
! 1714: /* DEFAULT ACTIONS on empty input */
! 1715: if(!strlen(u_input)) { usr_command = (p->next? C_FORWARD : C_MENU); } else {
! 1716: if( u_input[0] == ':' ) {
! 1717: switch(toupper( u_input[1] )) {
! 1718: case 'H': if( allow_hint ) { usr_command=C_HINT; } break;
! 1719: case 'M': usr_command=C_MENU; break;
! 1720: case 'N': if( allow_n ) { usr_command=C_NEXTSCR; } break;
! 1721: case 'P': if( allow_p ) { usr_command=C_PREVSCR; } break;
! 1722: case 'X': usr_command=C_EXIT; break;
! 1723: case 'A': if( allow_subj ) { usr_command=C_SUBJANS; } break;
! 1724: default : sscanf(u_input,":%d",&whereto);
! 1725: if(whereto >0 && whereto <= num_questions) usr_command=C_JUMP;
! 1726: break;
! 1727: }
! 1728: } else { /* user entered some answer */
! 1729: if( p->ans_op == ANS_AND ) {
! 1730: if(canAnswer) { usr_command=C_ANSWER;
! 1731: ans_strs = (char **)capa_malloc(sizeof(char *), p->ans_cnt);
! 1732: ans_strs[0] = (char *)capa_malloc(strlen(u_input)+1,1);
! 1733: strcpy(ans_strs[0],u_input);
! 1734: for(i=1;i<p->ans_cnt;i++) {
! 1735: mvaddstr(A_ROW,A_COL," ");
! 1736: mvaddstr(A_ROW,A_COL,ans_strs[i-1]);
! 1737: sprintf(one_line, " Entering answer %3d of %3d ", i+1,p->ans_cnt);
! 1738: mvaddstr(A_ROW,S_COL,one_line);
! 1739: mvaddstr(S_ROW,A_COL," ");
! 1740: get_xinput(S_ROW,A_COL,u_input,U_ANS_CHAR);
! 1741: ans_strs[i] = (char *)capa_malloc(strlen(u_input)+1,1);
! 1742: strcpy(ans_strs[i],u_input);
! 1743:
! 1744: }
! 1745:
! 1746: /* now in ans_strs[][] are user inputs */
! 1747:
! 1748: }
! 1749: } else { /* one answer or ANS_OR */
! 1750: ans_strs = (char **)capa_malloc(sizeof(char *), 1);
! 1751: ans_strs[0] = (char *)capa_malloc(strlen(u_input)+1,1);
! 1752: strcpy(ans_strs[0], u_input);
! 1753: if(canAnswer) { usr_command=C_ANSWER;
! 1754: mvaddstr(S_ROW,A_COL," ");
! 1755: mvaddstr(A_ROW,A_COL," ");
! 1756: mvaddstr(A_ROW,A_COL,ans_strs[0]); }
! 1757: }
! 1758: } /* end if u_input[0] == ':' */
! 1759: } /* end if !strlen(u_input) */
! 1760:
! 1761:
! 1762:
! 1763:
! 1764:
! 1765: /* PROCESS USER COMMAND */
! 1766: switch(usr_command) {
! 1767: case C_FORWARD: /* Forwards */
! 1768: if (p->next) {
! 1769: p=p->next; num++;
! 1770: display=1; allow_hint=0; scr_idx=1;
! 1771: } else
! 1772: mvaddstr(X_ROW,R_COL,"RETURN = Main Menu ");
! 1773: break;
! 1774: case C_NEXTSCR: scr_idx = 2; display=1;
! 1775: break;
! 1776: case C_PREVSCR: scr_idx = 1; display=1;
! 1777: break;
! 1778: case C_EXIT: /* Exit */
! 1779: ex=1; p=0; break;
! 1780: case C_MENU: /* Return to main menu */
! 1781: p=0; break;
! 1782: case C_HINT: /* Hint */
! 1783: if (! p->hint) break;
! 1784: display_hint(p->hint);
! 1785: display=1;
! 1786: break;
! 1787: case C_ANSWER: /* Answer question */
! 1788: {
! 1789: if(p->ans_type== ANSWER_IS_SUBJECTIVE) {
! 1790: move(A_ROW,A_COL); clrtoeol();
! 1791: mvaddstr(A_ROW,A_COL,"Enter :A to answer subjective question");
! 1792: capa_mfree(ans_strs[0]);
! 1793: break;
! 1794: }
! 1795: if( p->ans_op == ANS_AND ) {
! 1796: leng = 0;
! 1797: for(i=0;i<p->ans_cnt;i++) {
! 1798: leng += (strlen((char *)ans_strs[i]) + 2);
! 1799: }
! 1800: a_str = (char *)capa_malloc(leng+1,1);
! 1801: a_str[0]=0;
! 1802: strcat(a_str,ans_strs[0]);
! 1803: if ( is_all_ws(ans_strs[0]) ) break;
! 1804: trim_response_ws(ans_strs[0]);
! 1805: for(i=1;i<p->ans_cnt;i++) {
! 1806: strcat(a_str,"\t");
! 1807: strcat(a_str,ans_strs[i]);
! 1808: if ( is_all_ws(ans_strs[i]) ) break;
! 1809: trim_response_ws(ans_strs[i]);
! 1810: }
! 1811: if (i < p->ans_cnt) {
! 1812: display=1; /*handle early breaks out of the*/
! 1813: break; /*loop which mean typed only ws */
! 1814: }
! 1815: } else { /* only one answer */
! 1816: leng = (strlen((char *)ans_strs[0]) + 2);
! 1817: a_str = (char *)capa_malloc(leng+1,1);
! 1818: a_str[0]=0;
! 1819: strcat(a_str,ans_strs[0]);
! 1820: if ( is_all_ws(ans_strs[0]) ) break;
! 1821: trim_response_ws(ans_strs[0]);
! 1822: }
! 1823:
! 1824: sprintf(submissions_str,"%d\t%s\t",num+1,a_str);
! 1825: log_submissions(student_number,set,submissions_str);
! 1826:
! 1827: {
! 1828: int cnt=((p->ans_op==ANS_AND)?p->ans_cnt:1);
! 1829: if (g_inhibit_response) {
! 1830: canAnswer = give_inhibited_response(p, ans_strs,cnt,
! 1831: &(tried[num]),&log_char);
! 1832: } else {
! 1833: canAnswer = give_response(p, ans_strs,cnt, &(tried[num]),&log_char);
! 1834: }
! 1835: }
! 1836: if( p->ans_op == ANS_AND ) {
! 1837: for(i=0;i<p->ans_cnt;i++) {
! 1838: capa_mfree( (char *)ans_strs[i] );
! 1839: }
! 1840:
! 1841: } else { /* there is only one user answer */
! 1842: capa_mfree( (char *)ans_strs[0] );
! 1843:
! 1844: }
! 1845: capa_mfree((char *)ans_strs);
! 1846: capa_mfree( (char *)a_str );
! 1847:
! 1848: if (p->hint &&
! 1849: (
! 1850: (p->show_hint<=tried[num])||
! 1851: (log_char == 'y') ||
! 1852: (log_char == 'Y')
! 1853: )
! 1854: ){
! 1855: allow_hint=1;
! 1856: mvaddstr(X_ROW,H_COL,":H = Show Hint");
! 1857: }
! 1858: switch(log_char) {
! 1859: case 'U': case 'u': case 'S':
! 1860: entry.answers[num]='N'; break;
! 1861: case 'Y': allow_hint=1; mvaddstr(X_ROW,H_COL,":H = Show Hint"); /* fall through here */
! 1862: default: entry.answers[num]=log_char; break;
! 1863: }
! 1864: log_string[num]=log_char;
! 1865:
! 1866: log_attempt(student_number,set,*section,log_string);
! 1867: /* for (i=0; i<num_questions; i++) { log_string[i] = '-' ; } */
! 1868: set_entry_tries(tried,entry.tries,num,num_questions);
! 1869: log_string[num]='-';
! 1870: /* ------------------------------ check due date */
! 1871: time(&curtime);
! 1872: /* ===> if (compare_datetime(curtime,header.due_date) > 0) { */
! 1873: if( capa_check_date(CHECK_DUE_DATE,student_number,*section,set) > 0 ) {
! 1874: capa_get_date(CHECK_DUE_DATE,student_number,*section,set,date_str);
! 1875: sprintf(answer,"Sorry, the due date was: %s",date_str);
! 1876: move(20,1); clrtobot(); addstr(answer); mypause(23,1);
! 1877: } else {
! 1878: capa_set_entry(&entry,student_number,set,offset);
! 1879: }
! 1880: } break;
! 1881: case C_JUMP: /* Jump to specific question number */
! 1882: num=whereto-1;
! 1883: for (p=first_problem; whereto > 1 && p->next; whereto--)
! 1884: p=p->next;
! 1885: display=1; allow_hint=0; scr_idx=1;
! 1886: break;
! 1887: case C_SUBJANS:
! 1888: answered=answer_subjective(student_number,set,section,num+1);
! 1889: if (answered) {
! 1890: tried[num]++;
! 1891: if (p->hint && ((p->show_hint<=tried[num]))) { allow_hint=1; }
! 1892: entry.answers[num]='0';
! 1893: log_string[num]='A';
! 1894: log_attempt(student_number,set,*section,log_string);
! 1895: log_string[num]='-';
! 1896: set_entry_tries(tried,entry.tries,num,num_questions);
! 1897: capa_set_entry(&entry,student_number,set,offset);
! 1898: }
! 1899: display=1;
! 1900: break;
! 1901: case C_DONTCARE: break;
! 1902: }
! 1903: }
! 1904: for (i=0,j=0, num=0; num<num_questions; num++) {
! 1905: j = j + (header.weight[num] - '0');
! 1906: if((entry.answers[num]=='Y') || (entry.answers[num]=='y'))
! 1907: i = i + (header.weight[num] - '0');
! 1908: if( entry.answers[num] >= '0' && entry.answers[num] <= '9' ) {
! 1909: i = i + (entry.answers[num] - '0');
! 1910: }
! 1911: if((entry.answers[num]=='E') || (entry.answers[num]=='e'))
! 1912: j = j - (header.weight[num] - '0');
! 1913: if((tried[num] >=0) && (tried[num] <= TRY_BOUND) ) {
! 1914: if(tried[num] < 10 ) {
! 1915: entry.tries[3*num] = ' ';
! 1916: entry.tries[3*num+1] = tried[num] + '0';
! 1917: if(num < num_questions-1) entry.tries[3*num+2] = ',';
! 1918: } else {
! 1919: entry.tries[3*num] = (int)(tried[num]/10) + '0';
! 1920: entry.tries[3*num+1] = (tried[num] % 10) + '0';
! 1921: if(num < num_questions-1) entry.tries[3*num+2] = ',';
! 1922: }
! 1923: } else {
! 1924: entry.tries[3*num] = ' ';
! 1925: entry.tries[3*num+1] = 1 + '0';
! 1926: if(num < num_questions-1) entry.tries[3*num+2] = ',';
! 1927: }
! 1928: }
! 1929: capa_mfree(header.weight);
! 1930: capa_mfree(header.partial_credit);
! 1931:
! 1932: sprintf(answer,"Your score for this set is now: %d/%d",i,j);
! 1933: move(20,1); clrtobot(); addstr(answer); mypause(23,1);
! 1934: /* ------- original code , should check due date before save it
! 1935:
! 1936: time(&curtime);
! 1937: if (compare_datetime(curtime,header.due_date) > 0) {
! 1938: if( capa_check_date(CHECK_DUE_DATE,*section,set) > 0 ) {
! 1939: need to deal with due_date
! 1940: sprintf(answer,"Sorry, the due date was: %s",header.due_date);
! 1941: move(20,1); clrtobot(); addstr(answer); mypause(23,1);
! 1942: } else {
! 1943: sprintf(answer,"Your score for this set is now: %d/%d",i,j);
! 1944: move(20,1); clrtobot(); addstr(answer); mypause(23,1);
! 1945:
! 1946: capa_set_entry(&entry,student_number,set,offset);
! 1947: }
! 1948: ------ */
! 1949: /* FREE UP MALLOC'ED SPACE (VERY IMPORTANT) */
! 1950: capa_mfree(entry.answers);
! 1951: capa_mfree(entry.tries);
! 1952: free_problems(first_problem);
! 1953: /* log_attempt(student_number,set,*section,log_string); */
! 1954: capa_mfree(log_string);
! 1955: capa_mfree((char*)tried);
! 1956: if (ex) properly_logout(student_number);
! 1957:
! 1958: }
! 1959:
! 1960: #define COL_ONE 1
! 1961: #define COL_TWO 17
! 1962: #define COL_THREE 34
! 1963: #define COL_FOUR 43
! 1964: #define COL_FIVE 69
! 1965:
! 1966: /* ------------------------------------------------------------------------- */
! 1967: /* REVIEW PREVIOUS PROBLEM SETS */
! 1968: /* ------------------------------------------------------------------------- */
! 1969: void /* RETURNS: (nothing) */
! 1970: view_previous(student_number,set,section) /* ARGUMENTS: */
! 1971: char *student_number; /* Student number */
! 1972: int set; /* Set number */
! 1973: int *section; /* Section number */
! 1974: { /* LOCAL VARIABLES: */
! 1975: T_entry entry; /* Database entry */
! 1976: Problem_t *first_problem, /* Pointer to first problem */
! 1977: *problem; /* Previous problem */
! 1978: int num_questions, /* Total # of questions */
! 1979: ex=0, /* Exit system flag */
! 1980: display=1, /* Redraw flag */
! 1981: usr_command,
! 1982: whereto,
! 1983: allow_hint=0, allow_explain=0;
! 1984: int num; /* Temporary variable */
! 1985: char buf[4], /* Command input buffer */
! 1986: aLine[MAX_BUFFER_SIZE];
! 1987: T_header header; /* Set header */
! 1988: time_t curtime; /* Current time */
! 1989: double upper_ans;
! 1990: char fmt_ans[ANSWER_STRING_LENG], goto_str[ANSWER_STRING_LENG],
! 1991: tmp_str[ANSWER_STRING_LENG];
! 1992: int scr_idx=1, second_scr, allow_n, allow_p;
! 1993:
! 1994: /* QUERY USER FOR SET */
! 1995: move(15,5); /* deleteln(); */
! 1996: addstr(" Which set would you like to view?");
! 1997: mvaddstr(16,15, "Enter a set number and press ENTER/RETURN");
! 1998: move(17,1); clrtoeol(); /* erase Enter a command ... */
! 1999: do { get_input(15,51,buf,3); } while(!strlen(buf));
! 2000: sscanf(buf,"%d",&num);
! 2001: if (num<1 || num>set) {
! 2002: move(17,5); clrtoeol();
! 2003: mvaddstr(17,15," Error: Invalid previous set number\n");
! 2004: mypause(19,17); return;
! 2005: }
! 2006: /* ------------------------------------ answer date */
! 2007: time(&curtime);
! 2008: /* ===> if (compare_datetime(curtime,header.answer_date) < 0) { */
! 2009: if ( capa_check_date(CHECK_ANS_DATE,student_number,*section,num) < 0 ) {
! 2010: move(16,1); clrtoeol();
! 2011: move(17,5); clrtoeol();
! 2012: mvaddstr(17,15," Answers are not yet available\n"); mypause(19,17); return;
! 2013: }
! 2014:
! 2015: /* LOAD IN THE INFO NEEDED */
! 2016: capa_get_header(&header,num);
! 2017: capa_get_entry(&entry,student_number,num);
! 2018: capa_parse(num,&first_problem,student_number,&num_questions,NULL);
! 2019: sprintf(goto_str,"#=go to problem #, [%d problems]", num_questions);
! 2020: for (num=0,problem=first_problem; problem; ) {
! 2021: if (display) {
! 2022: allow_hint = allow_explain=0;
! 2023: allow_n = allow_p = 0;
! 2024: CLEAR();
! 2025: second_scr = display_prob_scr(problem->question,scr_idx);
! 2026: if( problem->ans_type == ANSWER_IS_FLOAT ) {
! 2027: upper_ans = (double)atof(problem->answer);
! 2028: sprintf(fmt_ans, problem->ans_fmt, upper_ans);
! 2029: } else {
! 2030: sprintf(fmt_ans, "%s", problem->answer);
! 2031: }
! 2032: if( problem->ans_unit ) {
! 2033: sprintf(tmp_str, "Answer: %s %s",fmt_ans,problem->unit_str);
! 2034: } else {
! 2035: sprintf(tmp_str, "Answer: %s",fmt_ans);
! 2036: }
! 2037: mvaddstr(S_ROW,COL_ONE,tmp_str);
! 2038:
! 2039: switch(entry.answers[num]) {
! 2040: case 'Y': mvaddstr(S_ROW,COL_FOUR,"CORRECT "); break;
! 2041: case 'y': mvaddstr(S_ROW,COL_FOUR,"HANDIN CORRECT "); break;
! 2042: case '-': mvaddstr(S_ROW,COL_FOUR,"UNANSWERED "); break;
! 2043: case 'e': mvaddstr(S_ROW,COL_FOUR,"EXCUSED "); break;
! 2044: case 'E': mvaddstr(S_ROW,COL_FOUR,"EXCUSED "); break;
! 2045: case 'n': mvaddstr(S_ROW,COL_FOUR,"HANDIN INCORRECT"); break;
! 2046: case 'N': mvaddstr(S_ROW,COL_FOUR,"INCORRECT "); break;
! 2047: default : if(entry.answers[num] >= '0' && entry.answers[num] <= '9') {
! 2048: sprintf(aLine,"HAND-GRADED %c/%c ",entry.answers[num],
! 2049: header.weight[num]);
! 2050: mvaddstr(S_ROW,COL_FOUR,aLine);
! 2051: }
! 2052: break;
! 2053: }
! 2054: mvaddstr(S_ROW,COL_FIVE,"OPTION:");
! 2055:
! 2056: mvaddstr(O_ROW,COL_ONE,"M=Main menu");
! 2057: if( second_scr && scr_idx == 1) {
! 2058: mvaddstr(O_ROW,COL_TWO,"N=Next screen");
! 2059: allow_n = 1;
! 2060: }
! 2061: if( second_scr && scr_idx == 2) {
! 2062: mvaddstr(O_ROW,COL_TWO,"P=Prev screen");
! 2063: allow_p = 1;
! 2064: }
! 2065: mvaddstr(O_ROW,COL_THREE,"X=eXit");
! 2066: mvaddstr(O_ROW,COL_FOUR, "RETURN=Enter/Execute");
! 2067: if ( problem->hint &&
! 2068: (
! 2069: (problem->show_hint <= problem->tries) ||
! 2070: (entry.answers[num] == 'Y') ||
! 2071: (entry.answers[num] == 'y')
! 2072: )
! 2073: ) {
! 2074: allow_hint=1; mvaddstr(O_ROW,COL_FIVE,"H=Hint");
! 2075: }
! 2076: mvaddstr(X_ROW,COL_ONE,goto_str);
! 2077: if (problem->next)
! 2078: mvaddstr(X_ROW,COL_FOUR,"RETURN=next problem");
! 2079: else
! 2080: mvaddstr(X_ROW,COL_FOUR,"RETURN=main menu ");
! 2081: if ( problem->explain ) { allow_explain=1; mvaddstr(X_ROW,COL_FIVE,"E=Explain"); }
! 2082:
! 2083: }
! 2084: get_input(S_ROW,COL_FIVE+7,buf,3);
! 2085: display=0; usr_command=C_DONTCARE;
! 2086: /* DEFAULT ACTIONS on empty input */
! 2087: if(!strlen(buf)) { usr_command = (problem->next? C_FORWARD : C_MENU); } else {
! 2088: switch(toupper(buf[0])) {
! 2089: case 'X': usr_command=C_EXIT; break;
! 2090: case 'M': usr_command=C_MENU; break;
! 2091: case 'H': usr_command=C_HINT; break;
! 2092: case 'E': usr_command=C_EXPLAIN; break;
! 2093: case 'N': if( allow_n ) { usr_command=C_NEXTSCR; } break;
! 2094: case 'P': if( allow_p ) { usr_command=C_PREVSCR; } break;
! 2095: default : sscanf(buf,"%d",&whereto);
! 2096: if(whereto >0 && whereto <= num_questions) usr_command=C_JUMP;
! 2097: break;
! 2098: }
! 2099: }
! 2100:
! 2101:
! 2102: /* PROCESS USER COMMAND */
! 2103: switch(usr_command) {
! 2104: case C_FORWARD: /* FORWARDS ONE */
! 2105: if (problem->next) {
! 2106: problem=problem->next; display=1; scr_idx = 1; num++;
! 2107: } else
! 2108: mvaddstr(X_ROW,COL_FOUR,"RETURN=main menu ");
! 2109: break;
! 2110: case C_HINT: /* HINT */
! 2111: if(allow_hint) {
! 2112: display_hint(problem->hint);
! 2113: display=1;
! 2114: allow_hint = 0;
! 2115: }
! 2116: break;
! 2117: case C_EXPLAIN: /* Explain */
! 2118: if(allow_explain) {
! 2119: display_hint(problem->explain); display=1;
! 2120: allow_explain=0;
! 2121: }
! 2122: break;
! 2123: case C_NEXTSCR: scr_idx = 2; display=1;
! 2124: break;
! 2125: case C_PREVSCR: scr_idx = 1; display=1;
! 2126: break;
! 2127: case C_EXIT: /* EXIT SYSTEM */
! 2128: ex=1; problem=0; break;
! 2129:
! 2130: case C_MENU: /* RETURN TO MAIN MENU */
! 2131: problem=0; break;
! 2132:
! 2133: case C_JUMP: /* JUMP TO SPECIFIC PROBLEM # */
! 2134: num=whereto-1;
! 2135: for (problem=first_problem; whereto > 1 && problem->next; whereto--)
! 2136: problem=problem->next;
! 2137: display=1;
! 2138: scr_idx = 1;
! 2139: break;
! 2140: case C_TIME: break;
! 2141: case C_DONTCARE: break;
! 2142: }
! 2143: }
! 2144:
! 2145: /* FREE UP MALLOC'ED SPACE - VERY IMPORTANT */
! 2146: capa_mfree(header.weight);
! 2147: capa_mfree(header.partial_credit);
! 2148: capa_mfree(entry.answers);
! 2149: capa_mfree(entry.tries);
! 2150: free_problems(first_problem);
! 2151:
! 2152: if (ex) properly_logout(student_number);
! 2153: }
! 2154:
! 2155: /* -------------------------------------------------------------------------- */
! 2156: /* DISPLAY HELP SCREEN */
! 2157: /* -------------------------------------------------------------------------- */
! 2158: void /* RETURNS: (nothing) */
! 2159: display_help() /* ARGUMENTS: (none) */
! 2160: { /* LOCAL VARIABLES: */
! 2161: FILE *fp; /* Welcome file pointer */
! 2162: char buf[255]; /* Input buffer */
! 2163:
! 2164: CLEAR();
! 2165: if ((fp=fopen("help.msg","r"))!=NULL) {
! 2166: while (fgets(buf,255,fp)) addstr(buf);
! 2167: fclose(fp);
! 2168: }
! 2169: mypause(22,20);
! 2170: }
! 2171:
! 2172:
! 2173: /* A class directory must have */
! 2174: /* records/ */
! 2175: /* */
! 2176: /* returns: 0 structure is correct, but no set.db files */
! 2177: /* -1 structure is not correct */
! 2178: /* >=1 the last set.db */
! 2179:
! 2180: int
! 2181: check_class_get_set(dir_path) char *dir_path;
! 2182: {
! 2183: char f_name[1024];
! 2184: int set;
! 2185:
! 2186: if( capa_access(dir_path, F_OK) == 0 ) { /* class dir exists */
! 2187: sprintf(f_name,"%s/records",dir_path);
! 2188: if( capa_access(f_name, F_OK) == 0 ) { /* class/records dir exists */
! 2189: for(set = 1; ; set++ ) {
! 2190: sprintf(f_name,"%s/records/set%d.db",dir_path,set);
! 2191: if(capa_access(f_name, F_OK) == -1 ) break;
! 2192: }
! 2193: set--;
! 2194: } else {
! 2195: set = -1;
! 2196: }
! 2197: } else {
! 2198: set = -1;
! 2199: }
! 2200: return (set);
! 2201: }
! 2202: /* -------------------------------------------------------------------------- */
! 2203: /* Get Exam and Quiz Path */
! 2204: /* return 0, 1, 2, 3 */
! 2205: /* -------------------------------------------------------------------------- */
! 2206: int
! 2207: check_exam_quiz_f()
! 2208: {
! 2209: char buf[MAX_BUFFER_SIZE];
! 2210: int result = 0, configResult=0;
! 2211:
! 2212: #ifdef LOGIN_DBUG
! 2213: fprintf(dfp,"CHECK EXAM Access() success,and open(),%s\n",buf); fflush(dfp);
! 2214: #endif
! 2215: configResult=read_capa_config("exam_path",buf);
! 2216: if (configResult != 0 && configResult != -1) {
! 2217: Exam_set = check_class_get_set(buf);
! 2218: if(Exam_set > 0 ) {
! 2219: result = 1;
! 2220: sprintf(Exam_path,buf);
! 2221: }
! 2222: }
! 2223: #ifdef LOGIN_DBUG
! 2224: fprintf(dfp,"CHECK EXAM = %d,%s\n", result,Exam_path); fflush(dfp);
! 2225: #endif
! 2226: configResult=read_capa_config("quiz_path",buf);
! 2227: if (configResult != 0 && configResult != -1) {
! 2228: Quiz_set = check_class_get_set(buf);
! 2229: if(Quiz_set > 0 ) {
! 2230: result = (result | 2);
! 2231: sprintf(Quiz_path,buf);
! 2232: }
! 2233: }
! 2234:
! 2235: return (result);
! 2236: }
! 2237:
! 2238: /* -------------------------------------------------------------------------- */
! 2239: /* DISPLAY MAIN MENU */
! 2240: /* -------------------------------------------------------------------------- */
! 2241: void /* RETURNS: (nothing) */
! 2242: display_menu(student, exam_f, quiz_f)
! 2243: T_student *student;
! 2244: int exam_f, quiz_f;
! 2245: {
! 2246: char buff[MAX_BUFFER_SIZE];
! 2247: int c_y,configResult,term_summary_button=1;
! 2248:
! 2249: configResult=read_capa_config("term_summary_button",buff);
! 2250: if (configResult != 0 && configResult != -1 ) {
! 2251: if (strcasecmp(buff,"no")==0) {
! 2252: term_summary_button=0;
! 2253: }
! 2254: }
! 2255:
! 2256: CLEAR();
! 2257:
! 2258: mvaddstr(1,10,student->s_nm);
! 2259: sprintf(buff,"Section: %d",student->s_sec);
! 2260: mvaddstr(1,50,buff);
! 2261:
! 2262: mvaddstr( 4,25," MAIN MENU"); c_y = 6;
! 2263: mvaddstr( c_y,25,"H=Help"); c_y++;
! 2264: if (term_summary_button) { mvaddstr( c_y,25,"S=Summary"); c_y++; }
! 2265: mvaddstr( c_y,25,"T=Try set"); c_y++;
! 2266: mvaddstr( c_y,25,"V=View previous set"); c_y++;
! 2267: if(exam_f) { mvaddstr( c_y,25,"E=view Exam summary"); c_y++; }
! 2268: if(quiz_f) { mvaddstr( c_y,25,"Q=view Quiz summary"); c_y++; }
! 2269: mvaddstr( c_y,25,"X=eXit system");
! 2270:
! 2271: mvaddstr(14,25,"COMMAND:");
! 2272:
! 2273: mvaddstr(17, 5,"Enter a command from the list above and press ENTER/RETURN");
! 2274: }
! 2275:
! 2276: /* -------------------------------------------------------------------------- */
! 2277: /* CONTROL MAIN MENU SELECTIONS */
! 2278: /* -------------------------------------------------------------------------- */
! 2279: void /* RETURNS: (nothing) */
! 2280: menu_main(student_number,set,section) /* ARGUMENTS: */
! 2281: char *student_number; /* Student number */
! 2282: int set; /* Set number */
! 2283: int section; /* Section number */
! 2284: { /* LOCAL VARIABLES: */
! 2285: int ex=0, /* Exit system flag */
! 2286: cmd; /* User command */
! 2287: char buff[MAX_BUFFER_SIZE]; /* User command buffer */
! 2288: T_student a_student;
! 2289: int had_exam, had_quiz, outcome,configResult;
! 2290:
! 2291: #ifdef LOGIN_DBUG
! 2292: fprintf(dfp,"MENU in %s sec=%d\n", student_number,section); fflush(dfp);
! 2293: #endif
! 2294:
! 2295: outcome = check_exam_quiz_f();
! 2296: had_exam = outcome & 1;
! 2297: had_quiz = outcome & 2;
! 2298:
! 2299: #ifdef LOGIN_DBUG
! 2300: fprintf(dfp,"After check %d\n", outcome); fflush(dfp);
! 2301: #endif
! 2302:
! 2303: capa_get_student(student_number,&a_student);
! 2304:
! 2305: g_inhibit_response=capa_check_option(OPTION_INHIBIT_RESPONSE,set,section);
! 2306: if (g_inhibit_response < 0 ) g_inhibit_response=0;
! 2307:
! 2308: display_menu(&a_student,had_exam, had_quiz);
! 2309: while (!ex) {
! 2310: do {
! 2311: buff[0] = ' '; buff[1] = 0;
! 2312: get_input(14,34,buff,1); cmd=toupper(buff[0]);
! 2313: } while (isspace(cmd));
! 2314: move(14,35); clrtoeol();
! 2315: /* PROCESS USER COMMAND */
! 2316: switch(cmd) {
! 2317:
! 2318: case 'H': /* DISPLAY HELP */
! 2319: display_help();
! 2320: display_menu(&a_student,had_exam, had_quiz);
! 2321: break;
! 2322:
! 2323: case 'T': /* TRY CURRENT SET */
! 2324: try_set(student_number,set,§ion);
! 2325: display_menu(&a_student,had_exam, had_quiz);
! 2326: break;
! 2327:
! 2328: case 'V': /* VIEW PREVIOUS SET */
! 2329: view_previous(student_number,set,§ion);
! 2330: display_menu(&a_student,had_exam, had_quiz);
! 2331: break;
! 2332:
! 2333: case 'S': /* DISPLAY TERM SUMMARY */
! 2334: configResult=read_capa_config("term_summary_button",buff);
! 2335: if (configResult != 0 && configResult != -1 ) {
! 2336: if ((strcasecmp(buff,"no")==0)) {
! 2337: break;
! 2338: }
! 2339: }
! 2340: term_summary(student_number,set,§ion,TERM_SUMMARY);
! 2341: display_menu(&a_student,had_exam, had_quiz);
! 2342: break;
! 2343: case 'E': /* VIEW EXAM SUMMARY */
! 2344: if( had_exam ) {
! 2345: chdir(Exam_path);
! 2346: term_summary(student_number,Exam_set,§ion,EXAM_SUMMARY);
! 2347: display_menu(&a_student,had_exam, had_quiz);
! 2348: chdir(Orig_path);
! 2349: }
! 2350: break;
! 2351: case 'Q': /* VIEW QUIZ SUMMARY */
! 2352: if( had_quiz ) {
! 2353: chdir(Quiz_path);
! 2354: term_summary(student_number,Quiz_set,§ion,QUIZ_SUMMARY);
! 2355: display_menu(&a_student,had_exam, had_quiz);
! 2356: chdir(Orig_path);
! 2357: }
! 2358: break;
! 2359: case EOF: /* EXIT SYSTEM */
! 2360: case 'X': ex=1; break;
! 2361:
! 2362: default: /* INVALID COMMAND */
! 2363: /* printf("Invalid choice\n"); */
! 2364: break;
! 2365: }
! 2366: }
! 2367: }
! 2368:
! 2369: /* -------------------------------------------------------------------------- */
! 2370: /* DISPLAY WELCOME MESSAGE WHEN USER LOGS IN */
! 2371: /* -------------------------------------------------------------------------- */
! 2372: void /* RETURNS: (nothing) */
! 2373: welcome() /* ARGUMENTS: */
! 2374: { /* LOCAL VARIABLES: */
! 2375: FILE *fp; /* Welcome file pointer */
! 2376: char buf[TMP_LINE_LENGTH]; /* Input buffer */
! 2377:
! 2378: CLEAR();
! 2379: /* sprintf(buf,"This is your %d-time login to this set, good luck!",tries);
! 2380: addstr(buf);
! 2381: */
! 2382: if ((fp=fopen("welcome.msg","r"))!=NULL) {
! 2383: while (fgets(buf,TMP_LINE_LENGTH-1,fp)) addstr(buf);
! 2384: fclose(fp);
! 2385: }
! 2386: }
! 2387:
! 2388: void print_version()
! 2389: {
! 2390: printf("capalogin\n");
! 2391: printf(" CAPA version %s, %s\n",CAPA_VER,COMPILE_DATE);
! 2392: }
! 2393:
! 2394: /* ------------------------------------------------------------------------- */
! 2395: /* DRIVER: INITIALIZE AND GO TO LOGIN */
! 2396: /* ------------------------------------------------------------------------- */
! 2397: int
! 2398: main(int argc, char **argv)
! 2399: { /* LOCAL VARIABLES: */
! 2400: char student_number[MAX_STUDENT_NUMBER+1]; /* Student number */
! 2401: int set, /* Set number */
! 2402: section=0, /* Section number */
! 2403: result; /* stores result from read_capa_config */
! 2404: char filename[FILE_NAME_LENGTH]; /* Question filename buffer */
! 2405: #if defined(NeXT)
! 2406: char cwd[FILE_NAME_LENGTH];
! 2407: #endif
! 2408: char *class_path, buf[MAX_BUFFER_SIZE],*tty;
! 2409:
! 2410:
! 2411: if (argc > 1) { if (strcmp(argv[1],"-v") == 0) {print_version(); exit(0); } }
! 2412: #ifdef LOGIN_DBUG
! 2413: printf("Create login.DBUG file:: argc = %d\n",argc);
! 2414: sprintf(filename,"login.DBUG");
! 2415: if ((dfp=fopen(filename,"a"))==NULL) { printf("Error: can't open login debug\n"); return; }
! 2416: #endif /* LOGIN_DBUG */
! 2417: /* GET CURRENT SET NUMBER */
! 2418: for(set = 1; ; set++ ) {
! 2419: sprintf(filename,"set%d.qz",set);
! 2420: if(capa_access(filename, F_OK) == -1 ) break;
! 2421: }
! 2422: set--;
! 2423: #if defined(NeXT)
! 2424: class_path = getwd(cwd);
! 2425: if( class_path == NULL ) class_path = cwd;
! 2426: #else
! 2427: class_path = getcwd(NULL,512);
! 2428:
! 2429: #endif
! 2430: sprintf(Orig_path,"%s",class_path);
! 2431: free(class_path);
! 2432: /* ---------------------------------------------- CURSES INITIALIZATION */
! 2433: signal(SIGINT , kick_out);
! 2434: signal(SIGALRM, kick_out);
! 2435: signal(SIGFPE, SIG_IGN);
! 2436: initscr(); savetty(); cbreak(); noecho();
! 2437: time(&log_in_time);
! 2438: strncpy(in_t,ctime(&log_in_time),31);
! 2439: in_t[ strlen(in_t)-1 ]=0; /* Trash newline */
! 2440: tty=ttyname(0);
! 2441: if ( tty == NULL ) {
! 2442: strcpy(in_tty,"UNKNOWN");
! 2443: } else {
! 2444: strcpy(in_tty,tty);
! 2445: }
! 2446: result=read_capa_config("capalogin_goodbye_delay",buf);
! 2447: if (result != 0 && result != -1) {
! 2448: g_delay=atoi(buf);
! 2449: } else {
! 2450: g_delay=5;
! 2451: }
! 2452: result=read_capa_config("capalogin_inactivity_delay",buf);
! 2453: if (result != 0 && result != -1) {
! 2454: g_max_delay=atoi(buf);
! 2455: } else {
! 2456: g_max_delay=60;
! 2457: }
! 2458: welcome();
! 2459: strcpy(student_number, login(&set,§ion)); student_number[MAX_STUDENT_NUMBER] = 0;
! 2460: #ifdef LOGIN_DBUG
! 2461: fprintf(dfp,"login return:SNum=%s, set=%d, sec=%d\n", student_number,set, section); fflush(dfp);
! 2462: #endif
! 2463: menu_main(student_number,set,section);
! 2464: #ifdef LOGIN_DBUG
! 2465: fclose(dfp);
! 2466: #endif
! 2467: properly_logout(student_number);
! 2468: return 0;
! 2469: }
! 2470:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>