will this handle partial reads, read one full line and then do something with the full line?
char *read(int client_index, struct sockname *users) {
    int fd = users[client_index].sock.fd;
    char buf[BUFSIZE + 1];

    // Read user input and handle partial reads
    int inbuf = 0;           // Number of bytes in buf
    int room = sizeof(buf);  // How many bytes left in the buf
    char *after = buf;       // Pointer to the position after the data

    int nbytes;

    int command_read = 1;  // Store if a full line has been read

    while ((nbytes = read(fd, after, room)) > 0 || command_read == 1) {
        inbuf += nbytes;
        int where;

        if ((where = find_network_newline(buf, inbuf)) > 0) {  // When full line is read
            buf[where - 2] = '\0';                             // Null terminate the buffer

            // Update inbuf
            inbuf -= where;

            // Move everything after the full
            memmove(buf, buf + (sizeof(char) * where), inbuf);
            command_read = 0;
        }
        // Update after and room
        after = &buf[inbuf];
        room = BUFSIZE - inbuf;
    }
    close(fd);

    // Check for recieved username
    if (users[client_index].username == NULL) {
        users[client_index].username = malloc(sizeof(char) * strlen(buf) + 1);
        if (users[client_index].username == NULL) {
            perror("malloc");
            free(users[client_index].username);
            exit(1);
        }

        // Set the username
        strcpy(users[client_index].username, buf);
        users[client_index].username[strlen(buf) + 1] = '\0';

        return NULL;  // Return NULL if username was set
    } else {          // It is a command
        int cmd_len = strlen(buf) + 1;
        char *command = malloc(sizeof(char) * cmd_len);
        if (command == NULL) {
            perror("malloc");
            exit(1);
        }
        strcpy(command, buf);
        command[length] = '\0';
        return command;  // Return the command
    }
}