Skip to content

Instantly share code, notes, and snippets.

@syldrathecat
Created March 28, 2016 06:10
Show Gist options
  • Save syldrathecat/7243fbf5163122b9bde9 to your computer and use it in GitHub Desktop.
Save syldrathecat/7243fbf5163122b9bde9 to your computer and use it in GitHub Desktop.
/*
Built using the following command from libpurple directory:
gcc ./nss-flist-test.c -lm -lresolv `pkg-config --cflags --libs glib-2.0` \
`pkg-config --cflags --libs gobject-2.0` `pkg-config --cflags --libs gmodule-2.0` \
`pkg-config --cflags --libs gio-2.0` \
`pkg-config --cflags --libs nspr` `pkg-config --cflags --libs nss` \
`pkg-config --cflags --libs dbus-1` `pkg-config --cflags --libs dbus-glib-1` \
`pkg-config --cflags --libs libxml-2.0` -o nss-flist-test -I . \
account.c mediamanager.c stringref.c accountopt.c dbus-useful.c mime.c stun.c blist.c \
debug.c nat-pmp.c theme.c buddyicon.c desktopitem.c network.c request.c theme-loader.c \
certificate.c dnsquery.c notify.c roomlist.c theme-manager.c cipher.c dnssrv.c \
savedstatuses.c upnp.c circbuffer.c ntlm.c server.c util.c cmds.c eventloop.c plugin.c \
signals.c value.c connection.c ft.c pluginpref.c smiley.c version.c conversation.c idle.c \
pounce.c sound.c whiteboard.c core.c imgstore.c prefs.c sound-theme.c xmlnode.c log.c \
privacy.c sound-theme-loader.c dbus-server.c marshallers.c proxy.c sslconn.c media.c prpl.c \
status.c ciphers/des.c ciphers/gchecksum.c ciphers/hmac.c ciphers/md4.c ciphers/md5.c \
ciphers/rc4.c ciphers/sha1.c ciphers/sha256.c \
-DDATADIR=\"/usr/local/share\" -DLIBDIR=\"/usr/local/lib/purple-2/\" -DVERSION=\"2.10.13\" \
-DSYSCONFDIR=\"/usr/local/etc\" -DLOCALEDIR=\"/usr/local/locale\" -DSIZEOF_TIME_T=8 \
-DSTATIC_PROTO_INIT="static void static_proto_init(void) { }" \
-DPURPLE_PLUGINS=1 -DHAVE_NSS=1 -DHAVE_SSL=1 -DHAVE_GNUTLS=1
*/
#include "purple.h"
#include <stdio.h>
#include <unistd.h>
void next_request();
void my_ui_prefs_init(void) { }
void my_debug_ui_init(void) { }
void my_ui_init(void) { }
void my_quit(void) { }
GHashTable* my_get_ui_info(void)
{
GHashTable* info = g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_insert(info, "name", "nss-flist-test");
g_hash_table_insert(info, "version", "1.0");
g_hash_table_insert(info, "website", "http://www.f-list.net/");
g_hash_table_insert(info, "dev-website", "https://github.com/fcwill/fchat-pidgin/");
g_hash_table_insert(info, "client-type", "bot");
return info;
}
time_t my_get_time_idle(void)
{
return (time_t)0;
}
typedef struct my_io_t
{
PurpleInputFunction function;
gpointer data;
} my_io_t;
#define FINCH_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR)
#define FINCH_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
gboolean my_io_invoke(GIOChannel* source, GIOCondition condition, gpointer data)
{
my_io_t* io_struct = (my_io_t*)data;
PurpleInputCondition purple_cond = 0;
gint fd = g_io_channel_unix_get_fd(source);
if (condition & FINCH_READ_COND)
purple_cond |= PURPLE_INPUT_READ;
if (condition & FINCH_WRITE_COND)
purple_cond |= PURPLE_INPUT_WRITE;
//printf("input invoke: %i\n", fd);
io_struct->function(io_struct->data, fd, condition);
return TRUE;
}
void my_io_destroy(gpointer data)
{
free(data);
}
guint my_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function, gpointer data)
{
GIOChannel* channel = g_io_channel_unix_new(fd);
GIOCondition cond = 0;
my_io_t* io_struct = malloc(sizeof(my_io_t));
io_struct->function = function;
io_struct->data = data;
if (condition & PURPLE_INPUT_READ)
cond |= FINCH_READ_COND;
if (condition & PURPLE_INPUT_WRITE)
cond |= FINCH_WRITE_COND;
//printf("input added: %i\n", fd);
guint id = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, my_io_invoke, (gpointer)io_struct, my_io_destroy);
g_io_channel_unref(channel);
return id;
}
static void my_http_cb(PurpleUtilFetchUrlData *url_data, gpointer data, const gchar *b, size_t len, const gchar *err)
{
printf("[Request #%i] Recieved %i bytes\n", (int)data, (int)len);
if (len == 0)
{
printf("Error was: %s\n", err);
}
else
{
char filename_buf[] = "./dump0.png";
if ((int)data == 1)
{
filename_buf[8] = 'i';
filename_buf[9] = 'c';
filename_buf[10] = 'o';
}
filename_buf[6] = '0' + (int)data;
printf("--- Dumping data to %s ---\n", filename_buf);
FILE* fh = fopen(filename_buf, "wb");
fwrite(b, 1, len, fh);
fclose(fh);
printf("--- Dumping data done ---\n");
}
next_request();
}
void my_debug_print(PurpleDebugLevel level, const char* category, const char* arg_s)
{
// Redundant
}
gboolean my_debug_is_enabled(PurpleDebugLevel level, const char* category)
{
return TRUE;
}
static int i = 0;
// Tries to roughly simulate how the library is used in the plugin
void next_request()
{
++i;
if (i == 1)
{
const char* full_url = "https://www.f-list.net/favicon.ico";
printf("Making request #%i: %s\n", i, full_url);
purple_util_fetch_url_request(full_url, TRUE, "Pidgin F-Chat 0.5.0", TRUE, NULL, FALSE, my_http_cb, (gpointer)i);
}
else if (i >= 2 && i <= 3)
{
const char* full_url = "https://static.f-list.net/images/avatar/pidgin.png";
printf("Making request #%i: %s\n", i, full_url);
purple_util_fetch_url_request(full_url, TRUE, "Pidgin F-Chat 0.5.0", TRUE, NULL, FALSE, my_http_cb, (gpointer)i);
}
else if (i == 4)
{
const char* full_url = "https://static.f-list.net/images/avatar/syldra%20kitty.png";
printf("Making request #%i: %s\n", i, full_url);
purple_util_fetch_url_request(full_url, TRUE, "Pidgin F-Chat 0.5.0", TRUE, NULL, FALSE, my_http_cb, (gpointer)i);
printf("Making request #%i: %s\n", i, full_url);
purple_util_fetch_url_request(full_url, TRUE, "Pidgin F-Chat 0.5.0", TRUE, NULL, FALSE, my_http_cb, (gpointer)(i+1));
printf("Making request #%i: %s\n", i, full_url);
purple_util_fetch_url_request(full_url, TRUE, "Pidgin F-Chat 0.5.0", TRUE, NULL, FALSE, my_http_cb, (gpointer)(i+2));
}
else if (i == 7)
{
puts("We're done.");
exit(0);
}
}
int main()
{
PurpleCoreUiOps ui_ops;
PurpleIdleUiOps idle_ui_ops;
PurpleEventLoopUiOps eventloop_ui_ops;
PurpleDebugUiOps debug_ui_ops;
GMainLoop* loop;
ui_ops.ui_prefs_init = my_ui_prefs_init;
ui_ops.debug_ui_init = my_debug_ui_init;
ui_ops.ui_init = my_ui_init;
ui_ops.quit = my_quit;
ui_ops.get_ui_info = my_get_ui_info;
idle_ui_ops.get_time_idle = my_get_time_idle;
eventloop_ui_ops.timeout_add = g_timeout_add;
eventloop_ui_ops.timeout_remove = g_source_remove;
eventloop_ui_ops.input_add = my_input_add;
eventloop_ui_ops.input_remove = g_source_remove;
eventloop_ui_ops.input_get_error = NULL;
eventloop_ui_ops.timeout_add_seconds = g_timeout_add_seconds;
debug_ui_ops.print = my_debug_print;
debug_ui_ops.is_enabled = my_debug_is_enabled;
purple_core_set_ui_ops(&ui_ops);
purple_eventloop_set_ui_ops(&eventloop_ui_ops);
purple_idle_set_ui_ops(&idle_ui_ops);
purple_debug_set_enabled(TRUE);
purple_debug_set_unsafe(TRUE);
purple_core_init("x-nss-flist-test");
next_request();
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
purple_core_quit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment