Capability *wsp_cap_duplicate(Capability *cap) { Capability *new_cap; if (!cap) return NULL; new_cap = wsp_cap_create(cap->id, octstr_duplicate(cap->name), octstr_duplicate(cap->data)); new_cap->accept = cap->accept; return new_cap; }
/* Generate a refusal for all requested capabilities that are not * replied to. */ static void refuse_unreplied_capabilities(List *caps, List *req) { long i, len; Capability *cap; len = gwlist_len(req); for (i = 0; i < len; i++) { cap = gwlist_get(req, i); if (wsp_cap_count(caps, cap->id, cap->name) == 0) { cap = wsp_cap_create(cap->id, cap->name, NULL); gwlist_append(caps, cap); } } }
List *wsp_cap_unpack_list(Octstr *caps) { List *caps_list; long pos, capslen; caps_list = gwlist_create(); if (caps == NULL) return caps_list; capslen = octstr_len(caps); pos = 0; while (pos < capslen) { unsigned long length; int id; Octstr *name; Octstr *data; pos = octstr_extract_uintvar(caps, &length, pos); if (pos < 0 || length == 0) goto error; id = octstr_get_char(caps, pos); if (id >= 0x80) { id &= 0x7f; /* It's encoded as a short-integer */ name = NULL; data = octstr_copy(caps, pos + 1, length - 1); } else { long nullpos; id = -1; /* It's encoded as token-text */ nullpos = octstr_search_char(caps, 0, pos); if (nullpos < 0) goto error; /* check length * FIXME: If it's not allowed that data is empty then change check * to <= . */ if (length < (nullpos + 1 - pos)) goto error; name = octstr_copy(caps, pos, nullpos - pos); data = octstr_copy(caps, nullpos + 1, length - (nullpos + 1 - pos)); } gwlist_append(caps_list, wsp_cap_create(id, name, data)); pos += length; } return caps_list; error: warning(0, "WSP: Error unpacking capabilities"); return caps_list; }
static void reply_known_capabilities(List *caps, List *req, WSPMachine *m) { unsigned long ui; Capability *cap; Octstr *data; if (wsp_cap_count(caps, WSP_CAPS_CLIENT_SDU_SIZE, NULL) == 0) { if (wsp_cap_get_client_sdu(req, &ui) > 0) { /* Accept value if it is not silly. */ if ((ui >= 256 && ui < LONG_MAX) || ui == 0) { m->client_SDU_size = ui; } } /* Reply with the client SDU we decided on */ data = octstr_create(""); octstr_append_uintvar(data, m->client_SDU_size); cap = wsp_cap_create(WSP_CAPS_CLIENT_SDU_SIZE, NULL, data); gwlist_append(caps, cap); } if (wsp_cap_count(caps, WSP_CAPS_SERVER_SDU_SIZE, NULL) == 0) { /* Accept whatever size the client is willing * to send. If the client did not specify anything, * then use the default. */ if (wsp_cap_get_server_sdu(req, &ui) <= 0) { ui = 1400; } data = octstr_create(""); octstr_append_uintvar(data, ui); cap = wsp_cap_create(WSP_CAPS_SERVER_SDU_SIZE, NULL, data); gwlist_append(caps, cap); } /* Currently we cannot handle any protocol options */ if (wsp_cap_count(caps, WSP_CAPS_PROTOCOL_OPTIONS, NULL) == 0) { data = octstr_create(""); octstr_append_char(data, 0); cap = wsp_cap_create(WSP_CAPS_PROTOCOL_OPTIONS, NULL, data); gwlist_append(caps, cap); } /* Accept any Method-MOR the client sent; if it sent none, * use the default. */ if (wsp_cap_count(caps, WSP_CAPS_METHOD_MOR, NULL) == 0) { if (wsp_cap_get_method_mor(req, &ui) <= 0) { ui = 1; } data = octstr_create(""); octstr_append_char(data, ui); cap = wsp_cap_create(WSP_CAPS_METHOD_MOR, NULL, data); gwlist_append(caps, cap); } /* We will never send any Push requests because we don't support * that yet. But we already specified that in protocol options; * so, pretend we do, and handle the value that way. */ if (wsp_cap_count(caps, WSP_CAPS_PUSH_MOR, NULL) == 0) { if (wsp_cap_get_push_mor(req, &ui) > 0) { m->MOR_push = ui; } data = octstr_create(""); octstr_append_char(data, m->MOR_push); cap = wsp_cap_create(WSP_CAPS_PUSH_MOR, NULL, data); gwlist_append(caps, cap); } /* Supporting extended methods is up to the application layer, * not up to us. If the application layer didn't specify any, * then we refuse whatever the client requested. The default * is to support none, so we don't really have to add anything here. */ /* We do not support any header code pages. sanitize_capabilities * must have already deleted any reply that indicates otherwise. * Again, not adding anything here is the same as refusing support. */ /* Listing aliases is something the application layer can do if * it wants to. We don't care. */ }