do i need to free() anything else?
#include "friends.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void init(User *user) {
    user->friends[MAX_FRIENDS - 1] = NULL;
}
/*
 * Create a new user with the given name.  Insert it at the tail of the list
 * of users whose head is pointed to by *user_ptr_add.
 *
 * Return:
 *   - 0 if successful
 *   - 1 if a user by this name already exists in this list
 *   - 2 if the given name cannot fit in the 'name' array
 *       (don't forget about the null terminator)
 */
int create_user(const char *name, User **user_ptr_add) {
    if (strlen(name) > 33) {
        return 2;
    }
    struct user *new_user = malloc(sizeof(struct user));
    strcpy(new_user->name, name);
    new_user->next = NULL;

    struct user *last = *user_ptr_add;
    while (last != NULL) {
        if (strcmp(last->name, name) == 0) {
            return 1;
        }
        last = last->next;
    }

    if (*user_ptr_add == NULL) {
        *user_ptr_add = new_user;
    }
    else {
        last = *user_ptr_add;
        while (last->next != NULL) {
            last = last->next;
        }
        last->next = new_user;
    }
    init(new_user);
    free(new_user);
    return 0;
}




/*
 * Return a pointer to the user with this name in
 * the list starting with head. Return NULL if no such user exists.
 *
 * NOTE: You'll likely need to cast a (const User *) to a (User *)
 * to satisfy the prototype without warnings.
 */
User *find_user(const char *name, const User *head) {

    const User *curr = head;
    while (curr != NULL) {
        if (strcmp(curr->name, name) == 0) {
            return (User *)curr;
        }
        curr = curr->next;
    }
    return NULL;
}


/*
 * Print the usernames of all users in the list starting at curr.
 * Names should be printed to standard output, one per line.
 */
void list_users(const User *curr) {
    printf("User List\n");
    while (curr != NULL) {
        printf("    %s\n", curr->name);
        curr = curr->next;
    }
}


/*
 * Change the filename for the profile pic of the given user.
 *
 * Return:
 *   - 0 on success.
 *   - 1 if the file does not exist or cannot be opened.
 *   - 2 if the filename is too long.
 */
int update_pic(User *user, const char *filename) {

    if (strlen(filename) >= 33) {
        return 2;
    }
    if (fopen(filename, "r") == NULL) {
        return 1;
    } else {
        strcpy(user->profile_pic, filename);
        return 0;
    }
}


/*
 * Make two users friends with each other.  This is symmetric - a pointer to
 * each user must be stored in the 'friends' array of the other.
 *
 * New friends must be added in the first empty spot in the 'friends' array.
 *
 * Return:
 *   - 0 on success.
 *   - 1 if the two users are already friends.
 *   - 2 if the users are not already friends, but at least one already has
 *     MAX_FRIENDS friends.
 *   - 3 if the same user is passed in twice.
 *   - 4 if at least one user does not exist.
 *
 * Do not modify either user if the result is a failure.
 * NOTE: If multiple errors apply, return the *largest* error code that applies.
 */
int count_friends(const char *name, User *head){
    int count = 0;
    User *user_1 = find_user(name, head);
    for (int i = 0; i < MAX_FRIENDS; i++) {
        if (user_1->friends[i] != NULL) {
            count ++;
        }
    }
    return count;
}


int make_friends(const char *name1, const char *name2, User *head) {
    User *user_1 = find_user(name1, head);
    User *user_2 = find_user(name2, head);
    int friends_name1 = count_friends(name1, head);
    int friends_name2 = count_friends(name2, head);
    if ((user_1 == NULL) | (user_2 == NULL)) {
        return 4;
    }
    if (strcmp(name1, name2) == 0) {
        return 3;
    }
    for (int i = 0; i < MAX_FRIENDS; i++) {
        if ((user_1->friends[i] != user_2) & ((friends_name1 == MAX_FRIENDS) | (friends_name2 == MAX_FRIENDS))) {
            return 2;
        }
        if (user_1->friends[i] == user_2) {
            return 1;
        }
    }
    user_1->friends[friends_name1 + 1] = user_2;
    user_2->friends[friends_name2 + 1] = user_1;
    return 0;
}



/*
 * Print a user profile.
 * For an example of the required output format, see the example output
 * linked from the handout.
 * Return:
 *   - 0 on success.
 *   - 1 if the user is NULL.
 */
