If anyone could help me with the below feedback it would be great... I'm apparently not allowed to have Global Variables so I need to change my declarations but whenever I change them I seem to stuff my code up. Any help would be great.

21. FILE *fp;
==> Global variables are not allowed in this subject.

22. char *packet;
==> Global variables are not allowed in this subject.

23. struct messagenode *head_msg, *save_msg, *current_msg;
==> Global variables are not allowed in this subject.

24. struct pktnode *head_pkt, *save_pkt, *current_pkt;
==> Global variables are not allowed in this subject.

The previous lines in assign2.c are unacceptable

Code:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>

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;

};

FILE *fp;
char *packet;
struct messagenode *head_msg, *save_msg, *current_msg;
struct pktnode  *head_pkt, *save_pkt, *current_pkt;
#define DELIM ":"

void initiate(char *filename);
void populateInList(char *packet);
struct messagenode *getMsgNode();
struct pktnode *getPktNode();
struct messagenode *search_msg(int msg_id);
struct pktnode *search_pkt(int pkt_id);
void getPacketInfo(char *packet,  int *msg_id, int *pkt_id, char *message, int *prefix_len_msg);
void display();
void cleanUpAll();
void sortMsg();
int getlen(char *arg);

int main(int argc,  char **argv)
{
   /* Argument checking section */
   if(argc != 2)
   {
      printf("Please provide one message data file\n");
      return -1;
   }
   /* Perform necessary program initiation steps */
   initiate(argv[1]);

   /* Main Loop */
   while(1)
   {
      /* Grab packet from file */
      fgets(packet, 2001, fp);

      /* If no packet remaining or END packet received then stop processing */
      if(packet == NULL || !strcmp(packet, "END\n")|| !strcmp(packet, "END"))
         break;
      /* function to process and populate packet in linked list*/
      populateInList(packet);
   }
   /* Sort the message linked list,  i.e. the outer one */
   sortMsg();

   /* Display the list data structure */
   display();
   
   /* Post process routines. file close + freeing allocated memories */
   cleanUpAll();
   return 0;
}
void initiate(char *filename)
{
   
   head_msg = NULL;
   head_pkt = NULL;

   /* Opening packet data file */
        fp = fopen(filename, "r");
        if(fp == NULL)
        {
                printf("Unable to open %s\n", filename);
                exit(0);
        }
   packet = (char *)malloc(2000 * sizeof(char));
}
void populateInList(char *packet)
{
   int msg_id, pkt_id, prefix_len_msg;
   char *message;
   struct messagenode *tmp_message,  *loc;
   struct pktnode *tmp_packet,  *loc_pkt;;

   message = (char *)malloc(1500*sizeof(char));
   
   /* Get message id,  packet id and packet message from each packet string -
    * passed to function as argument.
     */   
   getPacketInfo(packet, &msg_id, &pkt_id, message, &prefix_len_msg);
   
   /* If packet belongs to an existing message,  find the message's location in message list.
     * If message not found the NULL will be returned,  otherwise location of message node
     * will be returned.
     *
     * First condition: loc != NULL i.e. message entry found in list.
     */
   if((loc = search_msg(msg_id)) != NULL)
   {
      /* Get a new packet node and populate it pkt_id and packet message.*/
      tmp_packet = getPktNode();
      tmp_packet->pkt_id = pkt_id;
      tmp_packet->message = message;

      /* Current packet head is the packet head of the current message.*/
      head_pkt = loc->pkthead;

      /* If current packet head is NULL then New packet will be the head packet.*/
      if(head_pkt == NULL)
         head_pkt = tmp_packet;
      else 
      {
         /* Otherwise,  find the location where the New packet will be inserted.
           * If location is the head packet and New packet id is less than the packet
           * id of located node then insert the New packet before located node.
           * Otherwise,  insert the New packet node after the located packet node.
           */
         loc_pkt = search_pkt(pkt_id);

         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
   {
      /* Second condition: loc==NULL i.e. Message entry not found.
        * So,  (1)Create a new message node. (2)Create a new packet node corresponding
        * to the new message node. (3) Populate them accordingly. (4) Add the new message 
        * node into the message linked list,  i.e. the outer one.
        */
      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.
 * If messahe head is NULL return NULL i.e. message not found
 * Else move through list searching for the node.
 * .. If whole list is traversed in vain then return NULL i.e. message not found.
 * .. Else return the location of the found message node.*/

struct messagenode *search_msg(int msg_id)
{
   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.(Inner one)
 * Save location of current packet in each iteration of while() loop.
 * If full packet list is traversed in vain or packet node is found
 * with given packet node,  saved location of packet is returned.*/

struct pktnode *search_pkt(int pkt_id)
{
   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.
 * Tokenize the string by strtok() with delemeter ':'.
 */

void getPacketInfo(char *packet,  int *msg_id, int *pkt_id, char *message, int *prefix_len_msg)
{
   char *tokenPtr = NULL;
   char array[10][1500];
   char bkp_packet[2000];
   int counter = 0, i=0;
   
   /* Take a backup of the packet string as strtok() modifies the original string.*/
   strcpy(bkp_packet, packet);

   /* Extract first token. i.e. message id and save in temporary array.*/
   tokenPtr = (char *)strtok(packet, DELIM);
   if(tokenPtr == NULL)
   {
      printf("Fatal Error1 !! Invalid Message Format\n");
      cleanUpAll();
      exit(0);
   }
   strcpy(array[0], tokenPtr);
   counter++;

   /* Subsequent extraction of tokens and saving them.*/
   while(1)
   {
      tokenPtr = (char *)strtok(NULL, DELIM);
      if(tokenPtr == NULL)
         break;
      strcpy(array[counter], tokenPtr);
      /* Special measure to keep the delemeter when it is a part of packet message.
        * Concatinating : character to the previous token if current token counter
        * is > 2. */
      if(counter>2)
      strcat(array[counter-1], ":");
      counter++;
   }
   if(counter < 3)
   {
      printf("Fatal Error3 !! Invalid Message Format\n");
      cleanUpAll();
      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()
{
   char display_string[2000];
   char prefix[3];
   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()
{
   fclose(fp);
   free(packet);
   while(head_msg != NULL)
   {
      head_pkt = head_msg->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->next;
      free(head_msg);
      head_msg = current_msg;
   }
}

/* Sort the message linked list,  i.e. the outer one.*/

void sortMsg()
{
   int tmp_id, tmp_len;
   struct pktnode *tmp_head;
   
   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;
            }
         }
      }
   }
}