The particular problem I have is that in my main function, I have added a print statement before and after I call the "bad" function. It always shows the before statement, but never the after statement. I also added a print statement to the end of the "bad" function, and I can see that it runs properly to the very last line of the "bad" function, so it should return normally. After the functions last print and before the main function print, I get the segfault. Any ideas? Here is the code:
int main(int argc, char* argv[])
{
    char myItem[100];
    int i = 0;
    while (i < 100) {
        scanf("%[^\n]", myItem);
        i++;
        if (myItem == EOF) {
            break;
        }
        int c;
        while ((c = getchar()) != '\n' && c != EOF);
        //printf("string read in from user typing: %s\n", myItem);
        printf("i = %d\n", i);
        emailFilter(myItem);
        printf("done with email filter in main\n");
        //printf("item from this pass is:%s\n\n", myItem);
    }
    return 0;
}
and the "bad" function:
void emailFilter(char* mySubject)
{
    printf(" Just entered the emailFilter() .\n");
    char * event_holder[5]; //holds five separate char ptrs
    for (int i = 0; i < 5; i++)
    {
        event_holder[i] = ((char*)malloc(100 * sizeof(char*)));
    }
    char command_type = parseSubject(mySubject, event_holder); //parses subject line and fills event_holder. returns command type, from parsing
    //call proper parsing result
    if (command_type == 'C')
    {
         create(event_holder);
    }
    else if (command_type == 'X')
    {
        change(event_holder);
    }
    else if (command_type == 'D')
    {
        delete(event_holder);
    }
    printf("Leaving emailfilter()...\n");
}
and running this code provides me:
$: 
i = 1
 Just entered the emailFilter() .
C, Meeting   ,01/12/2019,15:30,NEB202
Leaving emailfilter()...
done with email filter in main
i = 2
 Just entered the emailFilter() .
