예제 #1
0
파일: chat.c 프로젝트: prodigeni/toxic
static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t receive_send,
                               uint8_t filenum, uint8_t control_type, const char *data, uint16_t length)
{
    if (self->num != num)
        return;

    const char *filename;
    char msg[MAX_STR_SIZE] = {0};
    int i = 0;   /* file_sender index */

    if (receive_send == 0) {
        filename = friends[num].file_receiver.filenames[filenum];
    } else {
        for (i = 0; i < MAX_FILES; ++i) {
            if (file_senders[i].filenum == filenum)
                break;
        }

        filename = file_senders[i].pathname;
    }

    switch (control_type) {
        case TOX_FILECONTROL_ACCEPT:
            if (receive_send == 1) {
                const char *r_msg =  "File transfer for '%s' accepted.";
                line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, r_msg, filename);

                /* prep progress bar line */
                char progline[MAX_STR_SIZE];
                prep_prog_line(progline);
                line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, progline);
                file_senders[i].line_id = self->chatwin->hst->line_end->id + 2;
                notify(self, silent, NT_NOFOCUS | NT_BEEP | NT_WNDALERT_2);
            }

            break;

        case TOX_FILECONTROL_KILL:
            snprintf(msg, sizeof(msg), "File transfer for '%s' failed.", filename);

            if (receive_send == 0)
                chat_close_file_receiver(num, filenum);

            notify(self, error, NT_NOFOCUS | NT_WNDALERT_2);
            break;

        case TOX_FILECONTROL_FINISHED:
            if (receive_send == 0) {
                snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename);
                chat_close_file_receiver(num, filenum);
                notify(self, transfer_completed, NT_NOFOCUS | NT_WNDALERT_2);
            }

            break;
    }

    if (msg[0])
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
}
예제 #2
0
파일: chat.c 프로젝트: prodigeni/toxic
static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, const char *data,
                            uint16_t length)
{
    if (self->num != num)
        return;

    FILE *fp = friends[num].file_receiver.files[filenum];

    if (fp) {
        if (fwrite(data, length, 1, fp) != 1) {
            line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Error writing to file.");
            tox_file_send_control(m, num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0);
            chat_close_file_receiver(num, filenum);
        }
    }

    friends[num].file_receiver.bps[filenum] += length;
    double remain = (double) tox_file_data_remaining(m, num, filenum, 1);
    uint64_t curtime = get_unix_time();

    /* refresh line with percentage complete and transfer speed (must be called once per second) */
    if (!remain || timed_out(friends[num].file_receiver.last_progress[filenum], curtime, 1)) {
        friends[num].file_receiver.last_progress[filenum] = curtime;
        uint64_t size = friends[num].file_receiver.size[filenum];
        double pct_remain = remain > 0 ? (1 - (remain / size)) * 100 : 100;
        print_progress_bar(self, filenum, num, pct_remain);
        friends[num].file_receiver.bps[filenum] = 0;
    }
}
예제 #3
0
파일: chat_commands.c 프로젝트: zetok/toxic
void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
    if (argc < 2) {
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Requires type in|out and the file ID.");
        return;
    }

    const char *inoutstr = argv[1];
    int filenum = atoi(argv[2]);

    if (filenum >= MAX_FILES || filenum < 0) {
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
        return;
    }

    if (strcasecmp(inoutstr, "in") == 0) {    /* cancel an incoming file transfer */
        if (!Friends.list[self->num].file_receiver[filenum].active) {
            line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
            return;  
        }

        const char *filepath = Friends.list[self->num].file_receiver[filenum].filename;
        char name[MAX_STR_SIZE];
        get_file_name(name, sizeof(name), filepath);
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer for '%s' canceled.", name);
        chat_close_file_receiver(m, filenum, self->num, TOX_FILECONTROL_KILL);
        return;
    } else if (strcasecmp(inoutstr, "out") == 0) {    /* cancel an outgoing file transfer */
        int i;
        bool match = false;

        for (i = 0; i < MAX_FILES; ++i) {
            if (file_senders[i].active && file_senders[i].filenum == filenum) {
                match = true;
                break;
            }
        }

        if (!match) {
            line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
            return;  
        }

        const char *filename = file_senders[i].filename;
        char msg[MAX_STR_SIZE];
        snprintf(msg, sizeof(msg), "File transfer for '%s' canceled.", filename);
        close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, self->num);
        return;
    } else {
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type must be 'in' or 'out'.");
        return;
    }
}