


# include <stdio.h>
# include <errno.h>
# include <string.h>
# include <stddef.h>
# include <sys/file.h>

# include "serv.h"
# include "tables.h"

#define   EOT   "\012.\015\012"
char       *mit_id_ptr;
char       *term_ptr;
char       *sort_columns_ptr;
int        rc;

void
log_aline(line)             /* write  to a  file - for debugging */
        char           *line;
{
        int dfd;
        if ((dfd = open("/mit/net_dev/larissa/serv.log", 
			O_APPEND | O_CREAT | O_WRONLY, 0644)) == 0)
                printf("error logging transaction\n");
        write(dfd, line, strlen(line));
        close(dfd);
        return;
}



/*
 *   init_buf initializes the structure buffer_t *b, and if b_ptr == NULL
 *   allocates b_len bytes. If b_ptr != NULL that means that buffer is
 *   already allocated.
 */

static void
init_buf(buffer_t *b, long b_len, char *b_ptr)
{
     b->buflen = b_len;
     if (b_ptr != NULL)
       b->bufptr = b_ptr; /* buffer is already allocated */
       else
	 {
	   /* we have to allocate the buffer */
	   b->bufptr = (char *) malloc ( b->buflen + 1);
           if ( b->bufptr == NULL)
             fprintf (stdout,"Unable to allocate memory for the buffer\n");
	   fflush(stdout);
	 }
     b->buf_offset = b->bufptr;
}

/*
 *  next_field: it returns buf_offset ptr, looks for any of the delimeters,
 *              replaces the found delimeter with '\0', and moves
 *              buf_offset after that '\0'.
 */

static char *
next_field (buffer_t *b )
{
     char *field_ptr;

     field_ptr = b->buf_offset;

     while ( *( b->buf_offset) != DLMF && 
             *( b->buf_offset) != DLMR &&
             *( b->buf_offset) != EOM)
              b->buf_offset = b->buf_offset + 1;

     *( b->buf_offset) = '\0';
     log_aline ("field=");
     log_aline (field_ptr);

     b->buf_offset = b->buf_offset + 1;

     return (field_ptr);
}

/*
 *  int_buf reads symbols from the standard input until it finds the 
 *  delimeter DLMF. Then it converts the number to integer and stores it
 *  in the (*b).buflen, allocates buffer and reads it from stdin.
 */

static void
get_buf(buffer_t *b)
{
  int rc;

  fprintf(stdout,"Enter the buffer (%d bytes)>\n",b->buflen);
  fprintf(stdout,"%s",EOT);
  fflush(stdout);

  rc = read ( FILE_IN, b->bufptr, b->buflen);

  if (rc < 0)
    perror("trying to read the whole buffer");

  if ( *( b->bufptr + b->buflen ) != EOM)
    fprintf (stdout,"There is no EOM at the end of the buffer\n");
  fflush(stdout);

  *( b->bufptr + b->buflen + 1) = '\0';
  
  log_aline("/nThe buffer=");
  log_aline( b->bufptr);


      
}


/*
 * Append_field appends field + DLMF to the buffer and recalculates 
 * buf_offset. It checks if the buflen allows to do it.
 */

static void
append_field (buffer_t *b, char *field_ptr)
{
  size_t   field_len;
  field_len = strlen(field_ptr);
  if ( b->buf_offset + field_len > b->bufptr + b->buflen)
    printf("There is no space in buffer to append the field\n");
  else
    {
      strncpy( b->buf_offset, field_ptr, field_len);
      b->buf_offset = b->buf_offset + field_len;
      *( b->buf_offset) = DLMF;
      b->buf_offset = b->buf_offset + 1;
    }
  
}

main()
{
  buffer_t   in_head_buffer;
  buffer_t   in_buffer;
  buffer_t   out_buffer;
  int        loc_buflen = 12;

  message_header_t  in_message_header;

  char   first_field[6] = "first";
  char   sec_field[4]   = "sec";
  int     rc;

  static char    first_line[80];
  int     line_len = sizeof(first_line);

  
while(TRUE)
    {

      printf("Enter first line(buflen ret_code rec_type num_rec) ");
      printf(" followed by CR,\nor ... to QUIT>%s",EOT); 

      fflush(stdout);

      fgets (first_line, line_len, stdin);
      fputs (first_line, stdout);
        
      if (! strncmp (first_line, EOC, EOC_LEN) )
	break; /* if first_line = EOC -> we reached the end of connection */

      /* We have to initialize in_head_buffer in order to parse it */
      init_buf (&in_head_buffer, line_len, &first_line[0]);

      in_message_header.buflen      = atoi ( next_field (&in_head_buffer) );
      in_message_header.return_code = atoi ( next_field (&in_head_buffer) );
      in_message_header.record_type = *( next_field (&in_head_buffer) );
      in_message_header.num_records = atoi ( next_field (&in_head_buffer) );
      
      fprintf (stdout,"buflen      = %d\n", in_message_header.buflen);
      fprintf (stdout,"return_code = %d\n", in_message_header.return_code);
      fprintf (stdout,"record_type = %c\n", in_message_header.record_type);
      fprintf (stdout,"num_records = %d\n", in_message_header.num_records);
      
      fflush(stdout);
      
      init_buf (&in_buffer, in_message_header.buflen, NULL);
      
      switch (in_message_header.record_type) {
	
      case BIO_RECORD:
	log_aline( "\nget unique BIO record\n\n");
	break;
	
      case GRADE_HISTORY_TERM:
	log_aline( "\nget grade history for term\n\n");
	break;
	
      case GRADE_HISTORY_ALL:
	log_aline( "\nget grade history for all terms\n\n");
	break;
	
      case TERM_SUMMARY_TERM:
	log_aline( "\nget term summary for term\n\n");
	break;
	
      case TERM_SUMMARY_ALL:
	log_aline( "\nget term summary for all terms\n\n");
	break;
	
      case GRADES_TERM:
	log_aline( "\nget grades for term\n\n");
       	break;
	
      case GRADES_ALL:
	log_aline( "\nget grades for all terms\n\n");
	break;
	
      case AUDIT_STRIP:
	log_aline( "\nget audit strip\n\n");
	break;
	
      case SUBJECT_INFO:
	log_aline( "\nget subject info for a subject\n\n");
	break;
	
      case UPDATED_BIO_RECORD:
	log_aline( "\nreceive updated BIO record\n\n");
	break;
	
      default:
	fprintf(stdout,"\nunrecognized record type %c\n\n",
		in_message_header.record_type);
	fflush(stdout);
      }

      get_buf (&in_buffer);
      
      init_buf(&out_buffer, in_message_header.buflen, NULL);
      
      append_field(&out_buffer, in_buffer.bufptr);
      
      printf("out_buffer=%send\n",out_buffer.bufptr);
    }  
/* end of the loop till the end of connection - EOC */

}









