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
);
417 oprintf("\t\tdmOrdinal = ");
418 if (!envelope
->dmOrdinal
) oprintf("NULL\n");
419 else oprintf("%lu\n", *(envelope
->dmOrdinal
));
421 oprintf("\t\tdmMessageStatus = ");
422 if (!envelope
->dmMessageStatus
) oprintf("NULL\n");
424 switch(*(envelope
->dmMessageStatus
)) {
425 case MESSAGESTATE_SENT
: oprintf("SENT\n"); break;
426 case MESSAGESTATE_STAMPED
: oprintf("STAMPED\n"); break;
427 case MESSAGESTATE_INFECTED
: oprintf("INFECTED\n"); break;
428 case MESSAGESTATE_DELIVERED
: oprintf("DELIVERED\n"); break;
429 case MESSAGESTATE_SUBSTITUTED
: oprintf("SUBSTITUTED\n"); break;
430 case MESSAGESTATE_RECEIVED
: oprintf("RECEIVED\n"); break;
431 case MESSAGESTATE_READ
: oprintf("READ\n"); break;
432 case MESSAGESTATE_UNDELIVERABLE
: oprintf("UNDELIVERABLE\n"); break;
433 case MESSAGESTATE_REMOVED
: oprintf("REMOVED\n"); break;
434 case MESSAGESTATE_IN_SAFE
: oprintf("IN_SAFE\n"); break;
435 default: oprintf("<unknown type %d>\n",
436 *(envelope
->dmMessageStatus
));
439 oprintf("\t\tdmAttachmentSize = ");
440 if (!envelope
->dmAttachmentSize
) oprintf("NULL\n");
441 else oprintf("%lu kB\n", *(envelope
->dmAttachmentSize
));
443 oprintf("\t\tdmDeliveryTime = ");
444 print_timeval(envelope
->dmDeliveryTime
);
446 oprintf("\t\tdmAcceptanceTime = ");
447 print_timeval(envelope
->dmAcceptanceTime
);
449 oprintf("\t\thash = ");
450 print_hash(envelope
->hash
);
452 oprintf("\t\ttimestamp = %p\n", envelope
->timestamp
);
453 oprintf("\t\ttimestamp_length = %zu\n", envelope
->timestamp_length
);
455 oprintf("\t\tevents = ");
456 print_events(envelope
->events
);
462 void print_document(const struct isds_document
*document
) {
463 oprintf("\t\tdocument = ");
471 oprintf("\t\t\tis_xml = %u\n", !!document
->is_xml
);
472 oprintf("\t\t\txml_node_list = %p\n", document
->xml_node_list
);
474 oprintf("\t\t\tdata = %p\n", document
->data
);
475 oprintf("\t\t\tdata_length = %zu\n", document
->data_length
);
476 oprintf("\t\t\tdmMimeType = %s\n", document
->dmMimeType
);
478 oprintf("\t\t\tdmFileMetaType = ");
479 switch(document
->dmFileMetaType
) {
480 case FILEMETATYPE_MAIN
: oprintf("MAIN\n"); break;
481 case FILEMETATYPE_ENCLOSURE
: oprintf("ENCLOSURE\n"); break;
482 case FILEMETATYPE_SIGNATURE
: oprintf("SIGNATURE\n"); break;
483 case FILEMETATYPE_META
: oprintf("META\n"); break;
484 default: oprintf("<unknown type %d>\n", document
->dmFileMetaType
);
487 oprintf("\t\t\tdmFileGuid = %s\n", document
->dmFileGuid
);
488 oprintf("\t\t\tdmUpFileGuid = %s\n", document
->dmUpFileGuid
);
489 oprintf("\t\t\tdmFileDescr = %s\n", document
->dmFileDescr
);
490 oprintf("\t\t\tdmFormat = %s\n", document
->dmFormat
);
495 void print_documents(const struct isds_list
*documents
) {
496 const struct isds_list
*item
;
498 oprintf("\tdocuments = ");
506 for (item
= documents
; item
; item
= item
->next
) {
507 print_document((struct isds_document
*) (item
->data
));
514 void print_message(const struct isds_message
*message
) {
515 oprintf("message = ");
524 oprintf("\traw = %p\n", message
->raw
);
525 oprintf("\traw_length = %zu\n", message
->raw_length
);
526 oprintf("\traw_type = ");
527 print_raw_type(message
->raw_type
);
528 print_envelope(message
->envelope
);
529 print_documents(message
->documents
);
534 void print_copies(const struct isds_list
*copies
) {
535 const struct isds_list
*item
;
536 struct isds_message_copy
*copy
;
538 oprintf("Copies = ");
545 for (item
= copies
; item
; item
= item
->next
) {
546 copy
= (struct isds_message_copy
*) item
->data
;
547 oprintf("\tCopy = ");
553 oprintf("\t\tdbIDRecipient = %s\n", copy
->dbIDRecipient
);
554 oprintf("\t\tdmRecipientOrgUnit = %s\n", copy
->dmRecipientOrgUnit
);
556 oprintf("\t\tdmRecipientOrgUnitNum = ");
557 if (copy
->dmRecipientOrgUnitNum
)
558 oprintf("%ld\n", *copy
->dmRecipientOrgUnitNum
);
561 oprintf("\t\tdmToHands = %s\n", copy
->dmToHands
);
563 oprintf("\t\terror = %s\n", isds_strerror(copy
->error
));
564 oprintf("\t\tdmStatus = %s\n", copy
->dmStatus
);
565 oprintf("\t\tdmID = %s\n", copy
->dmID
);
573 void compare_hashes(const struct isds_hash
*hash1
,
574 const struct isds_hash
*hash2
) {
577 oprintf("Comparing hashes... ");
578 err
= isds_hash_cmp(hash1
, hash2
);
579 if (err
== IE_SUCCESS
)
580 oprintf("Hashes equal\n");
582 (err
== IE_NOTEQUAL
) oprintf("Hashes differ\n");
584 oprintf("isds_hash_cmp() failed: %s\n", isds_strerror(err
));
588 int progressbar(double upload_total
, double upload_current
,
589 double download_total
, double download_current
,
592 oprintf("Progress: upload %0f/%0f, download %0f/%0f, data=%p\n",
593 upload_current
, upload_total
, download_current
, download_total
,
599 /* Print formatted header if locale-encoded value is defined.
600 * @header is locale encoded header name
601 * @value is locale encoded header value */
602 void print_header(const char *header
, const char *value
) {
603 if (value
&& *value
) oprintf(_("%s: %s\n"), header
, value
);
607 /* Print formatted header if boolean value is defined.
608 * @header is locale encoded header name */
609 void print_header_bool(const char *header
, _Bool
*value
) {
610 if (value
) print_header(header
, (*value
) ? _("Yes") : _("No"));
614 /* Print formatted header if long int value is defined.
615 * @header is locale encoded header name */
616 void print_header_longint(const char *header
, long int *value
) {
617 if (value
) oprintf(_("%s: %ld\n"), header
, *value
);
621 /* Print formatted header if unsigned long int value is defined.
622 * @header is locale encoded header name */
623 void print_header_ulongint(const char *header
, unsigned long int *value
) {
624 if (value
) oprintf(_("%s: %lu\n"), header
, *value
);
628 /* Print formatted header if time value is defined.
629 * @header is locale encoded header name */
630 void print_header_timeval(const char *header
, struct timeval
*time
) {
636 if (!localtime_r(&(time
->tv_sec
), &broken
)) goto error
;
637 if (!strftime(buffer
, sizeof(buffer
)/sizeof(char), "%c", &broken
))
641 oprintf(_("%s: %s\n"), header
, buffer
);
642 else if ((time
->tv_usec
% 1000) == 0)
643 oprintf(_("%s: %s, %ld ms\n"), header
, buffer
, time
->tv_usec
/1000);
645 oprintf(_("%s: %s, %ld us\n"), header
, buffer
, time
->tv_usec
);
650 oprintf(_("%s: <Error while formatting time>\n"), header
);
655 /* Return formatted date as mallocated string. NULL or special error string can
656 * be returned. Application must free even the error string. */
657 char *tm2string(const struct tm
*date
) {
659 size_t buffer_length
= 128;
661 if (!date
) return NULL
;
663 buffer
= malloc(buffer_length
);
664 if (!buffer
) return strdup(_("<Error while formatting date>"));
666 if (0 == strftime(buffer
, buffer_length
, "%x", date
)) {
668 return strdup(_("<Error while formatting date>"));
675 /* Convert string representation of full ISO 8601 or locale date to tm structure.
676 * Return NULL if error occurs
677 * XXX: Not all ISO formats are supported */
678 struct tm
*datestring2tm(const char *string
) {
679 struct tm
*date
= NULL
;
681 if (!string
) return NULL
;
683 date
= calloc(1, sizeof(*date
));
684 if (!date
) return NULL
;
686 /* xsd:date is ISO 8601 string, thus ASCII */
687 offset
= strptime(string
, "%Y-%m-%d", date
);
688 if (offset
&& *offset
== '\0')
691 offset
= strptime(string
, "%x", date
);
692 if (offset
&& *offset
== '\0')
700 /* Print formatted header if date value is defined.
701 * @header is locale encoded header name */
702 void print_header_tm(const char *header
, struct tm
*date
) {
705 if (NULL
== date
) return;
706 string
= tm2string(date
);
709 oprintf(_("%s: <Error while formatting date>\n"), header
);
711 print_header(header
, string
);
717 /* Print formatted header if UTF-9 value is defined.
718 * @header is locale encoded header name
719 * @value is UTF-8 encoded header value */
720 void print_header_utf8(const char *header
, const char *value
) {
725 value_locale
= utf82locale(value
);
729 _("<Error while converting value>"));
734 /* Print formatted header and byte size.
735 * @header is locale encoded header name */
736 void print_header_size(const char *header
, size_t size
) {
740 shi_asprintf(&buffer
, _("%zu B"), size
);
741 else if (size
< (1<<20))
742 shi_asprintf(&buffer
, _("%0.2f KiB"), (float) size
/(1<<10));
744 shi_asprintf(&buffer
, _("%0.2f MiB"), (float) size
/(1<<20));
746 print_header(header
, buffer
);
751 /* Print formatted header if long int KB size is defined.
752 * @header is locale encoded header name */
753 void print_header_kbsize(const char *header
, const long int *size
) {
758 shi_asprintf(&buffer
, _("<Negative size>"));
759 else if (*size
< (1000))
760 shi_asprintf(&buffer
, _("%lu kB"), *size
);
762 shi_asprintf(&buffer
, _("%0.2f MB"), *size
/1000.0);
764 print_header(header
, buffer
);
769 static const char *DbType2string(const long int *type
) {
770 if (!type
) return NULL
;
772 case DBTYPE_SYSTEM
: return(_("System"));
773 case DBTYPE_FO
: return(_("Private individual"));
774 case DBTYPE_PFO
: return(_("Self-employed individual"));
775 case DBTYPE_PFO_ADVOK
: return(_("Lawyer"));
776 case DBTYPE_PFO_DANPOR
: return(_("Tax advisor"));
777 case DBTYPE_PFO_INSSPR
: return(_("Insolvency administrator"));
778 case DBTYPE_PO
: return(_("Organisation"));
779 case DBTYPE_PO_ZAK
: return(_("Organization based by law"));
780 case DBTYPE_PO_REQ
: return(_("Organization based on request"));
781 case DBTYPE_OVM
: return(_("Public authority"));
782 case DBTYPE_OVM_NOTAR
: return(_("Notary"));
783 case DBTYPE_OVM_EXEKUT
: return(_("Executor"));
784 case DBTYPE_OVM_REQ
: return(_("Public authority based on request"));
785 default: return(_("<Unknown type>"));
790 static const char *UserType2string(const long int *type
) {
791 if (!type
) return NULL
;
793 case USERTYPE_PRIMARY
: return(_("Primary"));
794 case USERTYPE_ENTRUSTED
: return(_("Entrusted"));
795 case USERTYPE_ADMINISTRATOR
: return(_("Administrator"));
796 case USERTYPE_OFFICIAL
: return(_("Official"));
797 default: return(_("<Unknown type>"));
802 static const char *isds_sender_type2string(const isds_sender_type
*type
) {
803 if (!type
) return NULL
;
805 case SENDERTYPE_PRIMARY
: return(_("Primary"));
806 case SENDERTYPE_ENTRUSTED
: return(_("Entrusted"));
807 case SENDERTYPE_ADMINISTRATOR
: return(_("Administrator"));
808 case SENDERTYPE_OFFICIAL
: return(_("Official"));
809 case SENDERTYPE_VIRTUAL
: return(_("Virtual"));
810 default: return(_("<unknown type>"));
815 /* Return formatted user privileges. Caller must free the string */
816 static char *UserPrivils2string(const long int *privils
) {
818 const char *priviledges
[] = {
819 N_("Read non-personal"),
821 N_("Send and read sent"),
822 N_("List messages and read delivery details"),
824 N_("Administer her box"),
825 N_("Read from safe"),
826 N_("Delete from safe")
828 const int priviledges_count
= sizeof(priviledges
)/sizeof(priviledges
[0]);
829 char *buffer
= NULL
, *new_buffer
= NULL
;
831 if (!privils
) return NULL
;
833 /*oprintf("%ld (", *privils);*/
835 for (int i
= 0; i
< priviledges_count
; i
++) {
836 if (*privils
& (1<<i
)) {
837 if ((*privils
% (1<<i
)))
838 shi_asprintf(&new_buffer
, _("%s, %s"),
839 buffer
, _(priviledges
[i
]));
841 shi_asprintf(&new_buffer
, "%s", _(priviledges
[i
]));
845 return(strdup(_("<Error while formatting privileges>")));
854 if (*privils
>= (1<<priviledges_count
)) {
855 if ((*privils
% (1<<priviledges_count
)))
856 shi_asprintf(&new_buffer
, _("%s, %s"),
857 buffer
, _("<Unknown privilege>"));
859 shi_asprintf(&new_buffer
, "%s", _("<Unknown privilege>"));
863 return(strdup(_("<Error while formatting privileges>")));
875 static const char *DmType2string(const char *type
) {
876 if (!type
) return NULL
;
877 if (!strcmp(type
, "V"))
879 else if (!strcmp(type
, "K"))
880 return(_("Commercial"));
881 else if (!strcmp(type
, "A"))
882 return(_("Commercial (initiatory, unused, subsidized)"));
883 else if (!strcmp(type
, "B"))
884 return(_("Commercial (initiatory, used, subsidized)"));
885 else if (!strcmp(type
, "C"))
886 return(_("Commercial (initiatory, expired, subsidized)"));
887 else if (!strcmp(type
, "D"))
888 return(_("Commercial (externally subsidized)"));
889 else if (!strcmp(type
, "E"))
890 return(_("Commercial (prepaid by a stamp)"));
891 else if (!strcmp(type
, "G"))
892 return(_("Commercial (sponsored)"));
893 else if (!strcmp(type
, "I"))
894 return(_("Commercial (initiatory, unused, paid by sender)"));
895 else if (!strcmp(type
, "O"))
896 return(_("Commercial (response paid by recipient)"));
897 else if (!strcmp(type
, "X"))
898 return(_("Commercial (initiatory, expired, paid by sender)"));
899 else if (!strcmp(type
, "Y"))
900 return(_("Commercial (initiatory, used, paid by sender)"));
901 else if (!strcmp(type
, "Z"))
902 return(_("Commercial (limitedly subsidized)"));
903 else return(_("<Unknown type>"));
907 /* Simplified commercial status printed on message listing.
908 * 'P' is a public message sent by a government
909 * 'C' is a commercial message
910 * 'I' is a commercial message offering to pay response instead of the
912 * 'i' is a commercial message that offered to pay reposne, but it does not
914 * 'R' is a commercial response message paid by sender of the I message. */
915 static const char DmType2flag(const char *type
) {
916 if (!type
) return ' ';
917 if (!strcmp(type
, "V")) return('P');
918 else if (!strcmp(type
, "K")) return('C');
919 else if (!strcmp(type
, "A")) return('I');
920 else if (!strcmp(type
, "B")) return('i');
921 else if (!strcmp(type
, "C")) return('i');
922 else if (!strcmp(type
, "D")) return('C');
923 else if (!strcmp(type
, "E")) return('C');
924 else if (!strcmp(type
, "G")) return('C');
925 else if (!strcmp(type
, "I")) return('I');
926 else if (!strcmp(type
, "O")) return('R');
927 else if (!strcmp(type
, "X")) return('i');
928 else if (!strcmp(type
, "Y")) return('i');
929 else if (!strcmp(type
, "Z")) return('C');
934 static const char *DmMessageStatus2string(const isds_message_status
*status
) {
935 if (!status
) return NULL
;
937 case MESSAGESTATE_SENT
: return(_("Sent"));
938 case MESSAGESTATE_STAMPED
: return(_("Stamped"));
939 case MESSAGESTATE_INFECTED
: return(_("Infected"));
940 case MESSAGESTATE_DELIVERED
: return(_("Delivered ordinary"));
941 case MESSAGESTATE_SUBSTITUTED
: return(_("Delivered substitutably"));
942 case MESSAGESTATE_RECEIVED
: return(_("Accepted"));
943 case MESSAGESTATE_READ
: return(_("Read"));
944 case MESSAGESTATE_UNDELIVERABLE
: return(_("Undeliverable"));
945 case MESSAGESTATE_REMOVED
: return(_("Deleted"));
946 case MESSAGESTATE_IN_SAFE
: return(_("Stored in safe"));
947 default: return(_("<Unknown state>"));
952 static const char DmMessageStatus2flag(const isds_message_status
*status
) {
953 if (!status
) return ' ';
955 case MESSAGESTATE_SENT
: return('>');
956 case MESSAGESTATE_STAMPED
: return('t');
957 case MESSAGESTATE_INFECTED
: return('I');
958 case MESSAGESTATE_DELIVERED
: return('N');
959 case MESSAGESTATE_SUBSTITUTED
: return('n');
960 case MESSAGESTATE_RECEIVED
: return('O');
961 case MESSAGESTATE_READ
: return(' ');
962 case MESSAGESTATE_UNDELIVERABLE
: return('!');
963 case MESSAGESTATE_REMOVED
: return('D');
964 case MESSAGESTATE_IN_SAFE
: return('S');
965 default: return('?');
970 /* Return timeval time formatted into shortest string with respect to current
971 * time. Caller must free the string. */
972 static char *timeval2shortstring(const struct timeval
*timeval
) {
973 struct tm broken
, current_broken
;
976 const size_t buffer_size
= 16;
978 if (!timeval
) return NULL
;
980 buffer
= malloc(buffer_size
);
981 if (!buffer
) goto error
;
983 /* Get current time */
984 current_time
= time(NULL
);
985 if (current_time
== (time_t) -1) goto error
;
986 if (!localtime_r(¤t_time
, ¤t_broken
)) goto error
;
988 /* Get broken time */
989 if (!localtime_r(&(timeval
->tv_sec
), &broken
)) goto error
;
991 /* Select proper abbreviated string representation */
992 if (broken
.tm_year
== current_broken
.tm_year
&&
993 broken
.tm_yday
== current_broken
.tm_yday
) {
994 /* Minute resolution in the same day */
995 if (!strftime(buffer
, buffer_size
, _("%k:%M"), &broken
))
998 /* Otherwise month and day */
999 if (!strftime(buffer
, buffer_size
, _("%b %d"), &broken
))
1007 return strdup(_("<Error>"));
1011 /* Formatted Law Authorization if defined. You must free it. */
1012 static char *envelope_law2string(const struct isds_envelope
*envelope
) {
1013 char *output
= NULL
;
1014 char *year_locale
= NULL
, *law_locale
= NULL
;
1015 char *sect_locale
= NULL
, *par_locale
= NULL
, *point_locale
= NULL
;
1018 !(envelope
->dmLegalTitleYear
|| envelope
->dmLegalTitleLaw
||
1019 envelope
->dmLegalTitleSect
|| envelope
->dmLegalTitlePar
||
1020 envelope
->dmLegalTitlePoint
)
1023 if (envelope
->dmLegalTitleYear
)
1024 shi_asprintf(&year_locale
, "%ld", *envelope
->dmLegalTitleYear
);
1026 year_locale
= strdup(_("?"));
1028 if (envelope
->dmLegalTitleLaw
)
1029 shi_asprintf(&law_locale
, "%ld", *envelope
->dmLegalTitleLaw
);
1031 law_locale
= strdup(_("?"));
1033 sect_locale
= utf82locale(envelope
->dmLegalTitleSect
);
1034 par_locale
= utf82locale(envelope
->dmLegalTitlePar
);
1035 point_locale
= utf82locale(envelope
->dmLegalTitlePoint
);
1038 shi_asprintf(&output
, _("point %s, par. %s, sect. %s, %s/%s Coll."),
1039 point_locale
, par_locale
, sect_locale
,
1040 law_locale
, year_locale
);
1041 else if (par_locale
)
1042 shi_asprintf(&output
, _("par. %s, sect. %s, %s/%s Coll."),
1043 par_locale
, sect_locale
, law_locale
, year_locale
);
1044 else if (sect_locale
)
1045 shi_asprintf(&output
, _("sect. %s, %s/%s Coll."),
1046 sect_locale
, law_locale
, year_locale
);
1048 shi_asprintf(&output
, _("%s/%s Coll."),
1049 law_locale
, year_locale
);
1060 static const char *isds_payment_type2string(const isds_payment_type
*type
) {
1061 if (!type
) return NULL
;
1063 case PAYMENT_SENDER
: return(_("Payed by sender"));
1064 case PAYMENT_STAMP
: return(_("Stamp pre-paid by sender"));
1065 case PAYMENT_SPONSOR
: return(_("Sponsor pays all messages"));
1066 case PAYMENT_RESPONSE
: return(_("Recipient pays a response"));
1067 case PAYMENT_SPONSOR_LIMITED
: return(_("Limitedly subsidized"));
1068 case PAYMENT_SPONSOR_EXTERNAL
: return(_("Externally subsidized"));
1069 default: return(_("<unknown type>"));
1074 /* Print formatted header if time any of message ID.
1075 * @header is locale encoded header name */
1076 static void print_header_messages_ids(const char *header
,
1077 const char *ref_number
, const char *ident
) {
1078 if (ref_number
|| ident
) {
1079 oprintf(_("%s:\n"), header
);
1080 print_header_utf8(_("\tReference number"), ref_number
);
1081 print_header_utf8(_("\tFile ID"), ident
);
1086 /* Return formatted hash value */
1087 char *hash2string(const struct isds_hash
*hash
) {
1088 const char *algorithm_string
= NULL
;
1089 char *buffer
= NULL
, *octet
= NULL
, *new_buffer
= NULL
;
1091 if (!hash
|| !hash
->value
) return NULL
;
1093 switch(hash
->algorithm
) {
1094 case HASH_ALGORITHM_MD5
: algorithm_string
= (_("MD5")); break;
1095 case HASH_ALGORITHM_SHA_1
: algorithm_string
= (_("SHA-1")); break;
1096 case HASH_ALGORITHM_SHA_224
: algorithm_string
= (_("SHA-224")); break;
1097 case HASH_ALGORITHM_SHA_256
: algorithm_string
= (_("SHA-256")); break;
1098 case HASH_ALGORITHM_SHA_384
: algorithm_string
= (_("SHA-384")); break;
1099 case HASH_ALGORITHM_SHA_512
: algorithm_string
= (_("SHA-512")); break;
1100 default: algorithm_string
= (_("<Unknown hash algorithm>")); break;
1103 for (int i
= 0; i
< hash
->length
; i
++) {
1104 shi_asprintf(&octet
, "%02x", ((uint8_t *)(hash
->value
))[i
]);
1106 free(buffer
); free(octet
); return NULL
;
1110 shi_asprintf(&new_buffer
, _("%s:%s"), buffer
, octet
);
1112 shi_asprintf(&new_buffer
, "%s", octet
);
1114 free(buffer
); free(octet
); return NULL
;
1117 buffer
= new_buffer
; new_buffer
= NULL
;
1120 shi_asprintf(&new_buffer
, _("%s %s"), algorithm_string
, buffer
);
1127 /* Print if any message delivery info exists. */
1128 void print_message_delivery_info(const struct isds_envelope
*envelope
) {
1129 char *hash_string
= NULL
;
1131 if (envelope
&& (envelope
->dmType
|| envelope
->dmMessageStatus
||
1132 envelope
->dmDeliveryTime
||
1133 envelope
->dmAcceptanceTime
|| envelope
->dmPersonalDelivery
||
1134 envelope
->dmAllowSubstDelivery
|| envelope
->hash
||
1135 envelope
->dmOrdinal
)) {
1136 oprintf(_("Delivery data:\n"));
1137 print_header(_("\tMessage type"), DmType2string(envelope
->dmType
));
1138 print_header(_("\tMessage status"),
1139 DmMessageStatus2string(envelope
->dmMessageStatus
));
1140 print_header_timeval(_("\tDelivered"), envelope
->dmDeliveryTime
);
1141 print_header_timeval(_("\tAccepted"), envelope
->dmAcceptanceTime
);
1142 print_header_bool(_("\tPersonal delivery required"),
1143 envelope
->dmPersonalDelivery
);
1144 print_header_bool(_("\tAllow substitutable delivery"),
1145 envelope
->dmAllowSubstDelivery
);
1147 hash_string
= hash2string(envelope
->hash
);
1148 print_header(_("\tHash"), hash_string
);
1151 print_header_ulongint(_("\tOrdinal number"), envelope
->dmOrdinal
);
1156 static const char *event_type2string(const isds_event_type
*type
) {
1157 if (!type
) return (_("<Undefined>"));
1160 case EVENT_UKNOWN
: return(_("Unknown"));
1161 case EVENT_ENTERED_SYSTEM
:
1162 return(_("Entered system"));
1163 case EVENT_ACCEPTED_BY_RECIPIENT
:
1164 return(_("Accepted by recipient"));
1165 case EVENT_ACCEPTED_BY_FICTION
:
1166 return(_("Delivered substitutably"));
1167 case EVENT_UNDELIVERABLE
:
1168 return(_("Undeliverable"));
1169 case EVENT_COMMERCIAL_ACCEPTED
:
1170 return(_("Commerical message accepted by "
1171 "recipient")); break;
1172 case EVENT_DELIVERED
:
1173 return(_("Delivered into box")); break;
1174 case EVENT_PRIMARY_LOGIN
:
1175 return(_("Primary user logged in")); break;
1176 case EVENT_ENTRUSTED_LOGIN
:
1177 return(_("Entrusted user logged in")); break;
1178 case EVENT_SYSCERT_LOGIN
:
1179 return(_("Application logged in by system "
1180 "certificate")); break;
1181 default: return(_("<Unknown event type>"));
1186 /* Print if any delivery event exists. */
1187 void print_delivery_events(const struct isds_list
*events
) {
1188 int counter_width
= 3;
1190 const struct isds_list
*item
;
1191 struct isds_event
*event
;
1193 if (!events
) return;
1195 oprintf(_("Delivery events:\n"));
1197 for (item
= events
; item
; item
= item
->next
) {
1198 event
= (struct isds_event
*) item
->data
;
1199 if (!event
) continue;
1202 oprintf(_("%*d %s\n"), counter_width
, order
,
1203 event_type2string(event
->type
));
1204 print_header_utf8(_("\tDescription"), event
->description
);
1205 print_header_timeval(_("\tWhen"), event
->time
);
1210 /* Print formatted message envelope */
1211 void format_envelope(const struct isds_envelope
*envelope
) {
1212 char *law_string
= NULL
;
1215 oprintf(_("<Missing envelope>\n"));
1219 print_header_utf8(_("Message ID"), envelope
->dmID
);
1221 if (envelope
->dbIDSender
|| envelope
->dmSender
||
1222 envelope
->dmSenderOrgUnit
|| envelope
->dmSenderOrgUnitNum
||
1223 envelope
->dmSenderAddress
|| envelope
->dmSenderType
||
1225 oprintf(_("Sender:\n"));
1226 print_header_utf8(_("\tID"), envelope
->dbIDSender
);
1227 print_header_utf8(_("\tName"), envelope
->dmSender
);
1228 print_header_utf8(_("\tUnit"), envelope
->dmSenderOrgUnit
);
1229 print_header_longint(_("\tUnit number"), envelope
->dmSenderOrgUnitNum
);
1230 print_header_utf8(_("\tAddress"), envelope
->dmSenderAddress
);
1231 print_header(_("\tType"), DbType2string(envelope
->dmSenderType
));
1232 print_header_bool(_("\tAs public authority"), envelope
->dmOVM
);
1235 if (envelope
->dbIDRecipient
|| envelope
->dmRecipient
||
1236 envelope
->dmRecipientOrgUnit
|| envelope
->dmRecipientOrgUnitNum
||
1237 envelope
->dmToHands
|| envelope
->dmRecipientAddress
||
1238 envelope
->dmAmbiguousRecipient
) {
1239 oprintf(_("Recipient:\n"));
1240 print_header_utf8(_("\tID"), envelope
->dbIDRecipient
);
1241 print_header_utf8(_("\tName"), envelope
->dmRecipient
);
1242 print_header_utf8(_("\tUnit"), envelope
->dmRecipientOrgUnit
);
1243 print_header_longint(_("\tUnit number"),
1244 envelope
->dmRecipientOrgUnitNum
);
1245 print_header_utf8(_("To hands"), envelope
->dmToHands
);
1246 print_header_utf8(_("\tAddress"), envelope
->dmRecipientAddress
);
1247 print_header_bool(_("\tAs public authority"),
1248 envelope
->dmAmbiguousRecipient
);
1251 print_header_utf8(_("Subject"), envelope
->dmAnnotation
);
1253 print_header_messages_ids(_("Sender message IDs"),
1254 envelope
->dmSenderRefNumber
, envelope
->dmSenderIdent
);
1255 print_header_messages_ids(_("Recipient message IDs"),
1256 envelope
->dmRecipientRefNumber
, envelope
->dmRecipientIdent
);
1258 law_string
= envelope_law2string(envelope
);
1259 print_header(_("Law authorization"), law_string
);
1262 print_message_delivery_info(envelope
);
1264 print_header_kbsize(_("Document total size"), envelope
->dmAttachmentSize
);
1266 /*oprintf("\t\ttimestamp = %p\n", envelope->timestamp);
1267 oprintf("\t\ttimestamp_length = %zu\n", envelope->timestamp_length);*/
1268 print_delivery_events(envelope
->events
);
1272 const char *DmFileMetaType2string(isds_FileMetaType type
) {
1274 case FILEMETATYPE_MAIN
: return(_("Main document"));
1275 case FILEMETATYPE_ENCLOSURE
: return(_("Enclosure"));
1276 case FILEMETATYPE_SIGNATURE
: return(_("Signature"));
1277 case FILEMETATYPE_META
: return(_("Meta document"));
1278 default: return(_("<unknown document type>"));
1283 /* Computes ordinal number of document identified by GUID
1284 * @documents is list of documents where to search
1285 * @id is UTF-8 encoded document ID reference
1286 * Return allocated array of ordinal numbers terminated by -1. Normally only
1287 * one document with @id exists. However ISDS does not check this higher
1288 * requirements and can transport message with duplicate document identifiers.
1289 * Therefore this function returns array of ordinals. Return NULL if error
1290 * occurs (e.g. memory insufficiency). */
1291 static int *dmFileGuid2ordinar(const struct isds_list
*documents
,
1293 const struct isds_list
*item
;
1294 struct isds_document
*document
;
1295 size_t ordinars_length
= 64, offset
= 0;
1296 int *ordinars
= NULL
, *new_ordinars
;
1299 if (!documents
|| !id
|| !*id
) return NULL
;
1300 ordinars
= malloc(ordinars_length
* sizeof(*ordinars
));
1301 if (!ordinars
) return NULL
;
1303 for (item
= documents
; item
; item
= item
->next
) {
1304 if (!item
->data
) continue;
1306 document
= (struct isds_document
*) (item
->data
);
1308 if (document
->dmFileGuid
&& !strcmp(document
->dmFileGuid
, id
)) {
1309 if (offset
== ordinars_length
) {
1310 /* Grow ordinals array */
1311 ordinars_length
*= 2;
1312 new_ordinars
= realloc(ordinars
,
1313 ordinars_length
* sizeof(*ordinars
));
1314 if (!new_ordinars
) {
1318 ordinars
= new_ordinars
;
1321 ordinars
[offset
++] = ordinar
;
1325 ordinars
[offset
] = -1;
1330 /* @id is UTF-8 encoded GUID of referred document
1331 * @refernces is array of ordinal numbers if exist terminated by -1. Can be
1332 * NULL to signal error. */
1333 static void format_document_reference(char *id
, int *references
) {
1334 char *buffer
= NULL
, *new_buffer
= NULL
;
1337 if (references
&& *references
!= -1) {
1338 for (; *references
> 0; references
++) {
1340 shi_asprintf(&new_buffer
, _("%d"), *references
);
1342 shi_asprintf(&new_buffer
, _("%s, %d"), buffer
, *references
);
1348 buffer
= new_buffer
;
1352 char *id_locale
= utf82locale(id
);
1353 shi_asprintf(&buffer
,
1354 _("<Reference to non-existing document ID `%s'>"), id_locale
);
1359 print_header(_("\tRefers to"), buffer
);
1361 print_header(_("\tRefers to"), _("<Error while formatting reference>"));
1366 /* Print formatted document
1367 * @references is ordinal number of referred document. Formally it's array
1368 * terminated by -1 because non-well-formed message can have more documents
1370 void format_document(const struct isds_document
*document
, int order
,
1372 int counter_width
= 3;
1373 char *filename_locale
= NULL
;
1375 if (!document
) return;
1377 oprintf(_("%*d "), counter_width
, order
);
1379 if (document
->dmFileDescr
) {
1380 filename_locale
= utf82locale(document
->dmFileDescr
);
1381 oprintf("%s\n", filename_locale
);
1382 free(filename_locale
);
1384 oprintf(_("<Unknown file name>\n"));
1387 if (document
->is_xml
) {
1388 char *message
=NULL
;
1391 for (xmlNodePtr node
= document
->xml_node_list
; node
;
1392 node
= node
->next
) nodes
++;
1393 shi_asprintf(&message
, ngettext("%d node", "%d nodes", nodes
), nodes
);
1395 print_header(_("\tXML document"), message
);
1399 print_header_size(_("\tSize"), document
->data_length
);
1401 print_header(_("\tMIME type"), document
->dmMimeType
);
1403 print_header(_("\tType"), DmFileMetaType2string(document
->dmFileMetaType
));
1404 print_header_utf8(_("\tMeta format"), document
->dmFormat
);
1406 print_header_utf8(_("\tID"), document
->dmFileGuid
);
1407 format_document_reference(document
->dmUpFileGuid
, references
);
1411 /* Print formatted message documents */
1412 void format_documents(const struct isds_list
*documents
) {
1413 const struct isds_list
*item
;
1414 const struct isds_document
*document
;
1417 if (!documents
) return;
1419 oprintf(_("Documents:\n"));
1421 for (item
= documents
; item
; item
= item
->next
) {
1422 if (!item
->data
) continue;
1423 document
= (struct isds_document
*) item
->data
;
1424 references
= dmFileGuid2ordinar(documents
, document
->dmUpFileGuid
);
1425 format_document(document
, ++i
, references
);
1431 /* Print formatted message */
1432 void format_message(const struct isds_message
*message
) {
1433 if (!message
) return;
1434 format_envelope(message
->envelope
);
1435 format_documents(message
->documents
);
1439 /* Print formatted list of message copies */
1440 void format_copies(const struct isds_list
*copies
) {
1441 const struct isds_list
*item
;
1442 const struct isds_message_copy
*copy
;
1444 int counter_width
= 3;
1445 if (!copies
) return;
1447 for (item
= copies
; item
; item
= item
->next
) {
1448 if (!item
->data
) continue;
1449 copy
= (struct isds_message_copy
*) item
->data
;
1452 oprintf(_("%*d Recipient:\n"), counter_width
, i
);
1453 print_header_utf8(_("\tID"), copy
->dbIDRecipient
);
1454 print_header_utf8(_("\tUnit"), copy
->dmRecipientOrgUnit
);
1455 print_header_longint(_("\tUnit number"), copy
->dmRecipientOrgUnitNum
);
1456 print_header_utf8(_("\tTo hands"), copy
->dmToHands
);
1461 void print_message_list(const struct isds_list
*messages
, _Bool outgoing
) {
1462 const struct isds_list
*item
;
1463 struct isds_envelope
*envelope
;
1464 unsigned long int counter
= 0;
1466 int counter_max
, id_max
= 0, name_max
= 0, subject_max
= 0;
1467 int counter_width
, id_width
= 0, flags_width
= 2, time_width
= 6,
1468 name_width
= 0, subject_width
= 0;
1470 char *id_locale
= NULL
, flags_locale
[3], *time_locale
= NULL
,
1471 *name_locale
= NULL
, *subject_locale
= NULL
;
1476 /* Compute column widths */
1477 rl_get_screen_size(NULL
, &screen_cols
);
1479 /* Get real maximal widths */
1480 for (counter
= 0, item
= messages
; item
; item
= item
->next
) {
1481 if (!item
->data
|| !((struct isds_message
*)item
->data
)->envelope
)
1483 envelope
= ((struct isds_message
*) item
->data
)->envelope
;
1486 width
= utf8width(envelope
->dmID
);
1487 if (width
> id_max
) id_max
= width
;
1489 width
= utf8width((outgoing
) ?
1490 envelope
->dmRecipient
: envelope
->dmSender
);
1491 if (width
> name_max
) name_max
= width
;
1493 width
= utf8width(envelope
->dmAnnotation
);
1494 if (width
> subject_max
) subject_max
= width
;
1496 counter_max
= numberwidth(counter
);
1498 /* Correct widths to fit into window */
1499 if (counter_max
< 0) counter_width
= -3; else counter_width
= counter_max
;
1500 if (id_max
< 0) id_width
= -6; else id_width
= id_max
;
1501 if (name_max
< 0) name_width
= -20; else name_width
= name_max
;
1502 if (subject_max
< 0) subject_width
= -32; else subject_width
= subject_max
;
1504 width
= abs(counter_width
) + 1 + abs(id_width
) + 1 + abs(flags_width
) + 1 +
1505 abs(time_width
) + 1 + abs(name_width
) + 1 + abs(subject_width
);
1506 if (width
> screen_cols
) {
1507 width
-= abs(name_width
) + abs(subject_width
);
1509 name_width
= subject_width
= 0;
1510 while (width
+ name_width
+ subject_width
< screen_cols
) {
1511 if (name_width
< abs(name_max
)) name_width
++;
1512 if (subject_width
< abs(subject_max
)) subject_width
++;
1514 if (width
+ name_width
+ subject_width
> screen_cols
) subject_width
--;
1518 /* TRANSLATORS: "No" is abbreviation for "Number" in listing header. */
1519 onprint(pgettext("list header", "No"), counter_width
);
1521 onprint(_("ID"), id_width
);
1523 onprint(_("Flags"), flags_width
);
1525 onprint(_("Delivered"), time_width
);
1527 onprint((outgoing
) ? _("To") : _("From"), name_width
);
1529 onprint(_("Subject"), subject_width
);
1531 for (int i
= 0; i
< screen_cols
; i
++) oprintf(_("-"));
1534 /* Print the list */
1535 for (counter
= 0, item
= messages
; item
; item
= item
->next
) {
1536 envelope
= ((struct isds_message
*) item
->data
)->envelope
;
1539 oprintf(_("%*lu "), counter_width
, counter
);
1542 oprintf(_("<Missing envelope>\n"));
1546 id_locale
= utf82locale(envelope
->dmID
);
1547 name_locale
= utf82locale((outgoing
) ?
1548 envelope
->dmRecipient
: envelope
->dmSender
);
1549 flags_locale
[0] = DmType2flag(envelope
->dmType
);
1550 flags_locale
[1] = DmMessageStatus2flag(envelope
->dmMessageStatus
);
1551 flags_locale
[2] = '\0';
1552 time_locale
= timeval2shortstring(envelope
->dmDeliveryTime
);
1553 subject_locale
= utf82locale(envelope
->dmAnnotation
);
1555 onprint(id_locale
, id_width
);
1557 onprint(flags_locale
, flags_width
);
1559 onprint(time_locale
, time_width
);
1561 onprint(name_locale
, name_width
);
1563 onprint(subject_locale
, subject_width
);
1569 zfree(subject_locale
);
1574 static void format_PersonName(const struct isds_PersonName
*personName
) {
1575 if (!personName
) return;
1577 oprintf(_("Person name:\n"));
1578 print_header_utf8(_("\tFirst"), personName
->pnFirstName
);
1579 print_header_utf8(_("\tMiddle"), personName
->pnMiddleName
);
1580 print_header_utf8(_("\tLast"), personName
->pnLastName
);
1581 print_header_utf8(_("\tLast at birth"),
1582 personName
->pnLastNameAtBirth
);
1586 static void format_BirthInfo(const struct isds_BirthInfo
*birth
) {
1587 if (!birth
|| !(birth
->biDate
|| birth
->biCity
|| birth
->biCounty
1588 || birth
->biState
)) return;
1590 oprintf(_("Birth details:\n"));
1592 print_header_tm(_("\tDate"), birth
->biDate
);
1593 print_header_utf8(_("\tCity"), birth
->biCity
);
1594 print_header_utf8(_("\tCounty"), birth
->biCounty
);
1595 print_header_utf8(_("\tState"), birth
->biState
);
1599 static void format_Address(const struct isds_Address
*address
) {
1600 if (!address
|| !(address
->adCity
|| address
->adState
||
1601 address
->adNumberInStreet
|| address
->adNumberInMunicipality
||
1602 address
->adZipCode
|| address
->adState
)) return;
1604 oprintf("Address:\n");
1605 print_header_utf8(_("\tCity"), address
->adCity
);
1606 print_header_utf8(_("\tStreet"), address
->adStreet
);
1607 print_header_utf8(_("\tNumber in street"), address
->adNumberInStreet
);
1608 print_header_utf8(_("\tNumber in municipality"),
1609 address
->adNumberInMunicipality
);
1610 print_header_utf8(_("\tZIP code"), address
->adZipCode
);
1611 print_header_utf8(_("\tState"), address
->adState
);
1615 /* Return static box state string or NULL if undefined */
1616 const char *DbState2string(const long int *state
) {
1617 if (!state
) return NULL
;
1620 case DBSTATE_ACCESSIBLE
: return(_("Accessible"));
1621 case DBSTATE_TEMP_UNACCESSIBLE
: return(_("Temporary inaccessible"));
1622 case DBSTATE_NOT_YET_ACCESSIBLE
: return(_("Not yet accessible"));
1623 case DBSTATE_PERM_UNACCESSIBLE
: return(_("Permanently inaccessible"));
1624 case DBSTATE_REMOVED
: return(_("Deleted"));
1625 default: return(_("<unknown state>"));
1630 void format_DbOwnerInfo(const struct isds_DbOwnerInfo
*info
) {
1633 print_header_utf8(_("Box ID"), info
->dbID
);
1634 print_header(_("Type"), DbType2string((long int *) (info
->dbType
)));
1635 print_header_utf8(_("Subject name"), info
->firmName
);
1636 print_header_utf8(_("Identity number"), info
->ic
);
1638 format_PersonName(info
->personName
);
1639 format_BirthInfo(info
->birthInfo
);
1641 format_Address(info
->address
);
1643 print_header_utf8(_("Nationality"), info
->nationality
);
1644 print_header_utf8(_("E-mail"), info
->email
);
1645 print_header_utf8(_("Phone"), info
->telNumber
);
1647 print_header_utf8(_("Identifier"), info
->identifier
);
1648 print_header_utf8(_("Registry code"), info
->registryCode
);
1650 print_header(_("State"), DbState2string(info
->dbState
));
1651 print_header_bool(_("Act as public authority"), info
->dbEffectiveOVM
);
1652 print_header_bool(_("Receive commercial messages"),
1653 info
->dbOpenAddressing
);
1657 static void format_supervising_firm(const char *ic
, const char *firmName
) {
1658 if (!ic
&& !firmName
) return;
1660 oprintf(_("Supervising subject:\n"));
1661 print_header_utf8(_("\tIdentity number"), ic
);
1662 print_header_utf8(_("\tName"), firmName
);
1666 static void format_contact_address(const char *caStreet
, const char *caCity
,
1667 const char *caZipCode
, const char *caState
) {
1668 if (!caStreet
&& !caCity
&& !caZipCode
) return;
1670 oprintf(_("Contact address:\n"));
1671 print_header_utf8(_("\tStreet"), caStreet
);
1672 print_header_utf8(_("\tCity"), caCity
);
1673 print_header_utf8(_("\tZIP code"), caZipCode
);
1674 print_header_utf8(_("\tState"), caState
);
1678 void format_DbUserInfo(const struct isds_DbUserInfo
*info
) {
1683 print_header_utf8(_("User ID"), info
->userID
);
1684 print_header(_("Type"), UserType2string((long int *) (info
->userType
)));
1686 buffer
= UserPrivils2string(info
->userPrivils
);
1687 print_header(_("Privileges"), buffer
);
1690 format_PersonName(info
->personName
);
1691 format_Address(info
->address
);
1693 print_header_tm(_("Birth date"), info
->biDate
);
1695 format_supervising_firm(info
->ic
, info
->firmName
);
1696 format_contact_address(info
->caStreet
, info
->caCity
, info
->caZipCode
,
1701 /* Print formated details about message sender */
1702 void format_sender_info(const char *dbID
, const isds_sender_type
*type
,
1703 const char *raw_type
, const char *name
) {
1704 const char *type_string
;
1706 if (!dbID
&& !type
&& !raw_type
&& !name
) return;
1708 oprintf(_("Message sender:\n"));
1709 print_header_utf8(_("\tMessage ID"), dbID
);
1711 type_string
= isds_sender_type2string(type
);
1713 print_header(_("\tType"), type_string
);
1715 print_header_utf8(_("\tRaw type"), raw_type
);
1717 print_header_utf8(_("\tName"), name
);
1721 void format_commercial_permission(
1722 const struct isds_commercial_permission
*permission
) {
1723 if (NULL
== permission
) return;
1725 print_header(_("Payment type"),
1726 isds_payment_type2string(&permission
->type
));
1727 print_header_utf8(_("Allowed recipient box ID"), permission
->recipient
);
1728 print_header_utf8(_("Payed by owner of box ID"), permission
->payer
);
1729 print_header_timeval(_("Permission expires"), permission
->expiration
);
1730 print_header_ulongint(_("Remaining messages"), permission
->count
);
1731 print_header_utf8(_("Reference to request"), permission
->reply_identifier
);