Merge lp:~cando/zeitgeist-datasources/fix_xchat into lp:zeitgeist-datasources/0.8

Proposed by Stefano Candori
Status: Merged
Merged at revision: 110
Proposed branch: lp:~cando/zeitgeist-datasources/fix_xchat
Merge into: lp:zeitgeist-datasources/0.8
Diff against target: 203 lines (+94/-10)
2 files modified
xchat/README (+13/-0)
xchat/zeitgeist-dataprovider.c (+81/-10)
To merge this branch: bzr merge lp:~cando/zeitgeist-datasources/fix_xchat
Reviewer Review Type Date Requested Status
Mikkel Kamstrup Erlandsen (community) Approve
Review via email: mp+46304@code.launchpad.net

Description of the change

In this branch i've improved the XChat dataprovider.
With these mods when the user quits from XChat, the dps sends LEAVE_EVENTS to Zeitgeist, that's very important because i guess that everybody don't use the /part command(that is handled correctly by the dps)for quitting from the channels...

To post a comment you must log in.
111. By Stefano Candori

Xchat dps: change g_slist_append to g_slist_prepend

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

There's something askew with how you use the channel_list GSList.

 1) You leak the string passed in to the g_slist_append() method. g_strdup() copies the string you pass to it and you need to free it again somehow. When that entry is removed from the list you need to g_free() the string somehow.

 2) You g_slist_remove() call will not match anything in your channel_list. It compares pointer values, not strings, for the lookup. Also - you call g_strdup(channel) which allocates new memory, which doesn't get freed. You need a matching g_free() on the return value of that call somewhere.

 3) The 'text' variable you build with g_strconcat() also needs a g_free() before you return. Otherwise you'll leak it.

 4) in on_quit() don't g_strdup() the data arg. Just cast it to a 'const gchar*'. In this case you also shouldn't g_free() it

 5) in on_quit() you leak the url and text strings. They need a g_free() as you do with 'channel' (unless you do as advised in 4)).

review: Needs Fixing
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

There's something askew with how you use the channel_list GSList.

 1) You leak the string passed in to the g_slist_append() method. g_strdup() copies the string you pass to it and you need to free it again somehow. When that entry is removed from the list you need to g_free() the string somehow.

 2) You g_slist_remove() call will not match anything in your channel_list. It compares pointer values, not strings, for the lookup. Also - you call g_strdup(channel) which allocates new memory, which doesn't get freed. You need a matching g_free() on the return value of that call somewhere.

 3) The 'text' variable you build with g_strconcat() also needs a g_free() before you return. Otherwise you'll leak it.

 4) in on_quit() don't g_strdup() the data arg. Just cast it to a 'const gchar*'. In this case you also shouldn't g_free() it

 5) in on_quit() you leak the url and text strings. They need a g_free() as you do with 'channel' (unless you do as advised in 4)).

review: Needs Fixing
112. By Stefano Candori

Fixed memory leaks

113. By Stefano Candori

Removed unuseful variable

Revision history for this message
Stefano Candori (cando) wrote :

OK, i should have fixed all these leaks...:)

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

Just a nitpick :-) Can you change this line:

  channel_list = g_slist_remove(channel_list, tmp->data);

to:

  channel_list = g_slist_delete_link(channel_list, tmp);

The way you do it now you do first a linear search for the data (the while(tmp) loop) and then another linear search to remove it with g_slist_remove(). Since you already have the link you wanna remove, you should use the O(1) function g_slist_delete_link() instead. But this is a nitpick ofcourse since the channels list isn't ever gonna be that big so it matters - but style is style right? :-)

In any case - approved. Nice work Stefano!

review: Approve
114. By Stefano Candori

