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_AUDITOR
: oprintf("PFO_AUDITOR\n"); break;
37 case DBTYPE_PFO_DANPOR
: oprintf("PFO_DAPOR\n"); break;
38 case DBTYPE_PFO_INSSPR
: oprintf("PFO_INSSPR\n"); break;
39 case DBTYPE_PO
: oprintf("PO\n"); break;
40 case DBTYPE_PO_ZAK
: oprintf("PO_ZAK\n"); break;
41 case DBTYPE_PO_REQ
: oprintf("PO_REQ\n"); break;
42 case DBTYPE_OVM
: oprintf("OVM\n"); break;
43 case DBTYPE_OVM_EXEKUT
: oprintf("OVM_EXEKUT\n"); break;
44 case DBTYPE_OVM_FO
: oprintf("OVM_FO\n"); break;
45 case DBTYPE_OVM_NOTAR
: oprintf("OVM_NOTAR\n"); break;
46 case DBTYPE_OVM_PFO
: oprintf("OVM_PFO\n"); break;
47 case DBTYPE_OVM_PO
: oprintf("OVM_PO\n"); break;
48 case DBTYPE_OVM_REQ
: oprintf("OVM_REQ\n"); break;
49 default: oprintf("<unknown type %ld>\n", *type
);
54 void print_UserType(const long int *type
) {
55 if (!type
) oprintf("NULL\n");
58 case USERTYPE_PRIMARY
: oprintf("PRIMARY\n"); break;
59 case USERTYPE_ENTRUSTED
: oprintf("ENTRUSTED\n"); break;
60 case USERTYPE_ADMINISTRATOR
: oprintf("ADMINISTRATOR\n"); break;
61 case USERTYPE_OFFICIAL
: oprintf("OFFICIAL\n"); break;
62 default: oprintf("<unknown type %ld>\n", *type
);
67 void print_UserPrivils(const long int *privils
) {
69 const char *priviledges
[] = {
79 const int priviledges_count
= sizeof(priviledges
)/sizeof(priviledges
[0]);
81 if (!privils
) oprintf("NULL\n");
83 oprintf("%ld (", *privils
);
85 for (int i
= 0; i
< priviledges_count
; i
++) {
86 if (*privils
& (1<<i
)) {
88 ((i
+ 1) == priviledges_count
) ? "%s" : "%s|",
98 void print_hash(const struct isds_hash
*hash
) {
104 switch(hash
->algorithm
) {
105 case HASH_ALGORITHM_MD5
: oprintf("MD5 "); break;
106 case HASH_ALGORITHM_SHA_1
: oprintf("SHA-1 "); break;
107 case HASH_ALGORITHM_SHA_256
: oprintf("SHA-256 "); break;
108 case HASH_ALGORITHM_SHA_512
: oprintf("SHA-512 "); break;
109 default: oprintf("<Unknown hash algorithm %d> ", hash
->algorithm
);
113 if (!hash
->value
) oprintf("<NULL>");
115 for (int i
= 0; i
< hash
->length
; i
++) {
116 if (i
> 0) oprintf(":");
117 oprintf("%02x", ((uint8_t *)(hash
->value
))[i
]);
124 void print_raw_type(const isds_raw_type type
) {
126 case RAWTYPE_INCOMING_MESSAGE
:
127 oprintf("INCOMING_MESSAGE\n"); break;
128 case RAWTYPE_PLAIN_SIGNED_INCOMING_MESSAGE
:
129 oprintf("PLAIN_SIGNED_INCOMING_MESSAGE\n"); break;
130 case RAWTYPE_CMS_SIGNED_INCOMING_MESSAGE
:
131 oprintf("CMS_SIGNED_INCOMING_MESSAGE\n"); break;
132 case RAWTYPE_PLAIN_SIGNED_OUTGOING_MESSAGE
:
133 oprintf("PLAIN_SIGNED_OUTGOING_MESSAGE\n"); break;
134 case RAWTYPE_CMS_SIGNED_OUTGOING_MESSAGE
:
135 oprintf("CMS_SIGNED_OUTGOING_MESSAGE\n"); break;
136 case RAWTYPE_DELIVERYINFO
:
137 oprintf("DELIVERYINFO\n"); break;
138 case RAWTYPE_PLAIN_SIGNED_DELIVERYINFO
:
139 oprintf("PLAIN_SIGNED_DELIVERYINFO\n"); break;
140 case RAWTYPE_CMS_SIGNED_DELIVERYINFO
:
141 oprintf("CMS_SIGNED_DELIVERYINFO\n"); break;
143 oprintf("<Unknown raw type %d> ", type
);
149 void print_bool(const _Bool
*boolean
) {
150 oprintf("%s\n", (!boolean
) ? "NULL" : ((*boolean
)? "true" : "false") );
154 void print_longint(const long int *number
) {
155 if (!number
) oprintf("NULL\n");
156 else oprintf("%ld\n", *number
);
160 void print_PersonName(const struct isds_PersonName
*personName
) {
161 oprintf("\tpersonName = ");
162 if (!personName
) oprintf("NULL\n");
165 oprintf("\t\tpnFirstName = %s\n", personName
->pnFirstName
);
166 oprintf("\t\tpnMiddleName = %s\n", personName
->pnMiddleName
);
167 oprintf("\t\tpnLastName = %s\n", personName
->pnLastName
);
168 oprintf("\t\tpnLastNameAtBirth = %s\n", personName
->pnLastNameAtBirth
);
174 void print_Address(const struct isds_Address
*address
) {
175 oprintf("\taddress = ");
176 if (!address
) oprintf("NULL\n");
179 oprintf("\t\tadCity = %s\n", address
->adCity
);
180 oprintf("\t\tadStreet = %s\n", address
->adStreet
);
181 oprintf("\t\tadNumberInStreet = %s\n", address
->adNumberInStreet
);
182 oprintf("\t\tadNumberInMunicipality = %s\n",
183 address
->adNumberInMunicipality
);
184 oprintf("\t\tadZipCode = %s\n", address
->adZipCode
);
185 oprintf("\t\tadState = %s\n", address
->adState
);
191 void print_date(const struct tm
*date
) {
192 if (!date
) oprintf("NULL\n");
193 else oprintf("%s", asctime(date
));
197 void print_DbOwnerInfo(const struct isds_DbOwnerInfo
*info
) {
198 oprintf("dbOwnerInfo = ");
206 oprintf("\tdbID = %s\n", info
->dbID
);
208 oprintf("\tdbType = ");
209 print_DbType((long int *) (info
->dbType
));
210 oprintf("\tic = %s\n", info
->ic
);
212 print_PersonName(info
->personName
);
214 oprintf("\tfirmName = %s\n", info
->firmName
);
216 oprintf("\tbirthInfo = ");
217 if (!info
->birthInfo
) oprintf("NULL\n");
221 oprintf("\t\tbiDate = ");
222 print_date(info
->birthInfo
->biDate
);
224 oprintf("\t\tbiCity = %s\n", info
->birthInfo
->biCity
);
225 oprintf("\t\tbiCounty = %s\n", info
->birthInfo
->biCounty
);
226 oprintf("\t\tbiState = %s\n", info
->birthInfo
->biState
);
230 print_Address(info
->address
);
232 oprintf("\tnationality = %s\n", info
->nationality
);
233 oprintf("\temail = %s\n", info
->email
);
234 oprintf("\ttelNumber = %s\n", info
->telNumber
);
235 oprintf("\tidentifier = %s\n", info
->identifier
);
236 oprintf("\tregistryCode = %s\n", info
->registryCode
);
238 oprintf("\tdbState = ");
239 if (!info
->dbState
) oprintf("NULL\n");
240 else print_DbState(*(info
->dbState
));
242 oprintf("\tdbEffectiveOVM = ");
243 print_bool(info
->dbEffectiveOVM
);
245 oprintf("\tdbOpenAddressing = ");
246 print_bool(info
->dbOpenAddressing
);
253 void print_DbUserInfo(const struct isds_DbUserInfo
*info
) {
254 oprintf("dbUserInfo = ");
262 oprintf("\tuserID = %s\n", info
->userID
);
264 oprintf("\tuserType = ");
265 print_UserType((long int *) (info
->userType
));
267 oprintf("\tuserPrivils = ");
268 print_UserPrivils(info
->userPrivils
);
270 print_PersonName(info
->personName
);
271 print_Address(info
->address
);
273 oprintf("\tbiDate = ");
274 print_date(info
->biDate
);
276 oprintf("\tic = %s\n", info
->ic
);
277 oprintf("\tfirmName = %s\n", info
->firmName
);
279 oprintf("\tcaStreet = %s\n", info
->caStreet
);
280 oprintf("\tcaCity = %s\n", info
->caCity
);
281 oprintf("\tcaZipCode = %s\n", info
->caZipCode
);
287 void print_timeval(const struct timeval
*time
) {
296 if (!localtime_r(&(time
->tv_sec
), &broken
)) goto error
;
297 if (!strftime(buffer
, sizeof(buffer
)/sizeof(char), "%c", &broken
))
299 oprintf("%s, %jd us\n", buffer
, (intmax_t)time
->tv_usec
);
303 oprintf("<Error while formatting>\n>");
308 void print_event_type(const isds_event_type
*type
) {
314 case EVENT_UKNOWN
: oprintf("UNKNOWN\n"); break;
315 case EVENT_ENTERED_SYSTEM
: printf("ENTERED_SYSTEM\n"); break;
316 case EVENT_ACCEPTED_BY_RECIPIENT
:
317 oprintf("ACCEPTED_BY_RECIPIENT\n"); break;
318 case EVENT_ACCEPTED_BY_FICTION
:
319 oprintf("DELIVERED_BY_FICTION\n"); break;
320 case EVENT_UNDELIVERABLE
:
321 oprintf("UNDELIVERABLE\n"); break;
322 case EVENT_COMMERCIAL_ACCEPTED
:
323 oprintf("COMMERCIAL_ACCEPTED\n"); break;
324 case EVENT_DELIVERED
:
325 oprintf("DELIVERED\n"); break;
326 case EVENT_PRIMARY_LOGIN
:
327 oprintf("PRIMARY_LOGIN\n"); break;
328 case EVENT_ENTRUSTED_LOGIN
:
329 oprintf("ENTRUSTED_LOGIN\n"); break;
330 case EVENT_SYSCERT_LOGIN
:
331 oprintf("SYSCERT_LOGIN\n"); break;
332 default: oprintf("<unknown type %d>\n", *type
);
337 void print_events(const struct isds_list
*events
) {
338 const struct isds_list
*item
;
339 const struct isds_event
*event
;
348 for (item
= events
; item
; item
= item
->next
) {
349 event
= (struct isds_event
*) item
->data
;
350 oprintf("\t\t\tevent = ");
351 if (!event
) oprintf("NULL");
355 oprintf("\t\t\t\ttype = ");
356 print_event_type(event
->type
);
358 oprintf("\t\t\t\tdescription = %s\n", event
->description
);
360 oprintf("\t\t\t\ttime = ");
361 print_timeval(event
->time
);
363 oprintf("\t\t\t}\n");
371 void print_envelope(const struct isds_envelope
*envelope
) {
372 oprintf("\tenvelope = ");
380 oprintf("\t\tdmID = %s\n", envelope
->dmID
);
381 oprintf("\t\tdbIDSender = %s\n", envelope
->dbIDSender
);
382 oprintf("\t\tdmSender = %s\n", envelope
->dmSender
);
383 oprintf("\t\tdmSenderAddress = %s\n", envelope
->dmSenderAddress
);
384 oprintf("\t\tdmSenderType = ");
385 print_DbType(envelope
->dmSenderType
);
386 oprintf("\t\tdmRecipient = %s\n", envelope
->dmRecipient
);
387 oprintf("\t\tdmRecipientAddress = %s\n", envelope
->dmRecipientAddress
);
388 oprintf("\t\tdmAmbiguousRecipient = ");
389 print_bool(envelope
->dmAmbiguousRecipient
);
390 oprintf("\t\tdmType = %s\n", envelope
->dmType
);
392 oprintf("\t\tdmSenderOrgUnit = %s\n", envelope
->dmSenderOrgUnit
);
393 oprintf("\t\tdmSenderOrgUnitNum = ");
394 print_longint(envelope
->dmSenderOrgUnitNum
);
395 oprintf("\t\tdbIDRecipient = %s\n", envelope
->dbIDRecipient
);
396 oprintf("\t\tdmRecipientOrgUnit = %s\n", envelope
->dmRecipientOrgUnit
);
397 oprintf("\t\tdmRecipientOrgUnitNum = ");
398 print_longint(envelope
->dmRecipientOrgUnitNum
);
399 oprintf("\t\tdmToHands = %s\n", envelope
->dmToHands
);
400 oprintf("\t\tdmAnnotation = %s\n", envelope
->dmAnnotation
);
401 oprintf("\t\tdmRecipientRefNumber = %s\n", envelope
->dmRecipientRefNumber
);
402 oprintf("\t\tdmSenderRefNumber = %s\n", envelope
->dmSenderRefNumber
);
403 oprintf("\t\tdmRecipientIdent = %s\n", envelope
->dmRecipientIdent
);
404 oprintf("\t\tdmSenderIdent = %s\n", envelope
->dmSenderIdent
);
406 oprintf("\t\tdmLegalTitleLaw = ");
407 print_longint(envelope
->dmLegalTitleLaw
);
408 oprintf("\t\tdmLegalTitleYear = ");
409 print_longint(envelope
->dmLegalTitleYear
);
410 oprintf("\t\tdmLegalTitleSect = %s\n", envelope
->dmLegalTitleSect
);
411 oprintf("\t\tdmLegalTitlePar = %s\n", envelope
->dmLegalTitlePar
);
412 oprintf("\t\tdmLegalTitlePoint = %s\n", envelope
->dmLegalTitlePoint
);
414 oprintf("\t\tdmPersonalDelivery = ");
415 print_bool(envelope
->dmPersonalDelivery
);
416 oprintf("\t\tdmAllowSubstDelivery = ");
417 print_bool(envelope
->dmAllowSubstDelivery
);
418 oprintf("\t\tdmOVM = ");
419 print_bool(envelope
->dmOVM
);
420 oprintf("\t\tdmPublishOwnID = ");
421 print_bool(envelope
->dmPublishOwnID
);
423 oprintf("\t\tdmOrdinal = ");
424 if (!envelope
->dmOrdinal
) oprintf("NULL\n");
425 else oprintf("%lu\n", *(envelope
->dmOrdinal
));
427 oprintf("\t\tdmMessageStatus = ");
428 if (!envelope
->dmMessageStatus
) oprintf("NULL\n");
430 switch(*(envelope
->dmMessageStatus
)) {
431 case MESSAGESTATE_SENT
: oprintf("SENT\n"); break;
432 case MESSAGESTATE_STAMPED
: oprintf("STAMPED\n"); break;
433 case MESSAGESTATE_INFECTED
: oprintf("INFECTED\n"); break;
434 case MESSAGESTATE_DELIVERED
: oprintf("DELIVERED\n"); break;
435 case MESSAGESTATE_SUBSTITUTED
: oprintf("SUBSTITUTED\n"); break;
436 case MESSAGESTATE_RECEIVED
: oprintf("RECEIVED\n"); break;
437 case MESSAGESTATE_READ
: oprintf("READ\n"); break;
438 case MESSAGESTATE_UNDELIVERABLE
: oprintf("UNDELIVERABLE\n"); break;
439 case MESSAGESTATE_REMOVED
: oprintf("REMOVED\n"); break;
440 case MESSAGESTATE_IN_SAFE
: oprintf("IN_SAFE\n"); break;
441 default: oprintf("<unknown type %d>\n",
442 *(envelope
->dmMessageStatus
));
445 oprintf("\t\tdmAttachmentSize = ");
446 if (!envelope
->dmAttachmentSize
) oprintf("NULL\n");
447 else oprintf("%lu kB\n", *(envelope
->dmAttachmentSize
));
449 oprintf("\t\tdmDeliveryTime = ");
450 print_timeval(envelope
->dmDeliveryTime
);
452 oprintf("\t\tdmAcceptanceTime = ");
453 print_timeval(envelope
->dmAcceptanceTime
);
455 oprintf("\t\thash = ");
456 print_hash(envelope
->hash
);
458 oprintf("\t\ttimestamp = %p\n", envelope
->timestamp
);
459 oprintf("\t\ttimestamp_length = %zu\n", envelope
->timestamp_length
);
461 oprintf("\t\tevents = ");
462 print_events(envelope
->events
);
468 void print_document(const struct isds_document
*document
) {
469 oprintf("\t\tdocument = ");
477 oprintf("\t\t\tis_xml = %u\n", !!document
->is_xml
);
478 oprintf("\t\t\txml_node_list = %p\n", document
->xml_node_list
);
480 oprintf("\t\t\tdata = %p\n", document
->data
);
481 oprintf("\t\t\tdata_length = %zu\n", document
->data_length
);
482 oprintf("\t\t\tdmMimeType = %s\n", document
->dmMimeType
);
484 oprintf("\t\t\tdmFileMetaType = ");
485 switch(document
->dmFileMetaType
) {
486 case FILEMETATYPE_MAIN
: oprintf("MAIN\n"); break;
487 case FILEMETATYPE_ENCLOSURE
: oprintf("ENCLOSURE\n"); break;
488 case FILEMETATYPE_SIGNATURE
: oprintf("SIGNATURE\n"); break;
489 case FILEMETATYPE_META
: oprintf("META\n"); break;
490 default: oprintf("<unknown type %d>\n", document
->dmFileMetaType
);
493 oprintf("\t\t\tdmFileGuid = %s\n", document
->dmFileGuid
);
494 oprintf("\t\t\tdmUpFileGuid = %s\n", document
->dmUpFileGuid
);
495 oprintf("\t\t\tdmFileDescr = %s\n", document
->dmFileDescr
);
496 oprintf("\t\t\tdmFormat = %s\n", document
->dmFormat
);
501 void print_documents(const struct isds_list
*documents
) {
502 const struct isds_list
*item
;
504 oprintf("\tdocuments = ");
512 for (item
= documents
; item
; item
= item
->next
) {
513 print_document((struct isds_document
*) (item
->data
));
520 void print_message(const struct isds_message
*message
) {
521 oprintf("message = ");
530 oprintf("\traw = %p\n", message
->raw
);
531 oprintf("\traw_length = %zu\n", message
->raw_length
);
532 oprintf("\traw_type = ");
533 print_raw_type(message
->raw_type
);
534 print_envelope(message
->envelope
);
535 print_documents(message
->documents
);
540 void print_copies(const struct isds_list
*copies
) {
541 const struct isds_list
*item
;
542 struct isds_message_copy
*copy
;
544 oprintf("Copies = ");
551 for (item
= copies
; item
; item
= item
->next
) {
552 copy
= (struct isds_message_copy
*) item
->data
;
553 oprintf("\tCopy = ");
559 oprintf("\t\tdbIDRecipient = %s\n", copy
->dbIDRecipient
);
560 oprintf("\t\tdmRecipientOrgUnit = %s\n", copy
->dmRecipientOrgUnit
);
562 oprintf("\t\tdmRecipientOrgUnitNum = ");
563 if (copy
->dmRecipientOrgUnitNum
)
564 oprintf("%ld\n", *copy
->dmRecipientOrgUnitNum
);
567 oprintf("\t\tdmToHands = %s\n", copy
->dmToHands
);
569 oprintf("\t\terror = %s\n", isds_strerror(copy
->error
));
570 oprintf("\t\tdmStatus = %s\n", copy
->dmStatus
);
571 oprintf("\t\tdmID = %s\n", copy
->dmID
);
579 void compare_hashes(const struct isds_hash
*hash1
,
580 const struct isds_hash
*hash2
) {
583 oprintf("Comparing hashes... ");
584 err
= isds_hash_cmp(hash1
, hash2
);
585 if (err
== IE_SUCCESS
)
586 oprintf("Hashes equal\n");
588 (err
== IE_NOTEQUAL
) oprintf("Hashes differ\n");
590 oprintf("isds_hash_cmp() failed: %s\n", isds_strerror(err
));
594 int progressbar(double upload_total
, double upload_current
,
595 double download_total
, double download_current
,
598 oprintf("Progress: upload %0f/%0f, download %0f/%0f, data=%p\n",
599 upload_current
, upload_total
, download_current
, download_total
,
605 /* Print formatted header if locale-encoded value is defined.
606 * @header is locale encoded header name
607 * @value is locale encoded header value */
608 void print_header(const char *header
, const char *value
) {
609 if (value
&& *value
) oprintf(_("%s: %s\n"), header
, value
);
613 /* Print formatted header if boolean value is defined.
614 * @header is locale encoded header name */
615 void print_header_bool(const char *header
, const _Bool
*value
) {
616 if (value
) print_header(header
, (*value
) ? _("Yes") : _("No"));
620 /* Print formatted header if long int value is defined.
621 * @header is locale encoded header name */
622 void print_header_longint(const char *header
, const long int *value
) {
623 if (value
) oprintf(_("%s: %ld\n"), header
, *value
);
627 /* Print formatted header if unsigned long int value is defined.
628 * @header is locale encoded header name */
629 void print_header_ulongint(const char *header
, const unsigned long int *value
) {
630 if (value
) oprintf(_("%s: %lu\n"), header
, *value
);
634 /* Print formatted header if time value is defined.
635 * @header is locale encoded header name */
636 void print_header_timeval(const char *header
, const struct timeval
*time
) {
642 if (!localtime_r(&(time
->tv_sec
), &broken
)) goto error
;
643 if (!strftime(buffer
, sizeof(buffer
)/sizeof(char), "%c", &broken
))
647 oprintf(_("%s: %s\n"), header
, buffer
);
648 else if ((time
->tv_usec
% 1000) == 0)
649 oprintf(_("%s: %s, %jd ms\n"), header
, buffer
, (intmax_t)time
->tv_usec
/1000);
651 oprintf(_("%s: %s, %jd us\n"), header
, buffer
, (intmax_t)time
->tv_usec
);
656 oprintf(_("%s: <Error while formatting time>\n"), header
);
661 /* Return formatted date as mallocated string. NULL or special error string can
662 * be returned. Application must free even the error string. */
663 char *tm2string(const struct tm
*date
) {
665 size_t buffer_length
= 128;
667 if (!date
) return NULL
;
669 buffer
= malloc(buffer_length
);
670 if (!buffer
) return strdup(_("<Error while formatting date>"));
672 if (0 == strftime(buffer
, buffer_length
, "%x", date
)) {
674 return strdup(_("<Error while formatting date>"));
681 /* Convert string representation of full ISO 8601 or locale date to tm structure.
682 * Return NULL if error occurs
683 * XXX: Not all ISO formats are supported */
684 struct tm
*datestring2tm(const char *string
) {
685 struct tm
*date
= NULL
;
687 if (!string
) return NULL
;
689 date
= calloc(1, sizeof(*date
));
690 if (!date
) return NULL
;
692 /* xsd:date is ISO 8601 string, thus ASCII */
693 offset
= strptime(string
, "%Y-%m-%d", date
);
694 if (offset
&& *offset
== '\0')
697 offset
= strptime(string
, "%x", date
);
698 if (offset
&& *offset
== '\0')
706 /* Convert string representation of box type to isds_DbType. Return false
707 * if the string was not recognized. Otherwise returns true. */
708 int string2isds_DbType(isds_DbType
*type
, const char *string
) {
709 if (!strcmp(string
, "FO"))
711 else if (!strcmp(string
, "PFO"))
713 else if (!strcmp(string
, "PFO_ADVOK"))
714 *type
= DBTYPE_PFO_ADVOK
;
715 else if (!strcmp(string
, "PFO_AUDITOR"))
716 *type
= DBTYPE_PFO_AUDITOR
;
717 else if (!strcmp(string
, "PFO_DANPOR"))
718 *type
= DBTYPE_PFO_DANPOR
;
719 else if (!strcmp(string
, "PFO_INSSPR"))
720 *type
= DBTYPE_PFO_INSSPR
;
721 else if (!strcmp(string
, "PO"))
723 else if (!strcmp(string
, "PO_ZAK"))
724 *type
= DBTYPE_PO_ZAK
;
725 else if (!strcmp(string
, "PO_REQ"))
726 *type
= DBTYPE_PO_REQ
;
727 else if (!strcmp(string
, "OVM"))
729 else if (!strcmp(string
, "OVM_NOTAR"))
730 *type
= DBTYPE_OVM_NOTAR
;
731 else if (!strcmp(string
, "OVM_EXEKUT"))
732 *type
= DBTYPE_OVM_EXEKUT
;
733 else if (!strcmp(string
, "OVM_REQ"))
734 *type
= DBTYPE_OVM_REQ
;
735 else if (!strcmp(string
, "OVM_FO"))
736 *type
= DBTYPE_OVM_FO
;
737 else if (!strcmp(string
, "OVM_PFO"))
738 *type
= DBTYPE_OVM_PFO
;
739 else if (!strcmp(string
, "OVM_PO"))
740 *type
= DBTYPE_OVM_PO
;
747 /* Print formatted header if date value is defined.
748 * @header is locale encoded header name */
749 void print_header_tm(const char *header
, const struct tm
*date
) {
752 if (NULL
== date
) return;
753 string
= tm2string(date
);
756 oprintf(_("%s: <Error while formatting date>\n"), header
);
758 print_header(header
, string
);
764 /* Print formatted header if UTF-8 value is defined.
765 * @header is locale encoded header name
766 * @value is UTF-8 encoded header value */
767 void print_header_utf8(const char *header
, const char *value
) {
772 value_locale
= utf82locale(value
);
776 _("<Error while converting value>"));
781 /* Print formatted header and byte size.
782 * @header is locale encoded header name */
783 void print_header_size(const char *header
, size_t size
) {
787 shi_asprintf(&buffer
, _("%zu B"), size
);
788 else if (size
< (1<<20))
789 shi_asprintf(&buffer
, _("%0.2f KiB"), (float) size
/(1<<10));
791 shi_asprintf(&buffer
, _("%0.2f MiB"), (float) size
/(1<<20));
793 print_header(header
, buffer
);
798 /* Print formatted header if long int KB size is defined.
799 * @header is locale encoded header name */
800 void print_header_kbsize(const char *header
, const long int *size
) {
805 shi_asprintf(&buffer
, _("<Negative size>"));
806 else if (*size
< (1000))
807 shi_asprintf(&buffer
, _("%lu kB"), *size
);
809 shi_asprintf(&buffer
, _("%0.2f MB"), *size
/1000.0);
811 print_header(header
, buffer
);
816 /* Print formatted header if long int CZK/100 currency value is defined.
817 * @header is locale encoded header name
818 * @value is pointer to value in hundredths of CZK */
819 void print_header_currency(const char *header
, const long int *value
) {
821 unsigned long int integer
;
822 unsigned long int fraction
;
824 if (NULL
== value
) return;
826 /* labs(3) and % with negative values are ISO C99 specific. Did I say this
827 * code did not support older compilers? */
828 integer
= labs(*value
/ 100);
829 fraction
= labs(*value
% 100);
831 /* XXX: We could use strfmon(3) only if it was standardized and if it
832 * supported arbitrary precision fraction (no float point types).
833 * We could reimplement strfmon(3) to use locale defintion, but that would
834 * be overkill. Direct localization is simpler. */
835 shi_asprintf(&buffer
,
837 _("CZK -%lu.%02lu") :
841 print_header(header
, buffer
);
847 static const char *DbType2string(const long int *type
) {
848 if (!type
) return NULL
;
850 case DBTYPE_SYSTEM
: return(_("System"));
851 case DBTYPE_FO
: return(_("Private individual"));
852 case DBTYPE_PFO
: return(_("Self-employed individual"));
853 case DBTYPE_PFO_ADVOK
: return(_("Lawyer"));
854 case DBTYPE_PFO_AUDITOR
: return(_("Statutory auditor"));
855 case DBTYPE_PFO_DANPOR
: return(_("Tax advisor"));
856 case DBTYPE_PFO_INSSPR
: return(_("Insolvency administrator"));
857 case DBTYPE_PO
: return(_("Organisation"));
858 case DBTYPE_PO_ZAK
: return(_("Organization based by law"));
859 case DBTYPE_PO_REQ
: return(_("Organization based on request"));
860 case DBTYPE_OVM
: return(_("Public authority"));
861 case DBTYPE_OVM_EXEKUT
: return(_("Executor"));
862 case DBTYPE_OVM_FO
: return(_("Private individual listed in the public authority index"));
863 case DBTYPE_OVM_NOTAR
: return(_("Notary"));
864 case DBTYPE_OVM_PFO
: return(_("Self-employed individual listed in the public authority index"));
865 case DBTYPE_OVM_PO
: return(_("Organisation listed in the public authority index"));
866 case DBTYPE_OVM_REQ
: return(_("Public authority based on request"));
867 default: return(_("<Unknown type>"));
872 static const char *UserType2string(const long int *type
) {
873 if (!type
) return NULL
;
875 case USERTYPE_PRIMARY
: return(_("Primary"));
876 case USERTYPE_ENTRUSTED
: return(_("Entrusted"));
877 case USERTYPE_ADMINISTRATOR
: return(_("Administrator"));
878 case USERTYPE_OFFICIAL
: return(_("Official"));
879 default: return(_("<Unknown type>"));
884 static const char *isds_sender_type2string(const isds_sender_type
*type
) {
885 if (!type
) return NULL
;
887 case SENDERTYPE_PRIMARY
: return(_("Primary"));
888 case SENDERTYPE_ENTRUSTED
: return(_("Entrusted"));
889 case SENDERTYPE_ADMINISTRATOR
: return(_("Administrator"));
890 case SENDERTYPE_OFFICIAL
: return(_("Official"));
891 case SENDERTYPE_VIRTUAL
: return(_("Virtual"));
892 default: return(_("<unknown type>"));
897 /* Return formatted user privileges. Caller must free the string */
898 static char *UserPrivils2string(const long int *privils
) {
900 const char *priviledges
[] = {
901 N_("Read non-personal"),
903 N_("Send and read sent"),
904 N_("List messages and read delivery details"),
906 N_("Administer her box"),
907 N_("Read from safe"),
908 N_("Delete from safe")
910 const int priviledges_count
= sizeof(priviledges
)/sizeof(priviledges
[0]);
911 char *buffer
= NULL
, *new_buffer
= NULL
;
913 if (!privils
) return NULL
;
915 /*oprintf("%ld (", *privils);*/
917 for (int i
= 0; i
< priviledges_count
; i
++) {
918 if (*privils
& (1<<i
)) {
919 if ((*privils
% (1<<i
)))
920 shi_asprintf(&new_buffer
, _("%s, %s"),
921 buffer
, _(priviledges
[i
]));
923 shi_asprintf(&new_buffer
, "%s", _(priviledges
[i
]));
927 return(strdup(_("<Error while formatting privileges>")));
936 if (*privils
>= (1<<priviledges_count
)) {
937 if ((*privils
% (1<<priviledges_count
)))
938 shi_asprintf(&new_buffer
, _("%s, %s"),
939 buffer
, _("<Unknown privilege>"));
941 shi_asprintf(&new_buffer
, "%s", _("<Unknown privilege>"));
945 return(strdup(_("<Error while formatting privileges>")));
957 static const char *DmType2string(const char *type
) {
958 if (!type
) return NULL
;
959 if (!strcmp(type
, "V"))
961 else if (!strcmp(type
, "K"))
962 return(_("Commercial"));
963 else if (!strcmp(type
, "A"))
964 return(_("Commercial (initiatory, unused, subsidized)"));
965 else if (!strcmp(type
, "B"))
966 return(_("Commercial (initiatory, used, subsidized)"));
967 else if (!strcmp(type
, "C"))
968 return(_("Commercial (initiatory, expired, subsidized)"));
969 else if (!strcmp(type
, "D"))
970 return(_("Commercial (externally subsidized)"));
971 else if (!strcmp(type
, "E"))
972 return(_("Commercial (prepaid by a stamp)"));
973 else if (!strcmp(type
, "G"))
974 return(_("Commercial (sponsored)"));
975 else if (!strcmp(type
, "I"))
976 return(_("Commercial (initiatory, unused, paid by sender)"));
977 else if (!strcmp(type
, "O"))
978 return(_("Commercial (response paid by recipient)"));
979 else if (!strcmp(type
, "X"))
980 return(_("Commercial (initiatory, expired, paid by sender)"));
981 else if (!strcmp(type
, "Y"))
982 return(_("Commercial (initiatory, used, paid by sender)"));
983 else if (!strcmp(type
, "Z"))
984 return(_("Commercial (limitedly subsidized)"));
985 else return(_("<Unknown type>"));
989 /* Simplified commercial status printed on message listing.
990 * 'P' is a public message sent by a government
991 * 'C' is a commercial message
992 * 'I' is a commercial message offering to pay response instead of the
994 * 'i' is a commercial message that offered to pay reposne, but it does not
996 * 'R' is a commercial response message paid by sender of the I message. */
997 static const char DmType2flag(const char *type
) {
998 if (!type
) return ' ';
999 if (!strcmp(type
, "V")) return('P');
1000 else if (!strcmp(type
, "K")) return('C');
1001 else if (!strcmp(type
, "A")) return('I');
1002 else if (!strcmp(type
, "B")) return('i');
1003 else if (!strcmp(type
, "C")) return('i');
1004 else if (!strcmp(type
, "D")) return('C');
1005 else if (!strcmp(type
, "E")) return('C');
1006 else if (!strcmp(type
, "G")) return('C');
1007 else if (!strcmp(type
, "I")) return('I');
1008 else if (!strcmp(type
, "O")) return('R');
1009 else if (!strcmp(type
, "X")) return('i');
1010 else if (!strcmp(type
, "Y")) return('i');
1011 else if (!strcmp(type
, "Z")) return('C');
1016 static const char *DmMessageStatus2string(const isds_message_status
*status
) {
1017 if (!status
) return NULL
;
1019 case MESSAGESTATE_SENT
: return(_("Sent"));
1020 case MESSAGESTATE_STAMPED
: return(_("Stamped"));
1021 case MESSAGESTATE_INFECTED
: return(_("Infected"));
1022 case MESSAGESTATE_DELIVERED
: return(_("Delivered ordinary"));
1023 case MESSAGESTATE_SUBSTITUTED
: return(_("Delivered substitutably"));
1024 case MESSAGESTATE_RECEIVED
: return(_("Accepted"));
1025 case MESSAGESTATE_READ
: return(_("Read"));
1026 case MESSAGESTATE_UNDELIVERABLE
: return(_("Undeliverable"));
1027 case MESSAGESTATE_REMOVED
: return(_("Deleted"));
1028 case MESSAGESTATE_IN_SAFE
: return(_("Stored in safe"));
1029 default: return(_("<Unknown state>"));
1034 static const char DmMessageStatus2flag(const isds_message_status
*status
) {
1035 if (!status
) return ' ';
1037 case MESSAGESTATE_SENT
: return('>');
1038 case MESSAGESTATE_STAMPED
: return('t');
1039 case MESSAGESTATE_INFECTED
: return('I');
1040 case MESSAGESTATE_DELIVERED
: return('N');
1041 case MESSAGESTATE_SUBSTITUTED
: return('n');
1042 case MESSAGESTATE_RECEIVED
: return('O');
1043 case MESSAGESTATE_READ
: return(' ');
1044 case MESSAGESTATE_UNDELIVERABLE
: return('!');
1045 case MESSAGESTATE_REMOVED
: return('D');
1046 case MESSAGESTATE_IN_SAFE
: return('S');
1047 default: return('?');
1052 /* Return timeval time formatted into shortest string with respect to current
1053 * time. Caller must free the string. */
1054 static char *timeval2shortstring(const struct timeval
*timeval
) {
1055 struct tm broken
, current_broken
;
1056 time_t current_time
;
1057 char *buffer
= NULL
;
1058 const size_t buffer_size
= 16;
1060 if (!timeval
) return NULL
;
1062 buffer
= malloc(buffer_size
);
1063 if (!buffer
) goto error
;
1065 /* Get current time */
1066 current_time
= time(NULL
);
1067 if (current_time
== (time_t) -1) goto error
;
1068 if (!localtime_r(¤t_time
, ¤t_broken
)) goto error
;
1070 /* Get broken time */
1071 if (!localtime_r(&(timeval
->tv_sec
), &broken
)) goto error
;
1073 /* Select proper abbreviated string representation */
1074 if (broken
.tm_year
== current_broken
.tm_year
&&
1075 broken
.tm_yday
== current_broken
.tm_yday
) {
1076 /* Minute resolution in the same day */
1077 if (!strftime(buffer
, buffer_size
, _("%k:%M"), &broken
))
1080 /* Otherwise month and day */
1081 if (!strftime(buffer
, buffer_size
, _("%b %d"), &broken
))
1089 return strdup(_("<Error>"));
1093 /* Formatted Law Authorization if defined. You must free it. */
1094 static char *envelope_law2string(const struct isds_envelope
*envelope
) {
1095 char *output
= NULL
;
1096 char *year_locale
= NULL
, *law_locale
= NULL
;
1097 char *sect_locale
= NULL
, *par_locale
= NULL
, *point_locale
= NULL
;
1100 !(envelope
->dmLegalTitleYear
|| envelope
->dmLegalTitleLaw
||
1101 envelope
->dmLegalTitleSect
|| envelope
->dmLegalTitlePar
||
1102 envelope
->dmLegalTitlePoint
)
1105 if (envelope
->dmLegalTitleYear
)
1106 shi_asprintf(&year_locale
, "%ld", *envelope
->dmLegalTitleYear
);
1108 year_locale
= strdup(_("?"));
1110 if (envelope
->dmLegalTitleLaw
)
1111 shi_asprintf(&law_locale
, "%ld", *envelope
->dmLegalTitleLaw
);
1113 law_locale
= strdup(_("?"));
1115 sect_locale
= utf82locale(envelope
->dmLegalTitleSect
);
1116 par_locale
= utf82locale(envelope
->dmLegalTitlePar
);
1117 point_locale
= utf82locale(envelope
->dmLegalTitlePoint
);
1120 shi_asprintf(&output
, _("point %s, par. %s, sect. %s, %s/%s Coll."),
1121 point_locale
, par_locale
, sect_locale
,
1122 law_locale
, year_locale
);
1123 else if (par_locale
)
1124 shi_asprintf(&output
, _("par. %s, sect. %s, %s/%s Coll."),
1125 par_locale
, sect_locale
, law_locale
, year_locale
);
1126 else if (sect_locale
)
1127 shi_asprintf(&output
, _("sect. %s, %s/%s Coll."),
1128 sect_locale
, law_locale
, year_locale
);
1130 shi_asprintf(&output
, _("%s/%s Coll."),
1131 law_locale
, year_locale
);
1142 static const char *isds_payment_type2string(const isds_payment_type
*type
) {
1143 if (!type
) return NULL
;
1145 case PAYMENT_SENDER
: return(_("Payed by sender"));
1146 case PAYMENT_STAMP
: return(_("Stamp pre-paid by sender"));
1147 case PAYMENT_SPONSOR
: return(_("Sponsor pays all messages"));
1148 case PAYMENT_RESPONSE
: return(_("Recipient pays a response"));
1149 case PAYMENT_SPONSOR_LIMITED
: return(_("Limitedly subsidized"));
1150 case PAYMENT_SPONSOR_EXTERNAL
: return(_("Externally subsidized"));
1151 default: return(_("<unknown type>"));
1156 /* Print formatted header if time any of message ID.
1157 * @header is locale encoded header name */
1158 static void print_header_messages_ids(const char *header
,
1159 const char *ref_number
, const char *ident
) {
1160 if (ref_number
|| ident
) {
1161 oprintf(_("%s:\n"), header
);
1162 print_header_utf8(_("\tReference number"), ref_number
);
1163 print_header_utf8(_("\tFile ID"), ident
);
1168 /* Return formatted hash value */
1169 char *hash2string(const struct isds_hash
*hash
) {
1170 const char *algorithm_string
= NULL
;
1171 char *buffer
= NULL
, *octet
= NULL
, *new_buffer
= NULL
;
1173 if (!hash
|| !hash
->value
) return NULL
;
1175 switch(hash
->algorithm
) {
1176 case HASH_ALGORITHM_MD5
: algorithm_string
= (_("MD5")); break;
1177 case HASH_ALGORITHM_SHA_1
: algorithm_string
= (_("SHA-1")); break;
1178 case HASH_ALGORITHM_SHA_224
: algorithm_string
= (_("SHA-224")); break;
1179 case HASH_ALGORITHM_SHA_256
: algorithm_string
= (_("SHA-256")); break;
1180 case HASH_ALGORITHM_SHA_384
: algorithm_string
= (_("SHA-384")); break;
1181 case HASH_ALGORITHM_SHA_512
: algorithm_string
= (_("SHA-512")); break;
1182 default: algorithm_string
= (_("<Unknown hash algorithm>")); break;
1185 for (int i
= 0; i
< hash
->length
; i
++) {
1186 shi_asprintf(&octet
, "%02x", ((uint8_t *)(hash
->value
))[i
]);
1188 free(buffer
); free(octet
); return NULL
;
1192 shi_asprintf(&new_buffer
, _("%s:%s"), buffer
, octet
);
1194 shi_asprintf(&new_buffer
, "%s", octet
);
1196 free(buffer
); free(octet
); return NULL
;
1199 buffer
= new_buffer
; new_buffer
= NULL
;
1202 shi_asprintf(&new_buffer
, _("%s %s"), algorithm_string
, buffer
);
1209 /* Print if any message delivery info exists. */
1210 void print_message_delivery_info(const struct isds_envelope
*envelope
) {
1211 char *hash_string
= NULL
;
1213 if (envelope
&& (envelope
->dmType
|| envelope
->dmMessageStatus
||
1214 envelope
->dmDeliveryTime
||
1215 envelope
->dmAcceptanceTime
|| envelope
->dmPersonalDelivery
||
1216 envelope
->dmAllowSubstDelivery
|| envelope
->hash
||
1217 envelope
->dmOrdinal
)) {
1218 oprintf(_("Delivery data:\n"));
1219 print_header(_("\tMessage type"), DmType2string(envelope
->dmType
));
1220 print_header(_("\tMessage status"),
1221 DmMessageStatus2string(envelope
->dmMessageStatus
));
1222 print_header_timeval(_("\tDelivered"), envelope
->dmDeliveryTime
);
1223 print_header_timeval(_("\tAccepted"), envelope
->dmAcceptanceTime
);
1224 print_header_bool(_("\tPersonal delivery required"),
1225 envelope
->dmPersonalDelivery
);
1226 print_header_bool(_("\tAllow substitutable delivery"),
1227 envelope
->dmAllowSubstDelivery
);
1229 hash_string
= hash2string(envelope
->hash
);
1230 print_header(_("\tHash"), hash_string
);
1233 print_header_ulongint(_("\tOrdinal number"), envelope
->dmOrdinal
);
1238 static const char *event_type2string(const isds_event_type
*type
) {
1239 if (!type
) return (_("<Undefined>"));
1242 case EVENT_UKNOWN
: return(_("Unknown"));
1243 case EVENT_ENTERED_SYSTEM
:
1244 return(_("Entered system"));
1245 case EVENT_ACCEPTED_BY_RECIPIENT
:
1246 return(_("Accepted by recipient"));
1247 case EVENT_ACCEPTED_BY_FICTION
:
1248 return(_("Delivered substitutably"));
1249 case EVENT_UNDELIVERABLE
:
1250 return(_("Undeliverable"));
1251 case EVENT_COMMERCIAL_ACCEPTED
:
1252 return(_("Commerical message accepted by "
1253 "recipient")); break;
1254 case EVENT_DELIVERED
:
1255 return(_("Delivered into box")); break;
1256 case EVENT_PRIMARY_LOGIN
:
1257 return(_("Primary user logged in")); break;
1258 case EVENT_ENTRUSTED_LOGIN
:
1259 return(_("Entrusted user logged in")); break;
1260 case EVENT_SYSCERT_LOGIN
:
1261 return(_("Application logged in by system "
1262 "certificate")); break;
1263 default: return(_("<Unknown event type>"));
1268 /* Print if any delivery event exists. */
1269 void print_delivery_events(const struct isds_list
*events
) {
1270 int counter_width
= 3;
1272 const struct isds_list
*item
;
1273 struct isds_event
*event
;
1275 if (!events
) return;
1277 oprintf(_("Delivery events:\n"));
1279 for (item
= events
; item
; item
= item
->next
) {
1280 event
= (struct isds_event
*) item
->data
;
1281 if (!event
) continue;
1284 oprintf(_("%*d %s\n"), counter_width
, order
,
1285 event_type2string(event
->type
));
1286 print_header_utf8(_("\tDescription"), event
->description
);
1287 print_header_timeval(_("\tWhen"), event
->time
);
1292 /* Print formatted message envelope */
1293 void format_envelope(const struct isds_envelope
*envelope
) {
1294 char *law_string
= NULL
;
1297 oprintf(_("<Missing envelope>\n"));
1301 print_header_utf8(_("Message ID"), envelope
->dmID
);
1303 if (envelope
->dbIDSender
|| envelope
->dmSender
||
1304 envelope
->dmSenderOrgUnit
|| envelope
->dmSenderOrgUnitNum
||
1305 envelope
->dmSenderAddress
|| envelope
->dmSenderType
||
1306 envelope
->dmOVM
|| envelope
->dmPublishOwnID
) {
1307 oprintf(_("Sender:\n"));
1308 print_header_utf8(_("\tID"), envelope
->dbIDSender
);
1309 print_header_utf8(_("\tName"), envelope
->dmSender
);
1310 print_header_utf8(_("\tUnit"), envelope
->dmSenderOrgUnit
);
1311 print_header_longint(_("\tUnit number"), envelope
->dmSenderOrgUnitNum
);
1312 print_header_utf8(_("\tAddress"), envelope
->dmSenderAddress
);
1313 print_header(_("\tType"), DbType2string(envelope
->dmSenderType
));
1314 print_header_bool(_("\tAs public authority"), envelope
->dmOVM
);
1315 print_header_bool(_("\tPublish user's identity"),
1316 envelope
->dmPublishOwnID
);
1319 if (envelope
->dbIDRecipient
|| envelope
->dmRecipient
||
1320 envelope
->dmRecipientOrgUnit
|| envelope
->dmRecipientOrgUnitNum
||
1321 envelope
->dmToHands
|| envelope
->dmRecipientAddress
||
1322 envelope
->dmAmbiguousRecipient
) {
1323 oprintf(_("Recipient:\n"));
1324 print_header_utf8(_("\tID"), envelope
->dbIDRecipient
);
1325 print_header_utf8(_("\tName"), envelope
->dmRecipient
);
1326 print_header_utf8(_("\tUnit"), envelope
->dmRecipientOrgUnit
);
1327 print_header_longint(_("\tUnit number"),
1328 envelope
->dmRecipientOrgUnitNum
);
1329 print_header_utf8(_("To hands"), envelope
->dmToHands
);
1330 print_header_utf8(_("\tAddress"), envelope
->dmRecipientAddress
);
1331 print_header_bool(_("\tAs public authority"),
1332 envelope
->dmAmbiguousRecipient
);
1335 print_header_utf8(_("Subject"), envelope
->dmAnnotation
);
1337 print_header_messages_ids(_("Sender message IDs"),
1338 envelope
->dmSenderRefNumber
, envelope
->dmSenderIdent
);
1339 print_header_messages_ids(_("Recipient message IDs"),
1340 envelope
->dmRecipientRefNumber
, envelope
->dmRecipientIdent
);
1342 law_string
= envelope_law2string(envelope
);
1343 print_header(_("Law authorization"), law_string
);
1346 print_message_delivery_info(envelope
);
1348 print_header_kbsize(_("Document total size"), envelope
->dmAttachmentSize
);
1350 /*oprintf("\t\ttimestamp = %p\n", envelope->timestamp);
1351 oprintf("\t\ttimestamp_length = %zu\n", envelope->timestamp_length);*/
1352 print_delivery_events(envelope
->events
);
1356 const char *DmFileMetaType2string(isds_FileMetaType type
) {
1358 case FILEMETATYPE_MAIN
: return(_("Main document"));
1359 case FILEMETATYPE_ENCLOSURE
: return(_("Enclosure"));
1360 case FILEMETATYPE_SIGNATURE
: return(_("Signature"));
1361 case FILEMETATYPE_META
: return(_("Meta document"));
1362 default: return(_("<unknown document type>"));
1367 /* Computes ordinal number of document identified by GUID
1368 * @documents is list of documents where to search
1369 * @id is UTF-8 encoded document ID reference
1370 * Return allocated array of ordinal numbers terminated by -1. Normally only
1371 * one document with @id exists. However ISDS does not check this higher
1372 * requirements and can transport message with duplicate document identifiers.
1373 * Therefore this function returns array of ordinals. Return NULL if error
1374 * occurs (e.g. memory insufficiency). */
1375 static int *dmFileGuid2ordinar(const struct isds_list
*documents
,
1377 const struct isds_list
*item
;
1378 struct isds_document
*document
;
1379 size_t ordinars_length
= 64, offset
= 0;
1380 int *ordinars
= NULL
, *new_ordinars
;
1383 if (!documents
|| !id
|| !*id
) return NULL
;
1384 ordinars
= malloc(ordinars_length
* sizeof(*ordinars
));
1385 if (!ordinars
) return NULL
;
1387 for (item
= documents
; item
; item
= item
->next
) {
1388 if (!item
->data
) continue;
1390 document
= (struct isds_document
*) (item
->data
);
1392 if (document
->dmFileGuid
&& !strcmp(document
->dmFileGuid
, id
)) {
1393 if (offset
== ordinars_length
) {
1394 /* Grow ordinals array */
1395 ordinars_length
*= 2;
1396 new_ordinars
= realloc(ordinars
,
1397 ordinars_length
* sizeof(*ordinars
));
1398 if (!new_ordinars
) {
1402 ordinars
= new_ordinars
;
1405 ordinars
[offset
++] = ordinar
;
1409 ordinars
[offset
] = -1;
1414 /* @id is UTF-8 encoded GUID of referred document
1415 * @refernces is array of ordinal numbers if exist terminated by -1. Can be
1416 * NULL to signal error. */
1417 static void format_document_reference(char *id
, int *references
) {
1418 char *buffer
= NULL
, *new_buffer
= NULL
;
1421 if (references
&& *references
!= -1) {
1422 for (; *references
> 0; references
++) {
1424 shi_asprintf(&new_buffer
, _("%d"), *references
);
1426 shi_asprintf(&new_buffer
, _("%s, %d"), buffer
, *references
);
1432 buffer
= new_buffer
;
1436 char *id_locale
= utf82locale(id
);
1437 shi_asprintf(&buffer
,
1438 _("<Reference to non-existing document ID `%s'>"), id_locale
);
1443 print_header(_("\tRefers to"), buffer
);
1445 print_header(_("\tRefers to"), _("<Error while formatting reference>"));
1450 /* Print formatted document
1451 * @references is ordinal number of referred document. Formally it's array
1452 * terminated by -1 because non-well-formed message can have more documents
1454 void format_document(const struct isds_document
*document
, int order
,
1456 int counter_width
= 3;
1457 char *filename_locale
= NULL
;
1459 if (!document
) return;
1461 oprintf(_("%*d "), counter_width
, order
);
1463 if (document
->dmFileDescr
) {
1464 filename_locale
= utf82locale(document
->dmFileDescr
);
1465 oprintf("%s\n", filename_locale
);
1466 free(filename_locale
);
1468 oprintf(_("<Unknown file name>\n"));
1471 if (document
->is_xml
) {
1472 char *message
=NULL
;
1475 for (xmlNodePtr node
= document
->xml_node_list
; node
;
1476 node
= node
->next
) nodes
++;
1477 shi_asprintf(&message
, ngettext("%d node", "%d nodes", nodes
), nodes
);
1479 print_header(_("\tXML document"), message
);
1483 print_header_size(_("\tSize"), document
->data_length
);
1485 print_header(_("\tMIME type"), document
->dmMimeType
);
1487 print_header(_("\tType"), DmFileMetaType2string(document
->dmFileMetaType
));
1488 print_header_utf8(_("\tMeta format"), document
->dmFormat
);
1490 print_header_utf8(_("\tID"), document
->dmFileGuid
);
1491 format_document_reference(document
->dmUpFileGuid
, references
);
1495 /* Print formatted message documents */
1496 void format_documents(const struct isds_list
*documents
) {
1497 const struct isds_list
*item
;
1498 const struct isds_document
*document
;
1501 if (!documents
) return;
1503 oprintf(_("Documents:\n"));
1505 for (item
= documents
; item
; item
= item
->next
) {
1506 if (!item
->data
) continue;
1507 document
= (struct isds_document
*) item
->data
;
1508 references
= dmFileGuid2ordinar(documents
, document
->dmUpFileGuid
);
1509 format_document(document
, ++i
, references
);
1515 /* Print formatted message */
1516 void format_message(const struct isds_message
*message
) {
1517 if (!message
) return;
1518 format_envelope(message
->envelope
);
1519 format_documents(message
->documents
);
1523 /* Print formatted list of message copies */
1524 void format_copies(const struct isds_list
*copies
) {
1525 const struct isds_list
*item
;
1526 const struct isds_message_copy
*copy
;
1528 int counter_width
= 3;
1529 if (!copies
) return;
1531 for (item
= copies
; item
; item
= item
->next
) {
1532 if (!item
->data
) continue;
1533 copy
= (struct isds_message_copy
*) item
->data
;
1536 oprintf(_("%*d Recipient:\n"), counter_width
, i
);
1537 print_header_utf8(_("\tID"), copy
->dbIDRecipient
);
1538 print_header_utf8(_("\tUnit"), copy
->dmRecipientOrgUnit
);
1539 print_header_longint(_("\tUnit number"), copy
->dmRecipientOrgUnitNum
);
1540 print_header_utf8(_("\tTo hands"), copy
->dmToHands
);
1545 void print_message_list(const struct isds_list
*messages
, _Bool outgoing
) {
1546 const struct isds_list
*item
;
1547 struct isds_envelope
*envelope
;
1548 unsigned long int counter
= 0;
1550 int counter_max
, id_max
= 0, name_max
= 0, subject_max
= 0;
1551 int counter_width
, id_width
= 0, flags_width
= 2, time_width
= 6,
1552 name_width
= 0, subject_width
= 0;
1554 char *id_locale
= NULL
, flags_locale
[3], *time_locale
= NULL
,
1555 *name_locale
= NULL
, *subject_locale
= NULL
;
1560 /* Compute column widths */
1561 rl_get_screen_size(NULL
, &screen_cols
);
1563 /* Get real maximal widths */
1564 for (counter
= 0, item
= messages
; item
; item
= item
->next
) {
1565 if (!item
->data
|| !((struct isds_message
*)item
->data
)->envelope
)
1567 envelope
= ((struct isds_message
*) item
->data
)->envelope
;
1570 width
= utf8width(envelope
->dmID
);
1571 if (width
> id_max
) id_max
= width
;
1573 width
= utf8width((outgoing
) ?
1574 envelope
->dmRecipient
: envelope
->dmSender
);
1575 if (width
> name_max
) name_max
= width
;
1577 width
= utf8width(envelope
->dmAnnotation
);
1578 if (width
> subject_max
) subject_max
= width
;
1580 counter_max
= numberwidth(counter
);
1582 /* Correct widths to fit into window */
1583 if (counter_max
< 0) counter_width
= -3; else counter_width
= counter_max
;
1584 if (id_max
< 0) id_width
= -6; else id_width
= id_max
;
1585 if (name_max
< 0) name_width
= -20; else name_width
= name_max
;
1586 if (subject_max
< 0) subject_width
= -32; else subject_width
= subject_max
;
1588 width
= abs(counter_width
) + 1 + abs(id_width
) + 1 + abs(flags_width
) + 1 +
1589 abs(time_width
) + 1 + abs(name_width
) + 1 + abs(subject_width
);
1590 if (width
> screen_cols
) {
1591 width
-= abs(name_width
) + abs(subject_width
);
1593 name_width
= subject_width
= 0;
1594 while (width
+ name_width
+ subject_width
< screen_cols
) {
1595 if (name_width
< abs(name_max
)) name_width
++;
1596 if (subject_width
< abs(subject_max
)) subject_width
++;
1598 if (width
+ name_width
+ subject_width
> screen_cols
) subject_width
--;
1602 /* TRANSLATORS: "No" is abbreviation for "Number" in listing header. */
1603 onprint(pgettext("list header", "No"), counter_width
);
1605 onprint(_("ID"), id_width
);
1607 onprint(_("Flags"), flags_width
);
1609 onprint(_("Delivered"), time_width
);
1611 onprint((outgoing
) ? _("To") : _("From"), name_width
);
1613 onprint(_("Subject"), subject_width
);
1615 for (int i
= 0; i
< screen_cols
; i
++) oprintf(_("-"));
1618 /* Print the list */
1619 for (counter
= 0, item
= messages
; item
; item
= item
->next
) {
1620 envelope
= ((struct isds_message
*) item
->data
)->envelope
;
1623 oprintf(_("%*lu "), counter_width
, counter
);
1626 oprintf(_("<Missing envelope>\n"));
1630 id_locale
= utf82locale(envelope
->dmID
);
1631 name_locale
= utf82locale((outgoing
) ?
1632 envelope
->dmRecipient
: envelope
->dmSender
);
1633 flags_locale
[0] = DmType2flag(envelope
->dmType
);
1634 flags_locale
[1] = DmMessageStatus2flag(envelope
->dmMessageStatus
);
1635 flags_locale
[2] = '\0';
1636 time_locale
= timeval2shortstring(envelope
->dmDeliveryTime
);
1637 subject_locale
= utf82locale(envelope
->dmAnnotation
);
1639 onprint(id_locale
, id_width
);
1641 onprint(flags_locale
, flags_width
);
1643 onprint(time_locale
, time_width
);
1645 onprint(name_locale
, name_width
);
1647 onprint(subject_locale
, subject_width
);
1653 zfree(subject_locale
);
1658 static void format_PersonName(const struct isds_PersonName
*personName
) {
1659 if (!personName
) return;
1661 oprintf(_("Person name:\n"));
1662 print_header_utf8(_("\tFirst"), personName
->pnFirstName
);
1663 print_header_utf8(_("\tMiddle"), personName
->pnMiddleName
);
1664 print_header_utf8(_("\tLast"), personName
->pnLastName
);
1665 print_header_utf8(_("\tLast at birth"),
1666 personName
->pnLastNameAtBirth
);
1670 static void format_BirthInfo(const struct isds_BirthInfo
*birth
) {
1671 if (!birth
|| !(birth
->biDate
|| birth
->biCity
|| birth
->biCounty
1672 || birth
->biState
)) return;
1674 oprintf(_("Birth details:\n"));
1676 print_header_tm(_("\tDate"), birth
->biDate
);
1677 print_header_utf8(_("\tCity"), birth
->biCity
);
1678 print_header_utf8(_("\tCounty"), birth
->biCounty
);
1679 print_header_utf8(_("\tState"), birth
->biState
);
1683 static void format_Address(const struct isds_Address
*address
) {
1684 if (!address
|| !(address
->adCity
|| address
->adStreet
||
1685 address
->adNumberInStreet
|| address
->adNumberInMunicipality
||
1686 address
->adZipCode
|| address
->adState
)) return;
1688 oprintf(_("Address:\n"));
1689 print_header_utf8(_("\tCity"), address
->adCity
);
1690 print_header_utf8(_("\tStreet"), address
->adStreet
);
1691 print_header_utf8(_("\tNumber in street"), address
->adNumberInStreet
);
1692 print_header_utf8(_("\tNumber in municipality"),
1693 address
->adNumberInMunicipality
);
1694 print_header_utf8(_("\tZIP code"), address
->adZipCode
);
1695 print_header_utf8(_("\tState"), address
->adState
);
1699 /* Return static box state string or NULL if undefined */
1700 const char *DbState2string(const long int *state
) {
1701 if (!state
) return NULL
;
1704 case DBSTATE_ACCESSIBLE
: return(_("Accessible"));
1705 case DBSTATE_TEMP_UNACCESSIBLE
: return(_("Temporary inaccessible"));
1706 case DBSTATE_NOT_YET_ACCESSIBLE
: return(_("Not yet accessible"));
1707 case DBSTATE_PERM_UNACCESSIBLE
: return(_("Permanently inaccessible"));
1708 case DBSTATE_REMOVED
: return(_("Deleted"));
1709 default: return(_("<unknown state>"));
1714 void format_DbOwnerInfo(const struct isds_DbOwnerInfo
*info
) {
1717 print_header_utf8(_("Box ID"), info
->dbID
);
1718 print_header(_("Type"), DbType2string((long int *) (info
->dbType
)));
1719 print_header_utf8(_("Subject name"), info
->firmName
);
1720 print_header_utf8(_("Identity number"), info
->ic
);
1722 format_PersonName(info
->personName
);
1723 format_BirthInfo(info
->birthInfo
);
1725 format_Address(info
->address
);
1727 print_header_utf8(_("Nationality"), info
->nationality
);
1728 print_header_utf8(_("E-mail"), info
->email
);
1729 print_header_utf8(_("Phone"), info
->telNumber
);
1731 print_header_utf8(_("Identifier"), info
->identifier
);
1732 print_header_utf8(_("Registry code"), info
->registryCode
);
1734 print_header(_("State"), DbState2string(info
->dbState
));
1735 print_header_bool(_("Act as public authority"), info
->dbEffectiveOVM
);
1736 print_header_bool(_("Receive commercial messages"),
1737 info
->dbOpenAddressing
);
1741 /* Print formated details about a box found by a full-text */
1742 void format_isds_fulltext_result(const struct isds_fulltext_result
*info
) {
1743 if (NULL
== info
) return;
1745 print_header_utf8(_("Box ID"), info
->dbID
);
1746 print_header(_("Type"), DbType2string((long int *)&(info
->dbType
)));
1747 print_header_utf8(_("Subject name"), info
->name
);
1748 print_header_utf8(_("Identity number"), info
->ic
);
1749 print_header_utf8(_("Address"), info
->address
);
1750 print_header_tm(_("Birth date"), info
->biDate
);
1752 print_header_bool(_("Act as public authority"), &info
->dbEffectiveOVM
);
1753 print_header_bool(_("Active"), &info
->active
);
1754 print_header_bool(_("Non-commercial message can be sent"),
1755 &info
->public_sending
);
1756 print_header_bool(_("Commercial message can be sent"),
1757 &info
->commercial_sending
);
1762 static void format_supervising_firm(const char *ic
, const char *firmName
) {
1763 if (!ic
&& !firmName
) return;
1765 oprintf(_("Supervising subject:\n"));
1766 print_header_utf8(_("\tIdentity number"), ic
);
1767 print_header_utf8(_("\tName"), firmName
);
1771 static void format_contact_address(const char *caStreet
, const char *caCity
,
1772 const char *caZipCode
, const char *caState
) {
1773 if (!caStreet
&& !caCity
&& !caZipCode
) return;
1775 oprintf(_("Contact address:\n"));
1776 print_header_utf8(_("\tStreet"), caStreet
);
1777 print_header_utf8(_("\tCity"), caCity
);
1778 print_header_utf8(_("\tZIP code"), caZipCode
);
1779 print_header_utf8(_("\tState"), caState
);
1783 void format_DbUserInfo(const struct isds_DbUserInfo
*info
) {
1788 print_header_utf8(_("User ID"), info
->userID
);
1789 print_header(_("Type"), UserType2string((long int *) (info
->userType
)));
1791 buffer
= UserPrivils2string(info
->userPrivils
);
1792 print_header(_("Privileges"), buffer
);
1795 format_PersonName(info
->personName
);
1796 format_Address(info
->address
);
1798 print_header_tm(_("Birth date"), info
->biDate
);
1800 format_supervising_firm(info
->ic
, info
->firmName
);
1801 format_contact_address(info
->caStreet
, info
->caCity
, info
->caZipCode
,
1806 /* Print formated details about message sender */
1807 void format_sender_info(const char *dbID
, const isds_sender_type
*type
,
1808 const char *raw_type
, const char *name
) {
1809 const char *type_string
;
1811 if (!dbID
&& !type
&& !raw_type
&& !name
) return;
1813 oprintf(_("Message sender:\n"));
1814 print_header_utf8(_("\tMessage ID"), dbID
);
1816 type_string
= isds_sender_type2string(type
);
1818 print_header(_("\tType"), type_string
);
1820 print_header_utf8(_("\tRaw type"), raw_type
);
1822 print_header_utf8(_("\tName"), name
);
1826 static const char *credit_event_type2string(
1827 const isds_credit_event_type type
) {
1829 case ISDS_CREDIT_CHARGED
: return(_("Credit charged"));
1830 case ISDS_CREDIT_DISCHARGED
: return(_("Credit discharged"));
1831 case ISDS_CREDIT_MESSAGE_SENT
: return(_("Message sent"));
1832 case ISDS_CREDIT_STORAGE_SET
: return(_("Long-term storage set"));
1833 case ISDS_CREDIT_EXPIRED
: return(_("Credit expired"));
1834 default: return(_("<Unknown credit event type>"));
1839 /* Print formated details about credit change event */
1840 void format_credit_event(const struct isds_credit_event
*event
) {
1841 if (NULL
== event
) return;
1843 print_header_timeval(_("When"), event
->time
);
1844 print_header_currency(_("Credit change"), &event
->credit_change
);
1845 print_header_currency(_("Total credit"), &event
->new_credit
);
1846 print_header(_("Type"), credit_event_type2string(event
->type
));
1848 switch (event
->type
) {
1849 case ISDS_CREDIT_CHARGED
:
1850 print_header(_("Transation ID"),
1851 event
->details
.charged
.transaction
);
1853 case ISDS_CREDIT_DISCHARGED
:
1854 print_header(_("Transation ID"),
1855 event
->details
.discharged
.transaction
);
1857 case ISDS_CREDIT_MESSAGE_SENT
:
1858 print_header(_("Message ID"),
1859 event
->details
.message_sent
.message_id
);
1860 print_header(_("Message recipient"),
1861 event
->details
.message_sent
.recipient
);
1863 case ISDS_CREDIT_STORAGE_SET
:
1864 if (NULL
!= event
->details
.storage_set
.old_capacity
) {
1865 oprintf(_("Old setting:\n"));
1866 oprintf(ngettext("%s: %ld message\n", "%s: %ld messages\n",
1867 *event
->details
.storage_set
.old_capacity
),
1869 *event
->details
.storage_set
.old_capacity
);
1870 print_header_tm(_("\tValid from"),
1871 event
->details
.storage_set
.old_valid_from
);
1872 print_header_tm(_("\tValid to"),
1873 event
->details
.storage_set
.old_valid_to
);
1875 oprintf(_("New setting:\n"));
1876 oprintf(ngettext("%s: %ld message\n", "%s: %ld messages",
1877 event
->details
.storage_set
.new_capacity
),
1879 event
->details
.storage_set
.new_capacity
);
1880 print_header_tm(_("\tValid from"),
1881 event
->details
.storage_set
.new_valid_from
);
1882 print_header_tm(_("\tValid to"),
1883 event
->details
.storage_set
.new_valid_to
);
1884 print_header_utf8(_("Initiator"),
1885 event
->details
.storage_set
.initiator
);
1887 case ISDS_CREDIT_EXPIRED
:
1890 oprintf(_("Details can be missing due to unkown type.\n"));
1895 void format_commercial_permission(
1896 const struct isds_commercial_permission
*permission
) {
1897 if (NULL
== permission
) return;
1899 print_header(_("Payment type"),
1900 isds_payment_type2string(&permission
->type
));
1901 print_header_utf8(_("Allowed recipient box ID"), permission
->recipient
);
1902 print_header_utf8(_("Payed by owner of box ID"), permission
->payer
);
1903 print_header_timeval(_("Permission expires"), permission
->expiration
);
1904 print_header_ulongint(_("Remaining messages"), permission
->count
);
1905 print_header_utf8(_("Reference to request"), permission
->reply_identifier
);