static void set_timezone(GVariant *parameters, GDBusMethodInvocation *invocation, const gchar *caller) { gboolean user_interaction, no_change; const gchar *timezone; struct method_call_data data; GVariant *current_timezone; g_variant_get(parameters, "(&sb)", &timezone, &user_interaction); if (!check_timezone_name(timezone)) { return_error(invocation, G_DBUS_ERROR_INVALID_ARGS, "Invalid timezone"); return; } current_timezone = get_timezone(); no_change = !g_strcmp0(g_variant_get_string(current_timezone, NULL), timezone); g_variant_unref(current_timezone); if (no_change) { return_success(invocation); return; } snprintf(data.set_timezone.timezone, sizeof data.set_timezone.timezone, "%s", timezone); start_auth_check(caller, POLKIT_ACTION_SET_TIMEZONE, user_interaction, invocation, finish_set_timezone, &data); }
/* * timestampname * * -- desc: * - use "local now": Xzzzz.yyyymmddhhmmss.uuuuuu */ int timestampname(char * out, const char * prefix, const char * suffix) { int tz; time_t sec_utc; struct tm tm_local; struct timeval today; if (NULL == out) { errno = EINVAL; return -1; } /* get the current time of today */ (void)gettimeofday(&today, NULL); /* get the utc time */ sec_utc = time(NULL);/* sec from 1970 .. */ if (((time_t) -1) == sec_utc) { return -1; } /* * get local time tm * use localtime_r for threads safe */ (void)memset(&tm_local, 0, sizeof(struct tm)); # if !defined(WIN32) (void)localtime_r(&sec_utc, &tm_local); # else (void)memcpy(&tm_local, localtime(&sec_utc), sizeof(struct tm)); # endif tz = get_timezone(&sec_utc); if (prefix) { (void)sprintf(out, "%s%05d.%04d%02d%02d%02d%02d%02d.%06ld", prefix, tz, tm_local.tm_year + 1900, tm_local.tm_mon + 1, tm_local.tm_mday, tm_local.tm_hour, tm_local.tm_min, tm_local.tm_sec, # if !defined(__APPLE__) today.tv_usec # else (long int)(today.tv_usec) # endif ); } else { (void)sprintf(out, "%05d.%04d%02d%02d%02d%02d%02d.%06ld", tz, tm_local.tm_year + 1900, tm_local.tm_mon + 1, tm_local.tm_mday, tm_local.tm_hour, tm_local.tm_min, tm_local.tm_sec, # if !defined(__APPLE__) today.tv_usec # else (long int)(today.tv_usec) # endif ); } if (suffix) { (void)strcat(out, suffix); } return 0; } /* timestampname */
/* Handle time-server tags. * * Sets tags_data->timestamp to the correct time (in unix time). * This received time is always in UTC. * * See http://ircv3.atheme.org/extensions/server-time-3.2 */ static void handle_message_tag_time (const char *time, message_tags_data *tags_data) { /* The time format defined in the ircv3.2 specification is * YYYY-MM-DDThh:mm:ss.sssZ * but znc simply sends a unix time (with 3 decimal places for miliseconds) * so we might as well support both. */ if (!*time) return; if (time[strlen (time) - 1] == 'Z') { /* as defined in the specification */ struct tm t; int z; /* we ignore the milisecond part */ z = sscanf (time, "%d-%d-%dT%d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec); if (z != 6) return; t.tm_year -= 1900; t.tm_mon -= 1; t.tm_isdst = 0; /* day light saving time */ tags_data->timestamp = mktime (&t); if (tags_data->timestamp < 0) { tags_data->timestamp = 0; return; } /* get rid of the local time (mktime() receives a local calendar time) */ tags_data->timestamp -= get_timezone(); } else { /* znc */ long long int t; /* we ignore the milisecond part */ if (sscanf (time, "%lld", &t) != 1) return; tags_data->timestamp = (time_t) t; } }
static void handle_method_call(GDBusConnection *connection, const gchar *caller, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { GVariantBuilder builder; GVariant *result; const gchar *interface, *property; if (!g_strcmp0(interface_name, TIMEDATED_INTERFACE)) { if (!g_strcmp0(method_name, "SetTime")) set_time(parameters, invocation, caller); else if (!g_strcmp0(method_name, "SetTimezone")) set_timezone(parameters, invocation, caller); else if (!g_strcmp0(method_name, "SetLocalRTC")) set_rtc_local(parameters, invocation, caller); else if (!g_strcmp0(method_name, "SetNTP")) set_ntp_active(parameters, invocation, caller); else g_assert_not_reached(); } else if (!g_strcmp0(interface_name, PROPERTIES_INTERFACE)) { if (!g_strcmp0(method_name, "Get")) { g_variant_get(parameters, "(&s&s)", &interface, &property); if (g_strcmp0(interface, TIMEDATED_INTERFACE) && g_strcmp0(interface, "")) { return_error(invocation, G_DBUS_ERROR_INVALID_ARGS, "No such interface"); return; } if (!g_strcmp0(property, "Timezone")) result = get_timezone(); else if (!g_strcmp0(property, "LocalRTC")) result = get_rtc_local(); else if (!g_strcmp0(property, "CanNTP")) result = get_ntp_available(); else if (!g_strcmp0(property, "NTP")) result = get_ntp_active(); else if (!g_strcmp0(property, "NTPSynchronized")) result = get_clock_synchronized(); else if (!g_strcmp0(property, "TimeUSec")) result = get_system_time(); else if (!g_strcmp0(property, "RTCTimeUSec")) result = get_rtc_time(); else { return_error(invocation, G_DBUS_ERROR_INVALID_ARGS, "No such property"); return; } g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", result)); } else if (!g_strcmp0(method_name, "GetAll")) { g_variant_get(parameters, "(&s)", &interface); if (g_strcmp0(interface, TIMEDATED_INTERFACE) && g_strcmp0(interface, "")) { return_error(invocation, G_DBUS_ERROR_INVALID_ARGS, "No such interface"); return; } g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); g_variant_builder_add(&builder, "{sv}", "Timezone", get_timezone()); g_variant_builder_add(&builder, "{sv}", "LocalRTC", get_rtc_local()); g_variant_builder_add(&builder, "{sv}", "CanNTP", get_ntp_available()); g_variant_builder_add(&builder, "{sv}", "NTP", get_ntp_active()); g_variant_builder_add(&builder, "{sv}", "NTPSynchronized", get_clock_synchronized()); g_variant_builder_add(&builder, "{sv}", "TimeUSec", get_system_time()); g_variant_builder_add(&builder, "{sv}", "RTCTimeUSec", get_rtc_time()); result = g_variant_new("(a{sv})", &builder); g_dbus_method_invocation_return_value(invocation, result); } else if (!g_strcmp0(method_name, "Set")) { g_variant_get(parameters, "(&s&sv)", &interface, &property, NULL); return_error(invocation, G_DBUS_ERROR_INVALID_ARGS, "Property %s not writable", property); } else { g_assert_not_reached(); } } else { g_assert_not_reached(); } }
int memcache_get (struct connection *c, const char *key, int len) { char *ptr; //char timezone[32]; long long cnt_id; if (verbosity >= 4) { fprintf (stderr, "memcache_get (key = \""); debug_key (key, len); fprintf (stderr, "\")\n"); } int dog_len = get_at_prefix_length (key, len); key += dog_len; len -= dog_len; Q_raw = 0; if (len > 0 && *key == '%') { dog_len ++; key ++; len --; Q_raw = 1; } if (len > 5 && !strncmp (key, "views", 5)) { int ver; if (!parse_countid_with_version (key + 5, &cnt_id, &ver)) { debug_error ("get", "couldn't parse count_id&version", key, len); return not_found (c); } //int res = get_counter_views(cnt_d, ver); TODO!!! int res = (ver == -1) ? get_counter_views (cnt_id) : get_counter_views_given_version (cnt_id,ver); if (res == -2) { return memcache_wait (c); } if (res >= 0) { //int return_one_key (struct connection *c, const char *key, char *val, int vlen) { if (!Q_raw) { return_one_key (c, key - dog_len, stats_buff, sprintf (stats_buff, "%d", res)); } else { *(int *)stats_buff = res; return_one_key (c, key - dog_len, stats_buff, sizeof (int)); } } return 0; } if (len > 8 && !strncmp (key, "visitors", 8)) { int ver; if (!parse_countid_with_version (key + 8, &cnt_id, &ver)) { debug_error ("get","couldn't parse count_id&version",key, len); return not_found(c); } //int res = get_counter_visitors(cnt_id, ver); TODO !!! int res = (ver == -1) ? get_counter_visitors (cnt_id) : get_counter_visitors_given_version (cnt_id, ver); if (res == -2) { return memcache_wait (c); } if (res >= 0) { //int return_one_key (struct connection *c, const char *key, char *val, int vlen) { if (!Q_raw) { return_one_key (c, key - dog_len, stats_buff, sprintf (stats_buff, "%d", res)); } else { *(int *)stats_buff = res; return_one_key (c, key - dog_len, stats_buff, sizeof (int)); } } return 0; } if (len > 14 && !strncmp (key, "enable_counter", 14)) { cnt_id = strtoll (key + 14, &ptr, 10); if (ptr > key + 14 && !*ptr) { int res = enable_counter (cnt_id, 0); if (res >= 0) { if (!Q_raw) { return_one_key (c, key - dog_len, stats_buff, sprintf (stats_buff, "%d", res)); } else { *(int *)stats_buff = res; return_one_key (c, key - dog_len, stats_buff, sizeof (int)); } } return 0; } } if (len > 15 && !strncmp (key, "disable_counter", 15)) { cnt_id = strtoll (key + 15, &ptr, 10); if (ptr > key + 15 && !*ptr) { int res = disable_counter (cnt_id, 0); if (!Q_raw) { return_one_key (c, key - dog_len, stats_buff, sprintf (stats_buff, "%d", res)); } else { *(int *)stats_buff = res; return_one_key (c, key - dog_len, stats_buff, sizeof (int)); } return 0; } } if (len > 12 && !strncmp(key, "set_timezone", 12)) { int tz = 0; //if (2 == sscanf(key+12,"%d#%31s",&cnt_id,timezone)) { if (2 == sscanf(key + 12,"%lld#%d", &cnt_id, &tz)) { tz = tz + 12 + 4; if (tz < 0) { return 0; } int res = set_timezone (cnt_id, tz, 0); if (!Q_raw) { return_one_key (c, key - dog_len, stats_buff, sprintf (stats_buff, "%d", res)); } else { *(int *)stats_buff = res; return_one_key (c, key - dog_len, stats_buff, sizeof (int)); } return 0; } } if (len > 8 && !strncmp(key, "timezone", 8)) { if (1 == sscanf(key + 8, "%lld", &cnt_id)) { int res = get_timezone (cnt_id); if (!Q_raw) { return_one_key (c, key - dog_len, stats_buff, sprintf (stats_buff, "%d", res)); } else { *(int *)stats_buff = res; return_one_key (c, key - dog_len, stats_buff, sizeof (int)); } return 0; } } if (len > 7 && !strncmp (key, "counter", 7)) { int ver = 0; if (sscanf (key, "counter%lld@%d", &cnt_id, &ver) >= 1) { int to_serialize = key[strlen(key) - 1] != '?'; if (verbosity >= 4) { fprintf(stderr, "cnt_id = %lld, ver = %d\n", cnt_id, ver); } int res = get_counter_serialized (stats_buff, cnt_id, ver); if (res == -2) { return memcache_wait (c); } if (res > 0) { if (to_serialize && !Q_raw) { write_out (&c->Out, stats_buff+res, sprintf (stats_buff+res, "VALUE %s 1 %d\r\n", key - dog_len, res)); } else { write_out (&c->Out, stats_buff+res, sprintf (stats_buff+res, "VALUE %s 0 %d\r\n", key - dog_len, res)); } write_out (&c->Out, stats_buff, res); write_out (&c->Out, "\r\n", 2); } return 0; } } if (len > 16 && !strncmp (key, "monthly_visitors", 16)) { cnt_id = 0; if (sscanf (key, "monthly_visitors%lld", &cnt_id) >= 1) { int res = get_monthly_visitors_serialized (stats_buff, cnt_id); if (res == -2) { return memcache_wait (c); } if (res >= 0) { return_one_key (c, key - dog_len, stats_buff, res); } return 0; } } if (len > 13 && !strncmp (key, "monthly_views", 13)) { cnt_id = 0; if (sscanf (key, "monthly_views%lld", &cnt_id) >= 1) { int res = get_monthly_views_serialized (stats_buff, cnt_id); if (res == -2) { return memcache_wait (c); } if (res >= 0) { return_one_key (c, key - dog_len, stats_buff, res); } return 0; } } if (len > 12 && !strncmp (key, "counters_sum", 12)) { int start_id = 0, finish_id = 0, id = 0; int to_serialize = key[strlen(key) - 1] != '?'; if (sscanf (key, "counters_sum%d_%d_%d", &id, &start_id, &finish_id)) { struct counter *C = get_counters_sum (id, start_id, finish_id); if (C == (void *)-2l) { return memcache_wait (c); } if (C) { int res = counter_serialize (C, stats_buff); assert (res >= 0); if (to_serialize && !Q_raw) { write_out (&c->Out, stats_buff+res, sprintf (stats_buff+res, "VALUE %s 1 %d\r\n", key - dog_len, res)); } else { write_out (&c->Out, stats_buff+res, sprintf (stats_buff+res, "VALUE %s 0 %d\r\n", key - dog_len, res)); } write_out (&c->Out, stats_buff, res); write_out (&c->Out, "\r\n", 2); } } } /* if (len > 7 && !strncmp (key, "counter", 7)) { int cnt_id, subcnt_id = -1, ver = 0; if (sscanf (key, "counter%d:%d@%d", &cnt_id, &subcnt_id, &ver) >= 2) { //int res = get_counter_serialized (stats_buff, cnt_id, subcnt_id, ver); TODO !!! int res = get_counter_serialized (stats_buff, cnt_id, ver); if (res > 0) { write_out (&c->Out, stats_buff+res, sprintf (stats_buff+res, "VALUE %s 1 %d\r\n", key, res)); write_out (&c->Out, stats_buff, res); write_out (&c->Out, "\r\n", 2); } return 0; } if (sscanf (key, "counter%d@%d", &cnt_id, &ver) == 2) { //int res = get_counter_serialized (stats_buff, cnt_id, -1, ver); TODO !!! int res = get_counter_serialized (stats_buff, cnt_id, ver); if (res > 0) { write_out (&c->Out, stats_buff+res, sprintf (stats_buff+res, "VALUE %s 1 %d\r\n", key, res)); write_out (&c->Out, stats_buff, res); write_out (&c->Out, "\r\n", 2); } return 0; } } */ if (len > 8 && !strncmp (key, "versions", 8)) { cnt_id = strtoll (key + 8, &ptr, 10); if (ptr > key+8 && !*ptr) { int res = get_counter_versions (stats_buff, cnt_id); if (res == -2) { return memcache_wait (c); } if (res > 0) { write_out (&c->Out, stats_buff + res, sprintf (stats_buff + res, "VALUE %s 0 %d\r\n", key - dog_len, res)); write_out (&c->Out, stats_buff, res); write_out (&c->Out, "\r\n", 2); } return 0; } } if (len >= 16 && !strncmp (key, "free_block_stats", 16)) { return_one_key_list (c, key - dog_len, len + dog_len, MAX_RECORD_WORDS, 0, FreeCnt, MAX_RECORD_WORDS); return 0; } if (len >= 16 && !strncmp (key, "used_block_stats", 16)) { return_one_key_list (c, key - dog_len, len + dog_len, MAX_RECORD_WORDS, 0, UsedCnt, MAX_RECORD_WORDS); return 0; } if (len >= 16 && !strncmp (key, "allocation_stats", 16)) { return_one_key_list (c, key - dog_len, len + dog_len, MAX_RECORD_WORDS, 0, NewAllocations[0], MAX_RECORD_WORDS * 4); return 0; } if (len >= 17 && !strncmp (key, "split_block_stats", 17)) { return_one_key_list (c, key - dog_len, len + dog_len, MAX_RECORD_WORDS, 0, SplitBlocks, MAX_RECORD_WORDS); return 0; } if (len >= 5 && !strncmp (key, "stats", 5)) { return_one_key (c, key - dog_len, stats_buff, stats_prepare_stats (c)); return 0; } return 0; }
static bool process_read_cmd() { send_zcl_header(CMDID_READ_RESPONSE); while(msg_available()) { uint16_t attr; attr = msg_get_16(); if (zcl.packet.cluster == CLUSTERID_BASIC) { switch(attr) { case ATTR_DEVICE_ENABLED: send_attr_resp_header(ATTR_DEVICE_ENABLED, TYPE_BOOLEAN); send_payload(get_mode()); break; case ATTR_ALARM_MASK: send_attr_resp_header(ATTR_ALARM_MASK, TYPE_BOOLEAN); send_payload(0); //FIXME: implement break; default: send_cmd_status(attr, STATUS_UNSUPPORTED_ATTRIBUTE); break; } } else if (zcl.packet.cluster == CLUSTERID_ELOVALO) { switch(attr) { case ATTR_IEEE_ADDRESS: { send_attr_resp_header(ATTR_IEEE_ADDRESS, TYPE_IEEE_ADDRESS); send_64(mac); break; } case ATTR_OPERATING_MODE: { send_attr_resp_header(ATTR_OPERATING_MODE, TYPE_ENUM); send_payload(get_mode()); break; } case ATTR_EFFECT_TEXT: send_cmd_status(ATTR_EFFECT_TEXT, STATUS_WRITE_ONLY); break; case ATTR_PLAYLIST: send_attr_resp_header(ATTR_PLAYLIST, TYPE_UINT8); send_payload(read_playlist()); break; case ATTR_TIMEZONE: send_attr_resp_header(ATTR_TIMEZONE, TYPE_INT32); send_i32(get_timezone()); break; case ATTR_TIME: send_attr_resp_header(ATTR_TIME, TYPE_UTC_TIME); send_32(time(NULL)-ZIGBEE_TIME_OFFSET); break; case ATTR_EFFECT_NAMES: send_attr_resp_header(ATTR_EFFECT_NAMES, TYPE_LONG_OCTET_STRING); send_effect_names(); break; case ATTR_PLAYLIST_NAMES: send_attr_resp_header(ATTR_PLAYLIST_NAMES, TYPE_LONG_OCTET_STRING); send_16(playlists_json_len); send_pgm_string_direct(playlists_json); break; case ATTR_PLAYLIST_EFFECTS: { send_attr_resp_header(ATTR_PLAYLIST_EFFECTS, TYPE_OCTET_STRING); // current playlist index uint8_t pl_begin = pgm_get(playlists[active_playlist], byte); // End index to playlist, not included to playlist uint8_t pl_end; if (active_playlist == playlists_len - 1) { pl_end = master_playlist_len; } else { pl_end = pgm_get(playlists[active_playlist + 1], byte); } //Send string length send_payload(pl_end - pl_begin); for (uint8_t i = pl_begin; i < pl_end; i++) { send_payload(pgm_get(master_playlist[i].id, byte)); //send_payload(i); } break; } case ATTR_EFFECT: send_attr_resp_header(ATTR_EFFECT, TYPE_UINT8); send_payload(read_effect()); break; case ATTR_HW_VERSION: send_attr_resp_header(ATTR_HW_VERSION, TYPE_OCTET_STRING); send_local_pgm_str(hw_resp); break; case ATTR_SW_VERSION: send_attr_resp_header(ATTR_SW_VERSION, TYPE_OCTET_STRING); send_local_pgm_str(sw_resp); break; case ATTR_PLAYLIST_POSITION: send_attr_resp_header(ATTR_PLAYLIST_POSITION, TYPE_UINT8); uint8_t start = pgm_get(playlists[active_playlist],byte); send_payload(active_effect-start); break; default: send_cmd_status(attr, STATUS_UNSUPPORTED_ATTRIBUTE); break; } } else { // FIXME: See if correct way to handle incorrect cluster if (!zcl.packet.disable_def_resp) { send_default_response(CMDID_READ, STATUS_UNSUP_CLUSTER_COMMAND); } return true; } } return true; }