Mercurial > pidgin.yaz
annotate src/idle.c @ 13143:a1d5f154585b
[gaim-migrate @ 15506]
SF Patch #1415729 from Evan
"I've received a few crash reports in which yahoo_receivefile_connected()
crashes in g_strdup_printf() as a result of being passed a NULL string.
There are only two arguments to that call... xd->path and xd->host. If
either were null for some reason, we couldn't receive a file, anyways, since
we need both to do the HTTP GET request.
This patch checks against NULL for both and cancels the transfer in the
same manner it would be canceled if fed a negative (invalid) source."
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Tue, 07 Feb 2006 01:43:27 +0000 |
parents | bd80fb1e8406 |
children | b76c6de0c3b5 |
rev | line source |
---|---|
12272 | 1 /* |
2 * gaim | |
3 * | |
4 * Gaim is the legal property of its developers, whose names are too numerous | |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
23 #include "internal.h" | |
24 | |
25 #include "connection.h" | |
26 #include "debug.h" | |
27 #include "idle.h" | |
28 #include "log.h" | |
29 #include "prefs.h" | |
30 #include "savedstatuses.h" | |
31 #include "signals.h" | |
32 | |
33 #define IDLEMARK 600 /* 10 minutes! */ | |
34 #define IDLE_CHECK_INTERVAL 5 /* 5 seconds */ | |
35 | |
36 typedef enum | |
37 { | |
38 GAIM_IDLE_NOT_AWAY = 0, | |
39 GAIM_IDLE_AUTO_AWAY, | |
40 GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY | |
41 | |
42 } GaimAutoAwayState; | |
43 | |
44 static GaimIdleUiOps *idle_ui_ops = NULL; | |
45 | |
46 /** | |
47 * This is needed for the I'dle Mak'er plugin to work correctly. We | |
48 * use it to determine if we're the ones who set our accounts idle | |
49 * or if someone else did it (the I'dle Mak'er plugin, for example). | |
12825 | 50 * Basically we just keep track of which accounts were set idle by us, |
51 * and then we'll only set these specific accounts unidle when the | |
52 * user returns. | |
12272 | 53 */ |
12825 | 54 static GList *idled_accts = NULL; |
12272 | 55 |
56 static guint idle_timer = 0; | |
57 | |
58 static time_t last_active_time = 0; | |
59 | |
60 static void | |
61 set_account_autoaway(GaimConnection *gc) | |
62 { | |
63 GaimAccount *account; | |
64 GaimPresence *presence; | |
65 GaimStatus *status; | |
66 | |
67 if (gc->is_auto_away) | |
68 /* This account is already auto-away! */ | |
69 return; | |
70 | |
71 account = gaim_connection_get_account(gc); | |
72 presence = gaim_account_get_presence(account); | |
73 status = gaim_presence_get_active_status(presence); | |
74 | |
75 if (gaim_status_is_available(status)) | |
76 { | |
77 GaimSavedStatus *saved_status; | |
78 | |
79 gaim_debug_info("idle", "Making %s auto-away\n", | |
80 gaim_account_get_username(account)); | |
81 | |
82 saved_status = gaim_savedstatus_get_idleaway(); | |
83 gaim_savedstatus_activate_for_account(saved_status, account); | |
84 | |
85 gc->is_auto_away = GAIM_IDLE_AUTO_AWAY; | |
86 } else { | |
87 gc->is_auto_away = GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY; | |
88 } | |
89 } | |
90 | |
91 static void | |
92 unset_account_autoaway(GaimConnection *gc) | |
93 { | |
94 GaimAccount *account; | |
95 GaimPresence *presence; | |
96 GaimStatus *status; | |
97 GaimSavedStatus *saved_status; | |
98 | |
99 account = gaim_connection_get_account(gc); | |
100 presence = gaim_account_get_presence(account); | |
101 status = gaim_presence_get_active_status(presence); | |
102 | |
103 if (!gc->is_auto_away) | |
104 /* This account is already not auto-away! */ | |
105 return; | |
106 | |
107 if (gc->is_auto_away == GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY) { | |
108 gc->is_auto_away = GAIM_IDLE_NOT_AWAY; | |
109 } else { | |
110 gc->is_auto_away = GAIM_IDLE_NOT_AWAY; | |
111 | |
112 gaim_debug_info("idle", "%s returning from auto-away\n", | |
113 gaim_account_get_username(account)); | |
114 | |
115 /* Return our account to its previous status */ | |
116 saved_status = gaim_savedstatus_get_current(); | |
117 gaim_savedstatus_activate_for_account(saved_status, account); | |
118 } | |
119 } | |
120 | |
121 static void | |
12825 | 122 set_account_idle(GaimAccount *account, int time_idle) |
12272 | 123 { |
124 GaimPresence *presence; | |
125 | |
126 presence = gaim_account_get_presence(account); | |
127 | |
128 if (gaim_presence_is_idle(presence)) | |
129 /* This account is already idle! */ | |
130 return; | |
131 | |
132 gaim_debug_info("idle", "Setting %s idle %d seconds\n", | |
133 gaim_account_get_username(account), time_idle); | |
134 gaim_presence_set_idle(presence, TRUE, time(NULL) - time_idle); | |
12825 | 135 idled_accts = g_list_prepend(idled_accts, account); |
12272 | 136 } |
137 | |
138 static void | |
12825 | 139 set_account_unidle(GaimAccount *account) |
12272 | 140 { |
141 GaimPresence *presence; | |
142 | |
143 presence = gaim_account_get_presence(account); | |
144 | |
12825 | 145 idled_accts = g_list_remove(idled_accts, account); |
146 | |
12272 | 147 if (!gaim_presence_is_idle(presence)) |
148 /* This account is already unidle! */ | |
149 return; | |
150 | |
151 gaim_debug_info("idle", "Setting %s unidle\n", | |
152 gaim_account_get_username(account)); | |
153 gaim_presence_set_idle(presence, FALSE, time(NULL)); | |
154 } | |
155 | |
156 /* | |
157 * This function should be called when you think your idle state | |
158 * may have changed. Maybe you're over the 10-minute mark and | |
159 * Gaim should start reporting idle time to the server. Maybe | |
160 * you've returned from being idle. Maybe your auto-away message | |
161 * should be set. | |
162 * | |
163 * There is no harm to calling this many many times, other than | |
164 * it will be kinda slow. This is called every 5 seconds by a | |
165 * timer set when Gaim starts. It is also called when | |
166 * you send an IM, a chat, etc. | |
167 * | |
168 * This function has 3 sections. | |
169 * 1. Get your idle time. It will query XScreenSaver or Windows | |
170 * or use the Gaim idle time. Whatever. | |
171 * 2. Set or unset your auto-away message. | |
172 * 3. Report your current idle time to the IM server. | |
173 */ | |
174 static gint | |
175 check_idleness() | |
176 { | |
177 time_t time_idle; | |
178 gboolean auto_away; | |
12573 | 179 const gchar *idle_reporting; |
12272 | 180 gboolean report_idle; |
181 GList *l; | |
182 | |
183 gaim_signal_emit(gaim_blist_get_handle(), "update-idle"); | |
184 | |
12573 | 185 idle_reporting = gaim_prefs_get_string("/core/away/idle_reporting"); |
186 report_idle = TRUE; | |
187 if (!strcmp(idle_reporting, "system") && | |
188 (idle_ui_ops != NULL) && (idle_ui_ops->get_time_idle != NULL)) | |
189 { | |
190 /* Use system idle time (mouse or keyboard movement, etc.) */ | |
12272 | 191 time_idle = idle_ui_ops->get_time_idle(); |
12573 | 192 } |
193 else if (!strcmp(idle_reporting, "gaim")) | |
194 { | |
12272 | 195 /* Use 'Gaim idle' */ |
196 time_idle = time(NULL) - last_active_time; | |
12573 | 197 } |
198 else | |
199 { | |
200 /* Don't report idle time */ | |
201 time_idle = 0; | |
202 report_idle = FALSE; | |
203 } | |
12272 | 204 |
205 /* Auto-away stuff */ | |
206 auto_away = gaim_prefs_get_bool("/core/away/away_when_idle"); | |
207 if (auto_away && | |
208 (time_idle > (60 * gaim_prefs_get_int("/core/away/mins_before_away")))) | |
209 { | |
210 for (l = gaim_connections_get_all(); l != NULL; l = l->next) | |
211 set_account_autoaway(l->data); | |
212 } | |
213 else if (time_idle < 60 * gaim_prefs_get_int("/core/away/mins_before_away")) | |
214 { | |
215 for (l = gaim_connections_get_all(); l != NULL; l = l->next) | |
216 unset_account_autoaway(l->data); | |
217 } | |
218 | |
219 /* Idle reporting stuff */ | |
12825 | 220 if (report_idle && (time_idle >= IDLEMARK)) |
12272 | 221 { |
222 for (l = gaim_connections_get_all(); l != NULL; l = l->next) | |
12825 | 223 { |
224 GaimConnection *gc = l->data; | |
225 set_account_idle(gaim_connection_get_account(gc), time_idle); | |
226 } | |
12272 | 227 } |
12825 | 228 else if (!report_idle || (time_idle < IDLEMARK)) |
12272 | 229 { |
12825 | 230 while (idled_accts != NULL) |
231 set_account_unidle(idled_accts->data); | |
12272 | 232 } |
233 | |
234 return TRUE; | |
235 } | |
236 | |
237 static void | |
238 im_msg_sent_cb(GaimAccount *account, const char *receiver, | |
239 const char *message, void *data) | |
240 { | |
241 /* Check our idle time after an IM is sent */ | |
242 check_idleness(); | |
243 } | |
244 | |
12825 | 245 static void |
246 signing_off_cb(GaimConnection *gc, void *data) | |
247 { | |
248 GaimAccount *account; | |
249 | |
250 account = gaim_connection_get_account(gc); | |
251 idled_accts = g_list_remove(idled_accts, account); | |
252 } | |
253 | |
12272 | 254 void |
255 gaim_idle_touch() | |
256 { | |
257 time(&last_active_time); | |
258 } | |
259 | |
260 void | |
261 gaim_idle_set(time_t time) | |
262 { | |
263 last_active_time = time; | |
264 } | |
265 | |
266 void | |
267 gaim_idle_set_ui_ops(GaimIdleUiOps *ops) | |
268 { | |
269 idle_ui_ops = ops; | |
270 } | |
271 | |
272 GaimIdleUiOps * | |
273 gaim_idle_get_ui_ops(void) | |
274 { | |
275 return idle_ui_ops; | |
276 } | |
277 | |
12412
a88ca6da0b38
[gaim-migrate @ 14719]
Richard Laager <rlaager@wiktel.com>
parents:
12272
diff
changeset
|
278 static void * |
12272 | 279 gaim_idle_get_handle() |
280 { | |
281 static int handle; | |
282 | |
283 return &handle; | |
284 } | |
285 | |
286 void | |
287 gaim_idle_init() | |
288 { | |
289 /* Add the timer to check if we're idle */ | |
290 idle_timer = gaim_timeout_add(IDLE_CHECK_INTERVAL * 1000, check_idleness, NULL); | |
291 | |
292 gaim_signal_connect(gaim_conversations_get_handle(), "sent-im-msg", | |
293 gaim_idle_get_handle(), | |
294 GAIM_CALLBACK(im_msg_sent_cb), NULL); | |
12825 | 295 gaim_signal_connect(gaim_connections_get_handle(), "signing-off", |
296 gaim_idle_get_handle(), | |
297 GAIM_CALLBACK(signing_off_cb), NULL); | |
12272 | 298 |
299 gaim_idle_touch(); | |
300 } | |
301 | |
302 void | |
303 gaim_idle_uninit() | |
304 { | |
305 gaim_signals_disconnect_by_handle(gaim_idle_get_handle()); | |
306 | |
307 /* Remove the idle timer */ | |
308 if (idle_timer > 0) | |
309 gaim_timeout_remove(idle_timer); | |
310 idle_timer = 0; | |
311 } |