/* IRCfs - IRC FileServ for *nix. * Copyright (C) 2002 Nick 'Zaf' Clifford * For licensing details, refer to the LICENSE file in the source * code directory. */ #include "module.h" #include "select.h" #include "server.h" #include "debug.h" #include "channel.h" #include #include #include #include #include #include #include "console.h" #include "dccchat.h" #include "user.h" #include "file.h" #include "dccfile.h" #include "session.h" typedef void (*console_func)(const char *cmd, const char *params); struct console_cmd { const char *name; console_func func; }; static void console_read(int fd, enum select_mode mode, void *data); static void console_call_command(char *cmd, char *params); static int console_new_server(struct eventmsg *em); static int console_server_goes(struct eventmsg *em); static int console_set_current(struct server *s); MODULE_NAME("console"); MODULE_INIT(console_init); MODULE_DESTROY(console_unload); MODULE_DEPENDS("server","select"); MODULE_REGISTER(console); static DEBUG console_debug; static struct server *current_server; static void console_parse_line(char *line); static int console_readline_init(); int console_getc(FILE *fp); static void console_open(const char *cmd, const char *params); static void console_chan(const char *cmd, const char *params); static void console_dccchat(const char *cmd, const char *params); static void console_dccfile(const char *cmd, const char *params); static void console_ctcp(const char *cmd, const char *params); static void console_user(const char *cmd, const char *params); static void console_session(const char *cmd, const char *params); static struct console_cmd console_commands[] = { { "session", console_session }, { "open", console_open }, { "chan", console_chan }, { "chat", console_dccchat }, { "send", console_dccfile }, { "ctcp", console_ctcp }, { "user", console_user }, { NULL, NULL} }; static int console_readline_started = 0; #define M_ESC "\x1b" static char console_write_buffer[1024]; int console_vwritef(const char *format, va_list vl) { vsnprintf(console_write_buffer,sizeof(console_write_buffer), format,vl); return console_write_str(console_write_buffer); } int console_writef(const char *format, ...) { va_list vl; va_start(vl,format); vsnprintf(console_write_buffer,sizeof(console_write_buffer), format,vl); va_end(vl); return console_write_str(console_write_buffer); } int console_write_str(const char *buffer) { const char clr_line[9] = M_ESC "[2K" M_ESC "[0G"; int r,l; if (!console_readline_started) { console_readline_init(); } my_write(1,clr_line,8); l = strlen(buffer); r = my_write(1,buffer,l); if (r != l) return -1; rl_forced_update_display(); return r; } int console_readline_init() { if (!console_readline_started) { console_readline_started = 1; rl_getc_function = console_getc; rl_callback_handler_install("ircfs: ",console_parse_line); //using_history(); errno = 0; } return 0; } int console_init() { console_debug = debug_register("console"); fcntl(0, F_SETFL, O_NONBLOCK); register_wait_item(0, select_mode_read, console_read,NULL); console_readline_init(); event_add_listener(server_get_event_obj(), server_event_new, NULL, console_new_server, NULL); event_add_listener(server_get_event_obj(), server_event_disconnected, NULL, console_server_goes, NULL); server_foreach(console_set_current); return 0; } int console_set_current(struct server *s) { current_server = s; debug(console_debug,"Current server: %s", server_get_name(s)); return 0; } int console_server_goes(struct eventmsg *em) { struct server *s; s = (struct server *)em->msg; info(console_debug,"Server gone"); current_server = NULL; return 0; } int console_new_server(struct eventmsg *em) { struct server *s; s = (struct server *)em->msg; current_server = s; debug(console_debug,"Current server: %s", server_get_name(s)); event_add_listener(server_get_event_obj(), server_event_disconnected, s, console_server_goes, NULL); return 0; } int console_unload() { rl_callback_handler_remove(); return 0; } int console_getc(FILE *fp) { char ch; int r; r = read(0,&ch,1); if (r > 0) return ch; return EOF; } void console_read(int fd, enum select_mode mode, void *data) { rl_callback_read_char(); } void console_parse_line(char *line) { char *cp; if (line == NULL) { rl_callback_handler_remove(); exit(0); return; } //if (*line) //add_history(line); //debug(console_debug,"Read: %s", line); if (line[0] == '/') { cp = line+1; while(*cp && !isspace(*cp)) cp++; if (*cp) { *cp = 0; cp++; while(isspace(*cp)) cp++; } console_call_command(line+1,cp); } else if (current_server) { server_send(current_server,line); } else { debug(console_debug,"No current server"); } free(line); return; } void console_call_command(char *cmd, char *params) { int i; for (i = 0; console_commands[i].name != NULL; i++) { if (strcasecmp(console_commands[i].name,cmd) == 0) { console_commands[i].func(cmd,params); return; } } return; } void console_user(const char *cmd, const char *params) { struct user *u; if (*params == 0) { /* List all users */ user_dump_list(current_server); return; } u = user_find(current_server, params); if (u == NULL) { debug(console_debug,"No such user"); return; } user_dump_user(u); } void console_open(const char *cmd, const char *params) { struct server *s; static char buf[512]; char *cp,*first,*second; strncpy(buf,params,511); buf[511]=0; for(cp = buf; *cp && !isspace(*cp); cp++) { } first = buf; if (*cp) { *cp = 0; cp++; second=cp; for(; isspace(*cp); cp++) { } } else { second = NULL; } if (*first == 0) { s = server_create(); current_server = s; server_setinfo(s,"eyedbb"); server_connect(s,"127.0.0.1",6667); return; } if (second == NULL && isdigit(*buf)) { s = server_create(); current_server = s; server_setinfo(s,"eyedbb"); server_connect(s,buf,6667); return; } else if (second == NULL) { s = server_open(first,NULL); return; } else { s = server_open(first,second); return; } } void console_chan(const char *cmd, const char *params) { if (!current_server) { debug(console_debug,"No current server"); return; } if (strcasecmp(params,"list") == 0) { channel_dump_chans(current_server); } else { channel_dump_chaninfo(current_server, params); } } void console_dccchat(const char *cmd, const char *params) { struct user *u; if (!current_server) { debug(console_debug,"No current server"); return; } u = user_find(current_server,params); if (!u) { debug(console_debug,"No such user"); return; } dccchat_start(u); } void console_ctcp(const char *cmd, const char *params) { static char buf[512]; struct user *u; char *cp; if (!current_server) { debug(console_debug,"No current server"); return; } strncpy(buf,params,511); buf[511]=0; for(cp = buf; *cp && !isspace(*cp); cp++) { } if (*cp) { *cp = 0; cp++; for(; isspace(*cp); cp++) { } } else { debug(console_debug,"/ctcp "); return; } u = user_find(current_server,buf); if (!u) { debug(console_debug,"No such user"); return; } server_send(current_server,"PRIVMSG %s :\01%s\01", user_get_nick(u), cp); return; } void console_dccfile(const char *cmd, const char *params) { static char buf[512]; struct user *u; struct file *f; struct file_handler *fh; char *cp; if (!current_server) { debug(console_debug,"No current server"); return; } strncpy(buf,params,511); buf[511]=0; for(cp = buf; *cp && !isspace(*cp); cp++) { } if (*cp) { *cp = 0; cp++; for(; isspace(*cp); cp++) { } } else { debug(console_debug,"/send "); return; } u = user_find(current_server,buf); if (!u) { debug(console_debug,"No such user"); return; } fh = find_file_handler("ufs"); if (!fh) { debug(console_debug,"Can't find file handler"); return; } f = fh->open(NULL,cp,file_flag_readonly); if (!f) { debug(console_debug,"Can't open file"); return; } dccfile_start_send(u,f); } void console_session(const char *cmd, const char *params) { static char buf[512]; struct user *u; struct dir *d; struct dir_handler *dh; char *cp; if (!current_server) { debug(console_debug,"No current server"); return; } strncpy(buf,params,511); buf[511]=0; for(cp = buf; *cp && !isspace(*cp); cp++) { } if (*cp) { *cp = 0; cp++; for(; isspace(*cp); cp++) { } } else { debug(console_debug,"/session "); return; } u = user_find(current_server,buf); if (!u) { debug(console_debug,"No such user"); return; } dh = find_dir_handler("ufs"); if (!dh) { debug(console_debug,"Can't find dir handler"); return; } d = dh->open(NULL,cp); if (!d) { debug(console_debug,"Can't open dir %s",cp); return; } session_create(u,d); }