static void cb_group_invite(Tox *m, int32_t friendnumber, uint8_t type, const uint8_t *group_pub_key, uint16_t length, void *userdata) { if (!friend_is_master(m, friendnumber)) return; char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnumber, (uint8_t *) name, NULL); size_t len = tox_friend_get_name_size(m, friendnumber, NULL); name[len] = '\0'; int groupnum = -1; if (type == TOX_GROUPCHAT_TYPE_TEXT) groupnum = tox_join_groupchat(m, friendnumber, group_pub_key, length); else if (type == TOX_GROUPCHAT_TYPE_AV) groupnum = toxav_join_av_groupchat(m, friendnumber, group_pub_key, length, NULL, NULL); if (groupnum == -1) { fprintf(stderr, "Invite from %s failed (core failure)\n", name); return; } if (group_add(groupnum, type, NULL) == -1) { fprintf(stderr, "Invite from %s failed (group_add failed)\n", name); tox_del_groupchat(m, groupnum); return; } printf("Accepted groupchat invite from %s [%d]\n", name, groupnum); }
QString Core::getPeerName(const ToxId& id) const { QString name; CUserId cid(id.toString()); uint32_t friendId = tox_friend_by_public_key(tox, (uint8_t*)cid.data(), nullptr); if (friendId == std::numeric_limits<uint32_t>::max()) { qWarning() << "getPeerName: No such peer"; return name; } const size_t nameSize = tox_friend_get_name_size(tox, friendId, nullptr); if (nameSize == SIZE_MAX) return name; uint8_t* cname = new uint8_t[nameSize<TOX_MAX_NAME_LENGTH ? TOX_MAX_NAME_LENGTH : nameSize]; if (!tox_friend_get_name(tox, friendId, cname, nullptr)) { qWarning() << "getPeerName: Can't get name of friend "+QString().setNum(friendId); delete[] cname; return name; } name = CString::toString(cname, nameSize); delete[] cname; return name; }
QString Core::getPeerName(const ToxID& id) const { QString name; CUserId cid(id.toString()); uint32_t friendId = tox_friend_by_public_key(tox, (uint8_t*)cid.data(), nullptr); if (friendId == std::numeric_limits<uint32_t>::max()) { qWarning() << "Core::getPeerName: No such peer "+id.toString(); return name; } const size_t nameSize = tox_friend_get_name_size(tox, friendId, nullptr); if (nameSize == SIZE_MAX) { //qDebug() << "Core::getPeerName: Can't get name of friend "+QString().setNum(friendId)+" ("+id.toString()+")"; return name; } uint8_t* cname = new uint8_t[nameSize<TOX_MAX_NAME_LENGTH ? TOX_MAX_NAME_LENGTH : nameSize]; if (tox_friend_get_name(tox, friendId, cname, nullptr) == false) { qWarning() << "Core::getPeerName: Can't get name of friend "+QString().setNum(friendId)+" ("+id.toString()+")"; delete[] cname; return name; } name = name.fromLocal8Bit((char*)cname, nameSize); delete[] cname; return name; }
static void cmd_title_set(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 2) { outmsg = "Error: Two arguments are required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } if (argv[2][0] != '\"') { outmsg = "Error: title must be enclosed in quotes"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } int groupnum = atoi(argv[1]); if (groupnum == 0 && strcmp(argv[1], "0")) { outmsg = "Error: Invalid group number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } /* remove opening and closing quotes */ char title[MAX_COMMAND_LENGTH]; snprintf(title, sizeof(title), "%s", &argv[2][1]); int len = strlen(title) - 1; title[len] = '\0'; char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t nlen = tox_friend_get_name_size(m, friendnum, NULL); name[nlen] = '\0'; TOX_ERR_CONFERENCE_TITLE err; if (!tox_conference_set_title(m, groupnum, (uint8_t *) title, len, &err)) { printf("%s failed to set the title '%s' for group %d\n", name, title, groupnum); outmsg = "Failed to set title. This may be caused by an invalid group number or an empty room"; send_error(m, friendnum, outmsg, err); return; } int idx = group_index(groupnum); memcpy(Tox_Bot.g_chats[idx].title, title, len + 1); Tox_Bot.g_chats[idx].title_len = len; outmsg = "Group title set"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); printf("%s set group %d title to %s\n", name, groupnum, title); }
static void cmd_invite(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; int groupnum = Tox_Bot.default_groupnum; if (argc >= 1) { groupnum = atoi(argv[1]); if (groupnum == 0 && strcmp(argv[1], "0")) { outmsg = "Error: Invalid group number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } } int idx = group_index(groupnum); if (idx == -1) { outmsg = "Group doesn't exist."; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } int has_pass = Tox_Bot.g_chats[idx].has_pass; char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t len = tox_friend_get_name_size(m, friendnum, NULL); name[len] = '\0'; const char *passwd = NULL; if (argc >= 2) { passwd = argv[2]; } if (has_pass && (!passwd || strcmp(argv[2], Tox_Bot.g_chats[idx].password) != 0)) { fprintf(stderr, "Failed to invite %s to group %d (invalid password)\n", name, groupnum); outmsg = "Invalid password."; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } TOX_ERR_CONFERENCE_INVITE err; if (!tox_conference_invite(m, friendnum, groupnum, &err)) { fprintf(stderr, "Failed to invite %s to group %d\n", name, groupnum); outmsg = "Invite failed"; send_error(m, friendnum, outmsg, err); return; } printf("Invited %s to group %d\n", name, groupnum); }
/** * @brief Get the username of a friend */ QString Core::getFriendUsername(uint32_t friendnumber) const { size_t namesize = tox_friend_get_name_size(tox, friendnumber, nullptr); if (namesize == SIZE_MAX) { qWarning() << "getFriendUsername: Failed to get name size for friend "<<friendnumber; return QString(); } uint8_t* name = new uint8_t[namesize]; tox_friend_get_name(tox, friendnumber, name, nullptr); QString sname = CString::toString(name, namesize); delete[] name; return sname; }
/** * Get the null-terminated name of a Tox friend. Must be freed. */ char * twc_get_name_nt(Tox *tox, int32_t friend_number) { TOX_ERR_FRIEND_QUERY err; size_t length = tox_friend_get_name_size(tox, friend_number, &err); if ((err != TOX_ERR_FRIEND_QUERY_OK) || (length == 0)) return twc_get_friend_id_short(tox, friend_number); uint8_t name[length]; tox_friend_get_name(tox, friend_number, name, &err); return twc_null_terminate(name, length); }
/* puts friendnum's nick in buf, truncating at TOXIC_MAX_NAME_LENGTH if necessary. if toxcore API call fails, put UNKNOWN_NAME in buf Returns nick len */ size_t get_nick_truncate(Tox *m, char *buf, uint32_t friendnum) { size_t len = tox_friend_get_name_size(m, friendnum, NULL); if (len == 0) { strcpy(buf, UNKNOWN_NAME); len = strlen(UNKNOWN_NAME); } else { tox_friend_get_name(m, friendnum, (uint8_t *) buf, NULL); } len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1); buf[len] = '\0'; filter_str(buf, len); return len; }
static void cmd_master(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: Tox ID required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } const char *id = argv[1]; if (strlen(id) != TOX_ADDRESS_SIZE * 2) { outmsg = "Error: Invalid Tox ID"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } FILE *fp = fopen(MASTERLIST_FILE, "a"); if (fp == NULL) { outmsg = "Error: could not find masterkeys file"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } fprintf(fp, "%s\n", id); fclose(fp); char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t len = tox_friend_get_name_size(m, friendnum, NULL); name[len] = '\0'; printf("%s added master: %s\n", name, id); outmsg = "ID added to masterkeys list"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); }
static void cmd_leave(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: Group number required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } int groupnum = atoi(argv[1]); if (groupnum == 0 && strcmp(argv[1], "0")) { outmsg = "Error: Invalid group number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } if (!tox_conference_delete(m, groupnum, NULL)) { outmsg = "Error: Invalid group number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } char msg[MAX_COMMAND_LENGTH]; char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t len = tox_friend_get_name_size(m, friendnum, NULL); name[len] = '\0'; group_leave(groupnum); printf("Left group %d (%s)\n", groupnum, name); snprintf(msg, sizeof(msg), "Left group %d", groupnum); tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) msg, strlen(msg), NULL); }
void Core::loadFriends() { const uint32_t friendCount = tox_self_get_friend_list_size(tox); if (friendCount > 0) { // assuming there are not that many friends to fill up the whole stack uint32_t *ids = new uint32_t[friendCount]; tox_self_get_friend_list(tox, ids); uint8_t clientId[TOX_PUBLIC_KEY_SIZE]; for (int32_t i = 0; i < static_cast<int32_t>(friendCount); ++i) { if (tox_friend_get_public_key(tox, ids[i], clientId, nullptr)) { emit friendAdded(ids[i], CUserId::toString(clientId)); const size_t nameSize = tox_friend_get_name_size(tox, ids[i], nullptr); if (nameSize && nameSize != SIZE_MAX) { uint8_t *name = new uint8_t[nameSize]; if (tox_friend_get_name(tox, ids[i], name, nullptr)) emit friendUsernameChanged(ids[i], CString::toString(name, nameSize)); delete[] name; } const size_t statusMessageSize = tox_friend_get_status_message_size(tox, ids[i], nullptr); if (statusMessageSize != SIZE_MAX) { uint8_t *statusMessage = new uint8_t[statusMessageSize]; if (tox_friend_get_status_message(tox, ids[i], statusMessage, nullptr)) { emit friendStatusMessageChanged(ids[i], CString::toString(statusMessage, statusMessageSize)); } delete[] statusMessage; } checkLastOnline(ids[i]); } } delete[] ids; } }
static void cmd_status(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: status required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } TOX_USER_STATUS type; const char *status = argv[1]; if (strcasecmp(status, "online") == 0) { type = TOX_USER_STATUS_NONE; } else if (strcasecmp(status, "away") == 0) { type = TOX_USER_STATUS_AWAY; } else if (strcasecmp(status, "busy") == 0) { type = TOX_USER_STATUS_BUSY; } else { outmsg = "Invalid status. Valid statuses are: online, busy and away."; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } tox_self_set_status(m, type); char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t nlen = tox_friend_get_name_size(m, friendnum, NULL); name[nlen] = '\0'; printf("%s set status to %s\n", name, status); save_data(m, DATA_FILE); }
void utox_friend_init(Tox *tox, uint32_t friend_number){ int size; // get friend pointer FRIEND *f = &friend[friend_number]; uint8_t name[TOX_MAX_NAME_LENGTH]; // Set scroll position to bottom of window. f->msg.scroll = 1.0; // Get and set the public key for this friend number and set it. tox_friend_get_public_key(tox, friend_number, f->cid, 0); // Set the friend number we got from toxcore f->number = friend_number; // Get and set friend name and length size = tox_friend_get_name_size(tox, friend_number, 0); tox_friend_get_name(tox, friend_number, name, 0); // Set the name for utox as well friend_setname(f, name, size); // Get and set the status message size = tox_friend_get_status_message_size(tox, friend_number, 0); f->status_message = malloc(size); tox_friend_get_status_message(tox, friend_number, f->status_message, 0); f->status_length = size; // Get the hex version of this friends ID char_t cid[TOX_PUBLIC_KEY_SIZE * 2]; cid_to_string(cid, f->cid); init_avatar(&f->avatar, cid, NULL, NULL); // Get the chat backlog log_read(tox, friend_number); // Load the meta data, if it exists. friend_meta_data_read(tox, friend_number); }
static void cmd_statusmessage(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: message required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } if (argv[1][0] != '\"') { outmsg = "Error: message must be enclosed in quotes"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } /* remove opening and closing quotes */ char msg[MAX_COMMAND_LENGTH]; snprintf(msg, sizeof(msg), "%s", &argv[1][1]); int len = strlen(msg) - 1; msg[len] = '\0'; tox_self_set_status_message(m, (uint8_t *) msg, len, NULL); char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t nlen = tox_friend_get_name_size(m, friendnum, NULL); name[nlen] = '\0'; printf("%s set status message to \"%s\"\n", name, msg); save_data(m, DATA_FILE); }
static void cmd_purge(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: number > 0 required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } uint64_t days = (uint64_t) atoi(argv[1]); if (days <= 0) { outmsg = "Error: number > 0 required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } uint64_t seconds = days * SECONDS_IN_DAY; Tox_Bot.inactive_limit = seconds; char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t nlen = tox_friend_get_name_size(m, friendnum, NULL); name[nlen] = '\0'; char msg[MAX_COMMAND_LENGTH]; snprintf(msg, sizeof(msg), "Purge time set to %"PRIu64" days", days); tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) msg, strlen(msg), NULL); printf("Purge time set to %"PRIu64" days by %s\n", days, name); }
static void cmd_name(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: Name required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } char name[TOX_MAX_NAME_LENGTH]; int len = 0; if (argv[1][0] == '\"') { /* remove opening and closing quotes */ snprintf(name, sizeof(name), "%s", &argv[1][1]); len = strlen(name) - 1; } else { snprintf(name, sizeof(name), "%s", argv[1]); len = strlen(name); } name[len] = '\0'; tox_self_set_name(m, (uint8_t *) name, (uint16_t) len, NULL); char m_name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) m_name, NULL); size_t nlen = tox_friend_get_name_size(m, friendnum, NULL); m_name[nlen] = '\0'; printf("%s set name to %s\n", m_name, name); save_data(m, DATA_FILE); }
static void cmd_default(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: Room number required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } int groupnum = atoi(argv[1]); if ((groupnum == 0 && strcmp(argv[1], "0")) || groupnum < 0) { outmsg = "Error: Invalid room number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } Tox_Bot.default_groupnum = groupnum; char msg[MAX_COMMAND_LENGTH]; snprintf(msg, sizeof(msg), "Default room number set to %d", groupnum); tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) msg, strlen(msg), NULL); char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t len = tox_friend_get_name_size(m, friendnum, NULL); name[len] = '\0'; printf("Default room number set to %d by %s", groupnum, name); }
int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Tox *const tox1 = tox_new_log(nullptr, nullptr, nullptr); Tox *const tox2 = tox_new_log(nullptr, nullptr, nullptr); printf("bootstrapping tox2 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); struct test_data to_compare = {{0}}; uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox1, public_key); tox_friend_add_norequest(tox2, public_key, nullptr); tox_self_get_public_key(tox2, public_key); tox_friend_add_norequest(tox1, public_key, nullptr); uint8_t reference_name[TOX_MAX_NAME_LENGTH] = { 0 }; uint8_t reference_status[TOX_MAX_STATUS_MESSAGE_LENGTH] = { 0 }; set_random(tox1, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox2, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox1, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); set_random(tox2, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); tox_self_get_name(tox2, reference_name); tox_self_get_status_message(tox2, reference_status); tox_callback_friend_name(tox1, namechange_callback); tox_callback_friend_status_message(tox1, statuschange_callback); while (true) { if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) && tox_friend_get_connection_status(tox1, 0, nullptr) == TOX_CONNECTION_UDP) { printf("Connected.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, nullptr); c_sleep(tox_iteration_interval(tox1)); } while (true) { if (to_compare.received_name && to_compare.received_status_message) { printf("Exchanged names and status messages.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, nullptr); c_sleep(tox_iteration_interval(tox1)); } size_t save_size = tox_get_savedata_size(tox1); VLA(uint8_t, savedata, save_size); tox_get_savedata(tox1, savedata); struct Tox_Options *const options = tox_options_new(nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, savedata, save_size); Tox *const tox_to_compare = tox_new_log(options, nullptr, nullptr); tox_friend_get_name(tox_to_compare, 0, to_compare.name, nullptr); tox_friend_get_status_message(tox_to_compare, 0, to_compare.status_message, nullptr); ck_assert_msg(memcmp(reference_name, to_compare.name, TOX_MAX_NAME_LENGTH) == 0, "incorrect name: should be all zeroes"); ck_assert_msg(memcmp(reference_status, to_compare.status_message, TOX_MAX_STATUS_MESSAGE_LENGTH) == 0, "incorrect status message: should be all zeroes"); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox_to_compare); return 0; }
static void cmd_gmessage(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: Group number required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } if (argc < 2) { outmsg = "Error: Message required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } int groupnum = atoi(argv[1]); if (groupnum == 0 && strcmp(argv[1], "0")) { outmsg = "Error: Invalid group number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } if (group_index(groupnum) == -1) { outmsg = "Error: Invalid group number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } if (argv[2][0] != '\"') { outmsg = "Error: Message must be enclosed in quotes"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } /* remove opening and closing quotes */ char msg[MAX_COMMAND_LENGTH]; snprintf(msg, sizeof(msg), "%s", &argv[2][1]); int len = strlen(msg) - 1; msg[len] = '\0'; TOX_ERR_CONFERENCE_SEND_MESSAGE err; if (!tox_conference_send_message(m, groupnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) msg, strlen(msg), &err)) { outmsg = "Error: Failed to send message."; send_error(m, friendnum, outmsg, err); return; } char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t nlen = tox_friend_get_name_size(m, friendnum, NULL); name[nlen] = '\0'; outmsg = "Message sent."; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); printf("<%s> message to group %d: %s\n", name, groupnum, msg); }
int main(int argc, char *argv[]) { Tox *tox1 = tox_new_log(0, 0, 0); Tox *tox2 = tox_new_log(0, 0, 0); struct test_data to_compare = { { 0 } }; uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox1, public_key); tox_friend_add_norequest(tox2, public_key, NULL); tox_self_get_public_key(tox2, public_key); tox_friend_add_norequest(tox1, public_key, NULL); uint8_t reference_name[TOX_MAX_NAME_LENGTH] = { 0 }; uint8_t reference_status[TOX_MAX_STATUS_MESSAGE_LENGTH] = { 0 }; set_random(tox1, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox2, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox1, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); set_random(tox2, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); tox_self_get_name(tox2, reference_name); tox_self_get_status_message(tox2, reference_status); tox_callback_friend_name(tox1, namechange_callback); tox_callback_friend_status_message(tox1, statuschange_callback); while (true) { if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) && tox_friend_get_connection_status(tox1, 0, 0) == TOX_CONNECTION_UDP) { printf("Connected.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, NULL); c_sleep(tox_iteration_interval(tox1)); } while (true) { if (to_compare.received_name && to_compare.received_status_message) { printf("Exchanged names and status messages.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, NULL); c_sleep(tox_iteration_interval(tox1)); } size_t save_size = tox_get_savedata_size(tox1); VLA(uint8_t, savedata, save_size); tox_get_savedata(tox1, savedata); struct Tox_Options *options = tox_options_new(NULL); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, savedata, save_size); Tox *tox_to_compare = tox_new(options, 0); tox_friend_get_name(tox_to_compare, 0, to_compare.name, 0); tox_friend_get_status_message(tox_to_compare, 0, to_compare.status_message, 0); assert(memcmp(reference_name, to_compare.name, TOX_MAX_NAME_LENGTH) == 0); assert(memcmp(reference_status, to_compare.status_message, TOX_MAX_STATUS_MESSAGE_LENGTH) == 0); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox_to_compare); return 0; }
static void cmd_passwd(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (!friend_is_master(m, friendnum)) { authent_failed(m, friendnum); return; } if (argc < 1) { outmsg = "Error: group number required"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } int groupnum = atoi(argv[1]); if (groupnum == 0 && strcmp(argv[1], "0")) { outmsg = "Error: Invalid group number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } int idx = group_index(groupnum); if (idx == -1) { outmsg = "Error: Invalid group number"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t nlen = tox_friend_get_name_size(m, friendnum, NULL); name[nlen] = '\0'; /* no password */ if (argc < 2) { Tox_Bot.g_chats[idx].has_pass = false; memset(Tox_Bot.g_chats[idx].password, 0, MAX_PASSWORD_SIZE); outmsg = "No password set"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); printf("No password set for group %d by %s\n", groupnum, name); return; } if (strlen(argv[2]) >= MAX_PASSWORD_SIZE) { outmsg = "Password too long"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } Tox_Bot.g_chats[idx].has_pass = true; snprintf(Tox_Bot.g_chats[idx].password, sizeof(Tox_Bot.g_chats[idx].password), "%s", argv[2]); outmsg = "Password set"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); printf("Password for group %d set by %s\n", groupnum, name); }
static void cmd_group(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (argc < 1) { outmsg = "Please specify the group type: audio or text"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } uint8_t type = TOX_CONFERENCE_TYPE_AV ? !strcasecmp(argv[1], "audio") : TOX_CONFERENCE_TYPE_TEXT; char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t len = tox_friend_get_name_size(m, friendnum, NULL); name[len] = '\0'; int groupnum = -1; if (type == TOX_CONFERENCE_TYPE_TEXT) { TOX_ERR_CONFERENCE_NEW err; groupnum = tox_conference_new(m, &err); if (err != TOX_ERR_CONFERENCE_NEW_OK) { printf("Group chat creation by %s failed to initialize\n", name); outmsg = "Group chat instance failed to initialize."; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } } else if (type == TOX_CONFERENCE_TYPE_AV) { groupnum = toxav_add_av_groupchat(m, NULL, NULL); if (groupnum == -1) { printf("Group chat creation by %s failed to initialize\n", name); outmsg = "Group chat instance failed to initialize."; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } } const char *password = argc >= 2 ? argv[2] : NULL; if (password && strlen(argv[2]) >= MAX_PASSWORD_SIZE) { printf("Group chat creation by %s failed: Password too long\n", name); outmsg = "Group chat instance failed to initialize: Password too long"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } if (group_add(groupnum, type, password) == -1) { printf("Group chat creation by %s failed\n", name); outmsg = "Group chat creation failed"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); tox_conference_delete(m, groupnum, NULL); return; } const char *pw = password ? " (Password protected)" : ""; printf("Group chat %d created by %s%s\n", groupnum, name, pw); char msg[MAX_COMMAND_LENGTH]; snprintf(msg, sizeof(msg), "Group chat %d created%s", groupnum, pw); tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) msg, strlen(msg), NULL); }