Leaving emailfilter()...
Segmentation fault
This shows that I always make it through the function, but still don't return properly.
Here is my entire code to reproduce the error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
   char * event_data[5];
   struct node * next;
};
struct node *head = NULL;
struct node *current = NULL;
char* earliest = NULL;
char* substring (char* orig, char* dest, int offset, int len)
{
    int input_len = strlen (orig);
    if (offset + len > input_len)
    {
        return NULL;
    }
    strncpy (dest, orig + offset, len);
    //add null char \0 to end
    char * term = "\0";
    strncpy (dest + len, term, 1);
    return dest;
}
char * firstItem(char* shortenedSubject)
{
    int i = 0;
    int currentLength = 0;
    int currentCharIndex = 0;
    int eventIndex = 0;
    char * toReturn = (char*)malloc(100);
    while ((shortenedSubject[currentLength] != '\0') && (shortenedSubject[currentLength] != ',') )//50 is my safety num to make sure it exits eventually
    {
        currentLength++;
    }
    if (shortenedSubject[currentLength] == ',') {
        substring(shortenedSubject, toReturn, 0, currentLength);
    }
    return toReturn;
}
char parseSubject(char* subject,char * eventDataToReturn[5]) //returns "what type of command called, or none"
{
    char toReturn;
    char * shortenedSubject  = (char*)malloc(100);
    substring(subject,shortenedSubject,9,strlen(subject)-9);//put substring into tempString
    int currentCharIndex = 0;// well feed into index of substring()
    int eventIndex = 0; //lets us know which event to fill in
    int currentLength = 0;//lets us know length of current event
    int i = 0; //which char in temp string were alooking at
    char * action = firstItem(shortenedSubject);
    if (strlen(action) == 1)
    {
        if ( action[0] == 'C')
        {
            toReturn = 'C';
        }
        else if (action[0] == 'X')
        {
            toReturn = 'X';
        }
        else if (action[0] == 'D')
        {
            toReturn = 'D';
        }
        else
        {
            toReturn = 'N'; //not valid
            //invalid email command, do nothing
        }
    }
    else
    {
        toReturn = 'N'; //not valid
        //invalid email command, do nothing
    }
    char* debug2;
    while ((shortenedSubject[i] != '\0') && (i <= 50) )//50 is my safety num to make sure it exits eventually
    {
        char debugvar = shortenedSubject[i];
        currentLength++;
        if (shortenedSubject[i] == ',')
        {
            //eventDataToReturn[i] =  substring2(shortenedSubject,currentCharIndex,currentLength);
            substring(shortenedSubject,eventDataToReturn[eventIndex],currentCharIndex,currentLength-1);
            debug2 = eventDataToReturn[eventIndex];
            currentCharIndex= i +1;
            eventIndex++;
            currentLength = 0;
            //i++;
        }
        i++;
    }
    substring(shortenedSubject,eventDataToReturn[4],currentCharIndex,currentLength);
    return toReturn;
} 
void printEventData(char* my_event_data[])
{
    //printf("\nPrinting event data...\n");
    for (int i = 1; i < 4; i++)
    {
        printf("%s,",my_event_data[i]);
    }
    //print last entry, no comma
    printf("%s",my_event_data[4]);
   
}
void printEventsInorder()
{
    struct node * ptr = head;
    while (ptr != NULL)//if not empty, check each one and add when ready
    {
        printEventData(ptr->event_data);
        printf("\n");
        ptr = ptr->next;
    }
}
void insertFront(char* my_event_data[5])
{
   struct node *link = (struct node*) malloc(sizeof(struct node));
   link->next = NULL;
   for (int i = 0; i < 5; i++)
   {
       link->event_data[i] = my_event_data[i];
   }
   head = link;
}
int isEarlier(char* event_data_L[5], char* event_data_R[5])
{// will be given like    12:30      12:45,turn timeL into timeL1 and timeL2, and time R1 and timeR2  
    //compare dates for earlier
    int month_L,day_L,year_L;
    int month_R,day_R,year_R;
    char* char_holder;
    substring(event_data_L[2],char_holder,0,2);//extract first half of time
    month_L = atoi(char_holder); //convert first half of time to int
    substring(event_data_L[2],char_holder,3,2);//extract first half of time
    day_L = atoi(char_holder); //convert first half of time to int
    substring(event_data_L[2],char_holder,6,4);//extract first half of time
    year_L = atoi(char_holder); //convert first half of time to int
    substring(event_data_R[2],char_holder,0,2);//extract first half of time
    month_R = atoi(char_holder); //convert first half of time to int
    substring(event_data_R[2],char_holder,3,2);//extract first half of time
    day_R = atoi(char_holder); //convert first half of time to int
    substring(event_data_R[2],char_holder,6,4);//extract first half of time
    year_R = atoi(char_holder); //convert first half of time to int
    int time_L1,time_L2,time_R1,time_R2;
    substring(event_data_L[3],char_holder,0,2);//extract first half of time
    time_L1 = atoi(char_holder); //convert first half of time to int
    substring(event_data_L[3],char_holder,3,2);//extract second half of time
    time_L2 = atoi(char_holder); //convert second half of time to int
    substring(event_data_R[3],char_holder,0,2);
    time_R1 = atoi(char_holder);
    substring(event_data_R[3],char_holder,3,2);
    time_R2 = atoi(char_holder);
    
   //convert to 2 ints, first compare left ints, then right ints
   if(year_L < year_R)
   {
       return 1;
   }
   else if ( year_L == year_R)
   {
        if (month_L < month_L)
        {
            return 1;
        }
        else if (month_L == month_L)
        {
            if (day_L < day_R)
            {
                return 1;
            }
            else if (day_L == day_R)
            {
                if (time_L1 < time_R1)
                {
                    return 1;
                }
                else if (time_L1 == time_R1)
                {
                    if (time_L2 < time_R2)
                    {
                        return 1;
                    }
                    else if (time_L2 == time_R2)
                    {
                        return 2;
                    }
                    else//else, time is greater
                    {
                        return 3;
                    }
                }
                else //left time is greater, return 3
                {
                    return 3;
                }
            }
            else
            {
                return 3;
            }
        }
        else
        {
            return 3;
        }
   }
   else //its left is greater than right so return 3 to show that
   {
       return 3;
   }
}
void create(char* my_event_data[5]) {
    //print required sentence
   char * debugvar2 = my_event_data[3];
    if (head == NULL)//if empty calendar, just add it
    {
        insertFront(my_event_data);
        //printf("EARLIEST bc empty list, \n");
        printf("C, ");
        printEventData(my_event_data);
        printf("\n");
        return;
    }
    else
    {
        struct node *link = (struct node*) malloc(sizeof(struct node));
        link->next = NULL;
        for (int i = 1; i < 5; i++)
        {
            link->event_data[i] = my_event_data[i];
        }
        struct node *ptr = head;
        struct node *prev = NULL;
        if (ptr->next == NULL) //if this is the last node to check against
        {
            if (isEarlier(my_event_data, ptr->event_data) == 1)
            { //check against it
                printf("C, ");
                printEventData(my_event_data);
                printf("\n");
                if (prev != NULL) //if this is first item in linked list...
                {
                    link->next = head; //assign something before head
                    head = link; //move head to that thing
                }
                if (prev != NULL)
                {
                    prev->next = link;
                }
                link->next = ptr;
                return;
            }
            else //else is equal to or later, so tack it on after:
            {
                ptr->next = link;
            }
        }
        else
        {
            while (ptr->next != NULL)//if not empty, check each one and add when ready
            {
                //if next node is later than current, we are done with insertion
                if (isEarlier(my_event_data,ptr->event_data) == 1)
                {
                    if (head == ptr) //if earlier than head... insert and print
                    {
                        //printf("earlier than head!");
                        printf("C, ");
                        printEventData(my_event_data);
                        printf("\n");
                        link->next = ptr;
                        head = link;
                    }
                    else //if earlier than non head, insert, but dont print
                    {
                        if (prev != NULL)
                        {
                            prev->next = link;
                        }
                        link->next = ptr;
                    }
                    return;
                }
                else
                {
                    prev = ptr;
                    ptr = ptr->next;
                }
            }
            if (isEarlier(my_event_data,ptr->event_data) == 1) //while ptr-> is null now
            {
                printf("C, ");
                printEventData(my_event_data);
                printf("\n");
                if (prev != NULL)
                {
                    prev->next = link;
                }
                link->next = ptr->next;
                return;
            }
            else
            {
                prev = link;
                link = ptr;
            }
        }
        return;
    }
    //if it gets here, it is the latest meeting, tack it on the end
    //prev->ptr = link;
}
void change(char* my_event_data[5]) {
   //create a link
   struct node *ptr = head;
    while (ptr->next != NULL)//if not empty, check each one and add when ready
    {
        //if next node is later than current, we are done with insertion
        if (*ptr->event_data[1] == *my_event_data[1])
        {
            for (int i = 1; i < 5; i++)
            {
                ptr->event_data[i] = my_event_data[i];
            }
                printf("X, ");
                printEventData(my_event_data);
                printf("\n");
            return;
        }
        ptr = ptr->next;
    }
    if (*ptr->event_data[1] == *my_event_data[1]) //check final node
    {
        for (int i = 0; i < 5; i++)
        {
            ptr->event_data[i] = my_event_data[i];
        }
        printf("X, ");
        printEventData(my_event_data);
        printf("\n");
        return;
    }
    printf("event to change not found");
    return;
    //if it gets here, nothing matched the title to change
}
void delete(char* my_event_data[5])
{
    struct node *ptr = head;
    struct node *prev = NULL;
    while (ptr != NULL)//if not empty, check each one and add when ready
    {
        //if next node is later than current, we are done with insertion
        if ( strcmp( ptr->event_data[1], my_event_data[1] ) == 0) // if title matches, delete it
        {
            if (prev != NULL)
            {
                prev->next = ptr->next;
            }
           if (ptr == head)
           {
               head = ptr->next;
           }
            free(ptr);
            printf("D, ");
            printEventData(my_event_data);
            printf("\n"); 
            return;
        }
        prev = ptr;
        ptr = ptr->next;
    }
}
void emailFilter(char* mySubject)
{
    if (strlen(mySubject) < 9)
    {
        return;
    }
    char * event_holder[5]; //holds five separate char ptrs
    for (int i = 0; i < 5; i++)
    {
        event_holder[i] = ((char*)malloc(100 * sizeof(char*)));
    }
    char command_type = parseSubject(mySubject, event_holder); //parses subject line and fills event_holder. returns command type, from parsing
    //call proper parsing result
    if (command_type == 'C')
    {
         create(event_holder);
    }
    else if (command_type == 'X')
    {
        change(event_holder);
    }
    else if (command_type == 'D')
    {
        delete(event_holder);
    }
}
int main(int argc, char* argv[])
{
    char myItem[100];
    int i = 0;
    while (i < 100)
    {
        scanf("%[^\n]", myItem);
        i++;
        if ( myItem == EOF )
        {
            break;
        }
        int c;
        while ((c = getchar()) != '\n' && c != EOF);
        printf("i = %d\n", i);
        emailFilter(myItem);
    }
    return 0;
}
Also please note that this error happens when I use a txt file as STDIN via the ">" symbol on the command line. Here is the file I use:
Subject: C,Meeting   ,01/12/2019,15:30,NEB202
Subject: C,Meeting   ,01/12/2019,16:30,NEB202
Subject: C,Meeting   ,01/12/2019,11:30,NEB202
 
     
     
    