Fix using CURLOPT_XFERINFOFUNCTION curl option
[libisds.git] / client / sendxmldoc.c
blobcf4907a2213f6a9aaa0487e3ff77416598df3e4e
1 #include "../config.h"
2 #define _XOPEN_SOURCE XOPEN_SOURCE_LEVEL_FOR_STRDUP
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <locale.h>
6 #include <time.h>
7 #include <string.h>
8 #include <libgen.h>
9 #include <isds.h>
10 #include <libxml/parser.h>
11 #include <libxml/xpath.h>
12 #include <libxml/debugXML.h>
13 #include "common.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);
25 if (!result) {
26 printf("Error while evaluating XPath expression `%s'\n", xpath_expr);
27 return -1;
30 if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
31 printf("Empty match, returning empty node list\n");
32 *node_list = NULL;
33 } else {
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));
38 if (!node) {
39 fprintf(stderr, "Not enough memory\n");
40 xmlXPathFreeObject(result);
41 for (node = *node_list; node;) {
42 xmlNodePtr next_node = node->next;
43 free(node);
44 node = next_node;
46 *node_list = NULL;
47 return -1;
49 memcpy(node, result->nodesetval->nodeTab[i], sizeof(*node));
51 /* Add node to node_list */
52 node->prev = prev_node;
53 node->next = NULL;
54 if (prev_node)
55 prev_node->next = node;
56 else
57 *node_list = node;
58 prev_node = node;
60 /* Debug */
61 printf("* Embeding node #%d:\n", i);
62 xmlDebugDumpNode(stdout, node, 2);
67 xmlXPathFreeObject(result);
68 return 0;
72 int main(int argc, char **argv) {
73 struct isds_ctx *ctx = NULL;
74 isds_error err;
75 char *recipient = NULL;
76 xmlDocPtr xml = NULL;
77 struct isds_list *documents = NULL;
79 setlocale(LC_ALL, "");
81 err = isds_init();
82 if (err) {
83 printf("isds_init() failed: %s\n", isds_strerror(err));
84 exit(EXIT_FAILURE);
87 isds_set_logging(ILF_ALL & ~ILF_HTTP, ILL_ALL);
89 ctx = isds_ctx_create();
90 if (!ctx) {
91 printf("isds_ctx_create() failed");
94 err = isds_set_timeout(ctx, 10000);
95 if (err) {
96 printf("isds_set_timeout() failed: %s\n", isds_strerror(err));
99 err = isds_login(ctx, url, username(), password(), NULL, NULL);
100 if (err) {
101 printf("isds_login() failed: %s: %s\n", isds_strerror(err),
102 isds_long_message(ctx));
103 } else {
104 printf("Logged in :)\n");
108 if (argv[1] && argv[1][0]) {
109 recipient = strdup(argv[1]);
110 } else {
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);
127 recipient = strdup(
128 ((struct isds_DbOwnerInfo *)(boxes->data))->dbID);
130 } else {
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;
146 if (argc < 4) {
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",
152 basename(argv[0]));
153 exit(EXIT_FAILURE);
156 xml = xmlParseFile(argv[2]);
157 if (!xml) {
158 printf("Error while parsing `%s'\n", argv[1]);
159 exit(EXIT_FAILURE);
162 xpath_ctx = xmlXPathNewContext(xml);
163 if (!xpath_ctx) {
164 printf("Error while creating XPath context\n");
165 exit(EXIT_FAILURE);
168 for (int j = 3; j < argc; j++) {
169 printf("** Building XML document #%d:\n", j);
171 document = calloc(1, sizeof(*document));
172 if (!document) {
173 printf("Not enough memory\n");
174 exit(EXIT_FAILURE);
176 document->is_xml = 1;
177 document->dmMimeType = "text/xml";
178 if (prev_documents_item)
179 document->dmFileMetaType = FILEMETATYPE_ENCLOSURE;
180 else
181 document->dmFileMetaType = FILEMETATYPE_MAIN;
182 document->dmFileDescr = "in-line.xml";
184 if (xpath2nodelist(&document->xml_node_list, xpath_ctx,
185 BAD_CAST argv[j])) {
186 printf("Could not convert XPath result to node list: %s\n",
187 argv[j]);
188 exit(EXIT_FAILURE);
191 documents_item = calloc(1, sizeof(*documents_item));
192 if (!documents_item) {
193 printf("Not enough memory\n");
194 exit(EXIT_FAILURE);
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;
201 else {
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);
232 } else
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) {
241 if (item->data) {
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;
247 free(node);
248 node = next_node;
254 free(recipient);
255 xmlFreeDoc(xml);
258 err = isds_logout(ctx);
259 if (err) {
260 printf("isds_logout() failed: %s\n", isds_strerror(err));
264 err = isds_ctx_free(&ctx);
265 if (err) {
266 printf("isds_ctx_free() failed: %s\n", isds_strerror(err));
270 err = isds_cleanup();
271 if (err) {
272 printf("isds_cleanup() failed: %s\n", isds_strerror(err));
275 exit (EXIT_SUCCESS);