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