static int attr_set_rpc (attr_ctx_t *ctx, const char *name, const char *val) { flux_future_t *f; attr_t *attr; int rc = -1; #if JANSSON_VERSION_HEX >= 0x020800 /* $? format specifier was introduced in jansson 2.8 */ f = flux_rpc_pack (ctx->h, "attr.set", FLUX_NODEID_ANY, 0, "{s:s, s:s?}", "name", name, "value", val); #else f = flux_rpc_pack (ctx->h, "attr.set", FLUX_NODEID_ANY, 0, val ? "{s:s, s:s}" : "{s:s, s:n}", "name", name, "value", val); #endif if (!f) goto done; if (flux_future_get (f, NULL) < 0) goto done; if (val) { if (!(attr = attr_create (val, 0))) goto done; zhash_update (ctx->hash, name, attr); zhash_freefn (ctx->hash, name, attr_destroy); } else zhash_delete (ctx->hash, name); rc = 0; done: flux_future_destroy (f); return rc; }
int flux_attr_fake (flux_t *h, const char *name, const char *val, int flags) { attr_ctx_t *ctx = getctx (h); attr_t *attr = attr_create (val, flags); if (!ctx || !attr) return -1; zhash_update (ctx->hash, name, attr); zhash_freefn (ctx->hash, name, attr_destroy); return 0; }
static int attr_get_rpc (attr_ctx_t *ctx, const char *name, attr_t **attrp) { flux_future_t *f; const char *val; int flags; attr_t *attr; int rc = -1; if (!(f = flux_rpc_pack (ctx->h, "attr.get", FLUX_NODEID_ANY, 0, "{s:s}", "name", name))) goto done; if (flux_rpc_get_unpack (f, "{s:s, s:i}", "value", &val, "flags", &flags) < 0) goto done; if (!(attr = attr_create (val, flags))) goto done; zhash_update (ctx->hash, name, attr); zhash_freefn (ctx->hash, name, attr_destroy); *attrp = attr; rc = 0; done: flux_future_destroy (f); return rc; }
/* * attr_create_from_str * * Parse the passed string into an attr structure and return a pointer to a list of * attr_entry structs. * * Attribute strings are formatted much like URL arguments: * foo=bar&blah=humbug&blorg=42&test=one * You cannot, currently, have an "=" or "&" character in the value for an * attribute. */ extern attr attr_create_from_str(const char *attr_str) { char *tmp; char *cur; char *name; char *val; attr res = NULL; if(!str_length(attr_str)) { return NULL; } /* make a copy for a destructive read. */ tmp = str_dup(attr_str); if(!tmp) { return NULL; } res = attr_create(); if(!res) { mem_free(tmp); return NULL; } /* * walk the pointer along the input and copy the * names and values along the way. */ cur = tmp; while(*cur) { /* read the name */ name = cur; while(*cur && *cur != '=') cur++; /* did we run off the end of the string? * That is an error because we need to have a value. */ if(*cur == 0) { if(res) attr_destroy(res); mem_free(tmp); return NULL; } /* terminate the name string */ *cur = 0; /* read the value */ cur++; val = cur; while(*cur && *cur != '&') cur++; /* we do not care if we ran off the end, much. */ if(*cur) { *cur = 0; cur++; } if(attr_set_str(res, name, val)) { if(res) attr_destroy(res); mem_free(tmp); return NULL; } } mem_free(tmp); return res; }