modules/ims_qos: added patch for flow-description bug when request originates from...
[sip-router] / src / lib / kmi / attr.c
1 /*
2  * $Id: attr.c 4518 2008-07-28 15:39:28Z henningw $
3  *
4  * Copyright (C) 2006 Voice Sistem SRL
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  *
22  *
23  * History:
24  * ---------
25  *  2006-09-08  first version (bogdan)
26  */
27
28 /*!
29  * \file 
30  * \brief MI :: Attributes
31  * \ingroup mi
32  */
33
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <errno.h>
38
39 #include "../../dprint.h"
40 #include "mi_mem.h"
41 #include "attr.h"
42 #include "fmt.h"
43
44
45 extern char *mi_ap_buf;
46 extern int  mi_ap_buf_len;
47
48
49 struct mi_attr *add_mi_attr(struct mi_node *node, int flags,
50                                                 char *name, int name_len, char *value, int value_len)
51 {
52         struct mi_attr *new, *p;
53         int size_mem, name_pos, value_pos;
54
55         if(!node)
56                 return NULL;
57
58         if (!name) name_len=0;
59         if (!name_len) name=0;
60         if (!value) value_len=0;
61         if (!value_len) value=0;
62
63         if(!name && !value)
64                 return NULL;
65
66         size_mem = sizeof(struct mi_attr);
67         value_pos = name_pos = 0;
68
69         if(name && (flags & MI_DUP_NAME)){
70                 name_pos = size_mem;
71                 size_mem += name_len;
72         }
73         if(value && (flags & MI_DUP_VALUE)){
74                 value_pos = size_mem;
75                 size_mem += value_len;
76         }
77
78         new = (struct mi_attr *)mi_malloc(size_mem);
79         if (!new) {
80                 LM_ERR("no more pkg mem (%d)\n",size_mem);
81                 return NULL;
82         }
83         memset(new,0,size_mem);
84
85         if (name) {
86                 new->name.len = name_len;
87                 if(flags & MI_DUP_NAME){
88                         new->name.s = ((char *)new) + name_pos;
89                         strncpy(new->name.s, name, name_len);
90                 } else{
91                         new->name.s = name;
92                 }
93         }
94
95         if (value) {
96                 new->value.len = value_len;
97                 if(flags & MI_DUP_VALUE){
98                         new->value.s = ((char *)new) + value_pos;
99                         strncpy(new->value.s, value, value_len);
100                 }else{
101                         new->value.s = value;
102                 }
103         }
104
105         if(!(node->attributes)){
106                 new->next = NULL;
107                 return (node->attributes = new);
108         }
109
110         for(p = node->attributes ; p->next ; p = p->next);
111
112         new->next = NULL;
113         p->next = new;
114
115         return new;
116 }
117
118
119
120 struct mi_attr *addf_mi_attr(struct mi_node *node, int flags,
121                                                         char *name, int name_len, char *fmt_val, ...)
122 {
123         va_list ap;
124         char *p;
125         int  len = 0;
126
127         va_start(ap, fmt_val);
128         p = mi_print_fmt( fmt_val, ap, &len);
129         va_end(ap);
130         if (p==NULL)
131                 return 0;
132         return add_mi_attr(node, flags|MI_DUP_VALUE, name, name_len, p, len);
133 }
134
135
136
137 struct mi_attr *get_mi_attr_by_name(struct mi_node *node, char *name, int len)
138 {
139         struct mi_attr *head;
140
141         if(!node || !name || !(node->attributes))
142                 return NULL;
143
144         for(head = node->attributes ; head->next ; head = head->next)
145                 if(len == head->name.len 
146                 && !strncasecmp(name, head->name.s, head->name.len))
147                         return head;
148
149         return NULL;
150 }
151
152
153 void del_mi_attr_list(struct mi_node *node)
154 {
155         struct mi_attr *p, *head;
156
157         if(!node || !(node->attributes))
158                 return;
159
160         for(head = node->attributes; head ;){
161                 p = head->next;
162                 mi_free(head);
163                 head = p;
164         }
165
166         node->attributes = NULL;
167 }
168