int print_user(const User *user) {
    if (user == NULL) {
        return 1;
    }
    int c;
    FILE *file;
    file = fopen(user->profile_pic, "r");
    if (file != NULL) {
        while ((c = fgetc(file)) != EOF)
            printf("%c", c);
        fclose(file);
        printf("\nName: %s\n", user->name);
    }else {
        printf("Name: %s\n", user->name);
    }
    printf("------------------------------------------\n");
    printf("Friends:\n");
    for (int i = 0; i < 10; i++) {
        if (user->friends[i] != NULL) {
            printf("%s\n", user->friends[i]->name);
        }
    }
    printf("------------------------------------------\n");
    printf("Posts: \n");
    Post *cur_post = user->first_post;
    while (cur_post != NULL) {
        if (cur_post->next != NULL) {
            printf("From: %s\n", cur_post->author);
            char *date_str = ctime(cur_post->date);
            printf("Date: %s\n", date_str);
            printf("%s\n\n", cur_post->contents);
            printf("===\n");
            cur_post = cur_post->next;
            printf("\n");
        }
        else {
            printf("From: %s\n", cur_post->author);
            char *date_str = ctime(cur_post->date);
            printf("Date: %s\n", date_str);
            printf("%s\n", cur_post->contents);
            cur_post = cur_post->next;
        }
    }
    printf("------------------------------------------\n");
    return 0;
}


/*
 * Make a new post from 'author' to the 'target' user,
 * containing the given contents, IF the users are friends.
 *
 * Insert the new post at the *front* of the user's list of posts.
 *
 * 'contents' is a pointer to heap-allocated memory - you do not need
 * to allocate more memory to store the contents of the post.
 *
 * Return:
 *   - 0 on success
 *   - 1 if users exist but are not friends
 *   - 2 if either User pointer is NULL
 */
int is_friends(const User *name1, User *name2) {

    int i = 0;
    int friends = 0;
    while (i < MAX_FRIENDS) {
        if (name1 == name2->friends[i]) {
            friends = 1;
        }
        i++;
    }
    return friends;
}

int make_post(const User *author, User *target, char *contents) {

    if (author == NULL | target == NULL) {
        return 2;
    }
    if (!(is_friends(author, target))) {
        return 1;
    }

    Post *new_post = malloc(sizeof(Post));
    if (new_post == NULL) {
        perror("malloc");  // Look up the documentation for perror
        return 2;
    }

    strcpy(new_post->author, author->name);
    new_post->contents = contents;


    time_t *date = malloc(sizeof(time_t));
    if (date == NULL) {
        perror("malloc");  // Look up the documentation for perror
        return 2;
    }
    *date = time(NULL);
    new_post->date = date;
    new_post->next = target->first_post;
    target->first_post = new_post;

    free(new_post);
    free(date);

    return 0;
}


/*
 * From the list pointed to by *user_ptr_del, delete the user
 * with the given name.
 * Remove the deleted user from any lists of friends.
 *
 * Return:
 *   - 0 on success.
 *   - 1 if a user with this name does not exist.
 */

void remove_friends(const char *name, User **user_ptr_r){

    struct user *last = *user_ptr_r;
    while (last != NULL) {
        for (int i = 0; i < MAX_FRIENDS; i++) {
            if (last->friends[i] != NULL && strcmp(last->friends[i]->name, name) == 0) { // find name wanted to be deleted
                last->friends[i] = NULL;
            }
        }
        if (strcmp(last->name, name) == 0) {
            last->friends[MAX_FRIENDS - 1] = NULL;
        }
        last = last->next;
    }
}

int delete_user(const char *name, User **user_ptr_del) {

    struct user *temp = *user_ptr_del, *prev;
    if (find_user(name, temp) == NULL) {
        return 1;
    }

    if (temp != NULL && strcmp(temp->name, name) == 0) {
        *user_ptr_del = temp->next; // Changed head
        free(temp); // free old head
        return 0;
    }

    while (temp != NULL && strcmp(temp->name, name) != 0) {
        prev = temp;
        temp = temp->next;
    }

    Post *post = temp->first_post;
    while (post != NULL) {
        Post *next_post = post->next;
        free(post->contents);
        free(post);
        post = next_post;
    }

    // If key was not present in linked list
    if (temp == NULL){
        return 1;
    }
    remove_friends(name, user_ptr_del);

    prev->next = temp->next;
    free(temp); // Free memory
    return 0;
}