
/* common.c - functions used by both sender.c and receiver.c */

#include <stdio.h>			/* standard i/o definitions */
#include <strings.h>			/* string handling definitions */
#include "defs.h"			/* common parameter definitions */
#include "common.h"			/* function prototypes for common.c */

#define JRWPRINTSIZE	80		/* redefine PRINTSIZE to larger value */

char	buf[JRWPRINTSIZE];		/* print buffer for error() and log() */

/*
 * void error(char *string);
 *
 * error issues a message to standard error and terminates the calling program.
 *
 */

void error(char *string)
{
   int i;

   sprintf(buf,"\nFatal Error:%s\n",string);
   for (i = 0; i < JRWPRINTSIZE && buf[i] != '\0'; i++); /* compute length */
   write(mystderr,buf,i);
   exit(-1);
}

/*
 * void log(char *string);
 *
 * log issues a message to standard error and returns to the calling program.
 *
 */

void log(char *string)
{
   int i;

   sprintf(buf,"\rLOG:%s\n",string);
   for (i = 0; i < JRWPRINTSIZE && buf[i] != '\0'; i++); /* compute length */
   write(mystderr,buf,i);
   return;
}

/*
 * void nlog(char format[], int value);
 *
 * nlog logs a message to standard error. The caller specifies an sprintf
 * format string (containing a %d) and an integer value; nlog formats the 
 * number in the message and calls log() to display the message.
 *
 */

void nlog(char format[], int value)
{

   char line[100];

   sprintf(line, format, value);
   log(line);

   return;

}

/*
 * void nnlog(char format[], int value1, int value2);
 *
 * nnlog behaves like nlog() but allows for two integer values to be
 * specified, which are formatted as indicated in the format string.
 *
 */

void nnlog(char format[], int value1, int value2)
{

   char line[100];

   sprintf(line, format, value1, value2);
   log(line);

   return;

}

/*
 * void slog(char format[], char value[]);
 *
 * slog behaves like nlog() but allows for the specification of a string
 * rather than an integer to be substituted in the format string.
 *
 */

void slog(char format[], char value[])
{

   char line[100];

   sprintf(line, format, value);
   log(line);

   return;

}

/*
 * int valid_packet(packet *msgpkt, char progname[]);
 *
 * valid_packet verifies that the specified message packet is correct.
 * Specifically, the checksum is verified to be correct and the sender's
 * initials are confirmed to be as expected.
 *
 * valid_packet returns TRUE if the packet is valid. If the checksum or
 * initials are incorrect, an error message is logged and a value of FALSE 
 * is returned.
 *
 * progname is a character array containing the name of the program calling
 * valid_packet. This name is inserted in messages logged by valid_packet. 
 *
 */

int valid_packet(packet *msgpkt, char progname[])
{
   char error_message_buffer[80];

   short checksum_received;		/* checksum sent with current block */

   /* validate checksum received matches recalculated checksum */

   checksum_received =  msgpkt->mdr.checksum; /* save transmitted checksum */
   msgpkt->mdr.checksum = 0;		/* set to zero for recomputation */
   if (checksum_received != (short) in_cksum(msgpkt, sizeof(packet))) {
      sprintf(error_message_buffer, "%s: checksum error; invalid packet "
         "discarded.", progname);
      log(error_message_buffer);
      return FALSE; 	/* return invalid status */
   }

   /* verify that initials sent by sender are what were expected */

   if (msgpkt->mdr.initials[0] != 'j' ||
       msgpkt->mdr.initials[1] != 'r' ||
       msgpkt->mdr.initials[2] != 'w') {
      sprintf(error_message_buffer, "%s: initials in packet header "
         "incorrect; invalid packet ignored.", progname);
      log(error_message_buffer);
      return FALSE; 	/* return invalid status */
   }

   /* packet has been shown to be valid - return valid status */

   return TRUE;

}

