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