static void packet_put(struct interface_t * iface, struct packet_t * packet) { uint16_t dsize = packet_dsize(packet); interface_write(iface, &(packet->header), 2); interface_write(iface, &(packet->length), 2); interface_write(iface, &(packet->command), 1); if(dsize) interface_write(iface, &(packet->data[0]), dsize); interface_write(iface, &(packet->crc), 4); }
void interface_notify_chan(gpointer data, gpointer user_data) { GIOChannel* chan = data; GString* str = user_data; interface_write(chan, str->str); }
/* Interface event -- accept connections, create IO channels for clients */ gboolean interface_event(GIOChannel* source, GIOCondition condition, gpointer data) { int sock; struct sockaddr client_addr; socklen_t addrlen; int client; GIOChannel* client_chan; char client_hostname[NI_MAXHOST]; char client_port[NI_MAXSERV]; sock = g_io_channel_unix_get_fd(source); /* Accept the connection */ addrlen = sizeof(client_addr); client = accept(sock, &client_addr, &addrlen); if (client == -1) g_error("Can't accept connection"); /* Get client IP and port */ int ret = getnameinfo(&client_addr, addrlen, client_hostname, NI_MAXHOST, client_port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV); if (ret != 0) g_error("Can't convert address to text: %s", gai_strerror(ret)); g_info("[ie:%d] Connection from %s:%s", client, client_hostname, client_port); /* Create IO channel for the client, send greetings, and add it to the main loop */ client_chan = g_io_channel_unix_new(client); if (!client_chan) g_error("[ie:%d] Can't create IO channel for the client socket.", client); g_io_channel_set_close_on_unref(client_chan, TRUE); if (!interface_write(client_chan, proto_greetings)) goto ie_client_clean; g_io_add_watch(client_chan, G_IO_IN|G_IO_HUP, interface_client_event, NULL); return TRUE; ie_client_clean: g_io_channel_shutdown(client_chan, TRUE, NULL); g_io_channel_unref(client_chan); g_debug("[ie:%d] Connection closed.", client); return TRUE; }
void interface_finalize(const gchar* str, GIOChannel* chan) { interface_write(chan, str); }
/* Parse the command and execute it */ command_result interface_handle_command(GIOChannel* chan, gchar* command){ GError* err = NULL; gint argc; gchar** argv_; gchar** argv; size_t i; /* Parse the command in a shell-like fashion */ if (!g_shell_parse_argv(g_strstrip(command), &argc, &argv_, &err)) { g_debug("Command parser error: %s", err->message); interface_write(chan, "{ \"error\": \"invalid command\" }\n"); return CR_OK; } /* Copy argv_ to the stack so it's easier to use... */ argv = g_newa(gchar*, argc); for(i=0; i < argc; i++) { argv[i] = g_newa(gchar, strlen(argv_[i]+1)); strcpy(argv[i], argv_[i]); } g_strfreev(argv_); g_debug("Command: [%s] with %d parameter(s)", argv[0], argc-1); /* Now execute the command */ command_full_descriptor* cmd_desc = NULL; for (i=0; g_commands[i].name != NULL; i++) { int nb_args = 0; while ((nb_args < MAX_CMD_ARGS) && (g_commands[i].desc.args[nb_args] != CA_NONE)) nb_args += 1; if ((strcmp(g_commands[i].name, argv[0]) == 0) && (nb_args == argc-1)) { cmd_desc = &(g_commands[i]); break; } } if (!cmd_desc) { interface_write(chan, "{ \"error\": \"unknown command\" }\n"); return CR_OK; } /* Handle "normal" and "special" commands separately. */ switch (cmd_desc->type) { case CT_FUNC: { gboolean ret; ret = command_run((command_finalize_func) interface_finalize, chan, &(cmd_desc->desc), argc, argv); return (ret ? CR_OK : CR_DEFERED); } case CT_BYE: interface_write(chan, "Bye bye!\n"); return CR_CLOSE; case CT_QUIT: g_message("Got a quit command, exiting..."); exit(0); case CT_IDLE: return CR_IDLE; } return CR_OK; }
int interface_recovery(disk_t *disk_car, const list_part_t * list_part_org, const int verbose, const int dump_ind, const int align, const int ask_part_order, const unsigned int expert, char **current_cmd) { int res_interface_write; int fast_mode=0; do { list_part_t *list_part; const list_part_t *element; unsigned int menu=0; if(fast_mode==0) menu=3; /* Search! */ #ifdef HAVE_NCURSES aff_copy(stdscr); wmove(stdscr,4,0); wprintw(stdscr,"%s",disk_car->description(disk_car)); wmove(stdscr,5,0); #endif res_interface_write=0; list_part=search_part(disk_car, list_part_org, verbose, dump_ind, fast_mode, current_cmd); if(list_part!=NULL && (disk_car->arch==&arch_i386 || disk_car->arch==&arch_sun)) { /* Correct disk geometry is necessary for successfull Intel and Sun partition recovery */ const unsigned int heads_per_cylinder=get_geometry_from_list_part(disk_car, list_part, verbose); if(disk_car->geom.heads_per_cylinder!=heads_per_cylinder) { log_warning("Warning: the current number of heads per cylinder is %u but the correct value may be %u.\n", disk_car->geom.heads_per_cylinder, heads_per_cylinder); #ifdef HAVE_NCURSES if(*current_cmd==NULL) { warning_geometry_ncurses(disk_car, heads_per_cylinder); } #endif } } align_structure(list_part, disk_car, align); disk_car->arch->init_structure(disk_car,list_part,verbose); if(verbose>0) { #ifdef TARGET_LINUX unsigned int i=0; #endif /* Write found partitions in the log file */ log_info("\nResults\n"); for(element=list_part;element!=NULL;element=element->next) log_partition(disk_car,element->part); #ifdef TARGET_LINUX if(list_part!=NULL) log_info("\nHint for advanced users: dmsetup may be used if you prefer to avoid rewriting the partition table for the moment:\n"); for(element=list_part;element!=NULL;element=element->next) { const partition_t *partition=element->part; log_info("echo \"0 %llu linear %s %llu\" | dmsetup create test%u\n", (long long unsigned)(partition->part_size/512), disk_car->device, (long long unsigned)(partition->part_offset/512), i++); } #endif } do { list_part=ask_structure(disk_car,list_part,verbose,current_cmd); } while(fast_mode!=0 && list_part!=NULL && is_structure_empty(list_part) #ifdef HAVE_NCURSES && ask_confirmation("Discard the results, confirm ? (Y/N)")==0 #endif ); if(disk_car->arch->test_structure(list_part)==0) { int do_again=0; int max_ext=0; int can_ask_minmax_ext=0; int no_confirm=0; list_part=reduce_structure(list_part); /* sort list_part */ list_part=sort_partition_list(list_part); /* Create PC/Intel Extended partition */ /* if(disk_car->arch==&arch_i386) */ { list_part_t *parts; uint64_t partext_offset=0; uint64_t partext_size=0; list_part=add_ext_part_i386(disk_car, list_part, !max_ext, verbose); for(parts=list_part;parts!=NULL;parts=parts->next) if(parts->part->status==STATUS_EXT) { partext_offset=parts->part->part_offset; partext_size=parts->part->part_size; } if(partext_offset>0) { list_part=add_ext_part_i386(disk_car, list_part, max_ext, verbose); for(parts=list_part;parts!=NULL;parts=parts->next) if(parts->part->status==STATUS_EXT) { if(partext_offset!=parts->part->part_offset || partext_size!=parts->part->part_size) can_ask_minmax_ext=1; } } } list_part=disk_car->arch->init_part_order(disk_car,list_part); if(ask_part_order!=0) { /* Demande l'ordre des entrees dans le MBR */ #ifdef HAVE_NCURSES ask_mbr_order_i386(disk_car,list_part); #endif /* Demande l'ordre des partitions etendues */ } do { do_again=0; res_interface_write=interface_write(disk_car,list_part,(fast_mode<1),can_ask_minmax_ext, &no_confirm, current_cmd,&menu); switch(res_interface_write) { case 'W': if(disk_car->arch == &arch_mac) { #ifdef HAVE_NCURSES write_part_mac_warning_ncurses(); #endif } else if(disk_car->arch == &arch_sun) { #ifdef HAVE_NCURSES not_implemented("write_part_sun"); #endif } else if(disk_car->arch == &arch_xbox) { #ifdef HAVE_NCURSES not_implemented("write_part_xbox"); #endif } else if(disk_car->arch->write_part!=NULL) { if(no_confirm!=0 #ifdef HAVE_NCURSES || ask_confirmation("Write partition table, confirm ? (Y/N)")!=0 #endif ) { log_info("write!\n"); if(disk_car->arch->write_part(disk_car, list_part, RW, verbose)) { display_message(msg_PART_WR_ERR); } else { use_backup(disk_car,list_part,verbose,dump_ind,expert,current_cmd); if(no_confirm==0) display_message("You will have to reboot for the change to take effect.\n"); } } else log_info("Don't write, no confirmation\n"); } break; case 0: if(disk_car->arch->write_part!=NULL) { log_info("simulate write!\n"); disk_car->arch->write_part(disk_car, list_part, RO, verbose); } break; case 'S': if(fast_mode<2) fast_mode++; break; case 'E': max_ext=!max_ext; list_part=add_ext_part_i386(disk_car, list_part, max_ext, verbose); do_again=1; break; } } while(do_again==1); } else { display_message("Invalid partition structure.\n"); } part_free_list(list_part); } while(res_interface_write=='S'); return 0; }