l10n: Update translation catalogues
[libisds.git] / client / common.c
blob8abb4e736900fa60c78197084fd882f0d85cfe07
1 #define _XOPEN_SOURCE 700
2 #include <stdlib.h>
3 #include <stdio.h>
4 /*#include <locale.h>*/
5 #include <time.h>
6 #include <string.h>
7 #include <stdint.h>
8 #include <errno.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <sys/mman.h>
14 #include <isds.h>
16 char credentials_file[] = "../test_credentials";
18 static int read_config(char **line, int order) {
19 FILE *file;
20 size_t length = 0;
21 char *eol;
23 if (!line) return -1;
24 free(*line);
25 *line = NULL;
27 file = fopen(credentials_file, "r");
28 if (!file) {
29 fprintf(stderr, "Could open %s\n", credentials_file);
30 return -1;
33 for (int i = 0; i < order; i++) {
34 if (-1 == getline(line, &length, file)) {
35 fprintf(stderr, "Could not read line #%d from %s: ",
36 i + 1, credentials_file);
37 if (ferror(file))
38 fprintf(stderr, "error occured\n");
39 else if (feof(file))
40 fprintf(stderr, "end of file reached\n");
41 else
42 fprintf(stderr, "I don't know why\n");
43 fclose(file);
44 free(*line);
45 *line = NULL;
46 return -1;
50 fclose(file);
52 eol = strpbrk(*line, "\r\n");
53 if (eol) *eol = '\0';
55 return 0;
58 const char *username(void) {
59 static char *username;
61 if (!username) {
62 username = getenv("ISDS_USERNAME");
63 if (!username)
64 read_config(&username, 1);
66 return username;
69 const char *password(void) {
70 static char *password;
72 if (!password) {
73 password = getenv("ISDS_PASSWORD");
74 if (!password)
75 read_config(&password, 2);
77 return password;
80 void print_DbState(const long int state) {
81 switch(state) {
82 case DBSTATE_ACCESSIBLE: printf("ACCESSIBLE\n"); break;
83 case DBSTATE_TEMP_UNACCESSIBLE: printf("TEMP_UNACCESSIBLE\n"); break;
84 case DBSTATE_NOT_YET_ACCESSIBLE: printf("NOT_YET_ACCESSIBLE\n"); break;
85 case DBSTATE_PERM_UNACCESSIBLE: printf("PERM_UNACCESSIBLE\n"); break;
86 case DBSTATE_REMOVED: printf("REMOVED\n"); break;
87 case DBSTATE_TEMP_UNACCESSIBLE_LAW: printf("DBSTATE_TEMP_UNACCESSIBLE_LAW"); break;
88 default: printf("<unknown state %ld>\n", state);
92 void print_DbType(const long int *type) {
93 if (!type) printf("NULL\n");
94 else
95 switch(*type) {
96 case DBTYPE_SYSTEM: printf("SYSTEM\n"); break;
97 case DBTYPE_FO: printf("FO\n"); break;
98 case DBTYPE_PFO: printf("PFO\n"); break;
99 case DBTYPE_PFO_ADVOK: printf("PFO_ADVOK\n"); break;
100 case DBTYPE_PFO_DANPOR: printf("PFO_DAPOR\n"); break;
101 case DBTYPE_PFO_INSSPR: printf("PFO_INSSPR\n"); break;
102 case DBTYPE_PFO_AUDITOR: printf("PFO_AUDITOR\n"); break;
103 case DBTYPE_PO: printf("PO\n"); break;
104 case DBTYPE_PO_ZAK: printf("PO_ZAK\n"); break;
105 case DBTYPE_PO_REQ: printf("PO_REQ\n"); break;
106 case DBTYPE_OVM: printf("OVM\n"); break;
107 case DBTYPE_OVM_NOTAR: printf("OVM_NOTAR\n"); break;
108 case DBTYPE_OVM_EXEKUT: printf("OVM_EXEKUT\n"); break;
109 case DBTYPE_OVM_REQ: printf("OVM_REQ\n"); break;
110 case DBTYPE_OVM_FO: printf("OVM_FO\n"); break;
111 case DBTYPE_OVM_PFO: printf("OVM_PFO\n"); break;
112 case DBTYPE_OVM_PO: printf("OVM_PO\n"); break;
113 default: printf("<unknown type %ld>\n", *type);
118 void print_UserType(const long int *type) {
119 if (!type) printf("NULL\n");
120 else
121 switch(*type) {
122 case USERTYPE_PRIMARY: printf("PRIMARY\n"); break;
123 case USERTYPE_ENTRUSTED: printf("ENTRUSTED\n"); break;
124 case USERTYPE_ADMINISTRATOR: printf("ADMINISTRATOR\n"); break;
125 case USERTYPE_OFFICIAL: printf("OFFICIAL\n"); break;
126 case USERTYPE_OFFICIAL_CERT: printf("OFFICIAL_CERT\n"); break;
127 case USERTYPE_LIQUIDATOR: printf("LIQUIDATOR\n"); break;
128 case USERTYPE_RECEIVER: printf("RECEIVER\n"); break;
129 case USERTYPE_GUARDIAN: printf("GUARDIAN\n"); break;
130 default: printf("<unknown type %ld>\n", *type);
135 void print_sender_type(const isds_sender_type *type) {
136 if (!type) printf("NULL\n");
137 else
138 switch(*type) {
139 case SENDERTYPE_PRIMARY: printf("PRIMARY\n"); break;
140 case SENDERTYPE_ENTRUSTED: printf("ENTRUSTED\n"); break;
141 case SENDERTYPE_ADMINISTRATOR: printf("ADMINISTRATOR\n"); break;
142 case SENDERTYPE_OFFICIAL: printf("OFFICIAL\n"); break;
143 case SENDERTYPE_VIRTUAL: printf("VIRTUAL\n"); break;
144 case SENDERTYPE_OFFICIAL_CERT: printf("OFFICIAL_CERT\n"); break;
145 case SENDERTYPE_LIQUIDATOR: printf("LIQUIDATOR\n"); break;
146 case SENDERTYPE_RECEIVER: printf("RECEIVER\n"); break;
147 case SENDERTYPE_GUARDIAN: printf("GUARDIAN\n"); break;
148 default: printf("<unknown type %u>\n", *type);
153 void print_UserPrivils(const long int *privils) {
155 const char *priviledges[] = {
156 "READ_NON_PERSONAL",
157 "READ_ALL",
158 "CREATE_DM",
159 "VIEW_INFO",
160 "SEARCH_DB",
161 "OWNER_ADM",
162 "READ_VAULT",
163 "ERASE_VAULT"
165 const int priviledges_count = sizeof(priviledges)/sizeof(priviledges[0]);
167 if (!privils) printf("NULL\n");
168 else {
169 printf("%ld (", *privils);
171 for (int i = 0; i < priviledges_count; i++) {
172 if (*privils & (1<<i)) {
173 printf(
174 ((i + 1) == priviledges_count) ? "%s" : "%s|",
175 priviledges[i]);
179 printf(")\n");
184 void print_hash(const struct isds_hash *hash) {
185 if (!hash) {
186 printf("NULL\n");
187 return;
190 switch(hash->algorithm) {
191 case HASH_ALGORITHM_MD5: printf("MD5 "); break;
192 case HASH_ALGORITHM_SHA_1: printf("SHA-1 "); break;
193 case HASH_ALGORITHM_SHA_256: printf("SHA-256 "); break;
194 case HASH_ALGORITHM_SHA_512: printf("SHA-512 "); break;
195 default: printf("<Unknown hash algorithm %d> ", hash->algorithm);
196 break;
199 if (!hash->value) printf("<NULL>");
200 else
201 for (size_t i = 0; i < hash->length; i++) {
202 if (i > 0) printf(":");
203 printf("%02x", ((uint8_t *)(hash->value))[i]);
206 printf("\n");
210 void print_raw_type(const isds_raw_type type) {
211 switch(type) {
212 case RAWTYPE_INCOMING_MESSAGE:
213 printf("INCOMING_MESSAGE\n"); break;
214 case RAWTYPE_PLAIN_SIGNED_INCOMING_MESSAGE:
215 printf("PLAIN_SIGNED_INCOMING_MESSAGE\n"); break;
216 case RAWTYPE_CMS_SIGNED_INCOMING_MESSAGE:
217 printf("CMS_SIGNED_INCOMING_MESSAGE\n"); break;
218 case RAWTYPE_PLAIN_SIGNED_OUTGOING_MESSAGE:
219 printf("PLAIN_SIGNED_OUTGOING_MESSAGE\n"); break;
220 case RAWTYPE_CMS_SIGNED_OUTGOING_MESSAGE:
221 printf("CMS_SIGNED_OUTGOING_MESSAGE\n"); break;
222 case RAWTYPE_DELIVERYINFO:
223 printf("DELIVERYINFO\n"); break;
224 case RAWTYPE_PLAIN_SIGNED_DELIVERYINFO:
225 printf("PLAIN_SIGNED_DELIVERYINFO\n"); break;
226 case RAWTYPE_CMS_SIGNED_DELIVERYINFO:
227 printf("CMS_SIGNED_DELIVERYINFO\n"); break;
228 default:
229 printf("<Unknown raw type %d> ", type);
230 break;
234 static void print_dmMessageStatus(const isds_message_status *status) {
235 if (!status) printf("NULL\n");
236 else
237 switch(*status) {
238 case MESSAGESTATE_SENT: printf("SENT\n"); break;
239 case MESSAGESTATE_STAMPED: printf("STAMPED\n"); break;
240 case MESSAGESTATE_INFECTED: printf("INFECTED\n"); break;
241 case MESSAGESTATE_DELIVERED: printf("DELIVERED\n"); break;
242 case MESSAGESTATE_SUBSTITUTED: printf("SUBSTITUTED\n"); break;
243 case MESSAGESTATE_RECEIVED: printf("RECEIVED\n"); break;
244 case MESSAGESTATE_READ: printf("READ\n"); break;
245 case MESSAGESTATE_UNDELIVERABLE: printf("UNDELIVERABLE\n"); break;
246 case MESSAGESTATE_REMOVED: printf("REMOVED\n"); break;
247 case MESSAGESTATE_IN_SAFE: printf("IN_SAFE\n"); break;
248 default: printf("<unknown type %d>\n", *status);
252 void print_bool(const _Bool *boolean) {
253 printf("%s\n", (!boolean) ? "NULL" : ((*boolean)? "true" : "false") );
257 void print_longint(const long int *number) {
258 if (!number) printf("NULL\n");
259 else printf("%ld\n", *number);
263 void print_PersonName(const struct isds_PersonName *personName) {
264 printf("\tpersonName = ");
265 if (!personName) printf("NULL\n");
266 else {
267 printf("{\n");
268 printf("\t\tpnFirstName = %s\n", personName->pnFirstName);
269 printf("\t\tpnMiddleName = %s\n", personName->pnMiddleName);
270 printf("\t\tpnLastName = %s\n", personName->pnLastName);
271 printf("\t\tpnLastNameAtBirth = %s\n", personName->pnLastNameAtBirth);
272 printf("\t}\n");
277 void print_Address(const struct isds_Address *address) {
278 printf("\taddress = ");
279 if (!address) printf("NULL\n");
280 else {
281 printf("{\n");
282 printf("\t\tadCity = %s\n", address->adCity);
283 printf("\t\tadStreet = %s\n", address->adStreet);
284 printf("\t\tadNumberInStreet = %s\n", address->adNumberInStreet);
285 printf("\t\tadNumberInMunicipality = %s\n",
286 address->adNumberInMunicipality);
287 printf("\t\tadZipCode = %s\n", address->adZipCode);
288 printf("\t\tadState = %s\n", address->adState);
289 printf("\t}\n");
294 void print_date(const struct tm *date) {
295 if (!date) printf("NULL\n");
296 else printf("%s", asctime(date));
300 void print_DbOwnerInfo(const struct isds_DbOwnerInfo *info) {
301 printf("dbOwnerInfo = ");
303 if (!info) {
304 printf("NULL\n");
305 return;
308 printf("{\n");
309 printf("\tdbID = %s\n", info->dbID);
311 printf("\tdbType = ");
312 print_DbType((long int *) (info->dbType));
313 printf("\tic = %s\n", info->ic);
315 print_PersonName(info->personName);
317 printf("\tfirmName = %s\n", info->firmName);
319 printf("\tbirthInfo = ");
320 if (!info->birthInfo) printf("NULL\n");
321 else {
322 printf("{\n");
324 printf("\t\tbiDate = ");
325 print_date(info->birthInfo->biDate);
327 printf("\t\tbiCity = %s\n", info->birthInfo->biCity);
328 printf("\t\tbiCounty = %s\n", info->birthInfo->biCounty);
329 printf("\t\tbiState = %s\n", info->birthInfo->biState);
330 printf("\t}\n");
333 print_Address(info->address);
335 printf("\tnationality = %s\n", info->nationality);
336 printf("\temail = %s\n", info->email);
337 printf("\ttelNumber = %s\n", info->telNumber);
338 printf("\tidentifier = %s\n", info->identifier);
339 printf("\tregistryCode = %s\n", info->registryCode);
341 printf("\tdbState = ");
342 if (!info->dbState) printf("NULL\n");
343 else print_DbState(*(info->dbState));
345 printf("\tdbEffectiveOVM = ");
346 print_bool(info->dbEffectiveOVM);
348 printf("\tdbOpenAddressing = ");
349 print_bool(info->dbOpenAddressing);
351 printf("}\n");
356 void print_DbUserInfo(const struct isds_DbUserInfo *info) {
357 printf("dbUserInfo = ");
359 if (!info) {
360 printf("NULL\n");
361 return;
364 printf("{\n");
365 printf("\tuserID = %s\n", info->userID);
367 printf("\tuserType = ");
368 print_UserType((long int *) (info->userType));
370 printf("\tuserPrivils = ");
371 print_UserPrivils(info->userPrivils);
373 print_PersonName(info->personName);
374 print_Address(info->address);
376 printf("\tbiDate = ");
377 print_date(info->biDate);
379 printf("\tic = %s\n", info->ic);
380 printf("\tfirmName = %s\n", info->firmName);
382 printf("\tcaStreet = %s\n", info->caStreet);
383 printf("\tcaCity = %s\n", info->caCity);
384 printf("\tcaZipCode = %s\n", info->caZipCode);
385 printf("\tcaState = %s\n", info->caState);
387 printf("}\n");
391 void print_timeval(const struct timeval *time) {
392 struct tm broken;
393 char buffer[128];
395 if (!time) {
396 printf("NULL\n");
397 return;
400 if (!localtime_r(&(time->tv_sec), &broken)) goto error;
401 if (!strftime(buffer, sizeof(buffer)/sizeof(char), "%c", &broken))
402 goto error;
403 printf("%s, %jd us\n", buffer, (intmax_t)time->tv_usec);
404 return;
406 error:
407 printf("<Error while formating>\n>");
408 return;
412 void print_event_type(const isds_event_type *type) {
413 if (!type) {
414 printf("NULL");
415 return;
417 switch (*type) {
418 case EVENT_UKNOWN: printf("UNKNOWN\n"); break;
419 case EVENT_ENTERED_SYSTEM: printf("ENTERED_SYSTEM\n"); break;
420 case EVENT_ACCEPTED_BY_RECIPIENT:
421 printf("ACCEPTED_BY_RECIPIENT\n"); break;
422 case EVENT_ACCEPTED_BY_FICTION:
423 printf("DELIVERED_BY_FICTION\n"); break;
424 case EVENT_UNDELIVERABLE:
425 printf("UNDELIVERABLE\n"); break;
426 case EVENT_COMMERCIAL_ACCEPTED:
427 printf("COMMERCIAL_ACCEPTED\n"); break;
428 case EVENT_DELIVERED:
429 printf("DELIVERED\n"); break;
430 case EVENT_PRIMARY_LOGIN:
431 printf("PRIMARY_LOGIN\n"); break;
432 case EVENT_ENTRUSTED_LOGIN:
433 printf("ENTRUSTED_LOGIN\n"); break;
434 case EVENT_SYSCERT_LOGIN:
435 printf("SYSCERT_LOGIN\n"); break;
436 default: printf("<unknown type %d>\n", *type);
441 void print_events(const struct isds_list *events) {
442 const struct isds_list *item;
443 const struct isds_event *event;
445 if (!events) {
446 printf("NULL\n");
447 return;
450 printf("{\n");
452 for (item = events; item; item = item->next) {
453 event = (struct isds_event *) item->data;
454 printf("\t\t\tevent = ");
455 if (!event) printf("NULL");
456 else {
457 printf("{\n");
459 printf("\t\t\t\ttype = ");
460 print_event_type(event->type);
462 printf("\t\t\t\tdescription = %s\n", event->description);
464 printf("\t\t\t\ttime = ");
465 print_timeval(event->time);
467 printf("\t\t\t}\n");
471 printf("\t\t}\n");
475 void print_envelope(const struct isds_envelope *envelope) {
476 printf("\tenvelope = ");
478 if (!envelope) {
479 printf("NULL\n");
480 return;
482 printf("{\n");
484 printf("\t\tdmID = %s\n", envelope->dmID);
485 printf("\t\tdbIDSender = %s\n", envelope->dbIDSender);
486 printf("\t\tdmSender = %s\n", envelope->dmSender);
487 printf("\t\tdmSenderAddress = %s\n", envelope->dmSenderAddress);
488 printf("\t\tdmSenderType = ");
489 print_DbType(envelope->dmSenderType);
490 printf("\t\tdmRecipient = %s\n", envelope->dmRecipient);
491 printf("\t\tdmRecipientAddress = %s\n", envelope->dmRecipientAddress);
492 printf("\t\tdmAmbiguousRecipient = ");
493 print_bool(envelope->dmAmbiguousRecipient);
494 printf("\t\tdmType = %s\n", envelope->dmType);
496 printf("\t\tdmSenderOrgUnit = %s\n", envelope->dmSenderOrgUnit);
497 printf("\t\tdmSenderOrgUnitNum = ");
498 print_longint(envelope->dmSenderOrgUnitNum);
499 printf("\t\tdbIDRecipient = %s\n", envelope->dbIDRecipient);
500 printf("\t\tdmRecipientOrgUnit = %s\n", envelope->dmRecipientOrgUnit);
501 printf("\t\tdmRecipientOrgUnitNum = ");
502 print_longint(envelope->dmRecipientOrgUnitNum);
503 printf("\t\tdmToHands = %s\n", envelope->dmToHands);
504 printf("\t\tdmAnnotation = %s\n", envelope->dmAnnotation);
505 printf("\t\tdmRecipientRefNumber = %s\n", envelope->dmRecipientRefNumber);
506 printf("\t\tdmSenderRefNumber = %s\n", envelope->dmSenderRefNumber);
507 printf("\t\tdmRecipientIdent = %s\n", envelope->dmRecipientIdent);
508 printf("\t\tdmSenderIdent = %s\n", envelope->dmSenderIdent);
510 printf("\t\tdmLegalTitleLaw = ");
511 print_longint(envelope->dmLegalTitleLaw);
512 printf("\t\tdmLegalTitleYear = ");
513 print_longint(envelope->dmLegalTitleYear);
514 printf("\t\tdmLegalTitleSect = %s\n", envelope->dmLegalTitleSect);
515 printf("\t\tdmLegalTitlePar = %s\n", envelope->dmLegalTitlePar);
516 printf("\t\tdmLegalTitlePoint = %s\n", envelope->dmLegalTitlePoint);
518 printf("\t\tdmPersonalDelivery = ");
519 print_bool(envelope->dmPersonalDelivery);
520 printf("\t\tdmAllowSubstDelivery = ");
521 print_bool(envelope->dmAllowSubstDelivery);
522 printf("\t\tdmOVM = ");
523 print_bool(envelope->dmOVM);
524 printf("\t\tdmPublishOwnID = ");
525 print_bool(envelope->dmPublishOwnID);
527 printf("\t\tdmOrdinal = ");
528 if (!envelope->dmOrdinal) printf("NULL\n");
529 else printf("%lu\n", *(envelope->dmOrdinal));
531 printf("\t\tdmMessageStatus = ");
532 print_dmMessageStatus(envelope->dmMessageStatus);
534 printf("\t\tdmAttachmentSize = ");
535 if (!envelope->dmAttachmentSize) printf("NULL\n");
536 else printf("%lu kB\n", *(envelope->dmAttachmentSize));
538 printf("\t\tdmDeliveryTime = ");
539 print_timeval(envelope->dmDeliveryTime);
541 printf("\t\tdmAcceptanceTime = ");
542 print_timeval(envelope->dmAcceptanceTime);
544 printf("\t\thash = ");
545 print_hash(envelope->hash);
547 printf("\t\ttimestamp = %p\n", envelope->timestamp);
548 printf("\t\ttimestamp_length = %zu\n", envelope->timestamp_length);
550 printf("\t\tevents = ");
551 print_events(envelope->events);
553 printf("\t}\n");
557 void print_document(const struct isds_document *document) {
558 printf("\t\tdocument = ");
560 if (!document) {
561 printf("NULL\n");
562 return;
564 printf("\{\n");
566 printf("\t\t\tis_xml = %u\n", !!document->is_xml);
567 printf("\t\t\txml_node_list = %p\n", document->xml_node_list);
569 printf("\t\t\tdata = %p\n", document->data);
570 printf("\t\t\tdata_length = %zu\n", document->data_length);
571 printf("\t\t\tdmMimeType = %s\n", document->dmMimeType);
573 printf("\t\t\tdmFileMetaType = ");
574 switch(document->dmFileMetaType) {
575 case FILEMETATYPE_MAIN: printf("MAIN\n"); break;
576 case FILEMETATYPE_ENCLOSURE: printf("ENCLOSURE\n"); break;
577 case FILEMETATYPE_SIGNATURE: printf("SIGNATURE\n"); break;
578 case FILEMETATYPE_META: printf("META\n"); break;
579 default: printf("<unknown type %d>\n", document->dmFileMetaType);
582 printf("\t\t\tdmFileGuid = %s\n", document->dmFileGuid);
583 printf("\t\t\tdmUpFileGuid = %s\n", document->dmUpFileGuid);
584 printf("\t\t\tdmFileDescr = %s\n", document->dmFileDescr);
585 printf("\t\t\tdmFormat = %s\n", document->dmFormat);
586 printf("\t\t}\n");
590 void print_documents(const struct isds_list *documents) {
591 const struct isds_list *item;
593 printf("\tdocuments = ");
595 if (!documents) {
596 printf("NULL\n");
597 return;
599 printf("{\n");
601 for (item = documents; item; item = item->next) {
602 print_document((struct isds_document *) (item->data));
605 printf("\t}\n");
609 void print_message(const struct isds_message *message) {
610 printf("message = ");
612 if (!message) {
613 printf("NULL\n");
614 return;
617 printf("{\n");
619 printf("\traw = %p\n", message->raw);
620 printf("\traw_length = %zu\n", message->raw_length);
621 printf("\traw_type = ");
622 print_raw_type(message->raw_type);
623 printf("\txml = %p\n", message->xml);
624 print_envelope(message->envelope);
625 print_documents(message->documents);
627 printf("}\n");
630 void print_copies(const struct isds_list *copies) {
631 const struct isds_list *item;
632 struct isds_message_copy *copy;
634 printf("Copies = ");
635 if (!copies) {
636 printf("<NULL>\n");
637 return;
640 printf("{\n");
641 for (item = copies; item; item = item->next) {
642 copy = (struct isds_message_copy *) item->data;
643 printf("\tCopy = ");
645 if (!copy)
646 printf("<NULL>\n");
647 else {
648 printf("{\n");
649 printf("\t\tdbIDRecipient = %s\n", copy->dbIDRecipient);
650 printf("\t\tdmRecipientOrgUnit = %s\n", copy->dmRecipientOrgUnit);
652 printf("\t\tdmRecipientOrgUnitNum = ");
653 if (copy->dmRecipientOrgUnitNum)
654 printf("%ld\n", *copy->dmRecipientOrgUnitNum);
655 else
656 printf("<NULL>\n");
657 printf("\t\tdmToHands = %s\n", copy->dmToHands);
659 printf("\t\terror = %s\n", isds_strerror(copy->error));
660 printf("\t\tdmStatus = %s\n", copy->dmStatus);
661 printf("\t\tdmID = %s\n", copy->dmID);
662 printf("\t}\n");
665 printf("}\n");
668 void print_message_status_change(
669 const struct isds_message_status_change *changed_status) {
670 printf("message_status_change = ");
672 if (!changed_status) {
673 printf("NULL\n");
674 return;
677 printf("{\n");
679 printf("\tdmID = %s\n", changed_status->dmID);
681 printf("\tdmMessageStatus = ");
682 print_dmMessageStatus(changed_status->dmMessageStatus);
684 printf("\ttime = ");
685 print_timeval(changed_status->time);
687 printf("}\n");
690 void compare_hashes(const struct isds_hash *hash1,
691 const struct isds_hash *hash2) {
692 isds_error err;
694 printf("Comparing hashes... ");
695 err = isds_hash_cmp(hash1, hash2);
696 if (err == IE_SUCCESS)
697 printf("Hashes equal\n");
698 else if
699 (err == IE_NOTEQUAL) printf("Hashes differ\n");
700 else
701 printf("isds_hash_cmp() failed: %s\n", isds_strerror(err));
705 int progressbar(double upload_total, double upload_current,
706 double download_total, double download_current,
707 void *data) {
709 printf("Progress: upload %0f/%0f, download %0f/%0f, data=%p\n",
710 upload_current, upload_total, download_current, download_total,
711 data);
712 if (data) {
713 printf("Aborting transfer...\n");
714 return 1;
716 return 0;
720 int mmap_file(const char *file, int *fd, void **buffer, size_t *length) {
721 struct stat file_info;
723 if (!file || !fd || !buffer || !length) return -1;
726 *fd = open(file, O_RDONLY);
727 if (*fd == -1) {
728 fprintf(stderr, "%s: Could not open file: %s\n", file, strerror(errno));
729 return -1;
732 if (-1 == fstat(*fd, &file_info)) {
733 fprintf(stderr, "%s: Could not get file size: %s\n", file,
734 strerror(errno));
735 close(*fd);
736 return -1;
738 if (file_info.st_size < 0) {
739 fprintf(stderr, "File `%s' has negative size: %jd\n", file,
740 (intmax_t) file_info.st_size);
741 close(*fd);
742 return -1;
744 *length = file_info.st_size;
746 if (!*length) {
747 /* Empty region cannot be mmapped */
748 *buffer = NULL;
749 } else {
750 *buffer = mmap(NULL, *length, PROT_READ, MAP_PRIVATE, *fd, 0);
751 if (*buffer == MAP_FAILED) {
752 fprintf(stderr, "%s: Could not map file to memory: %s\n", file,
753 strerror(errno));
754 close(*fd);
755 return -1;
759 return 0;
763 int munmap_file(int fd, void *buffer, size_t length) {
764 int err = 0;
765 long int page_size = sysconf(_SC_PAGE_SIZE);
766 size_t pages = (length % page_size) ?
767 ((length / page_size) + 1) * page_size:
768 length;
770 if (length) {
771 err = munmap(buffer, pages);
772 if (err) {
773 fprintf(stderr,
774 "Could not unmap memory at %p and length %zu: %s\n",
775 buffer, pages, strerror(errno));
779 err = close(fd);
780 if (err) {
781 fprintf(stderr, "Could close file descriptor %d: %s\n", fd,
782 strerror(errno));
785 return err;
789 static int save_data_to_file(const char *file, const void *data,
790 const size_t length) {
791 int fd;
792 ssize_t written, left = length;
794 if (!file) return -1;
795 if (length > 0 && !data) return -1;
797 fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0666);
798 if (fd == -1) {
799 fprintf(stderr, "%s: Could not open file for writing: %s\n",
800 file, strerror(errno));
801 return -1;
804 printf("Writing %zu bytes to file `%s'...\n", length, file);
805 while (left) {
806 written = write(fd, data + length - left, left);
807 if (written == -1) {
808 fprintf(stderr, "%s: Could not save file: %s\n",
809 file, strerror(errno));
810 close(fd);
811 return -1;
813 left-=written;
816 if (-1 == close(fd)) {
817 fprintf(stderr, "%s: Closing file failed: %s\n",
818 file, strerror(errno));
819 return -1;
822 printf("Done.\n");
823 return 0;
827 int save_data(const char *message, const void *data, const size_t length) {
828 if (message)
829 printf("%s\n", message);
830 return save_data_to_file("output", data, length);