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 enoungh memory\n");
40 xmlXPathFreeObject(result
);
41 for (node
= *node_list
; node
; node
= node
->next
)
46 memcpy(node
, result
->nodesetval
->nodeTab
[i
], sizeof(*node
));
48 /* Add node to node_list */
49 node
->prev
= prev_node
;
52 prev_node
->next
= node
;
58 printf("* Embeding node #%d:\n", i
);
59 xmlDebugDumpNode(stdout
, node
, 2);
64 xmlXPathFreeObject(result
);
69 int main(int argc
, char **argv
) {
70 struct isds_ctx
*ctx
= NULL
;
72 char *recipient
= NULL
;
74 struct isds_list
*documents
= NULL
;
76 setlocale(LC_ALL
, "");
80 printf("isds_init() failed: %s\n", isds_strerror(err
));
84 isds_set_logging(ILF_ALL
& ~ILF_HTTP
, ILL_ALL
);
86 ctx
= isds_ctx_create();
88 printf("isds_ctx_create() failed");
91 err
= isds_set_timeout(ctx
, 10000);
93 printf("isds_set_timeout() failed: %s\n", isds_strerror(err
));
96 err
= isds_login(ctx
, url
, username(), password(), NULL
, NULL
);
98 printf("isds_login() failed: %s: %s\n", isds_strerror(err
),
99 isds_long_message(ctx
));
101 printf("Logged in :)\n");
105 if (argv
[1] && argv
[1][0]) {
106 recipient
= strdup(argv
[1]);
108 /* Find a recipient */
109 struct isds_list
*boxes
= NULL
;
110 struct isds_DbOwnerInfo criteria
;
111 isds_DbType criteria_db_type
= DBTYPE_OVM
;
112 memset(&criteria
, 0, sizeof(criteria
));
113 criteria
.firmName
= "Místní";
114 criteria
.dbType
= &criteria_db_type
;
116 printf("Searching box with firm name `%s':\n", criteria
.firmName
);
117 err
= isds_FindDataBox(ctx
, &criteria
, &boxes
);
118 if (err
== IE_SUCCESS
|| err
== IE_2BIG
) {
119 printf("isds_FindDataBox() succeeded:\n");
121 if (boxes
&& boxes
->data
) {
122 printf("Selected recipient:\n");
123 print_DbOwnerInfo(boxes
->data
);
125 ((struct isds_DbOwnerInfo
*)(boxes
->data
))->dbID
);
128 printf("isds_FindDataBox() failed: %s: %s\n",
129 isds_strerror(err
), isds_long_message(ctx
));
132 isds_list_free(&boxes
);
137 /* Create XML documents */
138 xmlXPathContextPtr xpath_ctx
= NULL
;
140 struct isds_document
*document
;
141 struct isds_list
*documents_item
, *prev_documents_item
= NULL
;
144 printf("Bad number of arguments\n");
145 printf("Usage: %s RECIPIENT XML_FILE XPATH_EXPRESSION...\n"
146 "Send a message with XML document defined by XPATH_EXPRESSION on XML_FILE\n"
147 "to RECIPIENT. If RECIPIENT is empty, send to random foubd one. If more\n"
148 "XPATH_EXPRESSIONS are specified creates XML document for each of them.\n",
153 xml
= xmlParseFile(argv
[2]);
155 printf("Error while parsing `%s'\n", argv
[1]);
159 xpath_ctx
= xmlXPathNewContext(xml
);
161 printf("Error while creating XPath context\n");
165 for (int j
= 3; j
< argc
; j
++) {
166 printf("** Building XML document #%d:\n", j
);
168 document
= calloc(1, sizeof(*document
));
170 printf("Not enough memory\n");
173 document
->is_xml
= 1;
174 document
->dmMimeType
= "text/xml";
175 if (prev_documents_item
)
176 document
->dmFileMetaType
= FILEMETATYPE_ENCLOSURE
;
178 document
->dmFileMetaType
= FILEMETATYPE_MAIN
;
179 document
->dmFileDescr
= "in-line.xml";
181 if (xpath2nodelist(&document
->xml_node_list
, xpath_ctx
,
183 printf("Could not convert XPath result to node list: %s\n",
188 documents_item
= calloc(1, sizeof(*documents_item
));
189 if (!documents_item
) {
190 printf("Not enough memory\n");
194 documents_item
->data
= document
,
195 documents_item
->destructor
= (void(*)(void**))isds_document_free
;
196 if (!prev_documents_item
)
197 documents
= prev_documents_item
= documents_item
;
199 prev_documents_item
->next
= documents_item
;
200 prev_documents_item
= documents_item
;
204 xmlXPathFreeContext(xpath_ctx
);
209 /* Send one message */
210 struct isds_message message
;
211 memset(&message
, 0, sizeof(message
));
213 struct isds_envelope envelope
;
214 memset(&envelope
, 0, sizeof(envelope
));
215 message
.envelope
= &envelope
;
216 long int dmSenderOrgUnitNum
= 42;
217 envelope
.dmSenderOrgUnitNum
= &dmSenderOrgUnitNum
;
218 envelope
.dmAnnotation
= "XML documents";
219 envelope
.dbIDRecipient
= recipient
;
221 message
.documents
= documents
;
223 printf("Sending message to box ID `%s'\n", recipient
);
224 err
= isds_send_message(ctx
, &message
);
226 if (err
== IE_SUCCESS
){
227 printf("isds_send_message() succeeded: message ID = %s\n",
228 message
.envelope
->dmID
);
230 printf("isds_send_message() failed: "
231 "%s: %s\n", isds_strerror(err
), isds_long_message(ctx
));
235 /* Free document xml_node_lists because they are weak copies of nodes in
236 * message->xml and isds_document_free() does not free it. */
237 for (struct isds_list
*item
= documents
; item
; item
= item
->next
) {
239 struct isds_document
*document
=
240 (struct isds_document
*)item
->data
;
241 if (document
->is_xml
) {
242 for (xmlNodePtr node
= document
->xml_node_list
; node
;
253 err
= isds_logout(ctx
);
255 printf("isds_logout() failed: %s\n", isds_strerror(err
));
259 err
= isds_ctx_free(&ctx
);
261 printf("isds_ctx_free() failed: %s\n", isds_strerror(err
));
265 err
= isds_cleanup();
267 printf("isds_cleanup() failed: %s\n", isds_strerror(err
));