Adapt to OpenSSL 1.1.0
[libisds.git] / client / sendxmldoc.c
blobf4b44488711410809a99d9ea93a3ea877977bafe
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 enoungh memory\n");
40 xmlXPathFreeObject(result);
41 for (node = *node_list; node; node = node->next)
42 free(node);
43 *node_list = NULL;
44 return -1;
46 memcpy(node, result->nodesetval->nodeTab[i], sizeof(*node));
48 /* Add node to node_list */
49 node->prev = prev_node;
50 node->next = NULL;
51 if (prev_node)
52 prev_node->next = node;
53 else
54 *node_list = node;
55 prev_node = node;
57 /* Debug */
58 printf("* Embeding node #%d:\n", i);
59 xmlDebugDumpNode(stdout, node, 2);
64 xmlXPathFreeObject(result);
65 return 0;
69 int main(int argc, char **argv) {
70 struct isds_ctx *ctx = NULL;
71 isds_error err;
72 char *recipient = NULL;
73 xmlDocPtr xml = NULL;
74 struct isds_list *documents = NULL;
76 setlocale(LC_ALL, "");
78 err = isds_init();
79 if (err) {
80 printf("isds_init() failed: %s\n", isds_strerror(err));
81 exit(EXIT_FAILURE);
84 isds_set_logging(ILF_ALL & ~ILF_HTTP, ILL_ALL);
86 ctx = isds_ctx_create();
87 if (!ctx) {
88 printf("isds_ctx_create() failed");
91 err = isds_set_timeout(ctx, 10000);
92 if (err) {
93 printf("isds_set_timeout() failed: %s\n", isds_strerror(err));
96 err = isds_login(ctx, url, username(), password(), NULL, NULL);
97 if (err) {
98 printf("isds_login() failed: %s: %s\n", isds_strerror(err),
99 isds_long_message(ctx));
100 } else {
101 printf("Logged in :)\n");
105 if (argv[1] && argv[1][0]) {
106 recipient = strdup(argv[1]);
107 } else {
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);
124 recipient = strdup(
125 ((struct isds_DbOwnerInfo *)(boxes->data))->dbID);
127 } else {
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;
143 if (argc < 4) {
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",
149 basename(argv[0]));
150 exit(EXIT_FAILURE);
153 xml = xmlParseFile(argv[2]);
154 if (!xml) {
155 printf("Error while parsing `%s'\n", argv[1]);
156 exit(EXIT_FAILURE);
159 xpath_ctx = xmlXPathNewContext(xml);
160 if (!xpath_ctx) {
161 printf("Error while creating XPath context\n");
162 exit(EXIT_FAILURE);
165 for (int j = 3; j < argc; j++) {
166 printf("** Building XML document #%d:\n", j);
168 document = calloc(1, sizeof(*document));
169 if (!document) {
170 printf("Not enough memory\n");
171 exit(EXIT_FAILURE);
173 document->is_xml = 1;
174 document->dmMimeType = "text/xml";
175 if (prev_documents_item)
176 document->dmFileMetaType = FILEMETATYPE_ENCLOSURE;
177 else
178 document->dmFileMetaType = FILEMETATYPE_MAIN;
179 document->dmFileDescr = "in-line.xml";
181 if (xpath2nodelist(&document->xml_node_list, xpath_ctx,
182 BAD_CAST argv[j])) {
183 printf("Could not convert XPath result to node list: %s\n",
184 argv[j]);
185 exit(EXIT_FAILURE);
188 documents_item = calloc(1, sizeof(*documents_item));
189 if (!documents_item) {
190 printf("Not enough memory\n");
191 exit(EXIT_FAILURE);
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;
198 else {
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);
229 } else
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) {
238 if (item->data) {
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;
243 node = node->next)
244 free(node);
249 free(recipient);
250 xmlFreeDoc(xml);
253 err = isds_logout(ctx);
254 if (err) {
255 printf("isds_logout() failed: %s\n", isds_strerror(err));
259 err = isds_ctx_free(&ctx);
260 if (err) {
261 printf("isds_ctx_free() failed: %s\n", isds_strerror(err));
265 err = isds_cleanup();
266 if (err) {
267 printf("isds_cleanup() failed: %s\n", isds_strerror(err));
270 exit (EXIT_SUCCESS);