LIB_EXPORT plc_tag plc_tag_create(const char *attrib_str) { plc_tag tag = PLC_TAG_NULL; attr attribs = NULL; int rc = PLCTAG_STATUS_OK; if(!attrib_str || !str_length(attrib_str)) { return PLC_TAG_NULL; } attribs = attr_create_from_str(attrib_str); if(!attribs) { return PLC_TAG_NULL; } /* * create the tag, this is protocol specific. * * If this routine wants to keep the attributes around, it needs * to clone them. */ tag = ab_tag_create(attribs); /* * FIXME - this really should be here??? Maybe not? But, this is * the only place it can be without making every protocol type do this automatically. */ if(tag && tag->status == PLCTAG_STATUS_OK) { rc = mutex_create(&tag->mut); tag->status = rc; tag->read_cache_expire = (uint64_t)0; tag->read_cache_ms = attr_get_int(attribs,"read_cache_ms",0); } /* * Release memory for attributes * * some code is commented out that would have kept a pointer * to the attributes in the tag and released the memory upon * tag destruction. To prevent a memory leak without maintaining * that pointer, the memory needs to be released here. */ attr_destroy(attribs); return tag; }
int entry_destroy(void) { slap_list *e; if ( ebuf ) free( ebuf ); ebuf = NULL; ecur = NULL; emaxsize = 0; for ( e=entry_chunks; e; e=entry_chunks ) { entry_chunks = e->next; free( e ); } ldap_pvt_thread_mutex_destroy( &entry_mutex ); ldap_pvt_thread_mutex_destroy( &entry2str_mutex ); return attr_destroy(); }
/* * 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; }