/* broken start to a new CGI library
   Copyright (C) 1992-2000 Michigan State University

   The CAPA system is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CAPA system is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with the CAPA system; see the file COPYING.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   As a special exception, you have permission to link this program
   with the TtH/TtM library and distribute executables, as long as you
   follow the requirements of the GNU GPL in regard to all of the
   software in the executable aside from TtH/TtM.
*/

char *makeword(char *line, char stop)
{
    int x = 0,y;
    char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));

    for(x=0;((line[x]) && (line[x] != stop));x++)
        word[x] = line[x];

    word[x] = '\0';
    if(line[x]) ++x;
   y=0;

    while((line[y++] = line[x++]));
    return word;
}

char *fmakeword(FILE *f,char  stop,int * cl)
{
    int wsize;
    char *word;
    int ll;

    wsize = 102400;
    ll=0;
    word = (char *) malloc(sizeof(char) * (wsize + 1));

    while(1) {
        word[ll] = (char)fgetc(f);
        if(ll==wsize) {
            word[ll+1] = '\0';
            wsize+=102400;
            word = (char *)realloc(word,sizeof(char)*(wsize+1));
        }
        --(*cl);
        if((word[ll] == stop) || (feof(f)) || (!(*cl))) {
            if(word[ll] != stop) ll++;
            word[ll] = '\0';
            return word;
        }
        ++ll;
    }
}

char x2c(char *what)
{
    register char digit;

    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
    digit *= 16;
    digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
    return(digit);
}

void unescape_url(char *url)
{
    register int x,y;

    for(x=0,y=0;url[y];++x,++y) {
        if((url[x] = url[y]) == '%') {
            url[x] = x2c(&url[y+1]);
            y+=2;
        }
    }
    url[x] = '\0';
}

void plustospace(char *str)
{
    register int x;

    for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' ';
}

void web_parse_input(char * submissions_str)
{
  int x;

  for(x=0; x <= m; x++) {
    if( !strcmp(g_entries[x].name,"CLASS") ) {
      strncpy(g_class_name,g_entries[x].val,MAX_CLASS_CHAR);
    }
    if( !strcmp(g_entries[x].name,"M") ) {
      sscanf(g_entries[x].val,"%d",&g_run_mode);
    }
    if( !strcmp(g_entries[x].name,"SNUM") ) {
      strncpy(g_student_number,g_entries[x].val,MAX_STUDENT_NUMBER+4);
    }
    if( !strcmp(g_entries[x].name,"CAPAID") ) {
      sscanf(g_entries[x].val,"%d",&g_entered_pin);
    }
    if( !strcmp(g_entries[x].name,"SET") ) {
      sscanf(g_entries[x].val,"%d",&g_set);
    }
    if( !strcmp(g_entries[x].name,"VSET") ) {
      if (g_entries[x].val[0] == '\0') {
	g_vset=0;
      } else {
	sscanf(g_entries[x].val,"%d",&g_vset);
      }
    }
    if( !strcmp(g_entries[x].name,"KND") ) {
      sscanf(g_entries[x].val,"%d",&g_skind);
    }
    if( !strncmp(g_entries[x].name,"INPUT",5) ) {
      sscanf(g_entries[x].name,"INPUT%d",&q_idx);
      if( q_idx > 0 && q_idx < MAX_PROBLEM_CNT ) {
	strncpy(g_student_answer[q_idx],g_entries[x].val,MAX_ANSWER_CHAR);
      }
      if ( g_student_answer[q_idx][0] != '\0' ) {
	sprintf(buf,"%d\t%s\t",q_idx,g_student_answer[q_idx]);
	strcat(submissions_str,buf);
      }
    }
    if( !strncmp(g_entries[x].name,"LAST",4) ) {
      sscanf(g_entries[x].name,"LAST%d",&q_idx);
      if( q_idx > 0 && q_idx < MAX_PROBLEM_CNT ) {
	strncpy(g_last_answer[q_idx],g_entries[x].val,MAX_ANSWER_CHAR);
      }
    }
    free(g_entries[x].val);
    free(g_entries[x].name);
  }
}

