summary refs log tree commit diff stats
path: root/plugins/fishlim/plugin_hexchat.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/fishlim/plugin_hexchat.c')
-rw-r--r--plugins/fishlim/plugin_hexchat.c137
1 files changed, 67 insertions, 70 deletions
diff --git a/plugins/fishlim/plugin_hexchat.c b/plugins/fishlim/plugin_hexchat.c
index f200ea8c..556a2f51 100644
--- a/plugins/fishlim/plugin_hexchat.c
+++ b/plugins/fishlim/plugin_hexchat.c
@@ -22,17 +22,14 @@
 
 */
 
+#include "config.h"
+
 #include <glib.h>
 #include <stdlib.h>
 #include <string.h>
 
-// #pragma GCC visibility push(default)
 #include "hexchat-plugin.h"
 #define HEXCHAT_MAX_WORDS 32
-// #pragma GCC visibility pop
-
-//#define EXPORT __attribute((visibility("default")))
-//#define EXPORT
 
 #include "fish.h"
 #include "keystore.h"
@@ -52,26 +49,18 @@ static hexchat_plugin *ph;
  * Returns the path to the key store file.
  */
 gchar *get_config_filename() {
-    return g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL);
-}
+    char *filename_fs, *filename_utf8;
 
-/**
- * Appends data to a string. Returns true if there was sufficient memory.
- * Frees *s and returns false if an error occurs.
- */
-static bool append(char **s, size_t *length, const char *data) {
-    size_t datalen = strlen(data);
-    char *extended = realloc(*s, *length + datalen + 1);
-    if (!extended) {
-        free(*s);
-        return false;
-    }
-    memcpy(extended + *length, data, datalen + 1);
-    *s = extended;
-    *length += datalen;
-    return true;
+    filename_utf8 = g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL);
+    filename_fs = g_filename_from_utf8 (filename_utf8, -1, NULL, NULL, NULL);
+
+    g_free (filename_utf8);
+    return filename_fs;
 }
 
+int irc_nick_cmp(const char *a, const char *b) {
+	return hexchat_nickcmp (ph, a, b);
+}
 
 /*static int handle_debug(char *word[], char *word_eol[], void *userdata) {
     hexchat_printf(ph, "debug incoming: ");
@@ -87,26 +76,26 @@ static bool append(char **s, size_t *length, const char *data) {
  */
 static int handle_outgoing(char *word[], char *word_eol[], void *userdata) {
     const char *own_nick;
-    // Encrypt the message if possible
+    /* Encrypt the message if possible */
     const char *channel = hexchat_get_info(ph, "channel");
     char *encrypted = fish_encrypt_for_nick(channel, word_eol[1]);
     if (!encrypted) return HEXCHAT_EAT_NONE;
     
-    // Display message
+    /* Display message */
     own_nick = hexchat_get_info(ph, "nick");
     hexchat_emit_print(ph, "Your Message", own_nick, word_eol[1], NULL);
     
-    // Send message
+    /* Send message */
     hexchat_commandf(ph, "PRIVMSG %s :+OK %s", channel, encrypted);
     
-    free(encrypted);
+    g_free(encrypted);
     return HEXCHAT_EAT_HEXCHAT;
 }
 
 /**
  * Called when a channel message or private message is received.
  */
