/** * Handle input command. * * This function should return 0, even if the command failed. * Return of != 0 means the event loop will quit. */ static int handle_input_command(const dstring* string) { dstrlist* list; dstring** argv; unsigned int argc; int error; ENetPacket* packet; if (string->len == 0) { /* empty command */ return 0; } else if (string->data[0] == '/') { /* local command */ /* parse the command */ list = dstrlex_parse(string, &error); if (list == NULL) { fprintf(stderr, "Failed to parse command string '%s': %s\n", string->data, dstrlex_errstr(error)); return 0; } /* convert list to vector */ argc = list->size; argv = dlist_tovector(list); dlist_free(list); /* select command to execute */ if (dcmpcs(argv[0], "/connect") == 0) { error = cmd_connect(argc, argv); } else if (dcmpcs(argv[0], "/disconnect") == 0) { error = cmd_disconnect(argc, argv); } else if (dcmpcs(argv[0], "/quit") == 0) { error = cmd_quit(argc, argv); } else if (dcmpcs(argv[0], "/mute") == 0) { error = cmd_mute(argc, argv); } else if (dcmpcs(argv[0], "/deafen") == 0) { error = cmd_deafen(argc, argv); } else { fprintf(stderr, "Unknown command '%s'\n", argv[0]->data); error = 0; } dvec_free(argv); return error; } else if (client.state == SVCECLIENT_STATE_CONNECTED) { /* send to server if connected */ mutex_lock(&client.network_lock); packet = enet_packet_create(string->data, string->len, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(client.client, 0, packet); mutex_unlock(&client.network_lock); } else if (client.state == SVCECLIENT_STATE_CONNECTING) { /* server command but still connecting */ fprintf(stderr, "Can't send command to server, still connecting.\n"); } else { /* server command but not connected */ fprintf(stderr, "Can't send command to server, not connected.\n"); } return 0; }
void cmd_exit(void) { /* * "exit" is a synonym for quit except in engine mode * when it means leave analyze mode */ if ( flags & ANALYZE ){ flags = preanalyze_flags ; /* this implicitly clears ANALYZE flag */ SetDataToEngine( token[0] ); } else { cmd_quit(); } }
/** * Internal Signal handler for SIGSEGV * @param signum * @param info * @param pcontext * @return */ void e2dbg_internal_sigsegv_handler(int signum, siginfo_t *info, void *pcontext) { //ucontext_t *context; CLRSIG; if (profiler_enabled()) profiler_disable_all(); //context = (ucontext_t *) pcontext; fprintf(stderr, "\n [!] Segfault in E2dbg, exiting ...\n\n"); e2dbg_bt(); cmd_quit(); SETSIG; }
void exec_command(char cmd, char *param) { switch(cmd){ case'Q':cmd_quit(); break; case'C':cmd_check(); break; case'P':cmd_print(atoi(param)); break; case'R':cmd_read(param); break; case'W':cmd_write(param); break; case'F':cmd_find(param); break; case'S':cmd_sort(atoi(param)); break; case'E':cmd_edit(); break; case'H':cmd_help(); break; default:fprintf(stderr,"error\n\n"); } printf(":"); }
void exec_command(char cmd, char *param) { switch (cmd) { case 'Q': cmd_quit(); break; case 'C': cmd_check(); break; case 'P': cmd_print(atoi(param)); break; case 'R': cmd_read(param); break; case 'W': cmd_write(param); break; case 'F': cmd_find(param); break; case 'S': cmd_sort(atoi(param)); break; case 'D': cmd_delete(param); break; case 'r': cmd_random(); break; case 'T': test(atoi(param)); break; default: fprintf(stderr, "Invalid command %c: ignored.\n", cmd); break; } }
// 运行客户端 void run(char* ip, char* pt) { int sockfd = connectToHost(ip, pt); if (getReplyCode(sockfd) != SERVICE_READY) errorReport("Service Connect Error!"); while (userLogin(sockfd) != 0) // 调用登录函数userLogin printf("Please try again.\n"); int isQuit = 0; char buf[BUF_SIZE]; while (!isQuit) { printf("[Client command] "); fgets(buf, sizeof(buf), stdin); switch (cmdToNum(buf)) { case GET: cmd_get(sockfd, buf); break; case PUT: cmd_put(sockfd, buf); break; case PWD: cmd_pwd(sockfd); break; case DIR: cmd_dir(sockfd); break; case CD: cmd_cd(sockfd, buf); break; case HELP: cmd_help(); break; case QUIT: cmd_quit(sockfd); isQuit = 1; break; default: cmd_help(); break; } } close(sockfd); }
void * tcp_task (void *p_arg) { int i, nfds, dret; int event_fd; #ifdef SHOW_TRAFFIC rold_time = time (NULL); #endif while (1) { timerN_invoke (pTimerInfo); timerN_invoke (pReTimerInfo); nfds = epoll_wait (g_epoll_fd, g_events, MAX_EVENTS, 100); /**< timeout 100ms */ if (nfds == 0) { timerN_invoke (pTimerInfo); timerN_invoke (pReTimerInfo); continue; /**< no event **/ } if (nfds < 0) { if( errno != EINTR ) { dAppLog (LOG_CRI, "epoll wait error! %d-%s. EPOLL_FD[%d]", errno, strerror(errno), g_epoll_fd); cmd_quit ("epoll wait error"); exit(1); } } for (i=0; i < nfds; i++) { rcv_tcpsock (&g_events[i]); } } return p_arg; }
void my_cmd2(char **com, int const cfd) { if (strcmp(com[0], "/part") == 0) cmd_part(com, cfd); else if (strcmp(com[0], "/list") == 0) cmd_list(com, cfd); else if (strcmp(com[0], "/quit") == 0) cmd_quit(com, cfd); else if (strcmp(com[0], "/users") == 0) cmd_users(com, cfd); else if (strcmp(com[0], "/msg") == 0) cmd_mp(com, cfd); else if (strcmp(com[0], "/topic") == 0) cmd_topic(com, cfd); else if (strcmp(com[0], "/kick") == 0) cmd_kick(com, cfd); else if (strcmp(com[0], "/kill") == 0) cmd_kill(com, cfd); else if (strcmp(com[0], "/ping") == 0) dprintf(cfd, "PING \r\n"); else cmd_msg(com, cfd); }
static int cmd_eval(void *data, const char *input) { char *p; RCore *core = (RCore *)data; switch (input[0]) { case 't': // env if (input[1]==' ' && input[2]) { RConfigNode *node = r_config_node_get (core->config, input+2); if (node) { const char *type = r_config_node_type (node); if (type && *type) { r_cons_printf ("%s\n", type); } } } else { eprintf ("Usage: et [varname] ; show type of eval var\n"); } break; case 'n': // env if (!strchr (input, '=')) { char *var, *p; var = strchr (input, ' '); if (var) while (*var==' ') var++; p = r_sys_getenv (var); if (p) { r_cons_printf ("%s\n", p); free (p); } else { char **e = r_sys_get_environ (); while (e && *e) { r_cons_printf ("%s\n", *e); e++; } } } else if (strlen (input)>3) { char *v, *k = strdup (input+3); if (!k) break; v = strchr (k, '='); if (v) { *v++ = 0; r_sys_setenv (k, v); } free (k); } return true; case 'x': // exit return cmd_quit (data, ""); case 'j': r_config_list (core->config, NULL, 'j'); break; case '\0': r_config_list (core->config, NULL, 0); break; case 'c': switch (input[1]) { case 'h': // echo if (( p = strchr (input, ' ') )) { r_cons_strcat (p+1); r_cons_newline (); } break; case 'd': r_cons_pal_init (NULL); break; case '?': { const char *helpmsg[] = { "Usage ec[s?] [key][[=| ]fg] [bg]","","", "ec","","list all color keys", "ec*","","same as above, but using r2 commands", "ecd","","set default palette", "ecr","","set random palette", "ecs","","show a colorful palette", "ecj","","show palette in JSON", "ecc","","show palette in CSS", "eco"," dark|white","load white color scheme template", "ecn","","load next color theme", "ec"," prompt red","change color of prompt", "ec"," prompt red blue","change color and background of prompt", ""," ","", "colors:","","rgb:000, red, green, blue, ...", "e scr.rgbcolor","=1|0","for 256 color cube (boolean)", "e scr.truecolor","=1|0","for 256*256*256 colors (boolean)", "$DATADIR/radare2/cons","","~/.config/radare2/cons ./", NULL}; r_core_cmd_help (core, helpmsg); } break; case 'o': // "eco" if (input[2] == ' ') { bool failed = false; char *home, path[512]; snprintf (path, sizeof (path), ".config/radare2/cons/%s", input+3); home = r_str_home (path); snprintf (path, sizeof (path), R2_DATDIR"/radare2/" R2_VERSION"/cons/%s", input+3); if (!r_core_cmd_file (core, home)) { if (r_core_cmd_file (core, path)) { //curtheme = r_str_dup (curtheme, path); curtheme = r_str_dup (curtheme, input + 3); } else { if (r_core_cmd_file (core, input+3)) { curtheme = r_str_dup (curtheme, input + 3); } else { eprintf ("eco: cannot open colorscheme profile (%s)\n", path); failed = true; } } } free (home); } else { nextpal (core, 'l'); } break; case 's': r_cons_pal_show (); break; case '*': r_cons_pal_list (1); break; case 'j': r_cons_pal_list ('j'); break; case 'c': r_cons_pal_list ('c'); break; case '\0': r_cons_pal_list (0); break; case 'r': // "ecr" r_cons_pal_random (); break; case 'n': // "ecn" nextpal (core, 'n'); break; default: { char *p = strdup (input + 2); char *q = strchr (p, '='); if (!q) q = strchr (p, ' '); if (q) { // set *q++ = 0; r_cons_pal_set (p, q); } else { const char *k = r_cons_pal_get (p); if (k) eprintf ("(%s)(%sCOLOR"Color_RESET")\n", p, k); } free (p); } } break; case 'e': if (input[1]==' ') { char *p; const char *val, *input2 = strchr (input+2, ' '); if (input2) input2++; else input2 = input+2; val = r_config_get (core->config, input2); p = r_core_editor (core, NULL, val); if (p) { r_str_replace_char (p, '\n', ';'); r_config_set (core->config, input2, p); } } else eprintf ("Usage: ee varname\n"); break; case '!': input = r_str_chop_ro (input+1); if (!r_config_toggle (core->config, input)) eprintf ("r_config: '%s' is not a boolean variable.\n", input); break; case '-': r_core_config_init (core); //eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n"); break; case 'v': eprintf ("Invalid command '%s'. Use 'e?'\n", input); break; case '*': r_config_list (core->config, NULL, 1); break; case '?': switch (input[1]) { case '?': r_config_list (core->config, input+2, 2); break; default: r_config_list (core->config, input+1, 2); break; case 0:{ const char* help_msg[] = { "Usage:", "e[?] [var[=value]]", "Evaluable vars", "e","?asm.bytes", "show description", "e", "??", "list config vars with description", "e", "", "list config vars", "e-", "", "reset config vars", "e*", "", "dump config vars in r commands", "e!", "a", "invert the boolean value of 'a' var", "ee", "var", "open editor to change the value of var", "er", " [key]", "set config key as readonly. no way back", "ec", " [k] [color]", "set color for given key (prompt, offset, ...)", "et", " [key]", "show type of given config variable", "e", " a", "get value of var 'a'", "e", " a=b", "set var 'a' the 'b' value", "env", " [k[=v]]", "get/set environment variable", NULL}; r_core_cmd_help (core, help_msg); } } break; case 'r': if (input[1]) { const char *key = input+((input[1]==' ')?2:1); if (!r_config_readonly (core->config, key)) eprintf ("cannot find key '%s'\n", key); } else eprintf ("Usage: er [key]\n"); break; case ' ': r_config_eval (core->config, input+1); break; default: r_config_eval (core->config, input); break; } return 0; }
int exec_parsed(){ // Execs a parsed command line. int error=0,i,got=-1,n; // Now execute the command. if(parse_nwords!=0){ // Search for a matching known command. for(i=0;i<max_cmds;i++){ if(strcmp(con_cmds[i].name,parse_words[0])==0){ got=i; } } if(got>=0){ // Make sure that we have the correct number of arguments for a command. if(con_cmds[got].type=='C'){ if(parse_nwords!=con_cmds[got].max+1){ got=-2; } } // If we have a variable, deal with it here. else{ // No arguments means view the variable. if(parse_nwords==1){ view_variable(got); got=1000; } // One argument means set the variable. if(parse_nwords==2){ // Find the value to set the variable to. if(con_cmds[got].type=='F'){ // It's a FIXED variable. n=ftofix(atof(parse_words[1])); } if(con_cmds[got].type=='I'){ // It's an INT. n=atoi(parse_words[1]); } if(con_cmds[got].type=='S'){ // It's a string. internal_setstring(con_cmds[got].s_mirror,parse_words[1]); } else{ // Put the value within limits. if(n<con_cmds[got].min){n=con_cmds[got].min;} if(n>con_cmds[got].max){n=con_cmds[got].max;} // Set the mirror to the value. con_cmds[got].mirror=n; } } // If we don't have one or two arguments, then its an error. if(parse_nwords>2){ got=-2; } } } // Execute an actual command, or set a given variable. switch(got){ case -1: internal_error();break; case 0: cmd_clear();break; case 1: player_crosshair=n;break; case 2: player_crosshair_color=n;break; case 3: cmd_dir();break; case 4: cmd_disconnect();break; case 5: cmd_exec();break; case 6: player_floors=n;break; case 7: player_fov_degrees=fixtof(n);break; case 8: player_fps=n;break; case 9: player_gamma=n;cmd_gamma();break; case 10: player_gfx_mode=n;cmd_gfx_mode();break; case 11: cmd_gfx_modes();break; case 12: player_heightfix=n;break; case 13: player_invert=n;break; case 14: light_con=n;break; case 15: light_depth=fixtof(n);break; case 16: cmd_loopdemo();break; case 17: cmd_map();break; case 18: cmd_mapinfo();break; case 19: player_map_rotate=n;break; case 20: player_map=n;break; case 21: player_map_size=n;break; case 22: cmd_mem();break; case 23: internal_setstring(player_pic_con,parse_words[1]); cmd_pic_con();break; case 24: cmd_playdemo();break; case 25: cmd_pwad();break; case 26: cmd_quit();break; case 27: cmd_recdemo();break; case 28: player_r_grad=n;break; case 29: player_r_gun=n;break; case 30: cmd_stop();break; case 31: cmd_syntax();break; case 32: cmd_time();break; case 33: cmd_timerefresh();break; case 34: player_trace=1;break; case 35: cmd_viewpic();break; case 36: cmd_viewtex();break; case 37: player_vsync=n;break; case 38: cmd_wads();break; case 39: player_walls=n;break; case 40: player_windowsize=n;break; } } // Return the error value. DEBUG: Do we use this? return(error); }
static int cmd_eval(void *data, const char *input) { char *p; RCore *core = (RCore *)data; switch (input[0]) { case 't': // env if (input[1] == 'a') { r_cons_printf ("%s\n", (r_num_rand (10) % 2)? "wen": "son"); } else if (input[1]==' ' && input[2]) { RConfigNode *node = r_config_node_get (core->config, input+2); if (node) { const char *type = r_config_node_type (node); if (type && *type) { r_cons_println (type); } } } else { eprintf ("Usage: et [varname] ; show type of eval var\n"); } break; case 'n': // env if (!strchr (input, '=')) { char *var, *p; var = strchr (input, ' '); if (var) while (*var==' ') var++; p = r_sys_getenv (var); if (p) { r_cons_println (p); free (p); } else { char **e = r_sys_get_environ (); while (e && *e) { r_cons_println (*e); e++; } } } else if (strlen (input)>3) { char *v, *k = strdup (input+3); if (!k) break; v = strchr (k, '='); if (v) { *v++ = 0; r_sys_setenv (k, v); } free (k); } return true; case 'x': // exit // XXX we need headers for the cmd_xxx files. return cmd_quit (data, ""); case 'j': // json r_config_list (core->config, NULL, 'j'); break; case 'v': // verbose r_config_list (core->config, input + 1, 'v'); break; case 'q': // quiet list of eval keys r_config_list (core->config, NULL, 'q'); break; case '\0': // "e" r_config_list (core->config, NULL, 0); break; case 'c': // "ec" switch (input[1]) { case 'd': r_cons_pal_init (NULL); break; case '?': { const char *helpmsg[] = { "Usage ec[s?] [key][[=| ]fg] [bg]","","", "ec","","list all color keys", "ec*","","same as above, but using r2 commands", "ecd","","set default palette", "ecr","","set random palette (see also scr.randpal)", "ecs","","show a colorful palette", "ecj","","show palette in JSON", "ecc"," [prefix]","show palette in CSS", "eco"," dark|white","load white color scheme template", "ecp","","load previous color theme", "ecn","","load next color theme", "ecH","[?]","highlight word or instruction", "ec"," prompt red","change color of prompt", "ec"," prompt red blue","change color and background of prompt", ""," ","", "colors:","","rgb:000, red, green, blue, ...", "e scr.rgbcolor","=1|0","for 256 color cube (boolean)", "e scr.truecolor","=1|0","for 256*256*256 colors (boolean)", "$DATADIR/radare2/cons","","~/.config/radare2/cons ./", NULL}; r_core_cmd_help (core, helpmsg); } break; case 'o': // "eco" if (input[2] == 'j') { nextpal (core, 'j'); } else if (input[2] == ' ') { bool failed = false; char *home, path[512]; snprintf (path, sizeof (path), ".config/radare2/cons/%s", input + 3); home = r_str_home (path); snprintf (path, sizeof (path), R2_DATDIR"/radare2/" R2_VERSION"/cons/%s", input + 3); if (!load_theme (core, home)) { if (load_theme (core, path)) { //curtheme = r_str_dup (curtheme, path); curtheme = r_str_dup (curtheme, input + 3); } else { if (load_theme (core, input + 3)) { curtheme = r_str_dup (curtheme, input + 3); } else { char *absfile = r_file_abspath (input + 3); eprintf ("eco: cannot open colorscheme profile (%s)\n", absfile); free (absfile); failed = true; } } } free (home); if (failed) { eprintf ("Something went wrong\n"); } } else if (input[2] == '?') { eprintf ("Usage: eco [themename] ;load theme from "R2_DATDIR"/radare2/"R2_VERSION"/cons/\n"); } else { nextpal (core, 'l'); } break; case 's': r_cons_pal_show (); break; // "ecs" case '*': r_cons_pal_list (1, NULL); break; // "ec*" case 'h': // echo if (( p = strchr (input, ' ') )) { r_cons_strcat (p+1); r_cons_newline (); } else { // "ech" r_cons_pal_list ('h', NULL); } break; case 'j': // "ecj" r_cons_pal_list ('j', NULL); break; case 'c': // "ecc" r_cons_pal_list ('c', input + 2); break; case '\0': // "ec" r_cons_pal_list (0, NULL); break; case 'r': // "ecr" r_cons_pal_random (); break; case 'n': // "ecn" nextpal (core, 'n'); break; case 'p': // "ecp" nextpal (core, 'p'); break; case 'H': { // "ecH" char *color_code = NULL; char *word = NULL; int argc = 0; char** argv = r_str_argv (input + 4, &argc); switch (input[2]) { case '?': { const char *helpmsg[] = { "Usage ecH[iw-?]","","", "ecHi","[color]","highlight current instruction with 'color' background", "ecHw","[word] [color]","highlight 'word ' in current instruction with 'color' background", "ecH-","","remove all highlights on current instruction", NULL }; r_core_cmd_help (core, helpmsg); } break; case '-': r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, ""); return false; case '\0': case 'i': // "ecHi if (argc) { char *dup = r_str_newf ("bgonly %s", argv[0]); color_code = r_cons_pal_parse (dup); R_FREE (dup); } break; case 'w': // "ecHw" if (!argc) { eprintf ("Usage: echw word [color]\n"); r_str_argv_free (argv); return true; } word = strdup (argv[0]); if (argc > 1) { char *dup = r_str_newf ("bgonly %s", argv[1]); color_code = r_cons_pal_parse (dup); if (!color_code) { eprintf ("Unknown color %s\n", argv[1]); r_str_argv_free (argv); free (dup); free (word); return true; } R_FREE (dup); } break; default: eprintf ("See ecH?\n"); r_str_argv_free (argv); return true; } char *str = r_meta_get_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset); char *dup = r_str_newf ("%s \"%s%s\"", str?str:"", word?word:"", color_code?color_code:r_cons_pal_get ("highlight")); r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, dup); r_str_argv_free (argv); R_FREE (word); R_FREE (dup); break; } default: { char *p = strdup (input + 2); char *q = strchr (p, '='); if (!q) { q = strchr (p, ' '); } if (q) { // set *q++ = 0; r_cons_pal_set (p, q); } else { const char *k = r_cons_pal_get (p); if (k) { eprintf ("(%s)(%sCOLOR"Color_RESET")\n", p, k); } } free (p); } } break; case 'e': if (input[1] == ' ') { char *p; const char *val, *input2 = strchr (input+2, ' '); if (input2) input2++; else input2 = input+2; val = r_config_get (core->config, input2); p = r_core_editor (core, NULL, val); if (p) { r_str_replace_char (p, '\n', ';'); r_config_set (core->config, input2, p); } } else { eprintf ("Usage: ee varname\n"); } break; case '!': input = r_str_chop_ro (input+1); if (!r_config_toggle (core->config, input)) eprintf ("r_config: '%s' is not a boolean variable.\n", input); break; case 's': r_config_list (core->config, (input[1])? input + 1: NULL, 's'); break; case '-': r_core_config_init (core); //eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n"); break; case '*': r_config_list (core->config, NULL, 1); break; case '?': switch (input[1]) { case '?': r_config_list (core->config, input+2, 2); break; default: r_config_list (core->config, input+1, 2); break; case 0: r_core_cmd_help (core, help_msg_e); } break; case 'r': if (input[1]) { const char *key = input+((input[1]==' ')?2:1); if (!r_config_readonly (core->config, key)) { eprintf ("cannot find key '%s'\n", key); } } else { eprintf ("Usage: er [key]\n"); } break; case ' ': r_config_eval (core->config, input+1); break; default: r_config_eval (core->config, input); break; } return 0; }
static int cmd_eval(void *data, const char *input) { RCore *core = (RCore *)data; switch (input[0]) { case '\0': // "e" r_config_list (core->config, NULL, 0); break; case '?': // "e?" default: switch (input[1]) { case '\0': r_core_cmd_help (core, help_msg_e); break; case '?': r_config_list (core->config, input + 2, 2); break; default: r_config_list (core->config, input + 1, 2); break; } break; case 't': // "et" if (input[1] == 'a') { r_cons_printf ("%s\n", (r_num_rand (10) % 2)? "wen": "son"); } else if (input[1]==' ' && input[2]) { RConfigNode *node = r_config_node_get (core->config, input+2); if (node) { const char *type = r_config_node_type (node); if (type && *type) { r_cons_println (type); } } } else { eprintf ("Usage: et [varname] ; show type of eval var\n"); } break; case 'n': // "en" if (!strchr (input, '=')) { char *var, *p; var = strchr (input, ' '); if (var) while (*var==' ') var++; p = r_sys_getenv (var); if (p) { r_cons_println (p); free (p); } else { char **e = r_sys_get_environ (); while (e && *e) { r_cons_println (*e); e++; } } } else if (strlen (input)>3) { char *v, *k = strdup (input+3); if (!k) break; v = strchr (k, '='); if (v) { *v++ = 0; r_sys_setenv (k, v); } free (k); } return true; case 'x': // exit // XXX we need headers for the cmd_xxx files. return cmd_quit (data, ""); case 'j': // json r_config_list (core->config, NULL, 'j'); break; case 'v': // verbose r_config_list (core->config, input + 1, 'v'); break; case 'q': // quiet list of eval keys r_config_list (core->config, NULL, 'q'); break; case 'c': // "ec" switch (input[1]) { case 'd': // "ecd" r_cons_pal_init (core->cons->context); break; case '?': r_core_cmd_help (core, help_msg_ec); break; case 'o': // "eco" if (input[2] == 'j') { nextpal (core, 'j'); } else if (input[2] == ' ') { cmd_load_theme (core, input + 3); } else if (input[2] == 'o') { cmd_load_theme (core, r_core_get_theme ()); } else if (input[2] == 'c' || input[2] == '.') { r_cons_printf ("%s\n", r_core_get_theme ()); } else if (input[2] == '?') { r_core_cmd_help (core, help_msg_eco); } else if (input[2] == 'q') { RList *themes_list = r_core_list_themes (core); RListIter *th_iter; const char *th; r_list_foreach (themes_list, th_iter, th) { r_cons_printf ("%s\n", th); } } else {