1 /*
2 The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3 Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include <osipparser2/internal.h>
21
22 #include <osipparser2/osip_port.h>
23 #include <osipparser2/osip_message.h>
24 #include <osipparser2/osip_parser.h>
25
26 /* Add a header to a SIP message. */
27 /* INPUT : char *hname | pointer to a header name. */
28 /* INPUT : char *hvalue | pointer to a header value. */
29 /* OUTPUT: osip_message_t *sip | structure to save results. */
30 /* returns -1 on error. */
osip_message_set_header(osip_message_t * sip,const char * hname,const char * hvalue)31 int osip_message_set_header(osip_message_t *sip, const char *hname, const char *hvalue) {
32 osip_header_t *h;
33 int i;
34
35 if (sip == NULL || hname == NULL)
36 return OSIP_BADPARAMETER;
37
38 i = osip_header_init(&h);
39
40 if (i != 0)
41 return i;
42
43 h->hname = (char *) osip_malloc(strlen(hname) + 1);
44
45 if (h->hname == NULL) {
46 osip_header_free(h);
47 return OSIP_NOMEM;
48 }
49
50 osip_clrncpy(h->hname, hname, strlen(hname));
51
52 if (hvalue != NULL) { /* some headers can be null ("subject:") */
53 h->hvalue = (char *) osip_malloc(strlen(hvalue) + 1);
54
55 if (h->hvalue == NULL) {
56 osip_header_free(h);
57 return OSIP_NOMEM;
58 }
59
60 osip_clrncpy(h->hvalue, hvalue, strlen(hvalue));
61
62 } else
63 h->hvalue = NULL;
64
65 sip->message_property = 2;
66 osip_list_add(&sip->headers, h, -1);
67 return OSIP_SUCCESS; /* ok */
68 }
69
70 /* Add a or replace exising header to a SIP message. */
71 /* INPUT : char *hname | pointer to a header name. */
72 /* INPUT : char *hvalue | pointer to a header value. */
73 /* OUTPUT: osip_message_t *sip | structure to save results. */
74 /* returns -1 on error. */
osip_message_replace_header(osip_message_t * sip,const char * hname,const char * hvalue)75 int osip_message_replace_header(osip_message_t *sip, const char *hname, const char *hvalue) {
76 osip_header_t *h, *oldh;
77 int i, oldpos = -1;
78
79 if (sip == NULL || hname == NULL)
80 return OSIP_BADPARAMETER;
81
82 oldpos = osip_message_header_get_byname(sip, hname, 0, &oldh);
83
84 i = osip_header_init(&h);
85
86 if (i != 0)
87 return i;
88
89 h->hname = (char *) osip_malloc(strlen(hname) + 1);
90
91 if (h->hname == NULL) {
92 osip_header_free(h);
93 return OSIP_NOMEM;
94 }
95
96 osip_clrncpy(h->hname, hname, strlen(hname));
97
98 if (hvalue != NULL) { /* some headers can be null ("subject:") */
99 h->hvalue = (char *) osip_malloc(strlen(hvalue) + 1);
100
101 if (h->hvalue == NULL) {
102 osip_header_free(h);
103 return OSIP_NOMEM;
104 }
105
106 osip_clrncpy(h->hvalue, hvalue, strlen(hvalue));
107
108 } else
109 h->hvalue = NULL;
110
111 if (oldpos != -1) {
112 osip_list_remove(&sip->headers, oldpos);
113 osip_header_free(oldh);
114 }
115
116 sip->message_property = 2;
117 osip_list_add(&sip->headers, h, -1);
118 return OSIP_SUCCESS; /* ok */
119 }
120
121 #ifndef MINISIZE
122 /* Add a header to a SIP message at the top of the list. */
123 /* INPUT : char *hname | pointer to a header name. */
124 /* INPUT : char *hvalue | pointer to a header value. */
125 /* OUTPUT: osip_message_t *sip | structure to save results. */
126 /* returns -1 on error. */
osip_message_set_topheader(osip_message_t * sip,const char * hname,const char * hvalue)127 int osip_message_set_topheader(osip_message_t *sip, const char *hname, const char *hvalue) {
128 osip_header_t *h;
129 int i;
130
131 if (sip == NULL || hname == NULL)
132 return OSIP_BADPARAMETER;
133
134 i = osip_header_init(&h);
135
136 if (i != 0)
137 return i;
138
139 h->hname = (char *) osip_malloc(strlen(hname) + 1);
140
141 if (h->hname == NULL) {
142 osip_header_free(h);
143 return OSIP_NOMEM;
144 }
145
146 osip_clrncpy(h->hname, hname, strlen(hname));
147
148 if (hvalue != NULL) { /* some headers can be null ("subject:") */
149 h->hvalue = (char *) osip_malloc(strlen(hvalue) + 1);
150
151 if (h->hvalue == NULL) {
152 osip_header_free(h);
153 return OSIP_NOMEM;
154 }
155
156 osip_clrncpy(h->hvalue, hvalue, strlen(hvalue));
157
158 } else
159 h->hvalue = NULL;
160
161 sip->message_property = 2;
162 osip_list_add(&sip->headers, h, 0);
163 return OSIP_SUCCESS; /* ok */
164 }
165
166 /* Get a header in a SIP message. */
167 /* INPUT : int pos | position of number in message. */
168 /* OUTPUT: osip_message_t *sip | structure to scan for a header .*/
169 /* return null on error. */
osip_message_get_header(const osip_message_t * sip,int pos,osip_header_t ** dest)170 int osip_message_get_header(const osip_message_t *sip, int pos, osip_header_t **dest) {
171 *dest = NULL;
172
173 if (osip_list_size(&sip->headers) <= pos)
174 return OSIP_UNDEFINED_ERROR; /* NULL */
175
176 *dest = (osip_header_t *) osip_list_get(&sip->headers, pos);
177 return pos;
178 }
179 #endif
180
181 /* Get a header in a SIP message. */
182 /* INPUT : int pos | position where we start the search */
183 /* OUTPUT: osip_message_t *sip | structure to look for header. */
184 /* return the current position of the header found */
185 /* and -1 on error. */
osip_message_header_get_byname(const osip_message_t * sip,const char * hname,int pos,osip_header_t ** dest)186 int osip_message_header_get_byname(const osip_message_t *sip, const char *hname, int pos, osip_header_t **dest) {
187 int i;
188 osip_header_t *tmp;
189
190 *dest = NULL;
191 i = pos;
192
193 if (osip_list_size(&sip->headers) <= pos)
194 return OSIP_UNDEFINED_ERROR; /* NULL */
195
196 while (osip_list_size(&sip->headers) > i) {
197 tmp = (osip_header_t *) osip_list_get(&sip->headers, i);
198
199 if (osip_strcasecmp(tmp->hname, hname) == 0) {
200 *dest = tmp;
201 return i;
202 }
203
204 i++;
205 }
206
207 return OSIP_UNDEFINED_ERROR; /* not found */
208 }
209
osip_header_init(osip_header_t ** header)210 int osip_header_init(osip_header_t **header) {
211 *header = (osip_header_t *) osip_malloc(sizeof(osip_header_t));
212
213 if (*header == NULL)
214 return OSIP_NOMEM;
215
216 (*header)->hname = NULL;
217 (*header)->hvalue = NULL;
218 return OSIP_SUCCESS;
219 }
220
osip_header_free(osip_header_t * header)221 void osip_header_free(osip_header_t *header) {
222 if (header == NULL)
223 return;
224
225 osip_free(header->hname);
226 osip_free(header->hvalue);
227 header->hname = NULL;
228 header->hvalue = NULL;
229
230 osip_free(header);
231 }
232
233 /* returns the header as a string. */
234 /* INPUT : osip_header_t *header | header. */
235 /* returns null on error. */
osip_header_to_str(const osip_header_t * header,char ** dest)236 int osip_header_to_str(const osip_header_t *header, char **dest) {
237 size_t len, hlen;
238
239 *dest = NULL;
240
241 if ((header == NULL) || (header->hname == NULL))
242 return OSIP_BADPARAMETER;
243
244 len = 0;
245 hlen = strlen(header->hname);
246
247 if (header->hvalue != NULL)
248 len = strlen(header->hvalue);
249
250 *dest = (char *) osip_malloc(hlen + len + 3);
251
252 if (*dest == NULL)
253 return OSIP_NOMEM;
254
255 if (header->hvalue != NULL)
256 snprintf(*dest, hlen + len + 3, "%s: %s", header->hname, header->hvalue);
257
258 else
259 snprintf(*dest, hlen + len + 3, "%s: ", header->hname);
260
261 if (*dest[0] >= 'a' && *dest[0] <= 'z')
262 *dest[0] = (*dest[0] - 32);
263
264 return OSIP_SUCCESS;
265 }
266
osip_header_get_name(const osip_header_t * header)267 char *osip_header_get_name(const osip_header_t *header) {
268 if (header == NULL)
269 return NULL;
270
271 return header->hname;
272 }
273
osip_header_set_name(osip_header_t * header,char * name)274 void osip_header_set_name(osip_header_t *header, char *name) {
275 header->hname = name;
276 }
277
osip_header_get_value(const osip_header_t * header)278 char *osip_header_get_value(const osip_header_t *header) {
279 if (header == NULL)
280 return NULL;
281
282 return header->hvalue;
283 }
284
osip_header_set_value(osip_header_t * header,char * value)285 void osip_header_set_value(osip_header_t *header, char *value) {
286 header->hvalue = value;
287 }
288
osip_header_clone(const osip_header_t * header,osip_header_t ** dest)289 int osip_header_clone(const osip_header_t *header, osip_header_t **dest) {
290 int i;
291 osip_header_t *he;
292
293 *dest = NULL;
294
295 if (header == NULL)
296 return OSIP_BADPARAMETER;
297
298 if (header->hname == NULL)
299 return OSIP_BADPARAMETER;
300
301 i = osip_header_init(&he);
302
303 if (i != 0)
304 return i;
305
306 he->hname = osip_strdup(header->hname);
307
308 if (he->hname == NULL) {
309 osip_header_free(he);
310 return OSIP_NOMEM;
311 }
312
313 if (header->hvalue != NULL) {
314 he->hvalue = osip_strdup(header->hvalue);
315
316 if (he->hvalue == NULL) {
317 osip_header_free(he);
318 return OSIP_NOMEM;
319 }
320 }
321
322 *dest = he;
323 return OSIP_SUCCESS;
324 }
325