78
by mvo
* src/*.c: added #include "config.h" (/me <- stupid for forgeting it) |
1 |
#ifdef HAVE_CONFIG_H
|
2 |
#include "config.h" |
|
3 |
#endif
|
|
4 |
||
340
by Michael Vogt
* code cleanups |
5 |
#include <fcntl.h> |
476
by Michael Vogt
fix -Wall errors |
6 |
#include <unistd.h> |
7 |
#include <stdlib.h> |
|
8 |
||
143
by mvo
* various include fixes |
9 |
#include <glib.h> |
10 |
#include <gtk/gtk.h> |
|
11 |
#include <glib/gstdio.h> |
|
210
by Michael Vogt
* added a notification on hooks |
12 |
#include <libnotify/notify.h> |
143
by mvo
* various include fixes |
13 |
|
14 |
#include <locale.h> |
|
390
by Michael Vogt
* src/hooks.c: |
15 |
#include <langinfo.h> |
143
by mvo
* various include fixes |
16 |
|
17 |
#include "update-notifier.h" |
|
45
by mvo
* added basic "interactive-update-hooks" support |
18 |
#include "hooks.h" |
19 |
#include "rfc822.h" |
|
20 |
#include "assert.h" |
|
21 |
||
210
by Michael Vogt
* added a notification on hooks |
22 |
|
45
by mvo
* added basic "interactive-update-hooks" support |
23 |
/* relative to the home dir */
|
591
by Michael Vogt
apply xdg patches by Sebastian Geiger, many thanks |
24 |
#define HOOKS_SEEN_DEPRECATED ".update-notifier/hooks_seen"
|
25 |
/* relative to the XDG_CONFIG_HOME dir */
|
|
26 |
#define HOOKS_SEEN "update-notifier/hooks_seen"
|
|
168
by mvo
* src/hooks.c: |
27 |
|
28 |
/* used by e.g. the installer to mark stuff that's already done */
|
|
128
by mvo
* debian/dirs: |
29 |
#define GLOBAL_HOOKS_SEEN "/etc/update-notifier/hooks_seen"
|
125
by mvo
* src/hooks.c: |
30 |
|
143
by mvo
* various include fixes |
31 |
|
400
by Michael Vogt
* src/hooks.c: |
32 |
// the size of the md5 hash digest for the duplicated note detection
|
33 |
static const int DIGEST_SIZE=16; |
|
34 |
||
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
35 |
static inline void |
36 |
g_debug_hooks(const char *msg, ...) |
|
125
by mvo
* src/hooks.c: |
37 |
{
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
38 |
va_list va; |
454
by Michael Vogt
fix crash in --debug mode (LP: #348883) |
39 |
va_start(va, msg); |
40 |
g_logv("hooks",G_LOG_LEVEL_DEBUG, msg, va); |
|
41 |
va_end(va); |
|
125
by mvo
* src/hooks.c: |
42 |
}
|
43 |
||
45
by mvo
* added basic "interactive-update-hooks" support |
44 |
void hooks_trayicon_update_tooltip (TrayApplet *un, int num_hooks) |
45 |
{
|
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
46 |
g_debug_hooks("update_tooltip: %p ", un); |
45
by mvo
* added basic "interactive-update-hooks" support |
47 |
gchar *updates; |
48 |
||
317
by Michael Vogt
* implemented new "Title" key in the UpgradeHooks file |
49 |
updates = _("Information available"); |
45
by mvo
* added basic "interactive-update-hooks" support |
50 |
|
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
51 |
gtk_status_icon_set_tooltip(un->tray_icon, updates); |
45
by mvo
* added basic "interactive-update-hooks" support |
52 |
}
|
53 |
||
124
by mvo
* src/hooks.{c,h}: |
54 |
|
125
by mvo
* src/hooks.c: |
55 |
// compare a HookFile with a filename and find the HookFile that matches
|
45
by mvo
* added basic "interactive-update-hooks" support |
56 |
gint compare_hook_func(gconstpointer a, gconstpointer b) |
57 |
{
|
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
58 |
//g_debug_hooks("compare: %s %s\n",(char*)(((HookFileSeen*)a)->filename),(char*)b);
|
161
by mvo
* src/hooks.c: |
59 |
g_assert(a); |
60 |
g_assert(b); |
|
61 |
||
124
by mvo
* src/hooks.{c,h}: |
62 |
return strcmp(((HookFile*)a)->filename, b); |
45
by mvo
* added basic "interactive-update-hooks" support |
63 |
}
|
64 |
||
164
by mvo
* src/hooks.c: |
65 |
// return the most recent mtime or ctime of the file
|
66 |
time_t hook_file_time(const gchar *filename) |
|
45
by mvo
* added basic "interactive-update-hooks" support |
67 |
{
|
124
by mvo
* src/hooks.{c,h}: |
68 |
struct stat buf; |
69 |
char *file = g_strdup_printf("%s/%s",HOOKS_DIR, filename); |
|
70 |
if(g_stat(file, &buf) <0) { |
|
191
by mvo
* move a bunch of g_error -> g_warning |
71 |
g_warning("can't stat %s\n",file); |
144
by mvo
* debian/control: |
72 |
g_free(file); |
124
by mvo
* src/hooks.{c,h}: |
73 |
return 0; |
74 |
}
|
|
75 |
g_free(file); |
|
164
by mvo
* src/hooks.c: |
76 |
|
77 |
time_t mtime = buf.st_mtime; |
|
78 |
time_t ctime = buf.st_ctime; |
|
79 |
||
80 |
return mtime > ctime ? mtime : ctime; |
|
45
by mvo
* added basic "interactive-update-hooks" support |
81 |
}
|
82 |
||
476
by Michael Vogt
fix -Wall errors |
83 |
gboolean hook_file_md5(const gchar *filename, guint8 *md5) |
144
by mvo
* debian/control: |
84 |
{
|
380.1.2
by Bruce Cowan
Removed custom MD5 code, make use of GChecksum, code a bit odd though. |
85 |
guchar buf[512]; |
144
by mvo
* debian/control: |
86 |
FILE *f; |
87 |
char *file; |
|
476
by Michael Vogt
fix -Wall errors |
88 |
gsize n; |
380.1.2
by Bruce Cowan
Removed custom MD5 code, make use of GChecksum, code a bit odd though. |
89 |
GChecksum *checksum; |
144
by mvo
* debian/control: |
90 |
|
91 |
file = g_strdup_printf("%s/%s",HOOKS_DIR, filename); |
|
92 |
f = fopen(file,"r"); |
|
162
by mvo
* src/hooks.c: |
93 |
if(f == NULL) { |
94 |
g_warning("can't read %s\n",file); |
|
144
by mvo
* debian/control: |
95 |
g_free(file); |
96 |
return FALSE; |
|
97 |
}
|
|
380.1.2
by Bruce Cowan
Removed custom MD5 code, make use of GChecksum, code a bit odd though. |
98 |
checksum = g_checksum_new(G_CHECKSUM_MD5); |
144
by mvo
* debian/control: |
99 |
do { |
380.1.2
by Bruce Cowan
Removed custom MD5 code, make use of GChecksum, code a bit odd though. |
100 |
n = fread(buf, 1, sizeof(buf), f); |
101 |
g_checksum_update(checksum, buf, n); |
|
144
by mvo
* debian/control: |
102 |
} while(n > 0); |
400
by Michael Vogt
* src/hooks.c: |
103 |
|
104 |
n=DIGEST_SIZE; |
|
105 |
g_checksum_get_digest(checksum, md5, &n); |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
106 |
//g_debug_hooks("md5: %s -> '%s' ", filename, md5);
|
144
by mvo
* debian/control: |
107 |
|
108 |
g_free(file); |
|
380.1.2
by Bruce Cowan
Removed custom MD5 code, make use of GChecksum, code a bit odd though. |
109 |
g_checksum_free(checksum); |
144
by mvo
* debian/control: |
110 |
return TRUE; |
111 |
}
|
|
112 |
||
125
by mvo
* src/hooks.c: |
113 |
/* mark a given hook file as seen
|
114 |
(actually implemented to write out all the information we have)
|
|
115 |
*/
|
|
210
by Michael Vogt
* added a notification on hooks |
116 |
gboolean hook_file_mark_as_seen(HookTrayAppletPrivate *priv, |
124
by mvo
* src/hooks.{c,h}: |
117 |
HookFile *hf) |
45
by mvo
* added basic "interactive-update-hooks" support |
118 |
{
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
119 |
g_debug_hooks("mark_hook_file_as_seen: %s", hf->filename); |
124
by mvo
* src/hooks.{c,h}: |
120 |
|
144
by mvo
* debian/control: |
121 |
// copy the md5
|
476
by Michael Vogt
fix -Wall errors |
122 |
guint8 md5[DIGEST_SIZE]; |
208
by Michael Vogt
* -Wall clean now |
123 |
hook_file_md5(hf->filename, md5); |
144
by mvo
* debian/control: |
124 |
|
124
by mvo
* src/hooks.{c,h}: |
125 |
// mark as seen
|
126 |
hf->seen = TRUE; |
|
127 |
||
167
by mvo
* src/hooks.c: |
128 |
// update the time (extra paranoia, shouldn't be needed)
|
129 |
hf->mtime = hook_file_time(hf->filename); |
|
130 |
||
124
by mvo
* src/hooks.{c,h}: |
131 |
// write out the list of known files
|
590
by Michael Vogt
* updated to use xdg config dirs |
132 |
gchar *filename = g_strdup_printf("%s/%s", |
133 |
g_get_user_config_dir(), |
|
134 |
HOOKS_SEEN); |
|
124
by mvo
* src/hooks.{c,h}: |
135 |
FILE *f = fopen(filename, "w"); |
125
by mvo
* src/hooks.c: |
136 |
if(f==NULL) { |
137 |
g_warning("Something went wrong writing the users hook file"); |
|
45
by mvo
* added basic "interactive-update-hooks" support |
138 |
return FALSE; |
125
by mvo
* src/hooks.c: |
139 |
}
|
144
by mvo
* debian/control: |
140 |
|
167
by mvo
* src/hooks.c: |
141 |
// write out all the hooks that are seen
|
142 |
//
|
|
143 |
// and any hooks that are not yet seen but have the same md5sum
|
|
144 |
// as the one just marked (avoids showing duplicated hooks effecivly).
|
|
145 |
//
|
|
146 |
// For hooks with the same md5sum use the mtime of the just displayed hook
|
|
210
by Michael Vogt
* added a notification on hooks |
147 |
GList *elm = g_list_first(priv->hook_files); |
124
by mvo
* src/hooks.{c,h}: |
148 |
for(;elm != NULL; elm = g_list_next(elm)) { |
149 |
HookFile *e = (HookFile*)elm->data; |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
150 |
g_debug_hooks("will write out: %s (%s)",e->filename, e->md5); |
167
by mvo
* src/hooks.c: |
151 |
if(e->seen == TRUE) { |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
152 |
g_debug_hooks("e->seen: %s %li %x", e->filename,e->mtime, (int)(e->cmd_run)); |
340
by Michael Vogt
* code cleanups |
153 |
fprintf(f,"%s %li %x\n", e->filename, e->mtime, (int)(e->cmd_run)); |
400
by Michael Vogt
* src/hooks.c: |
154 |
} else if(memcmp(e->md5,md5,DIGEST_SIZE) == 0) { |
144
by mvo
* debian/control: |
155 |
e->seen = TRUE; |
340
by Michael Vogt
* code cleanups |
156 |
fprintf(f,"%s %li %x\n", e->filename,hf->mtime, (int)(e->cmd_run)); |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
157 |
g_debug_hooks("same md5: %s %li %x",e->filename,hf->mtime,(int)(e->cmd_run)); |
125
by mvo
* src/hooks.c: |
158 |
}
|
124
by mvo
* src/hooks.{c,h}: |
159 |
}
|
45
by mvo
* added basic "interactive-update-hooks" support |
160 |
|
161 |
fclose(f); |
|
162 |
g_free(filename); |
|
163 |
||
164 |
return TRUE; |
|
165 |
}
|
|
166 |
||
125
by mvo
* src/hooks.c: |
167 |
/* mark a given HookFile as run */
|
210
by Michael Vogt
* added a notification on hooks |
168 |
gboolean mark_hook_file_as_run(HookTrayAppletPrivate *priv, HookFile *hf) |
45
by mvo
* added basic "interactive-update-hooks" support |
169 |
{
|
138
by mvo
* src/update.c: |
170 |
if(hf == NULL) |
171 |
return FALSE; |
|
172 |
||
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
173 |
g_debug_hooks("mark_hook_file_as_run: %s",hf->filename); |
124
by mvo
* src/hooks.{c,h}: |
174 |
hf->cmd_run = TRUE; |
175 |
||
45
by mvo
* added basic "interactive-update-hooks" support |
176 |
return TRUE; |
177 |
}
|
|
178 |
||
179 |
||
70
by mvo
* src/rfc822.h: added a comment explaining about the memory use |
180 |
/* get the language code in a static allocated buffer
|
181 |
* short_form: only return the languagecode if true, otherwise
|
|
182 |
* languagecode_countrycode
|
|
183 |
*/
|
|
184 |
char* get_lang_code(gboolean short_form) |
|
185 |
{
|
|
186 |
/* make own private copy */
|
|
187 |
static gchar locale[51]; |
|
188 |
strncpy(locale, setlocale(LC_MESSAGES, NULL), 50); |
|
189 |
||
190 |
// FIXME: we need to be more inteligent here
|
|
191 |
// _and_ we probably want to look into the "LANGUAGE" enviroment too
|
|
192 |
if(short_form) { |
|
193 |
locale[2] = 0; |
|
194 |
return locale; |
|
195 |
} else { |
|
196 |
locale[5] = 0; |
|
197 |
return locale; |
|
198 |
}
|
|
199 |
}
|
|
200 |
||
201 |
/*
|
|
202 |
* get a i18n field of the rfc822 header
|
|
203 |
* Return Value: a pointer that must not be freed (part of the rfc822 struct)
|
|
204 |
*/
|
|
205 |
char *hook_file_lookup_i18n(struct rfc822_header *rfc822, char *field) |
|
206 |
{
|
|
296
by Michael Vogt
* src/hooks.c: |
207 |
gchar *s, *entry, *text; |
208 |
||
209 |
/* first check for langpacks, then i18n fields */
|
|
210 |
entry = rfc822_header_lookup(rfc822, "GettextDomain"); |
|
211 |
if(entry != NULL) { |
|
212 |
text = rfc822_header_lookup(rfc822, field); |
|
213 |
s = dgettext(entry, text); |
|
214 |
if(text != s) |
|
215 |
return s; |
|
216 |
}
|
|
70
by mvo
* src/rfc822.h: added a comment explaining about the memory use |
217 |
|
390
by Michael Vogt
* src/hooks.c: |
218 |
/* try $field-$languagecode_$countrycode.$codeset first */
|
219 |
s = g_strdup_printf("%s-%s.%s", field, get_lang_code(FALSE), nl_langinfo(CODESET)); |
|
220 |
entry = rfc822_header_lookup(rfc822, s); |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
221 |
//g_debug_hooks("Looking for: %s ; found: %s\n",s,entry);
|
390
by Michael Vogt
* src/hooks.c: |
222 |
g_free(s); |
223 |
if(entry != NULL) |
|
224 |
return entry; |
|
225 |
||
226 |
/* try $field-$languagecode_$countrycode (and assume utf-8) */
|
|
70
by mvo
* src/rfc822.h: added a comment explaining about the memory use |
227 |
s = g_strdup_printf("%s-%s", field, get_lang_code(FALSE)); |
228 |
entry = rfc822_header_lookup(rfc822, s); |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
229 |
//g_debug_hooks("Looking for: %s ; found: %s\n",s,entry);
|
70
by mvo
* src/rfc822.h: added a comment explaining about the memory use |
230 |
g_free(s); |
231 |
if(entry != NULL) |
|
232 |
return entry; |
|
233 |
||
390
by Michael Vogt
* src/hooks.c: |
234 |
/* try $field-$languagecode.$codeset next */
|
235 |
s = g_strdup_printf("%s-%s.%s", field, get_lang_code(TRUE), nl_langinfo(CODESET)); |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
236 |
//g_debug_hooks("Looking for: %s ; found: %s\n",s,entry);
|
390
by Michael Vogt
* src/hooks.c: |
237 |
entry = rfc822_header_lookup(rfc822, s); |
238 |
g_free(s); |
|
239 |
if(entry != NULL) |
|
240 |
return entry; |
|
241 |
||
242 |
/* try $field-$languagecode (and assume utf-8 codeset) */
|
|
70
by mvo
* src/rfc822.h: added a comment explaining about the memory use |
243 |
s = g_strdup_printf("%s-%s", field, get_lang_code(TRUE)); |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
244 |
//g_debug_hooks("Looking for: %s ; found: %s\n",s,entry);
|
70
by mvo
* src/rfc822.h: added a comment explaining about the memory use |
245 |
entry = rfc822_header_lookup(rfc822, s); |
246 |
g_free(s); |
|
247 |
if(entry != NULL) |
|
248 |
return entry; |
|
249 |
||
153
by mvo
* configure.in: |
250 |
/* now try translating it with gettext */
|
251 |
entry = rfc822_header_lookup(rfc822, field); |
|
154
by mvo
* src/hooks.c: |
252 |
return entry; |
253 |
}
|
|
254 |
||
255 |
char* hook_description_get_summary(struct rfc822_header *rfc822) |
|
256 |
{
|
|
300
by Michael Vogt
* src/rfc822.c: |
257 |
char *summary = hook_file_lookup_i18n(rfc822, "Name"); |
154
by mvo
* src/hooks.c: |
258 |
return summary; |
259 |
}
|
|
260 |
||
261 |
char* hook_description_get_description(struct rfc822_header *rfc822) |
|
262 |
{
|
|
263 |
char *description = hook_file_lookup_i18n(rfc822, "Description"); |
|
300
by Michael Vogt
* src/rfc822.c: |
264 |
return description; |
70
by mvo
* src/rfc822.h: added a comment explaining about the memory use |
265 |
}
|
266 |
||
267 |
/*
|
|
268 |
* show the given hook file
|
|
269 |
*/
|
|
124
by mvo
* src/hooks.{c,h}: |
270 |
gboolean show_next_hook(TrayApplet *ta, GList *hooks) |
45
by mvo
* added basic "interactive-update-hooks" support |
271 |
{
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
272 |
//g_debug_hooks("show_next_hook()\n");
|
124
by mvo
* src/hooks.{c,h}: |
273 |
|
210
by Michael Vogt
* added a notification on hooks |
274 |
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate *)ta->user_data; |
464.1.7
by seb128
use gtkbuilder for the hooks too |
275 |
GtkBuilder *builder = priv->gtk_builder; |
45
by mvo
* added basic "interactive-update-hooks" support |
276 |
|
464.1.7
by seb128
use gtkbuilder for the hooks too |
277 |
GtkWidget *title = GTK_WIDGET (gtk_builder_get_object(builder, "label_title")); |
317
by Michael Vogt
* implemented new "Title" key in the UpgradeHooks file |
278 |
assert(title); |
464.1.7
by seb128
use gtkbuilder for the hooks too |
279 |
GtkWidget *text = GTK_WIDGET (gtk_builder_get_object(builder, "textview_hook")); |
45
by mvo
* added basic "interactive-update-hooks" support |
280 |
assert(text); |
464.1.7
by seb128
use gtkbuilder for the hooks too |
281 |
GtkWidget *button_next = GTK_WIDGET (gtk_builder_get_object(builder, "button_next")); |
45
by mvo
* added basic "interactive-update-hooks" support |
282 |
assert(button_next); |
464.1.7
by seb128
use gtkbuilder for the hooks too |
283 |
GtkWidget *button_run = GTK_WIDGET (gtk_builder_get_object(builder, "button_run")); |
45
by mvo
* added basic "interactive-update-hooks" support |
284 |
assert(button_run); |
285 |
||
124
by mvo
* src/hooks.{c,h}: |
286 |
// init some vars
|
287 |
HookFile *hf = NULL; |
|
288 |
char *hook_file = NULL; |
|
289 |
||
290 |
// find the next unseen hook
|
|
291 |
GList *elm = g_list_first(hooks); |
|
292 |
for(;elm != NULL; elm = g_list_next(elm)) { |
|
293 |
hf = (HookFile*)elm->data; |
|
294 |
if(hf->seen == FALSE) { |
|
295 |
hook_file = hf->filename; |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
296 |
//g_debug_hooks("next_hook is: %s\n",hook_file);
|
124
by mvo
* src/hooks.{c,h}: |
297 |
break; |
298 |
}
|
|
299 |
}
|
|
300 |
||
301 |
if(hook_file == NULL) { |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
302 |
g_debug_hooks("no unseen hookfile found in hook list of len (%i)", |
162
by mvo
* src/hooks.c: |
303 |
g_list_length(hooks)); |
167
by mvo
* src/hooks.c: |
304 |
return FALSE; |
124
by mvo
* src/hooks.{c,h}: |
305 |
}
|
306 |
||
45
by mvo
* added basic "interactive-update-hooks" support |
307 |
char *filename = g_strdup_printf("%s%s",HOOKS_DIR,hook_file); |
308 |
||
309 |
/* setup the message */
|
|
310 |
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); |
|
311 |
FILE *f = fopen(filename, "r"); |
|
312 |
if(f == NULL) { |
|
191
by mvo
* move a bunch of g_error -> g_warning |
313 |
g_warning("can't open %s", filename); |
45
by mvo
* added basic "interactive-update-hooks" support |
314 |
g_free(filename); |
167
by mvo
* src/hooks.c: |
315 |
return FALSE; |
45
by mvo
* added basic "interactive-update-hooks" support |
316 |
}
|
317 |
struct rfc822_header *rfc822 = rfc822_parse_stanza(f); |
|
318 |
||
319 |
char *cmd = rfc822_header_lookup(rfc822, "Command"); |
|
320 |
char *term = g_strstrip(rfc822_header_lookup(rfc822, "Terminal")); |
|
321 |
g_object_set_data(G_OBJECT(button_run),"cmd", g_strdup(cmd)); |
|
322 |
g_object_set_data(G_OBJECT(button_run),"term", g_strdup(term)); |
|
138
by mvo
* src/update.c: |
323 |
g_object_set_data(G_OBJECT(button_run),"hook_file", hf); |
45
by mvo
* added basic "interactive-update-hooks" support |
324 |
if(cmd != NULL) { |
325 |
gtk_widget_show(button_run); |
|
326 |
} else { |
|
327 |
gtk_widget_hide(button_run); |
|
328 |
}
|
|
317
by Michael Vogt
* implemented new "Title" key in the UpgradeHooks file |
329 |
char *title_str = hook_file_lookup_i18n(rfc822, "Title"); |
330 |
if(title_str != NULL) { |
|
331 |
gchar *s = g_strdup_printf("<span weight=\"bold\" size=\"larger\">%s</span>", title_str); |
|
332 |
gtk_label_set_markup(GTK_LABEL(title), s); |
|
333 |
g_free(s); |
|
334 |
}
|
|
154
by mvo
* src/hooks.c: |
335 |
char *summary = hook_description_get_summary(rfc822); |
336 |
char *descr = hook_description_get_description(rfc822); |
|
383
by Michael Vogt
* src/hooks.c: |
337 |
char *s; |
338 |
if(summary) { |
|
339 |
s = g_strdup_printf("%s\n\n%s\n",gettext(summary), gettext(descr)); |
|
340 |
gtk_text_buffer_set_text(buf, s, -1); |
|
341 |
// set the name to bold
|
|
342 |
GtkTextIter start, end; |
|
343 |
gtk_text_buffer_get_iter_at_offset(buf, &start, 0); |
|
344 |
gtk_text_buffer_get_iter_at_offset(buf, &end, g_utf8_strlen(gettext(summary),-1)); |
|
345 |
gtk_text_buffer_apply_tag_by_name(buf, "bold_tag", &start, &end); |
|
346 |
||
347 |
} else { |
|
348 |
s = g_strdup_printf("%s\n",gettext(descr)); |
|
349 |
gtk_text_buffer_set_text(buf, s, -1); |
|
350 |
}
|
|
351 |
||
352 |
// set button name (if needed)
|
|
353 |
char *b = hook_file_lookup_i18n(rfc822, "ButtonText"); |
|
354 |
if(b) |
|
355 |
gtk_button_set_label(GTK_BUTTON (button_run), b); |
|
356 |
else
|
|
357 |
gtk_button_set_label(GTK_BUTTON (button_run), _("_Run this action now")); |
|
126
by mvo
* debian/changelog,configure.in: |
358 |
|
359 |
// clean up
|
|
45
by mvo
* added basic "interactive-update-hooks" support |
360 |
fclose(f); |
154
by mvo
* src/hooks.c: |
361 |
g_free(filename); |
45
by mvo
* added basic "interactive-update-hooks" support |
362 |
g_free(s); |
363 |
rfc822_header_free_all(rfc822); |
|
364 |
||
365 |
/* mark the current hook file as seen */
|
|
124
by mvo
* src/hooks.{c,h}: |
366 |
g_object_set_data(G_OBJECT(button_next), "HookFile", hf); |
367 |
||
368 |
return TRUE; |
|
45
by mvo
* added basic "interactive-update-hooks" support |
369 |
}
|
370 |
||
371 |
||
464.1.7
by seb128
use gtkbuilder for the hooks too |
372 |
void on_button_run_clicked(GtkWidget *self, gpointer *data) |
45
by mvo
* added basic "interactive-update-hooks" support |
373 |
{
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
374 |
//g_debug_hooks("cb_button_run()\n");
|
138
by mvo
* src/update.c: |
375 |
gchar *cmdline; |
45
by mvo
* added basic "interactive-update-hooks" support |
376 |
|
377 |
TrayApplet *ta = (TrayApplet *)data; |
|
210
by Michael Vogt
* added a notification on hooks |
378 |
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate *)ta->user_data; |
45
by mvo
* added basic "interactive-update-hooks" support |
379 |
|
380 |
/* mark the current hook file as run */
|
|
138
by mvo
* src/update.c: |
381 |
HookFile *hf = g_object_get_data(G_OBJECT(self), "hook_file"); |
210
by Michael Vogt
* added a notification on hooks |
382 |
mark_hook_file_as_run(priv, hf); |
45
by mvo
* added basic "interactive-update-hooks" support |
383 |
|
384 |
gchar *cmd = g_object_get_data(G_OBJECT(self), "cmd"); |
|
385 |
gchar *term = g_object_get_data(G_OBJECT(self), "term"); |
|
386 |
||
387 |
if(cmd == NULL) { |
|
388 |
g_warning("cmd is NULL\n"); |
|
389 |
return; |
|
390 |
}
|
|
391 |
||
392 |
if(term != NULL && !g_ascii_strncasecmp(term, "true",-1)) { |
|
138
by mvo
* src/update.c: |
393 |
cmdline = g_strdup_printf("gnome-terminal -e %s",cmd); |
394 |
} else |
|
395 |
cmdline = g_strdup(cmd); |
|
396 |
||
397 |
g_spawn_command_line_async(cmdline, NULL); |
|
398 |
g_free(cmdline); |
|
45
by mvo
* added basic "interactive-update-hooks" support |
399 |
}
|
400 |
||
464.1.7
by seb128
use gtkbuilder for the hooks too |
401 |
void on_button_next_clicked(GtkWidget *self, gpointer *data) |
45
by mvo
* added basic "interactive-update-hooks" support |
402 |
{
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
403 |
g_debug_hooks("cb_button_next()"); |
45
by mvo
* added basic "interactive-update-hooks" support |
404 |
TrayApplet *ta = (TrayApplet *)data; |
210
by Michael Vogt
* added a notification on hooks |
405 |
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate *)ta->user_data; |
45
by mvo
* added basic "interactive-update-hooks" support |
406 |
|
124
by mvo
* src/hooks.{c,h}: |
407 |
HookFile *hf; |
408 |
hf = (HookFile*)g_object_get_data(G_OBJECT(self),"HookFile"); |
|
409 |
if(hf == NULL) { |
|
410 |
g_warning("button_next called without HookFile\n"); |
|
411 |
return; |
|
412 |
}
|
|
413 |
||
414 |
// mark as seen
|
|
210
by Michael Vogt
* added a notification on hooks |
415 |
hook_file_mark_as_seen(priv, hf); |
124
by mvo
* src/hooks.{c,h}: |
416 |
check_update_hooks(ta); |
417 |
||
210
by Michael Vogt
* added a notification on hooks |
418 |
if(priv->hook_files != NULL) |
419 |
show_next_hook(ta, priv->hook_files); |
|
45
by mvo
* added basic "interactive-update-hooks" support |
420 |
}
|
421 |
||
434
by Michael Vogt
make the interactive upgrade hooks dialog open up immediately |
422 |
void show_hooks(TrayApplet *ta, gboolean focus_on_map) |
45
by mvo
* added basic "interactive-update-hooks" support |
423 |
{
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
424 |
g_debug_hooks("show_hooks()"); |
210
by Michael Vogt
* added a notification on hooks |
425 |
HookTrayAppletPrivate* priv = (HookTrayAppletPrivate *)ta->user_data; |
45
by mvo
* added basic "interactive-update-hooks" support |
426 |
|
464.1.7
by seb128
use gtkbuilder for the hooks too |
427 |
GtkBuilder *builder = priv->gtk_builder; |
428 |
GtkWidget *dia = GTK_WIDGET (gtk_builder_get_object(builder, "dialog_hooks")); |
|
434
by Michael Vogt
make the interactive upgrade hooks dialog open up immediately |
429 |
gtk_window_set_title(GTK_WINDOW(dia), _("Information available")); |
45
by mvo
* added basic "interactive-update-hooks" support |
430 |
assert(dia); |
464.1.7
by seb128
use gtkbuilder for the hooks too |
431 |
GtkWidget *button_run = GTK_WIDGET (gtk_builder_get_object(builder, "button_run")); |
45
by mvo
* added basic "interactive-update-hooks" support |
432 |
assert(button_run); |
464.1.7
by seb128
use gtkbuilder for the hooks too |
433 |
GtkWidget *button_next = GTK_WIDGET (gtk_builder_get_object(builder, "button_next")); |
124
by mvo
* src/hooks.{c,h}: |
434 |
assert(button_next); |
435 |
||
434
by Michael Vogt
make the interactive upgrade hooks dialog open up immediately |
436 |
gtk_window_set_focus_on_map(GTK_WINDOW(dia), focus_on_map); |
437 |
||
167
by mvo
* src/hooks.c: |
438 |
// if show_next_hook() fails for some reason don't do anything
|
210
by Michael Vogt
* added a notification on hooks |
439 |
if(!show_next_hook(ta, priv->hook_files)) |
167
by mvo
* src/hooks.c: |
440 |
return; |
124
by mvo
* src/hooks.{c,h}: |
441 |
|
45
by mvo
* added basic "interactive-update-hooks" support |
442 |
int res = gtk_dialog_run(GTK_DIALOG(dia)); |
443 |
if(res == GTK_RESPONSE_CLOSE) { |
|
124
by mvo
* src/hooks.{c,h}: |
444 |
// mark the currently current hookfile as seen
|
445 |
HookFile *hf; |
|
446 |
hf = (HookFile*)g_object_get_data(G_OBJECT(button_next),"HookFile"); |
|
447 |
if(hf == NULL) { |
|
448 |
g_warning("show_hooks called without HookFile\n"); |
|
449 |
return; |
|
450 |
}
|
|
451 |
||
452 |
// mark as seen
|
|
210
by Michael Vogt
* added a notification on hooks |
453 |
hook_file_mark_as_seen(priv, hf); |
124
by mvo
* src/hooks.{c,h}: |
454 |
check_update_hooks(ta); |
45
by mvo
* added basic "interactive-update-hooks" support |
455 |
}
|
124
by mvo
* src/hooks.{c,h}: |
456 |
|
45
by mvo
* added basic "interactive-update-hooks" support |
457 |
gtk_widget_hide(dia); |
124
by mvo
* src/hooks.{c,h}: |
458 |
}
|
45
by mvo
* added basic "interactive-update-hooks" support |
459 |
|
124
by mvo
* src/hooks.{c,h}: |
460 |
static gboolean |
461 |
button_release_cb (GtkWidget *widget, |
|
462 |
TrayApplet *ta) |
|
463 |
{
|
|
210
by Michael Vogt
* added a notification on hooks |
464 |
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate*)ta->user_data; |
465 |
||
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
466 |
if(priv->active_notification != NULL) { |
467 |
notify_notification_close(priv->active_notification, NULL); |
|
468 |
priv->active_notification = NULL; |
|
469 |
}
|
|
470 |
||
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
471 |
//g_debug_hooks("left click on hook applet\n");
|
434
by Michael Vogt
make the interactive upgrade hooks dialog open up immediately |
472 |
show_hooks(ta, TRUE); |
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
473 |
return TRUE; |
45
by mvo
* added basic "interactive-update-hooks" support |
474 |
}
|
475 |
||
138
by mvo
* src/update.c: |
476 |
gboolean is_hook_relevant(const gchar *hook_file) |
477 |
{
|
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
478 |
g_debug_hooks("is_hook_relevant(): %s", hook_file); |
138
by mvo
* src/update.c: |
479 |
gboolean res = TRUE; |
480 |
||
481 |
char *filename = g_strdup_printf("%s%s",HOOKS_DIR,hook_file); |
|
482 |
FILE *f = fopen(filename, "r"); |
|
483 |
if(f == NULL) { |
|
484 |
// can't open, can't be relevant
|
|
485 |
return FALSE; |
|
486 |
}
|
|
487 |
struct rfc822_header *rfc822 = rfc822_parse_stanza(f); |
|
488 |
||
388
by Michael Vogt
* src/hooks.c: |
489 |
// check if its a note that is relevant only for admin users
|
490 |
// (this is the default)
|
|
491 |
gchar *b = rfc822_header_lookup(rfc822, "OnlyAdminUsers"); |
|
492 |
if(b == NULL || g_ascii_strncasecmp(b, "true",-1) == 0) { |
|
493 |
if (!in_admin_group()) |
|
494 |
return FALSE; |
|
495 |
}
|
|
496 |
||
138
by mvo
* src/update.c: |
497 |
// check the DontShowAfterReboot flag
|
388
by Michael Vogt
* src/hooks.c: |
498 |
b = rfc822_header_lookup(rfc822, "DontShowAfterReboot"); |
138
by mvo
* src/update.c: |
499 |
if(b != NULL && g_ascii_strncasecmp(b, "true",-1) == 0) { |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
500 |
g_debug_hooks("found DontShowAfterReboot"); |
138
by mvo
* src/update.c: |
501 |
|
502 |
// read the uptime information
|
|
503 |
double uptime=0, idle=0; |
|
504 |
char buf[1024]; |
|
151
by mvo
* src/hooks.c: |
505 |
int fd = open("/proc/uptime", 0); |
138
by mvo
* src/update.c: |
506 |
int local_n = read(fd, buf, sizeof(buf)-1); |
507 |
buf[local_n] = '\0'; |
|
508 |
char *savelocale = setlocale(LC_NUMERIC, NULL); |
|
509 |
setlocale(LC_NUMERIC,"C"); |
|
510 |
sscanf(buf, "%lf %lf", &uptime,&idle); |
|
511 |
close(fd); |
|
512 |
setlocale(LC_NUMERIC,savelocale); |
|
513 |
||
164
by mvo
* src/hooks.c: |
514 |
time_t mtime = hook_file_time(hook_file); |
138
by mvo
* src/update.c: |
515 |
time_t now = time(NULL); |
516 |
||
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
517 |
g_debug_hooks("now: %li mtime: %li uptime: %f",now,mtime,uptime); |
518 |
g_debug_hooks("diff: %li uptime: %f",now-mtime,uptime); |
|
138
by mvo
* src/update.c: |
519 |
if((int)uptime > 0 && (now - mtime) > (int)uptime) { |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
520 |
g_debug_hooks("not relevant because of reboot: %s",hook_file); |
138
by mvo
* src/update.c: |
521 |
res = FALSE; |
211
by Michael Vogt
* added debugging support via --debug-hooks |
522 |
} else |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
523 |
g_debug_hooks("hook is relevant"); |
138
by mvo
* src/update.c: |
524 |
}
|
525 |
fclose(f); |
|
144
by mvo
* debian/control: |
526 |
|
297
by Michael Vogt
* src/hooks.c: |
527 |
// check for DisplayIf test
|
528 |
b = rfc822_header_lookup(rfc822, "DisplayIf"); |
|
529 |
if(b != NULL) { |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
530 |
g_debug_hooks("found DisplayIf command: '%s'", b); |
297
by Michael Vogt
* src/hooks.c: |
531 |
int exitc = system(b); |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
532 |
g_debug_hooks("'%s' returned: %i", b, exitc); |
300
by Michael Vogt
* src/rfc822.c: |
533 |
res = (exitc == 0); |
297
by Michael Vogt
* src/hooks.c: |
534 |
}
|
144
by mvo
* debian/control: |
535 |
|
138
by mvo
* src/update.c: |
536 |
g_free(filename); |
537 |
rfc822_header_free_all(rfc822); |
|
538 |
return res; |
|
539 |
}
|
|
48
by mvo
* various fixes |
540 |
|
215
by Michael Vogt
* now the notification for a hook with a delay |
541 |
static gboolean show_notification(void *data) |
542 |
{
|
|
543 |
TrayApplet *ta = (TrayApplet*)data; |
|
544 |
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate*)ta->user_data; |
|
545 |
||
365
by Michael Vogt
* src/update.c, src/crash.c, src/hooks.c: |
546 |
if(!gtk_status_icon_get_visible(ta->tray_icon)) |
547 |
return FALSE; |
|
548 |
||
464.1.7
by seb128
use gtkbuilder for the hooks too |
549 |
GtkWidget *d = GTK_WIDGET (gtk_builder_get_object(priv->gtk_builder,"dialog_hooks")); |
595.1.1
by Michael Terry
* Add --disable-deprecations configure flag to test for deprecated API use |
550 |
if((d && gtk_widget_get_visible(d)) || priv->active_notification != NULL) |
340
by Michael Vogt
* code cleanups |
551 |
return FALSE; |
215
by Michael Vogt
* now the notification for a hook with a delay |
552 |
|
333
by Michael Vogt
* fix leftover from pre-GtkStatusIcon code (LP: #127965) |
553 |
GdkRectangle area; |
554 |
gtk_status_icon_get_geometry(ta->tray_icon, NULL, &area, NULL); |
|
555 |
// no usefull coordiante yet, do another timeout
|
|
556 |
if(area.x <= 0 || area.y <= 0 || area.width <= 0 || area.height <= 0) |
|
557 |
return TRUE; |
|
558 |
||
215
by Michael Vogt
* now the notification for a hook with a delay |
559 |
NotifyNotification *n; |
560 |
GdkPixbuf* pix; |
|
334
by Michael Vogt
* fix crash in leftover from pre-GtkStatusIcon code (LP: #127965) |
561 |
n = notify_notification_new_with_status_icon( |
562 |
_("Information available"), |
|
207.1.4
by Sebastian Heinlein
* Wording fixes |
563 |
_("Click on the notification icon" |
564 |
" to show the available information.\n"), |
|
215
by Michael Vogt
* now the notification for a hook with a delay |
565 |
NULL, |
334
by Michael Vogt
* fix crash in leftover from pre-GtkStatusIcon code (LP: #127965) |
566 |
ta->tray_icon); |
215
by Michael Vogt
* now the notification for a hook with a delay |
567 |
|
568 |
pix = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), |
|
569 |
GTK_STOCK_DIALOG_INFO, 48,0,NULL); |
|
570 |
notify_notification_set_icon_from_pixbuf (n, pix); |
|
571 |
g_object_unref(pix); |
|
572 |
notify_notification_set_timeout (n, 60*1000); |
|
573 |
notify_notification_show(n, NULL); |
|
574 |
priv->active_notification = n; |
|
317
by Michael Vogt
* implemented new "Title" key in the UpgradeHooks file |
575 |
|
215
by Michael Vogt
* now the notification for a hook with a delay |
576 |
return FALSE; |
577 |
}
|
|
578 |
||
45
by mvo
* added basic "interactive-update-hooks" support |
579 |
gboolean check_update_hooks(TrayApplet *ta) |
580 |
{
|
|
340
by Michael Vogt
* code cleanups |
581 |
GList *elm; |
582 |
HookFile *hf; |
|
45
by mvo
* added basic "interactive-update-hooks" support |
583 |
GDir* dir; |
584 |
const gchar *hook_file; |
|
585 |
||
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
586 |
g_debug_hooks("check_update_hooks()"); |
340
by Michael Vogt
* code cleanups |
587 |
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate*)ta->user_data; |
588 |
||
45
by mvo
* added basic "interactive-update-hooks" support |
589 |
dir=g_dir_open(HOOKS_DIR, 0, NULL); |
254
by Michael Vogt
* src/crash.c, src/hooks.c: |
590 |
if(dir == NULL) { |
191
by mvo
* move a bunch of g_error -> g_warning |
591 |
g_warning("can't read %s directory\n",HOOKS_DIR); |
254
by Michael Vogt
* src/crash.c, src/hooks.c: |
592 |
return FALSE; |
593 |
}
|
|
45
by mvo
* added basic "interactive-update-hooks" support |
594 |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
595 |
g_debug_hooks("reading '%s' dir", HOOKS_DIR); |
138
by mvo
* src/update.c: |
596 |
int unseen_count = 0; |
45
by mvo
* added basic "interactive-update-hooks" support |
597 |
while((hook_file=g_dir_read_name(dir)) != NULL) { |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
598 |
g_debug_hooks("investigating file '%s' ", hook_file); |
138
by mvo
* src/update.c: |
599 |
|
600 |
// check if the hook still applies (for e.g. DontShowAfterReboot)
|
|
211
by Michael Vogt
* added debugging support via --debug-hooks |
601 |
if(!is_hook_relevant(hook_file)) { |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
602 |
g_debug_hooks("not relevant: '%s'",hook_file); |
138
by mvo
* src/update.c: |
603 |
continue; |
211
by Michael Vogt
* added debugging support via --debug-hooks |
604 |
}
|
124
by mvo
* src/hooks.{c,h}: |
605 |
// see if we already know about this hook filename
|
340
by Michael Vogt
* code cleanups |
606 |
elm = g_list_find_custom(priv->hook_files,hook_file, |
124
by mvo
* src/hooks.{c,h}: |
607 |
compare_hook_func); |
163
by mvo
* src/hooks.c: |
608 |
|
124
by mvo
* src/hooks.{c,h}: |
609 |
// not seen before, add to the list
|
610 |
if(elm == NULL) { |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
611 |
g_debug_hooks("never seen before: %s",hook_file); |
124
by mvo
* src/hooks.{c,h}: |
612 |
HookFile *t = g_new0(HookFile, 1); |
613 |
t->filename = strdup(hook_file); |
|
164
by mvo
* src/hooks.c: |
614 |
t->mtime = hook_file_time(hook_file); |
144
by mvo
* debian/control: |
615 |
hook_file_md5(hook_file, t->md5); |
124
by mvo
* src/hooks.{c,h}: |
616 |
t->cmd_run = FALSE; |
617 |
t->seen = FALSE; |
|
340
by Michael Vogt
* code cleanups |
618 |
priv->hook_files = g_list_append(priv->hook_files, (gpointer)t); |
163
by mvo
* src/hooks.c: |
619 |
// init elm with the just added record (will be needed below)
|
210
by Michael Vogt
* added a notification on hooks |
620 |
elm = g_list_find_custom(priv->hook_files,hook_file, |
144
by mvo
* debian/control: |
621 |
compare_hook_func); |
622 |
assert(elm != NULL); |
|
124
by mvo
* src/hooks.{c,h}: |
623 |
}
|
624 |
||
163
by mvo
* src/hooks.c: |
625 |
// this is the hook file information we have (either because it was
|
626 |
// availabe already or because we added it)
|
|
340
by Michael Vogt
* code cleanups |
627 |
hf = (HookFile*)elm->data; |
125
by mvo
* src/hooks.c: |
628 |
|
163
by mvo
* src/hooks.c: |
629 |
// file has changed since we last saw it
|
164
by mvo
* src/hooks.c: |
630 |
time_t new_mtime = hook_file_time(hook_file); |
163
by mvo
* src/hooks.c: |
631 |
if(new_mtime > hf->mtime) { |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
632 |
g_debug_hooks("newer mtime: %s (%li > %li))",hook_file, new_mtime, hf->mtime); |
163
by mvo
* src/hooks.c: |
633 |
hf->seen = FALSE; |
634 |
}
|
|
635 |
||
636 |
// we have not seen it yet (because e.g. it was just added)
|
|
125
by mvo
* src/hooks.c: |
637 |
if(hf->seen == FALSE) { |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
638 |
g_debug_hooks("the file '%s' was NOT SEEN yet",hook_file); |
144
by mvo
* debian/control: |
639 |
|
162
by mvo
* src/hooks.c: |
640 |
// update mtime (because we haven't seen the old one and there
|
641 |
// is a new one now)
|
|
163
by mvo
* src/hooks.c: |
642 |
hf->mtime = new_mtime; |
162
by mvo
* src/hooks.c: |
643 |
|
144
by mvo
* debian/control: |
644 |
// check if there is already another notification that is
|
645 |
// a) not this one
|
|
646 |
// b) not seen yet
|
|
647 |
// c) the same
|
|
648 |
// if so, we don't increase the unseen count as all identical
|
|
649 |
// ones will maked as unseen at onces
|
|
650 |
gboolean md5match = FALSE; |
|
210
by Michael Vogt
* added a notification on hooks |
651 |
GList *x = g_list_first(priv->hook_files); |
144
by mvo
* debian/control: |
652 |
while(x!=NULL) { |
653 |
HookFile *e = (HookFile*)x->data; |
|
654 |
if((elm != x) && |
|
655 |
(e->seen == FALSE) && |
|
400
by Michael Vogt
* src/hooks.c: |
656 |
(memcmp(hf->md5,e->md5,DIGEST_SIZE)==0) ) |
144
by mvo
* debian/control: |
657 |
{
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
658 |
g_debug_hooks("%s (%s) was seen also in %s (%s)\n", |
162
by mvo
* src/hooks.c: |
659 |
hf->filename, hf->md5, e->filename, e->md5); |
144
by mvo
* debian/control: |
660 |
md5match = TRUE; |
661 |
}
|
|
662 |
x = g_list_next(x); |
|
663 |
}
|
|
664 |
if(!md5match) { |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
665 |
g_debug_hooks("%s increases unseen_count\n",hf->filename); |
144
by mvo
* debian/control: |
666 |
unseen_count++; |
667 |
}
|
|
211
by Michael Vogt
* added debugging support via --debug-hooks |
668 |
} else |
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
669 |
g_debug_hooks("already seen: '%s'",hook_file); |
45
by mvo
* added basic "interactive-update-hooks" support |
670 |
}
|
671 |
g_dir_close(dir); |
|
672 |
||
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
673 |
//g_debug_hooks("hooks: %i (new: %i)", g_list_length(hook_files), unseen_count);
|
45
by mvo
* added basic "interactive-update-hooks" support |
674 |
|
464.1.7
by seb128
use gtkbuilder for the hooks too |
675 |
GtkBuilder *builder = priv->gtk_builder; |
676 |
GtkWidget *button_next = GTK_WIDGET (gtk_builder_get_object(builder, "button_next")); |
|
124
by mvo
* src/hooks.{c,h}: |
677 |
assert(button_next); |
45
by mvo
* added basic "interactive-update-hooks" support |
678 |
|
434
by Michael Vogt
make the interactive upgrade hooks dialog open up immediately |
679 |
// check if we do a notification or a dialog
|
680 |
GConfClient *gconf = gconf_client_get_default(); |
|
681 |
if(gconf_client_get_bool(gconf, GCONF_KEY_AUTO_LAUNCH, NULL)) { |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
682 |
g_debug_hooks("showing hooks with focus on map == FALSE"); |
434
by Michael Vogt
make the interactive upgrade hooks dialog open up immediately |
683 |
if (unseen_count < 2) |
684 |
gtk_widget_hide(button_next); |
|
685 |
else
|
|
686 |
gtk_widget_show(button_next); |
|
687 |
show_hooks(ta, FALSE); |
|
688 |
return TRUE; |
|
689 |
}
|
|
690 |
||
691 |
// no dialog, do the notification
|
|
692 |
if((unseen_count > 0) && !gtk_status_icon_get_visible (ta->tray_icon)) |
|
215
by Michael Vogt
* now the notification for a hook with a delay |
693 |
g_timeout_add(5000, show_notification, ta); |
210
by Michael Vogt
* added a notification on hooks |
694 |
|
138
by mvo
* src/update.c: |
695 |
switch(unseen_count) { |
125
by mvo
* src/hooks.c: |
696 |
case 0: |
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
697 |
gtk_status_icon_set_visible (ta->tray_icon, FALSE); |
45
by mvo
* added basic "interactive-update-hooks" support |
698 |
gtk_widget_hide(button_next); |
125
by mvo
* src/hooks.c: |
699 |
break; |
700 |
case 1: |
|
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
701 |
gtk_status_icon_set_visible (ta->tray_icon, TRUE); |
125
by mvo
* src/hooks.c: |
702 |
gtk_widget_hide(button_next); |
703 |
break; |
|
704 |
default: |
|
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
705 |
gtk_status_icon_set_visible (ta->tray_icon, TRUE); |
45
by mvo
* added basic "interactive-update-hooks" support |
706 |
gtk_widget_show(button_next); |
125
by mvo
* src/hooks.c: |
707 |
break; |
45
by mvo
* added basic "interactive-update-hooks" support |
708 |
}
|
138
by mvo
* src/update.c: |
709 |
hooks_trayicon_update_tooltip (ta, unseen_count); |
45
by mvo
* added basic "interactive-update-hooks" support |
710 |
|
711 |
return TRUE; |
|
712 |
}
|
|
713 |
||
210
by Michael Vogt
* added a notification on hooks |
714 |
void hook_read_seen_file(HookTrayAppletPrivate *priv, const char* filename) |
45
by mvo
* added basic "interactive-update-hooks" support |
715 |
{
|
340
by Michael Vogt
* code cleanups |
716 |
HookFile *t; |
45
by mvo
* added basic "interactive-update-hooks" support |
717 |
char buf[512]; |
718 |
int time, was_run; |
|
719 |
FILE *f = fopen(filename, "r"); |
|
720 |
if(f==NULL) |
|
161
by mvo
* src/hooks.c: |
721 |
return; |
128
by mvo
* debian/dirs: |
722 |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
723 |
g_debug_hooks("reading hook_file: %s ", filename); |
128
by mvo
* debian/dirs: |
724 |
|
45
by mvo
* added basic "interactive-update-hooks" support |
725 |
while(fscanf(f, "%s %i %i",buf,&time,&was_run) == 3) { |
129
by mvo
* src/hooks.c: |
726 |
|
167
by mvo
* src/hooks.c: |
727 |
// first check if the file actually exists, if not skip it
|
728 |
// (may already be delete when e.g. a package was removed)
|
|
729 |
char *filename = g_strdup_printf("%s%s",HOOKS_DIR,buf); |
|
730 |
gboolean res = g_file_test(filename, G_FILE_TEST_EXISTS); |
|
731 |
g_free(filename); |
|
732 |
if(!res) |
|
733 |
continue; |
|
734 |
||
129
by mvo
* src/hooks.c: |
735 |
// now check if we already have that filename in the list
|
210
by Michael Vogt
* added a notification on hooks |
736 |
GList *elm = g_list_find_custom(priv->hook_files,buf, |
129
by mvo
* src/hooks.c: |
737 |
compare_hook_func); |
738 |
if(elm != NULL) { |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
739 |
g_debug_hooks("hookfile: %s already in the list", buf); |
161
by mvo
* src/hooks.c: |
740 |
|
741 |
// we have that file already in the list with a newer mtime,
|
|
742 |
// than the file in the config file. ignore the config file
|
|
129
by mvo
* src/hooks.c: |
743 |
HookFile *exisiting = (HookFile *)elm->data; |
744 |
// and it's more current
|
|
745 |
if(exisiting->mtime > time) { |
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
746 |
g_debug_hooks("existing is newer, ignoring the read one\n"); |
129
by mvo
* src/hooks.c: |
747 |
continue; |
748 |
}
|
|
749 |
||
161
by mvo
* src/hooks.c: |
750 |
// we have it in the list, but the the file in the list is older
|
167
by mvo
* src/hooks.c: |
751 |
// than the one in the config file. use this config-file instead
|
752 |
// and update the values in the list
|
|
161
by mvo
* src/hooks.c: |
753 |
exisiting->cmd_run = was_run; |
167
by mvo
* src/hooks.c: |
754 |
exisiting->seen = TRUE; |
161
by mvo
* src/hooks.c: |
755 |
exisiting->mtime = time; |
162
by mvo
* src/hooks.c: |
756 |
hook_file_md5(exisiting->filename,exisiting->md5); |
757 |
||
161
by mvo
* src/hooks.c: |
758 |
} else { |
167
by mvo
* src/hooks.c: |
759 |
// not in the list yet
|
161
by mvo
* src/hooks.c: |
760 |
// add the just read hook file to the list
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
761 |
g_debug_hooks("got: %s %i %i ",buf,time,was_run); |
340
by Michael Vogt
* code cleanups |
762 |
t = g_new0(HookFile, 1); |
161
by mvo
* src/hooks.c: |
763 |
t->filename = strdup(buf); |
764 |
t->mtime = time; |
|
765 |
t->cmd_run = was_run; |
|
766 |
t->seen = TRUE; |
|
162
by mvo
* src/hooks.c: |
767 |
hook_file_md5(t->filename,t->md5); |
768 |
||
340
by Michael Vogt
* code cleanups |
769 |
priv->hook_files = g_list_append(priv->hook_files, (gpointer)t); |
129
by mvo
* src/hooks.c: |
770 |
}
|
45
by mvo
* added basic "interactive-update-hooks" support |
771 |
}
|
128
by mvo
* debian/dirs: |
772 |
fclose(f); |
773 |
}
|
|
774 |
||
434
by Michael Vogt
make the interactive upgrade hooks dialog open up immediately |
775 |
gboolean
|
776 |
init_already_seen_hooks(TrayApplet *ta) |
|
128
by mvo
* debian/dirs: |
777 |
{
|
452
by Michael Vogt
rework the debug options and support --debug-inotify, |
778 |
g_debug_hooks("init_already_seen_hooks"); |
129
by mvo
* src/hooks.c: |
779 |
|
210
by Michael Vogt
* added a notification on hooks |
780 |
HookTrayAppletPrivate* priv = (HookTrayAppletPrivate*)ta->user_data; |
590
by Michael Vogt
* updated to use xdg config dirs |
781 |
char *filename, *old_filename; |
128
by mvo
* debian/dirs: |
782 |
|
145
by mvo
* updated hungarian translation |
783 |
// init with default value
|
210
by Michael Vogt
* added a notification on hooks |
784 |
priv->hook_files = NULL; |
128
by mvo
* debian/dirs: |
785 |
|
786 |
// read global hook file
|
|
590
by Michael Vogt
* updated to use xdg config dirs |
787 |
hook_read_seen_file(priv, GLOBAL_HOOKS_SEEN); |
129
by mvo
* src/hooks.c: |
788 |
|
590
by Michael Vogt
* updated to use xdg config dirs |
789 |
filename = g_strdup_printf("%s/%s", |
790 |
g_get_user_config_dir(), |
|
791 |
HOOKS_SEEN); |
|
792 |
// compat with the previous version
|
|
793 |
old_filename = g_strdup_printf("%s/%s", |
|
794 |
g_get_home_dir(), |
|
591
by Michael Vogt
apply xdg patches by Sebastian Geiger, many thanks |
795 |
HOOKS_SEEN_DEPRECATED); |
590
by Michael Vogt
* updated to use xdg config dirs |
796 |
if (g_file_test(old_filename, G_FILE_TEST_IS_REGULAR)) { |
797 |
g_rename(old_filename, filename); |
|
798 |
}
|
|
128
by mvo
* debian/dirs: |
799 |
// read user hook file
|
210
by Michael Vogt
* added a notification on hooks |
800 |
hook_read_seen_file(priv,filename); |
45
by mvo
* added basic "interactive-update-hooks" support |
801 |
g_free(filename); |
128
by mvo
* debian/dirs: |
802 |
|
45
by mvo
* added basic "interactive-update-hooks" support |
803 |
return TRUE; |
804 |
}
|
|
805 |
||
271
by Michael Vogt
* src/hooks.c: |
806 |
static void |
807 |
on_insert_text(GtkTextBuffer *buffer, |
|
808 |
GtkTextIter *iter_end, |
|
809 |
gchar *text, |
|
810 |
gint arg3, |
|
811 |
gpointer user_data) |
|
812 |
{
|
|
340
by Michael Vogt
* code cleanups |
813 |
GtkTextIter iter, match_start, match_end, match_tmp; |
271
by Michael Vogt
* src/hooks.c: |
814 |
|
815 |
// get where we start
|
|
816 |
gtk_text_buffer_get_iter_at_offset(buffer, &iter, |
|
817 |
gtk_text_iter_get_offset(iter_end) - g_utf8_strlen(text,-1)); |
|
818 |
// search for http:// uris
|
|
819 |
while(gtk_text_iter_forward_search(&iter, |
|
820 |
"http://", GTK_TEXT_SEARCH_VISIBLE_ONLY, |
|
821 |
&match_start, &match_end, iter_end)) { |
|
822 |
match_tmp = match_end; |
|
823 |
// we found a uri, iterate it until the end is found
|
|
824 |
while(gtk_text_iter_forward_char(&match_tmp)) { |
|
825 |
gchar *s = gtk_text_iter_get_text(&match_end,&match_tmp); |
|
826 |
if(strlen(s) < 1) |
|
827 |
break; |
|
828 |
char c = s[strlen(s)-1]; |
|
829 |
if(c == ' ' || c == ')' || c == ']' || c == '\n' || c == '\t' || c == '>') |
|
830 |
break; |
|
831 |
match_end = match_tmp; |
|
832 |
}
|
|
833 |
gchar *url = gtk_text_iter_get_text(&match_start, &match_end); |
|
834 |
//g_print("url: '%s'\n",url);
|
|
835 |
GtkTextTag *tag; |
|
836 |
tag = gtk_text_buffer_create_tag(buffer, NULL, |
|
837 |
"foreground","blue", |
|
838 |
"underline", PANGO_UNDERLINE_SINGLE, |
|
839 |
NULL); |
|
840 |
g_object_set_data(G_OBJECT(tag), "url", url); |
|
841 |
gtk_text_buffer_apply_tag(buffer, tag, &match_start, &match_end); |
|
842 |
iter = match_end; |
|
843 |
}
|
|
844 |
}
|
|
845 |
||
846 |
static void |
|
847 |
on_event_after(GtkWidget *widget, |
|
848 |
GdkEventButton *event, |
|
849 |
gpointer user_data) |
|
850 |
{
|
|
851 |
if(event->type != GDK_BUTTON_RELEASE) |
|
852 |
return; |
|
853 |
if(event->button != 1) |
|
854 |
return; |
|
855 |
gint x,y; |
|
856 |
gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget), |
|
857 |
GTK_TEXT_WINDOW_WIDGET, |
|
858 |
event->x, event->y, |
|
859 |
&x, &y); |
|
860 |
GtkTextIter iter; |
|
861 |
gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, x, y); |
|
862 |
GSList *tags = gtk_text_iter_get_tags(&iter); |
|
863 |
for( ; tags != NULL ; tags = tags->next) { |
|
864 |
gchar *url = g_object_get_data(G_OBJECT(tags->data), "url"); |
|
865 |
if(url != NULL) { |
|
866 |
//g_print("click: '%s'\n",url);
|
|
867 |
char *argv[] = { "/usr/bin/gnome-open", url, NULL }; |
|
868 |
g_spawn_async(NULL, argv, NULL, 0, NULL, NULL, NULL, NULL); |
|
869 |
break; |
|
870 |
}
|
|
871 |
}
|
|
872 |
}
|
|
45
by mvo
* added basic "interactive-update-hooks" support |
873 |
|
874 |
void hook_tray_icon_init(TrayApplet *ta) |
|
875 |
{
|
|
464.1.7
by seb128
use gtkbuilder for the hooks too |
876 |
GError* error = NULL; |
877 |
GtkBuilder* builder = gtk_builder_new (); |
|
878 |
||
210
by Michael Vogt
* added a notification on hooks |
879 |
HookTrayAppletPrivate *priv = g_new0(HookTrayAppletPrivate, 1); |
880 |
ta->user_data = priv; |
|
464.1.7
by seb128
use gtkbuilder for the hooks too |
881 |
|
882 |
if (!gtk_builder_add_from_file (builder, UIDIR"hooks-dialog.ui", &error)) { |
|
476
by Michael Vogt
fix -Wall errors |
883 |
g_warning ("Couldn't load builder file: %s", error->message); |
884 |
g_error_free (error); |
|
464.1.7
by seb128
use gtkbuilder for the hooks too |
885 |
}
|
886 |
||
887 |
assert(builder); |
|
888 |
priv->gtk_builder = builder; |
|
889 |
gtk_builder_connect_signals (builder, (gpointer)ta); |
|
45
by mvo
* added basic "interactive-update-hooks" support |
890 |
|
891 |
/* show dialog on click */
|
|
892 |
g_signal_connect (G_OBJECT(ta->tray_icon), |
|
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
893 |
"activate", |
45
by mvo
* added basic "interactive-update-hooks" support |
894 |
G_CALLBACK (button_release_cb), |
895 |
ta); |
|
896 |
||
126
by mvo
* debian/changelog,configure.in: |
897 |
// create a bold tag
|
464.1.7
by seb128
use gtkbuilder for the hooks too |
898 |
GtkWidget *text = GTK_WIDGET (gtk_builder_get_object(builder, "textview_hook")); |
126
by mvo
* debian/changelog,configure.in: |
899 |
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); |
900 |
gtk_text_buffer_create_tag (buf, "bold_tag", |
|
901 |
"scale", PANGO_SCALE_LARGE, |
|
902 |
"weight", PANGO_WEIGHT_BOLD, |
|
903 |
NULL); |
|
271
by Michael Vogt
* src/hooks.c: |
904 |
g_signal_connect_after(G_OBJECT(buf), "insert-text", |
905 |
G_CALLBACK(on_insert_text), NULL); |
|
906 |
g_signal_connect_after(G_OBJECT(text), "event-after", |
|
907 |
G_CALLBACK(on_event_after), NULL); |
|
126
by mvo
* debian/changelog,configure.in: |
908 |
|
909 |
||
45
by mvo
* added basic "interactive-update-hooks" support |
910 |
/* read already seen hooks */
|
911 |
init_already_seen_hooks(ta); |
|
912 |
||
913 |
/* Check for hooks */
|
|
914 |
check_update_hooks(ta); |
|
915 |
}
|