1*a93a1f58Sgm209912 /* 2*a93a1f58Sgm209912 * CDDL HEADER START 3*a93a1f58Sgm209912 * 4*a93a1f58Sgm209912 * The contents of this file are subject to the terms of the 5*a93a1f58Sgm209912 * Common Development and Distribution License (the "License"). 6*a93a1f58Sgm209912 * You may not use this file except in compliance with the License. 7*a93a1f58Sgm209912 * 8*a93a1f58Sgm209912 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*a93a1f58Sgm209912 * or http://www.opensolaris.org/os/licensing. 10*a93a1f58Sgm209912 * See the License for the specific language governing permissions 11*a93a1f58Sgm209912 * and limitations under the License. 12*a93a1f58Sgm209912 * 13*a93a1f58Sgm209912 * When distributing Covered Code, include this CDDL HEADER in each 14*a93a1f58Sgm209912 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*a93a1f58Sgm209912 * If applicable, add the following below this CDDL HEADER, with the 16*a93a1f58Sgm209912 * fields enclosed by brackets "[]" replaced with your own identifying 17*a93a1f58Sgm209912 * information: Portions Copyright [yyyy] [name of copyright owner] 18*a93a1f58Sgm209912 * 19*a93a1f58Sgm209912 * CDDL HEADER END 20*a93a1f58Sgm209912 */ 21*a93a1f58Sgm209912 22*a93a1f58Sgm209912 /* 23*a93a1f58Sgm209912 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*a93a1f58Sgm209912 * Use is subject to license terms. 25*a93a1f58Sgm209912 */ 26*a93a1f58Sgm209912 27*a93a1f58Sgm209912 #pragma ident "%Z%%M% %I% %E% SMI" 28*a93a1f58Sgm209912 29*a93a1f58Sgm209912 /* 30*a93a1f58Sgm209912 * Helper functions to skip white spaces, find tokens, find separators and free 31*a93a1f58Sgm209912 * memory. 32*a93a1f58Sgm209912 */ 33*a93a1f58Sgm209912 34*a93a1f58Sgm209912 #include <stdio.h> 35*a93a1f58Sgm209912 #include <assert.h> 36*a93a1f58Sgm209912 #include <errno.h> 37*a93a1f58Sgm209912 #include <stdlib.h> 38*a93a1f58Sgm209912 #include <string.h> 39*a93a1f58Sgm209912 #include <ctype.h> 40*a93a1f58Sgm209912 #include <sdp.h> 41*a93a1f58Sgm209912 42*a93a1f58Sgm209912 #include "sdp_parse.h" 43*a93a1f58Sgm209912 #include "commp_util.h" 44*a93a1f58Sgm209912 45*a93a1f58Sgm209912 void 46*a93a1f58Sgm209912 sdp_free_origin(sdp_origin_t *origin) 47*a93a1f58Sgm209912 { 48*a93a1f58Sgm209912 if (origin != NULL) { 49*a93a1f58Sgm209912 if (origin->o_username != NULL) 50*a93a1f58Sgm209912 free(origin->o_username); 51*a93a1f58Sgm209912 if (origin->o_nettype != NULL) 52*a93a1f58Sgm209912 free(origin->o_nettype); 53*a93a1f58Sgm209912 if (origin->o_addrtype != NULL) 54*a93a1f58Sgm209912 free(origin->o_addrtype); 55*a93a1f58Sgm209912 if (origin->o_address != NULL) 56*a93a1f58Sgm209912 free(origin->o_address); 57*a93a1f58Sgm209912 free(origin); 58*a93a1f58Sgm209912 } 59*a93a1f58Sgm209912 } 60*a93a1f58Sgm209912 61*a93a1f58Sgm209912 void 62*a93a1f58Sgm209912 sdp_free_key(sdp_key_t *key) 63*a93a1f58Sgm209912 { 64*a93a1f58Sgm209912 if (key != NULL) { 65*a93a1f58Sgm209912 if (key->k_method != NULL) 66*a93a1f58Sgm209912 free(key->k_method); 67*a93a1f58Sgm209912 if (key->k_enckey != NULL) 68*a93a1f58Sgm209912 free(key->k_enckey); 69*a93a1f58Sgm209912 free(key); 70*a93a1f58Sgm209912 } 71*a93a1f58Sgm209912 } 72*a93a1f58Sgm209912 73*a93a1f58Sgm209912 void 74*a93a1f58Sgm209912 sdp_free_zone(sdp_zone_t *zone) 75*a93a1f58Sgm209912 { 76*a93a1f58Sgm209912 sdp_zone_t *next_zone; 77*a93a1f58Sgm209912 78*a93a1f58Sgm209912 while (zone != NULL) { 79*a93a1f58Sgm209912 next_zone = zone->z_next; 80*a93a1f58Sgm209912 if (zone->z_offset != NULL) 81*a93a1f58Sgm209912 free(zone->z_offset); 82*a93a1f58Sgm209912 free(zone); 83*a93a1f58Sgm209912 zone = next_zone; 84*a93a1f58Sgm209912 } 85*a93a1f58Sgm209912 } 86*a93a1f58Sgm209912 87*a93a1f58Sgm209912 void 88*a93a1f58Sgm209912 sdp_free_list(sdp_list_t *list) 89*a93a1f58Sgm209912 { 90*a93a1f58Sgm209912 sdp_list_t *next_list; 91*a93a1f58Sgm209912 92*a93a1f58Sgm209912 while (list != NULL) { 93*a93a1f58Sgm209912 next_list = list->next; 94*a93a1f58Sgm209912 if (list->value != NULL) 95*a93a1f58Sgm209912 free(list->value); 96*a93a1f58Sgm209912 free(list); 97*a93a1f58Sgm209912 list = next_list; 98*a93a1f58Sgm209912 } 99*a93a1f58Sgm209912 } 100*a93a1f58Sgm209912 101*a93a1f58Sgm209912 void 102*a93a1f58Sgm209912 sdp_free_media(sdp_media_t *media) 103*a93a1f58Sgm209912 { 104*a93a1f58Sgm209912 sdp_media_t *next_media; 105*a93a1f58Sgm209912 106*a93a1f58Sgm209912 while (media != NULL) { 107*a93a1f58Sgm209912 next_media = media->m_next; 108*a93a1f58Sgm209912 if (media->m_name != NULL) 109*a93a1f58Sgm209912 free(media->m_name); 110*a93a1f58Sgm209912 if (media->m_proto != NULL) 111*a93a1f58Sgm209912 free(media->m_proto); 112*a93a1f58Sgm209912 if (media->m_format != NULL) 113*a93a1f58Sgm209912 sdp_free_list(media->m_format); 114*a93a1f58Sgm209912 if (media->m_info != NULL) 115*a93a1f58Sgm209912 free(media->m_info); 116*a93a1f58Sgm209912 if (media->m_conn != NULL) 117*a93a1f58Sgm209912 sdp_free_connection(media->m_conn); 118*a93a1f58Sgm209912 if (media->m_bw != NULL) 119*a93a1f58Sgm209912 sdp_free_bandwidth(media->m_bw); 120*a93a1f58Sgm209912 if (media->m_key != NULL) 121*a93a1f58Sgm209912 sdp_free_key(media->m_key); 122*a93a1f58Sgm209912 if (media->m_attr != NULL) 123*a93a1f58Sgm209912 sdp_free_attribute(media->m_attr); 124*a93a1f58Sgm209912 free(media); 125*a93a1f58Sgm209912 media = next_media; 126*a93a1f58Sgm209912 } 127*a93a1f58Sgm209912 } 128*a93a1f58Sgm209912 129*a93a1f58Sgm209912 void 130*a93a1f58Sgm209912 sdp_free_attribute(sdp_attr_t *attr) 131*a93a1f58Sgm209912 { 132*a93a1f58Sgm209912 sdp_attr_t *next_attr; 133*a93a1f58Sgm209912 134*a93a1f58Sgm209912 while (attr != NULL) { 135*a93a1f58Sgm209912 next_attr = attr->a_next; 136*a93a1f58Sgm209912 if (attr->a_name != NULL) 137*a93a1f58Sgm209912 free(attr->a_name); 138*a93a1f58Sgm209912 if (attr->a_value != NULL) 139*a93a1f58Sgm209912 free(attr->a_value); 140*a93a1f58Sgm209912 free(attr); 141*a93a1f58Sgm209912 attr = next_attr; 142*a93a1f58Sgm209912 } 143*a93a1f58Sgm209912 } 144*a93a1f58Sgm209912 145*a93a1f58Sgm209912 void 146*a93a1f58Sgm209912 sdp_free_connection(sdp_conn_t *conn) 147*a93a1f58Sgm209912 { 148*a93a1f58Sgm209912 sdp_conn_t *next_conn; 149*a93a1f58Sgm209912 150*a93a1f58Sgm209912 while (conn != NULL) { 151*a93a1f58Sgm209912 next_conn = conn->c_next; 152*a93a1f58Sgm209912 if (conn->c_nettype != NULL) 153*a93a1f58Sgm209912 free(conn->c_nettype); 154*a93a1f58Sgm209912 if (conn->c_addrtype != NULL) 155*a93a1f58Sgm209912 free(conn->c_addrtype); 156*a93a1f58Sgm209912 if (conn->c_address != NULL) 157*a93a1f58Sgm209912 free(conn->c_address); 158*a93a1f58Sgm209912 free(conn); 159*a93a1f58Sgm209912 conn = next_conn; 160*a93a1f58Sgm209912 } 161*a93a1f58Sgm209912 } 162*a93a1f58Sgm209912 163*a93a1f58Sgm209912 void 164*a93a1f58Sgm209912 sdp_free_bandwidth(sdp_bandwidth_t *bw) 165*a93a1f58Sgm209912 { 166*a93a1f58Sgm209912 sdp_bandwidth_t *next_bw; 167*a93a1f58Sgm209912 168*a93a1f58Sgm209912 while (bw != NULL) { 169*a93a1f58Sgm209912 next_bw = bw->b_next; 170*a93a1f58Sgm209912 if (bw->b_type != NULL) 171*a93a1f58Sgm209912 free(bw->b_type); 172*a93a1f58Sgm209912 free(bw); 173*a93a1f58Sgm209912 bw = next_bw; 174*a93a1f58Sgm209912 } 175*a93a1f58Sgm209912 } 176*a93a1f58Sgm209912 177*a93a1f58Sgm209912 void 178*a93a1f58Sgm209912 sdp_free_repeat(sdp_repeat_t *repeat) 179*a93a1f58Sgm209912 { 180*a93a1f58Sgm209912 sdp_repeat_t *next_repeat; 181*a93a1f58Sgm209912 182*a93a1f58Sgm209912 while (repeat != NULL) { 183*a93a1f58Sgm209912 next_repeat = repeat->r_next; 184*a93a1f58Sgm209912 sdp_free_list(repeat->r_offset); 185*a93a1f58Sgm209912 free(repeat); 186*a93a1f58Sgm209912 repeat = next_repeat; 187*a93a1f58Sgm209912 } 188*a93a1f58Sgm209912 } 189*a93a1f58Sgm209912 190*a93a1f58Sgm209912 void 191*a93a1f58Sgm209912 sdp_free_time(sdp_time_t *time) 192*a93a1f58Sgm209912 { 193*a93a1f58Sgm209912 sdp_time_t *next_time; 194*a93a1f58Sgm209912 195*a93a1f58Sgm209912 while (time != NULL) { 196*a93a1f58Sgm209912 next_time = time->t_next; 197*a93a1f58Sgm209912 sdp_free_repeat(time->t_repeat); 198*a93a1f58Sgm209912 free(time); 199*a93a1f58Sgm209912 time = next_time; 200*a93a1f58Sgm209912 } 201*a93a1f58Sgm209912 } 202*a93a1f58Sgm209912 203*a93a1f58Sgm209912 void 204*a93a1f58Sgm209912 sdp_free_session(sdp_session_t *session) 205*a93a1f58Sgm209912 { 206*a93a1f58Sgm209912 if (session == NULL) 207*a93a1f58Sgm209912 return; 208*a93a1f58Sgm209912 if (session->s_origin != NULL) 209*a93a1f58Sgm209912 sdp_free_origin(session->s_origin); 210*a93a1f58Sgm209912 if (session->s_name != NULL) 211*a93a1f58Sgm209912 free(session->s_name); 212*a93a1f58Sgm209912 if (session->s_info != NULL) 213*a93a1f58Sgm209912 free(session->s_info); 214*a93a1f58Sgm209912 if (session->s_uri != NULL) 215*a93a1f58Sgm209912 free(session->s_uri); 216*a93a1f58Sgm209912 if (session->s_email != NULL) 217*a93a1f58Sgm209912 sdp_free_list(session->s_email); 218*a93a1f58Sgm209912 if (session->s_phone != NULL) 219*a93a1f58Sgm209912 sdp_free_list(session->s_phone); 220*a93a1f58Sgm209912 if (session->s_conn != NULL) 221*a93a1f58Sgm209912 sdp_free_connection(session->s_conn); 222*a93a1f58Sgm209912 if (session->s_bw != NULL) 223*a93a1f58Sgm209912 sdp_free_bandwidth(session->s_bw); 224*a93a1f58Sgm209912 if (session->s_time != NULL) 225*a93a1f58Sgm209912 sdp_free_time(session->s_time); 226*a93a1f58Sgm209912 if (session->s_zone != NULL) 227*a93a1f58Sgm209912 sdp_free_zone(session->s_zone); 228*a93a1f58Sgm209912 if (session->s_key != NULL) 229*a93a1f58Sgm209912 sdp_free_key(session->s_key); 230*a93a1f58Sgm209912 if (session->s_attr != NULL) 231*a93a1f58Sgm209912 sdp_free_attribute(session->s_attr); 232*a93a1f58Sgm209912 if (session->s_media != NULL) 233*a93a1f58Sgm209912 sdp_free_media(session->s_media); 234*a93a1f58Sgm209912 free(session); 235*a93a1f58Sgm209912 } 236*a93a1f58Sgm209912 237*a93a1f58Sgm209912 /* 238*a93a1f58Sgm209912 * Adds text of a given length to a linked list. If the list is NULL to 239*a93a1f58Sgm209912 * start with it builds the new list 240*a93a1f58Sgm209912 */ 241*a93a1f58Sgm209912 int 242*a93a1f58Sgm209912 add_value_to_list(sdp_list_t **list, const char *value, int len, boolean_t text) 243*a93a1f58Sgm209912 { 244*a93a1f58Sgm209912 sdp_list_t *new = NULL; 245*a93a1f58Sgm209912 sdp_list_t *tmp = NULL; 246*a93a1f58Sgm209912 247*a93a1f58Sgm209912 new = malloc(sizeof (sdp_list_t)); 248*a93a1f58Sgm209912 if (new == NULL) 249*a93a1f58Sgm209912 return (ENOMEM); 250*a93a1f58Sgm209912 new->next = NULL; 251*a93a1f58Sgm209912 if (text) 252*a93a1f58Sgm209912 new->value = (char *)calloc(1, len + 1); 253*a93a1f58Sgm209912 else 254*a93a1f58Sgm209912 new->value = (uint64_t *)calloc(1, sizeof (uint64_t)); 255*a93a1f58Sgm209912 if (new->value == NULL) { 256*a93a1f58Sgm209912 free(new); 257*a93a1f58Sgm209912 return (ENOMEM); 258*a93a1f58Sgm209912 } 259*a93a1f58Sgm209912 if (text) { 260*a93a1f58Sgm209912 (void) strncpy(new->value, value, len); 261*a93a1f58Sgm209912 } else { 262*a93a1f58Sgm209912 if (commp_time_to_secs((char *)value, (char *)(value + 263*a93a1f58Sgm209912 len), new->value) != 0) { 264*a93a1f58Sgm209912 sdp_free_list(new); 265*a93a1f58Sgm209912 return (EINVAL); 266*a93a1f58Sgm209912 } 267*a93a1f58Sgm209912 } 268*a93a1f58Sgm209912 if (*list == NULL) { 269*a93a1f58Sgm209912 *list = new; 270*a93a1f58Sgm209912 } else { 271*a93a1f58Sgm209912 tmp = *list; 272*a93a1f58Sgm209912 while (tmp->next != NULL) 273*a93a1f58Sgm209912 tmp = tmp->next; 274*a93a1f58Sgm209912 tmp->next = new; 275*a93a1f58Sgm209912 } 276*a93a1f58Sgm209912 return (0); 277*a93a1f58Sgm209912 } 278*a93a1f58Sgm209912 279*a93a1f58Sgm209912 /* 280*a93a1f58Sgm209912 * Given a linked list converts it to space separated string. 281*a93a1f58Sgm209912 */ 282*a93a1f58Sgm209912 int 283*a93a1f58Sgm209912 sdp_list_to_str(sdp_list_t *list, char **buf, boolean_t text) 284*a93a1f58Sgm209912 { 285*a93a1f58Sgm209912 int size = 0; 286*a93a1f58Sgm209912 int wrote = 0; 287*a93a1f58Sgm209912 sdp_list_t *tmp; 288*a93a1f58Sgm209912 char *ret; 289*a93a1f58Sgm209912 char c[1]; 290*a93a1f58Sgm209912 291*a93a1f58Sgm209912 if (list == NULL) { 292*a93a1f58Sgm209912 *buf = NULL; 293*a93a1f58Sgm209912 return (EINVAL); 294*a93a1f58Sgm209912 } 295*a93a1f58Sgm209912 tmp = list; 296*a93a1f58Sgm209912 while (list != NULL) { 297*a93a1f58Sgm209912 if (text) 298*a93a1f58Sgm209912 size += strlen((char *)list->value); 299*a93a1f58Sgm209912 else 300*a93a1f58Sgm209912 size += snprintf(c, 1, "%lld", 301*a93a1f58Sgm209912 *(uint64_t *)list->value); 302*a93a1f58Sgm209912 size++; 303*a93a1f58Sgm209912 list = list->next; 304*a93a1f58Sgm209912 } 305*a93a1f58Sgm209912 list = tmp; 306*a93a1f58Sgm209912 if (size > 0) { 307*a93a1f58Sgm209912 *buf = calloc(1, size + 1); 308*a93a1f58Sgm209912 if (*buf == NULL) 309*a93a1f58Sgm209912 return (ENOMEM); 310*a93a1f58Sgm209912 ret = *buf; 311*a93a1f58Sgm209912 while (list != NULL) { 312*a93a1f58Sgm209912 if (text) { 313*a93a1f58Sgm209912 wrote = snprintf(ret, size, "%s ", 314*a93a1f58Sgm209912 (char *)list->value); 315*a93a1f58Sgm209912 } else { 316*a93a1f58Sgm209912 wrote = snprintf(ret, size, "%lld ", 317*a93a1f58Sgm209912 *(uint64_t *)list->value); 318*a93a1f58Sgm209912 } 319*a93a1f58Sgm209912 ret = ret + wrote; 320*a93a1f58Sgm209912 size = size - wrote; 321*a93a1f58Sgm209912 list = list->next; 322*a93a1f58Sgm209912 } 323*a93a1f58Sgm209912 } else { 324*a93a1f58Sgm209912 return (EINVAL); 325*a93a1f58Sgm209912 } 326*a93a1f58Sgm209912 return (0); 327*a93a1f58Sgm209912 } 328*a93a1f58Sgm209912 329*a93a1f58Sgm209912 /* 330*a93a1f58Sgm209912 * Given a space separated string, converts it into linked list. SDP field 331*a93a1f58Sgm209912 * repeat and media can have undefined number of offsets or formats 332*a93a1f58Sgm209912 * respectively. We need to capture it in a linked list. 333*a93a1f58Sgm209912 */ 334*a93a1f58Sgm209912 int 335*a93a1f58Sgm209912 sdp_str_to_list(sdp_list_t **list, const char *buf, int len, boolean_t text) 336*a93a1f58Sgm209912 { 337*a93a1f58Sgm209912 const char *begin; 338*a93a1f58Sgm209912 const char *current; 339*a93a1f58Sgm209912 const char *end; 340*a93a1f58Sgm209912 int ret = 0; 341*a93a1f58Sgm209912 342*a93a1f58Sgm209912 if (len == 0) 343*a93a1f58Sgm209912 return (EINVAL); 344*a93a1f58Sgm209912 current = buf; 345*a93a1f58Sgm209912 end = current + len; 346*a93a1f58Sgm209912 /* takes care of strings with just spaces */ 347*a93a1f58Sgm209912 if (commp_skip_white_space(¤t, end) != 0) 348*a93a1f58Sgm209912 return (EINVAL); 349*a93a1f58Sgm209912 while (current < end) { 350*a93a1f58Sgm209912 (void) commp_skip_white_space(¤t, end); 351*a93a1f58Sgm209912 begin = current; 352*a93a1f58Sgm209912 while (current < end) { 353*a93a1f58Sgm209912 if (isspace(*current)) 354*a93a1f58Sgm209912 break; 355*a93a1f58Sgm209912 ++current; 356*a93a1f58Sgm209912 } 357*a93a1f58Sgm209912 if (current != begin) { 358*a93a1f58Sgm209912 if ((ret = add_value_to_list(list, begin, 359*a93a1f58Sgm209912 current - begin, text)) != 0) { 360*a93a1f58Sgm209912 sdp_free_list(*list); 361*a93a1f58Sgm209912 *list = NULL; 362*a93a1f58Sgm209912 return (ret); 363*a93a1f58Sgm209912 } 364*a93a1f58Sgm209912 } 365*a93a1f58Sgm209912 } 366*a93a1f58Sgm209912 return (0); 367*a93a1f58Sgm209912 } 368