void mpd_say_status(void) { gchar *state; gchar *artist, *title; if (!mpd.conn) { irc_say("Not connected to MPD"); return; } if (mpd.status) mpd_status_free(mpd.status); mpd_run_noidle(mpd.conn); mpd.status = mpd_run_status(mpd.conn); if (!mpd_response_finish(mpd.conn)) { mpd_report_error(); return; } mpd_send_idle_mask(mpd.conn, MPD_IDLE_PLAYER); switch (mpd_status_get_state(mpd.status)) { case MPD_STATE_STOP: state = g_strdup("stopped"); break; case MPD_STATE_PLAY: state = g_strdup("playing"); break; case MPD_STATE_PAUSE: state = g_strdup("paused"); break; default: state = g_strdup("unknown"); break; } if (mpd.song) { artist = g_strdup(mpd_song_get_tag(mpd.song, MPD_TAG_ARTIST, 0)); title = g_strdup(mpd_song_get_tag(mpd.song, MPD_TAG_TITLE, 0)); } else { artist = g_strdup(""); title = g_strdup(""); } irc_say("[%s] %s - %s (%i:%02i/%i:%02i) | repeat: %sabled | " "random: %sabled | announce: %sabled", state, artist, title, mpd_status_get_elapsed_time(mpd.status) / 60, mpd_status_get_elapsed_time(mpd.status) % 60, mpd_status_get_total_time(mpd.status) / 60, mpd_status_get_total_time(mpd.status) % 60, (mpd_status_get_repeat(mpd.status) ? "en" : "dis"), (mpd_status_get_random(mpd.status) ? "en" : "dis"), (prefs.announce ? "en" : "dis")); g_free(state); g_free(artist); g_free(title); }
static void mpd_disconnect(void) { if (mpd.conn) mpd_connection_free(mpd.conn); mpd.conn = NULL; irc_say("Disconnected from MPD"); }
void google(const char *str) { assert(str); const char *channel = natural_channel_name(); if (!channel) { io_out("don't use fgoogle till your in a channel!\n"); return; } #define google "http://www.google.com/search?query=" #define GOOGLE_SIZE (sizeof(google) - 1) char *search = urlize(str); assert(search); size_t len = GOOGLE_SIZE; len += strlen(search); char *url = malloc(len + 1); strcpy(url, google); strcpy(&url[GOOGLE_SIZE], search); irc_say(url); free(search); free(url); #undef google #undef GOOGLE_SIZE }
void mpd_random(void) { const gboolean mode = !mpd_status_get_random(mpd.status); if (!mpd.conn) { irc_say("Not connected to MPD"); return; } mpd_run_noidle(mpd.conn); mpd_run_random(mpd.conn, mode); if (!mpd_response_finish(mpd.conn)) { mpd_report_error(); return; } irc_say("Random %sabled", (mode ? "en" : "dis")); mpd_send_idle_mask(mpd.conn, MPD_IDLE_PLAYER); }
void mpd_announce_song(void) { const gchar *artist, *song, *album; artist = mpd_song_get_tag(mpd.song, MPD_TAG_ARTIST, 0); song = mpd_song_get_tag(mpd.song, MPD_TAG_TITLE, 0); album = mpd_song_get_tag(mpd.song, MPD_TAG_ALBUM, 0); irc_say("Now playing: %s - %s (%s)", artist, song, album); }
static void mpd_report_error(void) { const gchar *error = mpd_connection_get_error_message(mpd.conn); g_warning("MPD error: %s", error); irc_say("MPD error: %s", error); if (mpd_connection_clear_error(mpd.conn)) { g_warning("Unable to recover, reconnecting"); mpd_disconnect(); mpd_schedule_reconnect(); } }
void irc_connect(void) { struct sockaddr_in addr; struct hostent *serv; char buf[IRC_MSG_LEN]; fd = socket(AF_INET, SOCK_STREAM/*|SOCK_NONBLOCK*/, 0); printf("Connecting to %s...\n", conf.host); serv = gethostbyname(conf.host); addr.sin_family = AF_INET; memcpy(&addr.sin_addr.s_addr, serv->h_addr, serv->h_length); addr.sin_port = htons(conf.port); if(connect(fd, (struct sockaddr *) &addr, sizeof(addr))<0) { puts("Connection error"); exit(EXIT_FAILURE); } irc_read(buf); irc_read(buf); strcpy(buf, "USER "); strcat(buf, conf.name); strcat(buf, " "); strcat(buf, conf.name); strcat(buf, " "); strcat(buf, conf.name); strcat(buf, " "); strcat(buf, conf.name); strcat(buf, "\r\n"); irc_cmd(buf); strcpy(buf, "NICK "); strcat(buf, conf.name); strcat(buf, "\r\n"); irc_cmd(buf); irc_read(buf); buf[1] = 'O'; irc_cmd(buf); while(irc_read(buf)) { buf[strlen(conf.name)+1] = '\0'; if(!strcmp(buf+1, conf.name)) break; } strcpy(buf, "JOIN "); strcat(buf, conf.chan); strcat(buf, "\r\n"); irc_cmd(buf); puts("Connected!"); sprintf(buf, "Hello, I'm %s!", conf.name); irc_say(buf); while(irc_read(buf) && irc_get_type(buf)!=T_JOIN); }
void mpd_stop(void) { if (!mpd.conn) { irc_say("Not connected to MPD"); return; } mpd_run_noidle(mpd.conn); mpd_run_stop(mpd.conn); if (!mpd_response_finish(mpd.conn)) { mpd_report_error(); return; } mpd_send_idle_mask(mpd.conn, MPD_IDLE_PLAYER); }
gboolean mpd_connect(void) { mpd.conn = mpd_connection_new(prefs.mpd_server, prefs.mpd_port, 10000); mpd.idle_source = 0; if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) { g_warning("Failed to connect to MPD: %s", mpd_connection_get_error_message(mpd.conn)); return FALSE; } else if (mpd_connection_cmp_server_version(mpd.conn, 0, 14, 0) < 0) { g_critical("MPD too old, please upgrade to 0.14 or newer"); return FALSE; } else { GIOChannel *channel; mpd_command_list_begin(mpd.conn, TRUE); if (prefs.mpd_password) mpd_send_password(mpd.conn, prefs.mpd_password); mpd_send_status(mpd.conn); mpd_send_current_song(mpd.conn); mpd_command_list_end(mpd.conn); mpd.status = mpd_recv_status(mpd.conn); if (!mpd_response_next(mpd.conn)) { mpd_report_error(); return FALSE; } mpd.song = mpd_recv_song(mpd.conn); if (!mpd_response_finish(mpd.conn)) { mpd_report_error(); return FALSE; } g_message("Connected to MPD"); irc_say("Connected to MPD"); mpd_send_idle_mask(mpd.conn, MPD_IDLE_PLAYER); channel = g_io_channel_unix_new( mpd_connection_get_fd(mpd.conn)); mpd.idle_source = g_io_add_watch(channel, G_IO_IN, (GIOFunc) mpd_parse, NULL); g_io_channel_unref(channel); return TRUE; } }
static void tell_on(Module *m, char **args, enum irc_type type) { LastSeen *l; char buf[IRC_MSG_LEN], notfirst = 0; int minutes; time_t now; double dt, seconds; if(type==T_CHAN) { strcpy(buf, args[0]); strcat(buf, ": "); } else buf[0] = '\0'; if(*args[2]) { minutes = proper_atoi(args[2]); if(minutes<0) { strcat(buf, usage); goto say; } strcat(buf, "Seen on the last "); strcat(buf, args[2]); strcat(buf, " minutes: "); } else { minutes = DEFAULT_MINUTES; strcat(buf, min_default); } seconds = ((double)minutes) * 60.; time(&now); l = base.next; while(l) { dt = difftime(now, l->seen); if(dt<seconds) { if(!notfirst) notfirst = 1; else strcat_msg(buf, ", "); strcat_msg(buf, l->name); } l = l->next; } say: if(type==T_CHAN) irc_say(buf); else irc_msg(args[0], buf); }
static void help(char **args, enum irc_type type) { char buf[IRC_MSG_LEN], act; int i, j, with_S0_total_len; Module *m = &mod; /* i is the string index of the message we build. j is the string index of m->help. */ if(type==T_CHAN) { sprintf(buf, "%s: I'll send you the help in a private message.", args[0]); irc_say(buf); } do { for(i=0; i<IRC_MSG_LEN-2 && (buf[i]=m->name[i]); i++); buf[i] = ':'; i++; buf[i] = ' '; i++; for(j=0; i<IRC_MSG_LEN && (act=m->help[j]); j++, i++) { if(act!='$') { buf[i] = act; continue; } j++; if(!(act=m->help[j]) || act!='0') break; if(!m->invoker) { printf("Module %s doesn't have an invoker, cannot use $0 in help!\n", m->name); exit(EXIT_FAILURE); } with_S0_total_len = i + S0_base_len + 2*strlen(m->invoker); if(with_S0_total_len < IRC_MSG_LEN) { sprintf(buf+i, S0_string, m->invoker, m->invoker); i = with_S0_total_len-1; } } buf[i] = '\0'; irc_msg(args[0], buf); m = m->next; } while(m); }