Added PFO_AUDITOR box type.
[libisds.git] / client / common.c
blob36badbe2b53d3363f72fbde64967121f2f156171
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 <inttypes.h>
9 #include <errno.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <sys/mman.h>
15 #include <isds.h>
17 char credentials_file[] = "../test_credentials";
19 static int read_config(char **line, int order) {
20 FILE *file;
21 size_t length = 0;
22 char *eol;
24 if (!line) return -1;
25 free(*line);
26 *line = NULL;
28 file = fopen(credentials_file, "r");
29 if (!file) {
30 fprintf(stderr, "Could open %s\n", credentials_file);
31 return -1;
34 for (int i = 0; i < order; i++) {
35 if (-1 == getline(line, &length, file)) {
36 fprintf(stderr, "Could not read line #%d from %s: ",
37 i + 1, credentials_file);
38 if (ferror(file))
39 fprintf(stderr, "error occured\n");
40 else if (feof(file))
41 fprintf(stderr, "end of file reached\n");
42 else
43 fprintf(stderr, "I don't know why\n");
44 fclose(file);
45 free(*line);
46 *line = NULL;
47 return -1;
51 fclose(file);
53 eol = strpbrk(*line, "\r\n");
54 if (eol) *eol = '\0';
56 return 0;
59 const char *username(void) {
60 static char *username;
62 if (!username) {
63 username = getenv("ISDS_USERNAME");
64 if (!username)
65 read_config(&username, 1);
67 return username;
70 const char *password(void) {
71 static char *password;
73 if (!password) {
74 password = getenv("ISDS_PASSWORD");
75 if (!password)
76 read_config(&password, 2);
78 return password;
81 void print_DbState(const long int state) {
82 switch(state) {
83 case DBSTATE_ACCESSIBLE: printf("ACCESSIBLE\n"); break;
84 case DBSTATE_TEMP_UNACCESSIBLE: printf("TEMP_UNACCESSIBLE\n"); break;
85 case DBSTATE_NOT_YET_ACCESSIBLE: printf("NOT_YET_ACCESSIBLE\n"); break;
86 case DBSTATE_PERM_UNACCESSIBLE: printf("PERM_UNACCESSIBLE\n"); break;
87 case DBSTATE_REMOVED: printf("REMOVED\n"); break;
88 case DBSTATE_TEMP_UNACCESSIBLE_LAW: printf("DBSTATE_TEMP_UNACCESSIBLE_LAW"); break;
89 default: printf("<unknown state %ld>\n", state);
93 void print_DbType(const long int *type) {
94 if (!type) printf("NULL\n");
95 else
96 switch(*type) {
97 case DBTYPE_SYSTEM: printf("SYSTEM\n"); break;
98 case DBTYPE_FO: printf("FO\n"); break;
99 case DBTYPE_PFO: printf("PFO\n"); break;
100 case DBTYPE_PFO_ADVOK: printf("PFO_ADVOK\n"); break;
101 case DBTYPE_PFO_DANPOR: printf("PFO_DAPOR\n"); break;
102 case DBTYPE_PFO_INSSPR: printf("PFO_INSSPR\n"); break;
103 case DBTYPE_PFO_AUDITOR: printf("PFO_AUDITOR\n"); break;
104 case DBTYPE_PO: printf("PO\n"); break;
105 case DBTYPE_PO_ZAK: printf("PO_ZAK\n"); break;
106 case DBTYPE_PO_REQ: printf("PO_REQ\n"); break;
107 case DBTYPE_OVM: printf("OVM\n"); break;
108 case DBTYPE_OVM_NOTAR: printf("OVM_NOTAR\n"); break;
109 case DBTYPE_OVM_EXEKUT: printf("OVM_EXEKUT\n"); break;
110 case DBTYPE_OVM_REQ: printf("OVM_REQ\n"); break;
111 default: printf("<unknown type %ld>\n", *type);
116 void print_UserType(const long int *type) {
117 if (!type) printf("NULL\n");
118 else
119 switch(*type) {
120 case USERTYPE_PRIMARY: printf("PRIMARY\n"); break;
121 case USERTYPE_ENTRUSTED: printf("ENTRUSTED\n"); break;
122 case USERTYPE_ADMINISTRATOR: printf("ADMINISTRATOR\n"); break;
123 case USERTYPE_OFFICIAL: printf("OFFICIAL\n"); break;
124 default: printf("<unknown type %ld>\n", *type);
129 void print_sender_type(const isds_sender_type *type) {
130 if (!type) printf("NULL\n");
131 else
132 switch(*type) {
133 case SENDERTYPE_PRIMARY: printf("PRIMARY\n"); break;
134 case SENDERTYPE_ENTRUSTED: printf("ENTRUSTED\n"); break;
135 case SENDERTYPE_ADMINISTRATOR: printf("ADMINISTRATOR\n"); break;
136 case SENDERTYPE_OFFICIAL: printf("OFFICIAL\n"); break;
137 case SENDERTYPE_VIRTUAL: printf("VIRTUAL\n"); break;
138 default: printf("<unknown type %u>\n", *type);
143 void print_UserPrivils(const long int *privils) {
145 const char *priviledges[] = {
146 "READ_NON_PERSONAL",
147 "READ_ALL",
148 "CREATE_DM",
149 "VIEW_INFO",
150 "SEARCH_DB",
151 "OWNER_ADM",
152 "READ_VAULT",
153 "ERASE_VAULT"
155 const int priviledges_count = sizeof(priviledges)/sizeof(priviledges[0]);
157 if (!privils) printf("NULL\n");
158 else {
159 printf("%ld (", *privils);
161 for (int i = 0; i < priviledges_count; i++) {
162 if (*privils & (1<<i)) {
163 printf(
164 ((i + 1) == priviledges_count) ? "%s" : "%s|",
165 priviledges[i]);
169 printf(")\n");
174 void print_hash(const struct isds_hash *hash) {
175 if (!hash) {
176 printf("NULL\n");
177 return;
180 switch(hash->algorithm) {
181 case HASH_ALGORITHM_MD5: printf("MD5 "); break;
182 case HASH_ALGORITHM_SHA_1: printf("SHA-1 "); break;
183 case HASH_ALGORITHM_SHA_256: printf("SHA-256 "); break;
184 case HASH_ALGORITHM_SHA_512: printf("SHA-512 "); break;
185 default: printf("<Unknown hash algorithm %d> ", hash->algorithm);
186 break;
189 if (!hash->value) printf("<NULL>");
190 else
191 for (size_t i = 0; i < hash->length; i++) {
192 if (i > 0) printf(":");
193 printf("%02x", ((uint8_t *)(hash->value))[i]);
196 printf("\n");
200 void print_raw_type(const isds_raw_type type) {
201 switch(type) {
202 case RAWTYPE_INCOMING_MESSAGE:
203 printf("INCOMING_MESSAGE\n"); break;
204 case RAWTYPE_PLAIN_SIGNED_INCOMING_MESSAGE:
205 printf("PLAIN_SIGNED_INCOMING_MESSAGE\n"); break;
206 case RAWTYPE_CMS_SIGNED_INCOMING_MESSAGE:
207 printf("CMS_SIGNED_INCOMING_MESSAGE\n"); break;
208 case RAWTYPE_PLAIN_SIGNED_OUTGOING_MESSAGE:
209 printf("PLAIN_SIGNED_OUTGOING_MESSAGE\n"); break;
210 case RAWTYPE_CMS_SIGNED_OUTGOING_MESSAGE:
211 printf("CMS_SIGNED_OUTGOING_MESSAGE\n"); break;
212 case RAWTYPE_DELIVERYINFO:
213 printf("DELIVERYINFO\n"); break;
214 case RAWTYPE_PLAIN_SIGNED_DELIVERYINFO:
215 printf("PLAIN_SIGNED_DELIVERYINFO\n"); break;
216 case RAWTYPE_CMS_SIGNED_DELIVERYINFO:
217 printf("CMS_SIGNED_DELIVERYINFO\n"); break;
218 default:
219 printf("<Unknown raw type %d> ", type);
220 break;
224 static void print_dmMessageStatus(const isds_message_status *status) {
225 if (!status) printf("NULL\n");
226 else
227 switch(*status) {
228 case MESSAGESTATE_SENT: printf("SENT\n"); break;
229 case MESSAGESTATE_STAMPED: printf("STAMPED\n"); break;
230 case MESSAGESTATE_INFECTED: printf("INFECTED\n"); break;
231 case MESSAGESTATE_DELIVERED: printf("DELIVERED\n"); break;
232 case MESSAGESTATE_SUBSTITUTED: printf("SUBSTITUTED\n"); break;
233 case MESSAGESTATE_RECEIVED: printf("RECEIVED\n"); break;
234 case MESSAGESTATE_READ: printf("READ\n"); break;
235 case MESSAGESTATE_UNDELIVERABLE: printf("UNDELIVERABLE\n"); break;
236 case MESSAGESTATE_REMOVED: printf("REMOVED\n"); break;
237 case MESSAGESTATE_IN_SAFE: printf("IN_SAFE\n"); break;
238 default: printf("<unknown type %d>\n", *status);
242 void print_bool(const _Bool *boolean) {
243 printf("%s\n", (!boolean) ? "NULL" : ((*boolean)? "true" : "false") );
247 void print_longint(const long int *number) {
248 if (!number) printf("NULL\n");
249 else printf("%ld\n", *number);
253 void print_PersonName(const struct isds_PersonName *personName) {
254 printf("\tpersonName = ");
255 if (!personName) printf("NULL\n");
256 else {
257 printf("{\n");
258 printf("\t\tpnFirstName = %s\n", personName->pnFirstName);
259 printf("\t\tpnMiddleName = %s\n", personName->pnMiddleName);
260 printf("\t\tpnLastName = %s\n", personName->pnLastName);
261 printf("\t\tpnLastNameAtBirth = %s\n", personName->pnLastNameAtBirth);
262 printf("\t}\n");
267 void print_Address(const struct isds_Address *address) {
268 printf("\taddress = ");
269 if (!address) printf("NULL\n");
270 else {
271 printf("{\n");
273 printf("\t\tadCode = ");
274 print_longint(address->adCode);
276 printf("\t\tadCity = %s\n", address->adCity);
277 printf("\t\tadDistrict = %s\n", address->adDistrict);
278 printf("\t\tadStreet = %s\n", address->adStreet);
279 printf("\t\tadNumberInStreet = %s\n", address->adNumberInStreet);
280 printf("\t\tadNumberInMunicipality = %s\n",
281 address->adNumberInMunicipality);
282 printf("\t\tadZipCode = %s\n", address->adZipCode);
283 printf("\t\tadState = %s\n", address->adState);
284 printf("\t}\n");
289 void print_date(const struct tm *date) {
290 if (!date) printf("NULL\n");
291 else printf("%s", asctime(date));
295 void print_DbOwnerInfo(const struct isds_DbOwnerInfo *info) {
296 printf("dbOwnerInfo = ");
298 if (!info) {
299 printf("NULL\n");
300 return;
303 printf("{\n");
304 printf("\tdbID = %s\n", info->dbID);
306 printf("\tdbType = ");
307 print_DbType((long int *) (info->dbType));
308 printf("\tic = %s\n", info->ic);
310 print_PersonName(info->personName);
312 printf("\tfirmName = %s\n", info->firmName);
314 printf("\tbirthInfo = ");
315 if (!info->birthInfo) printf("NULL\n");
316 else {
317 printf("{\n");
319 printf("\t\tbiDate = ");
320 print_date(info->birthInfo->biDate);
322 printf("\t\tbiCity = %s\n", info->birthInfo->biCity);
323 printf("\t\tbiCounty = %s\n", info->birthInfo->biCounty);
324 printf("\t\tbiState = %s\n", info->birthInfo->biState);
325 printf("\t}\n");
328 print_Address(info->address);
330 printf("\tnationality = %s\n", info->nationality);
331 printf("\temail = %s\n", info->email);
332 printf("\ttelNumber = %s\n", info->telNumber);
333 printf("\tidentifier = %s\n", info->identifier);
335 printf("\taifoIsds = ");
336 print_bool(info->aifoIsds);
338 printf("\tregistryCode = %s\n", info->registryCode);
340 printf("\tdbState = ");
341 if (!info->dbState) printf("NULL\n");
342 else print_DbState(*(info->dbState));
344 printf("\tdbEffectiveOVM = ");
345 print_bool(info->dbEffectiveOVM);
347 printf("\tdbOpenAddressing = ");
348 print_bool(info->dbOpenAddressing);
350 printf("}\n");
355 void print_DbUserInfo(const struct isds_DbUserInfo *info) {
356 printf("dbUserInfo = ");
358 if (!info) {
359 printf("NULL\n");
360 return;
363 printf("{\n");
364 printf("\tuserID = %s\n", info->userID);
366 printf("\tuserType = ");
367 print_UserType((long int *) (info->userType));
369 printf("\tuserPrivils = ");
370 print_UserPrivils(info->userPrivils);
372 print_PersonName(info->personName);
373 print_Address(info->address);
375 printf("\tbiDate = ");
376 print_date(info->biDate);
378 printf("\tic = %s\n", info->ic);
379 printf("\tfirmName = %s\n", info->firmName);
381 printf("\tcaStreet = %s\n", info->caStreet);
382 printf("\tcaCity = %s\n", info->caCity);
383 printf("\tcaZipCode = %s\n", info->caZipCode);
384 printf("\tcaState = %s\n", info->caState);
385 printf("\taifo_ticket = %s\n", info->aifo_ticket);
387 printf("}\n");
391 void print_timeval(const struct timeval *time) {
392 struct tm broken;
393 char buffer[128];
394 time_t seconds_as_time_t;
396 if (!time) {
397 printf("NULL\n");
398 return;
401 /* MinGW32 GCC 4.8+ uses 64-bit time_t but time->tv_sec is defined as
402 * 32-bit long in Microsoft API. Convert value to the type expected by
403 * gmtime_r(). */
404 seconds_as_time_t = time->tv_sec;
405 if (!localtime_r(&seconds_as_time_t, &broken)) goto error;
406 if (!strftime(buffer, sizeof(buffer)/sizeof(char), "%c", &broken))
407 goto error;
408 printf("%s, %" PRIdMAX " us\n", buffer, (intmax_t)time->tv_usec);
409 return;
411 error:
412 printf("<Error while formating>\n>");
413 return;
417 void print_event_type(const isds_event_type *type) {
418 if (!type) {
419 printf("NULL");
420 return;
422 switch (*type) {
423 case EVENT_UKNOWN: printf("UNKNOWN\n"); break;
424 case EVENT_ENTERED_SYSTEM: printf("ENTERED_SYSTEM\n"); break;
425 case EVENT_ACCEPTED_BY_RECIPIENT:
426 printf("ACCEPTED_BY_RECIPIENT\n"); break;
427 case EVENT_ACCEPTED_BY_FICTION:
428 printf("DELIVERED_BY_FICTION\n"); break;
429 case EVENT_UNDELIVERABLE:
430 printf("UNDELIVERABLE\n"); break;
431 case EVENT_COMMERCIAL_ACCEPTED:
432 printf("COMMERCIAL_ACCEPTED\n"); break;
433 case EVENT_DELIVERED:
434 printf("DELIVERED\n"); break;
435 case EVENT_PRIMARY_LOGIN:
436 printf("PRIMARY_LOGIN\n"); break;
437 case EVENT_ENTRUSTED_LOGIN:
438 printf("ENTRUSTED_LOGIN\n"); break;
439 case EVENT_SYSCERT_LOGIN:
440 printf("SYSCERT_LOGIN\n"); break;
441 default: printf("<unknown type %d>\n", *type);
446 void print_events(const struct isds_list *events) {
447 const struct isds_list *item;
448 const struct isds_event *event;
450 if (!events) {
451 printf("NULL\n");
452 return;
455 printf("{\n");
457 for (item = events; item; item = item->next) {
458 event = (struct isds_event *) item->data;
459 printf("\t\t\tevent = ");
460 if (!event) printf("NULL");
461 else {
462 printf("{\n");
464 printf("\t\t\t\ttype = ");
465 print_event_type(event->type);
467 printf("\t\t\t\tdescription = %s\n", event->description);
469 printf("\t\t\t\ttime = ");
470 print_timeval(event->time);
472 printf("\t\t\t}\n");
476 printf("\t\t}\n");
480 void print_envelope(const struct isds_envelope *envelope) {
481 printf("\tenvelope = ");
483 if (!envelope) {
484 printf("NULL\n");
485 return;
487 printf("{\n");
489 printf("\t\tdmID = %s\n", envelope->dmID);
490 printf("\t\tdbIDSender = %s\n", envelope->dbIDSender);
491 printf("\t\tdmSender = %s\n", envelope->dmSender);
492 printf("\t\tdmSenderAddress = %s\n", envelope->dmSenderAddress);
493 printf("\t\tdmSenderType = ");
494 print_DbType(envelope->dmSenderType);
495 printf("\t\tdmRecipient = %s\n", envelope->dmRecipient);
496 printf("\t\tdmRecipientAddress = %s\n", envelope->dmRecipientAddress);
497 printf("\t\tdmAmbiguousRecipient = ");
498 print_bool(envelope->dmAmbiguousRecipient);
499 printf("\t\tdmType = %s\n", envelope->dmType);
501 printf("\t\tdmSenderOrgUnit = %s\n", envelope->dmSenderOrgUnit);
502 printf("\t\tdmSenderOrgUnitNum = ");
503 print_longint(envelope->dmSenderOrgUnitNum);
504 printf("\t\tdbIDRecipient = %s\n", envelope->dbIDRecipient);
505 printf("\t\tdmRecipientOrgUnit = %s\n", envelope->dmRecipientOrgUnit);
506 printf("\t\tdmRecipientOrgUnitNum = ");
507 print_longint(envelope->dmRecipientOrgUnitNum);
508 printf("\t\tdmToHands = %s\n", envelope->dmToHands);
509 printf("\t\tdmAnnotation = %s\n", envelope->dmAnnotation);
510 printf("\t\tdmRecipientRefNumber = %s\n", envelope->dmRecipientRefNumber);
511 printf("\t\tdmSenderRefNumber = %s\n", envelope->dmSenderRefNumber);
512 printf("\t\tdmRecipientIdent = %s\n", envelope->dmRecipientIdent);
513 printf("\t\tdmSenderIdent = %s\n", envelope->dmSenderIdent);
515 printf("\t\tdmLegalTitleLaw = ");
516 print_longint(envelope->dmLegalTitleLaw);
517 printf("\t\tdmLegalTitleYear = ");
518 print_longint(envelope->dmLegalTitleYear);
519 printf("\t\tdmLegalTitleSect = %s\n", envelope->dmLegalTitleSect);
520 printf("\t\tdmLegalTitlePar = %s\n", envelope->dmLegalTitlePar);
521 printf("\t\tdmLegalTitlePoint = %s\n", envelope->dmLegalTitlePoint);
523 printf("\t\tdmPersonalDelivery = ");
524 print_bool(envelope->dmPersonalDelivery);
525 printf("\t\tdmAllowSubstDelivery = ");
526 print_bool(envelope->dmAllowSubstDelivery);
527 printf("\t\tdmOVM = ");
528 print_bool(envelope->dmOVM);
529 printf("\t\tdmPublishOwnID = ");
530 print_bool(envelope->dmPublishOwnID);
532 printf("\t\tdmOrdinal = ");
533 if (!envelope->dmOrdinal) printf("NULL\n");
534 else printf("%lu\n", *(envelope->dmOrdinal));
536 printf("\t\tdmMessageStatus = ");
537 print_dmMessageStatus(envelope->dmMessageStatus);
539 printf("\t\tdmAttachmentSize = ");
540 if (!envelope->dmAttachmentSize) printf("NULL\n");
541 else printf("%lu kB\n", *(envelope->dmAttachmentSize));
543 printf("\t\tdmDeliveryTime = ");
544 print_timeval(envelope->dmDeliveryTime);
546 printf("\t\tdmAcceptanceTime = ");
547 print_timeval(envelope->dmAcceptanceTime);
549 printf("\t\thash = ");
550 print_hash(envelope->hash);
552 printf("\t\ttimestamp = %p\n", envelope->timestamp);
553 printf("\t\ttimestamp_length = %zu\n", envelope->timestamp_length);
555 printf("\t\tevents = ");
556 print_events(envelope->events);
558 printf("\t}\n");
562 void print_document(const struct isds_document *document) {
563 printf("\t\tdocument = ");
565 if (!document) {
566 printf("NULL\n");
567 return;
569 printf("\{\n");
571 printf("\t\t\tis_xml = %u\n", !!document->is_xml);
572 printf("\t\t\txml_node_list = %p\n", document->xml_node_list);
574 printf("\t\t\tdata = %p\n", document->data);
575 printf("\t\t\tdata_length = %zu\n", document->data_length);
576 printf("\t\t\tdmMimeType = %s\n", document->dmMimeType);
578 printf("\t\t\tdmFileMetaType = ");
579 switch(document->dmFileMetaType) {
580 case FILEMETATYPE_MAIN: printf("MAIN\n"); break;
581 case FILEMETATYPE_ENCLOSURE: printf("ENCLOSURE\n"); break;
582 case FILEMETATYPE_SIGNATURE: printf("SIGNATURE\n"); break;
583 case FILEMETATYPE_META: printf("META\n"); break;
584 default: printf("<unknown type %d>\n", document->dmFileMetaType);
587 printf("\t\t\tdmFileGuid = %s\n", document->dmFileGuid);
588 printf("\t\t\tdmUpFileGuid = %s\n", document->dmUpFileGuid);
589 printf("\t\t\tdmFileDescr = %s\n", document->dmFileDescr);
590 printf("\t\t\tdmFormat = %s\n", document->dmFormat);
591 printf("\t\t}\n");
595 void print_documents(const struct isds_list *documents) {
596 const struct isds_list *item;
598 printf("\tdocuments = ");
600 if (!documents) {
601 printf("NULL\n");
602 return;
604 printf("{\n");
606 for (item = documents; item; item = item->next) {
607 print_document((struct isds_document *) (item->data));
610 printf("\t}\n");
614 void print_message(const struct isds_message *message) {
615 printf("message = ");
617 if (!message) {
618 printf("NULL\n");
619 return;
622 printf("{\n");
624 printf("\traw = %p\n", message->raw);
625 printf("\traw_length = %zu\n", message->raw_length);
626 printf("\traw_type = ");
627 print_raw_type(message->raw_type);
628 printf("\txml = %p\n", message->xml);
629 print_envelope(message->envelope);
630 print_documents(message->documents);
632 printf("}\n");
635 void print_copies(const struct isds_list *copies) {
636 const struct isds_list *item;
637 struct isds_message_copy *copy;
639 printf("Copies = ");
640 if (!copies) {
641 printf("<NULL>\n");
642 return;
645 printf("{\n");
646 for (item = copies; item; item = item->next) {
647 copy = (struct isds_message_copy *) item->data;
648 printf("\tCopy = ");
650 if (!copy)
651 printf("<NULL>\n");
652 else {
653 printf("{\n");
654 printf("\t\tdbIDRecipient = %s\n", copy->dbIDRecipient);
655 printf("\t\tdmRecipientOrgUnit = %s\n", copy->dmRecipientOrgUnit);
657 printf("\t\tdmRecipientOrgUnitNum = ");
658 if (copy->dmRecipientOrgUnitNum)
659 printf("%ld\n", *copy->dmRecipientOrgUnitNum);
660 else
661 printf("<NULL>\n");
662 printf("\t\tdmToHands = %s\n", copy->dmToHands);
664 printf("\t\terror = %s\n", isds_strerror(copy->error));
665 printf("\t\tdmStatus = %s\n", copy->dmStatus);
666 printf("\t\tdmID = %s\n", copy->dmID);
667 printf("\t}\n");
670 printf("}\n");
673 void print_message_status_change(
674 const struct isds_message_status_change *changed_status) {
675 printf("message_status_change = ");
677 if (!changed_status) {
678 printf("NULL\n");
679 return;
682 printf("{\n");
684 printf("\tdmID = %s\n", changed_status->dmID);
686 printf("\tdmMessageStatus = ");
687 print_dmMessageStatus(changed_status->dmMessageStatus);
689 printf("\ttime = ");
690 print_timeval(changed_status->time);
692 printf("}\n");
695 void compare_hashes(const struct isds_hash *hash1,
696 const struct isds_hash *hash2) {
697 isds_error err;
699 printf("Comparing hashes... ");
700 err = isds_hash_cmp(hash1, hash2);
701 if (err == IE_SUCCESS)
702 printf("Hashes equal\n");
703 else if
704 (err == IE_NOTEQUAL) printf("Hashes differ\n");
705 else
706 printf("isds_hash_cmp() failed: %s\n", isds_strerror(err));
710 int progressbar(double upload_total, double upload_current,
711 double download_total, double download_current,
712 void *data) {
714 printf("Progress: upload %0f/%0f, download %0f/%0f, data=%p\n",
715 upload_current, upload_total, download_current, download_total,
716 data);
717 if (data) {
718 printf("Aborting transfer...\n");
719 return 1;
721 return 0;
725 int mmap_file(const char *file, int *fd, void **buffer, size_t *length) {
726 struct stat file_info;
728 if (!file || !fd || !buffer || !length) return -1;
731 *fd = open(file, O_RDONLY);
732 if (*fd == -1) {
733 fprintf(stderr, "%s: Could not open file: %s\n", file, strerror(errno));
734 return -1;
737 if (-1 == fstat(*fd, &file_info)) {
738 fprintf(stderr, "%s: Could not get file size: %s\n", file,
739 strerror(errno));
740 close(*fd);
741 return -1;
743 if (file_info.st_size < 0) {
744 fprintf(stderr, "File `%s' has negative size: %" PRIdMAX "\n", file,
745 (intmax_t) file_info.st_size);
746 close(*fd);
747 return -1;
749 *length = file_info.st_size;
751 if (!*length) {
752 /* Empty region cannot be mmapped */
753 *buffer = NULL;
754 } else {
755 *buffer = mmap(NULL, *length, PROT_READ, MAP_PRIVATE, *fd, 0);
756 if (*buffer == MAP_FAILED) {
757 fprintf(stderr, "%s: Could not map file to memory: %s\n", file,
758 strerror(errno));
759 close(*fd);
760 return -1;
764 return 0;
768 int munmap_file(int fd, void *buffer, size_t length) {
769 int err = 0;
770 long int page_size = sysconf(_SC_PAGE_SIZE);
771 size_t pages = (length % page_size) ?
772 ((length / page_size) + 1) * page_size:
773 length;
775 if (length) {
776 err = munmap(buffer, pages);
777 if (err) {
778 fprintf(stderr,
779 "Could not unmap memory at %p and length %zu: %s\n",
780 buffer, pages, strerror(errno));
784 err = close(fd);
785 if (err) {
786 fprintf(stderr, "Could close file descriptor %d: %s\n", fd,
787 strerror(errno));
790 return err;
794 static int save_data_to_file(const char *file, const void *data,
795 const size_t length) {
796 int fd;
797 ssize_t written, left = length;
799 if (!file) return -1;
800 if (length > 0 && !data) return -1;
802 fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0666);
803 if (fd == -1) {
804 fprintf(stderr, "%s: Could not open file for writing: %s\n",
805 file, strerror(errno));
806 return -1;
809 printf("Writing %zu bytes to file `%s'...\n", length, file);
810 while (left) {
811 written = write(fd, data + length - left, left);
812 if (written == -1) {
813 fprintf(stderr, "%s: Could not save file: %s\n",
814 file, strerror(errno));
815 close(fd);
816 return -1;
818 left-=written;
821 if (-1 == close(fd)) {
822 fprintf(stderr, "%s: Closing file failed: %s\n",
823 file, strerror(errno));
824 return -1;
827 printf("Done.\n");
828 return 0;
832 int save_data(const char *message, const void *data, const size_t length) {
833 if (message)
834 printf("%s\n", message);
835 return save_data_to_file("output", data, length);