/* * info.c * * Code regarding the sending and receiving of info, both connection * info and served info * * Copyright (c) 2004 Todd MacDermid * Jack Lloyd * */ #include #include #include #include int cutlass_info_parse(cutlass_t *cut_handle, conn_t *conn, uint8_t *info_packet, struct timespec *now) { cutlass_capability_t tmp_capabilities; uint8_t *packet_loc; uint8_t name_len; packet_loc = info_packet; tmp_capabilities = ntohl(*(cutlass_capability_t *)packet_loc); packet_loc += sizeof(cutlass_capability_t); name_len = *((uint8_t *)packet_loc); if(name_len >= CUTLASS_NAME_LEN) { cutlass_sysmsg(cut_handle, CUT_DEBUG, "cutlass_info_parse: oversized name\n"); return(1); } packet_loc += sizeof(uint8_t); conn->capabilities = tmp_capabilities; strncpy(conn->conn_name, packet_loc, name_len); conn->conn_name[name_len] = 0; conn->have_info = 1; return(0); } int cutlass_info_send(cutlass_t *cut_handle, conn_t *conn, struct timespec *now) { struct cutlass_packet_hdr info_packet_header; uint8_t info_packet_payload[CUT_MSG_LEN_MAX] = { 0 }; uint8_t *packet_loc; uint32_t info_len = 0; packet_loc = info_packet_payload; cutlass_sysmsg(cut_handle, CUT_DEBUG, "cutlass_info_send locking handle\n"); pthread_mutex_lock(&(cut_handle->handle_mutex)); /* DEADLOCK?! */ info_len = sizeof(cut_handle->local_info.capabilities) + sizeof(cut_handle->local_info.name_len) + cut_handle->local_info.name_len; info_packet_header.cut_type = CUT_CONN_INFO; info_packet_header.channel_id = 0; info_packet_header.length = info_len; *((cutlass_capability_t *)packet_loc) = htonl(cut_handle->local_info.capabilities); packet_loc += sizeof(cutlass_capability_t); *((uint8_t *)packet_loc) = cut_handle->local_info.name_len; packet_loc += sizeof(cut_handle->local_info.name_len); memcpy(packet_loc, &(cut_handle->local_info.name), cut_handle->local_info.name_len); cutlass_sysmsg(cut_handle, CUT_DEBUG, "cutlass_info_send unlocking handle\n"); pthread_mutex_unlock(&(cut_handle->handle_mutex)); if(cutlass_send_process(cut_handle, conn, &info_packet_header, info_packet_payload, info_len) != 0) { cutlass_sysmsg(cut_handle, CUT_ERROR, "cutlass_info_send: cutlass_send_process failed\n"); return(-1); } return(0); } int cutlass_info_request(cutlass_t *cut_handle, conn_t *conn, struct timespec *now) { struct cutlass_packet_hdr header; /* Construct the stuff: ping packet, no contents */ header.cut_type = CUT_INFO_REQ; header.channel_id = 0; header.length = 0; if(cutlass_send_process(cut_handle, conn, &header, NULL, 0) != 0) { cutlass_sysmsg(cut_handle, CUT_ERROR, "cutlass_msg_ack: cutlass_send failed\n"); return -1; } return(0); } int cutlass_info_update_all(cutlass_t *cut_handle) { uint8_t conn_array[CUT_HK_ARRAY_SZ * CUT_ID_LEN]; uint8_t *array_loc; conn_t *conn; int i; int num_conn; struct timespec now; if(NULL == cut_handle) { cutlass_sysmsg(cut_handle, CUT_ERROR, "cutlass_info_update_all: Passed a NULL pointer\n"); return(1); } array_loc = conn_array; num_conn = cutlass_conn_list(cut_handle, conn_array, CUT_HK_ARRAY_SZ); cutlass_time(&now); for(i = 0; i < num_conn; i++) { conn = hashtable_fingerprint_find(cut_handle, array_loc); if((NULL != conn) && (conn->conn_state == CUTSTATE_ACTIVE)) { cutlass_info_send(cut_handle, conn, &now); } cutlass_sysmsg(cut_handle, CUT_DEBUG, "cutlass_info_update_all unlocking conn\n"); pthread_mutex_unlock(&(conn->conn_mutex)); } return(0); } int cutlass_nick_change(cutlass_t *cut_handle, char *newnick) { char *tmp_ptr; if((tmp_ptr = strchr(newnick, '\n')) != NULL) { *tmp_ptr = 0; } if(strlen(newnick) > CUTLASS_NAME_LEN - 1) { cutlass_sysmsg(cut_handle, CUT_ERROR, "cutlass_nick_change: Name too long\n"); return(-1); } pthread_mutex_lock(&(cut_handle->handle_mutex)); strncpy(cut_handle->local_info.name, newnick, CUTLASS_NAME_LEN-1); cut_handle->local_info.name_len = strlen(newnick); pthread_mutex_unlock(&(cut_handle->handle_mutex)); cutlass_info_update_all(cut_handle); return(0); }