1 /* zxidmkwsf.c - Handwritten nitty-gritty functions for constructing various elems
2 * Copyright (c) 2010-2011 Sampo Kellomaki <sampo@iki.fi>, All Rights Reserved.
3 * Copyright (c) 2007-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
4 * Author: Sampo Kellomaki (sampo@iki.fi)
5 * This is confidential unpublished proprietary source code of the author.
6 * NO WARRANTY, not even implied warranties. Contains trade secrets.
7 * Distribution prohibited unless authorized in writing.
8 * Licensed under Apache License 2.0, see file COPYING.
9 * $Id: zxidmkwsf.c,v 1.12 2009-11-24 23:53:40 sampo Exp $
10 *
11 * 12.1.2007, created --Sampo
12 * 7.10.2008, added documentation --Sampo
13 * 15.11.2009, added ID-WSF <lu:Status> --Sampo
14 * 25.5.2010, added SOAP fault, tas3:Status, error formatting --Sampo
15 */
16
17 #include "platform.h"
18 #include "errmac.h"
19 #include "zxid.h"
20 #include "zxidconf.h"
21 #include "saml2.h"
22 #include "wsf.h"
23 #include "c/zx-const.h"
24 #include "c/zx-ns.h"
25 #include "c/zx-data.h"
26
27 /* *** What correct API should look like? This is still in flux
28 * and the initial goal is just to make single query for single
29 * service. All other complicated options and multi service queries
30 * will come in later releases. */
31
32 /*() Create ID-WSF protocol <lu:Status> element, given various levels of error input.
33 *
34 * sc1:: First level status code
35 * sc2:: Second level status code, if any
36 * msg:: First level status message
37 * ref:: First level Status/@ref. Ref is used to point to culprit XML element, if any.
38 * returns:: lu:Status data structure with fields populated.
39 *
40 * See also: zxid_mk_fault() */
41
42 /* Called by: covimp_test, zxid_di_query x2, zxid_idp_as_do x3, zxid_idp_map_nid2uid, zxid_imreq x6, zxid_mk_fault, zxid_mk_lu_Status, zxid_mk_tas3_status, zxid_ps_addent_invite x2, zxid_ps_resolv_id */
zxid_mk_lu_Status(zxid_conf * cf,struct zx_elem_s * father,const char * sc1,const char * sc2,const char * msg,const char * ref)43 struct zx_lu_Status_s* zxid_mk_lu_Status(zxid_conf* cf, struct zx_elem_s* father, const char* sc1, const char* sc2, const char* msg, const char* ref)
44 {
45 struct zx_lu_Status_s* st = zx_NEW_lu_Status(cf->ctx,father);
46 st->code = zx_dup_attr(cf->ctx, &st->gg, zx_code_ATTR, STRNULLCHKQ(sc1));
47 if (msg)
48 st->comment = zx_dup_attr(cf->ctx, &st->gg, zx_comment_ATTR, msg);
49 if (ref)
50 st->ref = zx_dup_attr(cf->ctx, &st->gg, zx_ref_ATTR, ref);
51 if (sc2)
52 st->Status = zxid_mk_lu_Status(cf, &st->gg, sc2, 0, 0, 0);
53 return st;
54 }
55
56 /*() Create TAS3 application level Status (error) header. */
57
58 /* Called by: covimp_test, zxid_get_fault_status */
zxid_mk_tas3_status(zxid_conf * cf,struct zx_elem_s * father,const char * ctlpt,const char * sc1,const char * sc2,const char * msg,const char * ref)59 zxid_tas3_status* zxid_mk_tas3_status(zxid_conf* cf, struct zx_elem_s* father, const char* ctlpt, const char* sc1, const char* sc2, const char* msg, const char* ref)
60 {
61 zxid_tas3_status* st = zx_NEW_tas3_Status(cf->ctx, father);
62 st->mustUnderstand = zx_ref_attr(cf->ctx, &st->gg, zx_e_mustUnderstand_ATTR, "0");
63 if (ref)
64 st->ref = zx_dup_attr(cf->ctx, &st->gg, zx_ref_ATTR, ref);
65 if (ctlpt)
66 st->ctlpt = zx_dup_attr(cf->ctx, &st->gg, zx_ctlpt_ATTR, ctlpt);
67 if (msg)
68 st->comment = zx_dup_attr(cf->ctx, &st->gg, zx_comment_ATTR, msg);
69 st->code = zx_dup_attr(cf->ctx, &st->gg, zx_code_ATTR, STRNULLCHKQ(sc1));
70 if (sc2)
71 st->Status = zxid_mk_lu_Status(cf, &st->gg, sc2, 0, 0, 0);
72 return st;
73 }
74
75 /*() Create SOAP Fault element (see Table 2 of [SOAPBind2], pp.12-13)
76 *
77 * cf:: Configuration object
78 * father:: Optional father XML element
79 * fa:: Optional fault actor, such as one of the TAS3 control points (ctlpt)
80 * fc:: Fault code. Should be "e:Client" or "e:Server".
81 * fs:: Fault string. Human readable string explanation of the fault.
82 * sc1:: First level status code (to be placed inside <detail> element)
83 * sc2:: Second level status code, if any
84 * msg:: First level status message
85 * ref:: First level Status/@ref. Ref is used to point to culprit XML element, if any.
86 * returns:: Fault data structure with fields populated.
87 *
88 * See also: zxid_mk_lu_Status()
89 */
90
91 /* Called by: covimp_test, zxid_call, zxid_query_ctlpt_pdp x2, zxid_timestamp_chk x2, zxid_validate_cond x3, zxid_wsc_call, zxid_wsc_valid_re_env x11, zxid_wsf_validate_a7n x6, zxid_wsp_validate x2, zxid_wsp_validate_env x11 */
zxid_mk_fault(zxid_conf * cf,struct zx_elem_s * father,const char * fa,const char * fc,const char * fs,const char * sc1,const char * sc2,const char * msg,const char * ref)92 zxid_fault* zxid_mk_fault(zxid_conf* cf, struct zx_elem_s* father, const char* fa, const char* fc, const char* fs, const char* sc1, const char* sc2, const char* msg, const char* ref)
93 {
94 zxid_fault* flt = zx_NEW_e_Fault(cf->ctx, father);
95 if (sc1) {
96 flt->detail = zx_NEW_e_detail(cf->ctx, &flt->gg);
97 flt->detail->Status = zxid_mk_lu_Status(cf, &flt->detail->gg, sc1, sc2, msg, ref);
98 }
99 if (fa)
100 flt->faultactor = zx_dup_elem(cf->ctx, &flt->gg, zx_e_faultactor_ELEM, fa);
101 flt->faultstring = zx_dup_elem(cf->ctx, &flt->gg, zx_e_faultstring_ELEM, fs?fs:"Unknown");
102 flt->faultcode = zx_dup_elem(cf->ctx, &flt->gg, zx_e_faultcode_ELEM,fc?fc:"e:Client");
103 return flt;
104 }
105
106 /*() Construct SOAP Fault data structure from zx_str arguments. */
107
108 /* Called by: zxid_wsc_call */
zxid_mk_fault_zx_str(zxid_conf * cf,struct zx_elem_s * father,struct zx_str * fa,struct zx_str * fc,struct zx_str * fs)109 zxid_fault* zxid_mk_fault_zx_str(zxid_conf* cf, struct zx_elem_s* father, struct zx_str* fa, struct zx_str* fc, struct zx_str* fs)
110 {
111 zxid_fault* flt = zx_NEW_e_Fault(cf->ctx, father);
112 if (fa)
113 flt->faultactor = zx_dup_len_elem(cf->ctx, &flt->gg, zx_e_faultactor_ELEM, fa->len, fa->s);
114 flt->faultstring = zx_dup_len_elem(cf->ctx, &flt->gg, zx_e_faultstring_ELEM, fs?fs->len:sizeof("Unknown")-1, fs?fs->s:"Unknown");
115 flt->faultcode = zx_dup_len_elem(cf->ctx, &flt->gg, zx_e_faultcode_ELEM, fc?fc->len:sizeof("e:Client")-1, fc?fc->s:"e:Client");
116 return flt;
117 }
118
119 /*() Set current SOAP Fault of the session. If current fault is set, the zxid_wsp_decorate()
120 * function will generate a SOAP Fault response instead of normal SOAP response. If
121 * you wish to return application response in situation where fault has been
122 * detected, you can use this function to reset the current fault to null. */
123
124 /* Called by: zxid_call, zxid_query_ctlpt_pdp x2, zxid_timestamp_chk x2, zxid_validate_cond x3, zxid_wsc_call x2, zxid_wsc_valid_re_env x12, zxid_wsf_validate_a7n x6, zxid_wsp_validate x2, zxid_wsp_validate_env x12 */
zxid_set_fault(zxid_conf * cf,zxid_ses * ses,zxid_fault * flt)125 void zxid_set_fault(zxid_conf* cf, zxid_ses* ses, zxid_fault* flt) {
126 if (ses->curflt) /* Free the previous fault */
127 zx_free_elem(cf->ctx, &ses->curflt->gg, 1);
128 ses->curflt = flt;
129 }
130
131 /*() Read current SOAP Fault of the session. NULL return means that there was no fault. */
132
133 /* Called by: covimp_test */
zxid_get_fault(zxid_conf * cf,zxid_ses * ses)134 zxid_fault* zxid_get_fault(zxid_conf* cf, zxid_ses* ses) {
135 return ses->curflt;
136 }
137
138 /*() Return first level status code from SOAP Fault.
139 * Typically called as sc1 = zxid_get_tas3_fault_sc1(cf, zxid_get_fault(cf, ses)); */
140
141 /* Called by: covimp_test x2, zxid_get_fault_status */
zxid_get_tas3_fault_sc1(zxid_conf * cf,zxid_fault * flt)142 char* zxid_get_tas3_fault_sc1(zxid_conf* cf, zxid_fault* flt) {
143 if (!flt || !ZX_SIMPLE_ELEM_CHK(flt->faultcode))
144 return 0;
145 return zx_str_to_c(cf->ctx, ZX_GET_CONTENT(flt->faultcode));
146 }
147
148 /*() Return second level status code from SOAP Fault.
149 * Typically called as sc2 = zxid_get_tas3_fault_sc2(cf, zxid_get_fault(cf, ses)); */
150
151 /* Called by: covimp_test x2 */
zxid_get_tas3_fault_sc2(zxid_conf * cf,zxid_fault * flt)152 char* zxid_get_tas3_fault_sc2(zxid_conf* cf, zxid_fault* flt) {
153 if (!flt || !flt->detail || !flt->detail->Status || !flt->detail->Status->code || !flt->detail->Status->code->g.s)
154 return 0;
155 return zx_str_to_c(cf->ctx, &flt->detail->Status->code->g);
156 }
157
158 /*() Return comment field from SOAP Fault.
159 * Typically called as c = zxid_get_tas3_fault_comment(cf, zxid_get_fault(cf, ses)); */
160
161 /* Called by: covimp_test x2, zxid_get_fault_status */
zxid_get_tas3_fault_comment(zxid_conf * cf,zxid_fault * flt)162 char* zxid_get_tas3_fault_comment(zxid_conf* cf, zxid_fault* flt) {
163 if (!flt || !ZX_SIMPLE_ELEM_CHK(flt->faultstring))
164 return 0;
165 return zx_str_to_c(cf->ctx, ZX_GET_CONTENT(flt->faultstring));
166 }
167
168 /*() Return reference field from SOAP Fault.
169 * Typically called as ref = zxid_get_tas3_fault_ref(cf, zxid_get_fault(cf, ses));
170 *
171 * Reference field may indicate which XML element is causing the fault.
172 * Its value correspons to id XML attribute of the faulting element. */
173
174 /* Called by: covimp_test x2 */
zxid_get_tas3_fault_ref(zxid_conf * cf,zxid_fault * flt)175 char* zxid_get_tas3_fault_ref(zxid_conf* cf, zxid_fault* flt) {
176 if (!flt || !flt->detail || !flt->detail->Status || !flt->detail->Status->ref || !flt->detail->Status->ref->g.s)
177 return 0;
178 return zx_str_to_c(cf->ctx, &flt->detail->Status->ref->g);
179 }
180
181 /*() Return actor field from SOAP Fault.
182 * Typically called as act = zxid_get_tas3_fault_actor(cf, zxid_get_fault(cf, ses));
183 *
184 * Actor field may indicate whether the detected error is attributable to Server or Client. */
185
186 /* Called by: covimp_test x2, zxid_get_fault_status */
zxid_get_tas3_fault_actor(zxid_conf * cf,zxid_fault * flt)187 char* zxid_get_tas3_fault_actor(zxid_conf* cf, zxid_fault* flt) {
188 if (!flt || !ZX_SIMPLE_ELEM_CHK(flt->faultactor))
189 return 0;
190 return zx_str_to_c(cf->ctx, ZX_GET_CONTENT(flt->faultactor));
191 }
192
193 /*() Extract TAS3 status from SOAP Fault */
194
195 /* Called by: */
zxid_get_fault_status(zxid_conf * cf,zxid_fault * flt)196 zxid_tas3_status* zxid_get_fault_status(zxid_conf* cf, zxid_fault* flt) {
197 zxid_tas3_status* st;
198 if (!flt || !flt->detail || !flt->detail->Status)
199 return 0;
200 st = zxid_mk_tas3_status(cf, 0,
201 zxid_get_tas3_fault_actor(cf, flt),
202 zxid_get_tas3_fault_sc1(cf, flt),
203 0,
204 zxid_get_tas3_fault_comment(cf, flt),
205 0);
206 st->Status = flt->detail->Status;
207 return st;
208 }
209
210 /*() Set current TAS3 Status of the session. If current Status is set,
211 * the zxid_wsp_decorate() function will generate a TAS3 status
212 * header. */
213
214 /* Called by: zxid_wsc_valid_re_env, zxid_wsp_validate_env */
zxid_set_tas3_status(zxid_conf * cf,zxid_ses * ses,zxid_tas3_status * status)215 void zxid_set_tas3_status(zxid_conf* cf, zxid_ses* ses, zxid_tas3_status* status) {
216 D("curstatus=%p status=%p", ses->curstatus, status);
217 if (ses->curstatus) /* Free the previous fault */
218 zx_free_elem(cf->ctx, &ses->curstatus->gg, 0);
219 ses->curstatus = status;
220 }
221
222 /*() Read current fault of the session. NULL return means that there was no fault. */
223
224 /* Called by: covimp_test */
zxid_get_tas3_status(zxid_conf * cf,zxid_ses * ses)225 zxid_tas3_status* zxid_get_tas3_status(zxid_conf* cf, zxid_ses* ses) {
226 return ses->curstatus;
227 }
228
229 /*() Return first level status code from TAS3 status.
230 * Typically called as sc1 = zxid_get_tas3_status_sc1(cf, zxid_get_tas3_status(cf, ses)); */
231
232 /* Called by: covimp_test x2 */
zxid_get_tas3_status_sc1(zxid_conf * cf,zxid_tas3_status * st)233 char* zxid_get_tas3_status_sc1(zxid_conf* cf, zxid_tas3_status* st) {
234 if (!st || !st->code || !st->code->g.s)
235 return 0;
236 return zx_str_to_c(cf->ctx, &st->code->g);
237 }
238
239 /*() Return second level status code from TAS3 status.
240 * Typically called as sc2 = zxid_get_tas3_status_sc2(cf, zxid_get_tas3_status(cf, ses)); */
241
242 /* Called by: covimp_test x2 */
zxid_get_tas3_status_sc2(zxid_conf * cf,zxid_tas3_status * st)243 char* zxid_get_tas3_status_sc2(zxid_conf* cf, zxid_tas3_status* st) {
244 if (!st || !st->Status || !st->Status->code || !st->Status->code->g.s)
245 return 0;
246 return zx_str_to_c(cf->ctx, &st->Status->code->g);
247 }
248
249 /*() Return comment from TAS3 status.
250 * Typically called as c = zxid_get_tas3_status_comment(cf, zxid_get_tas3_status(cf, ses)); */
251
252 /* Called by: covimp_test x2 */
zxid_get_tas3_status_comment(zxid_conf * cf,zxid_tas3_status * st)253 char* zxid_get_tas3_status_comment(zxid_conf* cf, zxid_tas3_status* st) {
254 if (!st || !st->comment || !st->comment->g.s)
255 return 0;
256 return zx_str_to_c(cf->ctx, &st->comment->g);
257 }
258
259 /*() Return reference field from TAS3 status.
260 * Typically called as ref = zxid_get_tas3_status_ref(cf, zxid_get_tas3_status(cf, ses));
261 *
262 * Reference field may indicate which XML element is causing the fault.
263 * Its value correspons to id XML attribute of the faulting element. */
264
265 /* Called by: covimp_test x2 */
zxid_get_tas3_status_ref(zxid_conf * cf,zxid_tas3_status * st)266 char* zxid_get_tas3_status_ref(zxid_conf* cf, zxid_tas3_status* st) {
267 if (!st || !st->ref || !st->ref->g.s)
268 return 0;
269 return zx_str_to_c(cf->ctx, &st->ref->g);
270 }
271
272 /*() Return control point from TAS3 status.
273 * Typically called as cp = zxid_get_tas3_status_ctlpt(cf, zxid_get_tas3_status(cf, ses));
274 *
275 * Control points are Policy Enforcement Points (PEPs) defined in TAS3
276 * architecture, e.g. "urn:tas3:ctlpt:pep:rq:out", "urn:tas3:ctlpt:pep:rq:in",
277 * "urn:tas3:ctlpt:pep:rs:out", or "urn:tas3:ctlpt:pep:rs:in". */
278
279 /* Called by: covimp_test x2 */
zxid_get_tas3_status_ctlpt(zxid_conf * cf,zxid_tas3_status * st)280 char* zxid_get_tas3_status_ctlpt(zxid_conf* cf, zxid_tas3_status* st) {
281 if (!st || !st->ctlpt || !st->ctlpt->g.s)
282 return 0;
283 return zx_str_to_c(cf->ctx, &st->ctlpt->g);
284 }
285
286 /*() Low level constructor for discovery <di:RequestedService>. */
287
288 /* Called by: zxid_mk_di_query */
zxid_mk_di_req_svc(zxid_conf * cf,struct zx_elem_s * father,int req_id,const char * svc_type,const char * url,const char * di_opt,const char * action)289 static struct zx_di_RequestedService_s* zxid_mk_di_req_svc(zxid_conf* cf, struct zx_elem_s* father, int req_id, const char* svc_type, const char* url, const char* di_opt, const char* action)
290 {
291 struct zx_di_RequestedService_s* rs = zx_NEW_di_RequestedService(cf->ctx, father);
292 if (svc_type)
293 rs->ServiceType = zx_ref_elem(cf->ctx, &rs->gg, zx_di_ServiceType_ELEM, svc_type);
294 if (url)
295 rs->ProviderID = zx_ref_elem(cf->ctx, &rs->gg, zx_di_ProviderID_ELEM, url);
296 if (di_opt) {
297 rs->Options = zx_NEW_di_Options(cf->ctx, &rs->gg);
298 /* N.B: We adopt here a simplification that there can only be one option, but it
299 * can be fully generic URI, including a query string. If it is desireable to
300 * support additional options, dollar ($) could be used as a separator. */
301 rs->Options->Option = zx_ref_elem(cf->ctx, &rs->Options->gg, zx_di_Option_ELEM, di_opt);
302 }
303 #if 0
304 rs->reqID = zx_strf(cf->ctx, "RS%x", req_id);
305 rs->resultType = zx_ref_str(cf->ctx, "all"); /* OPTIONAL: "best", "only-one" */
306 rs->SecurityMechID = zx_ref_elem(cf->ctx, &rs->gg, zx_di_SecurityMechID_ELEM, WSF20_SEC_MECH_TLS_BEARER);
307 rs->SecurityMechID = zx_ref_elem(cf->ctx, &rs->gg, zx_di_SecurityMechID_ELEM, WSF20_SEC_MECH_TLS_SAML2);
308 #endif
309 rs->Framework = zx_NEW_di_Framework(cf->ctx, &rs->gg);
310 rs->Framework->version = zx_ref_attr(cf->ctx, &rs->Framework->gg, zx_version_ATTR, "2.0"); /* Request specific framework, omit=any */
311 if (action)
312 rs->Action = zx_ref_elem(cf->ctx, &rs->gg, zx_di_Action_ELEM, action);
313 zx_reverse_elem_lists(&rs->gg);
314 return rs;
315 }
316
317 /*() Low level constructor for discovery <di:Query>. */
318
319 /* Called by: main x2, zxid_get_epr */
zxid_mk_di_query(zxid_conf * cf,struct zx_elem_s * father,const char * svc_type,const char * url,const char * di_opt,const char * action)320 struct zx_di_Query_s* zxid_mk_di_query(zxid_conf* cf, struct zx_elem_s* father, const char* svc_type, const char* url, const char* di_opt, const char* action)
321 {
322 struct zx_di_Query_s* q = zx_NEW_di_Query(cf->ctx, father);
323 q->RequestedService = zxid_mk_di_req_svc(cf, &q->gg, 1, svc_type, url, di_opt, action);
324 return q;
325 }
326
327 /*() Low level constructor for WSA <Address>. */
328
329 /* Called by: zxid_wsc_prep, zxid_wsf_decor */
zxid_mk_addr(zxid_conf * cf,struct zx_elem_s * father,struct zx_str * url)330 struct zx_a_Address_s* zxid_mk_addr(zxid_conf* cf, struct zx_elem_s* father, struct zx_str* url)
331 {
332 struct zx_a_Address_s* addr = zx_NEW_a_Address(cf->ctx, father);
333 zx_add_content(cf->ctx, &addr->gg, url);
334 return addr;
335 }
336
337 /* --------------- DAP: Select and QueryItem -------------- */
338
339 /*() Low level constructor for <dap:Select>. */
340
341 /* Called by: covimp_test x2, main x4 */
zxid_mk_dap_select(zxid_conf * cf,struct zx_elem_s * father,char * dn,char * filter,char * attributes,int derefaliases,int scope,int sizelimit,int timelimit,int typesonly)342 struct zx_dap_Select_s* zxid_mk_dap_select(zxid_conf* cf, struct zx_elem_s* father, char* dn, char* filter, char* attributes, int derefaliases, int scope, int sizelimit, int timelimit, int typesonly)
343 {
344 struct zx_dap_Select_s* sel = zx_NEW_dap_Select(cf->ctx, father);
345 if (dn) sel->dn = zx_ref_elem(cf->ctx, &sel->gg, zx_dap_dn_ELEM, dn);
346 if (filter) sel->filter = zx_ref_elem(cf->ctx, &sel->gg, zx_dap_filter_ELEM, filter);
347 if (attributes) sel->attributes = zx_ref_attr(cf->ctx, &sel->gg, zx_attributes_ATTR, attributes);
348 if (derefaliases) sel->derefaliases = zx_attrf(cf->ctx, &sel->gg, zx_derefaliases_ATTR, "%d", derefaliases);
349 if (scope) sel->scope = zx_attrf(cf->ctx, &sel->gg, zx_scope_ATTR, "%d", scope);
350 if (sizelimit) sel->sizelimit = zx_attrf(cf->ctx, &sel->gg, zx_sizelimit_ATTR, "%d", sizelimit);
351 if (timelimit) sel->timelimit = zx_attrf(cf->ctx, &sel->gg, zx_timelimit_ATTR, "%d", timelimit);
352 if (typesonly) sel->typesonly = zx_ref_attr(cf->ctx, &sel->gg, zx_typesonly_ATTR, XML_TRUE);
353 return sel;
354 }
355
356 /*() Low level constructor for <dap:QueryItem>. */
357
358 /* Called by: covimp_test, main x3 */
zxid_mk_dap_query_item(zxid_conf * cf,struct zx_elem_s * father,struct zx_dap_Select_s * sel,char * objtype,char * predef,char * sort,char * changed_since,int incl_common_attr,int offset,int count,char * setreq,char * setid,char * contingent_itemidref)359 struct zx_dap_QueryItem_s* zxid_mk_dap_query_item(zxid_conf* cf, struct zx_elem_s* father, struct zx_dap_Select_s* sel, char* objtype, char* predef, char* sort, char* changed_since, int incl_common_attr, int offset, int count, char* setreq, char* setid, char* contingent_itemidref)
360 {
361 struct zx_dap_QueryItem_s* qi = zx_NEW_dap_QueryItem(cf->ctx, father);
362 qi->Select = sel;
363 if (objtype) qi->objectType = zx_ref_attr(cf->ctx, &qi->gg, zx_objectType_ATTR, objtype);
364 if (changed_since) qi->changedSince = zx_ref_attr(cf->ctx, &qi->gg, zx_changedSince_ATTR, changed_since);
365 if (predef) qi->predefined = zx_ref_attr(cf->ctx, &qi->gg, zx_predefined_ATTR, predef);
366 if (sort) qi->Sort = zx_ref_elem(cf->ctx, &qi->gg, zx_dap_Sort_ELEM, sort);
367
368 #if 0
369 /* ID-DAP specification only allows ChangeFormat == "currentElements"
370 * and in fact recommends omitting it altogether. */
371 if (changed_elems)
372 qi->ChangeFormat = zx_ref_elem(cf->ctx, &qi->gg, zx_dap_ChangeFormat_ELEM, "changedElements");
373 if (curr_elems) {
374 if (qi->ChangeFormat)
375 qi->ChangeFormat->g.n = (struct zx_node_s*)zx_ref_elem(cf->ctx, &qi->gg, zx_dap_ChangeFormat_ELEM, "currentElements");
376 else
377 qi->ChangeFormat = zx_ref_elem(cf->ctx, &qi->gg, zx_dap_ChangeFormat_ELEM, "currentElements");
378 }
379 #endif
380
381 if (incl_common_attr) qi->includeCommonAttributes = zx_ref_attr(cf->ctx, &qi->gg, zx_includeCommonAttributes_ATTR, XML_TRUE);
382 if (offset) qi->offset = zx_attrf(cf->ctx, &qi->gg, zx_offset_ATTR, "%d", offset);
383 if (count) qi->count = zx_attrf(cf->ctx, &qi->gg, zx_count_ATTR, "%d", count);
384
385 if (setreq) qi->setReq = zx_ref_attr(cf->ctx, &qi->gg, zx_setReq_ATTR, setreq); /* Request new set */
386 if (setid) qi->setID = zx_ref_attr(cf->ctx, &qi->gg, zx_setID_ATTR, setid); /* Continue to use existing set */
387
388 qi->itemID = zxid_mk_id_attr(cf, &qi->gg, zx_itemID_ATTR, "qi", ZXID_ID_BITS);
389
390 if (contingent_itemidref) {
391 qi->itemIDRef = zx_ref_attr(cf->ctx, &qi->gg, zx_itemIDRef_ATTR, contingent_itemidref);
392 qi->contingency = zx_ref_attr(cf->ctx, &qi->gg, zx_contingency_ATTR, XML_TRUE);
393 }
394 return qi;
395 }
396
397 /* --------------- DAP: Test -------------- */
398
399 /*() Low level constructor for <dap:TestOp>. */
400
401 /* Called by: covimp_test, main */
zxid_mk_dap_testop(zxid_conf * cf,struct zx_elem_s * father,char * dn,char * filter,char * attributes,int derefaliases,int scope,int sizelimit,int timelimit,int typesonly)402 struct zx_dap_TestOp_s* zxid_mk_dap_testop(zxid_conf* cf, struct zx_elem_s* father, char* dn, char* filter, char* attributes, int derefaliases, int scope, int sizelimit, int timelimit, int typesonly)
403 {
404 struct zx_dap_TestOp_s* sel = zx_NEW_dap_TestOp(cf->ctx, father);
405 if (dn) sel->dn = zx_ref_elem(cf->ctx, &sel->gg, zx_dap_dn_ELEM, dn);
406 if (filter) sel->filter = zx_ref_elem(cf->ctx, &sel->gg, zx_dap_filter_ELEM, filter);
407 if (attributes) sel->attributes = zx_ref_attr(cf->ctx, &sel->gg, zx_attributes_ATTR, attributes);
408 if (derefaliases) sel->derefaliases = zx_attrf(cf->ctx, &sel->gg, zx_derefaliases_ATTR, "%d", derefaliases);
409 if (scope) sel->scope = zx_attrf(cf->ctx, &sel->gg, zx_scope_ATTR, "%d", scope);
410 if (sizelimit) sel->sizelimit = zx_attrf(cf->ctx, &sel->gg, zx_sizelimit_ATTR, "%d", sizelimit);
411 if (timelimit) sel->timelimit = zx_attrf(cf->ctx, &sel->gg, zx_timelimit_ATTR, "%d", timelimit);
412 if (typesonly) sel->typesonly = zx_ref_attr(cf->ctx, &sel->gg, zx_typesonly_ATTR, XML_TRUE);
413 return sel;
414 }
415
416 /*() Low level constructor for <dap:TestItem>. */
417
418 /* Called by: covimp_test, main */
zxid_mk_dap_test_item(zxid_conf * cf,struct zx_elem_s * father,struct zx_dap_TestOp_s * top,char * objtype,char * predef)419 struct zx_dap_TestItem_s* zxid_mk_dap_test_item(zxid_conf* cf, struct zx_elem_s* father, struct zx_dap_TestOp_s* top, char* objtype, char* predef)
420 {
421 struct zx_dap_TestItem_s* ti = zx_NEW_dap_TestItem(cf->ctx, father);
422 ti->TestOp = top;
423 ti->id = ti->itemID = zxid_mk_id_attr(cf, &ti->gg, zx_id_ATTR, "ti", ZXID_ID_BITS);
424 if (objtype) ti->objectType = zx_ref_attr(cf->ctx, &ti->gg, zx_objectType_ATTR, objtype);
425 if (predef) ti->predefined = zx_ref_attr(cf->ctx, &ti->gg, zx_predefined_ATTR, predef);
426 return ti;
427 }
428
429 /* --------------- DAP: ResultQuery and Subscription -------------- */
430
431 /*() Low level constructor for <dap:ResultQuery>. */
432
433 /* Called by: covimp_test, main */
zxid_mk_dap_resquery(zxid_conf * cf,struct zx_elem_s * father,struct zx_dap_Select_s * sel,char * objtype,char * predef,char * sort,char * changed_since,int incl_common_attr,char * contingent_itemidref)434 struct zx_dap_ResultQuery_s* zxid_mk_dap_resquery(zxid_conf* cf, struct zx_elem_s* father, struct zx_dap_Select_s* sel, char* objtype, char* predef, char* sort, char* changed_since, int incl_common_attr, char* contingent_itemidref)
435 {
436 struct zx_dap_ResultQuery_s* qi = zx_NEW_dap_ResultQuery(cf->ctx, father);
437 qi->Select = sel;
438 if (changed_since) qi->changedSince = zx_ref_attr(cf->ctx, &qi->gg, zx_changedSince_ATTR, changed_since);
439 if (objtype) qi->objectType = zx_ref_attr(cf->ctx, &qi->gg, zx_objectType_ATTR, objtype);
440 if (predef) qi->predefined = zx_ref_attr(cf->ctx, &qi->gg, zx_predefined_ATTR, predef);
441 if (sort) qi->Sort = zx_ref_elem(cf->ctx, &qi->gg, zx_dap_Sort_ELEM, sort);
442
443 #if 0
444 /* ID-DAP specification only allows ChangeFormat == "currentElements"
445 * and in fact recommends omitting it altogether. */
446 if (changed_elems)
447 qi->ChangeFormat = zx_ref_elem(cf->ctx, &qi->gg, zx_dap_ChangeFormat_ELEM, "changedElements");
448 if (curr_elems) {
449 if (qi->ChangeFormat)
450 qi->ChangeFormat->g.n = (struct zx_node_s*)zx_ref_elem(cf->ctx, &qi->gg, zx_dap_ChangeFormat_ELEM, "currentElements");
451 else
452 qi->ChangeFormat = zx_ref_elem(cf->ctx, &qi->gg, zx_dap_ChangeFormat_ELEM, "currentElements");
453 }
454 #endif
455
456 if (incl_common_attr)
457 qi->includeCommonAttributes = zx_ref_attr(cf->ctx, &qi->gg, zx_includeCommonAttributes_ATTR, XML_TRUE);
458
459 qi->itemID = zxid_mk_id_attr(cf, &qi->gg, zx_itemID_ATTR, "qi", ZXID_ID_BITS);
460
461 if (contingent_itemidref) {
462 qi->itemIDRef = zx_ref_attr(cf->ctx, &qi->gg, zx_itemIDRef_ATTR, contingent_itemidref);
463 qi->contingency = zx_ref_attr(cf->ctx, &qi->gg, zx_contingency_ATTR, XML_TRUE);
464 }
465 return qi;
466 }
467
468 /*() Low level constructor for <dap:Subscription>. */
469
470 /* Called by: covimp_test, main */
zxid_mk_dap_subscription(zxid_conf * cf,struct zx_elem_s * father,char * subsID,char * itemidref,struct zx_dap_ResultQuery_s * rq,char * aggreg,char * trig,char * starts,char * expires,int incl_data,char * admin_notif,char * notify_ref)471 struct zx_dap_Subscription_s* zxid_mk_dap_subscription(zxid_conf* cf, struct zx_elem_s* father, char* subsID, char* itemidref, struct zx_dap_ResultQuery_s* rq, char* aggreg, char* trig, char* starts, char* expires, int incl_data, char* admin_notif, char* notify_ref)
472 {
473 struct zx_dap_Subscription_s* subs = zx_NEW_dap_Subscription(cf->ctx, father);
474 if (itemidref) {
475 subs->RefItem = zx_NEW_subs_RefItem(cf->ctx, &subs->gg);
476 subs->RefItem->itemIDRef = zx_ref_attr(cf->ctx, &subs->RefItem->gg, zx_itemIDRef_ATTR, itemidref);
477 if (subsID)
478 subs->RefItem->subscriptionID = zx_ref_attr(cf->ctx, &subs->RefItem->gg, zx_subscriptionID_ATTR, subsID);
479 }
480 subs->ResultQuery = rq;
481 if (aggreg) subs->Aggregation = zx_ref_elem(cf->ctx, &subs->gg, zx_dap_Aggregation_ELEM, aggreg);
482 if (trig) subs->Trigger = zx_ref_elem(cf->ctx, &subs->gg, zx_dap_Trigger_ELEM, trig);
483 if (starts) subs->starts = zx_ref_attr(cf->ctx, &subs->gg, zx_starts_ATTR, starts);
484 if (expires) subs->expires = zx_ref_attr(cf->ctx, &subs->gg, zx_expires_ATTR, expires);
485 if (incl_data) subs->includeData = zx_ref_attr(cf->ctx, &subs->gg, zx_includeData_ATTR, XML_TRUE);
486 if (admin_notif) subs->adminNotifyToRef = zx_ref_attr(cf->ctx, &subs->gg, zx_adminNotifyToRef_ATTR, admin_notif);
487 if (notify_ref) subs->notifyToRef = zx_ref_attr(cf->ctx, &subs->gg, zx_notifyToRef_ATTR, notify_ref);
488 subs->subscriptionID = zxid_mk_id_attr(cf, &subs->gg, zx_subscriptionID_ATTR, "subs", ZXID_ID_BITS);;
489 return subs;
490 }
491
492 /* --------------- DAP: Query -------------- */
493
494 /*() Low level constructor for <dap:Query>. */
495
496 /* Called by: covimp_test, main x3 */
zxid_mk_dap_query(zxid_conf * cf,struct zx_elem_s * father,struct zx_dap_TestItem_s * tis,struct zx_dap_QueryItem_s * qis,struct zx_dap_Subscription_s * subs)497 struct zx_dap_Query_s* zxid_mk_dap_query(zxid_conf* cf, struct zx_elem_s* father, struct zx_dap_TestItem_s* tis, struct zx_dap_QueryItem_s* qis, struct zx_dap_Subscription_s* subs)
498 {
499 struct zx_dap_Query_s* q = zx_NEW_dap_Query(cf->ctx, father);
500 q->TestItem = tis;
501 q->QueryItem = qis;
502 q->Subscription = subs;
503 q->itemID = zx_ref_attr(cf->ctx, &q->gg, zx_itemID_ATTR, "QRY");
504 return q;
505 }
506
507 /* EOF -- zxidmkwsf.c */
508