+/*
+ * value list:
+ * {
+ * values => [ @values ],
+ * time => $time,
+ * host => $host,
+ * plugin => $plugin,
+ * plugin_instance => $pinstance,
+ * type_instance => $tinstance,
+ * }
+ */
+static int hv2value_list (pTHX_ HV *hash, value_list_t *vl)
+{
+ SV **tmp;
+
+ if ((NULL == hash) || (NULL == vl))
+ return -1;
+
+ if (NULL == (tmp = hv_fetch (hash, "type", 4, 0))) {
+ log_err ("hv2value_list: No type given.");
+ return -1;
+ }
+
+ sstrncpy (vl->type, SvPV_nolen (*tmp), sizeof (vl->type));
+
+ if ((NULL == (tmp = hv_fetch (hash, "values", 6, 0)))
+ || (! (SvROK (*tmp) && (SVt_PVAV == SvTYPE (SvRV (*tmp)))))) {
+ log_err ("hv2value_list: No valid values given.");
+ return -1;
+ }
+
+ {
+ AV *array = (AV *)SvRV (*tmp);
+ int len = av_len (array) + 1;
+
+ if (len <= 0)
+ return -1;
+
+ vl->values = (value_t *)smalloc (len * sizeof (value_t));
+ vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp),
+ vl->values, len);
+
+ if (-1 == vl->values_len) {
+ sfree (vl->values);
+ return -1;
+ }
+ }
+
+ if (NULL != (tmp = hv_fetch (hash, "time", 4, 0)))
+ vl->time = (time_t)SvIV (*tmp);
+
+ if (NULL != (tmp = hv_fetch (hash, "interval", 8, 0)))
+ vl->interval = SvIV (*tmp);
+
+ if (NULL != (tmp = hv_fetch (hash, "host", 4, 0)))
+ sstrncpy (vl->host, SvPV_nolen (*tmp), sizeof (vl->host));
+ else
+ sstrncpy (vl->host, hostname_g, sizeof (vl->host));
+
+ if (NULL != (tmp = hv_fetch (hash, "plugin", 6, 0)))
+ sstrncpy (vl->plugin, SvPV_nolen (*tmp), sizeof (vl->plugin));
+
+ if (NULL != (tmp = hv_fetch (hash, "plugin_instance", 15, 0)))
+ sstrncpy (vl->plugin_instance, SvPV_nolen (*tmp),
+ sizeof (vl->plugin_instance));
+
+ if (NULL != (tmp = hv_fetch (hash, "type_instance", 13, 0)))
+ sstrncpy (vl->type_instance, SvPV_nolen (*tmp),
+ sizeof (vl->type_instance));
+ return 0;
+} /* static int hv2value_list (pTHX_ HV *, value_list_t *) */
+
+static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds)
+{
+ int len, i;
+
+ if ((NULL == array) || (NULL == name) || (NULL == ds))
+ return -1;
+
+ len = av_len (array);
+
+ if (-1 == len) {
+ log_err ("av2data_set: Invalid data set.");
+ return -1;
+ }
+
+ ds->ds = (data_source_t *)smalloc ((len + 1) * sizeof (data_source_t));
+ ds->ds_num = len + 1;
+
+ for (i = 0; i <= len; ++i) {
+ SV **elem = av_fetch (array, i, 0);
+
+ if (NULL == elem) {
+ log_err ("av2data_set: Failed to fetch data source %i.", i);
+ return -1;
+ }
+
+ if (! (SvROK (*elem) && (SVt_PVHV == SvTYPE (SvRV (*elem))))) {
+ log_err ("av2data_set: Invalid data source.");
+ return -1;
+ }
+
+ if (-1 == hv2data_source (aTHX_ (HV *)SvRV (*elem), &ds->ds[i]))
+ return -1;
+
+ log_debug ("av2data_set: "
+ "DS.name = \"%s\", DS.type = %i, DS.min = %f, DS.max = %f",
+ ds->ds[i].name, ds->ds[i].type, ds->ds[i].min, ds->ds[i].max);
+ }
+
+ sstrncpy (ds->type, name, sizeof (ds->type));
+ return 0;
+} /* static int av2data_set (pTHX_ AV *, data_set_t *) */
+
+/*
+ * notification:
+ * {
+ * severity => $severity,
+ * time => $time,
+ * message => $msg,
+ * host => $host,
+ * plugin => $plugin,
+ * type => $type,
+ * plugin_instance => $instance,
+ * type_instance => $type_instance,
+ * meta => [ { name => <name>, value => <value> }, ... ]
+ * }
+ */
+static int av2notification_meta (pTHX_ AV *array, notification_meta_t **meta)
+{
+ notification_meta_t **m = meta;
+
+ int len = av_len (array);
+ int i;
+
+ for (i = 0; i <= len; ++i) {
+ SV **tmp = av_fetch (array, i, 0);
+ HV *hash;
+
+ if (NULL == tmp)
+ return -1;
+
+ if (! (SvROK (*tmp) && (SVt_PVHV == SvTYPE (SvRV (*tmp))))) {
+ log_warn ("av2notification_meta: Skipping invalid "
+ "meta information.");
+ continue;
+ }
+
+ hash = (HV *)SvRV (*tmp);
+
+ *m = (notification_meta_t *)smalloc (sizeof (**m));
+
+ if (NULL == (tmp = hv_fetch (hash, "name", 4, 0))) {
+ log_warn ("av2notification_meta: Skipping invalid "
+ "meta information.");
+ free (*m);
+ continue;
+ }
+ sstrncpy ((*m)->name, SvPV_nolen (*tmp), sizeof ((*m)->name));
+
+ if (NULL == (tmp = hv_fetch (hash, "value", 5, 0))) {
+ log_warn ("av2notification_meta: Skipping invalid "
+ "meta information.");
+ free ((*m)->name);
+ free (*m);
+ continue;
+ }
+
+ if (SvNOK (*tmp)) {
+ (*m)->nm_value.nm_double = SvNVX (*tmp);
+ (*m)->type = NM_TYPE_DOUBLE;
+ }
+ else if (SvUOK (*tmp)) {
+ (*m)->nm_value.nm_unsigned_int = SvUVX (*tmp);
+ (*m)->type = NM_TYPE_UNSIGNED_INT;
+ }
+ else if (SvIOK (*tmp)) {
+ (*m)->nm_value.nm_signed_int = SvIVX (*tmp);
+ (*m)->type = NM_TYPE_SIGNED_INT;
+ }
+ else {
+ (*m)->nm_value.nm_string = sstrdup (SvPV_nolen (*tmp));
+ (*m)->type = NM_TYPE_STRING;
+ }
+
+ (*m)->next = NULL;
+ m = &((*m)->next);
+ }
+ return 0;
+} /* static int av2notification_meta (AV *, notification_meta_t *) */
+
+static int hv2notification (pTHX_ HV *hash, notification_t *n)
+{
+ SV **tmp = NULL;
+
+ if ((NULL == hash) || (NULL == n))
+ return -1;
+
+ if (NULL != (tmp = hv_fetch (hash, "severity", 8, 0)))
+ n->severity = SvIV (*tmp);
+ else
+ n->severity = NOTIF_FAILURE;
+
+ if (NULL != (tmp = hv_fetch (hash, "time", 4, 0)))
+ n->time = (time_t)SvIV (*tmp);
+ else
+ n->time = time (NULL);
+
+ if (NULL != (tmp = hv_fetch (hash, "message", 7, 0)))
+ sstrncpy (n->message, SvPV_nolen (*tmp), sizeof (n->message));
+
+ if (NULL != (tmp = hv_fetch (hash, "host", 4, 0)))
+ sstrncpy (n->host, SvPV_nolen (*tmp), sizeof (n->host));
+ else
+ sstrncpy (n->host, hostname_g, sizeof (n->host));
+
+ if (NULL != (tmp = hv_fetch (hash, "plugin", 6, 0)))
+ sstrncpy (n->plugin, SvPV_nolen (*tmp), sizeof (n->plugin));
+
+ if (NULL != (tmp = hv_fetch (hash, "plugin_instance", 15, 0)))
+ sstrncpy (n->plugin_instance, SvPV_nolen (*tmp),
+ sizeof (n->plugin_instance));
+
+ if (NULL != (tmp = hv_fetch (hash, "type", 4, 0)))
+ sstrncpy (n->type, SvPV_nolen (*tmp), sizeof (n->type));
+
+ if (NULL != (tmp = hv_fetch (hash, "type_instance", 13, 0)))
+ sstrncpy (n->type_instance, SvPV_nolen (*tmp),
+ sizeof (n->type_instance));
+
+ n->meta = NULL;
+ while (NULL != (tmp = hv_fetch (hash, "meta", 4, 0))) {
+ if (! (SvROK (*tmp) && (SVt_PVAV == SvTYPE (SvRV (*tmp))))) {
+ log_warn ("hv2notification: Ignoring invalid meta information.");
+ break;
+ }
+
+ if (0 != av2notification_meta (aTHX_ (AV *)SvRV (*tmp), &n->meta)) {
+ plugin_notification_meta_free (n->meta);
+ n->meta = NULL;
+ return -1;
+ }
+ break;
+ }
+ return 0;
+} /* static int hv2notification (pTHX_ HV *, notification_t *) */
+