int web_login() 
{
  if( g_entered_pin != 0 ) {
    g_login_set = capa_PIN(g_student_number,999,g_entered_pin);
  } else {
    return WEB_ERR_ENTERED_PIN;
  }

  if (!g_login_set) { 
    return WEB_ERR_BADLOGIN;
  } else {
    if ( g_login_set > 99 )  { return WEB_ERR_LOGINTOHIGH; }
    if(g_login_set < g_vset ) {
      return WEB_ERR_NOTVIEWABLE;
    }
    chdir(g_class_fullpath);  /* again, to make sure */
      
    if ( capa_get_student(g_student_number,&g_student_data) == 0 ) {
      return WEB_ERR_STUDENT_NOT_EXIST;
    } else {
      time(&curtime);
      if (capa_get_header(&header, g_login_set, wgt, pcr))  {
	return WEB_ERR_SET_NOT_READY;
      }
      if(capa_check_date(CHECK_OPEN_DATE,g_student_data.s_sec,
			 g_login_set) < 0 ) {
	
	return WEB_ERR_SET_NOT_OPEN;
      }
    }
  }
  return (error);
}

int web_get_input() 
{
  
  envPtr=getenv("REQUEST_METHOD");
  if (!envPtr ) { return WEB_ERR_REQ_METHOD; }
  if (strcmp(envPtr,"POST")) { return WEB_ERR_ENV_POST; }
  envPtr=getenv("CONTENT_TYPE");
  if (!envPtr ) { return WEB_ERR_CONTENT_TYPE; }
  if (strcmp(envPtr,"application/x-www-form-urlencoded")) { 
    return WEB_ERR_ENV_CONTENT; 
  }
  envPtr=getenv("CONTENT_LENGTH");
  if (!envPtr ) { return WEB_ERR_CONTENT_LENGTH; }
  content_length=atoi(envPtr);

  /* read the form into the g_entries array*/
  for(x=0;content_length && (!feof(stdin));x++) {
    m=x;
    g_entries[x].val = fmakeword(stdin,'&',&content_length);
    plustospace(g_entries[x].val);
    unescape_url(g_entries[x].val);
    g_entries[x].name = makeword(g_entries[x].val,'=');
  }

  web_parse_input(submissions_str);

  if ( g_run_mode == WEB_CHECKIN ) {
    time(&curtime); time_str = ctime(&curtime);
    time_str[ strlen(time_str)-1 ] = '\0';
    envPtr=getenv("REMOTE_HOST");
    envPtr2=getenv("HTTP_USER_AGENT");
    sprintf(log_str,"%s\t%s\t%s\t%s\t%s\n",g_class_name,g_student_number,
	    time_str,envPtr,envPtr2);
    if (web_log(log_str) == -1 ) { return WEB_ERR_WEB_LOG; }
  }

  getwd(g_cwd);

  web_getclassdir(&g_cpath, &g_cowner, g_class_name);
  sprintf(g_class_fullpath,"%s/%s",g_cpath,g_class_name);
  if( !capa_access(g_class_fullpath, F_OK) == 0 ) { return WEB_ERR_ACCESS; }
    
  chdir(g_class_fullpath);
  if ( g_run_mode == M_CHECKANS) {
    if (w_log_submissions(g_student_number,g_set,submissions_str) == -1 ) {
      return WEB_ERR_SUBMMISIONS_LOG;    
    }
  }
  
  result=read_capa_config("capaweb_cgibin_path",buf);
  if (result != 0 && result != -1) {
    g_cgibin_path=capa_malloc(strlen(buf)+1,1);
    strcpy(g_cgibin_path,buf);
  } else {
    g_cgibin_path=capa_malloc(strlen("capa-bin")+1,1);
    strcpy(g_cgibin_path,"capa-bin");
  }  
  return web_login();
}

