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_ENTERED_SYSTEM
: printf("ENTERED_SYSTEM\n"); break;
312 case EVENT_ACCEPTED_BY_RECIPIENT
:
313 oprintf("ACCEPTED_BY_RECIPIENT\n"); break;
314 case EVENT_ACCEPTED_BY_FICTION
:
315 oprintf("DELIVERED_BY_FICTION\n"); break;
316 case EVENT_UNDELIVERABLE
:
317 oprintf("UNDELIVERABLE\n"); break;
318 case EVENT_COMMERCIAL_ACCEPTED
:
319 oprintf("COMMERCIAL_ACCEPTED\n"); break;
320 case EVENT_DELIVERED
:
321 oprintf("DELIVERED\n"); break;
322 case EVENT_PRIMARY_LOGIN
:
323 oprintf("PRIMARY_LOGIN\n"); break;
324 case EVENT_ENTRUSTED_LOGIN
:
325 oprintf("ENTRUSTED_LOGIN\n"); break;
326 case EVENT_SYSCERT_LOGIN
:
327 oprintf("SYSCERT_LOGIN\n"); break;
328 default: oprintf("<unknown type %d>\n", *type
);
333 void print_events(const struct isds_list
*events
) {
334 const struct isds_list
*item
;
335 const struct isds_event
*event
;
344 for (item
= events
; item
; item
= item
->next
) {
345 event
= (struct isds_event
*) item
->data
;
346 oprintf("\t\t\tevent = ");
347 if (!event
) oprintf("NULL");
351 oprintf("\t\t\t\ttype = ");
352 print_event_type(event
->type
);
354 oprintf("\t\t\t\tdescription = %s\n", event
->description
);
356 oprintf("\t\t\t\ttime = ");
357 print_timeval(event
->time
);
359 oprintf("\t\t\t}\n");
367 void print_envelope(const struct isds_envelope
*envelope
) {
368 oprintf("\tenvelope = ");
376 oprintf("\t\tdmID = %s\n", envelope
->dmID
);
377 oprintf("\t\tdbIDSender = %s\n", envelope
->dbIDSender
);
378 oprintf("\t\tdmSender = %s\n", envelope
->dmSender
);
379 oprintf("\t\tdmSenderAddress = %s\n", envelope
->dmSenderAddress
);
380 oprintf("\t\tdmSenderType = ");
381 print_DbType(envelope
->dmSenderType
);
382 oprintf("\t\tdmRecipient = %s\n", envelope
->dmRecipient
);
383 oprintf("\t\tdmRecipientAddress = %s\n", envelope
->dmRecipientAddress
);
384 oprintf("\t\tdmAmbiguousRecipient = ");
385 print_bool(envelope
->dmAmbiguousRecipient
);
386 oprintf("\t\tdmType = %s\n", envelope
->dmType
);
388 oprintf("\t\tdmSenderOrgUnit = %s\n", envelope
->dmSenderOrgUnit
);
389 oprintf("\t\tdmSenderOrgUnitNum = ");
390 print_longint(envelope
->dmSenderOrgUnitNum
);
391 oprintf("\t\tdbIDRecipient = %s\n", envelope
->dbIDRecipient
);
392 oprintf("\t\tdmRecipientOrgUnit = %s\n", envelope
->dmRecipientOrgUnit
);
393 oprintf("\t\tdmRecipientOrgUnitNum = ");
394 print_longint(envelope
->dmRecipientOrgUnitNum
);
395 oprintf("\t\tdmToHands = %s\n", envelope
->dmToHands
);
396 oprintf("\t\tdmAnnotation = %s\n", envelope
->dmAnnotation
);
397 oprintf("\t\tdmRecipientRefNumber = %s\n", envelope
->dmRecipientRefNumber
);
398 oprintf("\t\tdmSenderRefNumber = %s\n", envelope
->dmSenderRefNumber
);
399 oprintf("\t\tdmRecipientIdent = %s\n", envelope
->dmRecipientIdent
);
400 oprintf("\t\tdmSenderIdent = %s\n", envelope
->dmSenderIdent
);
402 oprintf("\t\tdmLegalTitleLaw = ");
403 print_longint(envelope
->dmLegalTitleLaw
);
404 oprintf("\t\tdmLegalTitleYear = ");
405 print_longint(envelope
->dmLegalTitleYear
);
406 oprintf("\t\tdmLegalTitleSect = %s\n", envelope
->dmLegalTitleSect
);
407 oprintf("\t\tdmLegalTitlePar = %s\n", envelope
->dmLegalTitlePar
);
408 oprintf("\t\tdmLegalTitlePoint = %s\n", envelope
->dmLegalTitlePoint
);
410 oprintf("\t\tdmPersonalDelivery = ");
411 print_bool(envelope
->dmPersonalDelivery
);
412 oprintf("\t\tdmAllowSubstDelivery = ");
413 print_bool(envelope
->dmAllowSubstDelivery
);
414 oprintf("\t\tdmOVM = ");
415 print_bool(envelope
->dmOVM
);
416 oprintf("\t\tdmPublishOwnID = ");
417 print_bool(envelope
->dmPublishOwnID
);
419 oprintf("\t\tdmOrdinal = ");
420 if (!envelope
->dmOrdinal
) oprintf("NULL\n");
421 else oprintf("%lu\n", *(envelope
->dmOrdinal
));
423 oprintf("\t\tdmMessageStatus = ");
424 if (!envelope
->dmMessageStatus
) oprintf("NULL\n");
426 switch(*(envelope
->dmMessageStatus
)) {
427 case MESSAGESTATE_SENT
: oprintf("SENT\n"); break;
428 case MESSAGESTATE_STAMPED
: oprintf("STAMPED\n"); break;
429 case MESSAGESTATE_INFECTED
: oprintf("INFECTED\n"); break;
430 case MESSAGESTATE_DELIVERED
: oprintf("DELIVERED\n"); break;
431 case MESSAGESTATE_SUBSTITUTED
: oprintf("SUBSTITUTED\n"); break;
432 case MESSAGESTATE_RECEIVED
: oprintf("RECEIVED\n"); break;
433 case MESSAGESTATE_READ
: oprintf("READ\n"); break;
434 case MESSAGESTATE_UNDELIVERABLE
: oprintf("UNDELIVERABLE\n"); break;
435 case MESSAGESTATE_REMOVED
: oprintf("REMOVED\n"); break;
436 case MESSAGESTATE_IN_SAFE
: oprintf("IN_SAFE\n"); break;
437 default: oprintf("<unknown type %d>\n",
438 *(envelope
->dmMessageStatus
));
441 oprintf("\t\tdmAttachmentSize = ");
442 if (!envelope
->dmAttachmentSize
) oprintf("NULL\n");
443 else oprintf("%lu kB\n", *(envelope
->dmAttachmentSize
));
445 oprintf("\t\tdmDeliveryTime = ");
446 print_timeval(envelope
->dmDeliveryTime
);
448 oprintf("\t\tdmAcceptanceTime = ");
449 print_timeval(envelope
->dmAcceptanceTime
);
451 oprintf("\t\thash = ");
452 print_hash(envelope
->hash
);
454 oprintf("\t\ttimestamp = %p\n", envelope
->timestamp
);
455 oprintf("\t\ttimestamp_length = %zu\n", envelope
->timestamp_length
);
457 oprintf("\t\tevents = ");
458 print_events(envelope
->events
);
464 void print_document(const struct isds_document
*document
) {
465 oprintf("\t\tdocument = ");
473 oprintf("\t\t\tis_xml = %u\n", !!document
->is_xml
);
474 oprintf("\t\t\txml_node_list = %p\n", document
->xml_node_list
);
476 oprintf("\t\t\tdata = %p\n", document
->data
);
477 oprintf("\t\t\tdata_length = %zu\n", document
->data_length
);
478 oprintf("\t\t\tdmMimeType = %s\n", document
->dmMimeType
);
480 oprintf("\t\t\tdmFileMetaType = ");
481 switch(document
->dmFileMetaType
) {
482 case FILEMETATYPE_MAIN
: oprintf("MAIN\n"); break;
483 case FILEMETATYPE_ENCLOSURE
: oprintf("ENCLOSURE\n"); break;
484 case FILEMETATYPE_SIGNATURE
: oprintf("SIGNATURE\n"); break;
485 case FILEMETATYPE_META
: oprintf("META\n"); break;
486 default: oprintf("<unknown type %d>\n", document
->dmFileMetaType
);
489 oprintf("\t\t\tdmFileGuid = %s\n", document
->dmFileGuid
);
490 oprintf("\t\t\tdmUpFileGuid = %s\n", document
->dmUpFileGuid
);
491 oprintf("\t\t\tdmFileDescr = %s\n", document
->dmFileDescr
);
492 oprintf("\t\t\tdmFormat = %s\n", document
->dmFormat
);
497 void print_documents(const struct isds_list
*documents
) {
498 const struct isds_list
*item
;
500 oprintf("\tdocuments = ");
508 for (item
= documents
; item
; item
= item
->next
) {
509 print_document((struct isds_document
*) (item
->data
));
516 void print_message(const struct isds_message
*message
) {
517 oprintf("message = ");
526 oprintf("\traw = %p\n", message
->raw
);
527 oprintf("\traw_length = %zu\n", message
->raw_length
);
528 oprintf("\traw_type = ");
529 print_raw_type(message
->raw_type
);
530 print_envelope(message
->envelope
);
531 print_documents(message
->documents
);
536 void print_copies(const struct isds_list
*copies
) {
537 const struct isds_list
*item
;
538 struct isds_message_copy
*copy
;
540 oprintf("Copies = ");
547 for (item
= copies
; item
; item
= item
->next
) {
548 copy
= (struct isds_message_copy
*) item
->data
;
549 oprintf("\tCopy = ");
555 oprintf("\t\tdbIDRecipient = %s\n", copy
->dbIDRecipient
);
556 oprintf("\t\tdmRecipientOrgUnit = %s\n", copy
->dmRecipientOrgUnit
);
558 oprintf("\t\tdmRecipientOrgUnitNum = ");
559 if (copy
->dmRecipientOrgUnitNum
)
560 oprintf("%ld\n", *copy
->dmRecipientOrgUnitNum
);
563 oprintf("\t\tdmToHands = %s\n", copy
->dmToHands
);
565 oprintf("\t\terror = %s\n", isds_strerror(copy
->error
));
566 oprintf("\t\tdmStatus = %s\n", copy
->dmStatus
);
567 oprintf("\t\tdmID = %s\n", copy
->dmID
);
575 void compare_hashes(const struct isds_hash
*hash1
,
576 const struct isds_hash
*hash2
) {
579 oprintf("Comparing hashes... ");
580 err
= isds_hash_cmp(hash1
, hash2
);
581 if (err
== IE_SUCCESS
)
582 oprintf("Hashes equal\n");
584 (err
== IE_NOTEQUAL
) oprintf("Hashes differ\n");
586 oprintf("isds_hash_cmp() failed: %s\n", isds_strerror(err
));
590 int progressbar(double upload_total
, double upload_current
,
591 double download_total
, double download_current
,
594 oprintf("Progress: upload %0f/%0f, download %0f/%0f, data=%p\n",
595 upload_current
, upload_total
, download_current
, download_total
,
601 /* Print formatted header if locale-encoded value is defined.
602 * @header is locale encoded header name
603 * @value is locale encoded header value */
604 void print_header(const char *header
, const char *value
) {
605 if (value
&& *value
) oprintf(_("%s: %s\n"), header
, value
);
609 /* Print formatted header if boolean value is defined.
610 * @header is locale encoded header name */
611 void print_header_bool(const char *header
, const _Bool
*value
) {
612 if (value
) print_header(header
, (*value
) ? _("Yes") : _("No"));
616 /* Print formatted header if long int value is defined.
617 * @header is locale encoded header name */
618 void print_header_longint(const char *header
, const long int *value
) {
619 if (value
) oprintf(_("%s: %ld\n"), header
, *value
);
623 /* Print formatted header if unsigned long int value is defined.
624 * @header is locale encoded header name */
625 void print_header_ulongint(const char *header
, const unsigned long int *value
) {
626 if (value
) oprintf(_("%s: %lu\n"), header
, *value
);
630 /* Print formatted header if time value is defined.
631 * @header is locale encoded header name */
632 void print_header_timeval(const char *header
, const struct timeval
*time
) {
638 if (!localtime_r(&(time
->tv_sec
), &broken
)) goto error
;
639 if (!strftime(buffer
, sizeof(buffer
)/sizeof(char), "%c", &broken
))
643 oprintf(_("%s: %s\n"), header
, buffer
);
644 else if ((time
->tv_usec
% 1000) == 0)
645 oprintf(_("%s: %s, %ld ms\n"), header
, buffer
, time
->tv_usec
/1000);
647 oprintf(_("%s: %s, %ld us\n"), header
, buffer
, time
->tv_usec
);
652 oprintf(_("%s: <Error while formatting time>\n"), header
);
657 /* Return formatted date as mallocated string. NULL or special error string can
658 * be returned. Application must free even the error string. */
659 char *tm2string(const struct tm
*date
) {
661 size_t buffer_length
= 128;
663 if (!date
) return NULL
;
665 buffer
= malloc(buffer_length
);
666 if (!buffer
) return strdup(_("<Error while formatting date>"));
668 if (0 == strftime(buffer
, buffer_length
, "%x", date
)) {
670 return strdup(_("<Error while formatting date>"));
677 /* Convert string representation of full ISO 8601 or locale date to tm structure.
678 * Return NULL if error occurs
679 * XXX: Not all ISO formats are supported */
680 struct tm
*datestring2tm(const char *string
) {
681 struct tm
*date
= NULL
;
683 if (!string
) return NULL
;
685 date
= calloc(1, sizeof(*date
));
686 if (!date
) return NULL
;
688 /* xsd:date is ISO 8601 string, thus ASCII */
689 offset
= strptime(string
, "%Y-%m-%d", date
);
690 if (offset
&& *offset
== '\0')
693 offset
= strptime(string
, "%x", date
);
694 if (offset
&& *offset
== '\0')
702 /* Print formatted header if date value is defined.
703 * @header is locale encoded header name */
704 void print_header_tm(const char *header
, const struct tm
*date
) {
707 if (NULL
== date
) return;
708 string
= tm2string(date
);
711 oprintf(_("%s: <Error while formatting date>\n"), header
);
713 print_header(header
, string
);
719 /* Print formatted header if UTF-8 value is defined.
720 * @header is locale encoded header name
721 * @value is UTF-8 encoded header value */
722 void print_header_utf8(const char *header
, const char *value
) {
727 value_locale
= utf82locale(value
);
731 _("<Error while converting value>"));
736 /* Print formatted header and byte size.
737 * @header is locale encoded header name */
738 void print_header_size(const char *header
, size_t size
) {
742 shi_asprintf(&buffer
, _("%zu B"), size
);
743 else if (size
< (1<<20))
744 shi_asprintf(&buffer
, _("%0.2f KiB"), (float) size
/(1<<10));
746 shi_asprintf(&buffer
, _("%0.2f MiB"), (float) size
/(1<<20));
748 print_header(header
, buffer
);
753 /* Print formatted header if long int KB size is defined.
754 * @header is locale encoded header name */
755 void print_header_kbsize(const char *header
, const long int *size
) {
760 shi_asprintf(&buffer
, _("<Negative size>"));
761 else if (*size
< (1000))
762 shi_asprintf(&buffer
, _("%lu kB"), *size
);
764 shi_asprintf(&buffer
, _("%0.2f MB"), *size
/1000.0);
766 print_header(header
, buffer
);
771 static const char *DbType2string(const long int *type
) {
772 if (!type
) return NULL
;
774 case DBTYPE_SYSTEM
: return(_("System"));
775 case DBTYPE_FO
: return(_("Private individual"));
776 case DBTYPE_PFO
: return(_("Self-employed individual"));
777 case DBTYPE_PFO_ADVOK
: return(_("Lawyer"));
778 case DBTYPE_PFO_DANPOR
: return(_("Tax advisor"));
779 case DBTYPE_PFO_INSSPR
: return(_("Insolvency administrator"));
780 case DBTYPE_PO
: return(_("Organisation"));
781 case DBTYPE_PO_ZAK
: return(_("Organization based by law"));
782 case DBTYPE_PO_REQ
: return(_("Organization based on request"));
783 case DBTYPE_OVM
: return(_("Public authority"));
784 case DBTYPE_OVM_NOTAR
: return(_("Notary"));
785 case DBTYPE_OVM_EXEKUT
: return(_("Executor"));
786 case DBTYPE_OVM_REQ
: return(_("Public authority based on request"));
787 default: return(_("<Unknown type>"));
792 static const char *UserType2string(const long int *type
) {
793 if (!type
) return NULL
;
795 case USERTYPE_PRIMARY
: return(_("Primary"));
796 case USERTYPE_ENTRUSTED
: return(_("Entrusted"));
797 case USERTYPE_ADMINISTRATOR
: return(_("Administrator"));
798 case USERTYPE_OFFICIAL
: return(_("Official"));
799 default: return(_("<Unknown type>"));
804 static const char *isds_sender_type2string(const isds_sender_type
*type
) {
805 if (!type
) return NULL
;
807 case SENDERTYPE_PRIMARY
: return(_("Primary"));
808 case SENDERTYPE_ENTRUSTED
: return(_("Entrusted"));
809 case SENDERTYPE_ADMINISTRATOR
: return(_("Administrator"));
810 case SENDERTYPE_OFFICIAL
: return(_("Official"));
811 case SENDERTYPE_VIRTUAL
: return(_("Virtual"));
812 default: return(_("<unknown type>"));
817 /* Return formatted user privileges. Caller must free the string */
818 static char *UserPrivils2string(const long int *privils
) {
820 const char *priviledges
[] = {
821 N_("Read non-personal"),
823 N_("Send and read sent"),
824 N_("List messages and read delivery details"),
826 N_("Administer her box"),
827 N_("Read from safe"),
828 N_("Delete from safe")
830 const int priviledges_count
= sizeof(priviledges
)/sizeof(priviledges
[0]);
831 char *buffer
= NULL
, *new_buffer
= NULL
;
833 if (!privils
) return NULL
;
835 /*oprintf("%ld (", *privils);*/
837 for (int i
= 0; i
< priviledges_count
; i
++) {
838 if (*privils
& (1<<i
)) {
839 if ((*privils
% (1<<i
)))
840 shi_asprintf(&new_buffer
, _("%s, %s"),
841 buffer
, _(priviledges
[i
]));
843 shi_asprintf(&new_buffer
, "%s", _(priviledges
[i
]));
847 return(strdup(_("<Error while formatting privileges>")));
856 if (*privils
>= (1<<priviledges_count
)) {
857 if ((*privils
% (1<<priviledges_count
)))
858 shi_asprintf(&new_buffer
, _("%s, %s"),
859 buffer
, _("<Unknown privilege>"));
861 shi_asprintf(&new_buffer
, "%s", _("<Unknown privilege>"));
865 return(strdup(_("<Error while formatting privileges>")));
877 static const char *DmType2string(const char *type
) {
878 if (!type
) return NULL
;
879 if (!strcmp(type
, "V"))
881 else if (!strcmp(type
, "K"))
882 return(_("Commercial"));
883 else if (!strcmp(type
, "A"))
884 return(_("Commercial (initiatory, unused, subsidized)"));
885 else if (!strcmp(type
, "B"))
886 return(_("Commercial (initiatory, used, subsidized)"));
887 else if (!strcmp(type
, "C"))
888 return(_("Commercial (initiatory, expired, subsidized)"));
889 else if (!strcmp(type
, "D"))
890 return(_("Commercial (externally subsidized)"));
891 else if (!strcmp(type
, "E"))
892 return(_("Commercial (prepaid by a stamp)"));
893 else if (!strcmp(type
, "G"))
894 return(_("Commercial (sponsored)"));
895 else if (!strcmp(type
, "I"))
896 return(_("Commercial (initiatory, unused, paid by sender)"));
897 else if (!strcmp(type
, "O"))
898 return(_("Commercial (response paid by recipient)"));
899 else if (!strcmp(type
, "X"))
900 return(_("Commercial (initiatory, expired, paid by sender)"));
901 else if (!strcmp(type
, "Y"))
902 return(_("Commercial (initiatory, used, paid by sender)"));
903 else if (!strcmp(type
, "Z"))
904 return(_("Commercial (limitedly subsidized)"));
905 else return(_("<Unknown type>"));
909 /* Simplified commercial status printed on message listing.
910 * 'P' is a public message sent by a government
911 * 'C' is a commercial message
912 * 'I' is a commercial message offering to pay response instead of the
914 * 'i' is a commercial message that offered to pay reposne, but it does not
916 * 'R' is a commercial response message paid by sender of the I message. */
917 static const char DmType2flag(const char *type
) {
918 if (!type
) return ' ';
919 if (!strcmp(type
, "V")) return('P');
920 else if (!strcmp(type
, "K")) return('C');
921 else if (!strcmp(type
, "A")) return('I');
922 else if (!strcmp(type
, "B")) return('i');
923 else if (!strcmp(type
, "C")) return('i');
924 else if (!strcmp(type
, "D")) return('C');
925 else if (!strcmp(type
, "E")) return('C');
926 else if (!strcmp(type
, "G")) return('C');
927 else if (!strcmp(type
, "I")) return('I');
928 else if (!strcmp(type
, "O")) return('R');
929 else if (!strcmp(type
, "X")) return('i');
930 else if (!strcmp(type
, "Y")) return('i');
931 else if (!strcmp(type
, "Z")) return('C');
936 static const char *DmMessageStatus2string(const isds_message_status
*status
) {
937 if (!status
) return NULL
;
939 case MESSAGESTATE_SENT
: return(_("Sent"));
940 case MESSAGESTATE_STAMPED
: return(_("Stamped"));
941 case MESSAGESTATE_INFECTED
: return(_("Infected"));
942 case MESSAGESTATE_DELIVERED
: return(_("Delivered ordinary"));
943 case MESSAGESTATE_SUBSTITUTED
: return(_("Delivered substitutably"));
944 case MESSAGESTATE_RECEIVED
: return(_("Accepted"));
945 case MESSAGESTATE_READ
: return(_("Read"));
946 case MESSAGESTATE_UNDELIVERABLE
: return(_("Undeliverable"));
947 case MESSAGESTATE_REMOVED
: return(_("Deleted"));
948 case MESSAGESTATE_IN_SAFE
: return(_("Stored in safe"));
949 default: return(_("<Unknown state>"));
954 static const char DmMessageStatus2flag(const isds_message_status
*status
) {
955 if (!status
) return ' ';
957 case MESSAGESTATE_SENT
: return('>');
958 case MESSAGESTATE_STAMPED
: return('t');
959 case MESSAGESTATE_INFECTED
: return('I');
960 case MESSAGESTATE_DELIVERED
: return('N');
961 case MESSAGESTATE_SUBSTITUTED
: return('n');
962 case MESSAGESTATE_RECEIVED
: return('O');
963 case MESSAGESTATE_READ
: return(' ');
964 case MESSAGESTATE_UNDELIVERABLE
: return('!');
965 case MESSAGESTATE_REMOVED
: return('D');
966 case MESSAGESTATE_IN_SAFE
: return('S');
967 default: return('?');
972 /* Return timeval time formatted into shortest string with respect to current
973 * time. Caller must free the string. */
974 static char *timeval2shortstring(const struct timeval
*timeval
) {
975 struct tm broken
, current_broken
;
978 const size_t buffer_size
= 16;
980 if (!timeval
) return NULL
;
982 buffer
= malloc(buffer_size
);
983 if (!buffer
) goto error
;
985 /* Get current time */
986 current_time
= time(NULL
);
987 if (current_time
== (time_t) -1) goto error
;
988 if (!localtime_r(¤t_time
, ¤t_broken
)) goto error
;
990 /* Get broken time */
991 if (!localtime_r(&(timeval
->tv_sec
), &broken
)) goto error
;
993 /* Select proper abbreviated string representation */
994 if (broken
.tm_year
== current_broken
.tm_year
&&
995 broken
.tm_yday
== current_broken
.tm_yday
) {
996 /* Minute resolution in the same day */
997 if (!strftime(buffer
, buffer_size
, _("%k:%M"), &broken
))
1000 /* Otherwise month and day */
1001 if (!strftime(buffer
, buffer_size
, _("%b %d"), &broken
))
1009 return strdup(_("<Error>"));
1013 /* Formatted Law Authorization if defined. You must free it. */
1014 static char *envelope_law2string(const struct isds_envelope
*envelope
) {
1015 char *output
= NULL
;
1016 char *year_locale
= NULL
, *law_locale
= NULL
;
1017 char *sect_locale
= NULL
, *par_locale
= NULL
, *point_locale
= NULL
;
1020 !(envelope
->dmLegalTitleYear
|| envelope
->dmLegalTitleLaw
||
1021 envelope
->dmLegalTitleSect
|| envelope
->dmLegalTitlePar
||
1022 envelope
->dmLegalTitlePoint
)
1025 if (envelope
->dmLegalTitleYear
)
1026 shi_asprintf(&year_locale
, "%ld", *envelope
->dmLegalTitleYear
);
1028 year_locale
= strdup(_("?"));
1030 if (envelope
->dmLegalTitleLaw
)
1031 shi_asprintf(&law_locale
, "%ld", *envelope
->dmLegalTitleLaw
);
1033 law_locale
= strdup(_("?"));
1035 sect_locale
= utf82locale(envelope
->dmLegalTitleSect
);
1036 par_locale
= utf82locale(envelope
->dmLegalTitlePar
);
1037 point_locale
= utf82locale(envelope
->dmLegalTitlePoint
);
1040 shi_asprintf(&output
, _("point %s, par. %s, sect. %s, %s/%s Coll."),
1041 point_locale
, par_locale
, sect_locale
,
1042 law_locale
, year_locale
);
1043 else if (par_locale
)
1044 shi_asprintf(&output
, _("par. %s, sect. %s, %s/%s Coll."),
1045 par_locale
, sect_locale
, law_locale
, year_locale
);
1046 else if (sect_locale
)
1047 shi_asprintf(&output
, _("sect. %s, %s/%s Coll."),
1048 sect_locale
, law_locale
, year_locale
);
1050 shi_asprintf(&output
, _("%s/%s Coll."),
1051 law_locale
, year_locale
);
1062 static const char *isds_payment_type2string(const isds_payment_type
*type
) {
1063 if (!type
) return NULL
;
1065 case PAYMENT_SENDER
: return(_("Payed by sender"));
1066 case PAYMENT_STAMP
: return(_("Stamp pre-paid by sender"));
1067 case PAYMENT_SPONSOR
: return(_("Sponsor pays all messages"));
1068 case PAYMENT_RESPONSE
: return(_("Recipient pays a response"));
1069 case PAYMENT_SPONSOR_LIMITED
: return(_("Limitedly subsidized"));
1070 case PAYMENT_SPONSOR_EXTERNAL
: return(_("Externally subsidized"));
1071 default: return(_("<unknown type>"));
1076 /* Print formatted header if time any of message ID.
1077 * @header is locale encoded header name */
1078 static void print_header_messages_ids(const char *header
,
1079 const char *ref_number
, const char *ident
) {
1080 if (ref_number
|| ident
) {
1081 oprintf(_("%s:\n"), header
);
1082 print_header_utf8(_("\tReference number"), ref_number
);
1083 print_header_utf8(_("\tFile ID"), ident
);
1088 /* Return formatted hash value */
1089 char *hash2string(const struct isds_hash
*hash
) {
1090 const char *algorithm_string
= NULL
;
1091 char *buffer
= NULL
, *octet
= NULL
, *new_buffer
= NULL
;
1093 if (!hash
|| !hash
->value
) return NULL
;
1095 switch(hash
->algorithm
) {
1096 case HASH_ALGORITHM_MD5
: algorithm_string
= (_("MD5")); break;
1097 case HASH_ALGORITHM_SHA_1
: algorithm_string
= (_("SHA-1")); break;
1098 case HASH_ALGORITHM_SHA_224
: algorithm_string
= (_("SHA-224")); break;
1099 case HASH_ALGORITHM_SHA_256
: algorithm_string
= (_("SHA-256")); break;
1100 case HASH_ALGORITHM_SHA_384
: algorithm_string
= (_("SHA-384")); break;
1101 case HASH_ALGORITHM_SHA_512
: algorithm_string
= (_("SHA-512")); break;
1102 default: algorithm_string
= (_("<Unknown hash algorithm>")); break;
1105 for (int i
= 0; i
< hash
->length
; i
++) {
1106 shi_asprintf(&octet
, "%02x", ((uint8_t *)(hash
->value
))[i
]);
1108 free(buffer
); free(octet
); return NULL
;
1112 shi_asprintf(&new_buffer
, _("%s:%s"), buffer
, octet
);
1114 shi_asprintf(&new_buffer
, "%s", octet
);
1116 free(buffer
); free(octet
); return NULL
;
1119 buffer
= new_buffer
; new_buffer
= NULL
;
1122 shi_asprintf(&new_buffer
, _("%s %s"), algorithm_string
, buffer
);
1129 /* Print if any message delivery info exists. */
1130 void print_message_delivery_info(const struct isds_envelope
*envelope
) {
1131 char *hash_string
= NULL
;
1133 if (envelope
&& (envelope
->dmType
|| envelope
->dmMessageStatus
||
1134 envelope
->dmDeliveryTime
||
1135 envelope
->dmAcceptanceTime
|| envelope
->dmPersonalDelivery
||
1136 envelope
->dmAllowSubstDelivery
|| envelope
->hash
||
1137 envelope
->dmOrdinal
)) {
1138 oprintf(_("Delivery data:\n"));
1139 print_header(_("\tMessage type"), DmType2string(envelope
->dmType
));
1140 print_header(_("\tMessage status"),
1141 DmMessageStatus2string(envelope
->dmMessageStatus
));
1142 print_header_timeval(_("\tDelivered"), envelope
->dmDeliveryTime
);
1143 print_header_timeval(_("\tAccepted"), envelope
->dmAcceptanceTime
);
1144 print_header_bool(_("\tPersonal delivery required"),
1145 envelope
->dmPersonalDelivery
);
1146 print_header_bool(_("\tAllow substitutable delivery"),
1147 envelope
->dmAllowSubstDelivery
);
1149 hash_string
= hash2string(envelope
->hash
);
1150 print_header(_("\tHash"), hash_string
);
1153 print_header_ulongint(_("\tOrdinal number"), envelope
->dmOrdinal
);
1158 static const char *event_type2string(const isds_event_type
*type
) {
1159 if (!type
) return (_("<Undefined>"));
1162 case EVENT_UKNOWN
: return(_("Unknown"));
1163 case EVENT_ENTERED_SYSTEM
:
1164 return(_("Entered system"));
1165 case EVENT_ACCEPTED_BY_RECIPIENT
:
1166 return(_("Accepted by recipient"));
1167 case EVENT_ACCEPTED_BY_FICTION
:
1168 return(_("Delivered substitutably"));
1169 case EVENT_UNDELIVERABLE
:
1170 return(_("Undeliverable"));
1171 case EVENT_COMMERCIAL_ACCEPTED
:
1172 return(_("Commerical message accepted by "
1173 "recipient")); break;
1174 case EVENT_DELIVERED
:
1175 return(_("Delivered into box")); break;
1176 case EVENT_PRIMARY_LOGIN
:
1177 return(_("Primary user logged in")); break;
1178 case EVENT_ENTRUSTED_LOGIN
:
1179 return(_("Entrusted user logged in")); break;
1180 case EVENT_SYSCERT_LOGIN
:
1181 return(_("Application logged in by system "
1182 "certificate")); break;
1183 default: return(_("<Unknown event type>"));
1188 /* Print if any delivery event exists. */
1189 void print_delivery_events(const struct isds_list
*events
) {
1190 int counter_width
= 3;
1192 const struct isds_list
*item
;
1193 struct isds_event
*event
;
1195 if (!events
) return;
1197 oprintf(_("Delivery events:\n"));
1199 for (item
= events
; item
; item
= item
->next
) {
1200 event
= (struct isds_event
*) item
->data
;
1201 if (!event
) continue;
1204 oprintf(_("%*d %s\n"), counter_width
, order
,
1205 event_type2string(event
->type
));
1206 print_header_utf8(_("\tDescription"), event
->description
);
1207 print_header_timeval(_("\tWhen"), event
->time
);
1212 /* Print formatted message envelope */
1213 void format_envelope(const struct isds_envelope
*envelope
) {
1214 char *law_string
= NULL
;
1217 oprintf(_("<Missing envelope>\n"));
1221 print_header_utf8(_("Message ID"), envelope
->dmID
);
1223 if (envelope
->dbIDSender
|| envelope
->dmSender
||
1224 envelope
->dmSenderOrgUnit
|| envelope
->dmSenderOrgUnitNum
||
1225 envelope
->dmSenderAddress
|| envelope
->dmSenderType
||
1226 envelope
->dmOVM
|| envelope
->dmPublishOwnID
) {
1227 oprintf(_("Sender:\n"));
1228 print_header_utf8(_("\tID"), envelope
->dbIDSender
);
1229 print_header_utf8(_("\tName"), envelope
->dmSender
);
1230 print_header_utf8(_("\tUnit"), envelope
->dmSenderOrgUnit
);
1231 print_header_longint(_("\tUnit number"), envelope
->dmSenderOrgUnitNum
);
1232 print_header_utf8(_("\tAddress"), envelope
->dmSenderAddress
);
1233 print_header(_("\tType"), DbType2string(envelope
->dmSenderType
));
1234 print_header_bool(_("\tAs public authority"), envelope
->dmOVM
);
1235 print_header_bool(_("\tPublish user's identity"),
1236 envelope
->dmPublishOwnID
);
1239 if (envelope
->dbIDRecipient
|| envelope
->dmRecipient
||
1240 envelope
->dmRecipientOrgUnit
|| envelope
->dmRecipientOrgUnitNum
||
1241 envelope
->dmToHands
|| envelope
->dmRecipientAddress
||
1242 envelope
->dmAmbiguousRecipient
) {
1243 oprintf(_("Recipient:\n"));
1244 print_header_utf8(_("\tID"), envelope
->dbIDRecipient
);
1245 print_header_utf8(_("\tName"), envelope
->dmRecipient
);
1246 print_header_utf8(_("\tUnit"), envelope
->dmRecipientOrgUnit
);
1247 print_header_longint(_("\tUnit number"),
1248 envelope
->dmRecipientOrgUnitNum
);
1249 print_header_utf8(_("To hands"), envelope
->dmToHands
);
1250 print_header_utf8(_("\tAddress"), envelope
->dmRecipientAddress
);
1251 print_header_bool(_("\tAs public authority"),
1252 envelope
->dmAmbiguousRecipient
);
1255 print_header_utf8(_("Subject"), envelope
->dmAnnotation
);
1257 print_header_messages_ids(_("Sender message IDs"),
1258 envelope
->dmSenderRefNumber
, envelope
->dmSenderIdent
);
1259 print_header_messages_ids(_("Recipient message IDs"),
1260 envelope
->dmRecipientRefNumber
, envelope
->dmRecipientIdent
);
1262 law_string
= envelope_law2string(envelope
);
1263 print_header(_("Law authorization"), law_string
);
1266 print_message_delivery_info(envelope
);
1268 print_header_kbsize(_("Document total size"), envelope
->dmAttachmentSize
);
1270 /*oprintf("\t\ttimestamp = %p\n", envelope->timestamp);
1271 oprintf("\t\ttimestamp_length = %zu\n", envelope->timestamp_length);*/
1272 print_delivery_events(envelope
->events
);
1276 const char *DmFileMetaType2string(isds_FileMetaType type
) {
1278 case FILEMETATYPE_MAIN
: return(_("Main document"));
1279 case FILEMETATYPE_ENCLOSURE
: return(_("Enclosure"));
1280 case FILEMETATYPE_SIGNATURE
: return(_("Signature"));
1281 case FILEMETATYPE_META
: return(_("Meta document"));
1282 default: return(_("<unknown document type>"));
1287 /* Computes ordinal number of document identified by GUID
1288 * @documents is list of documents where to search
1289 * @id is UTF-8 encoded document ID reference
1290 * Return allocated array of ordinal numbers terminated by -1. Normally only
1291 * one document with @id exists. However ISDS does not check this higher
1292 * requirements and can transport message with duplicate document identifiers.
1293 * Therefore this function returns array of ordinals. Return NULL if error
1294 * occurs (e.g. memory insufficiency). */
1295 static int *dmFileGuid2ordinar(const struct isds_list
*documents
,
1297 const struct isds_list
*item
;
1298 struct isds_document
*document
;
1299 size_t ordinars_length
= 64, offset
= 0;
1300 int *ordinars
= NULL
, *new_ordinars
;
1303 if (!documents
|| !id
|| !*id
) return NULL
;
1304 ordinars
= malloc(ordinars_length
* sizeof(*ordinars
));
1305 if (!ordinars
) return NULL
;
1307 for (item
= documents
; item
; item
= item
->next
) {
1308 if (!item
->data
) continue;
1310 document
= (struct isds_document
*) (item
->data
);
1312 if (document
->dmFileGuid
&& !strcmp(document
->dmFileGuid
, id
)) {
1313 if (offset
== ordinars_length
) {
1314 /* Grow ordinals array */
1315 ordinars_length
*= 2;
1316 new_ordinars
= realloc(ordinars
,
1317 ordinars_length
* sizeof(*ordinars
));
1318 if (!new_ordinars
) {
1322 ordinars
= new_ordinars
;
1325 ordinars
[offset
++] = ordinar
;
1329 ordinars
[offset
] = -1;
1334 /* @id is UTF-8 encoded GUID of referred document
1335 * @refernces is array of ordinal numbers if exist terminated by -1. Can be
1336 * NULL to signal error. */
1337 static void format_document_reference(char *id
, int *references
) {
1338 char *buffer
= NULL
, *new_buffer
= NULL
;
1341 if (references
&& *references
!= -1) {
1342 for (; *references
> 0; references
++) {
1344 shi_asprintf(&new_buffer
, _("%d"), *references
);
1346 shi_asprintf(&new_buffer
, _("%s, %d"), buffer
, *references
);
1352 buffer
= new_buffer
;
1356 char *id_locale
= utf82locale(id
);
1357 shi_asprintf(&buffer
,
1358 _("<Reference to non-existing document ID `%s'>"), id_locale
);
1363 print_header(_("\tRefers to"), buffer
);
1365 print_header(_("\tRefers to"), _("<Error while formatting reference>"));
1370 /* Print formatted document
1371 * @references is ordinal number of referred document. Formally it's array
1372 * terminated by -1 because non-well-formed message can have more documents
1374 void format_document(const struct isds_document
*document
, int order
,
1376 int counter_width
= 3;
1377 char *filename_locale
= NULL
;
1379 if (!document
) return;
1381 oprintf(_("%*d "), counter_width
, order
);
1383 if (document
->dmFileDescr
) {
1384 filename_locale
= utf82locale(document
->dmFileDescr
);
1385 oprintf("%s\n", filename_locale
);
1386 free(filename_locale
);
1388 oprintf(_("<Unknown file name>\n"));
1391 if (document
->is_xml
) {
1392 char *message
=NULL
;
1395 for (xmlNodePtr node
= document
->xml_node_list
; node
;
1396 node
= node
->next
) nodes
++;
1397 shi_asprintf(&message
, ngettext("%d node", "%d nodes", nodes
), nodes
);
1399 print_header(_("\tXML document"), message
);
1403 print_header_size(_("\tSize"), document
->data_length
);
1405 print_header(_("\tMIME type"), document
->dmMimeType
);
1407 print_header(_("\tType"), DmFileMetaType2string(document
->dmFileMetaType
));
1408 print_header_utf8(_("\tMeta format"), document
->dmFormat
);
1410 print_header_utf8(_("\tID"), document
->dmFileGuid
);
1411 format_document_reference(document
->dmUpFileGuid
, references
);
1415 /* Print formatted message documents */
1416 void format_documents(const struct isds_list
*documents
) {
1417 const struct isds_list
*item
;
1418 const struct isds_document
*document
;
1421 if (!documents
) return;
1423 oprintf(_("Documents:\n"));
1425 for (item
= documents
; item
; item
= item
->next
) {
1426 if (!item
->data
) continue;
1427 document
= (struct isds_document
*) item
->data
;
1428 references
= dmFileGuid2ordinar(documents
, document
->dmUpFileGuid
);
1429 format_document(document
, ++i
, references
);
1435 /* Print formatted message */
1436 void format_message(const struct isds_message
*message
) {
1437 if (!message
) return;
1438 format_envelope(message
->envelope
);
1439 format_documents(message
->documents
);
1443 /* Print formatted list of message copies */
1444 void format_copies(const struct isds_list
*copies
) {
1445 const struct isds_list
*item
;
1446 const struct isds_message_copy
*copy
;
1448 int counter_width
= 3;
1449 if (!copies
) return;
1451 for (item
= copies
; item
; item
= item
->next
) {
1452 if (!item
->data
) continue;
1453 copy
= (struct isds_message_copy
*) item
->data
;
1456 oprintf(_("%*d Recipient:\n"), counter_width
, i
);
1457 print_header_utf8(_("\tID"), copy
->dbIDRecipient
);
1458 print_header_utf8(_("\tUnit"), copy
->dmRecipientOrgUnit
);
1459 print_header_longint(_("\tUnit number"), copy
->dmRecipientOrgUnitNum
);
1460 print_header_utf8(_("\tTo hands"), copy
->dmToHands
);
1465 void print_message_list(const struct isds_list
*messages
, _Bool outgoing
) {
1466 const struct isds_list
*item
;
1467 struct isds_envelope
*envelope
;
1468 unsigned long int counter
= 0;
1470 int counter_max
, id_max
= 0, name_max
= 0, subject_max
= 0;
1471 int counter_width
, id_width
= 0, flags_width
= 2, time_width
= 6,
1472 name_width
= 0, subject_width
= 0;
1474 char *id_locale
= NULL
, flags_locale
[3], *time_locale
= NULL
,
1475 *name_locale
= NULL
, *subject_locale
= NULL
;
1480 /* Compute column widths */
1481 rl_get_screen_size(NULL
, &screen_cols
);
1483 /* Get real maximal widths */
1484 for (counter
= 0, item
= messages
; item
; item
= item
->next
) {
1485 if (!item
->data
|| !((struct isds_message
*)item
->data
)->envelope
)
1487 envelope
= ((struct isds_message
*) item
->data
)->envelope
;
1490 width
= utf8width(envelope
->dmID
);
1491 if (width
> id_max
) id_max
= width
;
1493 width
= utf8width((outgoing
) ?
1494 envelope
->dmRecipient
: envelope
->dmSender
);
1495 if (width
> name_max
) name_max
= width
;
1497 width
= utf8width(envelope
->dmAnnotation
);
1498 if (width
> subject_max
) subject_max
= width
;
1500 counter_max
= numberwidth(counter
);
1502 /* Correct widths to fit into window */
1503 if (counter_max
< 0) counter_width
= -3; else counter_width
= counter_max
;
1504 if (id_max
< 0) id_width
= -6; else id_width
= id_max
;
1505 if (name_max
< 0) name_width
= -20; else name_width
= name_max
;
1506 if (subject_max
< 0) subject_width
= -32; else subject_width
= subject_max
;
1508 width
= abs(counter_width
) + 1 + abs(id_width
) + 1 + abs(flags_width
) + 1 +
1509 abs(time_width
) + 1 + abs(name_width
) + 1 + abs(subject_width
);
1510 if (width
> screen_cols
) {
1511 width
-= abs(name_width
) + abs(subject_width
);
1513 name_width
= subject_width
= 0;
1514 while (width
+ name_width
+ subject_width
< screen_cols
) {
1515 if (name_width
< abs(name_max
)) name_width
++;
1516 if (subject_width
< abs(subject_max
)) subject_width
++;
1518 if (width
+ name_width
+ subject_width
> screen_cols
) subject_width
--;
1522 /* TRANSLATORS: "No" is abbreviation for "Number" in listing header. */
1523 onprint(pgettext("list header", "No"), counter_width
);
1525 onprint(_("ID"), id_width
);
1527 onprint(_("Flags"), flags_width
);
1529 onprint(_("Delivered"), time_width
);
1531 onprint((outgoing
) ? _("To") : _("From"), name_width
);
1533 onprint(_("Subject"), subject_width
);
1535 for (int i
= 0; i
< screen_cols
; i
++) oprintf(_("-"));
1538 /* Print the list */
1539 for (counter
= 0, item
= messages
; item
; item
= item
->next
) {
1540 envelope
= ((struct isds_message
*) item
->data
)->envelope
;
1543 oprintf(_("%*lu "), counter_width
, counter
);
1546 oprintf(_("<Missing envelope>\n"));
1550 id_locale
= utf82locale(envelope
->dmID
);
1551 name_locale
= utf82locale((outgoing
) ?
1552 envelope
->dmRecipient
: envelope
->dmSender
);
1553 flags_locale
[0] = DmType2flag(envelope
->dmType
);
1554 flags_locale
[1] = DmMessageStatus2flag(envelope
->dmMessageStatus
);
1555 flags_locale
[2] = '\0';
1556 time_locale
= timeval2shortstring(envelope
->dmDeliveryTime
);
1557 subject_locale
= utf82locale(envelope
->dmAnnotation
);
1559 onprint(id_locale
, id_width
);
1561 onprint(flags_locale
, flags_width
);
1563 onprint(time_locale
, time_width
);
1565 onprint(name_locale
, name_width
);
1567 onprint(subject_locale
, subject_width
);
1573 zfree(subject_locale
);
1578 static void format_PersonName(const struct isds_PersonName
*personName
) {
1579 if (!personName
) return;
1581 oprintf(_("Person name:\n"));
1582 print_header_utf8(_("\tFirst"), personName
->pnFirstName
);
1583 print_header_utf8(_("\tMiddle"), personName
->pnMiddleName
);
1584 print_header_utf8(_("\tLast"), personName
->pnLastName
);
1585 print_header_utf8(_("\tLast at birth"),
1586 personName
->pnLastNameAtBirth
);
1590 static void format_BirthInfo(const struct isds_BirthInfo
*birth
) {
1591 if (!birth
|| !(birth
->biDate
|| birth
->biCity
|| birth
->biCounty
1592 || birth
->biState
)) return;
1594 oprintf(_("Birth details:\n"));
1596 print_header_tm(_("\tDate"), birth
->biDate
);
1597 print_header_utf8(_("\tCity"), birth
->biCity
);
1598 print_header_utf8(_("\tCounty"), birth
->biCounty
);
1599 print_header_utf8(_("\tState"), birth
->biState
);
1603 static void format_Address(const struct isds_Address
*address
) {
1604 if (!address
|| !(address
->adCity
|| address
->adState
||
1605 address
->adNumberInStreet
|| address
->adNumberInMunicipality
||
1606 address
->adZipCode
|| address
->adState
)) return;
1608 oprintf("Address:\n");
1609 print_header_utf8(_("\tCity"), address
->adCity
);
1610 print_header_utf8(_("\tStreet"), address
->adStreet
);
1611 print_header_utf8(_("\tNumber in street"), address
->adNumberInStreet
);
1612 print_header_utf8(_("\tNumber in municipality"),
1613 address
->adNumberInMunicipality
);
1614 print_header_utf8(_("\tZIP code"), address
->adZipCode
);
1615 print_header_utf8(_("\tState"), address
->adState
);
1619 /* Return static box state string or NULL if undefined */
1620 const char *DbState2string(const long int *state
) {
1621 if (!state
) return NULL
;
1624 case DBSTATE_ACCESSIBLE
: return(_("Accessible"));
1625 case DBSTATE_TEMP_UNACCESSIBLE
: return(_("Temporary inaccessible"));
1626 case DBSTATE_NOT_YET_ACCESSIBLE
: return(_("Not yet accessible"));
1627 case DBSTATE_PERM_UNACCESSIBLE
: return(_("Permanently inaccessible"));
1628 case DBSTATE_REMOVED
: return(_("Deleted"));
1629 default: return(_("<unknown state>"));
1634 void format_DbOwnerInfo(const struct isds_DbOwnerInfo
*info
) {
1637 print_header_utf8(_("Box ID"), info
->dbID
);
1638 print_header(_("Type"), DbType2string((long int *) (info
->dbType
)));
1639 print_header_utf8(_("Subject name"), info
->firmName
);
1640 print_header_utf8(_("Identity number"), info
->ic
);
1642 format_PersonName(info
->personName
);
1643 format_BirthInfo(info
->birthInfo
);
1645 format_Address(info
->address
);
1647 print_header_utf8(_("Nationality"), info
->nationality
);
1648 print_header_utf8(_("E-mail"), info
->email
);
1649 print_header_utf8(_("Phone"), info
->telNumber
);
1651 print_header_utf8(_("Identifier"), info
->identifier
);
1652 print_header_utf8(_("Registry code"), info
->registryCode
);
1654 print_header(_("State"), DbState2string(info
->dbState
));
1655 print_header_bool(_("Act as public authority"), info
->dbEffectiveOVM
);
1656 print_header_bool(_("Receive commercial messages"),
1657 info
->dbOpenAddressing
);
1661 static void format_supervising_firm(const char *ic
, const char *firmName
) {
1662 if (!ic
&& !firmName
) return;
1664 oprintf(_("Supervising subject:\n"));
1665 print_header_utf8(_("\tIdentity number"), ic
);
1666 print_header_utf8(_("\tName"), firmName
);
1670 static void format_contact_address(const char *caStreet
, const char *caCity
,
1671 const char *caZipCode
, const char *caState
) {
1672 if (!caStreet
&& !caCity
&& !caZipCode
) return;
1674 oprintf(_("Contact address:\n"));
1675 print_header_utf8(_("\tStreet"), caStreet
);
1676 print_header_utf8(_("\tCity"), caCity
);
1677 print_header_utf8(_("\tZIP code"), caZipCode
);
1678 print_header_utf8(_("\tState"), caState
);
1682 void format_DbUserInfo(const struct isds_DbUserInfo
*info
) {
1687 print_header_utf8(_("User ID"), info
->userID
);
1688 print_header(_("Type"), UserType2string((long int *) (info
->userType
)));
1690 buffer
= UserPrivils2string(info
->userPrivils
);
1691 print_header(_("Privileges"), buffer
);
1694 format_PersonName(info
->personName
);
1695 format_Address(info
->address
);
1697 print_header_tm(_("Birth date"), info
->biDate
);
1699 format_supervising_firm(info
->ic
, info
->firmName
);
1700 format_contact_address(info
->caStreet
, info
->caCity
, info
->caZipCode
,
1705 /* Print formated details about message sender */
1706 void format_sender_info(const char *dbID
, const isds_sender_type
*type
,
1707 const char *raw_type
, const char *name
) {
1708 const char *type_string
;
1710 if (!dbID
&& !type
&& !raw_type
&& !name
) return;
1712 oprintf(_("Message sender:\n"));
1713 print_header_utf8(_("\tMessage ID"), dbID
);
1715 type_string
= isds_sender_type2string(type
);
1717 print_header(_("\tType"), type_string
);
1719 print_header_utf8(_("\tRaw type"), raw_type
);
1721 print_header_utf8(_("\tName"), name
);
1725 static const char *credit_event_type2string(
1726 const isds_credit_event_type type
) {
1728 case ISDS_CREDIT_CHARGED
: return(_("Credit charged"));
1729 case ISDS_CREDIT_DISCHARGED
: return(_("Credit discharged"));
1730 case ISDS_CREDIT_MESSAGE_SENT
: return(_("Message sent"));
1731 case ISDS_CREDIT_STORAGE_SET
: return(_("Long-term storage set"));
1732 case ISDS_CREDIT_EXPIRED
: return(_("Credit expired"));
1733 default: return(_("<Unknown credit event type>"));
1738 /* Print formated details about credit change event */
1739 void format_credit_event(const struct isds_credit_event
*event
) {
1740 if (NULL
== event
) return;
1742 print_header_timeval(_("When"), event
->time
);
1743 /* FIXME: Format the currency */
1744 print_header_longint(_("Credit change [CZK/100]"), &event
->credit_change
);
1745 print_header_longint(_("Total credit [CZK/100]"), &event
->new_credit
);
1746 print_header(_("Type"), credit_event_type2string(event
->type
));
1748 switch (event
->type
) {
1749 case ISDS_CREDIT_CHARGED
:
1750 print_header(_("Transation ID"),
1751 event
->details
.charged
.transaction
);
1753 case ISDS_CREDIT_DISCHARGED
:
1754 print_header(_("Transation ID"),
1755 event
->details
.discharged
.transaction
);
1757 case ISDS_CREDIT_MESSAGE_SENT
:
1758 print_header(_("Message ID"),
1759 event
->details
.message_sent
.message_id
);
1760 print_header(_("Message recipient"),
1761 event
->details
.message_sent
.recipient
);
1763 case ISDS_CREDIT_STORAGE_SET
:
1764 if (NULL
!= event
->details
.storage_set
.old_capacity
) {
1765 oprintf(_("Old setting:\n"));
1766 oprintf(ngettext("%s: %ld message\n", "%s: %ld messages",
1767 *event
->details
.storage_set
.old_capacity
),
1769 *event
->details
.storage_set
.old_capacity
);
1770 print_header_tm(_("\tValid from"),
1771 event
->details
.storage_set
.old_valid_from
);
1772 print_header_tm(_("\tValid to"),
1773 event
->details
.storage_set
.old_valid_to
);
1775 oprintf(_("New setting:\n"));
1776 oprintf(ngettext("%s: %ld message\n", "%s: %ld messages",
1777 event
->details
.storage_set
.new_capacity
),
1779 event
->details
.storage_set
.new_capacity
);
1780 print_header_tm(_("\tValid from"),
1781 event
->details
.storage_set
.new_valid_from
);
1782 print_header_tm(_("\tValid to"),
1783 event
->details
.storage_set
.new_valid_to
);
1784 print_header_utf8(_("Initiator"),
1785 event
->details
.storage_set
.initiator
);
1787 case ISDS_CREDIT_EXPIRED
:
1790 oprintf(_("Detail can be missing due to unkown type.\n"));
1795 void format_commercial_permission(
1796 const struct isds_commercial_permission
*permission
) {
1797 if (NULL
== permission
) return;
1799 print_header(_("Payment type"),
1800 isds_payment_type2string(&permission
->type
));
1801 print_header_utf8(_("Allowed recipient box ID"), permission
->recipient
);
1802 print_header_utf8(_("Payed by owner of box ID"), permission
->payer
);
1803 print_header_timeval(_("Permission expires"), permission
->expiration
);
1804 print_header_ulongint(_("Remaining messages"), permission
->count
);
1805 print_header_utf8(_("Reference to request"), permission
->reply_identifier
);