~ubuntu-core-dev/update-notifier/ubuntu

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
}