#include "e.h" static Ecore_Con_Url *url_up = NULL; static Eina_List *handlers = NULL; static Ecore_Timer *update_timer = NULL; static E_Dialog *dialog = NULL; static char *machid = NULL; static void _update_done(void) { if (url_up) { ecore_con_url_free(url_up); url_up = NULL; } } static void _delete_cb(void *obj EINA_UNUSED) { dialog = NULL; } static void _ok_cb(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED) { e_object_del(E_OBJECT(dialog)); if (e_config->update.later > 0) { e_config->update.later = 0; e_config_save_queue(); } } static void _bother_me_later_cb(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED) { e_object_del(E_OBJECT(dialog)); // 5 * 5 * 1hr === about 1 day limit, so bother-me later will wait // a day in between botherings. botherings reset on e start or restart if (e_config->update.later < 5) { e_config->update.later++; e_config_save_queue(); } } static void _never_tell_me_cb(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED) { if (update_timer) ecore_timer_del(update_timer); update_timer = NULL; e_object_del(E_OBJECT(dialog)); e_config->update.check = 0; e_config->update.later = 0; e_config_save_queue(); } static void _new_version(const char *ver) { char text[2048]; if (dialog) return; dialog = e_dialog_new(NULL, "E", "_update_available"); e_object_del_attach_func_set(E_OBJECT(dialog), _delete_cb); e_dialog_button_add(dialog, _("OK"), NULL, _ok_cb, NULL); e_dialog_button_add(dialog, _("Bother me later"), NULL, _bother_me_later_cb, NULL); e_dialog_button_add(dialog, _("Never tell me"), NULL, _never_tell_me_cb, NULL); e_dialog_button_focus_num(dialog, 1); e_dialog_title_set(dialog, _("Update Notice")); e_dialog_icon_set(dialog, "dialog-warning", 64); snprintf(text, sizeof(text), _("Your enlightenment version is" "not the current latest release." "The latest version is:" "" "%s" "" "Please visit www.enlightenment.org" "or update your system packages" "to get a new version."), ver); e_dialog_text_set(dialog, text); elm_win_center(dialog->win, 1, 1); e_dialog_show(dialog); } static Eina_Bool _upload_data_cb(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event) { Ecore_Con_Event_Url_Data *ev = event; if (ev->url_con != url_up) return EINA_TRUE; if (ev->size > 0) { char *txt = alloca(ev->size + 1); memcpy(txt, ev->data, ev->size); txt[ev->size] = 0; if (!strncmp(txt, "OK", 2)) { } else if (!strncmp(txt, "OLD", 3)) { char *ver = strchr(txt, ' '); if (ver) { ver++; _new_version(ver); } } } return EINA_FALSE; } static Eina_Bool _upload_progress_cb(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event) { Ecore_Con_Event_Url_Progress *ev = event; if (ev->url_con != url_up) return EINA_TRUE; return EINA_FALSE; } static Eina_Bool _upload_complete_cb(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event) { Ecore_Con_Event_Url_Complete *ev = event; if (ev->url_con != url_up) return EINA_TRUE; if (ev->status != 200) { _update_done(); return EINA_FALSE; } _update_done(); return EINA_FALSE; } static void _update_machid_get(void) { FILE *f; char buf[4096], *c; size_t len; f = fopen("/etc/machine-id", "r"); if (!f) f = fopen("/var/lib/dbus/machine-id", "r"); if (!f) { e_user_dir_concat_static(buf, ".machid"); f = fopen(buf, "r"); } if (f) { len = fread(buf, 1, sizeof(buf) - 1, f); if (len > 10) { buf[len] = 0; for (c = buf; *c; c++) { if (!isalnum(*c)) { *c = 0; break; } } machid = strdup(buf); fclose(f); return; } fclose(f); } // generate ID e_user_dir_concat_static(buf, ".machid"); f = fopen(buf, "w"); if (f) { double t; fwrite("GEN-", 4, 1, f); t = ecore_time_unix_get(); fprintf(f, "%1.16f-%i-%i\n", t, rand(), rand()); fclose(f); _update_machid_get(); return; } // this just is all a wash - just use this machid = strdup("NOIDEAWHATTHEIDOFTHISMACHINEIS"); } static void _update_post_generate(char *buf, int size) { if (!machid) _update_machid_get(); if (!machid) return; snprintf(buf, size, "CLIENT %s\n" "UPDATE enlightenment %s", machid, VERSION); } static void _update_check(void) { char buf[1024]; if (url_up) _update_done(); url_up = ecore_con_url_new("http://www.enlightenment.org/update.php"); if (url_up) { _update_post_generate(buf, sizeof(buf)); ecore_con_url_http_version_set(url_up, ECORE_CON_URL_HTTP_VERSION_1_0); ecore_con_url_post(url_up, buf, strlen(buf), "text/plain"); } else _update_done(); } static Eina_Bool _update_timeout_cb(void *data) { double t = 3600.0; // base minimum betwene checks -> 1hr min int later = e_config->update.later; if (e_config->update.check) _update_check(); if (update_timer) ecore_timer_del(update_timer); if (later > 0) { later++; t *= (later * later); } update_timer = ecore_timer_loop_add(t, _update_timeout_cb, data); return EINA_FALSE; } EINTERN int e_update_init(void) { if (ecore_con_url_init()) { handlers = eina_list_append (handlers, ecore_event_handler_add (ECORE_CON_EVENT_URL_DATA, _upload_data_cb, NULL)); handlers = eina_list_append (handlers, ecore_event_handler_add (ECORE_CON_EVENT_URL_PROGRESS, _upload_progress_cb, NULL)); handlers = eina_list_append (handlers, ecore_event_handler_add (ECORE_CON_EVENT_URL_COMPLETE, _upload_complete_cb, NULL)); if (e_config->update.check) { e_config->update.check = 0; _update_timeout_cb(NULL); e_config->update.check = 1; } } return 1; } EINTERN int e_update_shutdown(void) { if (handlers) { _update_done(); ecore_con_url_shutdown(); } if (update_timer) { ecore_timer_del(update_timer); update_timer = NULL; } if (dialog) e_object_del(E_OBJECT(dialog)); dialog = NULL; _update_done(); if (machid) { free(machid); machid = NULL; } return 1; }