1 #include "e.h"
2
3 static Ecore_Con_Url *url_up = NULL;
4 static Eina_List *handlers = NULL;
5 static Ecore_Timer *update_timer = NULL;
6 static E_Dialog *dialog = NULL;
7 static char *machid = NULL;
8
9 static void
_update_done(void)10 _update_done(void)
11 {
12 if (url_up)
13 {
14 ecore_con_url_free(url_up);
15 url_up = NULL;
16 }
17 }
18
19 static void
_delete_cb(void * obj EINA_UNUSED)20 _delete_cb(void *obj EINA_UNUSED)
21 {
22 dialog = NULL;
23 }
24
25 static void
_ok_cb(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)26 _ok_cb(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
27 {
28 e_object_del(E_OBJECT(dialog));
29 if (e_config->update.later > 0)
30 {
31 e_config->update.later = 0;
32 e_config_save_queue();
33 }
34 }
35
36 static void
_bother_me_later_cb(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)37 _bother_me_later_cb(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
38 {
39 e_object_del(E_OBJECT(dialog));
40 // 5 * 5 * 1hr === about 1 day limit, so bother-me later will wait
41 // a day in between botherings. botherings reset on e start or restart
42 if (e_config->update.later < 5)
43 {
44 e_config->update.later++;
45 e_config_save_queue();
46 }
47 }
48
49 static void
_never_tell_me_cb(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)50 _never_tell_me_cb(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
51 {
52 if (update_timer) ecore_timer_del(update_timer);
53 update_timer = NULL;
54 e_object_del(E_OBJECT(dialog));
55 e_config->update.check = 0;
56 e_config->update.later = 0;
57 e_config_save_queue();
58 }
59
60 static void
_new_version(const char * ver)61 _new_version(const char *ver)
62 {
63 char text[2048];
64
65 if (dialog) return;
66
67 dialog = e_dialog_new(NULL, "E", "_update_available");
68
69 e_object_del_attach_func_set(E_OBJECT(dialog), _delete_cb);
70 e_dialog_button_add(dialog, _("OK"), NULL,
71 _ok_cb, NULL);
72 e_dialog_button_add(dialog, _("Bother me later"), NULL,
73 _bother_me_later_cb, NULL);
74 e_dialog_button_add(dialog, _("Never tell me"), NULL,
75 _never_tell_me_cb, NULL);
76 e_dialog_button_focus_num(dialog, 1);
77 e_dialog_title_set(dialog, _("Update Notice"));
78 e_dialog_icon_set(dialog, "dialog-warning", 64);
79
80 snprintf(text, sizeof(text),
81 _("Your enlightenment version is<ps/>"
82 "not the current latest release.<ps/>"
83 "The latest version is:<ps/>"
84 "<ps/>"
85 "%s<ps/>"
86 "<ps/>"
87 "Please visit www.enlightenment.org<ps/>"
88 "or update your system packages<ps/>"
89 "to get a new version."), ver);
90 e_dialog_text_set(dialog, text);
91 elm_win_center(dialog->win, 1, 1);
92 e_dialog_show(dialog);
93 }
94
95 static Eina_Bool
_upload_data_cb(void * data EINA_UNUSED,int ev_type EINA_UNUSED,void * event)96 _upload_data_cb(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event)
97 {
98 Ecore_Con_Event_Url_Data *ev = event;
99 if (ev->url_con != url_up) return EINA_TRUE;
100 if (ev->size > 0)
101 {
102 char *txt = alloca(ev->size + 1);
103
104 memcpy(txt, ev->data, ev->size);
105 txt[ev->size] = 0;
106
107 if (!strncmp(txt, "OK", 2))
108 {
109 }
110 else if (!strncmp(txt, "OLD", 3))
111 {
112 char *ver = strchr(txt, ' ');
113 if (ver)
114 {
115 ver++;
116 _new_version(ver);
117 }
118 }
119 }
120 return EINA_FALSE;
121 }
122
123 static Eina_Bool
_upload_progress_cb(void * data EINA_UNUSED,int ev_type EINA_UNUSED,void * event)124 _upload_progress_cb(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event)
125 {
126 Ecore_Con_Event_Url_Progress *ev = event;
127 if (ev->url_con != url_up) return EINA_TRUE;
128 return EINA_FALSE;
129 }
130
131 static Eina_Bool
_upload_complete_cb(void * data EINA_UNUSED,int ev_type EINA_UNUSED,void * event)132 _upload_complete_cb(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event)
133 {
134 Ecore_Con_Event_Url_Complete *ev = event;
135 if (ev->url_con != url_up) return EINA_TRUE;
136 if (ev->status != 200)
137 {
138 _update_done();
139 return EINA_FALSE;
140 }
141 _update_done();
142 return EINA_FALSE;
143 }
144
145 static void
_update_machid_get(void)146 _update_machid_get(void)
147 {
148 FILE *f;
149 char buf[4096], *c;
150 size_t len;
151
152 f = fopen("/etc/machine-id", "r");
153 if (!f) f = fopen("/var/lib/dbus/machine-id", "r");
154 if (!f)
155 {
156 e_user_dir_concat_static(buf, ".machid");
157 f = fopen(buf, "r");
158 }
159 if (f)
160 {
161 len = fread(buf, 1, sizeof(buf) - 1, f);
162 if (len > 10)
163 {
164 buf[len] = 0;
165 for (c = buf; *c; c++)
166 {
167 if (!isalnum(*c))
168 {
169 *c = 0;
170 break;
171 }
172 }
173 machid = strdup(buf);
174 fclose(f);
175 return;
176 }
177 fclose(f);
178 }
179
180 // generate ID
181 e_user_dir_concat_static(buf, ".machid");
182 f = fopen(buf, "w");
183 if (f)
184 {
185 double t;
186 fwrite("GEN-", 4, 1, f);
187 t = ecore_time_unix_get();
188 fprintf(f, "%1.16f-%i-%i\n", t, rand(), rand());
189 fclose(f);
190 _update_machid_get();
191 return;
192 }
193 // this just is all a wash - just use this
194 machid = strdup("NOIDEAWHATTHEIDOFTHISMACHINEIS");
195 }
196
197 static void
_update_post_generate(char * buf,int size)198 _update_post_generate(char *buf, int size)
199 {
200 if (!machid) _update_machid_get();
201 if (!machid) return;
202 snprintf(buf, size,
203 "CLIENT %s\n"
204 "UPDATE enlightenment %s",
205 machid, VERSION);
206 }
207
208 static void
_update_check(void)209 _update_check(void)
210 {
211 char buf[1024];
212
213 if (url_up) _update_done();
214 url_up = ecore_con_url_new("http://www.enlightenment.org/update.php");
215 if (url_up)
216 {
217 _update_post_generate(buf, sizeof(buf));
218 ecore_con_url_http_version_set(url_up, ECORE_CON_URL_HTTP_VERSION_1_0);
219 ecore_con_url_post(url_up, buf, strlen(buf), "text/plain");
220 }
221 else
222 _update_done();
223 }
224
225 static Eina_Bool
_update_timeout_cb(void * data)226 _update_timeout_cb(void *data)
227 {
228 double t = 3600.0; // base minimum betwene checks -> 1hr min
229 int later = e_config->update.later;
230
231 if (e_config->update.check) _update_check();
232 if (update_timer) ecore_timer_del(update_timer);
233 if (later > 0)
234 {
235 later++;
236 t *= (later * later);
237 }
238 update_timer = ecore_timer_loop_add(t, _update_timeout_cb, data);
239 return EINA_FALSE;
240 }
241
242 EINTERN int
e_update_init(void)243 e_update_init(void)
244 {
245 if (ecore_con_url_init())
246 {
247 handlers = eina_list_append
248 (handlers, ecore_event_handler_add
249 (ECORE_CON_EVENT_URL_DATA, _upload_data_cb, NULL));
250 handlers = eina_list_append
251 (handlers, ecore_event_handler_add
252 (ECORE_CON_EVENT_URL_PROGRESS, _upload_progress_cb, NULL));
253 handlers = eina_list_append
254 (handlers, ecore_event_handler_add
255 (ECORE_CON_EVENT_URL_COMPLETE, _upload_complete_cb, NULL));
256 if (e_config->update.check)
257 {
258 e_config->update.check = 0;
259 _update_timeout_cb(NULL);
260 e_config->update.check = 1;
261 }
262 }
263 return 1;
264 }
265
266 EINTERN int
e_update_shutdown(void)267 e_update_shutdown(void)
268 {
269 if (handlers)
270 {
271 _update_done();
272 ecore_con_url_shutdown();
273 }
274 if (update_timer)
275 {
276 ecore_timer_del(update_timer);
277 update_timer = NULL;
278 }
279 if (dialog) e_object_del(E_OBJECT(dialog));
280 dialog = NULL;
281 _update_done();
282 if (machid)
283 {
284 free(machid);
285 machid = NULL;
286 }
287 return 1;
288 }
289
290