Code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#define DELIM ":"
struct pktnode
{
int pkt_id;
char *message;
struct pktnode *next;
};
struct messagenode
{
int msg_id;
int prefix_len;
char id_prefix[3];
struct pktnode *pkthead;
struct messagenode *next;
};
void initiate(char *filename, FILE **fp, char **packet);
void populateInList(char *packet, struct messagenode **msg_node, FILE **fp);
struct messagenode *getMsgNode();
struct pktnode *getPktNode();
struct messagenode *search_msg(int msg_id, struct messagenode **head_msg);
struct pktnode *search_pkt(int pkt_id, struct pktnode **head_pkt);
void getPacketInfo(char *packet, int *msg_id, int *pkt_id, char *message,
int *prefix_len_msg, struct messagenode **head_msg, FILE **fp);
void display(struct messagenode **head_msg);
void cleanUpAll(struct messagenode **head_msg, FILE **fp, char *packet);
void sortMsg(struct messagenode **head_msg);
int getlen(char *arg);
int main(int argc, char **argv)
{
FILE *fp;
char *packet;
struct messagenode *head_msg = NULL;
if(argc != 2)
{
printf("Must supply 1 argument to packet\n");
return 0;
}
initiate(argv[1], &fp, &packet);
while(1)
{
fgets(packet, 2001, fp);
if(packet == NULL || !strcmp(packet, "END\n")|| !strcmp(packet, "END"))
break;
populateInList(packet, &head_msg, &fp);
}
sortMsg(&head_msg);
display(&head_msg);
cleanUpAll(&head_msg, &fp, packet);
return 0;
}
/* Opening packet data file */
void initiate(char *filename, FILE **fp, char **packet)
{
*fp = fopen(filename, "r");
if(*fp == NULL)
{
printf("Unable to open %s\n", filename);
exit(0);
}
*packet = (char *)malloc(2000 * sizeof(char));
}
/* Get message id, packet id and packet message from each
* packet string passed to function as argument.
*/
void populateInList(char *packet, struct messagenode **head_msg, FILE **fp)
{
int msg_id, pkt_id, prefix_len_msg;
char *message;
struct messagenode *tmp_message, *loc, *current_msg, *save_msg;
struct pktnode *tmp_packet, *loc_pkt, *head_pkt;
message = (char *)malloc(1500*sizeof(char));
getPacketInfo(packet, &msg_id, &pkt_id, message,
&prefix_len_msg, head_msg, fp);
if((loc = search_msg(msg_id, head_msg)) != NULL)
{
tmp_packet = getPktNode();
tmp_packet->pkt_id = pkt_id;
tmp_packet->message = message;
head_pkt = loc->pkthead;
if(head_pkt == NULL)
head_pkt = tmp_packet;
else
{
loc_pkt = search_pkt(pkt_id, &head_pkt);
if(loc_pkt == head_pkt && pkt_id < loc_pkt->pkt_id)
{
tmp_packet->next = head_pkt;
head_pkt = tmp_packet;
loc->pkthead = head_pkt;
}
else
{
tmp_packet->next = loc_pkt->next;
loc_pkt->next = tmp_packet;
}
}
}
else
{
tmp_message = getMsgNode();
tmp_message->msg_id = msg_id;
tmp_message->prefix_len = prefix_len_msg;
tmp_message->next = NULL;
tmp_message->pkthead = getPktNode();
tmp_message->pkthead->pkt_id = pkt_id;
tmp_message->pkthead->message = message;
if(*head_msg == NULL)
*head_msg = tmp_message;
else
{
current_msg = *head_msg;
while(current_msg != NULL)
{
save_msg = current_msg;
current_msg = current_msg->next;
}
save_msg->next = tmp_message;
}
}
}
struct messagenode *getMsgNode()
{
struct messagenode *tmp;
tmp = (struct messagenode *)malloc(sizeof(struct messagenode));
tmp->pkthead = NULL;
return tmp;
}
struct pktnode * getPktNode()
{
struct pktnode *tmp;
tmp = (struct pktnode *)malloc(sizeof(struct pktnode));
tmp->next = NULL;
return tmp;
}
/* Function to search a message node in message linked list. */
struct messagenode *search_msg(int msg_id, struct messagenode **head_msg)
{
struct messagenode *current_msg;
current_msg = *head_msg;
if(*head_msg == NULL)
return NULL;
else
{
while((current_msg != NULL) && (current_msg->msg_id != msg_id))
current_msg = current_msg->next;
if(current_msg == NULL)
return NULL;
if(current_msg->msg_id == msg_id)
return current_msg;
else
return NULL;
}
}
/* Function to search a packet node in packet linked list. */
struct pktnode *search_pkt(int pkt_id, struct pktnode **head_pkt)
{
struct pktnode *current_pkt, *save_pkt;
current_pkt = *head_pkt;
save_pkt = current_pkt;
while((current_pkt != NULL) && (pkt_id > current_pkt->pkt_id))
{
save_pkt = current_pkt;
current_pkt = current_pkt->next;
}
return save_pkt;
}
/* Function to get packet info from packet string. */
void getPacketInfo(char *packet, int *msg_id, int *pkt_id, char *message,
int *prefix_len_msg, struct messagenode **head_msg, FILE **fp)
{
char *tokenPtr = NULL;
char array[10][1500];
char bkp_packet[2000];
int counter = 0, i=0;
strcpy(bkp_packet, packet);
tokenPtr = (char *)strtok(packet, DELIM);
if(tokenPtr == NULL)
{
printf("Fatal Error1 !! Invalid Message Format\n");
cleanUpAll(head_msg, fp, packet);
exit(0);
}
strcpy(array[0], tokenPtr);
counter++;
while(1)
{
tokenPtr = (char *)strtok(NULL, DELIM);
if(tokenPtr == NULL)
break;
strcpy(array[counter], tokenPtr);
if(counter>2)
strcat(array[counter-1], ":");
counter++;
}
if(counter < 3)
{
printf("Fatal Error3 !! Invalid Message Format\n");
cleanUpAll(head_msg, fp, packet);
exit(0);
}
*prefix_len_msg = getlen(array[0]);
*msg_id = atoi(array[0]);
*pkt_id = atoi(array[1]);
for(i=2; i<counter; i++)
{
strcat(message, array[i]);
}
}
int getlen(char *arg)
{
int n=0;
char ch;
while(1)
{
ch = arg[n];
if(ch != '0')
break;
n++;
}
return n;
}
/* Move through formulated linked list and display the content.*/
void display(struct messagenode **head_msg)
{
char display_string[2000];
char prefix[3];
struct messagenode *current_msg;
struct pktnode *current_pkt;
int i;
current_msg = *head_msg;
while(current_msg != NULL)
{
for(i=0; i<current_msg->prefix_len; i++)
prefix[i]= '0';
prefix[i]='\0';
sprintf(display_string, "Message %s%d\n", prefix, current_msg->msg_id);
current_pkt = current_msg->pkthead;
while(current_pkt != NULL)
{
strcat(display_string, current_pkt->message);
current_pkt = current_pkt->next;
}
current_msg = current_msg->next;
printf("%s\n", display_string);
}
}
/* Move through linked list and deallocate it. Close file pointer also */
void cleanUpAll(struct messagenode **head_msg, FILE **fp, char *packet)
{
struct messagenode *current_msg, *head_msg_local;
struct pktnode *current_pkt, *head_pkt;
fclose(*fp);
free(packet);
head_msg_local = *head_msg;
while(head_msg_local != NULL)
{
head_pkt = head_msg_local->pkthead;
while(head_pkt != NULL)
{
free(head_pkt->message);
current_pkt = head_pkt->next;
free(head_pkt);
head_pkt = current_pkt;
}
current_msg = head_msg_local->next;
free(head_msg_local);
head_msg_local = current_msg;
}
}
/* Sort the message linked list, i.e. the outer one.*/
void sortMsg(struct messagenode **head_msg)
{
int tmp_id, tmp_len;
struct pktnode *tmp_head;
struct messagenode *current_msg, *save_msg;
if(*head_msg == NULL)
return;
else
{
for(current_msg = *head_msg; (current_msg != NULL);
current_msg = current_msg->next)
{
for(save_msg = current_msg->next;
(save_msg != NULL); save_msg = save_msg->next)
{
if(current_msg->msg_id > save_msg->msg_id)
{
tmp_id = save_msg->msg_id;
tmp_head = save_msg->pkthead;
tmp_len = save_msg->prefix_len;
save_msg->msg_id = current_msg->msg_id;
save_msg->pkthead = current_msg->pkthead;
save_msg->prefix_len = current_msg->prefix_len;
current_msg->msg_id = tmp_id;
current_msg->pkthead = tmp_head;
current_msg->prefix_len = tmp_len;
}
}
}
}
}