Use isds_set_opt()
[shigofumi.git] / src / data.c
blobe077f55d28bbfb63071dae0c5d0b3f213c027806
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 <stdint.h>
8 #include <errno.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <isds.h>
13 #include <readline/readline.h>
15 #include "shigofumi.h"
17 void print_DbState(const long int state) {
18 switch(state) {
19 case DBSTATE_ACCESSIBLE: printf("ACCESSIBLE\n"); break;
20 case DBSTATE_TEMP_UNACCESSIBLE: printf("TEMP_UNACCESSIBLE\n"); break;
21 case DBSTATE_NOT_YET_ACCESSIBLE: printf("NOT_YET_ACCESSIBLE\n"); break;
22 case DBSTATE_PERM_UNACCESSIBLE: printf("PERM_UNACCESSIBLE\n"); break;
23 case DBSTATE_REMOVED: printf("REMOVED\n"); break;
24 default: printf("<unknown state %ld>\n", state);
28 void print_DbType(const long int *type) {
29 if (!type) printf("NULL\n");
30 else
31 switch(*type) {
32 case DBTYPE_FO: printf("FO\n"); break;
33 case DBTYPE_PFO: printf("PFO\n"); break;
34 case DBTYPE_PFO_ADVOK: printf("PFO_ADVOK\n"); break;
35 case DBTYPE_PFO_DANPOR: printf("PFO_DAPOR\n"); break;
36 case DBTYPE_PFO_INSSPR: printf("PFO_INSSPR\n"); break;
37 case DBTYPE_PO: printf("PO\n"); break;
38 case DBTYPE_PO_ZAK: printf("PO_ZAK\n"); break;
39 case DBTYPE_PO_REQ: printf("PO_REQ\n"); break;
40 case DBTYPE_OVM: printf("OVM\n"); break;
41 case DBTYPE_OVM_NOTAR: printf("OVM_NOTAR\n"); break;
42 case DBTYPE_OVM_EXEKUT: printf("OVM_EXEKUT\n"); break;
43 case DBTYPE_OVM_REQ: printf("OVM_REQ\n"); break;
44 default: printf("<unknown type %ld>\n", *type);
49 void print_UserType(const long int *type) {
50 if (!type) printf("NULL\n");
51 else
52 switch(*type) {
53 case USERTYPE_PRIMARY: printf("PRIMARY\n"); break;
54 case USERTYPE_ENTRUSTED: printf("ENTRUSTED\n"); break;
55 case USERTYPE_ADMINISTRATOR: printf("ADMINISTRATOR\n"); break;
56 case USERTYPE_OFFICIAL: printf("OFFICIAL\n"); break;
57 default: printf("<unknown type %ld>\n", *type);
62 void print_UserPrivils(const long int *privils) {
64 const char *priviledges[] = {
65 "READ_NON_PERSONAL",
66 "READ_ALL",
67 "CREATE_DM",
68 "VIEW_INFO",
69 "SEARCH_DB",
70 "OWNER_ADM",
71 "READ_VAULT",
72 "ERASE_VAULT"
74 const int priviledges_count = sizeof(priviledges)/sizeof(priviledges[0]);
76 if (!privils) printf("NULL\n");
77 else {
78 printf("%ld (", *privils);
80 for (int i = 0; i < priviledges_count; i++) {
81 if (*privils & (1<<i)) {
82 printf(
83 ((i + 1) == priviledges_count) ? "%s" : "%s|",
84 priviledges[i]);
88 printf(")\n");
93 void print_hash(const struct isds_hash *hash) {
94 if (!hash) {
95 printf("NULL\n");
96 return;
99 switch(hash->algorithm) {
100 case HASH_ALGORITHM_MD5: printf("MD5 "); break;
101 case HASH_ALGORITHM_SHA_1: printf("SHA-1 "); break;
102 case HASH_ALGORITHM_SHA_256: printf("SHA-256 "); break;
103 case HASH_ALGORITHM_SHA_512: printf("SHA-512 "); break;
104 default: printf("<Unknown hash algorithm %d> ", hash->algorithm);
105 break;
108 if (!hash->value) printf("<NULL>");
109 else
110 for (int i = 0; i < hash->length; i++) {
111 if (i > 0) printf(":");
112 printf("%02x", ((uint8_t *)(hash->value))[i]);
115 printf("\n");
119 void print_raw_type(const isds_raw_type type) {
120 switch(type) {
121 case RAWTYPE_INCOMING_MESSAGE:
122 printf("INCOMING_MESSAGE\n"); break;
123 case RAWTYPE_PLAIN_SIGNED_INCOMING_MESSAGE:
124 printf("PLAIN_SIGNED_INCOMING_MESSAGE\n"); break;
125 case RAWTYPE_CMS_SIGNED_INCOMING_MESSAGE:
126 printf("CMS_SIGNED_INCOMING_MESSAGE\n"); break;
127 case RAWTYPE_PLAIN_SIGNED_OUTGOING_MESSAGE:
128 printf("PLAIN_SIGNED_OUTGOING_MESSAGE\n"); break;
129 case RAWTYPE_CMS_SIGNED_OUTGOING_MESSAGE:
130 printf("CMS_SIGNED_OUTGOING_MESSAGE\n"); break;
131 case RAWTYPE_DELIVERYINFO:
132 printf("DELIVERYINFO\n"); break;
133 case RAWTYPE_PLAIN_SIGNED_DELIVERYINFO:
134 printf("PLAIN_SIGNED_DELIVERYINFO\n"); break;
135 case RAWTYPE_CMS_SIGNED_DELIVERYINFO:
136 printf("CMS_SIGNED_DELIVERYINFO\n"); break;
137 default:
138 printf("<Unknown raw type %d> ", type);
139 break;
144 void print_bool(const _Bool *boolean) {
145 printf("%s\n", (!boolean) ? "NULL" : ((*boolean)? "true" : "false") );
149 void print_longint(const long int *number) {
150 if (!number) printf("NULL\n");
151 else printf("%ld\n", *number);
155 void print_PersonName(const struct isds_PersonName *personName) {
156 printf("\tpersonName = ");
157 if (!personName) printf("NULL\n");
158 else {
159 printf("{\n");
160 printf("\t\tpnFirstName = %s\n", personName->pnFirstName);
161 printf("\t\tpnMiddleName = %s\n", personName->pnMiddleName);
162 printf("\t\tpnLastName = %s\n", personName->pnLastName);
163 printf("\t\tpnLastNameAtBirth = %s\n", personName->pnLastNameAtBirth);
164 printf("\t}\n");
169 void print_Address(const struct isds_Address *address) {
170 printf("\taddress = ");
171 if (!address) printf("NULL\n");
172 else {
173 printf("{\n");
174 printf("\t\tadCity = %s\n", address->adCity);
175 printf("\t\tadStreet = %s\n", address->adStreet);
176 printf("\t\tadNumberInStreet = %s\n", address->adNumberInStreet);
177 printf("\t\tadNumberInMunicipality = %s\n",
178 address->adNumberInMunicipality);
179 printf("\t\tadZipCode = %s\n", address->adZipCode);
180 printf("\t\tadState = %s\n", address->adState);
181 printf("\t}\n");
186 void print_date(const struct tm *date) {
187 if (!date) printf("NULL\n");
188 else printf("%s", asctime(date));
192 void print_DbOwnerInfo(const struct isds_DbOwnerInfo *info) {
193 printf("dbOwnerInfo = ");
195 if (!info) {
196 printf("NULL\n");
197 return;
200 printf("{\n");
201 printf("\tdbID = %s\n", info->dbID);
203 printf("\tdbType = ");
204 print_DbType((long int *) (info->dbType));
205 printf("\tic = %s\n", info->ic);
207 print_PersonName(info->personName);
209 printf("\tfirmName = %s\n", info->firmName);
211 printf("\tbirthInfo = ");
212 if (!info->birthInfo) printf("NULL\n");
213 else {
214 printf("{\n");
216 printf("\t\tbiDate = ");
217 print_date(info->birthInfo->biDate);
219 printf("\t\tbiCity = %s\n", info->birthInfo->biCity);
220 printf("\t\tbiCounty = %s\n", info->birthInfo->biCounty);
221 printf("\t\tbiState = %s\n", info->birthInfo->biState);
222 printf("\t}\n");
225 print_Address(info->address);
227 printf("\tnationality = %s\n", info->nationality);
228 printf("\temail = %s\n", info->email);
229 printf("\ttelNumber = %s\n", info->telNumber);
230 printf("\tidentifier = %s\n", info->identifier);
231 printf("\tregistryCode = %s\n", info->registryCode);
233 printf("\tdbState = ");
234 if (!info->dbState) printf("NULL\n");
235 else print_DbState(*(info->dbState));
237 printf("\tdbEffectiveOVM = ");
238 print_bool(info->dbEffectiveOVM);
240 printf("\tdbOpenAddressing = ");
241 print_bool(info->dbOpenAddressing);
243 printf("}\n");
248 void print_DbUserInfo(const struct isds_DbUserInfo *info) {
249 printf("dbUserInfo = ");
251 if (!info) {
252 printf("NULL\n");
253 return;
256 printf("{\n");
257 printf("\tuserID = %s\n", info->userID);
259 printf("\tuserType = ");
260 print_UserType((long int *) (info->userType));
262 printf("\tuserPrivils = ");
263 print_UserPrivils(info->userPrivils);
265 print_PersonName(info->personName);
266 print_Address(info->address);
268 printf("\tbiDate = ");
269 print_date(info->biDate);
271 printf("\tic = %s\n", info->ic);
272 printf("\tfirmName = %s\n", info->firmName);
274 printf("\tcaStreet = %s\n", info->caStreet);
275 printf("\tcaCity = %s\n", info->caCity);
276 printf("\tcaZipCode = %s\n", info->caZipCode);
278 printf("}\n");
282 void print_timeval(const struct timeval *time) {
283 struct tm broken;
284 char buffer[128];
286 if (!time) {
287 printf("NULL\n");
288 return;
291 if (!localtime_r(&(time->tv_sec), &broken)) goto error;
292 if (!strftime(buffer, sizeof(buffer)/sizeof(char), "%c", &broken))
293 goto error;
294 printf("%s, %ld us\n", buffer, time->tv_usec);
295 return;
297 error:
298 printf("<Error while formating>\n>");
299 return;
303 void print_event_type(const isds_event_type *type) {
304 if (!type) {
305 printf("NULL");
306 return;
308 switch (*type) {
309 case EVENT_UKNOWN: printf("UNKNOWN\n"); break;
310 case EVENT_ACCEPTED_BY_RECIPIENT:
311 printf("ACCEPTED_BY_RECIPIENT\n"); break;
312 case EVENT_ACCEPTED_BY_FICTION:
313 printf("DELIVERED_BY_FICTION\n"); break;
314 case EVENT_UNDELIVERABLE:
315 printf("UNDELIVERABLE\n"); break;
316 default: printf("<unknown type %d>\n", *type);
321 void print_events(const struct isds_list *events) {
322 const struct isds_list *item;
323 const struct isds_event *event;
325 if (!events) {
326 printf("NULL\n");
327 return;
330 printf("{\n");
332 for (item = events; item; item = item->next) {
333 event = (struct isds_event *) item->data;
334 printf("\t\t\tevent = ");
335 if (!event) printf("NULL");
336 else {
337 printf("{\n");
339 printf("\t\t\t\ttype = ");
340 print_event_type(event->type);
342 printf("\t\t\t\tdescription = %s\n", event->description);
344 printf("\t\t\t\ttime = ");
345 print_timeval(event->time);
347 printf("\t\t\t}\n");
351 printf("\t\t}\n");
355 void print_envelope(const struct isds_envelope *envelope) {
356 printf("\tenvelope = ");
358 if (!envelope) {
359 printf("NULL\n");
360 return;
362 printf("{\n");
364 printf("\t\tdmID = %s\n", envelope->dmID);
365 printf("\t\tdbIDSender = %s\n", envelope->dbIDSender);
366 printf("\t\tdmSender = %s\n", envelope->dmSender);
367 printf("\t\tdmSenderAddress = %s\n", envelope->dmSenderAddress);
368 printf("\t\tdmSenderType = ");
369 print_DbType(envelope->dmSenderType);
370 printf("\t\tdmRecipient = %s\n", envelope->dmRecipient);
371 printf("\t\tdmRecipientAddress = %s\n", envelope->dmRecipientAddress);
372 printf("\t\tdmAmbiguousRecipient = ");
373 print_bool(envelope->dmAmbiguousRecipient);
374 printf("\t\tdmType = %s\n", envelope->dmType);
376 printf("\t\tdmSenderOrgUnit = %s\n", envelope->dmSenderOrgUnit);
377 printf("\t\tdmSenderOrgUnitNum = ");
378 print_longint(envelope->dmSenderOrgUnitNum);
379 printf("\t\tdbIDRecipient = %s\n", envelope->dbIDRecipient);
380 printf("\t\tdmRecipientOrgUnit = %s\n", envelope->dmRecipientOrgUnit);
381 printf("\t\tdmRecipientOrgUnitNum = ");
382 print_longint(envelope->dmRecipientOrgUnitNum);
383 printf("\t\tdmToHands = %s\n", envelope->dmToHands);
384 printf("\t\tdmAnnotation = %s\n", envelope->dmAnnotation);
385 printf("\t\tdmRecipientRefNumber = %s\n", envelope->dmRecipientRefNumber);
386 printf("\t\tdmSenderRefNumber = %s\n", envelope->dmSenderRefNumber);
387 printf("\t\tdmRecipientIdent = %s\n", envelope->dmRecipientIdent);
388 printf("\t\tdmSenderIdent = %s\n", envelope->dmSenderIdent);
390 printf("\t\tdmLegalTitleLaw = ");
391 print_longint(envelope->dmLegalTitleLaw);
392 printf("\t\tdmLegalTitleYear = ");
393 print_longint(envelope->dmLegalTitleYear);
394 printf("\t\tdmLegalTitleSect = %s\n", envelope->dmLegalTitleSect);
395 printf("\t\tdmLegalTitlePar = %s\n", envelope->dmLegalTitlePar);
396 printf("\t\tdmLegalTitlePoint = %s\n", envelope->dmLegalTitlePoint);
398 printf("\t\tdmPersonalDelivery = ");
399 print_bool(envelope->dmPersonalDelivery);
400 printf("\t\tdmAllowSubstDelivery = ");
401 print_bool(envelope->dmAllowSubstDelivery);
402 printf("\t\tdmOVM = ");
403 print_bool(envelope->dmOVM);
405 printf("\t\tdmOrdinal = ");
406 if (!envelope->dmOrdinal) printf("NULL\n");
407 else printf("%lu\n", *(envelope->dmOrdinal));
409 printf("\t\tdmMessageStatus = ");
410 if (!envelope->dmMessageStatus) printf("NULL\n");
411 else
412 switch(*(envelope->dmMessageStatus)) {
413 case MESSAGESTATE_SENT: printf("SENT\n"); break;
414 case MESSAGESTATE_STAMPED: printf("STAMPED\n"); break;
415 case MESSAGESTATE_INFECTED: printf("INFECTED\n"); break;
416 case MESSAGESTATE_DELIVERED: printf("DELIVERED\n"); break;
417 case MESSAGESTATE_SUBSTITUTED: printf("SUBSTITUTED\n"); break;
418 case MESSAGESTATE_RECEIVED: printf("RECEIVED\n"); break;
419 case MESSAGESTATE_READ: printf("READ\n"); break;
420 case MESSAGESTATE_UNDELIVERABLE: printf("UNDELIVERABLE\n"); break;
421 case MESSAGESTATE_REMOVED: printf("REMOVED\n"); break;
422 case MESSAGESTATE_IN_SAFE: printf("IN_SAFE\n"); break;
423 default: printf("<unknown type %d>\n",
424 *(envelope->dmMessageStatus));
427 printf("\t\tdmAttachmentSize = ");
428 if (!envelope->dmAttachmentSize) printf("NULL\n");
429 else printf("%lu kB\n", *(envelope->dmAttachmentSize));
431 printf("\t\tdmDeliveryTime = ");
432 print_timeval(envelope->dmDeliveryTime);
434 printf("\t\tdmAcceptanceTime = ");
435 print_timeval(envelope->dmAcceptanceTime);
437 printf("\t\thash = ");
438 print_hash(envelope->hash);
440 printf("\t\ttimestamp = %p\n", envelope->timestamp);
441 printf("\t\ttimestamp_length = %zu\n", envelope->timestamp_length);
443 printf("\t\tevents = ");
444 print_events(envelope->events);
446 printf("\t}\n");
450 void print_document(const struct isds_document *document) {
451 printf("\t\tdocument = ");
453 if (!document) {
454 printf("NULL\n");
455 return;
457 printf("\{\n");
459 printf("\t\t\tdata = %p\n", document->data);
460 printf("\t\t\tdata_length = %zu\n", document->data_length);
461 printf("\t\t\tdmMimeType = %s\n", document->dmMimeType);
463 printf("\t\t\tdmFileMetaType = ");
464 switch(document->dmFileMetaType) {
465 case FILEMETATYPE_MAIN: printf("MAIN\n"); break;
466 case FILEMETATYPE_ENCLOSURE: printf("ENCLOSURE\n"); break;
467 case FILEMETATYPE_SIGNATURE: printf("SIGNATURE\n"); break;
468 case FILEMETATYPE_META: printf("META\n"); break;
469 default: printf("<unknown type %d>\n", document->dmFileMetaType);
472 printf("\t\t\tdmFileGuid = %s\n", document->dmFileGuid);
473 printf("\t\t\tdmUpFileGuid = %s\n", document->dmUpFileGuid);
474 printf("\t\t\tdmFileDescr = %s\n", document->dmFileDescr);
475 printf("\t\t\tdmFormat = %s\n", document->dmFormat);
476 printf("\t\t}\n");
480 void print_documents(const struct isds_list *documents) {
481 const struct isds_list *item;
483 printf("\tdocuments = ");
485 if (!documents) {
486 printf("NULL\n");
487 return;
489 printf("{\n");
491 for (item = documents; item; item = item->next) {
492 print_document((struct isds_document *) (item->data));
495 printf("\t}\n");
499 void print_message(const struct isds_message *message) {
500 printf("message = ");
502 if (!message) {
503 printf("NULL\n");
504 return;
507 printf("{\n");
509 printf("\traw = %p\n", message->raw);
510 printf("\traw_length = %zu\n", message->raw_length);
511 printf("\traw_type = ");
512 print_raw_type(message->raw_type);
513 print_envelope(message->envelope);
514 print_documents(message->documents);
516 printf("}\n");
519 void print_copies(const struct isds_list *copies) {
520 const struct isds_list *item;
521 struct isds_message_copy *copy;
523 printf("Copies = ");
524 if (!copies) {
525 printf("<NULL>\n");
526 return;
529 printf("{\n");
530 for (item = copies; item; item = item->next) {
531 copy = (struct isds_message_copy *) item->data;
532 printf("\tCopy = ");
534 if (!copy)
535 printf("<NULL>\n");
536 else {
537 printf("{\n");
538 printf("\t\tdbIDRecipient = %s\n", copy->dbIDRecipient);
539 printf("\t\tdmRecipientOrgUnit = %s\n", copy->dmRecipientOrgUnit);
541 printf("\t\tdmRecipientOrgUnitNum = ");
542 if (copy->dmRecipientOrgUnitNum)
543 printf("%ld\n", *copy->dmRecipientOrgUnitNum);
544 else
545 printf("<NULL>\n");
546 printf("\t\tdmToHands = %s\n", copy->dmToHands);
548 printf("\t\terror = %s\n", isds_strerror(copy->error));
549 printf("\t\tdmStatus = %s\n", copy->dmStatus);
550 printf("\t\tdmID = %s\n", copy->dmID);
551 printf("\t}\n");
554 printf("}\n");
558 void compare_hashes(const struct isds_hash *hash1,
559 const struct isds_hash *hash2) {
560 isds_error err;
562 printf("Comparing hashes... ");
563 err = isds_hash_cmp(hash1, hash2);
564 if (err == IE_SUCCESS)
565 printf("Hashes equal\n");
566 else if
567 (err == IE_NOTEQUAL) printf("Hashes differ\n");
568 else
569 printf("isds_hash_cmp() failed: %s\n", isds_strerror(err));
573 int progressbar(double upload_total, double upload_current,
574 double download_total, double download_current,
575 void *data) {
577 printf("Progress: upload %0f/%0f, download %0f/%0f, data=%p\n",
578 upload_current, upload_total, download_current, download_total,
579 data);
580 return 0;
584 /* Print formated header if locale-encoded value is defined.
585 * @header is locale encoded header name
586 * @value is locale encoded header value */
587 void print_header(const char *header, const char *value) {
588 if (value && *value) printf(_("%s: %s\n"), header, value);
592 /* Print formated header if boolean value is defined.
593 * @header is locale encoded header name */
594 void print_header_bool(const char *header, _Bool *value) {
595 if (value) print_header(header, (*value) ? _("Yes") : _("No"));
599 /* Print formated header if long int value is defined.
600 * @header is locale encoded header name */
601 void print_header_longint(const char *header, long int *value) {
602 if (value) printf(_("%s: %ld\n"), header, *value);
606 /* Print formated header if unsigned long int value is defined.
607 * @header is locale encoded header name */
608 void print_header_ulongint(const char *header, unsigned long int *value) {
609 if (value) printf(_("%s: %ld\n"), header, *value);
613 /* Print formated header if time value is defined.
614 * @header is locale encoded header name */
615 void print_header_timeval(const char *header, struct timeval *time) {
616 struct tm broken;
617 char buffer[128];
619 if (!time) return;
621 if (!localtime_r(&(time->tv_sec), &broken)) goto error;
622 if (!strftime(buffer, sizeof(buffer)/sizeof(char), "%c", &broken))
623 goto error;
625 if (!time->tv_usec)
626 printf(_("%s: %s\n"), header, buffer);
627 else if ((time->tv_usec % 1000) == 0)
628 printf(_("%s: %s, %ld ms\n"), header, buffer, time->tv_usec/1000);
629 else
630 printf(_("%s: %s, %ld us\n"), header, buffer, time->tv_usec);
632 return;
634 error:
635 printf(_("%s: <Error while formating time>\n"), header);
636 return;
640 /* Print formated header if UTF-9 value is defined.
641 * @header is locale encoded header name
642 * @value is UTF-8 encoded header value */
643 void print_header_utf8(const char *header, const char *value) {
644 char *value_locale;
646 if (!value) return;
648 value_locale = utf82locale(value);
649 print_header(header,
650 (value_locale) ?
651 value_locale :
652 _("<Error while converting value>"));
653 free(value_locale);
657 /* Print formated header and byte size.
658 * @header is locale encoded header name */
659 void print_header_size(const char *header, size_t size) {
660 char *buffer = NULL;
662 if (size < (1<<10))
663 shi_asprintf(&buffer, _("%zu B"), size);
664 else if (size < (1<<20))
665 shi_asprintf(&buffer, _("%0.2f KiB"), (float) size/(1<<10));
666 else
667 shi_asprintf(&buffer, _("%0.2f MiB"), (float) size/(1<<20));
669 print_header(header, buffer);
670 free(buffer);
674 /* Print formated header if long int KB size is defined.
675 * @header is locale encoded header name */
676 void print_header_kbsize(const char *header, const long int *size) {
677 char *buffer = NULL;
678 if (!size) return;
680 if (*size < 0)
681 shi_asprintf(&buffer, _("<Negative size>"));
682 else if (*size < (1000))
683 shi_asprintf(&buffer, _("%lu kB"), *size);
684 else
685 shi_asprintf(&buffer, _("%0.2f MB"), *size/1000.0);
687 print_header(header, buffer);
688 free(buffer);
692 static const char *DbType2string(const long int *type) {
693 if (!type) return NULL;
694 switch(*type) {
695 case DBTYPE_FO: return(_("Private individual"));
696 case DBTYPE_PFO: return(_("Self-employed individual"));
697 case DBTYPE_PFO_ADVOK: return(_("Lawyer"));
698 case DBTYPE_PFO_DANPOR: return(_("Tax advisor"));
699 case DBTYPE_PFO_INSSPR: return(_("Insolvency administrator"));
700 case DBTYPE_PO: return(_("Organisation"));
701 case DBTYPE_PO_ZAK: return(_("Organization based by law"));
702 case DBTYPE_PO_REQ: return(_("Organization based on request"));
703 case DBTYPE_OVM: return(_("Public authority"));
704 case DBTYPE_OVM_NOTAR: return(_("Notary"));
705 case DBTYPE_OVM_EXEKUT: return(_("Executor"));
706 case DBTYPE_OVM_REQ: return(_("Public authority based on request"));
707 default: return(_("<Unknown type>"));
712 static const char *UserType2string(const long int *type) {
713 if (!type) return NULL;
714 switch(*type) {
715 case USERTYPE_PRIMARY: return(_("Primary"));
716 case USERTYPE_ENTRUSTED: return(_("Entrusted"));
717 case USERTYPE_ADMINISTRATOR: return(_("Administrator"));
718 case USERTYPE_OFFICIAL: return(_("Official"));
719 default: return(_("<Unknown type>"));
724 /* Return formated user priviledges. Caller must free the string */
725 static char *UserPrivils2string(const long int *privils) {
727 const char *priviledges[] = {
728 N_("Read non-personal"),
729 N_("Read all"),
730 N_("Send and read sent"),
731 N_("List messages and read delivery details"),
732 N_("Search boxes"),
733 N_("Adminster her box"),
734 N_("Read from safe"),
735 N_("Delete from safe")
737 const int priviledges_count = sizeof(priviledges)/sizeof(priviledges[0]);
738 char *buffer = NULL, *new_buffer = NULL;
740 if (!privils) return NULL;
742 /*printf("%ld (", *privils);*/
744 for (int i = 0; i < priviledges_count; i++) {
745 if (*privils & (1<<i)) {
746 if ((*privils % (1<<i)))
747 shi_asprintf(&new_buffer, _("%s, %s"),
748 buffer, _(priviledges[i]));
749 else
750 shi_asprintf(&new_buffer, "%s", _(priviledges[i]));
752 if (!new_buffer) {
753 free(buffer);
754 return(strdup(_("<Error while formating priviledges>")));
757 free(buffer);
758 buffer = new_buffer;
759 new_buffer = NULL;
763 if (*privils >= (1<<priviledges_count)) {
764 if ((*privils % (1<<priviledges_count)))
765 shi_asprintf(&new_buffer, _("%s, %s"),
766 buffer, _("<Unknown priviledge>"));
767 else
768 shi_asprintf(&new_buffer, "%s", _("<Unknown priviledge>"));
770 if (!new_buffer) {
771 free(buffer);
772 return(strdup(_("<Error while formating priviledges>")));
775 free(buffer);
776 buffer = new_buffer;
777 new_buffer = NULL;
780 return buffer;
784 static const char *DmType2string(const char *type) {
785 if (!type) return NULL;
786 if (!strcmp(type, "V")) return(_("Public"));
787 else if (!strcmp(type, "K")) return(_("Commercial"));
788 else return(_("<Unknown type>"));
792 static const char DmType2flag(const char *type) {
793 if (!type) return ' ';
794 if (!strcmp(type, "V")) return('P');
795 else if (!strcmp(type, "K")) return('C');
796 else return('?');
800 static const char *DmMessageStatus2string(const isds_message_status *status) {
801 if (!status) return NULL;
802 switch(*status) {
803 case MESSAGESTATE_SENT: return(_("Sent"));
804 case MESSAGESTATE_STAMPED: return(_("Stamped"));
805 case MESSAGESTATE_INFECTED: return(_("Infected"));
806 case MESSAGESTATE_DELIVERED: return(_("Delivered ordinary"));
807 case MESSAGESTATE_SUBSTITUTED: return(_("Delivered substitutably"));
808 case MESSAGESTATE_RECEIVED: return(_("Accepted"));
809 case MESSAGESTATE_READ: return(_("Read"));
810 case MESSAGESTATE_UNDELIVERABLE: return(_("Undeliverable"));
811 case MESSAGESTATE_REMOVED: return(_("Deleted"));
812 case MESSAGESTATE_IN_SAFE: return(_("Stored in safe"));
813 default: return(_("<Unknown state>"));
818 static const char DmMessageStatus2flag(const isds_message_status *status) {
819 if (!status) return ' ';
820 switch(*status) {
821 case MESSAGESTATE_SENT: return('>');
822 case MESSAGESTATE_STAMPED: return('t');
823 case MESSAGESTATE_INFECTED: return('I');
824 case MESSAGESTATE_DELIVERED: return('N');
825 case MESSAGESTATE_SUBSTITUTED: return('n');
826 case MESSAGESTATE_RECEIVED: return('O');
827 case MESSAGESTATE_READ: return(' ');
828 case MESSAGESTATE_UNDELIVERABLE: return('!');
829 case MESSAGESTATE_REMOVED: return('D');
830 case MESSAGESTATE_IN_SAFE: return('S');
831 default: return('?');
836 /* Return timeval time formated into shortest string with respect to current
837 * time. Caller must free the string. */
838 static char *timeval2shortstring(const struct timeval *timeval) {
839 struct tm broken, current_broken;
840 time_t current_time;
841 char *buffer = NULL;
842 const size_t buffer_size = 16;
844 if (!timeval) return NULL;
846 buffer = malloc(buffer_size);
847 if (!buffer) goto error;
849 /* Get current time */
850 current_time = time(NULL);
851 if (current_time == (time_t) -1) goto error;
852 if (!localtime_r(&current_time, &current_broken)) goto error;
854 /* Get broken time */
855 if (!localtime_r(&(timeval->tv_sec), &broken)) goto error;
857 /* Select proper abbreviated string representation */
858 if (broken.tm_year == current_broken.tm_year &&
859 broken.tm_yday == current_broken.tm_yday) {
860 /* Minute resolution in the same day */
861 if (!strftime(buffer, buffer_size, _("%k:%M"), &broken))
862 goto error;
863 } else {
864 /* Otherwise mont and day */
865 if (!strftime(buffer, buffer_size, _("%b %d"), &broken))
866 goto error;
869 return buffer;
871 error:
872 free(buffer);
873 return strdup(_("<Error>"));
877 /* Formated Law Authorization if defined. You must free it. */
878 static char *envelope_law2string(const struct isds_envelope *envelope) {
879 char *output = NULL;
880 char *year_locale = NULL, *law_locale = NULL;
881 char *sect_locale = NULL, *par_locale = NULL, *point_locale = NULL;
883 if (!envelope ||
884 !(envelope->dmLegalTitleYear || envelope->dmLegalTitleLaw ||
885 envelope->dmLegalTitleSect || envelope->dmLegalTitlePar ||
886 envelope->dmLegalTitlePoint)
887 ) return NULL;
889 if (envelope->dmLegalTitleYear)
890 shi_asprintf(&year_locale, "%ld", *envelope->dmLegalTitleYear);
891 else
892 year_locale = strdup(_("?"));
894 if (envelope->dmLegalTitleLaw)
895 shi_asprintf(&law_locale, "%ld", *envelope->dmLegalTitleLaw);
896 else
897 law_locale = strdup(_("?"));
899 sect_locale = utf82locale(envelope->dmLegalTitleSect);
900 par_locale = utf82locale(envelope->dmLegalTitlePar);
901 point_locale = utf82locale(envelope->dmLegalTitlePoint);
903 if (point_locale)
904 shi_asprintf(&output, _("point %s, par. %s, sect. %s, %s/%s Coll."),
905 point_locale, par_locale, sect_locale,
906 law_locale, year_locale);
907 else if (par_locale)
908 shi_asprintf(&output, _("par. %s, sect. %s, %s/%s Coll."),
909 par_locale, sect_locale, law_locale, year_locale);
910 else if (sect_locale)
911 shi_asprintf(&output, _("sect. %s, %s/%s Coll."),
912 sect_locale, law_locale, year_locale);
913 else
914 shi_asprintf(&output, _("%s/%s Coll."),
915 law_locale, year_locale);
917 free(year_locale);
918 free(law_locale);
919 free(sect_locale);
920 free(par_locale);
921 free(point_locale);
922 return output;
926 /* Print formated header if time any of message ID.
927 * @header is locale encoded header name */
928 static void print_header_messages_ids(const char *header,
929 const char *ref_number, const char *ident) {
930 if (ref_number || ident) {
931 printf(_("%s:\n"), header);
932 print_header_utf8(_("\tReference number"), ref_number);
933 print_header_utf8(_("\tFile ID"), ident);
938 /* Return formated hash value */
939 char *hash2string(const struct isds_hash *hash) {
940 const char *algorithm_string = NULL;
941 char *buffer = NULL, *octet = NULL, *new_buffer = NULL;
943 if (!hash || !hash->value) return NULL;
945 switch(hash->algorithm) {
946 case HASH_ALGORITHM_MD5: algorithm_string = (_("MD5")); break;
947 case HASH_ALGORITHM_SHA_1: algorithm_string = (_("SHA-1")); break;
948 case HASH_ALGORITHM_SHA_224: algorithm_string = (_("SHA-224")); break;
949 case HASH_ALGORITHM_SHA_256: algorithm_string = (_("SHA-256")); break;
950 case HASH_ALGORITHM_SHA_384: algorithm_string = (_("SHA-384")); break;
951 case HASH_ALGORITHM_SHA_512: algorithm_string = (_("SHA-512")); break;
952 default: algorithm_string = (_("<Unknown hash algorithm>")); break;
955 for (int i = 0; i < hash->length; i++) {
956 shi_asprintf(&octet, "%02x", ((uint8_t *)(hash->value))[i]);
957 if (!octet) {
958 free(buffer); free(octet); return NULL;
961 if (i > 0)
962 shi_asprintf(&new_buffer, _("%s:%s"), buffer, octet);
963 else
964 shi_asprintf(&new_buffer, "%s", octet);
965 if (!new_buffer) {
966 free(buffer); free(octet); return NULL;
969 buffer = new_buffer; new_buffer = NULL;
972 shi_asprintf(&new_buffer, _("%s %s"), algorithm_string, buffer);
973 free(buffer);
975 return new_buffer;
979 /* Print if any message delivery info exists. */
980 void print_message_delivery_info(const struct isds_envelope *envelope) {
981 char *hash_string = NULL;
983 if (envelope && (envelope->dmType || envelope->dmMessageStatus ||
984 envelope->dmDeliveryTime ||
985 envelope->dmAcceptanceTime || envelope->dmPersonalDelivery ||
986 envelope->dmAllowSubstDelivery || envelope->hash ||
987 envelope->dmOrdinal)) {
988 printf(_("Delivery data:\n"));
989 print_header(_("\tMessage type"), DmType2string(envelope->dmType));
990 print_header(_("\tMessage status"),
991 DmMessageStatus2string(envelope->dmMessageStatus));
992 print_header_timeval(_("\tDelivered"), envelope->dmDeliveryTime);
993 print_header_timeval(_("\tAccepted"), envelope->dmAcceptanceTime);
994 print_header_bool(_("\tPersonal delivery required"),
995 envelope->dmPersonalDelivery);
996 print_header_bool(_("\tAllow substitutable delivery"),
997 envelope->dmAllowSubstDelivery);
999 hash_string = hash2string(envelope->hash);
1000 print_header(_("\tHash"), hash_string);
1001 free(hash_string);
1003 print_header_ulongint(_("\tOrdinal number"), envelope->dmOrdinal);
1008 static const char *event_type2string(const isds_event_type *type) {
1009 if (!type) return (_("<Undefined>"));
1011 switch (*type) {
1012 case EVENT_UKNOWN: return(_("Unknown"));
1013 case EVENT_ACCEPTED_BY_RECIPIENT:
1014 return(_("Accepted by recipient"));
1015 case EVENT_ACCEPTED_BY_FICTION:
1016 return(_("Delivered substitutably"));
1017 case EVENT_UNDELIVERABLE:
1018 return(_("Undeliverable"));
1019 default: return(_("<Unknown event type>"));
1024 /* Print if any delivery event exists. */
1025 void print_delivery_events(const struct isds_list *events) {
1026 int counter_width = 3;
1027 int order = 0;
1028 const struct isds_list *item;
1029 struct isds_event *event;
1031 if (!events) return;
1033 printf(_("Delivery events:\n"));
1035 for (item = events; item; item = item->next) {
1036 event = (struct isds_event *) item->data;
1037 if (!event) continue;
1038 order++;
1040 printf(_("%*d %s\n"), counter_width, order,
1041 event_type2string(event->type));
1042 print_header_utf8(_("\tDescription"), event->description);
1043 print_header_timeval(_("\tWhen"), event->time);
1048 /* Print formated message envelope */
1049 void format_envelope(const struct isds_envelope *envelope) {
1050 char *law_string = NULL;
1052 if (!envelope) {
1053 printf(_("<Missing envelope>\n"));
1054 return;
1057 print_header_utf8(_("Message ID"), envelope->dmID);
1059 if (envelope->dbIDSender || envelope->dmSender ||
1060 envelope->dmSenderOrgUnit || envelope->dmSenderOrgUnitNum ||
1061 envelope->dmSenderAddress || envelope->dmSenderType ||
1062 envelope->dmOVM) {
1063 printf(_("Sender:\n"));
1064 print_header_utf8(_("\tID"), envelope->dbIDSender);
1065 print_header_utf8(_("\tName"), envelope->dmSender);
1066 print_header_utf8(_("\tUnit"), envelope->dmSenderOrgUnit);
1067 print_header_longint(_("\tUnit number"), envelope->dmSenderOrgUnitNum);
1068 print_header_utf8(_("\tAddress"), envelope->dmSenderAddress);
1069 print_header(_("\tType"), DbType2string(envelope->dmSenderType));
1070 print_header_bool(_("\tAs public authority"), envelope->dmOVM);
1073 if (envelope->dbIDRecipient || envelope->dmRecipient ||
1074 envelope->dmRecipientOrgUnit || envelope->dmRecipientOrgUnitNum ||
1075 envelope->dmToHands || envelope->dmRecipientAddress ||
1076 envelope->dmAmbiguousRecipient) {
1077 printf(_("Recipient:\n"));
1078 print_header_utf8(_("\tID"), envelope->dbIDRecipient);
1079 print_header_utf8(_("\tName"), envelope->dmRecipient);
1080 print_header_utf8(_("\tUnit"), envelope->dmRecipientOrgUnit);
1081 print_header_longint(_("\tUnit number"),
1082 envelope->dmRecipientOrgUnitNum);
1083 print_header_utf8(_("To hands"), envelope->dmToHands);
1084 print_header_utf8(_("\tAddress"), envelope->dmRecipientAddress);
1085 print_header_bool(_("\tAs public authority"),
1086 envelope->dmAmbiguousRecipient);
1089 print_header_utf8(_("Subject"), envelope->dmAnnotation);
1091 print_header_messages_ids(_("Sender message IDs"),
1092 envelope->dmSenderRefNumber, envelope->dmSenderIdent);
1093 print_header_messages_ids(_("Recipient message IDs"),
1094 envelope->dmRecipientRefNumber, envelope->dmRecipientIdent);
1096 law_string = envelope_law2string(envelope);
1097 print_header(_("Law authorization"), law_string);
1098 free(law_string);
1100 print_message_delivery_info(envelope);
1102 print_header_kbsize(_("Document total size"), envelope->dmAttachmentSize);
1104 /*printf("\t\ttimestamp = %p\n", envelope->timestamp);
1105 printf("\t\ttimestamp_length = %zu\n", envelope->timestamp_length);*/
1106 print_delivery_events(envelope->events);
1110 const char *DmFileMetaType2string(isds_FileMetaType type) {
1111 switch(type) {
1112 case FILEMETATYPE_MAIN: return(_("Main document"));
1113 case FILEMETATYPE_ENCLOSURE: return(_("Enclosure"));
1114 case FILEMETATYPE_SIGNATURE: return(_("Signature"));
1115 case FILEMETATYPE_META: return(_("Meta document"));
1116 default: return(_("<unknown document type>"));
1121 /* Computes ordinar number of document identified by GUID
1122 * @documents is list of documents where to search
1123 * @id is UTF-8 encoded document ID refernce
1124 * Return allocated array of ordinar numbers terminated by -1. Normally only
1125 * one document with @id exists. However ISDS does not check this higher
1126 * requirments and can transport message with duplicate document identifiers.
1127 * Therefore this function returns array of ordinars. Return NULL if error
1128 * occures (e.g. memory insuficient). */
1129 static int *dmFileGuid2ordinar(const struct isds_list *documents,
1130 const char *id) {
1131 const struct isds_list *item;
1132 struct isds_document *document;
1133 size_t ordinars_length = 64, offset = 0;
1134 int *ordinars = NULL, *new_ordinars;
1135 int ordinar = 0;
1137 if (!documents || !id || !*id) return NULL;
1138 ordinars = malloc(ordinars_length * sizeof(*ordinars));
1139 if (!ordinars) return NULL;
1141 for (item = documents; item; item = item->next) {
1142 if (!item->data) continue;
1143 ordinar++;
1144 document = (struct isds_document *) (item->data);
1146 if (document->dmFileGuid && !strcmp(document->dmFileGuid, id)) {
1147 if (offset == ordinars_length) {
1148 /* Grow ordinars array */
1149 ordinars_length *= 2;
1150 new_ordinars = realloc(ordinars,
1151 ordinars_length * sizeof(*ordinars));
1152 if (!new_ordinars) {
1153 free(ordinars);
1154 return NULL;
1156 ordinars = new_ordinars;
1159 ordinars[offset++] = ordinar;
1163 ordinars[offset] = -1;
1164 return ordinars;
1168 /* @id is UTF-8 encoded GUID of refered document
1169 * @refernces is array of ordinar numbers if exist terminated by -1. Can be
1170 * NULL to signal error. */
1171 static void format_document_reference(char *id, int *references) {
1172 char *buffer = NULL, *new_buffer = NULL;
1173 if (!id) return;
1175 if (references && *references != -1) {
1176 for (; *references > 0; references++) {
1177 if (!buffer) {
1178 shi_asprintf(&new_buffer, _("%d"), *references);
1179 } else {
1180 shi_asprintf(&new_buffer, _("%s, %d"), buffer, *references);
1182 if (!new_buffer) {
1183 zfree(buffer);
1184 break;
1186 buffer = new_buffer;
1187 new_buffer = NULL;
1189 } else {
1190 char *id_locale = utf82locale(id);
1191 shi_asprintf(&buffer,
1192 _("<Reference to non-existing document ID `%s'>"), id_locale);
1193 free(id_locale);
1196 if (buffer)
1197 print_header(_("\tRefers to"), buffer);
1198 else
1199 print_header(_("\tRefers to"), _("<Error while formating reference>"));
1200 free(buffer);
1204 /* Print foramted document
1205 * @references is ordinar number of refered document. Formaly it's array
1206 * terminated by -1 because non-well-formed message can have more documents
1207 * with equal IDs */
1208 void format_document(const struct isds_document *document, int order,
1209 int *references) {
1210 int counter_width = 3;
1211 char *filename_locale = NULL;
1213 if (!document) return;
1215 printf(_("%*d "), counter_width, order);
1217 if (document->dmFileDescr) {
1218 filename_locale = utf82locale(document->dmFileDescr);
1219 printf("%s\n", filename_locale);
1220 free(filename_locale);
1221 } else {
1222 printf(_("<Unknown file name>\n"));
1225 print_header_size(_("\tSize"), document->data_length);
1226 print_header(_("\tMIME type"), document->dmMimeType);
1228 print_header(_("\tType"), DmFileMetaType2string(document->dmFileMetaType));
1229 print_header_utf8(_("\tMeta format"), document->dmFormat);
1231 print_header_utf8(_("\tID"), document->dmFileGuid);
1232 format_document_reference(document->dmUpFileGuid, references);
1236 /* Print formated message documents */
1237 void format_documents(const struct isds_list *documents) {
1238 const struct isds_list *item;
1239 const struct isds_document *document;
1240 int i = 0;
1241 int *references;
1242 if (!documents) return;
1244 printf(_("Documents:\n"));
1246 for (item = documents; item; item = item->next) {
1247 if (!item->data) continue;
1248 document = (struct isds_document *) item->data;
1249 references = dmFileGuid2ordinar(documents, document->dmUpFileGuid);
1250 format_document(document, ++i, references);
1251 free(references);
1256 /* Print formated message */
1257 void format_message(const struct isds_message *message) {
1258 if (!message) return;
1259 format_envelope(message->envelope);
1260 format_documents(message->documents);
1264 /* Print formated list of message copies */
1265 void format_copies(const struct isds_list *copies) {
1266 const struct isds_list *item;
1267 const struct isds_message_copy *copy;
1268 int i = 0;
1269 int counter_width = 3;
1270 if (!copies) return;
1272 for (item = copies; item; item = item->next) {
1273 if (!item->data) continue;
1274 copy = (struct isds_message_copy *) item->data;
1275 i++;
1277 printf(_("%*d Recipient:\n"), counter_width, i);
1278 print_header_utf8(_("\tID"), copy->dbIDRecipient);
1279 print_header_utf8(_("\tUnit"), copy->dmRecipientOrgUnit);
1280 print_header_longint(_("\tUnit number"), copy->dmRecipientOrgUnitNum);
1281 print_header_utf8(_("\tTo hands"), copy->dmToHands);
1286 void print_message_list(const struct isds_list *messages, _Bool outgoing) {
1287 const struct isds_list *item;
1288 struct isds_envelope *envelope;
1289 unsigned long int counter = 0;
1291 int counter_max, id_max = 0, name_max = 0, subject_max = 0;
1292 int counter_width, id_width = 0, flags_width = 2, time_width = 6,
1293 name_width = 0, subject_width = 0;
1295 char *id_locale = NULL, flags_locale[3], *time_locale = NULL,
1296 *name_locale = NULL, *subject_locale = NULL;
1297 int screen_cols;
1298 int width;
1301 /* Compute column widths */
1302 rl_get_screen_size(NULL, &screen_cols);
1304 /* Get real miximal widths */
1305 for (counter = 0, item = messages; item; item = item->next) {
1306 if (!item->data || !((struct isds_message *)item->data)->envelope)
1307 continue;
1308 envelope = ((struct isds_message *) item->data)->envelope;
1309 counter++;
1311 width = utf8width(envelope->dmID);
1312 if (width > id_max) id_max = width;
1314 width = utf8width((outgoing) ?
1315 envelope->dmRecipient : envelope->dmSender);
1316 if (width > name_max) name_max = width;
1318 width = utf8width(envelope->dmAnnotation);
1319 if (width > subject_max) subject_max = width;
1321 counter_max = numberwidth(counter);
1323 /* Correct widths to fit into window */
1324 if (counter_max < 0) counter_width = -3; else counter_width = counter_max;
1325 if (id_max < 0) id_width = -6; else id_width = id_max;
1326 if (name_max < 0) name_width = -20; else name_width = name_max;
1327 if (subject_max < 0) subject_width = -32; else subject_width = subject_max;
1329 width = abs(counter_width) + 1 + abs(id_width) + 1 + abs(flags_width) + 1 +
1330 abs(time_width) + 1 + abs(name_width) + 1 + abs(subject_width);
1331 if (width > screen_cols) {
1332 width -= abs(name_width) + abs(subject_width);
1334 name_width = subject_width = 0;
1335 while (width + name_width + subject_width < screen_cols) {
1336 if (name_width < abs(name_max)) name_width++;
1337 if (subject_width < abs(subject_max)) subject_width++;
1339 if (width + name_width + subject_width > screen_cols) subject_width--;
1342 /* Print header */
1343 fnprint(stdout, _("No"), counter_width);
1344 putchar(' ');
1345 fnprint(stdout, _("ID"), id_width);
1346 putchar(' ');
1347 fnprint(stdout, _("Flags"), flags_width);
1348 putchar(' ');
1349 fnprint(stdout, _("Delivered"), time_width);
1350 putchar(' ');
1351 fnprint(stdout, (outgoing) ? _("To") : _("From"), name_width);
1352 putchar(' ');
1353 fnprint(stdout, _("Subject"), subject_width);
1354 printf("\n");
1355 for (int i = 0; i < screen_cols; i++) printf(_("-"));
1356 printf("\n");
1358 /* Pring the list */
1359 for (counter = 0, item = messages; item; item = item->next) {
1360 envelope = ((struct isds_message *) item->data)->envelope;
1361 counter++;
1363 printf(_("%*lu "), counter_width, counter);
1365 if (!envelope) {
1366 printf(_("<Missing envelope>\n"));
1367 continue;
1370 id_locale = utf82locale(envelope->dmID);
1371 name_locale = utf82locale((outgoing) ?
1372 envelope->dmRecipient: envelope->dmSender);
1373 flags_locale[0] = DmType2flag(envelope->dmType);
1374 flags_locale[1] = DmMessageStatus2flag(envelope->dmMessageStatus);
1375 flags_locale[2] = '\0';
1376 time_locale = timeval2shortstring(envelope->dmDeliveryTime);
1377 subject_locale = utf82locale(envelope->dmAnnotation);
1379 fnprint(stdout, id_locale, id_width);
1380 putchar(' ');
1381 fnprint(stdout, flags_locale, flags_width);
1382 putchar(' ');
1383 fnprint(stdout, time_locale, time_width);
1384 putchar(' ');
1385 fnprint(stdout, name_locale, name_width);
1386 putchar(' ');
1387 fnprint(stdout, subject_locale, subject_width);
1388 printf("\n");
1390 zfree(id_locale);
1391 zfree(time_locale);
1392 zfree(name_locale);
1393 zfree(subject_locale);
1398 static void format_PersonName(const struct isds_PersonName *personName) {
1399 if (!personName) return;
1401 printf(_("Person name:\n"));
1402 print_header_utf8("\tFirst", personName->pnFirstName);
1403 print_header_utf8("\tMiddle", personName->pnMiddleName);
1404 print_header_utf8("\tLast", personName->pnLastName);
1405 print_header_utf8("\tLast at birth", personName->pnLastNameAtBirth);
1409 /* Return formated date as mallocated string. NULL or special error string can
1410 * be returned. Application must free even the error string. */
1411 char *tm2string(const struct tm *date) {
1412 char *buffer;
1413 size_t buffer_length = 128;
1415 if (!date) return NULL;
1417 buffer = malloc(buffer_length);
1418 if (!buffer) return strdup(_("<Error while formating date>"));
1420 if (0 == strftime(buffer, buffer_length, "%x", date)) {
1421 free(buffer);
1422 return strdup(_("<Error while formating date>"));
1425 return buffer;
1429 /* Convert string represantion of full ISO 8601 or locale date to tm structure.
1430 * Return NULL if error occures
1431 * XXX: Not all ISO formats are supported */
1432 struct tm *datestring2tm(const char *string) {
1433 struct tm *date = NULL;
1434 char *offset;
1435 if (!string) return NULL;
1437 date = calloc(1, sizeof(*date));
1438 if (!date) return NULL;
1440 /* xsd:date is ISO 8601 string, thus ASCII */
1441 offset = strptime(string, "%Y-%m-%d", date);
1442 if (offset && *offset == '\0')
1443 return date;
1445 offset = strptime(string, "%x", date);
1446 if (offset && *offset == '\0')
1447 return date;
1449 free(date);
1450 return NULL;
1454 static void format_BirthInfo(const struct isds_BirthInfo *birth) {
1455 char *date;
1456 if (!birth || !(birth->biDate || birth->biCity || birth->biCounty
1457 || birth->biState)) return;
1459 printf(_("Birth details:\n"));
1461 date = tm2string(birth->biDate);
1462 print_header(_("\tDate"), date);
1463 free(date);
1465 print_header_utf8(_("\tCity"), birth->biCity);
1466 print_header_utf8(_("\tCounty"), birth->biCounty);
1467 print_header_utf8(_("\tState"), birth->biState);
1471 static void format_Address(const struct isds_Address *address) {
1472 if (!address || !(address->adCity || address->adState ||
1473 address->adNumberInStreet || address->adNumberInMunicipality ||
1474 address->adZipCode || address->adState)) return;
1476 printf("Address:\n");
1477 print_header_utf8(_("\tCity"), address->adCity);
1478 print_header_utf8(_("\tStreet"), address->adStreet);
1479 print_header_utf8(_("\tNumber in street"), address->adNumberInStreet);
1480 print_header_utf8(_("\tNumber in municipality"),
1481 address->adNumberInMunicipality);
1482 print_header_utf8(_("\tZIP code"), address->adZipCode);
1483 print_header_utf8(_("\tState"), address->adState);
1487 /* Return static box state string or NULL if undefined */
1488 const char *DbState2string(const long int *state) {
1489 if (!state) return NULL;
1491 switch(*state) {
1492 case DBSTATE_ACCESSIBLE: return(_("Accessible"));
1493 case DBSTATE_TEMP_UNACCESSIBLE: return(_("Temporary unaccessible"));
1494 case DBSTATE_NOT_YET_ACCESSIBLE: return(_("Not yet accessible"));
1495 case DBSTATE_PERM_UNACCESSIBLE: return(_("Permanently unaccessible"));
1496 case DBSTATE_REMOVED: return(_("Deleted"));
1497 default: return(_("<unknown state>"));
1502 void format_DbOwnerInfo(const struct isds_DbOwnerInfo *info) {
1503 if (!info) return;
1505 print_header_utf8(_("Box ID"), info->dbID);
1506 print_header(_("Type"), DbType2string((long int *) (info->dbType)));
1507 print_header_utf8(_("Subject name"), info->firmName);
1508 print_header_utf8(_("Identity number"), info->ic);
1510 format_PersonName(info->personName);
1511 format_BirthInfo(info->birthInfo);
1513 format_Address(info->address);
1515 print_header_utf8(_("Nationality"), info->nationality);
1516 print_header_utf8(_("E-mail"), info->email);
1517 print_header_utf8(_("Phone"), info->telNumber);
1519 print_header_utf8(_("Identifier"), info->identifier);
1520 print_header_utf8(_("Registry code"), info->registryCode);
1522 print_header(_("State"), DbState2string(info->dbState));
1523 print_header_bool(_("Act as public authority"), info->dbEffectiveOVM);
1524 print_header_bool(_("Receive commercial messages"),
1525 info->dbOpenAddressing);
1529 static void format_supervising_firm(const char *ic, const char *firmName) {
1530 if (!ic && !firmName) return;
1532 printf(_("Supervising subject:\n"));
1533 print_header_utf8(_("\tIdentity number"), ic);
1534 print_header_utf8(_("\tName"), firmName);
1538 static void format_contact_address(const char *caStreet, const char *caCity,
1539 const char *caZipCode, const char *caState) {
1540 if (!caStreet && !caCity && !caZipCode) return;
1542 printf(_("Contact address:\n"));
1543 print_header_utf8(_("\tStreet"), caStreet);
1544 print_header_utf8(_("\tCity"), caCity);
1545 print_header_utf8(_("\tZIP code"), caZipCode);
1546 print_header_utf8(_("\tState"), caState);
1550 void format_DbUserInfo(const struct isds_DbUserInfo *info) {
1551 char *buffer;
1553 if (!info) return;
1555 print_header_utf8(_("User ID"), info->userID);
1556 print_header(_("Type"), UserType2string((long int *) (info->userType)));
1558 buffer = UserPrivils2string(info->userPrivils);
1559 print_header(_("Priviledges"), buffer);
1560 zfree(buffer);
1562 format_PersonName(info->personName);
1563 format_Address(info->address);
1565 buffer = tm2string(info->biDate);
1566 print_header(_("Birth date"), buffer);
1567 zfree(buffer);
1569 format_supervising_firm(info->ic, info->firmName);
1570 format_contact_address(info->caStreet, info->caCity, info->caZipCode,
1571 info->caState);