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