/************************************************************************* * (C) 2008 AITNET ltd - Sofia/Bulgaria - * by Michael Pounov * * $Author: misho $ * $Id: queue.c,v 1.3 2009/10/19 15:00:10 misho Exp $ * *************************************************************************/ #include "global.h" #include "aitcfg.h" /* * SelectAttribute() Select item //{tagPair} from config list with attribute parameter(s) * @cfg = Head list element * @csSec = Config section //[{csSec}], if NULL search in *default* section * @csAttr = Config attribute //{csAttr} = ..., if NULL search in *any* attribute * return: NULL not found attribute; //{tagPair} selected first seen attribute item from list */ static inline struct tagPair *SelectAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr) { struct tagPair *av; if (!cfg) return NULL; for (av = cfg->slh_first; av; av = av->sle_next) { if ((!csSec || !*csSec) && !av->psSection) { if (!csAttr) return av; if (!strcmp((char*) av->psAttribute, (char*) csAttr)) return av; } if (csSec && av->psSection && !strcmp((char*) av->psSection, (char*) csSec)) { if (!csAttr) return av; if (!strcmp((char*) av->psAttribute, (char*) csAttr)) return av; } } return NULL; } /* * DestroyAttribute() Free //{tagPair} item elements memory and destroy resource * @pair = Free this element */ static inline void DestroyAttribute(struct tagPair *pair) { if (!pair) return; if (pair->psValue) free(pair->psValue); if (pair->psAttribute) free(pair->psAttribute); if (pair->psSection) free(pair->psSection); free(pair); } // ---------------------------------------------- /* * cfg_FindAttribute() Find attribute position in config list * @cfg = Head list element * @csSec = Config section //[{csSec}] * @csAttr = Config attribute //{csAttr} = ... * return: 0 not found item; -1 error: null parameters; >0 position in list */ inline int cfg_FindAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr) { struct tagPair *av; register int cx = 0; if (!cfg || !csAttr) return -1; for (av = cfg->slh_first; av; av = av->sle_next) { ++cx; if ((!csSec || !*csSec) && !av->psSection) if (!strcmp((char*) av->psAttribute, (char*) csAttr)) return cx; if (csSec && av->psSection && !strcmp((char*) av->psSection, (char*) csSec)) if (!strcmp((char*) av->psAttribute, (char*) csAttr)) return cx; } return 0; } /* * cfg_UnsetAttribute() Unset item from config list and free resources * @cfg = Head list element * @csSec = Config section //[{csSec}], if NULL unset in *default* section * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute * return: 0 item not found, -1 error: null parameters; >0 position in list */ int cfg_UnsetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr) { struct tagPair *av, *curr; register int cx = 0; if (!cfg || !csAttr) return -1; av = SelectAttribute(cfg, csSec, csAttr); if (!av) return 0; // remove element // remove element when is first! if (cfg->slh_first == av) { cfg->slh_first = cfg->slh_first->sle_next; DestroyAttribute(av); return 1; } // remove element in other cases... curr = cfg->slh_first; while (curr->sle_next != av) { ++cx; curr = curr->sle_next; } curr->sle_next = curr->sle_next->sle_next; DestroyAttribute(av); return cx; } /* * cfg_SetAttribute() Set item in config list or add new item if not exists * @cfg = Head list element * @csSec = Config section //[{csSec}], if NULL set in *default* section * @csAttr = Config attribute //{csAttr} = ..., if NULL set as *any* attribute * @csVal = Config value //... = {csVal} to setup * return: 0 nothing changed, -1 error: not enough memory; 1 find and update item; 2 added new item */ int cfg_SetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr, const u_char *csVal) { struct tagPair *av, *section; int len; if (!cfg || !csAttr) return -1; av = SelectAttribute(cfg, csSec, csAttr); if (!av) { section = SelectAttribute(cfg, csSec, NULL); av = malloc(sizeof(struct tagPair)); if (!av) { LOGERR; return -1; } else { memset(av, 0, sizeof(struct tagPair)); if (!section) { // add new element av->sle_next = cfg->slh_first; cfg->slh_first = av; } else { // add new element in existing section av->sle_next = section->sle_next; section->sle_next = av; } } // added section name to element if (csSec && *csSec) { len = strlen((char*) csSec) + 1; av->psSection = malloc(len); if (!av->psSection) { LOGERR; free(av); return -1; } else { strlcpy((char*) av->psSection, (char*) csSec, len); } } else av->psSection = NULL; // added attribute to element len = strlen((char*) csAttr) + 1; av->psAttribute = malloc(len); if (!av->psAttribute) { LOGERR; free(av->psSection); free(av); return -1; } else { strlcpy((char*) av->psAttribute, (char*) csAttr, len); } // added value to element if (csVal && *csVal) { len = strlen((char*) csVal) + 1; av->psValue = malloc(len); if (!av->psValue) { LOGERR; free(av->psAttribute); free(av->psSection); free(av); return -1; } else { strlcpy((char*) av->psValue, (char*) csVal, len); } } else { av->psValue = malloc(1); *av->psValue = 0; } // Added new element return 2; } if (strcmp((char*) csVal, (char*) av->psValue)) { len = strlen((char*) csVal) + 1; av->psValue = realloc(av->psValue, len); strlcpy((char*) av->psValue, (char*) csVal, len); // Update element return 1; } // Nothing happens ... finded & values is equal! return 0; } /* * cfg_GetAttribute() Get item from config list and return his value * @cfg = Head list element * @csSec = Config section //[{csSec}], if NULL unset in *default* section * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute * return: NULL item not found or null parameters; !=NULL value const string */ inline const u_char *cfg_GetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr) { struct tagPair *av; if (!cfg || !csAttr) return NULL; av = SelectAttribute(cfg, csSec, csAttr); if (!av) return NULL; return av->psValue; } // -------------------------------------------------------------- /* * cfg_LoadAttribute() Extended get attribute, if not found item return *default value* * @cfg = Head list element * @csSec = Config section //[{csSec}], if NULL unset in *default* section * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute * @psVal = Return buffer for item Value //... = {psVal} * @ValLen = Length of buffer //{psVal} for return * @csDefValue = *Default Value* for return in //{psVal}, if not found item in config list * return: 0 item not found, -1 error: null parameters; >0 number of copied bytes in //{psVal} */ int cfg_LoadAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr, u_char * __restrict psVal, int ValLen, const char *csDefValue) { struct tagPair *av; int ret = 0; if (!cfg || !csAttr || !ValLen || !psVal) return -1; av = SelectAttribute(cfg, csSec, csAttr); if (!av) { if (csDefValue) { strlcpy((char*) psVal, csDefValue, ValLen); ret = strlen((char*) psVal); } return ret; } if (!av->psValue || !*av->psValue) { if (csDefValue) { strlcpy((char*) psVal, csDefValue, ValLen); ret = strlen((char*) psVal); } } else { strlcpy((char*) psVal, (char*) av->psValue, ValLen); ret = strlen((char*) psVal); } return ret; }