Changing g_slist_remove to g_slist_delete_link

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'xchat/README'
2--- xchat/README 1970-01-01 00:00:00 +0000
3+++ xchat/README 2011-01-18 09:25:42 +0000
4@@ -0,0 +1,13 @@
5+Zeitgeist plugin to the XChat irc client
6+****************************************
7+
8+To use this plugin:
9+
10+* Install Zeitgeist 0.3 (or greater)
11+* Type "make" and "sudo make install" for a system-wide installation; "make" and "make local-install"
12+ for a local installation
13+
14+*************************************************************************************************************
15+ N.B. Please don't install both system-wide and locally! XChat will load both plugins, getting double events
16+ on your Zeitgeist.
17+*************************************************************************************************************
18
19=== modified file 'xchat/zeitgeist-dataprovider.c'
20--- xchat/zeitgeist-dataprovider.c 2011-01-11 00:19:41 +0000
21+++ xchat/zeitgeist-dataprovider.c 2011-01-18 09:25:42 +0000
22@@ -22,17 +22,16 @@
23 #include "xchat-plugin.h"
24 #include <zeitgeist.h>
25
26-
27 #define PNAME "Zeitgeist"
28 #define PDESC "Inform Zeitgeist about your activity"
29 #define PVERSION "0.1"
30
31-static xchat_plugin *ph = NULL; /* plugin handle */
32-static ZeitgeistLog *zg_log = NULL; /* Zeitgeist-daemon hanlde*/
33+static xchat_plugin *ph = NULL; /* plugin handle */
34+static ZeitgeistLog *zg_log = NULL; /* Zeitgeist-daemon hanlde*/
35+static GSList *channel_list = NULL; /* List of joined channels */
36
37 static void send_event_to_zeitgeist(char *url_, char* text_, const char* ev_interpretation)
38 {
39- /* type is 0 for PART event, 1 for JOIN event */
40 const char *url, *origin, *mimetype, *text;
41 const char *interpretation = NULL;
42 const char *manifestation = NULL;
43@@ -40,7 +39,7 @@
44
45 url = url_;
46 origin = url;
47- mimetype = "text/plain"; //?
48+ mimetype = "text/plain";
49 text = text_;
50 interpretation = ZEITGEIST_NMO_IMMESSAGE;
51 manifestation = ZEITGEIST_NFO_SOFTWARE_SERVICE;
52@@ -66,7 +65,7 @@
53 text,
54 ev_interpretation);*/
55
56- zeitgeist_log_insert_events_no_reply (zg_log, event, NULL);
57+ zeitgeist_log_insert_events_no_reply (zg_log, event, NULL);
58 }
59
60 static int join_cb(char *word[], void *userdata)
61@@ -75,11 +74,16 @@
62 const char *channel = word[2];
63 char *url, *text;
64
65+ channel_list = g_slist_prepend(channel_list, g_strdup(channel));
66+
67 url = g_strconcat("irc://", server, "/", channel, NULL);
68 text = g_strconcat("You joined ", channel, NULL);
69
70 send_event_to_zeitgeist(url, text, ZEITGEIST_ZG_ACCESS_EVENT);
71
72+ g_free(url);
73+ g_free(text);
74+
75 return XCHAT_EAT_NONE;
76 }
77
78@@ -88,11 +92,26 @@
79 const char *server = xchat_get_info(ph, "host");
80 const char *channel = word[3];
81 char *url, *text;
82-
83+ GSList *tmp = channel_list;
84+
85 url = g_strconcat("irc://", server, "/", channel, NULL);
86 text = g_strconcat("You parted from ", channel, NULL);
87
88 send_event_to_zeitgeist(url, text, ZEITGEIST_ZG_LEAVE_EVENT);
89+
90+ while(tmp)
91+ {
92+ if (g_strcmp0 (tmp->data, channel) == 0)
93+ {
94+ g_free(tmp->data);
95+ channel_list = g_slist_delete_link(channel_list, tmp);
96+ break;
97+ }
98+ tmp = tmp->next;
99+ }
100+
101+ g_free(url);
102+ g_free(text);
103
104 return XCHAT_EAT_NONE;
105 }
106@@ -104,10 +123,13 @@
107 char *url, *text;
108
109 url = g_strconcat("irc://", server, "/", channel, NULL);
110- text = g_strconcat(channel, ": you sent a message: ", word[2], NULL);
111+ text = g_strconcat(channel, ": you sent \"", word[2],"\".", NULL);
112
113 send_event_to_zeitgeist(url, text, ZEITGEIST_ZG_SEND_EVENT);
114
115+ g_free(url);
116+ g_free(text);
117+
118 return XCHAT_EAT_NONE;
119 }
120
121@@ -118,13 +140,31 @@
122 char *url, *text;
123
124 url = g_strconcat("irc://", server, "/", channel, NULL);
125- text = g_strconcat(channel, ": you received a message from ", word[1],": ", word[2], NULL);
126+ text = g_strconcat(channel, ": you received \"", word[2],"\" from ", word[1], NULL);
127
128 send_event_to_zeitgeist(url, text, ZEITGEIST_ZG_RECEIVE_EVENT);
129-
130+
131+ g_free(url);
132+ g_free(text);
133+
134 return XCHAT_EAT_NONE;
135 }
136
137+static void on_quit(gpointer data, gpointer userdata)
138+{
139+ const char *server = xchat_get_info(ph, "host");
140+ const char *channel = (const char*) data;
141+ char *url, *text;
142+
143+ url = g_strconcat("irc://", server, "/", channel, NULL);
144+ text = g_strconcat("You parted from ", channel, NULL);
145+
146+ send_event_to_zeitgeist(url, text, ZEITGEIST_ZG_LEAVE_EVENT);
147+
148+ g_free(url);
149+ g_free(text);
150+}
151+
152 void xchat_plugin_get_info(char **name, char **desc, char **version, void **reserved)
153 {
154 *name = PNAME;
155@@ -132,6 +172,9 @@
156 *version = PVERSION;
157 }
158
159+static int initialized = 0;
160+static int reinit_tried = 0;
161+
162 int xchat_plugin_init(xchat_plugin *plugin_handle,
163 char **plugin_name,
164 char **plugin_desc,
165@@ -139,6 +182,16 @@
166 char *arg)
167 {
168 ph = plugin_handle;
169+
170+ /* Block double initalization. */
171+ if (initialized != 0) {
172+ xchat_print(ph, "Zeitgeist plugin already loaded");
173+ /* deinit is called even when init fails, so keep track
174+ * of a reinit failure. */
175+ reinit_tried++;
176+ return 0;
177+ }
178+ initialized = 1;
179
180 *plugin_name = PNAME;
181 *plugin_desc = PDESC;
182@@ -155,3 +208,21 @@
183
184 return 1;
185 }
186+
187+int xchat_plugin_deinit()
188+{
189+ /* A reinitialization was tried. Just give up */
190+ if (reinit_tried) {
191+ reinit_tried--;
192+ return 1;
193+ }
194+
195+ g_slist_foreach(channel_list, on_quit, NULL);
196+ g_slist_foreach(channel_list, (GFunc)g_free, NULL);
197+ g_slist_free(channel_list);
198+ channel_list = NULL;
199+
200+ g_object_unref(zg_log);
201+ zg_log = NULL;
202+ return 1;
203+}

Subscribers

People subscribed via source and target branches