std::string format_url(const TSS_UUID& tss_uuid, TSS_FLAG store_type) { UUID uuid = from_tss_uuid(tss_uuid); return format_url(from_tss_uuid(tss_uuid), storage_type_from_tss_flag(store_type)); }
void cmd_addpls (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *playlist; xmmsc_result_t *res, *res2; xmmsv_t *val; xmmsv_coll_t *coll; gchar *url; if (argc < 3) { print_error ("Supply path to playlist file"); } if (argc == 3) { playlist = NULL; url = format_url (argv[2], G_FILE_TEST_IS_REGULAR); } else { playlist = argv[2]; url = format_url (argv[3], G_FILE_TEST_IS_REGULAR); } res = xmmsc_coll_idlist_from_playlist_file (conn, url); g_free (url); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_is_error (val)) { print_error ("%s", xmmsv_get_error_old (val)); } if (!xmmsv_get_coll (val, &coll)) { print_error ("Couldn't get collection from result!"); } res2 = xmmsc_playlist_add_idlist (conn, playlist, coll); xmmsc_result_wait (res2); if (xmmsc_result_iserror (res2)) { print_error ("%s", xmmsc_result_get_error (res2)); } print_info ("Playlist with %d entries added", xmmsv_coll_idlist_get_size (coll)); xmmsc_result_unref (res); xmmsc_result_unref (res2); }
void cmd_insert (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *playlist = NULL; guint pos; gchar *url; char *endptr; xmmsc_result_t *res; if (argc < 4) { print_error ("Need a position and a file"); } pos = strtol (argv[2], &endptr, 10); if (*endptr == '\0') { url = format_url (argv[3], G_FILE_TEST_IS_REGULAR); /* No playlist name */ } else { playlist = argv[2]; /* extract playlist name */ pos = strtol (argv[3], NULL, 10); url = format_url (argv[4], G_FILE_TEST_IS_REGULAR); } if (!url) { print_error ("Invalid url"); } res = xmmsc_playlist_insert_url (conn, playlist, pos, url); xmmsc_result_wait (res); if (xmmsc_result_iserror (res)) { print_error ("Unable to add %s at postion %u: %s", url, pos, xmmsc_result_get_error (res)); } xmmsc_result_unref (res); print_info ("Inserted %s at %u", url, pos); g_free (url); }
void cmd_addarg (xmmsc_connection_t *conn, gint argc, gchar **argv) { xmmsc_result_t *res; gchar *playlist = NULL; gchar *url; int arg_start = 3; xmmsv_t *args; if (argc < 4) { print_error ("Need a filename and args to add"); } url = format_url (argv[2], G_FILE_TEST_IS_REGULAR); if (!url) { url = format_url (argv[3], G_FILE_TEST_IS_REGULAR); if (!url) { print_error ("Invalid url"); } else { /* FIXME: Fulhack to check for optional playlist argument */ playlist = argv[2]; arg_start = 4; } } args = args_to_dict (&argv[arg_start], argc - arg_start); res = xmmsc_playlist_add_full (conn, playlist, url, args); xmmsc_result_wait (res); if (xmmsc_result_iserror (res)) { print_error ("Couldn't add %s to playlist: %s\n", url, xmmsc_result_get_error (res)); } xmmsc_result_unref (res); print_info ("Added %s", url); g_free (url); }
void cmd_rinsert (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *playlist; gchar *endptr; xmmsc_result_t *res; guint pos; gint i, fileargn; if (argc < 4) { print_error ("Missing argument(s)"); } pos = strtol (argv[2], &endptr, 10); if (*endptr == '\0') { playlist = NULL; /* No playlist name */ fileargn = 3; } else { playlist = argv[2]; /* extract playlist name */ pos = strtol (argv[3], NULL, 10); fileargn = 4; } for (i = fileargn; i < argc; i++) { gchar *rfile; rfile = format_url (argv[i], G_FILE_TEST_IS_DIR); if (!rfile) { print_info ("Ignoring invalid path '%s'", argv[i]); continue; } res = xmmsc_playlist_rinsert (conn, playlist, pos, rfile); g_free (rfile); xmmsc_result_wait (res); if (xmmsc_result_iserror (res)) { print_info ("Cannot insert path '%s' at position %u: %s", argv[i], pos, xmmsc_result_get_error (res)); } xmmsc_result_unref (res); } }
void cmd_radd (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *playlist = NULL; xmmsc_result_t *res; gint i; if (argc < 3) { print_error ("Missing argument(s)"); } for (i = 2; i < argc; i++) { gchar *rfile; if (i == 2 && argc > 3 && !g_file_test (argv[i], G_FILE_TEST_EXISTS)) { playlist = argv[i]; continue; } rfile = format_url (argv[i], G_FILE_TEST_IS_DIR); if (!rfile) { print_info ("Ignoring invalid path '%s'", argv[i]); continue; } res = xmmsc_playlist_radd (conn, playlist, rfile); g_free (rfile); xmmsc_result_wait (res); if (xmmsc_result_iserror (res)) { print_info ("Cannot add path '%s': %s", argv[i], xmmsc_result_get_error (res)); } xmmsc_result_unref (res); } }
static void add_item_to_playlist (xmmsc_connection_t *conn, gchar *playlist, gchar *item) { xmmsc_result_t *res; gchar *url; url = format_url (item, G_FILE_TEST_IS_REGULAR); if (!url) { print_error ("Invalid url"); } res = xmmsc_playlist_add_url (conn, playlist, url); xmmsc_result_wait (res); g_free (url); if (xmmsc_result_iserror (res)) { print_error ("Couldn't add %s to playlist: %s\n", item, xmmsc_result_get_error (res)); } xmmsc_result_unref (res); print_info ("Added %s", item); }
static struct _send_data * build_dialog (EAccountList *accounts, CamelFolder *outbox, const char *destination) { GtkDialog *gd; GtkWidget *table; int row, num_sources; GList *list = NULL; struct _send_data *data; GtkWidget *send_icon; GtkWidget *recv_icon; GtkWidget *scrolled_window; GtkWidget *label; GtkWidget *status_label; GtkWidget *progress_bar; GtkWidget *cancel_button; struct _send_info *info; char *pretty_url; EAccount *account; EIterator *iter; GList *icon_list; EMEventTargetSendReceive *target; gd = (GtkDialog *)(send_recv_dialog = gtk_dialog_new_with_buttons(_("Send & Receive Mail"), NULL, GTK_DIALOG_NO_SEPARATOR, NULL)); gtk_window_set_modal ((GtkWindow *) gd, FALSE); gconf_bridge_bind_window_size ( gconf_bridge_get (), GCONF_KEY_PREFIX, GTK_WINDOW (send_recv_dialog)); gtk_widget_ensure_style ((GtkWidget *)gd); gtk_container_set_border_width ((GtkContainer *)gd->vbox, 0); gtk_container_set_border_width ((GtkContainer *)gd->action_area, 6); cancel_button = gtk_button_new_with_mnemonic (_("Cancel _All")); gtk_button_set_image ( GTK_BUTTON (cancel_button), gtk_image_new_from_stock ( GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON)); gtk_widget_show (cancel_button); gtk_dialog_add_action_widget (gd, cancel_button, GTK_RESPONSE_CANCEL); icon_list = e_icon_factory_get_icon_list ("mail-send-receive"); if (icon_list) { gtk_window_set_icon_list (GTK_WINDOW (gd), icon_list); g_list_foreach (icon_list, (GFunc) g_object_unref, NULL); g_list_free (icon_list); } num_sources = 0; iter = e_list_get_iterator ((EList *) accounts); while (e_iterator_is_valid (iter)) { account = (EAccount *) e_iterator_get (iter); if (account->source->url) num_sources++; e_iterator_next (iter); } g_object_unref (iter); table = gtk_table_new (num_sources, 4, FALSE); gtk_container_set_border_width (GTK_CONTAINER (table), 6); gtk_table_set_row_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 6); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_container_set_border_width ( GTK_CONTAINER (scrolled_window), 6); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW (scrolled_window), table); gtk_box_pack_start ( GTK_BOX (gd->vbox), scrolled_window, TRUE, TRUE, 0); gtk_widget_show (scrolled_window); /* must bet setup after send_recv_dialog as it may re-trigger send-recv button */ data = setup_send_data (); row = 0; iter = e_list_get_iterator ((EList *) accounts); while (e_iterator_is_valid (iter)) { EAccountService *source; account = (EAccount *) e_iterator_get (iter); source = account->source; if (!account->enabled || !source->url) { e_iterator_next (iter); continue; } /* see if we have an outstanding download active */ info = g_hash_table_lookup (data->active, source->url); if (info == NULL) { send_info_t type; type = get_receive_type (source->url); if (type == SEND_INVALID || type == SEND_SEND) { e_iterator_next (iter); continue; } info = g_malloc0 (sizeof (*info)); info->type = type; d(printf("adding source %s\n", source->url)); info->uri = g_strdup (source->url); info->keep = source->keep_on_server; info->cancel = camel_operation_new (operation_status, info); info->state = SEND_ACTIVE; info->timeout_id = g_timeout_add (STATUS_TIMEOUT, operation_status_timeout, info); g_hash_table_insert (data->active, info->uri, info); list = g_list_prepend (list, info); } else if (info->progress_bar != NULL) { /* incase we get the same source pop up again */ e_iterator_next (iter); continue; } else if (info->timeout_id == 0) info->timeout_id = g_timeout_add (STATUS_TIMEOUT, operation_status_timeout, info); recv_icon = e_icon_factory_get_image ( "mail-inbox", E_ICON_SIZE_LARGE_TOOLBAR); pretty_url = format_url (source->url, account->name); label = gtk_label_new (NULL); gtk_label_set_ellipsize ( GTK_LABEL (label), PANGO_ELLIPSIZE_END); gtk_label_set_markup (GTK_LABEL (label), pretty_url); g_free (pretty_url); progress_bar = gtk_progress_bar_new (); cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); status_label = gtk_label_new ( (info->type == SEND_UPDATE) ? _("Updating...") : _("Waiting...")); gtk_label_set_ellipsize ( GTK_LABEL (status_label), PANGO_ELLIPSIZE_END); /* g_object_set(data->label, "bold", TRUE, NULL); */ gtk_misc_set_alignment (GTK_MISC (label), 0, .5); gtk_misc_set_alignment (GTK_MISC (status_label), 0, .5); gtk_table_attach ( GTK_TABLE (table), recv_icon, 0, 1, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), label, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), progress_bar, 2, 3, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), cancel_button, 3, 4, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), status_label, 1, 2, row+1, row+2, GTK_EXPAND | GTK_FILL, 0, 0, 0); info->progress_bar = progress_bar; info->status_label = status_label; info->cancel_button = cancel_button; info->data = data; g_signal_connect ( cancel_button, "clicked", G_CALLBACK (receive_cancel), info); e_iterator_next (iter); row = row + 2; } g_object_unref (iter); /* Hook: If some one wants to hook on to the sendreceive dialog, this is the way to go. */ target = em_event_target_new_send_receive (em_event_peek(), table, data, row, EM_EVENT_SEND_RECEIVE); e_event_emit ((EEvent *)em_event_peek (), "mail.sendreceive", (EEventTarget *) target); if (outbox && destination) { info = g_hash_table_lookup (data->active, SEND_URI_KEY); if (info == NULL) { info = g_malloc0 (sizeof (*info)); info->type = SEND_SEND; d(printf("adding dest %s\n", destination)); info->uri = g_strdup (destination); info->keep = FALSE; info->cancel = camel_operation_new (operation_status, info); info->state = SEND_ACTIVE; info->timeout_id = g_timeout_add (STATUS_TIMEOUT, operation_status_timeout, info); g_hash_table_insert (data->active, SEND_URI_KEY, info); list = g_list_prepend (list, info); } else if (info->timeout_id == 0) info->timeout_id = g_timeout_add (STATUS_TIMEOUT, operation_status_timeout, info); send_icon = e_icon_factory_get_image ( "mail-outbox", E_ICON_SIZE_LARGE_TOOLBAR); pretty_url = format_url (destination, NULL); label = gtk_label_new (NULL); gtk_label_set_ellipsize ( GTK_LABEL (label), PANGO_ELLIPSIZE_END); gtk_label_set_markup (GTK_LABEL (label), pretty_url); g_free (pretty_url); progress_bar = gtk_progress_bar_new (); cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); status_label = gtk_label_new (_("Waiting...")); gtk_label_set_ellipsize ( GTK_LABEL (status_label), PANGO_ELLIPSIZE_END); gtk_misc_set_alignment (GTK_MISC (label), 0, .5); gtk_misc_set_alignment (GTK_MISC (status_label), 0, .5); gtk_table_attach ( GTK_TABLE (table), send_icon, 0, 1, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), label, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), progress_bar, 2, 3, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), cancel_button, 3, 4, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), status_label, 1, 2, row+1, row+2, GTK_EXPAND | GTK_FILL, 0, 0, 0); info->progress_bar = progress_bar; info->cancel_button = cancel_button; info->data = data; info->status_label = status_label; g_signal_connect ( cancel_button, "clicked", G_CALLBACK (receive_cancel), info); gtk_widget_show_all (table); } gtk_widget_show (GTK_WIDGET (gd)); g_signal_connect (gd, "response", G_CALLBACK (dialog_response), data); g_object_weak_ref ((GObject *) gd, (GWeakNotify) dialog_destroy_cb, data); data->infos = list; data->gd = gd; return data; }
void hash_url(const char* url, const char* port, sha1_t hash) { size_t len = strlen(url) + 3; unsigned char data[len]; format_url(url,port,data); SHA1(data, len, hash); }
int main(int argc, char *argv[]) { if (argc < 3) { // Checking for correct arquments printf("Useage: dhtnode own_hostname own_port\n"); exit(0); } char* my_url = argv[1]; char* my_port = argv[2]; sha1_t my_hash; // Create hash for own address hash_url(my_url, my_port, my_hash); fd_set master; fd_set rfds; int retval; int running = 1; int listensock = create_listen_socket(my_port); con_t server; memset(&server,0,sizeof server); con_t left; memset(&left,0,sizeof left); con_t right; memset(&right,0,sizeof right); FD_SET(STDIN_FILENO, &master); FD_SET(listensock, &master); int fdmax = listensock; struct timeval looptime; while (running) { looptime.tv_sec = 1; looptime.tv_usec = 0; rfds = master; retval = select(fdmax + 1, &rfds, NULL, NULL, &looptime); if (retval == -1) die("select failed"); else if (retval) { if (FD_ISSET(STDIN_FILENO, &rfds)) { int argcount; char** arguments = NULL; int cmd = getcommand(STDIN_FILENO, &argcount, &arguments); printf("got command\n"); if (cmd < 0) { //TODO handle different errors differently printf("error: %d\n", cmd); exit(-1); } switch (cmd) { case USER_EXIT: if(server.state != ST_EMPTY && (argcount == 0 || strcmp(arguments[0],"force"))){//remember strcmp returns 0 on match printf("trying to exit\n"); send_dht_pckt(server.socket,DHT_DEREGISTER_BEGIN,my_hash,my_hash,0,NULL); } else{ printf("exiting\n"); running = 0; } freeargs(argcount, arguments); break; case USER_CONNECT: if(argcount != 2){ printf("usage: connect url port\n"); freeargs(argcount,arguments); break; } if(server.state != ST_EMPTY){ printf("Already connected to the server. Use exit to disconnect.\n"); freeargs(argcount,arguments); break; } printf("connecting to %s:%s\n", arguments[0], arguments[1]); int sock = create_connection(arguments[0], arguments[1]); printf("connection made\n"); FD_SET(sock, &master); if(sock > fdmax) fdmax = sock; server.socket = sock; server.state = ST_WF_SER_SHAKE; freeargs(argcount, arguments); break; case USER_PRINT: printf("printing...\n"); for(int i = 0; i < argcount; i++){ printf("%s:\n",arguments[i]); if(!strcmp(arguments[i],"sockets")){ printf("server, %d %s\n",server.socket,(server.socket != 0 && FD_ISSET(server.socket,&master))? "is set":"not set"); printf("right, %d %s\n",right.socket,(right.socket != 0 && FD_ISSET(right.socket,&master))? "is set":"not set"); printf("left, %d %s\n",left.socket,(left.socket != 0 && FD_ISSET(left.socket,&master))? "is set":"not set"); } else if(!strcmp(arguments[i],"states")){ printf("server, %d\n",server.state); printf("right, %d\n",right.state); printf("left, %d\n",left.state); } } freeargs(argcount,arguments); break; case USER_UNKNW_CMD: printf("unknown command, line was:"); for (int i = 0; i < argcount; i++) { printf(" %s", arguments[i]); } printf("\n"); freeargs(argcount, arguments); break; } } //check for new connections if (FD_ISSET(listensock, &rfds)) { printf("someone is connecting\n"); if(right.state == ST_EMPTY){ right.socket = accept_connection(listensock); if(right.socket < 0){ die(strerror(errno)); } FD_SET(right.socket, &master); if(right.socket > fdmax) fdmax = right.socket; right.state = ST_WF_CLI_SHAKE; } else if (left.state == ST_EMPTY) { left.socket = accept_connection(listensock); if(left.socket < 0){ die(strerror(errno)); } FD_SET(left.socket, &master); if(left.socket > fdmax) fdmax = left.socket; left.state = ST_WF_CLI_SHAKE; } } //check for msg from server if(server.state != ST_EMPTY && FD_ISSET(server.socket, &rfds)){ int status; if(server.state == ST_WF_SER_SHAKE){ printf("getting shake\n"); status = recvdata(server.socket, NULL); if(status == NTW_SERVER_SHAKE){ printf("shaking back\n"); send_shake(server.socket, NTW_CLIENT_SHAKE); unsigned char formated_url[strlen(my_url)+3]; format_url(my_url, my_port, formated_url); printf("sending DHT_REGISTER_BEGIN\n"); send_dht_pckt(server.socket,DHT_REGISTER_BEGIN,my_hash,my_hash,strlen(my_url)+3,formated_url); server.state = ST_ONLINE; } //TODO error handling /*On correct shake shake back and send DHT_REGISTER_BEGIN with our sha1 as sender and target and our port+url as payload switch state to ST_ONLINE*/ } else{ DHT_t packet; memset(&packet, 0, sizeof packet); status = recvdata(server.socket, &packet); if(status != NTW_PACKET_OK){ switch(status){ case NTW_ERR_SERIOUS: die(strerror(errno)); break; case NTW_DISCONNECT: die("server disconnected"); break; default: printf("getting packet failed somehow\n"); memset(&packet, 0, sizeof packet); break; } } printf("received from server:\n"); print_dht_packet(&packet); //TODO error handling uint16_t reqt = ntohs(packet.req_type); if(server.state == ST_ONLINE && reqt == DHT_REGISTER_FAKE_ACK){ printf("fake ack received\n"); /*send DHT_REGISTER_DONE to server target and sender are both our hash state to ST_IDLING*/ int a = send_dht_pckt(server.socket, DHT_REGISTER_DONE, my_hash, my_hash, 0, NULL); if(a == 0) server.state = ST_IDLING; else exit(1); // or error handling } else if(server.state == ST_IDLING && reqt == DHT_REGISTER_BEGIN){ printf("dht_register_begin received\n"); /*open connection to the new node which port+url is in packet and send data + DHT_REGISTER_ACK our hash sender and target state to ST_WF_REG_DONE*/ char his_url[packet.pl_length-2]; strcpy(his_url,(char*)packet.payload+2); uint16_t* port = (uint16_t*)packet.payload; *port = ntohs(*port); char his_port[10]; sprintf(his_port,"%u",*port); int sock = create_connection(his_url,his_port); FD_SET(sock, &master); if(sock > fdmax) fdmax = sock; con_t* pal; pal = (right.state == ST_EMPTY) ? &right : &left; memcpy(pal->hash,packet.sender,20); pal->socket = sock; pal->state = ST_WF_SER_SHAKE; //server.state = ST_WF_REG_DONE; } else if(server.state == ST_IDLING && reqt == DHT_REGISTER_DONE){ printf("received reg done\n"); //server.state = ST_IDLING; /*dump old data and return to ST_IDLING*/ } else if(server.state == ST_IDLING && reqt == DHT_DEREGISTER_ACK){ printf("dereg ack received\n"); /*open connection to neighbours their urls are as payload of the package and send data and DHT_DEREGISTER_BEGIN (our hash as sender and target) change to ST_WF_DEREG_DONE*/ uint16_t port_buf = ((uint16_t*)packet.payload)[0]; port_buf = ntohs(port_buf); char port1[10]; sprintf(port1,"%u",port_buf); char url1[30]; strcpy(url1,(char*)(packet.payload+2)); port_buf = ((uint16_t*)(packet.payload+3+strlen(url1)))[0]; port_buf = ntohs(port_buf); char port2[10]; sprintf(port2,"%u",port_buf); char url2[30]; strcpy(url2,(char*)(packet.payload+5+strlen(url1))); printf("parsing got:\nurl1 = %s:%s\nurl2 = %s:%s\n", url1, port1, url2, port2); //connect to right neighbour right.socket = create_connection(url1,port1); FD_SET(right.socket, &master); if(right.socket > fdmax) fdmax = right.socket; hash_url(url1,port1,right.hash); right.state = ST_WF_SER_SHAKE; //connect to left neighbour left.socket = create_connection(url2,port2); FD_SET(left.socket, &master); if(left.socket > fdmax) fdmax = left.socket; hash_url(url2,port2,left.hash); left.state = ST_WF_SER_SHAKE; server.state = ST_WF_DEREG_DONE; } else if(server.state == ST_IDLING && reqt == DHT_DEREGISTER_DENY){ printf("dereg deny received\n"); /*tell user that leaving is impossible return to ST_IDLING*/ printf("Unable to exit. You are the last node. To over-ride this use exit force command.\n"); server.state = ST_IDLING; } else if(server.state == ST_WF_DEREG_DONE && reqt == DHT_DEREGISTER_DONE){ if(right.state == ST_DEREG_DATA_SENT && !memcmp(right.hash, packet.sender, 20)){ FD_CLR(right.socket, &master); close(right.socket); memset(&right,0,sizeof right); } else if(left.state == ST_DEREG_DATA_SENT && !memcmp(left.hash, packet.sender, 20)){ FD_CLR(left.socket, &master); close(left.socket); memset(&left,0,sizeof left); } if(left.state == ST_EMPTY && right.state == ST_EMPTY){ printf("leaving the network\n"); close(server.socket); FD_CLR(server.socket, &master); memset(&server,0,sizeof server); printf("left the network\n"); } /*close the connection to server state to ST_EMPTY*/ } } } } for(int i = 0; i<2;i++){ con_t* neighbour = (i == 0) ? &right : &left; //check for msg from right and left neighbour if(neighbour->state != ST_EMPTY && FD_ISSET(neighbour->socket, &rfds)){ int status; if(neighbour->state == ST_WF_CLI_SHAKE){ /* prepare to receive data switch state to ST_RCV_DATA_REG or ST_RCV_DATA_DEREG depending on server state*/ status = recvdata(neighbour->socket, NULL); if(status == NTW_CLIENT_SHAKE){ if(server.state == ST_ONLINE){ neighbour->state = ST_RCV_DATA_REG; } if(server.state == ST_IDLING){ neighbour->state = ST_RCV_DATA_DEREG; } } else { switch(status){ case NTW_ERR_SERIOUS: die(strerror(errno)); break; case NTW_DISCONNECT: printf("%s disconnected\n",(i)?"left":"right"); FD_CLR(neighbour->socket,&master); memset(neighbour,0,sizeof *neighbour); break; default: printf("getting shake failed somehow\n"); break; } } } else if (neighbour->state == ST_WF_SER_SHAKE){ /* answer with client shake and pump your data to the neighbour after that send DHT_REGISTER_ACK or DHT_DEREG_BEGIN either way after this the connection to neighbour can be disconnected*/ status = recvdata(neighbour->socket, NULL); if(status == NTW_SERVER_SHAKE){ printf("shaking back\n"); send_shake(neighbour->socket, NTW_CLIENT_SHAKE); if(server.state == ST_IDLING){ //we should end with DHT_REGISTER_ACK send_dht_pckt(neighbour->socket,DHT_REGISTER_ACK,my_hash,my_hash,0,NULL); FD_CLR(neighbour->socket, &master); close(neighbour->socket); memset(neighbour,0,sizeof *neighbour); } if(server.state == ST_WF_DEREG_DONE){ //we should end with DHT_DEREGISTER_BEGIN send_dht_pckt(neighbour->socket,DHT_DEREGISTER_BEGIN,my_hash,my_hash,0,NULL); FD_CLR(neighbour->socket, &master); close(neighbour->socket); neighbour->state = ST_DEREG_DATA_SENT; } } else { switch(status){ case NTW_ERR_SERIOUS: die(strerror(errno)); break; case NTW_DISCONNECT: die("neighbour disconnected"); break; default: printf("getting shake failed somehow\n"); break; } } } else{ DHT_t packet; memset(&packet, 0, sizeof packet); status = recvdata(neighbour->socket, &packet); printf("received package from %s:\n",(i)?"left":"right"); print_dht_packet(&packet); if(status != NTW_PACKET_OK){ switch(status){ case NTW_ERR_SERIOUS: die(strerror(errno)); break; case NTW_DISCONNECT: printf("%s neighbour disconnected.\n",(i)?"left":"right"); FD_CLR(neighbour->socket,&master); close(neighbour->socket); memset(neighbour,0,sizeof * neighbour); break; case NTW_ERR_TIMEOUT: printf("package from %s timed out!\n",(i)?"left":"right"); memset(&packet,0,sizeof packet); break; } } uint16_t reqt = ntohs(packet.req_type); if(neighbour->state == ST_RCV_DATA_REG && reqt == DHT_REGISTER_ACK){ /*all data is now received */ FD_CLR(neighbour->socket, &master); close(neighbour->socket); memset(neighbour,0,sizeof *neighbour); neighbour->state = ST_REG_DATA_RCVD; if(right.state == ST_REG_DATA_RCVD && left.state == ST_REG_DATA_RCVD){ send_dht_pckt(server.socket, DHT_REGISTER_DONE, my_hash, my_hash, 0, NULL); right.state = ST_EMPTY; left.state = ST_EMPTY; server.state = ST_IDLING; } } else if(neighbour->state == ST_RCV_DATA_DEREG && reqt == DHT_DEREGISTER_BEGIN){ send_dht_pckt(server.socket, DHT_DEREGISTER_DONE, packet.sender, my_hash, 0, NULL); FD_CLR(neighbour->socket, &master); close(neighbour->socket); memset(neighbour,0,sizeof *neighbour); } } } } } close(listensock); return 0; }