int m_addfriend_norequest(uint8_t * client_id) { if (getfriend_id(client_id) != -1) return -1; /* resize the friend list if necessary */ realloc_friendlist(numfriends + 1); uint32_t i; for (i = 0; i <= numfriends; ++i) { if(friendlist[i].status == NOFRIEND) { DHT_addfriend(client_id); friendlist[i].status = FRIEND_REQUESTED; friendlist[i].crypt_connection_id = -1; friendlist[i].friend_request_id = -1; memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); friendlist[i].statusmessage = calloc(1, 1); friendlist[i].statusmessage_length = 1; friendlist[i].userstatus = USERSTATUS_NONE; friendlist[i].message_id = 0; friendlist[i].receives_read_receipts = 1; /* default: YES */ ++numfriends; return i; } } return -1; }
int m_addfriend_norequest(Messenger *m, uint8_t *client_id) { if (getfriend_id(m, client_id) != -1) return -1; /* resize the friend list if necessary */ if (realloc_friendlist(m, m->numfriends + 1) != 0) return FAERR_NOMEM; memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); uint32_t i; for (i = 0; i <= m->numfriends; ++i) { if (m->friendlist[i].status == NOFRIEND) { DHT_addfriend(client_id); m->friendlist[i].status = FRIEND_CONFIRMED; m->friendlist[i].crypt_connection_id = -1; m->friendlist[i].friendrequest_lastsent = 0; memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE); m->friendlist[i].statusmessage = calloc(1, 1); m->friendlist[i].statusmessage_length = 1; m->friendlist[i].userstatus = USERSTATUS_NONE; m->friendlist[i].message_id = 0; m->friendlist[i].receives_read_receipts = 1; /* default: YES */ if (m->numfriends == i) ++ m->numfriends; return i; } } return -1; }
/* remove a friend return 0 if success return -1 if failure */ int m_delfriend(int friendnumber) { if (friendnumber >= numfriends || friendnumber < 0) return -1; DHT_delfriend(friendlist[friendnumber].client_id); crypto_kill(friendlist[friendnumber].crypt_connection_id); free(friendlist[friendnumber].statusmessage); memset(&friendlist[friendnumber], 0, sizeof(Friend)); uint32_t i; for (i = numfriends; i != 0; --i) { if (friendlist[i-1].status != NOFRIEND) break; } numfriends = i; realloc_friendlist(numfriends + 1); return 0; }
/* * add a friend * set the data that will be sent along with friend request * client_id is the client id of the friend * data is the data and length is the length * returns the friend number if success * return FA_TOOLONG if message length is too long * return FAERR_NOMESSAGE if no message (message length must be >= 1 byte) * return FAERR_OWNKEY if user's own key * return FAERR_ALREADYSENT if friend request already sent or already a friend * return FAERR_UNKNOWN for unknown error */ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) { if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) return FAERR_TOOLONG; if (length < 1) return FAERR_NOMESSAGE; if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) return FAERR_OWNKEY; if (getfriend_id(client_id) != -1) return FAERR_ALREADYSENT; /* resize the friend list if necessary */ realloc_friendlist(numfriends + 1); uint32_t i; for (i = 0; i <= numfriends; ++i) { if (friendlist[i].status == NOFRIEND) { DHT_addfriend(client_id); friendlist[i].status = FRIEND_ADDED; friendlist[i].crypt_connection_id = -1; friendlist[i].friend_request_id = -1; memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); friendlist[i].statusmessage = calloc(1, 1); friendlist[i].statusmessage_length = 1; friendlist[i].userstatus = USERSTATUS_NONE; memcpy(friendlist[i].info, data, length); friendlist[i].info_size = length; friendlist[i].message_id = 0; friendlist[i].receives_read_receipts = 1; /* default: YES */ ++numfriends; return i; } } return FAERR_UNKNOWN; }
/* remove a friend return 0 if success return -1 if failure */ int m_delfriend(Messenger *m, int friendnumber) { if (friendnumber >= m->numfriends || friendnumber < 0) return -1; DHT_delfriend(m->friendlist[friendnumber].client_id); crypto_kill(m->friendlist[friendnumber].crypt_connection_id); free(m->friendlist[friendnumber].statusmessage); memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); uint32_t i; for (i = m->numfriends; i != 0; --i) { if (m->friendlist[i - 1].status != NOFRIEND) break; } m->numfriends = i; if (realloc_friendlist(m, m->numfriends) != 0) return FAERR_NOMEM; return 0; }
/* * add a friend * set the data that will be sent along with friend request * address is the address of the friend (returned by getaddress of the friend you wish to add) it must be FRIEND_ADDRESS_SIZE bytes. TODO: add checksum. * data is the data and length is the length * returns the friend number if success * return FA_TOOLONG if message length is too long * return FAERR_NOMESSAGE if no message (message length must be >= 1 byte) * return FAERR_OWNKEY if user's own key * return FAERR_ALREADYSENT if friend request already sent or already a friend * return FAERR_UNKNOWN for unknown error * return FAERR_BADCHECKSUM if bad checksum in address * return FAERR_SETNEWNOSPAM if the friend was already there but the nospam was different * (the nospam for that friend was set to the new one) * return FAERR_NOMEM if increasing the friend list size fails */ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) { if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) return FAERR_TOOLONG; uint8_t client_id[crypto_box_PUBLICKEYBYTES]; memcpy(client_id, address, crypto_box_PUBLICKEYBYTES); uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check)); if (check != checksum) return FAERR_BADCHECKSUM; if (length < 1) return FAERR_NOMESSAGE; if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) return FAERR_OWNKEY; int friend_id = getfriend_id(m, client_id); if (friend_id != -1) { uint32_t nospam; memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam)); if (m->friendlist[friend_id].friendrequest_nospam == nospam) return FAERR_ALREADYSENT; m->friendlist[friend_id].friendrequest_nospam = nospam; return FAERR_SETNEWNOSPAM; } /* resize the friend list if necessary */ if (realloc_friendlist(m, m->numfriends + 1) != 0) return FAERR_NOMEM; memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); uint32_t i; for (i = 0; i <= m->numfriends; ++i) { if (m->friendlist[i].status == NOFRIEND) { DHT_addfriend(client_id); m->friendlist[i].status = FRIEND_ADDED; m->friendlist[i].crypt_connection_id = -1; m->friendlist[i].friendrequest_lastsent = 0; m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT; memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE); m->friendlist[i].statusmessage = calloc(1, 1); m->friendlist[i].statusmessage_length = 1; m->friendlist[i].userstatus = USERSTATUS_NONE; memcpy(m->friendlist[i].info, data, length); m->friendlist[i].info_size = length; m->friendlist[i].message_id = 0; m->friendlist[i].receives_read_receipts = 1; /* default: YES */ memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); if (m->numfriends == i) ++ m->numfriends; return i; } } return FAERR_UNKNOWN; }