1 #define _XOPEN_SOURCE 500
12 #include <readline/readline.h>
14 #include "shigofumi.h"
17 void print_DbState(const long int state
) {
19 case DBSTATE_ACCESSIBLE
: oprintf("ACCESSIBLE\n"); break;
20 case DBSTATE_TEMP_UNACCESSIBLE
: oprintf("TEMP_UNACCESSIBLE\n"); break;
21 case DBSTATE_NOT_YET_ACCESSIBLE
: oprintf("NOT_YET_ACCESSIBLE\n"); break;
22 case DBSTATE_PERM_UNACCESSIBLE
: oprintf("PERM_UNACCESSIBLE\n"); break;
23 case DBSTATE_REMOVED
: oprintf("REMOVED\n"); break;
24 default: oprintf("<unknown state %ld>\n", state
);
28 void print_DbType(const long int *type
) {
29 if (!type
) oprintf("NULL\n");
32 case DBTYPE_SYSTEM
: oprintf("SYSTEM\n"); break;
33 case DBTYPE_FO
: oprintf("FO\n"); break;
34 case DBTYPE_PFO
: oprintf("PFO\n"); break;
35 case DBTYPE_PFO_ADVOK
: oprintf("PFO_ADVOK\n"); break;
36 case DBTYPE_PFO_DANPOR
: oprintf("PFO_DAPOR\n"); break;
37 case DBTYPE_PFO_INSSPR
: oprintf("PFO_INSSPR\n"); break;
38 case DBTYPE_PO
: oprintf("PO\n"); break;
39 case DBTYPE_PO_ZAK
: oprintf("PO_ZAK\n"); break;
40 case DBTYPE_PO_REQ
: oprintf("PO_REQ\n"); break;
41 case DBTYPE_OVM
: oprintf("OVM\n"); break;
42 case DBTYPE_OVM_NOTAR
: oprintf("OVM_NOTAR\n"); break;
43 case DBTYPE_OVM_EXEKUT
: oprintf("OVM_EXEKUT\n"); break;
44 case DBTYPE_OVM_REQ
: oprintf("OVM_REQ\n"); break;
45 default: oprintf("<unknown type %ld>\n", *type
);
50 void print_UserType(const long int *type
) {
51 if (!type
) oprintf("NULL\n");
54 case USERTYPE_PRIMARY
: oprintf("PRIMARY\n"); break;
55 case USERTYPE_ENTRUSTED
: oprintf("ENTRUSTED\n"); break;
56 case USERTYPE_ADMINISTRATOR
: oprintf("ADMINISTRATOR\n"); break;
57 case USERTYPE_OFFICIAL
: oprintf("OFFICIAL\n"); break;
58 default: oprintf("<unknown type %ld>\n", *type
);
63 void print_UserPrivils(const long int *privils
) {
65 const char *priviledges
[] = {
75 const int priviledges_count
= sizeof(priviledges
)/sizeof(priviledges
[0]);
77 if (!privils
) oprintf("NULL\n");
79 oprintf("%ld (", *privils
);
81 for (int i
= 0; i
< priviledges_count
; i
++) {
82 if (*privils
& (1<<i
)) {
84 ((i
+ 1) == priviledges_count
) ? "%s" : "%s|",
94 void print_hash(const struct isds_hash
*hash
) {
100 switch(hash
->algorithm
) {
101 case HASH_ALGORITHM_MD5
: oprintf("MD5 "); break;
102 case HASH_ALGORITHM_SHA_1
: oprintf("SHA-1 "); break;
103 case HASH_ALGORITHM_SHA_256
: oprintf("SHA-256 "); break;
104 case HASH_ALGORITHM_SHA_512
: oprintf("SHA-512 "); break;
105 default: oprintf("<Unknown hash algorithm %d> ", hash
->algorithm
);
109 if (!hash
->value
) oprintf("<NULL>");
111 for (int i
= 0; i
< hash
->length
; i
++) {
112 if (i
> 0) oprintf(":");
113 oprintf("%02x", ((uint8_t *)(hash
->value
))[i
]);
120 void print_raw_type(const isds_raw_type type
) {
122 case RAWTYPE_INCOMING_MESSAGE
:
123 oprintf("INCOMING_MESSAGE\n"); break;
124 case RAWTYPE_PLAIN_SIGNED_INCOMING_MESSAGE
:
125 oprintf("PLAIN_SIGNED_INCOMING_MESSAGE\n"); break;
126 case RAWTYPE_CMS_SIGNED_INCOMING_MESSAGE
:
127 oprintf("CMS_SIGNED_INCOMING_MESSAGE\n"); break;
128 case RAWTYPE_PLAIN_SIGNED_OUTGOING_MESSAGE
:
129 oprintf("PLAIN_SIGNED_OUTGOING_MESSAGE\n"); break;
130 case RAWTYPE_CMS_SIGNED_OUTGOING_MESSAGE
:
131 oprintf("CMS_SIGNED_OUTGOING_MESSAGE\n"); break;
132 case RAWTYPE_DELIVERYINFO
:
133 oprintf("DELIVERYINFO\n"); break;
134 case RAWTYPE_PLAIN_SIGNED_DELIVERYINFO
:
135 oprintf("PLAIN_SIGNED_DELIVERYINFO\n"); break;
136 case RAWTYPE_CMS_SIGNED_DELIVERYINFO
:
137 oprintf("CMS_SIGNED_DELIVERYINFO\n"); break;
139 oprintf("<Unknown raw type %d> ", type
);
145 void print_bool(const _Bool
*boolean
) {
146 oprintf("%s\n", (!boolean
) ? "NULL" : ((*boolean
)? "true" : "false") );
150 void print_longint(const long int *number
) {
151 if (!number
) oprintf("NULL\n");
152 else oprintf("%ld\n", *number
);
156 void print_PersonName(const struct isds_PersonName
*personName
) {
157 oprintf("\tpersonName = ");
158 if (!personName
) oprintf("NULL\n");
161 oprintf("\t\tpnFirstName = %s\n", personName
->pnFirstName
);
162 oprintf("\t\tpnMiddleName = %s\n", personName
->pnMiddleName
);
163 oprintf("\t\tpnLastName = %s\n", personName
->pnLastName
);
164 oprintf("\t\tpnLastNameAtBirth = %s\n", personName
->pnLastNameAtBirth
);
170 void print_Address(const struct isds_Address
*address
) {
171 oprintf("\taddress = ");
172 if (!address
) oprintf("NULL\n");
175 oprintf("\t\tadCity = %s\n", address
->adCity
);
176 oprintf("\t\tadStreet = %s\n", address
->adStreet
);
177 oprintf("\t\tadNumberInStreet = %s\n", address
->adNumberInStreet
);
178 oprintf("\t\tadNumberInMunicipality = %s\n",
179 address
->adNumberInMunicipality
);
180 oprintf("\t\tadZipCode = %s\n", address
->adZipCode
);
181 oprintf("\t\tadState = %s\n", address
->adState
);
187 void print_date(const struct tm
*date
) {
188 if (!date
) oprintf("NULL\n");
189 else oprintf("%s", asctime(date
));
193 void print_DbOwnerInfo(const struct isds_DbOwnerInfo
*info
) {
194 oprintf("dbOwnerInfo = ");
202 oprintf("\tdbID = %s\n", info
->dbID
);
204 oprintf("\tdbType = ");
205 print_DbType((long int *) (info
->dbType
));
206 oprintf("\tic = %s\n", info
->ic
);
208 print_PersonName(info
->personName
);
210 oprintf("\tfirmName = %s\n", info
->firmName
);
212 oprintf("\tbirthInfo = ");
213 if (!info
->birthInfo
) oprintf("NULL\n");
217 oprintf("\t\tbiDate = ");
218 print_date(info
->birthInfo
->biDate
);
220 oprintf("\t\tbiCity = %s\n", info
->birthInfo
->biCity
);
221 oprintf("\t\tbiCounty = %s\n", info
->birthInfo
->biCounty
);
222 oprintf("\t\tbiState = %s\n", info
->birthInfo
->biState
);
226 print_Address(info
->address
);
228 oprintf("\tnationality = %s\n", info
->nationality
);
229 oprintf("\temail = %s\n", info
->email
);
230 oprintf("\ttelNumber = %s\n", info
->telNumber
);
231 oprintf("\tidentifier = %s\n", info
->identifier
);
232 oprintf("\tregistryCode = %s\n", info
->registryCode
);
234 oprintf("\tdbState = ");
235 if (!info
->dbState
) oprintf("NULL\n");
236 else print_DbState(*(info
->dbState
));
238 oprintf("\tdbEffectiveOVM = ");
239 print_bool(info
->dbEffectiveOVM
);
241 oprintf("\tdbOpenAddressing = ");
242 print_bool(info
->dbOpenAddressing
);
249 void print_DbUserInfo(const struct isds_DbUserInfo
*info
) {
250 oprintf("dbUserInfo = ");
258 oprintf("\tuserID = %s\n", info
->userID
);
260 oprintf("\tuserType = ");
261 print_UserType((long int *) (info
->userType
));
263 oprintf("\tuserPrivils = ");
264 print_UserPrivils(info
->userPrivils
);
266 print_PersonName(info
->personName
);
267 print_Address(info
->address
);
269 oprintf("\tbiDate = ");
270 print_date(info
->biDate
);
272 oprintf("\tic = %s\n", info
->ic
);
273 oprintf("\tfirmName = %s\n", info
->firmName
);
275 oprintf("\tcaStreet = %s\n", info
->caStreet
);
276 oprintf("\tcaCity = %s\n", info
->caCity
);
277 oprintf("\tcaZipCode = %s\n", info
->caZipCode
);
283 void print_timeval(const struct timeval
*time
) {
292 if (!localtime_r(&(time
->tv_sec
), &broken
)) goto error
;
293 if (!strftime(buffer
, sizeof(buffer
)/sizeof(char), "%c", &broken
))
295 oprintf("%s, %ld us\n", buffer
, time
->tv_usec
);
299 oprintf("<Error while formatting>\n>");
304 void print_event_type(const isds_event_type
*type
) {
310 case EVENT_UKNOWN
: oprintf("UNKNOWN\n"); break;
311 case EVENT_ACCEPTED_BY_RECIPIENT
:
312 oprintf("ACCEPTED_BY_RECIPIENT\n"); break;
313 case EVENT_ACCEPTED_BY_FICTION
:
314 oprintf("DELIVERED_BY_FICTION\n"); break;
315 case EVENT_UNDELIVERABLE
:
316 oprintf("UNDELIVERABLE\n"); break;
317 default: oprintf("<unknown type %d>\n", *type
);
322 void print_events(const struct isds_list
*events
) {
323 const struct isds_list
*item
;
324 const struct isds_event
*event
;
333 for (item
= events
; item
; item
= item
->next
) {
334 event
= (struct isds_event
*) item
->data
;
335 oprintf("\t\t\tevent = ");
336 if (!event
) oprintf("NULL");
340 oprintf("\t\t\t\ttype = ");
341 print_event_type(event
->type
);
343 oprintf("\t\t\t\tdescription = %s\n", event
->description
);
345 oprintf("\t\t\t\ttime = ");
346 print_timeval(event
->time
);
348 oprintf("\t\t\t}\n");
356 void print_envelope(const struct isds_envelope
*envelope
) {
357 oprintf("\tenvelope = ");
365 oprintf("\t\tdmID = %s\n", envelope
->dmID
);
366 oprintf("\t\tdbIDSender = %s\n", envelope
->dbIDSender
);
367 oprintf("\t\tdmSender = %s\n", envelope
->dmSender
);
368 oprintf("\t\tdmSenderAddress = %s\n", envelope
->dmSenderAddress
);
369 oprintf("\t\tdmSenderType = ");
370 print_DbType(envelope
->dmSenderType
);
371 oprintf("\t\tdmRecipient = %s\n", envelope
->dmRecipient
);
372 oprintf("\t\tdmRecipientAddress = %s\n", envelope
->dmRecipientAddress
);
373 oprintf("\t\tdmAmbiguousRecipient = ");
374 print_bool(envelope
->dmAmbiguousRecipient
);
375 oprintf("\t\tdmType = %s\n", envelope
->dmType
);
377 oprintf("\t\tdmSenderOrgUnit = %s\n", envelope
->dmSenderOrgUnit
);
378 oprintf("\t\tdmSenderOrgUnitNum = ");
379 print_longint(envelope
->dmSenderOrgUnitNum
);
380 oprintf("\t\tdbIDRecipient = %s\n", envelope
->dbIDRecipient
);
381 oprintf("\t\tdmRecipientOrgUnit = %s\n", envelope
->dmRecipientOrgUnit
);
382 oprintf("\t\tdmRecipientOrgUnitNum = ");
383 print_longint(envelope
->dmRecipientOrgUnitNum
);
384 oprintf("\t\tdmToHands = %s\n", envelope
->dmToHands
);
385 oprintf("\t\tdmAnnotation = %s\n", envelope
->dmAnnotation
);
386 oprintf("\t\tdmRecipientRefNumber = %s\n", envelope
->dmRecipientRefNumber
);
387 oprintf("\t\tdmSenderRefNumber = %s\n", envelope
->dmSenderRefNumber
);
388 oprintf("\t\tdmRecipientIdent = %s\n", envelope
->dmRecipientIdent
);
389 oprintf("\t\tdmSenderIdent = %s\n", envelope
->dmSenderIdent
);
391 oprintf("\t\tdmLegalTitleLaw = ");
392 print_longint(envelope
->dmLegalTitleLaw
);
393 oprintf("\t\tdmLegalTitleYear = ");
394 print_longint(envelope
->dmLegalTitleYear
);
395 oprintf("\t\tdmLegalTitleSect = %s\n", envelope
->dmLegalTitleSect
);
396 oprintf("\t\tdmLegalTitlePar = %s\n", envelope
->dmLegalTitlePar
);
397 oprintf("\t\tdmLegalTitlePoint = %s\n", envelope
->dmLegalTitlePoint
);
399 oprintf("\t\tdmPersonalDelivery = ");
400 print_bool(envelope
->dmPersonalDelivery
);
401 oprintf("\t\tdmAllowSubstDelivery = ");
402 print_bool(envelope
->dmAllowSubstDelivery
);
403 oprintf("\t\tdmOVM = ");
404 print_bool(envelope
->dmOVM
);
406 oprintf("\t\tdmOrdinal = ");
407 if (!envelope
->dmOrdinal
) oprintf("NULL\n");
408 else oprintf("%lu\n", *(envelope
->dmOrdinal
));
410 oprintf("\t\tdmMessageStatus = ");
411 if (!envelope
->dmMessageStatus
) oprintf("NULL\n");
413 switch(*(envelope
->dmMessageStatus
)) {
414 case MESSAGESTATE_SENT
: oprintf("SENT\n"); break;
415 case MESSAGESTATE_STAMPED
: oprintf("STAMPED\n"); break;
416 case MESSAGESTATE_INFECTED
: oprintf("INFECTED\n"); break;
417 case MESSAGESTATE_DELIVERED
: oprintf("DELIVERED\n"); break;
418 case MESSAGESTATE_SUBSTITUTED
: oprintf("SUBSTITUTED\n"); break;
419 case MESSAGESTATE_RECEIVED
: oprintf("RECEIVED\n"); break;
420 case MESSAGESTATE_READ
: oprintf("READ\n"); break;
421 case MESSAGESTATE_UNDELIVERABLE
: oprintf("UNDELIVERABLE\n"); break;
422 case MESSAGESTATE_REMOVED
: oprintf("REMOVED\n"); break;
423 case MESSAGESTATE_IN_SAFE
: oprintf("IN_SAFE\n"); break;
424 default: oprintf("<unknown type %d>\n",
425 *(envelope
->dmMessageStatus
));
428 oprintf("\t\tdmAttachmentSize = ");
429 if (!envelope
->dmAttachmentSize
) oprintf("NULL\n");
430 else oprintf("%lu kB\n", *(envelope
->dmAttachmentSize
));
432 oprintf("\t\tdmDeliveryTime = ");
433 print_timeval(envelope
->dmDeliveryTime
);
435 oprintf("\t\tdmAcceptanceTime = ");
436 print_timeval(envelope
->dmAcceptanceTime
);
438 oprintf("\t\thash = ");
439 print_hash(envelope
->hash
);
441 oprintf("\t\ttimestamp = %p\n", envelope
->timestamp
);
442 oprintf("\t\ttimestamp_length = %zu\n", envelope
->timestamp_length
);
444 oprintf("\t\tevents = ");
445 print_events(envelope
->events
);
451 void print_document(const struct isds_document
*document
) {
452 oprintf("\t\tdocument = ");
460 oprintf("\t\t\tis_xml = %u\n", !!document
->is_xml
);
461 oprintf("\t\t\txml_node_list = %p\n", document
->xml_node_list
);
463 oprintf("\t\t\tdata = %p\n", document
->data
);
464 oprintf("\t\t\tdata_length = %zu\n", document
->data_length
);
465 oprintf("\t\t\tdmMimeType = %s\n", document
->dmMimeType
);
467 oprintf("\t\t\tdmFileMetaType = ");
468 switch(document
->dmFileMetaType
) {
469 case FILEMETATYPE_MAIN
: oprintf("MAIN\n"); break;
470 case FILEMETATYPE_ENCLOSURE
: oprintf("ENCLOSURE\n"); break;
471 case FILEMETATYPE_SIGNATURE
: oprintf("SIGNATURE\n"); break;
472 case FILEMETATYPE_META
: oprintf("META\n"); break;
473 default: oprintf("<unknown type %d>\n", document
->dmFileMetaType
);
476 oprintf("\t\t\tdmFileGuid = %s\n", document
->dmFileGuid
);
477 oprintf("\t\t\tdmUpFileGuid = %s\n", document
->dmUpFileGuid
);
478 oprintf("\t\t\tdmFileDescr = %s\n", document
->dmFileDescr
);
479 oprintf("\t\t\tdmFormat = %s\n", document
->dmFormat
);
484 void print_documents(const struct isds_list
*documents
) {
485 const struct isds_list
*item
;
487 oprintf("\tdocuments = ");
495 for (item
= documents
; item
; item
= item
->next
) {
496 print_document((struct isds_document
*) (item
->data
));
503 void print_message(const struct isds_message
*message
) {
504 oprintf("message = ");
513 oprintf("\traw = %p\n", message
->raw
);
514 oprintf("\traw_length = %zu\n", message
->raw_length
);
515 oprintf("\traw_type = ");
516 print_raw_type(message
->raw_type
);
517 print_envelope(message
->envelope
);
518 print_documents(message
->documents
);
523 void print_copies(const struct isds_list
*copies
) {
524 const struct isds_list
*item
;
525 struct isds_message_copy
*copy
;
527 oprintf("Copies = ");
534 for (item
= copies
; item
; item
= item
->next
) {
535 copy
= (struct isds_message_copy
*) item
->data
;
536 oprintf("\tCopy = ");
542 oprintf("\t\tdbIDRecipient = %s\n", copy
->dbIDRecipient
);
543 oprintf("\t\tdmRecipientOrgUnit = %s\n", copy
->dmRecipientOrgUnit
);
545 oprintf("\t\tdmRecipientOrgUnitNum = ");
546 if (copy
->dmRecipientOrgUnitNum
)
547 oprintf("%ld\n", *copy
->dmRecipientOrgUnitNum
);
550 oprintf("\t\tdmToHands = %s\n", copy
->dmToHands
);
552 oprintf("\t\terror = %s\n", isds_strerror(copy
->error
));
553 oprintf("\t\tdmStatus = %s\n", copy
->dmStatus
);
554 oprintf("\t\tdmID = %s\n", copy
->dmID
);
562 void compare_hashes(const struct isds_hash
*hash1
,
563 const struct isds_hash
*hash2
) {
566 oprintf("Comparing hashes... ");
567 err
= isds_hash_cmp(hash1
, hash2
);
568 if (err
== IE_SUCCESS
)
569 oprintf("Hashes equal\n");
571 (err
== IE_NOTEQUAL
) oprintf("Hashes differ\n");
573 oprintf("isds_hash_cmp() failed: %s\n", isds_strerror(err
));
577 int progressbar(double upload_total
, double upload_current
,
578 double download_total
, double download_current
,
581 oprintf("Progress: upload %0f/%0f, download %0f/%0f, data=%p\n",
582 upload_current
, upload_total
, download_current
, download_total
,
588 /* Print formatted header if locale-encoded value is defined.
589 * @header is locale encoded header name
590 * @value is locale encoded header value */
591 void print_header(const char *header
, const char *value
) {
592 if (value
&& *value
) oprintf(_("%s: %s\n"), header
, value
);
596 /* Print formatted header if boolean value is defined.
597 * @header is locale encoded header name */
598 void print_header_bool(const char *header
, _Bool
*value
) {
599 if (value
) print_header(header
, (*value
) ? _("Yes") : _("No"));
603 /* Print formatted header if long int value is defined.
604 * @header is locale encoded header name */
605 void print_header_longint(const char *header
, long int *value
) {
606 if (value
) oprintf(_("%s: %ld\n"), header
, *value
);
610 /* Print formatted header if unsigned long int value is defined.
611 * @header is locale encoded header name */
612 void print_header_ulongint(const char *header
, unsigned long int *value
) {
613 if (value
) oprintf(_("%s: %ld\n"), header
, *value
);
617 /* Print formatted header if time value is defined.
618 * @header is locale encoded header name */
619 void print_header_timeval(const char *header
, struct timeval
*time
) {
625 if (!localtime_r(&(time
->tv_sec
), &broken
)) goto error
;
626 if (!strftime(buffer
, sizeof(buffer
)/sizeof(char), "%c", &broken
))
630 oprintf(_("%s: %s\n"), header
, buffer
);
631 else if ((time
->tv_usec
% 1000) == 0)
632 oprintf(_("%s: %s, %ld ms\n"), header
, buffer
, time
->tv_usec
/1000);
634 oprintf(_("%s: %s, %ld us\n"), header
, buffer
, time
->tv_usec
);
639 oprintf(_("%s: <Error while formatting time>\n"), header
);
644 /* Print formatted header if UTF-9 value is defined.
645 * @header is locale encoded header name
646 * @value is UTF-8 encoded header value */
647 void print_header_utf8(const char *header
, const char *value
) {
652 value_locale
= utf82locale(value
);
656 _("<Error while converting value>"));
661 /* Print formatted header and byte size.
662 * @header is locale encoded header name */
663 void print_header_size(const char *header
, size_t size
) {
667 shi_asprintf(&buffer
, _("%zu B"), size
);
668 else if (size
< (1<<20))
669 shi_asprintf(&buffer
, _("%0.2f KiB"), (float) size
/(1<<10));
671 shi_asprintf(&buffer
, _("%0.2f MiB"), (float) size
/(1<<20));
673 print_header(header
, buffer
);
678 /* Print formatted header if long int KB size is defined.
679 * @header is locale encoded header name */
680 void print_header_kbsize(const char *header
, const long int *size
) {
685 shi_asprintf(&buffer
, _("<Negative size>"));
686 else if (*size
< (1000))
687 shi_asprintf(&buffer
, _("%lu kB"), *size
);
689 shi_asprintf(&buffer
, _("%0.2f MB"), *size
/1000.0);
691 print_header(header
, buffer
);
696 static const char *DbType2string(const long int *type
) {
697 if (!type
) return NULL
;
699 case DBTYPE_SYSTEM
: return(_("System"));
700 case DBTYPE_FO
: return(_("Private individual"));
701 case DBTYPE_PFO
: return(_("Self-employed individual"));
702 case DBTYPE_PFO_ADVOK
: return(_("Lawyer"));
703 case DBTYPE_PFO_DANPOR
: return(_("Tax advisor"));
704 case DBTYPE_PFO_INSSPR
: return(_("Insolvency administrator"));
705 case DBTYPE_PO
: return(_("Organisation"));
706 case DBTYPE_PO_ZAK
: return(_("Organization based by law"));
707 case DBTYPE_PO_REQ
: return(_("Organization based on request"));
708 case DBTYPE_OVM
: return(_("Public authority"));
709 case DBTYPE_OVM_NOTAR
: return(_("Notary"));
710 case DBTYPE_OVM_EXEKUT
: return(_("Executor"));
711 case DBTYPE_OVM_REQ
: return(_("Public authority based on request"));
712 default: return(_("<Unknown type>"));
717 static const char *UserType2string(const long int *type
) {
718 if (!type
) return NULL
;
720 case USERTYPE_PRIMARY
: return(_("Primary"));
721 case USERTYPE_ENTRUSTED
: return(_("Entrusted"));
722 case USERTYPE_ADMINISTRATOR
: return(_("Administrator"));
723 case USERTYPE_OFFICIAL
: return(_("Official"));
724 default: return(_("<Unknown type>"));
729 /* Return formatted user privileges. Caller must free the string */
730 static char *UserPrivils2string(const long int *privils
) {
732 const char *priviledges
[] = {
733 N_("Read non-personal"),
735 N_("Send and read sent"),
736 N_("List messages and read delivery details"),
738 N_("Administer her box"),
739 N_("Read from safe"),
740 N_("Delete from safe")
742 const int priviledges_count
= sizeof(priviledges
)/sizeof(priviledges
[0]);
743 char *buffer
= NULL
, *new_buffer
= NULL
;
745 if (!privils
) return NULL
;
747 /*oprintf("%ld (", *privils);*/
749 for (int i
= 0; i
< priviledges_count
; i
++) {
750 if (*privils
& (1<<i
)) {
751 if ((*privils
% (1<<i
)))
752 shi_asprintf(&new_buffer
, _("%s, %s"),
753 buffer
, _(priviledges
[i
]));
755 shi_asprintf(&new_buffer
, "%s", _(priviledges
[i
]));
759 return(strdup(_("<Error while formatting privileges>")));
768 if (*privils
>= (1<<priviledges_count
)) {
769 if ((*privils
% (1<<priviledges_count
)))
770 shi_asprintf(&new_buffer
, _("%s, %s"),
771 buffer
, _("<Unknown privilege>"));
773 shi_asprintf(&new_buffer
, "%s", _("<Unknown privilege>"));
777 return(strdup(_("<Error while formatting privileges>")));
789 static const char *DmType2string(const char *type
) {
790 if (!type
) return NULL
;
791 if (!strcmp(type
, "V")) return(_("Public"));
792 else if (!strcmp(type
, "K")) return(_("Commercial"));
793 else return(_("<Unknown type>"));
797 static const char DmType2flag(const char *type
) {
798 if (!type
) return ' ';
799 if (!strcmp(type
, "V")) return('P');
800 else if (!strcmp(type
, "K")) return('C');
805 static const char *DmMessageStatus2string(const isds_message_status
*status
) {
806 if (!status
) return NULL
;
808 case MESSAGESTATE_SENT
: return(_("Sent"));
809 case MESSAGESTATE_STAMPED
: return(_("Stamped"));
810 case MESSAGESTATE_INFECTED
: return(_("Infected"));
811 case MESSAGESTATE_DELIVERED
: return(_("Delivered ordinary"));
812 case MESSAGESTATE_SUBSTITUTED
: return(_("Delivered substitutably"));
813 case MESSAGESTATE_RECEIVED
: return(_("Accepted"));
814 case MESSAGESTATE_READ
: return(_("Read"));
815 case MESSAGESTATE_UNDELIVERABLE
: return(_("Undeliverable"));
816 case MESSAGESTATE_REMOVED
: return(_("Deleted"));
817 case MESSAGESTATE_IN_SAFE
: return(_("Stored in safe"));
818 default: return(_("<Unknown state>"));
823 static const char DmMessageStatus2flag(const isds_message_status
*status
) {
824 if (!status
) return ' ';
826 case MESSAGESTATE_SENT
: return('>');
827 case MESSAGESTATE_STAMPED
: return('t');
828 case MESSAGESTATE_INFECTED
: return('I');
829 case MESSAGESTATE_DELIVERED
: return('N');
830 case MESSAGESTATE_SUBSTITUTED
: return('n');
831 case MESSAGESTATE_RECEIVED
: return('O');
832 case MESSAGESTATE_READ
: return(' ');
833 case MESSAGESTATE_UNDELIVERABLE
: return('!');
834 case MESSAGESTATE_REMOVED
: return('D');
835 case MESSAGESTATE_IN_SAFE
: return('S');
836 default: return('?');
841 /* Return timeval time formatted into shortest string with respect to current
842 * time. Caller must free the string. */
843 static char *timeval2shortstring(const struct timeval
*timeval
) {
844 struct tm broken
, current_broken
;
847 const size_t buffer_size
= 16;
849 if (!timeval
) return NULL
;
851 buffer
= malloc(buffer_size
);
852 if (!buffer
) goto error
;
854 /* Get current time */
855 current_time
= time(NULL
);
856 if (current_time
== (time_t) -1) goto error
;
857 if (!localtime_r(¤t_time
, ¤t_broken
)) goto error
;
859 /* Get broken time */
860 if (!localtime_r(&(timeval
->tv_sec
), &broken
)) goto error
;
862 /* Select proper abbreviated string representation */
863 if (broken
.tm_year
== current_broken
.tm_year
&&
864 broken
.tm_yday
== current_broken
.tm_yday
) {
865 /* Minute resolution in the same day */
866 if (!strftime(buffer
, buffer_size
, _("%k:%M"), &broken
))
869 /* Otherwise month and day */
870 if (!strftime(buffer
, buffer_size
, _("%b %d"), &broken
))
878 return strdup(_("<Error>"));
882 /* Formatted Law Authorization if defined. You must free it. */
883 static char *envelope_law2string(const struct isds_envelope
*envelope
) {
885 char *year_locale
= NULL
, *law_locale
= NULL
;
886 char *sect_locale
= NULL
, *par_locale
= NULL
, *point_locale
= NULL
;
889 !(envelope
->dmLegalTitleYear
|| envelope
->dmLegalTitleLaw
||
890 envelope
->dmLegalTitleSect
|| envelope
->dmLegalTitlePar
||
891 envelope
->dmLegalTitlePoint
)
894 if (envelope
->dmLegalTitleYear
)
895 shi_asprintf(&year_locale
, "%ld", *envelope
->dmLegalTitleYear
);
897 year_locale
= strdup(_("?"));
899 if (envelope
->dmLegalTitleLaw
)
900 shi_asprintf(&law_locale
, "%ld", *envelope
->dmLegalTitleLaw
);
902 law_locale
= strdup(_("?"));
904 sect_locale
= utf82locale(envelope
->dmLegalTitleSect
);
905 par_locale
= utf82locale(envelope
->dmLegalTitlePar
);
906 point_locale
= utf82locale(envelope
->dmLegalTitlePoint
);
909 shi_asprintf(&output
, _("point %s, par. %s, sect. %s, %s/%s Coll."),
910 point_locale
, par_locale
, sect_locale
,
911 law_locale
, year_locale
);
913 shi_asprintf(&output
, _("par. %s, sect. %s, %s/%s Coll."),
914 par_locale
, sect_locale
, law_locale
, year_locale
);
915 else if (sect_locale
)
916 shi_asprintf(&output
, _("sect. %s, %s/%s Coll."),
917 sect_locale
, law_locale
, year_locale
);
919 shi_asprintf(&output
, _("%s/%s Coll."),
920 law_locale
, year_locale
);
931 /* Print formatted header if time any of message ID.
932 * @header is locale encoded header name */
933 static void print_header_messages_ids(const char *header
,
934 const char *ref_number
, const char *ident
) {
935 if (ref_number
|| ident
) {
936 oprintf(_("%s:\n"), header
);
937 print_header_utf8(_("\tReference number"), ref_number
);
938 print_header_utf8(_("\tFile ID"), ident
);
943 /* Return formatted hash value */
944 char *hash2string(const struct isds_hash
*hash
) {
945 const char *algorithm_string
= NULL
;
946 char *buffer
= NULL
, *octet
= NULL
, *new_buffer
= NULL
;
948 if (!hash
|| !hash
->value
) return NULL
;
950 switch(hash
->algorithm
) {
951 case HASH_ALGORITHM_MD5
: algorithm_string
= (_("MD5")); break;
952 case HASH_ALGORITHM_SHA_1
: algorithm_string
= (_("SHA-1")); break;
953 case HASH_ALGORITHM_SHA_224
: algorithm_string
= (_("SHA-224")); break;
954 case HASH_ALGORITHM_SHA_256
: algorithm_string
= (_("SHA-256")); break;
955 case HASH_ALGORITHM_SHA_384
: algorithm_string
= (_("SHA-384")); break;
956 case HASH_ALGORITHM_SHA_512
: algorithm_string
= (_("SHA-512")); break;
957 default: algorithm_string
= (_("<Unknown hash algorithm>")); break;
960 for (int i
= 0; i
< hash
->length
; i
++) {
961 shi_asprintf(&octet
, "%02x", ((uint8_t *)(hash
->value
))[i
]);
963 free(buffer
); free(octet
); return NULL
;
967 shi_asprintf(&new_buffer
, _("%s:%s"), buffer
, octet
);
969 shi_asprintf(&new_buffer
, "%s", octet
);
971 free(buffer
); free(octet
); return NULL
;
974 buffer
= new_buffer
; new_buffer
= NULL
;
977 shi_asprintf(&new_buffer
, _("%s %s"), algorithm_string
, buffer
);
984 /* Print if any message delivery info exists. */
985 void print_message_delivery_info(const struct isds_envelope
*envelope
) {
986 char *hash_string
= NULL
;
988 if (envelope
&& (envelope
->dmType
|| envelope
->dmMessageStatus
||
989 envelope
->dmDeliveryTime
||
990 envelope
->dmAcceptanceTime
|| envelope
->dmPersonalDelivery
||
991 envelope
->dmAllowSubstDelivery
|| envelope
->hash
||
992 envelope
->dmOrdinal
)) {
993 oprintf(_("Delivery data:\n"));
994 print_header(_("\tMessage type"), DmType2string(envelope
->dmType
));
995 print_header(_("\tMessage status"),
996 DmMessageStatus2string(envelope
->dmMessageStatus
));
997 print_header_timeval(_("\tDelivered"), envelope
->dmDeliveryTime
);
998 print_header_timeval(_("\tAccepted"), envelope
->dmAcceptanceTime
);
999 print_header_bool(_("\tPersonal delivery required"),
1000 envelope
->dmPersonalDelivery
);
1001 print_header_bool(_("\tAllow substitutable delivery"),
1002 envelope
->dmAllowSubstDelivery
);
1004 hash_string
= hash2string(envelope
->hash
);
1005 print_header(_("\tHash"), hash_string
);
1008 print_header_ulongint(_("\tOrdinal number"), envelope
->dmOrdinal
);
1013 static const char *event_type2string(const isds_event_type
*type
) {
1014 if (!type
) return (_("<Undefined>"));
1017 case EVENT_UKNOWN
: return(_("Unknown"));
1018 case EVENT_ACCEPTED_BY_RECIPIENT
:
1019 return(_("Accepted by recipient"));
1020 case EVENT_ACCEPTED_BY_FICTION
:
1021 return(_("Delivered substitutably"));
1022 case EVENT_UNDELIVERABLE
:
1023 return(_("Undeliverable"));
1024 default: return(_("<Unknown event type>"));
1029 /* Print if any delivery event exists. */
1030 void print_delivery_events(const struct isds_list
*events
) {
1031 int counter_width
= 3;
1033 const struct isds_list
*item
;
1034 struct isds_event
*event
;
1036 if (!events
) return;
1038 oprintf(_("Delivery events:\n"));
1040 for (item
= events
; item
; item
= item
->next
) {
1041 event
= (struct isds_event
*) item
->data
;
1042 if (!event
) continue;
1045 oprintf(_("%*d %s\n"), counter_width
, order
,
1046 event_type2string(event
->type
));
1047 print_header_utf8(_("\tDescription"), event
->description
);
1048 print_header_timeval(_("\tWhen"), event
->time
);
1053 /* Print formatted message envelope */
1054 void format_envelope(const struct isds_envelope
*envelope
) {
1055 char *law_string
= NULL
;
1058 oprintf(_("<Missing envelope>\n"));
1062 print_header_utf8(_("Message ID"), envelope
->dmID
);
1064 if (envelope
->dbIDSender
|| envelope
->dmSender
||
1065 envelope
->dmSenderOrgUnit
|| envelope
->dmSenderOrgUnitNum
||
1066 envelope
->dmSenderAddress
|| envelope
->dmSenderType
||
1068 oprintf(_("Sender:\n"));
1069 print_header_utf8(_("\tID"), envelope
->dbIDSender
);
1070 print_header_utf8(_("\tName"), envelope
->dmSender
);
1071 print_header_utf8(_("\tUnit"), envelope
->dmSenderOrgUnit
);
1072 print_header_longint(_("\tUnit number"), envelope
->dmSenderOrgUnitNum
);
1073 print_header_utf8(_("\tAddress"), envelope
->dmSenderAddress
);
1074 print_header(_("\tType"), DbType2string(envelope
->dmSenderType
));
1075 print_header_bool(_("\tAs public authority"), envelope
->dmOVM
);
1078 if (envelope
->dbIDRecipient
|| envelope
->dmRecipient
||
1079 envelope
->dmRecipientOrgUnit
|| envelope
->dmRecipientOrgUnitNum
||
1080 envelope
->dmToHands
|| envelope
->dmRecipientAddress
||
1081 envelope
->dmAmbiguousRecipient
) {
1082 oprintf(_("Recipient:\n"));
1083 print_header_utf8(_("\tID"), envelope
->dbIDRecipient
);
1084 print_header_utf8(_("\tName"), envelope
->dmRecipient
);
1085 print_header_utf8(_("\tUnit"), envelope
->dmRecipientOrgUnit
);
1086 print_header_longint(_("\tUnit number"),
1087 envelope
->dmRecipientOrgUnitNum
);
1088 print_header_utf8(_("To hands"), envelope
->dmToHands
);
1089 print_header_utf8(_("\tAddress"), envelope
->dmRecipientAddress
);
1090 print_header_bool(_("\tAs public authority"),
1091 envelope
->dmAmbiguousRecipient
);
1094 print_header_utf8(_("Subject"), envelope
->dmAnnotation
);
1096 print_header_messages_ids(_("Sender message IDs"),
1097 envelope
->dmSenderRefNumber
, envelope
->dmSenderIdent
);
1098 print_header_messages_ids(_("Recipient message IDs"),
1099 envelope
->dmRecipientRefNumber
, envelope
->dmRecipientIdent
);
1101 law_string
= envelope_law2string(envelope
);
1102 print_header(_("Law authorization"), law_string
);
1105 print_message_delivery_info(envelope
);
1107 print_header_kbsize(_("Document total size"), envelope
->dmAttachmentSize
);
1109 /*oprintf("\t\ttimestamp = %p\n", envelope->timestamp);
1110 oprintf("\t\ttimestamp_length = %zu\n", envelope->timestamp_length);*/
1111 print_delivery_events(envelope
->events
);
1115 const char *DmFileMetaType2string(isds_FileMetaType type
) {
1117 case FILEMETATYPE_MAIN
: return(_("Main document"));
1118 case FILEMETATYPE_ENCLOSURE
: return(_("Enclosure"));
1119 case FILEMETATYPE_SIGNATURE
: return(_("Signature"));
1120 case FILEMETATYPE_META
: return(_("Meta document"));
1121 default: return(_("<unknown document type>"));
1126 /* Computes ordinal number of document identified by GUID
1127 * @documents is list of documents where to search
1128 * @id is UTF-8 encoded document ID reference
1129 * Return allocated array of ordinal numbers terminated by -1. Normally only
1130 * one document with @id exists. However ISDS does not check this higher
1131 * requirements and can transport message with duplicate document identifiers.
1132 * Therefore this function returns array of ordinals. Return NULL if error
1133 * occurs (e.g. memory insufficiency). */
1134 static int *dmFileGuid2ordinar(const struct isds_list
*documents
,
1136 const struct isds_list
*item
;
1137 struct isds_document
*document
;
1138 size_t ordinars_length
= 64, offset
= 0;
1139 int *ordinars
= NULL
, *new_ordinars
;
1142 if (!documents
|| !id
|| !*id
) return NULL
;
1143 ordinars
= malloc(ordinars_length
* sizeof(*ordinars
));
1144 if (!ordinars
) return NULL
;
1146 for (item
= documents
; item
; item
= item
->next
) {
1147 if (!item
->data
) continue;
1149 document
= (struct isds_document
*) (item
->data
);
1151 if (document
->dmFileGuid
&& !strcmp(document
->dmFileGuid
, id
)) {
1152 if (offset
== ordinars_length
) {
1153 /* Grow ordinals array */
1154 ordinars_length
*= 2;
1155 new_ordinars
= realloc(ordinars
,
1156 ordinars_length
* sizeof(*ordinars
));
1157 if (!new_ordinars
) {
1161 ordinars
= new_ordinars
;
1164 ordinars
[offset
++] = ordinar
;
1168 ordinars
[offset
] = -1;
1173 /* @id is UTF-8 encoded GUID of referred document
1174 * @refernces is array of ordinal numbers if exist terminated by -1. Can be
1175 * NULL to signal error. */
1176 static void format_document_reference(char *id
, int *references
) {
1177 char *buffer
= NULL
, *new_buffer
= NULL
;
1180 if (references
&& *references
!= -1) {
1181 for (; *references
> 0; references
++) {
1183 shi_asprintf(&new_buffer
, _("%d"), *references
);
1185 shi_asprintf(&new_buffer
, _("%s, %d"), buffer
, *references
);
1191 buffer
= new_buffer
;
1195 char *id_locale
= utf82locale(id
);
1196 shi_asprintf(&buffer
,
1197 _("<Reference to non-existing document ID `%s'>"), id_locale
);
1202 print_header(_("\tRefers to"), buffer
);
1204 print_header(_("\tRefers to"), _("<Error while formatting reference>"));
1209 /* Print formatted document
1210 * @references is ordinal number of referred document. Formally it's array
1211 * terminated by -1 because non-well-formed message can have more documents
1213 void format_document(const struct isds_document
*document
, int order
,
1215 int counter_width
= 3;
1216 char *filename_locale
= NULL
;
1218 if (!document
) return;
1220 oprintf(_("%*d "), counter_width
, order
);
1222 if (document
->dmFileDescr
) {
1223 filename_locale
= utf82locale(document
->dmFileDescr
);
1224 oprintf("%s\n", filename_locale
);
1225 free(filename_locale
);
1227 oprintf(_("<Unknown file name>\n"));
1230 if (document
->is_xml
) {
1231 char *message
=NULL
;
1234 for (xmlNodePtr node
= document
->xml_node_list
; node
;
1235 node
= node
->next
) nodes
++;
1236 shi_asprintf(&message
, ngettext("%d node", "%d nodes", nodes
), nodes
);
1238 print_header(_("\tXML document"), message
);
1242 print_header_size(_("\tSize"), document
->data_length
);
1244 print_header(_("\tMIME type"), document
->dmMimeType
);
1246 print_header(_("\tType"), DmFileMetaType2string(document
->dmFileMetaType
));
1247 print_header_utf8(_("\tMeta format"), document
->dmFormat
);
1249 print_header_utf8(_("\tID"), document
->dmFileGuid
);
1250 format_document_reference(document
->dmUpFileGuid
, references
);
1254 /* Print formatted message documents */
1255 void format_documents(const struct isds_list
*documents
) {
1256 const struct isds_list
*item
;
1257 const struct isds_document
*document
;
1260 if (!documents
) return;
1262 oprintf(_("Documents:\n"));
1264 for (item
= documents
; item
; item
= item
->next
) {
1265 if (!item
->data
) continue;
1266 document
= (struct isds_document
*) item
->data
;
1267 references
= dmFileGuid2ordinar(documents
, document
->dmUpFileGuid
);
1268 format_document(document
, ++i
, references
);
1274 /* Print formatted message */
1275 void format_message(const struct isds_message
*message
) {
1276 if (!message
) return;
1277 format_envelope(message
->envelope
);
1278 format_documents(message
->documents
);
1282 /* Print formatted list of message copies */
1283 void format_copies(const struct isds_list
*copies
) {
1284 const struct isds_list
*item
;
1285 const struct isds_message_copy
*copy
;
1287 int counter_width
= 3;
1288 if (!copies
) return;
1290 for (item
= copies
; item
; item
= item
->next
) {
1291 if (!item
->data
) continue;
1292 copy
= (struct isds_message_copy
*) item
->data
;
1295 oprintf(_("%*d Recipient:\n"), counter_width
, i
);
1296 print_header_utf8(_("\tID"), copy
->dbIDRecipient
);
1297 print_header_utf8(_("\tUnit"), copy
->dmRecipientOrgUnit
);
1298 print_header_longint(_("\tUnit number"), copy
->dmRecipientOrgUnitNum
);
1299 print_header_utf8(_("\tTo hands"), copy
->dmToHands
);
1304 void print_message_list(const struct isds_list
*messages
, _Bool outgoing
) {
1305 const struct isds_list
*item
;
1306 struct isds_envelope
*envelope
;
1307 unsigned long int counter
= 0;
1309 int counter_max
, id_max
= 0, name_max
= 0, subject_max
= 0;
1310 int counter_width
, id_width
= 0, flags_width
= 2, time_width
= 6,
1311 name_width
= 0, subject_width
= 0;
1313 char *id_locale
= NULL
, flags_locale
[3], *time_locale
= NULL
,
1314 *name_locale
= NULL
, *subject_locale
= NULL
;
1319 /* Compute column widths */
1320 rl_get_screen_size(NULL
, &screen_cols
);
1322 /* Get real maximal widths */
1323 for (counter
= 0, item
= messages
; item
; item
= item
->next
) {
1324 if (!item
->data
|| !((struct isds_message
*)item
->data
)->envelope
)
1326 envelope
= ((struct isds_message
*) item
->data
)->envelope
;
1329 width
= utf8width(envelope
->dmID
);
1330 if (width
> id_max
) id_max
= width
;
1332 width
= utf8width((outgoing
) ?
1333 envelope
->dmRecipient
: envelope
->dmSender
);
1334 if (width
> name_max
) name_max
= width
;
1336 width
= utf8width(envelope
->dmAnnotation
);
1337 if (width
> subject_max
) subject_max
= width
;
1339 counter_max
= numberwidth(counter
);
1341 /* Correct widths to fit into window */
1342 if (counter_max
< 0) counter_width
= -3; else counter_width
= counter_max
;
1343 if (id_max
< 0) id_width
= -6; else id_width
= id_max
;
1344 if (name_max
< 0) name_width
= -20; else name_width
= name_max
;
1345 if (subject_max
< 0) subject_width
= -32; else subject_width
= subject_max
;
1347 width
= abs(counter_width
) + 1 + abs(id_width
) + 1 + abs(flags_width
) + 1 +
1348 abs(time_width
) + 1 + abs(name_width
) + 1 + abs(subject_width
);
1349 if (width
> screen_cols
) {
1350 width
-= abs(name_width
) + abs(subject_width
);
1352 name_width
= subject_width
= 0;
1353 while (width
+ name_width
+ subject_width
< screen_cols
) {
1354 if (name_width
< abs(name_max
)) name_width
++;
1355 if (subject_width
< abs(subject_max
)) subject_width
++;
1357 if (width
+ name_width
+ subject_width
> screen_cols
) subject_width
--;
1361 /* TRANSLATORS: "No" is abbreviation for "Number" in listing header. */
1362 onprint(pgettext("list header", "No"), counter_width
);
1364 onprint(_("ID"), id_width
);
1366 onprint(_("Flags"), flags_width
);
1368 onprint(_("Delivered"), time_width
);
1370 onprint((outgoing
) ? _("To") : _("From"), name_width
);
1372 onprint(_("Subject"), subject_width
);
1374 for (int i
= 0; i
< screen_cols
; i
++) oprintf(_("-"));
1377 /* Print the list */
1378 for (counter
= 0, item
= messages
; item
; item
= item
->next
) {
1379 envelope
= ((struct isds_message
*) item
->data
)->envelope
;
1382 oprintf(_("%*lu "), counter_width
, counter
);
1385 oprintf(_("<Missing envelope>\n"));
1389 id_locale
= utf82locale(envelope
->dmID
);
1390 name_locale
= utf82locale((outgoing
) ?
1391 envelope
->dmRecipient
: envelope
->dmSender
);
1392 flags_locale
[0] = DmType2flag(envelope
->dmType
);
1393 flags_locale
[1] = DmMessageStatus2flag(envelope
->dmMessageStatus
);
1394 flags_locale
[2] = '\0';
1395 time_locale
= timeval2shortstring(envelope
->dmDeliveryTime
);
1396 subject_locale
= utf82locale(envelope
->dmAnnotation
);
1398 onprint(id_locale
, id_width
);
1400 onprint(flags_locale
, flags_width
);
1402 onprint(time_locale
, time_width
);
1404 onprint(name_locale
, name_width
);
1406 onprint(subject_locale
, subject_width
);
1412 zfree(subject_locale
);
1417 static void format_PersonName(const struct isds_PersonName
*personName
) {
1418 if (!personName
) return;
1420 oprintf(_("Person name:\n"));
1421 print_header_utf8(_("\tFirst"), personName
->pnFirstName
);
1422 print_header_utf8(_("\tMiddle"), personName
->pnMiddleName
);
1423 print_header_utf8(_("\tLast"), personName
->pnLastName
);
1424 print_header_utf8(_("\tLast at birth"),
1425 personName
->pnLastNameAtBirth
);
1429 /* Return formatted date as mallocated string. NULL or special error string can
1430 * be returned. Application must free even the error string. */
1431 char *tm2string(const struct tm
*date
) {
1433 size_t buffer_length
= 128;
1435 if (!date
) return NULL
;
1437 buffer
= malloc(buffer_length
);
1438 if (!buffer
) return strdup(_("<Error while formatting date>"));
1440 if (0 == strftime(buffer
, buffer_length
, "%x", date
)) {
1442 return strdup(_("<Error while formatting date>"));
1449 /* Convert string representation of full ISO 8601 or locale date to tm structure.
1450 * Return NULL if error occurs
1451 * XXX: Not all ISO formats are supported */
1452 struct tm
*datestring2tm(const char *string
) {
1453 struct tm
*date
= NULL
;
1455 if (!string
) return NULL
;
1457 date
= calloc(1, sizeof(*date
));
1458 if (!date
) return NULL
;
1460 /* xsd:date is ISO 8601 string, thus ASCII */
1461 offset
= strptime(string
, "%Y-%m-%d", date
);
1462 if (offset
&& *offset
== '\0')
1465 offset
= strptime(string
, "%x", date
);
1466 if (offset
&& *offset
== '\0')
1474 static void format_BirthInfo(const struct isds_BirthInfo
*birth
) {
1476 if (!birth
|| !(birth
->biDate
|| birth
->biCity
|| birth
->biCounty
1477 || birth
->biState
)) return;
1479 oprintf(_("Birth details:\n"));
1481 date
= tm2string(birth
->biDate
);
1482 print_header(_("\tDate"), date
);
1485 print_header_utf8(_("\tCity"), birth
->biCity
);
1486 print_header_utf8(_("\tCounty"), birth
->biCounty
);
1487 print_header_utf8(_("\tState"), birth
->biState
);
1491 static void format_Address(const struct isds_Address
*address
) {
1492 if (!address
|| !(address
->adCity
|| address
->adState
||
1493 address
->adNumberInStreet
|| address
->adNumberInMunicipality
||
1494 address
->adZipCode
|| address
->adState
)) return;
1496 oprintf("Address:\n");
1497 print_header_utf8(_("\tCity"), address
->adCity
);
1498 print_header_utf8(_("\tStreet"), address
->adStreet
);
1499 print_header_utf8(_("\tNumber in street"), address
->adNumberInStreet
);
1500 print_header_utf8(_("\tNumber in municipality"),
1501 address
->adNumberInMunicipality
);
1502 print_header_utf8(_("\tZIP code"), address
->adZipCode
);
1503 print_header_utf8(_("\tState"), address
->adState
);
1507 /* Return static box state string or NULL if undefined */
1508 const char *DbState2string(const long int *state
) {
1509 if (!state
) return NULL
;
1512 case DBSTATE_ACCESSIBLE
: return(_("Accessible"));
1513 case DBSTATE_TEMP_UNACCESSIBLE
: return(_("Temporary inaccessible"));
1514 case DBSTATE_NOT_YET_ACCESSIBLE
: return(_("Not yet accessible"));
1515 case DBSTATE_PERM_UNACCESSIBLE
: return(_("Permanently inaccessible"));
1516 case DBSTATE_REMOVED
: return(_("Deleted"));
1517 default: return(_("<unknown state>"));
1522 void format_DbOwnerInfo(const struct isds_DbOwnerInfo
*info
) {
1525 print_header_utf8(_("Box ID"), info
->dbID
);
1526 print_header(_("Type"), DbType2string((long int *) (info
->dbType
)));
1527 print_header_utf8(_("Subject name"), info
->firmName
);
1528 print_header_utf8(_("Identity number"), info
->ic
);
1530 format_PersonName(info
->personName
);
1531 format_BirthInfo(info
->birthInfo
);
1533 format_Address(info
->address
);
1535 print_header_utf8(_("Nationality"), info
->nationality
);
1536 print_header_utf8(_("E-mail"), info
->email
);
1537 print_header_utf8(_("Phone"), info
->telNumber
);
1539 print_header_utf8(_("Identifier"), info
->identifier
);
1540 print_header_utf8(_("Registry code"), info
->registryCode
);
1542 print_header(_("State"), DbState2string(info
->dbState
));
1543 print_header_bool(_("Act as public authority"), info
->dbEffectiveOVM
);
1544 print_header_bool(_("Receive commercial messages"),
1545 info
->dbOpenAddressing
);
1549 static void format_supervising_firm(const char *ic
, const char *firmName
) {
1550 if (!ic
&& !firmName
) return;
1552 oprintf(_("Supervising subject:\n"));
1553 print_header_utf8(_("\tIdentity number"), ic
);
1554 print_header_utf8(_("\tName"), firmName
);
1558 static void format_contact_address(const char *caStreet
, const char *caCity
,
1559 const char *caZipCode
, const char *caState
) {
1560 if (!caStreet
&& !caCity
&& !caZipCode
) return;
1562 oprintf(_("Contact address:\n"));
1563 print_header_utf8(_("\tStreet"), caStreet
);
1564 print_header_utf8(_("\tCity"), caCity
);
1565 print_header_utf8(_("\tZIP code"), caZipCode
);
1566 print_header_utf8(_("\tState"), caState
);
1570 void format_DbUserInfo(const struct isds_DbUserInfo
*info
) {
1575 print_header_utf8(_("User ID"), info
->userID
);
1576 print_header(_("Type"), UserType2string((long int *) (info
->userType
)));
1578 buffer
= UserPrivils2string(info
->userPrivils
);
1579 print_header(_("Privileges"), buffer
);
1582 format_PersonName(info
->personName
);
1583 format_Address(info
->address
);
1585 buffer
= tm2string(info
->biDate
);
1586 print_header(_("Birth date"), buffer
);
1589 format_supervising_firm(info
->ic
, info
->firmName
);
1590 format_contact_address(info
->caStreet
, info
->caCity
, info
->caZipCode
,