2 #define _XOPEN_SOURCE XOPEN_SOURCE_LEVEL_FOR_STRDUP
10 #include <libxml/parser.h>
11 #include <libxml/xpath.h>
12 #include <libxml/debugXML.h>
16 /* @node_list is pointer to by-function allocated weak copy of libxml node
17 * pointers list. *NULL means empty list. */
18 int xpath2nodelist(xmlNodePtr
*node_list
, xmlXPathContextPtr xpath_ctx
, const xmlChar
*xpath_expr
) {
19 xmlXPathObjectPtr result
= NULL
;
20 xmlNodePtr node
= NULL
, prev_node
= NULL
;
22 if (!node_list
|| !xpath_ctx
|| !xpath_expr
) return -1;
24 result
= xmlXPathEvalExpression(xpath_expr
, xpath_ctx
);
26 printf("Error while evaluating XPath expression `%s'\n", xpath_expr
);
30 if (xmlXPathNodeSetIsEmpty(result
->nodesetval
)) {
31 printf("Empty match, returning empty node list\n");
34 /* Convert node set to list of siblings */
35 for (int i
= 0; i
< result
->nodesetval
->nodeNr
; i
++) {
36 /* Make weak copy of the node */
37 node
= malloc(sizeof(*node
));
39 fprintf(stderr
, "Not enough memory\n");
40 xmlXPathFreeObject(result
);
41 for (node
= *node_list
; node
;) {
42 xmlNodePtr next_node
= node
->next
;
49 memcpy(node
, result
->nodesetval
->nodeTab
[i
], sizeof(*node
));
51 /* Add node to node_list */
52 node
->prev
= prev_node
;
55 prev_node
->next
= node
;
61 printf("* Embeding node #%d:\n", i
);
62 xmlDebugDumpNode(stdout
, node
, 2);
67 xmlXPathFreeObject(result
);
72 int main(int argc
, char **argv
) {
73 struct isds_ctx
*ctx
= NULL
;
75 char *recipient
= NULL
;
77 struct isds_list
*documents
= NULL
;
79 setlocale(LC_ALL
, "");
83 printf("isds_init() failed: %s\n", isds_strerror(err
));
87 isds_set_logging(ILF_ALL
& ~ILF_HTTP
, ILL_ALL
);
89 ctx
= isds_ctx_create();
91 printf("isds_ctx_create() failed");
94 err
= isds_set_timeout(ctx
, 10000);
96 printf("isds_set_timeout() failed: %s\n", isds_strerror(err
));
99 err
= isds_login(ctx
, url
, username(), password(), NULL
, NULL
);
101 printf("isds_login() failed: %s: %s\n", isds_strerror(err
),
102 isds_long_message(ctx
));
104 printf("Logged in :)\n");
108 if (argv
[1] && argv
[1][0]) {
109 recipient
= strdup(argv
[1]);
111 /* Find a recipient */
112 struct isds_list
*boxes
= NULL
;
113 struct isds_DbOwnerInfo criteria
;
114 isds_DbType criteria_db_type
= DBTYPE_OVM
;
115 memset(&criteria
, 0, sizeof(criteria
));
116 criteria
.firmName
= "Místní";
117 criteria
.dbType
= &criteria_db_type
;
119 printf("Searching box with firm name `%s':\n", criteria
.firmName
);
120 err
= isds_FindDataBox(ctx
, &criteria
, &boxes
);
121 if (err
== IE_SUCCESS
|| err
== IE_2BIG
) {
122 printf("isds_FindDataBox() succeeded:\n");
124 if (boxes
&& boxes
->data
) {
125 printf("Selected recipient:\n");
126 print_DbOwnerInfo(boxes
->data
);
128 ((struct isds_DbOwnerInfo
*)(boxes
->data
))->dbID
);
131 printf("isds_FindDataBox() failed: %s: %s\n",
132 isds_strerror(err
), isds_long_message(ctx
));
135 isds_list_free(&boxes
);
140 /* Create XML documents */
141 xmlXPathContextPtr xpath_ctx
= NULL
;
143 struct isds_document
*document
;
144 struct isds_list
*documents_item
, *prev_documents_item
= NULL
;
147 printf("Bad number of arguments\n");
148 printf("Usage: %s RECIPIENT XML_FILE XPATH_EXPRESSION...\n"
149 "Send a message with XML document defined by XPATH_EXPRESSION on XML_FILE\n"
150 "to RECIPIENT. If RECIPIENT is empty, send to random foubd one. If more\n"
151 "XPATH_EXPRESSIONS are specified creates XML document for each of them.\n",
156 xml
= xmlParseFile(argv
[2]);
158 printf("Error while parsing `%s'\n", argv
[1]);
162 xpath_ctx
= xmlXPathNewContext(xml
);
164 printf("Error while creating XPath context\n");
168 for (int j
= 3; j
< argc
; j
++) {
169 printf("** Building XML document #%d:\n", j
);
171 document
= calloc(1, sizeof(*document
));
173 printf("Not enough memory\n");
176 document
->is_xml
= 1;
177 document
->dmMimeType
= "text/xml";
178 if (prev_documents_item
)
179 document
->dmFileMetaType
= FILEMETATYPE_ENCLOSURE
;
181 document
->dmFileMetaType
= FILEMETATYPE_MAIN
;
182 document
->dmFileDescr
= "in-line.xml";
184 if (xpath2nodelist(&document
->xml_node_list
, xpath_ctx
,
186 printf("Could not convert XPath result to node list: %s\n",
191 documents_item
= calloc(1, sizeof(*documents_item
));
192 if (!documents_item
) {
193 printf("Not enough memory\n");
197 documents_item
->data
= document
,
198 documents_item
->destructor
= (void(*)(void**))isds_document_free
;
199 if (!prev_documents_item
)
200 documents
= prev_documents_item
= documents_item
;
202 prev_documents_item
->next
= documents_item
;
203 prev_documents_item
= documents_item
;
207 xmlXPathFreeContext(xpath_ctx
);
212 /* Send one message */
213 struct isds_message message
;
214 memset(&message
, 0, sizeof(message
));
216 struct isds_envelope envelope
;
217 memset(&envelope
, 0, sizeof(envelope
));
218 message
.envelope
= &envelope
;
219 long int dmSenderOrgUnitNum
= 42;
220 envelope
.dmSenderOrgUnitNum
= &dmSenderOrgUnitNum
;
221 envelope
.dmAnnotation
= "XML documents";
222 envelope
.dbIDRecipient
= recipient
;
224 message
.documents
= documents
;
226 printf("Sending message to box ID `%s'\n", recipient
);
227 err
= isds_send_message(ctx
, &message
);
229 if (err
== IE_SUCCESS
){
230 printf("isds_send_message() succeeded: message ID = %s\n",
231 message
.envelope
->dmID
);
233 printf("isds_send_message() failed: "
234 "%s: %s\n", isds_strerror(err
), isds_long_message(ctx
));
238 /* Free document xml_node_lists because they are weak copies of nodes in
239 * message->xml and isds_document_free() does not free it. */
240 for (struct isds_list
*item
= documents
; item
; item
= item
->next
) {
242 struct isds_document
*document
=
243 (struct isds_document
*)item
->data
;
244 if (document
->is_xml
) {
245 for (xmlNodePtr node
= document
->xml_node_list
; node
;) {
246 xmlNodePtr next_node
= node
->next
;
258 err
= isds_logout(ctx
);
260 printf("isds_logout() failed: %s\n", isds_strerror(err
));
264 err
= isds_ctx_free(&ctx
);
266 printf("isds_ctx_free() failed: %s\n", isds_strerror(err
));
270 err
= isds_cleanup();
272 printf("isds_cleanup() failed: %s\n", isds_strerror(err
));