Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <libconfig.h>
- //For getaddrinfo
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <xchat/xchat-plugin.h>
- #define PNAME "XChat MPD"
- #define PDESC "XChat MPD now playing plugin"
- #define PVERSION "0.1"
- static xchat_plugin *ph; //Plugin handle
- static FILE * configfile; //Pointer to config file
- static config_t config; //Config struct for libconfig
- static config_setting_t * hostname; //Pointer to hostname in config
- static config_setting_t * port; //Pointer to port in config
- //Function for /set command
- static int set_setting_mpd_np(char * word[]) {
- //If no setting is specified, simply print the current settings
- if (word[2] == NULL) {
- xchat_printf(ph, "Hostname: %s\n", config_setting_get_string(hostname));
- xchat_printf(ph, "Port: %s\n", config_setting_get_string(port));
- }
- if (strcasecmp(word[2], "HOSTNAME") == 0) {
- //Set new value for hostname, then dump to file
- config_setting_set_string(hostname, word[3]);
- config_write(&config, configfile);
- }
- else if (strcasecmp(word[2], "PORT") == 0) {
- //Set new value for hostname, then dump to file
- config_setting_set_string(port, word[3]);
- config_write(&config, configfile);
- }
- //Unknown setting! Return error
- else {
- xchat_printf(ph, "%s is not a valid setting\n", word[2]);
- }
- return XCHAT_EAT_ALL;
- }
- static int mpd_np_show() {
- //Structs for getaddrinfo
- struct addrinfo hints;
- struct addrinfo * results;
- int _socket;
- char buf[4096]; //Input buffer
- //Clear out the garbage from the hints structure
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC; //Allow IPv4 or 6
- hints.ai_socktype = SOCK_DGRAM; //Datagram socket
- hints.ai_flags = 0;
- hints.ai_protocol = 0; //Any protocol
- //If getaddrinfo fails to get the list of address structures, print a message
- int s = getaddrinfo(config_setting_get_string(hostname), config_setting_get_string(port),
- &hints, &results);
- if (s != 0) xchat_printf(ph, "ERROR: Could not connect (%s)\n", gai_strerror(s));
- //Try connecting to all the address structures returned by getaddrinfo
- struct addrinfo * cs; //The current structure we're on
- for (cs = results; cs != NULL; cs = cs->ai_next) {
- _socket = socket(cs->ai_family, cs->ai_socktype, cs->ai_protocol);
- if (_socket == -1)
- continue;
- if (connect(_socket, cs->ai_addr, cs->ai_addrlen) != -1)
- break;
- close(_socket);
- }
- //If none of the addresses worked
- if (cs == NULL) {
- xchat_print(ph, "Could not connect to MPD\n");
- return XCHAT_EAT_ALL;
- }
- freeaddrinfo(results); //Not needed now
- //Receive MPD's welcome message
- recv(_socket, &buf, 4096, 0);
- //Ask MPD for information on the current song
- send(_socket, "currentsong", sizeof("currentsong"), 0);
- //Receive and parse song info
- recv(_socket, &buf, 4096, 0);
- //Find the beggining of the artist tag, along with the end of the line it's on
- char * artistinfo_beg = strstr(buf, "Artist: ") + sizeof("Artist: ");
- char * artistinfo_end = strstr(artistinfo_beg, "\n");
- size_t artistinfo_len = artistinfo_end - artistinfo_beg;
- //Copy the artist info to a string
- char * artistinfo = malloc(artistinfo_len + 1); //Add 1 to account for '\0'
- strncpy(artistinfo, artistinfo_beg, artistinfo_len);
- xchat_commandf(ph, "say Artist: %s", artistinfo);
- free(artistinfo);
- return XCHAT_EAT_ALL;
- }
- void xchat_plugin_get_info(char **name, char **desc, char **version, void **reserved)
- {
- *name = PNAME;
- *desc = PDESC;
- *version = PVERSION;
- }
- int xchat_plugin_init(xchat_plugin *plugin_handle,
- char **plugin_name,
- char **plugin_desc,
- char **plugin_version,
- char **arg)
- {
- ph = plugin_handle; //Needed for use with any xchat_ functions
- //Tell XChat our info
- *plugin_name = PNAME;
- *plugin_desc = PDESC;
- *plugin_version = PVERSION;
- //Make sure ~/.config exists and is a directory
- struct stat *stat_s;
- if (stat("~/.config/", stat_s) != 0) {
- if (errno == ENOENT)
- mkdir("~/.config", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
- else {
- xchat_printf(ph, "%s\n", strerror(errno));
- return 0;
- }
- }
- //Initialize config structure
- config_init(&config);
- //Make sure ~/.config/xchat.mpd exists, if not create it and use default config
- if (stat("~/.config/xchatmpd.conf", stat_s) != 0) {
- if (errno == ENOENT) {
- //Create file
- configfile = fopen("~/.config/xchatmpd.conf", "w+");
- //Add hostname and port settings
- hostname = config_setting_add(config_root_setting(&config), "HOSTNAME", 4);
- port = config_setting_add(config_root_setting(&config), "PORT", 4);
- //Set value of new settings
- config_setting_set_string(hostname, "localhost");
- config_setting_set_string(port, "6600");
- //Dump settings into config file
- config_write(&config, configfile);
- }
- else {
- xchat_printf(ph, "%s\n", strerror(errno));
- return 0;
- }
- }
- else {
- //Open config file and retrieve settings
- configfile = fopen("~/.config/xchatmpd.conf", "w+");
- config_read(&config, configfile);
- //Set hostname and port pointers
- hostname = config_lookup(&config, "HOSTNAME");
- port = config_lookup(&config, "PORT");
- }
- //Now hook the commands
- xchat_hook_command(ph, "NP", XCHAT_PRI_NORM, mpd_np_show,
- "Usage: NP Shows the song currently playing in MPD", NULL);
- xchat_hook_command(ph, "NP_SET", XCHAT_PRI_NORM, set_setting_mpd_np,
- "Usage: NP_SET <setting> <new value> Changes setting's value to a new value.", NULL);
- xchat_print(ph, "X-Chat MPD Loaded!\n");
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement