Improved documentation ;o)
[mirrors/libpurple-core-answerscripts.git] / answerscripts.c
CommitLineData
73f7c2ff 1//#define __WIN32__
058e63ec
H
2#ifndef __WIN32__
3 #define ANSWERSCRIPT_EXT ""
4#else
5 #define ANSWERSCRIPT_EXT ".exe"
6#endif
7#define ANSWERSCRIPT "answerscripts" ANSWERSCRIPT_EXT
53478f8c
H
8#define ANSWERSCRIPTS_TIMEOUT_INTERVAL 250
9#define ANSWERSCRIPTS_LINE_LENGTH 4096
0636d441 10#define ENV_PREFIX "ANSW_"
2bcad731 11#define PROTOCOL_PREFIX "prpl-"
b44d7b66
H
12
13#include <stdio.h>
14#include <stdlib.h>
81749a99 15#include <errno.h>
2bcad731 16#include <string.h>
b44d7b66 17
81749a99
H
18#ifndef __WIN32__
19 #include <fcntl.h>
20#endif
21
53478f8c
H
22/* Purple plugin */
23#define PURPLE_PLUGINS
24#include <libpurple/debug.h>
25#include <libpurple/version.h>
26#include <libpurple/conversation.h>
27#include <libpurple/plugin.h>
28#include <libpurple/signals.h>
29#include <libpurple/util.h>
73f7c2ff 30
ca489436 31char *message = NULL;
b44d7b66 32char *hook_script = NULL;
6ec3c19f 33char response[ANSWERSCRIPTS_LINE_LENGTH+1];
b44d7b66
H
34int i;
35
6ec3c19f
H
36typedef struct {
37 FILE *pipe;
38 PurpleConversation *conv;
39} answerscripts_job;
40
81749a99 41int answerscripts_process_message_cb(answerscripts_job *job) {
6ec3c19f
H
42 FILE *pipe = job->pipe;
43 PurpleConversation *conv = job->conv;
44
81749a99
H
45 if (pipe && !feof(pipe)) {
46 if(!fgets(response, ANSWERSCRIPTS_LINE_LENGTH, pipe)
47 && (errno == EWOULDBLOCK || errno == EAGAIN)
48 ) return 1;
49
d852a694 50 for(i=0;response[i];i++) if(response[i]=='\n') response[i]=0;
6ec3c19f 51 purple_conv_im_send(purple_conversation_get_im_data(conv), response);
81749a99
H
52
53 if(!feof(pipe)) return 1;
d852a694
H
54 }
55 pclose(pipe);
6ec3c19f
H
56 free(job);
57 return 0;
d852a694
H
58}
59
73f7c2ff
H
60static void received_im_msg_cb(PurpleAccount *account, char *who, char *buffer, PurpleConversation *conv, PurpleMessageFlags flags, void *data) {
61 if (conv == NULL) conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, who); //* A workaround to avoid skipping of the first message as a result on NULL-conv: */
b44d7b66 62
ca489436
H
63 //Get message
64 message = purple_markup_strip_html(buffer);
65 //printf("\nHarvie received: %s: %s\n", who, message); //debug
b44d7b66
H
66 //purple_conv_im_send(purple_conversation_get_im_data(conv), ":-*"); //debug
67
2bcad731
H
68 //Get protocol ID
69 const char *protocol_id = purple_account_get_protocol_id(account);
70 if(!strncmp(protocol_id,PROTOCOL_PREFIX,strlen(PROTOCOL_PREFIX))) protocol_id += strlen(PROTOCOL_PREFIX); //trim out protocol prefix (eg.: "prpl-irc" => "irc")
71
7a45e05c
H
72 //Get status
73 PurpleStatus *status = purple_account_get_active_status(account);
74 PurpleStatusType *type = purple_status_get_type(status);
75
76 //Get status id
77 const char *status_id = NULL;
78 status_id = purple_primitive_get_id_from_type(purple_status_type_get_primitive(type));
79
80 //Get status message
81 const char *status_msg = NULL;
82 if (purple_status_type_get_attr(type, "message") != NULL) {
83 status_msg = purple_status_get_attr_string(status, "message");
84 } else {
85 status_msg = (char *) purple_savedstatus_get_message(purple_savedstatus_get_current());
86 }
87
ca489436 88 //Export variables to environment
51b65634 89 setenv(ENV_PREFIX "MSG", message, 1);
2bcad731
H
90 setenv(ENV_PREFIX "FROM", who, 1);
91 setenv(ENV_PREFIX "PROTOCOL", protocol_id, 1);
51b65634
H
92 setenv(ENV_PREFIX "STATUS", status_id, 1);
93 setenv(ENV_PREFIX "STATUS_MSG", status_msg, 1);
6ec3c19f 94
ca489436 95 //Launch job on background
6ec3c19f
H
96 answerscripts_job *job = (answerscripts_job*) malloc(sizeof(answerscripts_job));
97 job->pipe = popen(hook_script, "r");
98 job->conv = conv;
99
81749a99
H
100 #ifndef __WIN32__
101 int fflags = fcntl(fileno(job->pipe), F_GETFL, 0);
102 fcntl(fileno(job->pipe), F_SETFL, fflags | O_NONBLOCK);
103 #endif
104
105 purple_timeout_add(ANSWERSCRIPTS_TIMEOUT_INTERVAL, (GSourceFunc) answerscripts_process_message_cb, (gpointer) job);
b44d7b66
H
106}
107
b44d7b66 108static gboolean plugin_load(PurplePlugin * plugin) {
6ec3c19f 109 asprintf(&hook_script,"%s/%s",purple_user_dir(),ANSWERSCRIPT);
b44d7b66 110 void *conv_handle = purple_conversations_get_handle();
73f7c2ff 111 purple_signal_connect(conv_handle, "received-im-msg", plugin, PURPLE_CALLBACK(received_im_msg_cb), NULL);
53478f8c 112 return TRUE;
b44d7b66
H
113}
114
115static gboolean plugin_unload(PurplePlugin * plugin) {
116 free(hook_script);
53478f8c 117 return TRUE;
b44d7b66
H
118}
119
120static PurplePluginInfo info = {
121 PURPLE_PLUGIN_MAGIC,
122 PURPLE_MAJOR_VERSION,
123 PURPLE_MINOR_VERSION,
124 PURPLE_PLUGIN_STANDARD,
125 NULL,
126 0,
127 NULL,
128 PURPLE_PRIORITY_DEFAULT,
129
130 "core-answerscripts",
131 "AnswerScripts",
fe6fec76 132 "0.3.0",
53478f8c
H
133 "Framework for hooking scripts to process received messages for libpurple clients",
134 "This plugin will execute script ~/.purple/" ANSWERSCRIPT " "
135 "or any other executable called " ANSWERSCRIPT " and found in purple_user_dir() "
136 "for each single instant message received.\n"
137 "\n- Envinronment values PURPLE_MSG and PURPLE_FROM will be set to carry "
138 "informations about message text and sender so script can respond to that message."
139 "\n- Any text printed to STDOUT by the script will be sent back as answer to message."
140 "\n\nPlease see example scripts, documentation or source code for more informations...",
b44d7b66 141 "Harvie <harvie@email.cz>",
53478f8c 142 "http://github.com/harvie/libpurple-core-answerscripts",
b44d7b66
H
143
144 plugin_load,
145 plugin_unload,
146 NULL,
147 NULL,
148 NULL,
149 NULL,
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 NULL
155};
156
157static void init_plugin(PurplePlugin * plugin) {
158
159}
160
161PURPLE_INIT_PLUGIN(autoanswer, init_plugin, info)
This page took 0.252623 seconds and 4 git commands to generate.