1 #define _XOPEN_SOURCE 700
4 /*#include <locale.h>*/
10 #include <sys/types.h>
17 char credentials_file
[] = "../test_credentials";
19 static int read_config(char **line
, int order
) {
28 file
= fopen(credentials_file
, "r");
30 fprintf(stderr
, "Could open %s\n", credentials_file
);
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
);
39 fprintf(stderr
, "error occured\n");
41 fprintf(stderr
, "end of file reached\n");
43 fprintf(stderr
, "I don't know why\n");
53 eol
= strpbrk(*line
, "\r\n");
59 const char *username(void) {
60 static char *username
;
63 username
= getenv("ISDS_USERNAME");
65 read_config(&username
, 1);
70 const char *password(void) {
71 static char *password
;
74 password
= getenv("ISDS_PASSWORD");
76 read_config(&password
, 2);
81 void print_DbState(const long int 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");
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 case DBTYPE_OVM_FO
: printf("OVM_FO\n"); break;
112 case DBTYPE_OVM_PFO
: printf("OVM_PFO\n"); break;
113 case DBTYPE_OVM_PO
: printf("OVM_PO\n"); break;
114 default: printf("<unknown type %ld>\n", *type
);
119 void print_UserType(const long int *type
) {
120 if (!type
) printf("NULL\n");
123 case USERTYPE_PRIMARY
: printf("PRIMARY\n"); break;
124 case USERTYPE_ENTRUSTED
: printf("ENTRUSTED\n"); break;
125 case USERTYPE_ADMINISTRATOR
: printf("ADMINISTRATOR\n"); break;
126 case USERTYPE_OFFICIAL
: printf("OFFICIAL\n"); break;
127 case USERTYPE_OFFICIAL_CERT
: printf("OFFICIAL_CERT\n"); break;
128 case USERTYPE_LIQUIDATOR
: printf("LIQUIDATOR\n"); break;
129 case USERTYPE_RECEIVER
: printf("RECEIVER\n"); break;
130 case USERTYPE_GUARDIAN
: printf("GUARDIAN\n"); break;
131 default: printf("<unknown type %ld>\n", *type
);
136 void print_sender_type(const isds_sender_type
*type
) {
137 if (!type
) printf("NULL\n");
140 case SENDERTYPE_PRIMARY
: printf("PRIMARY\n"); break;
141 case SENDERTYPE_ENTRUSTED
: printf("ENTRUSTED\n"); break;
142 case SENDERTYPE_ADMINISTRATOR
: printf("ADMINISTRATOR\n"); break;
143 case SENDERTYPE_OFFICIAL
: printf("OFFICIAL\n"); break;
144 case SENDERTYPE_VIRTUAL
: printf("VIRTUAL\n"); break;
145 case SENDERTYPE_OFFICIAL_CERT
: printf("OFFICIAL_CERT\n"); break;
146 case SENDERTYPE_LIQUIDATOR
: printf("LIQUIDATOR\n"); break;
147 case SENDERTYPE_RECEIVER
: printf("RECEIVER\n"); break;
148 case SENDERTYPE_GUARDIAN
: printf("GUARDIAN\n"); break;
149 default: printf("<unknown type %u>\n", *type
);
154 void print_UserPrivils(const long int *privils
) {
156 const char *priviledges
[] = {
166 const int priviledges_count
= sizeof(priviledges
)/sizeof(priviledges
[0]);
168 if (!privils
) printf("NULL\n");
170 printf("%ld (", *privils
);
172 for (int i
= 0; i
< priviledges_count
; i
++) {
173 if (*privils
& (1<<i
)) {
175 ((i
+ 1) == priviledges_count
) ? "%s" : "%s|",
185 void print_hash(const struct isds_hash
*hash
) {
191 switch(hash
->algorithm
) {
192 case HASH_ALGORITHM_MD5
: printf("MD5 "); break;
193 case HASH_ALGORITHM_SHA_1
: printf("SHA-1 "); break;
194 case HASH_ALGORITHM_SHA_256
: printf("SHA-256 "); break;
195 case HASH_ALGORITHM_SHA_512
: printf("SHA-512 "); break;
196 default: printf("<Unknown hash algorithm %d> ", hash
->algorithm
);
200 if (!hash
->value
) printf("<NULL>");
202 for (size_t i
= 0; i
< hash
->length
; i
++) {
203 if (i
> 0) printf(":");
204 printf("%02x", ((uint8_t *)(hash
->value
))[i
]);
211 void print_raw_type(const isds_raw_type type
) {
213 case RAWTYPE_INCOMING_MESSAGE
:
214 printf("INCOMING_MESSAGE\n"); break;
215 case RAWTYPE_PLAIN_SIGNED_INCOMING_MESSAGE
:
216 printf("PLAIN_SIGNED_INCOMING_MESSAGE\n"); break;
217 case RAWTYPE_CMS_SIGNED_INCOMING_MESSAGE
:
218 printf("CMS_SIGNED_INCOMING_MESSAGE\n"); break;
219 case RAWTYPE_PLAIN_SIGNED_OUTGOING_MESSAGE
:
220 printf("PLAIN_SIGNED_OUTGOING_MESSAGE\n"); break;
221 case RAWTYPE_CMS_SIGNED_OUTGOING_MESSAGE
:
222 printf("CMS_SIGNED_OUTGOING_MESSAGE\n"); break;
223 case RAWTYPE_DELIVERYINFO
:
224 printf("DELIVERYINFO\n"); break;
225 case RAWTYPE_PLAIN_SIGNED_DELIVERYINFO
:
226 printf("PLAIN_SIGNED_DELIVERYINFO\n"); break;
227 case RAWTYPE_CMS_SIGNED_DELIVERYINFO
:
228 printf("CMS_SIGNED_DELIVERYINFO\n"); break;
230 printf("<Unknown raw type %d> ", type
);
235 static void print_dmMessageStatus(const isds_message_status
*status
) {
236 if (!status
) printf("NULL\n");
239 case MESSAGESTATE_SENT
: printf("SENT\n"); break;
240 case MESSAGESTATE_STAMPED
: printf("STAMPED\n"); break;
241 case MESSAGESTATE_INFECTED
: printf("INFECTED\n"); break;
242 case MESSAGESTATE_DELIVERED
: printf("DELIVERED\n"); break;
243 case MESSAGESTATE_SUBSTITUTED
: printf("SUBSTITUTED\n"); break;
244 case MESSAGESTATE_RECEIVED
: printf("RECEIVED\n"); break;
245 case MESSAGESTATE_READ
: printf("READ\n"); break;
246 case MESSAGESTATE_UNDELIVERABLE
: printf("UNDELIVERABLE\n"); break;
247 case MESSAGESTATE_REMOVED
: printf("REMOVED\n"); break;
248 case MESSAGESTATE_IN_SAFE
: printf("IN_SAFE\n"); break;
249 default: printf("<unknown type %d>\n", *status
);
253 void print_bool(const _Bool
*boolean
) {
254 printf("%s\n", (!boolean
) ? "NULL" : ((*boolean
)? "true" : "false") );
258 void print_longint(const long int *number
) {
259 if (!number
) printf("NULL\n");
260 else printf("%ld\n", *number
);
264 void print_PersonName(const struct isds_PersonName
*personName
) {
265 printf("\tpersonName = ");
266 if (!personName
) printf("NULL\n");
269 printf("\t\tpnFirstName = %s\n", personName
->pnFirstName
);
270 printf("\t\tpnMiddleName = %s\n", personName
->pnMiddleName
);
271 printf("\t\tpnLastName = %s\n", personName
->pnLastName
);
272 printf("\t\tpnLastNameAtBirth = %s\n", personName
->pnLastNameAtBirth
);
278 void print_Address(const struct isds_Address
*address
) {
279 printf("\taddress = ");
280 if (!address
) printf("NULL\n");
284 printf("\t\tadCode = ");
285 print_longint(address
->adCode
);
287 printf("\t\tadCity = %s\n", address
->adCity
);
288 printf("\t\tadDistrict = %s\n", address
->adDistrict
);
289 printf("\t\tadStreet = %s\n", address
->adStreet
);
290 printf("\t\tadNumberInStreet = %s\n", address
->adNumberInStreet
);
291 printf("\t\tadNumberInMunicipality = %s\n",
292 address
->adNumberInMunicipality
);
293 printf("\t\tadZipCode = %s\n", address
->adZipCode
);
294 printf("\t\tadState = %s\n", address
->adState
);
300 void print_date(const struct tm
*date
) {
301 if (!date
) printf("NULL\n");
302 else printf("%s", asctime(date
));
306 void print_DbOwnerInfo(const struct isds_DbOwnerInfo
*info
) {
307 printf("dbOwnerInfo = ");
315 printf("\tdbID = %s\n", info
->dbID
);
317 printf("\tdbType = ");
318 print_DbType((long int *) (info
->dbType
));
319 printf("\tic = %s\n", info
->ic
);
321 print_PersonName(info
->personName
);
323 printf("\tfirmName = %s\n", info
->firmName
);
325 printf("\tbirthInfo = ");
326 if (!info
->birthInfo
) printf("NULL\n");
330 printf("\t\tbiDate = ");
331 print_date(info
->birthInfo
->biDate
);
333 printf("\t\tbiCity = %s\n", info
->birthInfo
->biCity
);
334 printf("\t\tbiCounty = %s\n", info
->birthInfo
->biCounty
);
335 printf("\t\tbiState = %s\n", info
->birthInfo
->biState
);
339 print_Address(info
->address
);
341 printf("\tnationality = %s\n", info
->nationality
);
342 printf("\temail = %s\n", info
->email
);
343 printf("\ttelNumber = %s\n", info
->telNumber
);
344 printf("\tidentifier = %s\n", info
->identifier
);
346 printf("\taifoIsds = ");
347 print_bool(info
->aifoIsds
);
349 printf("\tregistryCode = %s\n", info
->registryCode
);
351 printf("\tdbState = ");
352 if (!info
->dbState
) printf("NULL\n");
353 else print_DbState(*(info
->dbState
));
355 printf("\tdbEffectiveOVM = ");
356 print_bool(info
->dbEffectiveOVM
);
358 printf("\tdbOpenAddressing = ");
359 print_bool(info
->dbOpenAddressing
);
366 void print_DbUserInfo(const struct isds_DbUserInfo
*info
) {
367 printf("dbUserInfo = ");
375 printf("\tuserID = %s\n", info
->userID
);
377 printf("\tuserType = ");
378 print_UserType((long int *) (info
->userType
));
380 printf("\tuserPrivils = ");
381 print_UserPrivils(info
->userPrivils
);
383 print_PersonName(info
->personName
);
384 print_Address(info
->address
);
386 printf("\tbiDate = ");
387 print_date(info
->biDate
);
389 printf("\tic = %s\n", info
->ic
);
390 printf("\tfirmName = %s\n", info
->firmName
);
392 printf("\tcaStreet = %s\n", info
->caStreet
);
393 printf("\tcaCity = %s\n", info
->caCity
);
394 printf("\tcaZipCode = %s\n", info
->caZipCode
);
395 printf("\tcaState = %s\n", info
->caState
);
396 printf("\taifo_ticket = %s\n", info
->aifo_ticket
);
402 void print_timeval(const struct timeval
*time
) {
405 time_t seconds_as_time_t
;
412 /* MinGW32 GCC 4.8+ uses 64-bit time_t but time->tv_sec is defined as
413 * 32-bit long in Microsoft API. Convert value to the type expected by
415 seconds_as_time_t
= time
->tv_sec
;
416 if (!localtime_r(&seconds_as_time_t
, &broken
)) goto error
;
417 if (!strftime(buffer
, sizeof(buffer
)/sizeof(char), "%c", &broken
))
419 printf("%s, %" PRIdMAX
" us\n", buffer
, (intmax_t)time
->tv_usec
);
423 printf("<Error while formating>\n>");
428 void print_event_type(const isds_event_type
*type
) {
434 case EVENT_UKNOWN
: printf("UNKNOWN\n"); break;
435 case EVENT_ENTERED_SYSTEM
: printf("ENTERED_SYSTEM\n"); break;
436 case EVENT_ACCEPTED_BY_RECIPIENT
:
437 printf("ACCEPTED_BY_RECIPIENT\n"); break;
438 case EVENT_ACCEPTED_BY_FICTION
:
439 printf("DELIVERED_BY_FICTION\n"); break;
440 case EVENT_UNDELIVERABLE
:
441 printf("UNDELIVERABLE\n"); break;
442 case EVENT_COMMERCIAL_ACCEPTED
:
443 printf("COMMERCIAL_ACCEPTED\n"); break;
444 case EVENT_DELIVERED
:
445 printf("DELIVERED\n"); break;
446 case EVENT_PRIMARY_LOGIN
:
447 printf("PRIMARY_LOGIN\n"); break;
448 case EVENT_ENTRUSTED_LOGIN
:
449 printf("ENTRUSTED_LOGIN\n"); break;
450 case EVENT_SYSCERT_LOGIN
:
451 printf("SYSCERT_LOGIN\n"); break;
452 default: printf("<unknown type %d>\n", *type
);
457 void print_events(const struct isds_list
*events
) {
458 const struct isds_list
*item
;
459 const struct isds_event
*event
;
468 for (item
= events
; item
; item
= item
->next
) {
469 event
= (struct isds_event
*) item
->data
;
470 printf("\t\t\tevent = ");
471 if (!event
) printf("NULL");
475 printf("\t\t\t\ttype = ");
476 print_event_type(event
->type
);
478 printf("\t\t\t\tdescription = %s\n", event
->description
);
480 printf("\t\t\t\ttime = ");
481 print_timeval(event
->time
);
491 void print_envelope(const struct isds_envelope
*envelope
) {
492 printf("\tenvelope = ");
500 printf("\t\tdmID = %s\n", envelope
->dmID
);
501 printf("\t\tdbIDSender = %s\n", envelope
->dbIDSender
);
502 printf("\t\tdmSender = %s\n", envelope
->dmSender
);
503 printf("\t\tdmSenderAddress = %s\n", envelope
->dmSenderAddress
);
504 printf("\t\tdmSenderType = ");
505 print_DbType(envelope
->dmSenderType
);
506 printf("\t\tdmRecipient = %s\n", envelope
->dmRecipient
);
507 printf("\t\tdmRecipientAddress = %s\n", envelope
->dmRecipientAddress
);
508 printf("\t\tdmAmbiguousRecipient = ");
509 print_bool(envelope
->dmAmbiguousRecipient
);
510 printf("\t\tdmType = %s\n", envelope
->dmType
);
512 printf("\t\tdmSenderOrgUnit = %s\n", envelope
->dmSenderOrgUnit
);
513 printf("\t\tdmSenderOrgUnitNum = ");
514 print_longint(envelope
->dmSenderOrgUnitNum
);
515 printf("\t\tdbIDRecipient = %s\n", envelope
->dbIDRecipient
);
516 printf("\t\tdmRecipientOrgUnit = %s\n", envelope
->dmRecipientOrgUnit
);
517 printf("\t\tdmRecipientOrgUnitNum = ");
518 print_longint(envelope
->dmRecipientOrgUnitNum
);
519 printf("\t\tdmToHands = %s\n", envelope
->dmToHands
);
520 printf("\t\tdmAnnotation = %s\n", envelope
->dmAnnotation
);
521 printf("\t\tdmRecipientRefNumber = %s\n", envelope
->dmRecipientRefNumber
);
522 printf("\t\tdmSenderRefNumber = %s\n", envelope
->dmSenderRefNumber
);
523 printf("\t\tdmRecipientIdent = %s\n", envelope
->dmRecipientIdent
);
524 printf("\t\tdmSenderIdent = %s\n", envelope
->dmSenderIdent
);
526 printf("\t\tdmLegalTitleLaw = ");
527 print_longint(envelope
->dmLegalTitleLaw
);
528 printf("\t\tdmLegalTitleYear = ");
529 print_longint(envelope
->dmLegalTitleYear
);
530 printf("\t\tdmLegalTitleSect = %s\n", envelope
->dmLegalTitleSect
);
531 printf("\t\tdmLegalTitlePar = %s\n", envelope
->dmLegalTitlePar
);
532 printf("\t\tdmLegalTitlePoint = %s\n", envelope
->dmLegalTitlePoint
);
534 printf("\t\tdmPersonalDelivery = ");
535 print_bool(envelope
->dmPersonalDelivery
);
536 printf("\t\tdmAllowSubstDelivery = ");
537 print_bool(envelope
->dmAllowSubstDelivery
);
538 printf("\t\tdmOVM = ");
539 print_bool(envelope
->dmOVM
);
540 printf("\t\tdmPublishOwnID = ");
541 print_bool(envelope
->dmPublishOwnID
);
543 printf("\t\tdmOrdinal = ");
544 if (!envelope
->dmOrdinal
) printf("NULL\n");
545 else printf("%lu\n", *(envelope
->dmOrdinal
));
547 printf("\t\tdmMessageStatus = ");
548 print_dmMessageStatus(envelope
->dmMessageStatus
);
550 printf("\t\tdmAttachmentSize = ");
551 if (!envelope
->dmAttachmentSize
) printf("NULL\n");
552 else printf("%lu kB\n", *(envelope
->dmAttachmentSize
));
554 printf("\t\tdmDeliveryTime = ");
555 print_timeval(envelope
->dmDeliveryTime
);
557 printf("\t\tdmAcceptanceTime = ");
558 print_timeval(envelope
->dmAcceptanceTime
);
560 printf("\t\thash = ");
561 print_hash(envelope
->hash
);
563 printf("\t\ttimestamp = %p\n", envelope
->timestamp
);
564 printf("\t\ttimestamp_length = %zu\n", envelope
->timestamp_length
);
566 printf("\t\tevents = ");
567 print_events(envelope
->events
);
573 void print_document(const struct isds_document
*document
) {
574 printf("\t\tdocument = ");
582 printf("\t\t\tis_xml = %u\n", !!document
->is_xml
);
583 printf("\t\t\txml_node_list = %p\n", document
->xml_node_list
);
585 printf("\t\t\tdata = %p\n", document
->data
);
586 printf("\t\t\tdata_length = %zu\n", document
->data_length
);
587 printf("\t\t\tdmMimeType = %s\n", document
->dmMimeType
);
589 printf("\t\t\tdmFileMetaType = ");
590 switch(document
->dmFileMetaType
) {
591 case FILEMETATYPE_MAIN
: printf("MAIN\n"); break;
592 case FILEMETATYPE_ENCLOSURE
: printf("ENCLOSURE\n"); break;
593 case FILEMETATYPE_SIGNATURE
: printf("SIGNATURE\n"); break;
594 case FILEMETATYPE_META
: printf("META\n"); break;
595 default: printf("<unknown type %d>\n", document
->dmFileMetaType
);
598 printf("\t\t\tdmFileGuid = %s\n", document
->dmFileGuid
);
599 printf("\t\t\tdmUpFileGuid = %s\n", document
->dmUpFileGuid
);
600 printf("\t\t\tdmFileDescr = %s\n", document
->dmFileDescr
);
601 printf("\t\t\tdmFormat = %s\n", document
->dmFormat
);
606 void print_documents(const struct isds_list
*documents
) {
607 const struct isds_list
*item
;
609 printf("\tdocuments = ");
617 for (item
= documents
; item
; item
= item
->next
) {
618 print_document((struct isds_document
*) (item
->data
));
625 void print_message(const struct isds_message
*message
) {
626 printf("message = ");
635 printf("\traw = %p\n", message
->raw
);
636 printf("\traw_length = %zu\n", message
->raw_length
);
637 printf("\traw_type = ");
638 print_raw_type(message
->raw_type
);
639 printf("\txml = %p\n", message
->xml
);
640 print_envelope(message
->envelope
);
641 print_documents(message
->documents
);
646 void print_copies(const struct isds_list
*copies
) {
647 const struct isds_list
*item
;
648 struct isds_message_copy
*copy
;
657 for (item
= copies
; item
; item
= item
->next
) {
658 copy
= (struct isds_message_copy
*) item
->data
;
665 printf("\t\tdbIDRecipient = %s\n", copy
->dbIDRecipient
);
666 printf("\t\tdmRecipientOrgUnit = %s\n", copy
->dmRecipientOrgUnit
);
668 printf("\t\tdmRecipientOrgUnitNum = ");
669 if (copy
->dmRecipientOrgUnitNum
)
670 printf("%ld\n", *copy
->dmRecipientOrgUnitNum
);
673 printf("\t\tdmToHands = %s\n", copy
->dmToHands
);
675 printf("\t\terror = %s\n", isds_strerror(copy
->error
));
676 printf("\t\tdmStatus = %s\n", copy
->dmStatus
);
677 printf("\t\tdmID = %s\n", copy
->dmID
);
684 void print_message_status_change(
685 const struct isds_message_status_change
*changed_status
) {
686 printf("message_status_change = ");
688 if (!changed_status
) {
695 printf("\tdmID = %s\n", changed_status
->dmID
);
697 printf("\tdmMessageStatus = ");
698 print_dmMessageStatus(changed_status
->dmMessageStatus
);
701 print_timeval(changed_status
->time
);
706 void compare_hashes(const struct isds_hash
*hash1
,
707 const struct isds_hash
*hash2
) {
710 printf("Comparing hashes... ");
711 err
= isds_hash_cmp(hash1
, hash2
);
712 if (err
== IE_SUCCESS
)
713 printf("Hashes equal\n");
715 (err
== IE_NOTEQUAL
) printf("Hashes differ\n");
717 printf("isds_hash_cmp() failed: %s\n", isds_strerror(err
));
721 int progressbar(double upload_total
, double upload_current
,
722 double download_total
, double download_current
,
725 printf("Progress: upload %0f/%0f, download %0f/%0f, data=%p\n",
726 upload_current
, upload_total
, download_current
, download_total
,
729 printf("Aborting transfer...\n");
736 int mmap_file(const char *file
, int *fd
, void **buffer
, size_t *length
) {
737 struct stat file_info
;
739 if (!file
|| !fd
|| !buffer
|| !length
) return -1;
742 *fd
= open(file
, O_RDONLY
);
744 fprintf(stderr
, "%s: Could not open file: %s\n", file
, strerror(errno
));
748 if (-1 == fstat(*fd
, &file_info
)) {
749 fprintf(stderr
, "%s: Could not get file size: %s\n", file
,
754 if (file_info
.st_size
< 0) {
755 fprintf(stderr
, "File `%s' has negative size: %" PRIdMAX
"\n", file
,
756 (intmax_t) file_info
.st_size
);
760 *length
= file_info
.st_size
;
763 /* Empty region cannot be mmapped */
766 *buffer
= mmap(NULL
, *length
, PROT_READ
, MAP_PRIVATE
, *fd
, 0);
767 if (*buffer
== MAP_FAILED
) {
768 fprintf(stderr
, "%s: Could not map file to memory: %s\n", file
,
779 int munmap_file(int fd
, void *buffer
, size_t length
) {
781 long int page_size
= sysconf(_SC_PAGE_SIZE
);
782 size_t pages
= (length
% page_size
) ?
783 ((length
/ page_size
) + 1) * page_size
:
787 err
= munmap(buffer
, pages
);
790 "Could not unmap memory at %p and length %zu: %s\n",
791 buffer
, pages
, strerror(errno
));
797 fprintf(stderr
, "Could close file descriptor %d: %s\n", fd
,
805 static int save_data_to_file(const char *file
, const void *data
,
806 const size_t length
) {
808 ssize_t written
, left
= length
;
810 if (!file
) return -1;
811 if (length
> 0 && !data
) return -1;
813 fd
= open(file
, O_WRONLY
|O_TRUNC
|O_CREAT
, 0666);
815 fprintf(stderr
, "%s: Could not open file for writing: %s\n",
816 file
, strerror(errno
));
820 printf("Writing %zu bytes to file `%s'...\n", length
, file
);
822 written
= write(fd
, data
+ length
- left
, left
);
824 fprintf(stderr
, "%s: Could not save file: %s\n",
825 file
, strerror(errno
));
832 if (-1 == close(fd
)) {
833 fprintf(stderr
, "%s: Closing file failed: %s\n",
834 file
, strerror(errno
));
843 int save_data(const char *message
, const void *data
, const size_t length
) {
845 printf("%s\n", message
);
846 return save_data_to_file("output", data
, length
);