Implement Re-signISDSDocument
[libisds.git] / client / sendxmldoc.c
blobfad6141f07c1c9f37aa026314817ea49e35560f2
1 #define _XOPEN_SOURCE 500
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <locale.h>
5 #include <time.h>
6 #include <string.h>
7 #include <libgen.h>
8 #include <isds.h>
9 #include <libxml/parser.h>
10 #include <libxml/xpath.h>
11 #include <libxml/debugXML.h>
12 #include "common.h"
15 /* @node_list is pointer to by-function allocated weak copy of libxml node
16 * pointers list. *NULL means empty list. */
17 int xpath2nodelist(xmlNodePtr *node_list, xmlXPathContextPtr xpath_ctx, const xmlChar *xpath_expr) {
18 xmlXPathObjectPtr result = NULL;
19 xmlNodePtr node = NULL, prev_node = NULL;
21 if (!node_list || !xpath_ctx || !xpath_expr) return -1;
23 result = xmlXPathEvalExpression(xpath_expr, xpath_ctx);
24 if (!result) {
25 printf("Error while evaluating XPath expression `%s'\n", xpath_expr);
26 return -1;
29 if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
30 printf("Empty match, returning empty node list\n");
31 *node_list = NULL;
32 } else {
33 /* Convert node set to list of siblings */
34 for (int i = 0; i < result->nodesetval->nodeNr; i++) {
35 /* Make weak copy of the node */
36 node = malloc(sizeof(*node));
37 if (!node) {
38 fprintf(stderr, "Not enoungh memory\n");
39 xmlXPathFreeObject(result);
40 for (node = *node_list; node; node = node->next)
41 free(node);
42 *node_list = NULL;
43 return -1;
45 memcpy(node, result->nodesetval->nodeTab[i], sizeof(*node));
47 /* Add node to node_list */
48 node->prev = prev_node;
49 node->next = NULL;
50 if (prev_node)
51 prev_node->next = node;
52 else
53 *node_list = node;
54 prev_node = node;
56 /* Debug */
57 printf("* Embeding node #%d:\n", i);
58 xmlDebugDumpNode(stdout, node, 2);
63 xmlXPathFreeObject(result);
64 return 0;
68 int main(int argc, char **argv) {
69 struct isds_ctx *ctx = NULL;
70 isds_error err;
71 char *recipient = NULL;
72 xmlDocPtr xml = NULL;
73 struct isds_list *documents = NULL;
75 setlocale(LC_ALL, "");
77 err = isds_init();
78 if (err) {
79 printf("isds_init() failed: %s\n", isds_strerror(err));
80 exit(EXIT_FAILURE);
83 isds_set_logging(ILF_ALL & ~ILF_HTTP, ILL_ALL);
85 ctx = isds_ctx_create();
86 if (!ctx) {
87 printf("isds_ctx_create() failed");
90 err = isds_set_timeout(ctx, 10000);
91 if (err) {
92 printf("isds_set_timeout() failed: %s\n", isds_strerror(err));
95 err = isds_login(ctx, url, username(), password(), NULL, NULL);
96 if (err) {
97 printf("isds_login() failed: %s: %s\n", isds_strerror(err),
98 isds_long_message(ctx));
99 } else {
100 printf("Logged in :)\n");
104 if (argv[1] && argv[1][0]) {
105 recipient = strdup(argv[1]);
106 } else {
107 /* Find a recipient */
108 struct isds_list *boxes = NULL;
109 struct isds_DbOwnerInfo criteria;
110 isds_DbType criteria_db_type = DBTYPE_OVM;
111 memset(&criteria, 0, sizeof(criteria));
112 criteria.firmName = "Místní";
113 criteria.dbType = &criteria_db_type;
115 printf("Searching box with firm name `%s':\n", criteria.firmName);
116 err = isds_FindDataBox(ctx, &criteria, &boxes);
117 if (err == IE_SUCCESS || err == IE_2BIG) {
118 printf("isds_FindDataBox() succeeded:\n");
120 if (boxes && boxes->data) {
121 printf("Selected recipient:\n");
122 print_DbOwnerInfo(boxes->data);
123 recipient = strdup(
124 ((struct isds_DbOwnerInfo *)(boxes->data))->dbID);
126 } else {
127 printf("isds_FindDataBox() failed: %s: %s\n",
128 isds_strerror(err), isds_long_message(ctx));
131 isds_list_free(&boxes);
136 /* Create XML documents */
137 xmlXPathContextPtr xpath_ctx = NULL;
139 struct isds_document *document;
140 struct isds_list *documents_item, *prev_documents_item = NULL;
142 if (argc < 4) {
143 printf("Bad number of arguments\n");
144 printf("Usage: %s RECIPIENT XML_FILE XPATH_EXPRESSION...\n"
145 "Send a message with XML document defined by XPATH_EXPRESSION on XML_FILE\n"
146 "to RECIPIENT. If RECIPIENT is empty, send to random foubd one. If more\n"
147 "XPATH_EXPRESSIONS are specified creates XML document for each of them.\n",
148 basename(argv[0]));
149 exit(EXIT_FAILURE);
152 xml = xmlParseFile(argv[2]);
153 if (!xml) {
154 printf("Error while parsing `%s'\n", argv[1]);
155 exit(EXIT_FAILURE);
158 xpath_ctx = xmlXPathNewContext(xml);
159 if (!xpath_ctx) {
160 printf("Error while creating XPath context\n");
161 exit(EXIT_FAILURE);
164 for (int j = 3; j < argc; j++) {
165 printf("** Building XML document #%d:\n", j);
167 document = calloc(1, sizeof(*document));
168 if (!document) {
169 printf("Not enough memory\n");
170 exit(EXIT_FAILURE);
172 document->is_xml = 1;
173 document->dmMimeType = "text/xml";
174 if (prev_documents_item)
175 document->dmFileMetaType = FILEMETATYPE_ENCLOSURE;
176 else
177 document->dmFileMetaType = FILEMETATYPE_MAIN;
178 document->dmFileDescr = "in-line.xml";
180 if (xpath2nodelist(&document->xml_node_list, xpath_ctx,
181 BAD_CAST argv[j])) {
182 printf("Could not convert XPath result to node list: %s\n",
183 argv[j]);
184 exit(EXIT_FAILURE);
187 documents_item = calloc(1, sizeof(*documents_item));
188 if (!documents_item) {
189 printf("Not enough memory\n");
190 exit(EXIT_FAILURE);
193 documents_item->data = document,
194 documents_item->destructor = (void(*)(void**))isds_document_free;
195 if (!prev_documents_item)
196 documents = prev_documents_item = documents_item;
197 else {
198 prev_documents_item->next = documents_item;
199 prev_documents_item = documents_item;
203 xmlXPathFreeContext(xpath_ctx);
208 /* Send one message */
209 struct isds_message message;
210 memset(&message, 0, sizeof(message));
212 struct isds_envelope envelope;
213 memset(&envelope, 0, sizeof(envelope));
214 message.envelope = &envelope;
215 long int dmSenderOrgUnitNum = 42;
216 envelope.dmSenderOrgUnitNum = &dmSenderOrgUnitNum;
217 envelope.dmAnnotation = "XML documents";
218 envelope.dbIDRecipient = recipient;
220 message.documents = documents;
222 printf("Sending message to box ID `%s'\n", recipient);
223 err = isds_send_message(ctx, &message);
225 if (err == IE_SUCCESS){
226 printf("isds_send_message() succeeded: message ID = %s\n",
227 message.envelope->dmID);
228 } else
229 printf("isds_send_message() failed: "
230 "%s: %s\n", isds_strerror(err), isds_long_message(ctx));
234 /* Free document xml_node_lists because they are weak copies of nodes in
235 * message->xml and isds_document_free() does not free it. */
236 for (struct isds_list *item = documents; item; item = item->next) {
237 if (item->data) {
238 struct isds_document *document =
239 (struct isds_document *)item->data;
240 if (document->is_xml) {
241 for (xmlNodePtr node = document->xml_node_list; node;
242 node = node->next)
243 free(node);
248 free(recipient);
249 xmlFreeDoc(xml);
252 err = isds_logout(ctx);
253 if (err) {
254 printf("isds_logout() failed: %s\n", isds_strerror(err));
258 err = isds_ctx_free(&ctx);
259 if (err) {
260 printf("isds_ctx_free() failed: %s\n", isds_strerror(err));
264 err = isds_cleanup();
265 if (err) {
266 printf("isds_cleanup() failed: %s\n", isds_strerror(err));
269 exit (EXIT_SUCCESS);