static Tox *init_tox(int ipv4) { /* Init core */ int ipv6 = !ipv4; Tox *m = tox_new(ipv6); /* * TOX_ENABLE_IPV6_DEFAULT is always 1. * Checking it is redundant, this *should* be doing ipv4 fallback */ if (ipv6 && m == NULL) { fprintf(stderr, "IPv6 didn't initialize, trying IPv4\n"); m = tox_new(0); } if (ipv4) fprintf(stderr, "Forcing IPv4 connection\n"); if (m == NULL) return NULL; /* Callbacks */ tox_callback_connection_status(m, on_connectionchange, NULL); tox_callback_typing_change(m, on_typing_change, NULL); tox_callback_friend_request(m, on_request, NULL); tox_callback_friend_message(m, on_message, NULL); tox_callback_name_change(m, on_nickchange, NULL); tox_callback_user_status(m, on_statuschange, NULL); tox_callback_status_message(m, on_statusmessagechange, NULL); tox_callback_friend_action(m, on_action, NULL); tox_callback_group_invite(m, on_groupinvite, NULL); tox_callback_group_message(m, on_groupmessage, NULL); tox_callback_group_action(m, on_groupaction, NULL); tox_callback_group_namelist_change(m, on_group_namelistchange, NULL); tox_callback_file_send_request(m, on_file_sendrequest, NULL); tox_callback_file_control(m, on_file_control, NULL); tox_callback_file_data(m, on_file_data, NULL); #ifdef __linux__ tox_set_name(m, (uint8_t *) "Cool dude", strlen("Cool dude")); #elif defined(__FreeBSD__) tox_set_name(m, (uint8_t *) "Nerd", strlen("Nerd")); #elif defined(__APPLE__) tox_set_name(m, (uint8_t *) "Hipster", strlen("Hipster")); /* This used to users of other Unixes are hipsters */ #else tox_set_name(m, (uint8_t *) "Registered Minix user #4", strlen("Registered Minix user #4")); #endif return m; }
void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Input required."); return; } char nick[MAX_STR_SIZE]; int len = 0; if (argv[1][0] == '\"') { /* remove opening and closing quotes */ snprintf(nick, sizeof(nick), "%s", &argv[1][1]); len = strlen(nick) - 1; nick[len] = '\0'; } else { snprintf(nick, sizeof(nick), "%s", argv[1]); len = strlen(nick); } if (!valid_nick(nick)) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid name."); return; } len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1); nick[len] = '\0'; tox_set_name(m, (uint8_t *) nick, (uint16_t) len); prompt_update_nick(prompt, nick); store_data(m, DATA_FILE); }
void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { char *errmsg; /* check arguments */ if (argc < 1) { errmsg = "Invalid name."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); return; } char *nick = argv[1]; int len = strlen(nick); if (nick[0] == '\"') { ++nick; len -= 2; nick[len] = '\0'; } if (!valid_nick(nick)) { errmsg = "Invalid name."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); return; } len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1); nick[len] = '\0'; tox_set_name(m, (uint8_t *) nick, (uint16_t) len); prompt_update_nick(prompt, nick); store_data(m, DATA_FILE); }
void Core::start() { tox = tox_new(0); if (tox == nullptr) { emit failedToStart(); return; } tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_action(tox, onAction, this); tox_callback_name_change(tox, onFriendNameChange, this); tox_callback_status_message(tox, onStatusMessageChanged, this); tox_callback_user_status(tox, onUserStatusChanged, this); tox_callback_connection_status(tox, onConnectionStatusChanged, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); CString cUsername(Settings::getInstance().getUsername()); tox_set_name(tox, cUsername.data(), cUsername.size()); CString cStatusMessage(Settings::getInstance().getStatusMessage()); tox_set_status_message(tox, cStatusMessage.data(), cStatusMessage.size()); bootstrapDht(); timer->setInterval(30); timer->start(); }
void Core::setUsername(const QString& username) { CString cUsername(username); if (tox_set_name(tox, cUsername.data(), cUsername.size()) == -1) { emit failedToSetUsername(username); } else { emit usernameSet(username); } }
static void load_defaults(Tox *tox) { uint8_t *name = (uint8_t*)DEFAULT_NAME, *status = (uint8_t*)DEFAULT_STATUS; uint16_t name_len = sizeof(DEFAULT_NAME) - 1, status_len = sizeof(DEFAULT_STATUS) - 1; tox_set_name(tox, name, name_len); tox_set_status_message(tox, status, status_len); self.name_length = name_len; memcpy(self.name, name, name_len); self.statusmsg_length = status_len; self.statusmsg = malloc(status_len); memcpy(self.statusmsg, status, status_len); }
void Core::start() { const Settings &settings = Settings::getInstance(); Tox_Options options; options.ipv6enabled = settings.isIPv6Enabled(); options.proxy_type = TOX_PROXY_NONE; options.udp_disabled = 0; tox = tox_new(&options); // if failed to initialize -- try to fallback to ipv4 if (tox == nullptr && settings.isIPv6Enabled() && settings.isIPv4FallbackEnabled()) { options.ipv6enabled = 0; tox = tox_new(&options); } // if still didn't manage to initialize -- throw an error if (tox == nullptr) { emit failedToStart(); return; } loadConfiguration(); tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_action(tox, onAction, this); tox_callback_name_change(tox, onFriendNameChange, this); tox_callback_typing_change(tox, onFriendTypingChange, this); tox_callback_status_message(tox, onStatusMessageChanged, this); tox_callback_user_status(tox, onUserStatusChanged, this); tox_callback_connection_status(tox, onConnectionStatusChanged, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); CString cUsername(settings.getUsername()); tox_set_name(tox, cUsername.data(), cUsername.size()); CString cStatusMessage(settings.getStatusMessage()); tox_set_status_message(tox, cStatusMessage.data(), cStatusMessage.size()); bootstrapDht(); timer->start(tox_do_interval(tox)); }
static Tox *init_tox() { Tox *m = tox_new(1); if (m == NULL) { printf(stderr, "IPv6 didn't initialize, trying IPv4\n"); m = tox_new(0); } if (m == NULL) printf(stderr, "Forcing IPv4 connection\n"); tox_callback_friend_message(m, friend_message, NULL); tox_set_name(m, MY_NAME, strlen(MY_NAME)); // Sets the username return m; }
static Tox *init_tox(void) { Tox_Options tox_opts; tox_opts.ipv6enabled = !arg_opts.use_ipv4; tox_opts.udp_disabled = arg_opts.force_tcp; tox_opts.proxy_enabled = arg_opts.use_proxy; if (tox_opts.proxy_enabled) { tox_opts.proxy_port = arg_opts.proxy_port; snprintf(tox_opts.proxy_address, sizeof(tox_opts.proxy_address), "%s", arg_opts.proxy_address); } /* Init core */ Tox *m = tox_new(&tox_opts); if (tox_opts.ipv6enabled && m == NULL) { fprintf(stderr, "IPv6 failed to initialize. Trying IPv4\n"); tox_opts.ipv6enabled = 0; m = tox_new(&tox_opts); } if (!tox_opts.ipv6enabled) fprintf(stderr, "Forcing IPv4 connection\n"); if (tox_opts.udp_disabled) fprintf(stderr, "UDP disabled\n"); if (tox_opts.proxy_enabled && m == NULL) exit_toxic_err("Proxy error", FATALERR_PROXY); if (m == NULL) return NULL; /* Callbacks */ tox_callback_connection_status(m, on_connectionchange, NULL); tox_callback_typing_change(m, on_typing_change, NULL); tox_callback_friend_request(m, on_request, NULL); tox_callback_friend_message(m, on_message, NULL); tox_callback_name_change(m, on_nickchange, NULL); tox_callback_user_status(m, on_statuschange, NULL); tox_callback_status_message(m, on_statusmessagechange, NULL); tox_callback_friend_action(m, on_action, NULL); tox_callback_group_invite(m, on_groupinvite, NULL); tox_callback_group_message(m, on_groupmessage, NULL); tox_callback_group_action(m, on_groupaction, NULL); tox_callback_group_namelist_change(m, on_group_namelistchange, NULL); tox_callback_file_send_request(m, on_file_sendrequest, NULL); tox_callback_file_control(m, on_file_control, NULL); tox_callback_file_data(m, on_file_data, NULL); #ifdef __linux__ tox_set_name(m, (uint8_t *) "Cool dude", strlen("Cool dude")); #elif defined(__FreeBSD__) tox_set_name(m, (uint8_t *) "Nerd", strlen("Nerd")); #elif defined(__APPLE__) tox_set_name(m, (uint8_t *) "Hipster", strlen("Hipster")); /* This used to users of other Unixes are hipsters */ #else tox_set_name(m, (uint8_t *) "Registered Minix user #4", strlen("Registered Minix user #4")); #endif return m; }
static void tox_thread_message(Tox *tox, ToxAv *av, uint64_t time, uint8_t msg, uint16_t param1, uint16_t param2, void *data) { switch(msg) { case TOX_SETNAME: { /* param1: name length * data: name */ tox_set_name(tox, data, param1); break; } case TOX_SETSTATUSMSG: { /* param1: status length * data: status message */ tox_set_status_message(tox, data, param1); break; } case TOX_SETSTATUS: { /* param1: status */ tox_set_user_status(tox, param1); break; } case TOX_ADDFRIEND: { /* param1: length of message * data: friend id + message */ int r; if(!param1) { STRING* default_add_msg = SPTR(DEFAULT_FRIEND_REQUEST_MESSAGE); r = tox_add_friend(tox, data, default_add_msg->str, default_add_msg->length); } else { r = tox_add_friend(tox, data, data + TOX_FRIEND_ADDRESS_SIZE, param1); } if(r < 0) { uint8_t addf_error; switch(r) { case TOX_FAERR_TOOLONG: addf_error = ADDF_TOOLONG; break; case TOX_FAERR_NOMESSAGE: addf_error = ADDF_NOMESSAGE; break; case TOX_FAERR_OWNKEY: addf_error = ADDF_OWNKEY; break; case TOX_FAERR_ALREADYSENT: addf_error = ADDF_ALREADYSENT; break; case TOX_FAERR_BADCHECKSUM: addf_error = ADDF_BADCHECKSUM; break; case TOX_FAERR_SETNEWNOSPAM: addf_error = ADDF_SETNEWNOSPAM; break; case TOX_FAERR_NOMEM: addf_error = ADDF_NOMEM; break; case TOX_FAERR_UNKNOWN: default: addf_error = ADDF_UNKNOWN; break; } postmessage(FRIEND_ADD, 1, addf_error, data); } else { postmessage(FRIEND_ADD, 0, r, data); } break; } case TOX_DELFRIEND: { /* param1: friend # */ tox_del_friend(tox, param1); postmessage(FRIEND_DEL, 0, 0, data); break; } case TOX_ACCEPTFRIEND: { /* data: FRIENDREQ */ FRIENDREQ *req = data; int r = tox_add_friend_norequest(tox, req->id); postmessage(FRIEND_ACCEPT, (r < 0), (r < 0) ? 0 : r, req); break; } case TOX_SENDMESSAGE: { /* param1: friend # * param2: message length * data: message */ log_write(tox, param1, data, param2, 1, LOG_FILE_MSG_TYPE_TEXT); void *p = data; while(param2 > TOX_MAX_MESSAGE_LENGTH) { uint16_t len = TOX_MAX_MESSAGE_LENGTH - utf8_unlen(p + TOX_MAX_MESSAGE_LENGTH); tox_send_message(tox, param1, p, len); param2 -= len; p += len; } tox_send_message(tox, param1, p, param2); free(data); break; } case TOX_SENDACTION: { /* param1: friend # * param2: message length * data: message */ log_write(tox, param1, data, param2, 1, LOG_FILE_MSG_TYPE_ACTION); void *p = data; while(param2 > TOX_MAX_MESSAGE_LENGTH) { uint16_t len = TOX_MAX_MESSAGE_LENGTH - utf8_unlen(p + TOX_MAX_MESSAGE_LENGTH); tox_send_action(tox, param1, p, len); param2 -= len; p += len; } tox_send_action(tox, param1, p, param2); free(data); break; } case TOX_SENDMESSAGEGROUP: { /* param1: group # * param2: message length * data: message */ tox_group_message_send(tox, param1, data, param2); free(data); break; } case TOX_SENDACTIONGROUP: { /* param1: group # * param2: message length * data: message */ tox_group_action_send(tox, param1, data, param2); free(data); } case TOX_SET_TYPING: { /* param1: friend # */ // Check if user has switched to another friend window chat. // Take care not to react on obsolete data from old Tox instance. _Bool need_resetting = (typing_state.tox == tox) && (typing_state.friendnumber != param1) && (typing_state.sent_value); if(need_resetting) { // Tell previous friend that he's betrayed. tox_set_user_is_typing(tox, typing_state.friendnumber, 0); // Mark that new friend doesn't know that we're typing yet. typing_state.sent_value = 0; } // Mark us as typing to this friend at the moment. // utox_thread_work_for_typing_notifications() will // send a notification if it deems necessary. typing_state.tox = tox; typing_state.friendnumber = param1; typing_state.time = time; //debug("Set typing state for friend (%d): %d\n", typing_state.friendnumber, typing_state.sent_value); break; } case TOX_CALL: { /* param1: friend # */ int32_t id; toxav_call(av, &id, param1, &av_DefaultSettings, 10); postmessage(FRIEND_CALL_STATUS, param1, id, (void*)CALL_RINGING); break; } case TOX_CALL_VIDEO: { /* param1: friend # */ ToxAvCSettings settings = av_DefaultSettings; settings.call_type = av_TypeVideo; settings.max_video_width = max_video_width; settings.max_video_height = max_video_height; int32_t id; toxav_call(av, &id, param1, &settings, 10); postmessage(FRIEND_CALL_STATUS, param1, id, (void*)CALL_RINGING_VIDEO); break; } case TOX_CALL_VIDEO_ON: { /* param1: friend # * param2: call # */ ToxAvCSettings settings = av_DefaultSettings; settings.call_type = av_TypeVideo; settings.max_video_width = max_video_width; settings.max_video_height = max_video_height; toxav_change_settings(av, param2, &settings); postmessage(FRIEND_CALL_START_VIDEO, param1, param2, NULL); break; } case TOX_CALL_VIDEO_OFF: { /* param1: friend # * param2: call # */ toxav_change_settings(av, param2, &av_DefaultSettings); postmessage(FRIEND_CALL_STOP_VIDEO, param1, param2, NULL); break; } case TOX_ACCEPTCALL: { /* param1: call # */ ToxAvCSettings settings = av_DefaultSettings; if(param2) { settings.call_type = av_TypeVideo; settings.max_video_width = max_video_width; settings.max_video_height = max_video_height; } toxav_answer(av, param1, &settings); break; } case TOX_HANGUP: { /* param1: call # */ toxav_hangup(av, param1); break; } case TOX_NEWGROUP: { /* */ int g = -1; if (param1) { g = toxav_add_av_groupchat(tox, &callback_av_group_audio, NULL); } else { g = tox_add_groupchat(tox); } if(g != -1) { postmessage(GROUP_ADD, g, 0, tox); } break; } case TOX_LEAVEGROUP: { /* param1: group # */ tox_del_groupchat(tox, param1); break; } case TOX_GROUPINVITE: { /* param1: group # * param2: friend # */ tox_invite_friend(tox, param2, param1); break; } case TOX_GROUPCHANGETOPIC: { /* param1: group # * param2: topic length * data: topic */ tox_group_set_title(tox, param1, data, param2); postmessage(GROUP_TITLE, param1, param2, data); break; } case TOX_GROUP_AUDIO_START:{ /* param1: group # */ postmessage(GROUP_AUDIO_START, param1, 0, NULL); break; } case TOX_GROUP_AUDIO_END:{ /* param1: group # */ postmessage(GROUP_AUDIO_END, param1, 0, NULL); break; } case TOX_SENDFILES: { /* param1: friend # * param2: offset of first file name in data * data: file names */ if(param2 == 0xFFFF) { //paths with line breaks uint8_t *name = data, *p = data, *s = name; while(*p) { _Bool end = 1; while(*p) { if(*p == '\n') { *p = 0; end = 0; break; } if(*p == '/' || *p == '\\') { s = p + 1; } p++; } if(strcmp2(name, "file://") == 0) { name += 7; } utox_transfer_start_file(tox, param1, name, s, p - s); p++; s = name = p; if(end) { break; } } } else { //windows path list uint8_t *name = data; _Bool multifile = (name[param2 - 1] == 0); if(!multifile) { utox_transfer_start_file(tox, param1, data, data + param2, strlen(data) - param2); } else { uint8_t *p = name + param2; name += param2 - 1; if(*(name - 1) != '\\') { *name++ = '\\'; } while(*p) { int len = strlen((char*)p) + 1; memmove(name, p, len); p += len; utox_transfer_start_file(tox, param1, data, name, len - 1); } } } free(data); break; } case TOX_SEND_INLINE: { /* param1: friend id data: pointer to a TOX_SEND_INLINE_MSG struct */ struct TOX_SEND_INLINE_MSG *tsim = data; utox_transfer_start_memory(tox, param1, tsim->image->png_data, tsim->image_size); free(tsim); break; } case TOX_ACCEPTFILE: { /* param1: friend # * param2: file # * data: path to write file */ FILE_T *ft = &friend[param1].incoming[param2]; ft->data = fopen(data, "wb"); if(!ft->data) { free(data); break; } ft->path = data; ft->status = FT_SEND; tox_file_send_control(tox, param1, 1, param2, TOX_FILECONTROL_ACCEPT, NULL, 0); postmessage(FRIEND_FILE_IN_STATUS, param1, param2, (void*)FILE_OK); break; } case TOX_FILE_IN_CANCEL: { /* param1: friend # * param2: file # */ FILE_T *ft = &friend[param1].incoming[param2]; if(ft->data) { if(ft->inline_png) { free(ft->data); } else { fclose(ft->data); free(ft->path); } } ft->status = FT_NONE; tox_file_send_control(tox, param1, 1, param2, TOX_FILECONTROL_KILL, NULL, 0); postmessage(FRIEND_FILE_IN_STATUS, param1, param2, (void*)FILE_KILLED); break; } case TOX_FILE_OUT_CANCEL: { /* param1: friend # * param2: file # */ FILE_T *ft = &friend[param1].outgoing[param2]; ft->status = FT_KILL; tox_file_send_control(tox, param1, 0, param2, TOX_FILECONTROL_KILL, NULL, 0); postmessage(FRIEND_FILE_OUT_STATUS, param1, param2, (void*)FILE_KILLED); break; } case TOX_FILE_IN_PAUSE: { /* param1: friend # * param2: file # */ tox_file_send_control(tox, param1, 1, param2, TOX_FILECONTROL_PAUSE, NULL, 0); postmessage(FRIEND_FILE_IN_STATUS, param1, param2, (void*)FILE_PAUSED); break; } case TOX_FILE_OUT_PAUSE: { /* param1: friend # * param2: file # */ FILE_T *ft = &friend[param1].outgoing[param2]; ft->status = FT_PAUSE; tox_file_send_control(tox, param1, 0, param2, TOX_FILECONTROL_PAUSE, NULL, 0); postmessage(FRIEND_FILE_OUT_STATUS, param1, param2, (void*)FILE_PAUSED); break; } case TOX_FILE_IN_RESUME: { /* param1: friend # * param2: file # */ tox_file_send_control(tox, param1, 1, param2, TOX_FILECONTROL_ACCEPT, NULL, 0); postmessage(FRIEND_FILE_IN_STATUS, param1, param2, (void*)FILE_OK); break; } case TOX_FILE_OUT_RESUME: { /* param1: friend # * param2: file # */ FILE_T *ft = &friend[param1].outgoing[param2]; ft->status = FT_SEND; tox_file_send_control(tox, param1, 0, param2, TOX_FILECONTROL_ACCEPT, NULL, 0); postmessage(FRIEND_FILE_OUT_STATUS, param1, param2, (void*)FILE_OK); break; } } }
void line_eval(Tox *m, char *line) { if (line[0] == '/') { char inpt_command = line[1]; char prompt[STRING_LENGTH + 2] = "> "; int prompt_offset = 3; strcat(prompt, line); new_lines(prompt); if (inpt_command == 'f') { // add friend command: /f ID int i, delta = 0; char temp_id[128]; for (i = 0; i < 128; i++) { temp_id[i - delta] = line[i + prompt_offset]; if ((temp_id[i - delta] == ' ') || (temp_id[i - delta] == '+')) delta++; } unsigned char *bin_string = hex_string_to_bin(temp_id); int num = tox_add_friend(m, bin_string, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo")); free(bin_string); char numstring[100]; switch (num) { case TOX_FAERR_TOOLONG: sprintf(numstring, "[i] Message is too long."); break; case TOX_FAERR_NOMESSAGE: sprintf(numstring, "[i] Please add a message to your request."); break; case TOX_FAERR_OWNKEY: sprintf(numstring, "[i] That appears to be your own ID."); break; case TOX_FAERR_ALREADYSENT: sprintf(numstring, "[i] Friend request already sent."); break; case TOX_FAERR_UNKNOWN: sprintf(numstring, "[i] Undefined error when adding friend."); break; default: if (num >= 0) { sprintf(numstring, "[i] Added friend as %d.", num); save_data(m); } else sprintf(numstring, "[i] Unknown error %i.", num); break; } new_lines(numstring); } else if (inpt_command == 'd') { tox_do(m); } else if (inpt_command == 'm') { //message command: /m friendnumber messsage char *posi[1]; int num = strtoul(line + prompt_offset, posi, 0); if (**posi != 0) { if (tox_send_message(m, num, (uint8_t *) *posi + 1, strlen(*posi + 1)) < 1) { char sss[256]; sprintf(sss, "[i] could not send message to friend num %u", num); new_lines(sss); } else { print_formatted_message(m, *posi + 1, num, 1); } } else new_lines("Error, bad input."); } else if (inpt_command == 'n') { uint8_t name[TOX_MAX_NAME_LENGTH]; size_t i, len = strlen(line); for (i = 3; i < len; i++) { if (line[i] == 0 || line[i] == '\n') break; name[i - 3] = line[i]; } name[i - 3] = 0; tox_set_name(m, name, i - 2); char numstring[100]; sprintf(numstring, "[i] changed nick to %s", (char *)name); new_lines(numstring); } else if (inpt_command == 'l') { print_friendlist(m); } else if (inpt_command == 's') { uint8_t status[TOX_MAX_STATUSMESSAGE_LENGTH]; size_t i, len = strlen(line); for (i = 3; i < len; i++) { if (line[i] == 0 || line[i] == '\n') break; status[i - 3] = line[i]; } status[i - 3] = 0; tox_set_status_message(m, status, strlen((char *)status)); char numstring[100]; sprintf(numstring, "[i] changed status to %s", (char *)status); new_lines(numstring); } else if (inpt_command == 'a') { // /a #: accept uint8_t numf = atoi(line + 3); char numchar[100]; if (numf >= num_requests || pending_requests[numf].accepted) { sprintf(numchar, "[i] you either didn't receive that request or you already accepted it"); new_lines(numchar); } else { int num = tox_add_friend_norequest(m, pending_requests[numf].id); if (num != -1) { pending_requests[numf].accepted = 1; sprintf(numchar, "[i] friend request %u accepted as friend no. %d", numf, num); new_lines(numchar); save_data(m); } else { sprintf(numchar, "[i] failed to add friend"); new_lines(numchar); } } } else if (inpt_command == 'r') { // /r #: remove friend uint8_t numf = atoi(line + 3); if (!tox_friend_exists(m, numf)) { char err[64]; sprintf(err, "You don't have a friend %i.", numf); new_lines(err); return; } char msg[128 + TOX_MAX_NAME_LENGTH]; char fname[TOX_MAX_NAME_LENGTH ]; getfriendname_terminated(m, numf, fname); sprintf(msg, "Are you sure you want to delete friend %i: %s? (y/n)", numf, fname); input_line[0] = 0; new_lines(msg); int c; do { c = getchar(); } while ((c != 'y') && (c != 'n') && (c != EOF)); if (c == 'y') { int res = tox_del_friend(m, numf); if (res == 0) sprintf(msg, "[i] [%i: %s] is no longer your friend", numf, fname); else sprintf(msg, "[i] failed to remove friend"); new_lines(msg); } } else if (inpt_command == 'h') { //help if (line[2] == ' ') { if (line[3] == 'f') { new_lines_mark(help_friend1, 1); new_lines_mark(help_friend2, 1); return; } else if (line[3] == 'g') { new_lines_mark(help_group, 1); return; } } new_lines_mark(help_main, 1); } else if (inpt_command == 'x') { //info char idstring[200]; get_id(m, idstring); new_lines(idstring); } else if (inpt_command == 'g') { //create new group chat char msg[256]; sprintf(msg, "[g] Created new group chat with number: %u", tox_add_groupchat(m)); new_lines(msg); } else if (inpt_command == 'i') { //invite friendnum to groupnum char *posi[1]; int friendnumber = strtoul(line + prompt_offset, posi, 0); int groupnumber = strtoul(*posi + 1, NULL, 0); char msg[256]; sprintf(msg, "[g] Invited friend number %u to group number %u, returned: %u (0 means success)", friendnumber, groupnumber, tox_invite_friend(m, friendnumber, groupnumber)); new_lines(msg); } else if (inpt_command == 'z') { //send message to groupnum char *posi[1]; int groupnumber = strtoul(line + prompt_offset, posi, 0); if (**posi != 0) { int res = tox_group_message_send(m, groupnumber, (uint8_t *)*posi + 1, strlen(*posi + 1)); if (res == 0) { char msg[32 + STRING_LENGTH]; sprintf(msg, "[g] #%u: YOU: %s", groupnumber, *posi + 1); new_lines(msg); } else { char msg[128]; sprintf(msg, "[i] could not send message to group no. %u: %i", groupnumber, res); new_lines(msg); } } } else if (inpt_command == 't') { char *posi[1]; int friendnum = strtoul(line + prompt_offset, posi, 0); if (**posi != 0) { char msg[512]; sprintf(msg, "[t] Sending file %s to friendnum %u filenumber is %i (-1 means failure)", *posi + 1, friendnum, add_filesender(m, friendnum, *posi + 1)); new_lines(msg); } } else if (inpt_command == 'q') { //exit save_data(m); endwin(); tox_kill(m); exit(EXIT_SUCCESS); } else if (inpt_command == 'c') { //set conversation partner if (line[2] == 'r') { if (conversation_default != 0) { conversation_default = 0; new_lines("[i] default conversation reset"); } else new_lines("[i] default conversation wasn't set, nothing to do"); } else if (line[3] != ' ') { new_lines("[i] invalid command"); } else { int num = atoi(line + 4); /* zero is also returned for not-a-number */ if (!num && strcmp(line + 4, "0")) num = -1; if (num < 0) new_lines("[i] invalid command parameter"); else if (line[2] == 'f') { conversation_default = num + 1; char buffer[128]; sprintf(buffer, "[i] default conversation is now to friend %i", num); new_lines(buffer); } else if (line[2] == 'g') { char buffer[128]; conversation_default = - (num + 1); sprintf(buffer, "[i] default conversation is now to group %i", num); new_lines(buffer); } else new_lines("[i] invalid command"); } } else if (inpt_command == 'p') { //list peers char *posi = NULL; int group_number = strtoul(line + prompt_offset, &posi, 0); if (posi != NULL) { char msg[64]; int peer_cnt = tox_group_number_peers(m, group_number); if (peer_cnt < 0) { new_lines("[g] Invalid group number."); } else if (peer_cnt == 0) { sprintf(msg, "[g] #%i: No peers in group.", group_number); new_lines(msg); } else { sprintf(msg, "[g] #%i: Group has %i peers. Names:", group_number, peer_cnt); new_lines(msg); print_groupchatpeers(m, group_number); } } } else { new_lines("[i] invalid command"); } } else { if (conversation_default != 0) { if (conversation_default > 0) { int friendnumber = conversation_default - 1; uint32_t res = tox_send_message(m, friendnumber, (uint8_t *)line, strlen(line)); if (res == 0) { char sss[128]; sprintf(sss, "[i] could not send message to friend no. %u", friendnumber); new_lines(sss); } else print_formatted_message(m, line, friendnumber, 1); } else { int groupnumber = - conversation_default - 1; int res = tox_group_message_send(m, groupnumber, (uint8_t *)line, strlen(line)); if (res == 0) { char msg[32 + STRING_LENGTH]; sprintf(msg, "[g] #%u: YOU: %s", groupnumber, line); new_lines(msg); } else { char msg[128]; sprintf(msg, "[i] could not send message to group no. %u: %i", groupnumber, res); new_lines(msg); } } } else new_lines("[i] invalid input: neither command nor in conversation"); } }