-static int handle_incoming(char *word[], char *word_eol[], void *userdata) {
+static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void *userdata) {
     const char *prefix;
     const char *command;
     const char *recipient;
@@ -114,20 +103,19 @@ static int handle_incoming(char *word[], char *word_eol[], void *userdata) {
     const char *peice;
     char *sender_nick;
     char *decrypted;
-    char *message;
     size_t w;
     size_t ew;
     size_t uw;
-    size_t length;
     char prefix_char = 0;
+    GString *message;
 
     if (!irc_parse_message((const char **)word, &prefix, &command, &w))
         return HEXCHAT_EAT_NONE;
     
-    // Topic (command 332) has an extra parameter
+    /* Topic (command 332) has an extra parameter */
     if (!strcmp(command, "332")) w++;
     
-    // Look for encrypted data
+    /* Look for encrypted data */
     for (ew = w+1; ew < HEXCHAT_MAX_WORDS-1; ew++) {
         const char *s = (ew == w+1 ? word[ew]+1 : word[ew]);
         if (*s && (s[1] == '+' || s[1] == 'm')) { prefix_char = *(s++); }
@@ -136,61 +124,70 @@ static int handle_incoming(char *word[], char *word_eol[], void *userdata) {
     }
     return HEXCHAT_EAT_NONE;
   has_encrypted_data: ;
-    // Extract sender nick and recipient nick/channel
+    /* Extract sender nick and recipient nick/channel */
     sender_nick = irc_prefix_get_nick(prefix);
     recipient = word[w];
     
-    // Try to decrypt with these (the keys are searched for in the key store)
+    /* Try to decrypt with these (the keys are searched for in the key store) */
     encrypted = word[ew+1];
     decrypted = fish_decrypt_from_nick(recipient, encrypted);
     if (!decrypted) decrypted = fish_decrypt_from_nick(sender_nick, encrypted);
     
-    // Check for error
+    /* Check for error */
     if (!decrypted) goto decrypt_error;
     
-    // Build unecrypted message
-    message = NULL;
-    length = 0;
-    if (!append(&message, &length, "RECV")) goto decrypt_error;
-    
+    /* Build unecrypted message */
+    message = g_string_sized_new (100); /* TODO: more accurate estimation of size */
+    g_string_append (message, "RECV");
+
+    if (attrs->server_time_utc)
+    {
+        GTimeVal tv = { (glong)attrs->server_time_utc, 0 };
+        char *timestamp = g_time_val_to_iso8601 (&tv);
+
+       g_string_append (message, " @time=");
+       g_string_append (message, timestamp);
+       g_free (timestamp);
+    }
+
     for (uw = 1; uw < HEXCHAT_MAX_WORDS; uw++) {
-        if (word[uw][0] != '\0' && !append(&message, &length, " ")) goto decrypt_error;
+        if (word[uw][0] != '\0')
+            g_string_append_c (message, ' ');
         
         if (uw == ew) {
-            // Add the encrypted data
+            /* Add the encrypted data */
             peice = decrypted;
-            uw++; // Skip "OK+"
+            uw++; /* Skip "OK+" */
             
             if (ew == w+1) {
-                // Prefix with colon, which gets stripped out otherwise
-                if (!append(&message, &length, ":")) goto decrypt_error;
+                /* Prefix with colon, which gets stripped out otherwise */
+                g_string_append_c (message, ':');
             }
             
             if (prefix_char) {
-                char prefix_str[2] = { prefix_char, '\0' };
-                if (!append(&message, &length, prefix_str)) goto decrypt_error;
+                g_string_append_c (message, prefix_char);
             }
             
         } else {
-            // Add unencrypted data (for example, a prefix from a bouncer or bot)
+            /* Add unencrypted data (for example, a prefix from a bouncer or bot) */
             peice = word[uw];
         }
-        
-        if (!append(&message, &length, peice)) goto decrypt_error;
+
+        g_string_append (message, peice);
     }
-    free(decrypted);
+    g_free(decrypted);
     
-    // Simulate unencrypted message
-    //hexchat_printf(ph, "simulating: %s\n", message);
-    hexchat_command(ph, message);
-    
-    free(message);
-    free(sender_nick);
+    /* Simulate unencrypted message */
+    /* hexchat_printf(ph, "simulating: %s\n", message->str); */
+    hexchat_command(ph, message->str);
+
+    g_string_free (message, TRUE);
+    g_free(sender_nick);
     return HEXCHAT_EAT_HEXCHAT;
   
   decrypt_error:
-    free(decrypted);
-    free(sender_nick);
+    g_free(decrypted);
+    g_free(sender_nick);
     return HEXCHAT_EAT_NONE;
 }
 
@@ -201,23 +198,23 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
     const char *nick;
     const char *key;
     
-    // Check syntax
+    /* Check syntax */
     if (*word[2] == '\0') {
         hexchat_printf(ph, "%s\n", usage_setkey);
         return HEXCHAT_EAT_HEXCHAT;
     }
     
     if (*word[3] == '\0') {
-        // /setkey password
+        /* /setkey password */
         nick = hexchat_get_info(ph, "channel");
         key = word_eol[2];
     } else {
-        // /setkey #channel password
+        /* /setkey #channel password */
         nick = word[2];
         key = word_eol[3];
     }
     
-    // Set password
+    /* Set password */
     if (keystore_store_key(nick, key)) {
         hexchat_printf(ph, "Stored key for %s\n", nick);
     } else {
@@ -233,15 +230,15 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
 static int handle_delkey(char *word[], char *word_eol[], void *userdata) {
     const char *nick;
     
-    // Check syntax
+    /* Check syntax */
     if (*word[2] == '\0' || *word[3] != '\0') {
         hexchat_printf(ph, "%s\n", usage_delkey);
         return HEXCHAT_EAT_HEXCHAT;
     }
     
-    nick = word_eol[2];
+    nick = g_strstrip (word_eol[2]);
     
-    // Delete the given nick from the key store
+    /* Delete the given nick from the key store */
     if (keystore_delete_nick(nick)) {
         hexchat_printf(ph, "Deleted key for %s\n", nick);
     } else {
@@ -282,11 +279,11 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle,
     
     /* Add handlers */
     hexchat_hook_command(ph, "", HEXCHAT_PRI_NORM, handle_outgoing, NULL, NULL);
-    hexchat_hook_server(ph, "NOTICE", HEXCHAT_PRI_NORM, handle_incoming, NULL);
-    hexchat_hook_server(ph, "PRIVMSG", HEXCHAT_PRI_NORM, handle_incoming, NULL);
-    //hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, handle_debug, NULL);
-    hexchat_hook_server(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL);
-    hexchat_hook_server(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL);
+    hexchat_hook_server_attrs(ph, "NOTICE", HEXCHAT_PRI_NORM, handle_incoming, NULL);
+    hexchat_hook_server_attrs(ph, "PRIVMSG", HEXCHAT_PRI_NORM, handle_incoming, NULL);
+    /* hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, handle_debug, NULL); */
+    hexchat_hook_server_attrs(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL);
+    hexchat_hook_server_attrs(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL);
     
     hexchat_printf(ph, "%s plugin loaded\n", plugin_name);
     /* Return success */