1 /****************************************************************************** 2 * 3 * Module Name: asfile - Main module for the acpi source processor utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpisrc.h" 45 #include "acapps.h" 46 47 /* Local prototypes */ 48 49 void 50 AsDoWildcard ( 51 ACPI_CONVERSION_TABLE *ConversionTable, 52 char *SourcePath, 53 char *TargetPath, 54 int MaxPathLength, 55 int FileType, 56 char *WildcardSpec); 57 58 BOOLEAN 59 AsDetectLoneLineFeeds ( 60 char *Filename, 61 char *Buffer); 62 63 static ACPI_INLINE int 64 AsMaxInt (int a, int b) 65 { 66 return (a > b ? a : b); 67 } 68 69 70 /****************************************************************************** 71 * 72 * FUNCTION: AsDoWildcard 73 * 74 * DESCRIPTION: Process files via wildcards 75 * 76 ******************************************************************************/ 77 78 void 79 AsDoWildcard ( 80 ACPI_CONVERSION_TABLE *ConversionTable, 81 char *SourcePath, 82 char *TargetPath, 83 int MaxPathLength, 84 int FileType, 85 char *WildcardSpec) 86 { 87 void *DirInfo; 88 char *Filename; 89 char *SourceDirPath; 90 char *TargetDirPath; 91 char RequestedFileType; 92 93 94 if (FileType == FILE_TYPE_DIRECTORY) 95 { 96 RequestedFileType = REQUEST_DIR_ONLY; 97 } 98 else 99 { 100 RequestedFileType = REQUEST_FILE_ONLY; 101 } 102 103 VERBOSE_PRINT (("Checking for %s source files in directory \"%s\"\n", 104 WildcardSpec, SourcePath)); 105 106 /* Open the directory for wildcard search */ 107 108 DirInfo = AcpiOsOpenDirectory (SourcePath, WildcardSpec, RequestedFileType); 109 if (DirInfo) 110 { 111 /* 112 * Get all of the files that match both the 113 * wildcard and the requested file type 114 */ 115 while ((Filename = AcpiOsGetNextFilename (DirInfo))) 116 { 117 /* Looking for directory files, must check file type */ 118 119 switch (RequestedFileType) 120 { 121 case REQUEST_DIR_ONLY: 122 123 /* If we actually have a dir, process the subtree */ 124 125 if (!AsCheckForDirectory (SourcePath, TargetPath, Filename, 126 &SourceDirPath, &TargetDirPath)) 127 { 128 VERBOSE_PRINT (("Subdirectory: %s\n", Filename)); 129 130 AsProcessTree (ConversionTable, SourceDirPath, TargetDirPath); 131 free (SourceDirPath); 132 free (TargetDirPath); 133 } 134 break; 135 136 case REQUEST_FILE_ONLY: 137 138 /* Otherwise, this is a file, not a directory */ 139 140 VERBOSE_PRINT (("File: %s\n", Filename)); 141 142 AsProcessOneFile (ConversionTable, SourcePath, TargetPath, 143 MaxPathLength, Filename, FileType); 144 break; 145 146 default: 147 148 break; 149 } 150 } 151 152 /* Cleanup */ 153 154 AcpiOsCloseDirectory (DirInfo); 155 } 156 } 157 158 159 /****************************************************************************** 160 * 161 * FUNCTION: AsProcessTree 162 * 163 * DESCRIPTION: Process the directory tree. Files with the extension ".C" and 164 * ".H" are processed as the tree is traversed. 165 * 166 ******************************************************************************/ 167 168 ACPI_NATIVE_INT 169 AsProcessTree ( 170 ACPI_CONVERSION_TABLE *ConversionTable, 171 char *SourcePath, 172 char *TargetPath) 173 { 174 int MaxPathLength; 175 176 177 MaxPathLength = AsMaxInt (strlen (SourcePath), strlen (TargetPath)); 178 179 if (!(ConversionTable->Flags & FLG_NO_FILE_OUTPUT)) 180 { 181 if (ConversionTable->Flags & FLG_LOWERCASE_DIRNAMES) 182 { 183 AcpiUtStrlwr (TargetPath); 184 } 185 186 VERBOSE_PRINT (("Creating Directory \"%s\"\n", TargetPath)); 187 if (mkdir (TargetPath)) 188 { 189 if (errno != EEXIST) 190 { 191 printf ("Could not create target directory\n"); 192 return (-1); 193 } 194 } 195 } 196 197 /* Do the C source files */ 198 199 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength, 200 FILE_TYPE_SOURCE, "*.c"); 201 202 /* Do the C header files */ 203 204 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength, 205 FILE_TYPE_HEADER, "*.h"); 206 207 /* Do the Lex file(s) */ 208 209 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength, 210 FILE_TYPE_SOURCE, "*.l"); 211 212 /* Do the yacc file(s) */ 213 214 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength, 215 FILE_TYPE_SOURCE, "*.y"); 216 217 /* Do any ASL files */ 218 219 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength, 220 FILE_TYPE_HEADER, "*.asl"); 221 222 /* Do any subdirectories */ 223 224 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength, 225 FILE_TYPE_DIRECTORY, "*"); 226 227 return (0); 228 } 229 230 231 /****************************************************************************** 232 * 233 * FUNCTION: AsDetectLoneLineFeeds 234 * 235 * DESCRIPTION: Find LF without CR. 236 * 237 ******************************************************************************/ 238 239 BOOLEAN 240 AsDetectLoneLineFeeds ( 241 char *Filename, 242 char *Buffer) 243 { 244 UINT32 i = 1; 245 UINT32 LfCount = 0; 246 UINT32 LineCount = 0; 247 248 249 if (!Buffer[0]) 250 { 251 return (FALSE); 252 } 253 254 while (Buffer[i]) 255 { 256 if (Buffer[i] == 0x0A) 257 { 258 if (Buffer[i-1] != 0x0D) 259 { 260 LfCount++; 261 } 262 263 LineCount++; 264 } 265 i++; 266 } 267 268 if (LfCount) 269 { 270 if (LineCount == LfCount) 271 { 272 if (!Gbl_IgnoreLoneLineFeeds) 273 { 274 printf ("%s: ****File has UNIX format**** (LF only, not CR/LF) %u lines\n", 275 Filename, LfCount); 276 } 277 } 278 else 279 { 280 printf ("%s: %u lone linefeeds in file\n", Filename, LfCount); 281 } 282 283 return (TRUE); 284 } 285 286 return (FALSE); 287 } 288 289 290 /****************************************************************************** 291 * 292 * FUNCTION: AsConvertFile 293 * 294 * DESCRIPTION: Perform the requested transforms on the file buffer (as 295 * determined by the ConversionTable and the FileType). 296 * 297 ******************************************************************************/ 298 299 void 300 AsConvertFile ( 301 ACPI_CONVERSION_TABLE *ConversionTable, 302 char *FileBuffer, 303 char *Filename, 304 ACPI_NATIVE_INT FileType) 305 { 306 UINT32 i; 307 UINT32 Functions; 308 ACPI_STRING_TABLE *StringTable; 309 ACPI_IDENTIFIER_TABLE *ConditionalTable; 310 ACPI_IDENTIFIER_TABLE *LineTable; 311 ACPI_TYPED_IDENTIFIER_TABLE *StructTable; 312 ACPI_IDENTIFIER_TABLE *SpecialMacroTable; 313 314 315 switch (FileType) 316 { 317 case FILE_TYPE_SOURCE: 318 319 Functions = ConversionTable->SourceFunctions; 320 StringTable = ConversionTable->SourceStringTable; 321 LineTable = ConversionTable->SourceLineTable; 322 ConditionalTable = ConversionTable->SourceConditionalTable; 323 StructTable = ConversionTable->SourceStructTable; 324 SpecialMacroTable = ConversionTable->SourceSpecialMacroTable; 325 break; 326 327 case FILE_TYPE_HEADER: 328 329 Functions = ConversionTable->HeaderFunctions; 330 StringTable = ConversionTable->HeaderStringTable; 331 LineTable = ConversionTable->HeaderLineTable; 332 ConditionalTable = ConversionTable->HeaderConditionalTable; 333 StructTable = ConversionTable->HeaderStructTable; 334 SpecialMacroTable = ConversionTable->HeaderSpecialMacroTable; 335 break; 336 337 case FILE_TYPE_PATCH: 338 339 Functions = ConversionTable->PatchFunctions; 340 StringTable = ConversionTable->PatchStringTable; 341 LineTable = ConversionTable->PatchLineTable; 342 ConditionalTable = ConversionTable->PatchConditionalTable; 343 StructTable = ConversionTable->PatchStructTable; 344 SpecialMacroTable = ConversionTable->PatchSpecialMacroTable; 345 break; 346 347 default: 348 349 printf ("Unknown file type, cannot process\n"); 350 return; 351 } 352 353 354 Gbl_StructDefs = strstr (FileBuffer, "/* acpisrc:StructDefs"); 355 Gbl_Files++; 356 VERBOSE_PRINT (("Processing %u bytes\n", 357 (unsigned int) strlen (FileBuffer))); 358 359 if (Gbl_Cleanup) 360 { 361 AsRemoveExtraLines (FileBuffer, Filename); 362 AsRemoveSpacesAfterPeriod (FileBuffer, Filename); 363 } 364 365 if (ConversionTable->LowerCaseTable) 366 { 367 for (i = 0; ConversionTable->LowerCaseTable[i].Identifier; i++) 368 { 369 AsLowerCaseString (ConversionTable->LowerCaseTable[i].Identifier, 370 FileBuffer); 371 } 372 } 373 374 /* Process all the string replacements */ 375 376 if (StringTable) 377 { 378 for (i = 0; StringTable[i].Target; i++) 379 { 380 AsReplaceString (StringTable[i].Target, StringTable[i].Replacement, 381 StringTable[i].Type, FileBuffer); 382 } 383 } 384 385 if (LineTable) 386 { 387 for (i = 0; LineTable[i].Identifier; i++) 388 { 389 AsRemoveLine (FileBuffer, LineTable[i].Identifier); 390 } 391 } 392 393 if (ConditionalTable) 394 { 395 for (i = 0; ConditionalTable[i].Identifier; i++) 396 { 397 AsRemoveConditionalCompile (FileBuffer, ConditionalTable[i].Identifier); 398 } 399 } 400 401 #ifdef _OBSOLETE_FUNCTIONS 402 if (MacroTable) 403 { 404 for (i = 0; MacroTable[i].Identifier; i++) 405 { 406 AsRemoveMacro (FileBuffer, MacroTable[i].Identifier); 407 } 408 } 409 #endif 410 411 if (StructTable) 412 { 413 for (i = 0; StructTable[i].Identifier; i++) 414 { 415 AsInsertPrefix (FileBuffer, StructTable[i].Identifier, 416 StructTable[i].Type); 417 } 418 } 419 420 if (SpecialMacroTable) 421 { 422 for (i = 0; SpecialMacroTable[i].Identifier; i++) 423 { 424 AsCleanupSpecialMacro (FileBuffer, SpecialMacroTable[i].Identifier); 425 } 426 } 427 428 /* Process the function table */ 429 430 for (i = 0; i < 32; i++) 431 { 432 /* Decode the function bitmap */ 433 434 switch ((1 << i) & Functions) 435 { 436 case 0: 437 438 /* This function not configured */ 439 break; 440 441 case CVT_COUNT_TABS: 442 443 AsCountTabs (FileBuffer, Filename); 444 break; 445 446 case CVT_COUNT_NON_ANSI_COMMENTS: 447 448 AsCountNonAnsiComments (FileBuffer, Filename); 449 break; 450 451 case CVT_CHECK_BRACES: 452 453 AsCheckForBraces (FileBuffer, Filename); 454 break; 455 456 case CVT_TRIM_LINES: 457 458 AsTrimLines (FileBuffer, Filename); 459 break; 460 461 case CVT_COUNT_LINES: 462 463 AsCountSourceLines (FileBuffer, Filename); 464 break; 465 466 case CVT_BRACES_ON_SAME_LINE: 467 468 AsBracesOnSameLine (FileBuffer); 469 break; 470 471 case CVT_MIXED_CASE_TO_UNDERSCORES: 472 473 AsMixedCaseToUnderscores (FileBuffer, Filename); 474 break; 475 476 case CVT_LOWER_CASE_IDENTIFIERS: 477 478 AsLowerCaseIdentifiers (FileBuffer); 479 break; 480 481 case CVT_REMOVE_DEBUG_MACROS: 482 483 AsRemoveDebugMacros (FileBuffer); 484 break; 485 486 case CVT_TRIM_WHITESPACE: 487 488 AsTrimWhitespace (FileBuffer); 489 break; 490 491 case CVT_REMOVE_EMPTY_BLOCKS: 492 493 AsRemoveEmptyBlocks (FileBuffer, Filename); 494 break; 495 496 case CVT_REDUCE_TYPEDEFS: 497 498 AsReduceTypedefs (FileBuffer, "typedef union"); 499 AsReduceTypedefs (FileBuffer, "typedef struct"); 500 break; 501 502 case CVT_SPACES_TO_TABS4: 503 504 AsTabify4 (FileBuffer); 505 break; 506 507 case CVT_SPACES_TO_TABS8: 508 509 AsTabify8 (FileBuffer); 510 break; 511 512 case CVT_COUNT_SHORTMULTILINE_COMMENTS: 513 514 #ifdef ACPI_FUTURE_IMPLEMENTATION 515 AsTrimComments (FileBuffer, Filename); 516 #endif 517 break; 518 519 default: 520 521 printf ("Unknown conversion subfunction opcode\n"); 522 break; 523 } 524 } 525 526 if (ConversionTable->NewHeader) 527 { 528 AsReplaceHeader (FileBuffer, ConversionTable->NewHeader); 529 } 530 } 531 532 533 /****************************************************************************** 534 * 535 * FUNCTION: AsProcessOneFile 536 * 537 * DESCRIPTION: Process one source file. The file is opened, read entirely 538 * into a buffer, converted, then written to a new file. 539 * 540 ******************************************************************************/ 541 542 ACPI_NATIVE_INT 543 AsProcessOneFile ( 544 ACPI_CONVERSION_TABLE *ConversionTable, 545 char *SourcePath, 546 char *TargetPath, 547 int MaxPathLength, 548 char *Filename, 549 ACPI_NATIVE_INT FileType) 550 { 551 char *Pathname; 552 char *OutPathname; 553 int Status = 0; 554 555 556 /* Allocate a file pathname buffer for both source and target */ 557 558 Pathname = calloc (MaxPathLength + strlen (Filename) + 2, 1); 559 if (!Pathname) 560 { 561 printf ("Could not allocate buffer for file pathnames\n"); 562 return (-1); 563 } 564 565 Gbl_FileType = FileType; 566 567 /* Generate the source pathname and read the file */ 568 569 if (SourcePath) 570 { 571 strcpy (Pathname, SourcePath); 572 strcat (Pathname, "/"); 573 } 574 575 strcat (Pathname, Filename); 576 577 if (AsGetFile (Pathname, &Gbl_FileBuffer, &Gbl_FileSize)) 578 { 579 Status = -1; 580 goto Exit1; 581 } 582 583 Gbl_HeaderSize = 0; 584 if (strstr (Filename, ".asl")) 585 { 586 Gbl_HeaderSize = LINES_IN_ASL_HEADER; /* Lines in default ASL header */ 587 } 588 else if (strstr (Gbl_FileBuffer, LEGAL_HEADER_SIGNATURE)) 589 { 590 Gbl_HeaderSize = LINES_IN_LEGAL_HEADER; /* Normal C file and H header */ 591 } 592 else if (strstr (Gbl_FileBuffer, LINUX_HEADER_SIGNATURE)) 593 { 594 Gbl_HeaderSize = LINES_IN_LINUX_HEADER; /* Linuxized C file and H header */ 595 } 596 597 /* Process the file in the buffer */ 598 599 Gbl_MadeChanges = FALSE; 600 if (!Gbl_IgnoreLoneLineFeeds && Gbl_HasLoneLineFeeds) 601 { 602 /* 603 * All lone LFs will be converted to CR/LF 604 * (when file is written, Windows version only) 605 */ 606 printf ("Converting lone linefeeds\n"); 607 Gbl_MadeChanges = TRUE; 608 } 609 610 AsConvertFile (ConversionTable, Gbl_FileBuffer, Pathname, FileType); 611 612 if (!(ConversionTable->Flags & FLG_NO_FILE_OUTPUT)) 613 { 614 if (!(Gbl_Overwrite && !Gbl_MadeChanges)) 615 { 616 /* Generate the target pathname and write the file */ 617 618 OutPathname = calloc (MaxPathLength + 619 strlen (Filename) + 2 + strlen (TargetPath), 1); 620 if (!OutPathname) 621 { 622 printf ("Could not allocate buffer for file pathnames\n"); 623 Status = -1; 624 goto Exit2; 625 } 626 627 strcpy (OutPathname, TargetPath); 628 if (SourcePath) 629 { 630 strcat (OutPathname, "/"); 631 strcat (OutPathname, Filename); 632 } 633 634 AsPutFile (OutPathname, Gbl_FileBuffer, ConversionTable->Flags); 635 free (OutPathname); 636 } 637 } 638 639 Exit2: 640 free (Gbl_FileBuffer); 641 642 Exit1: 643 free (Pathname); 644 return (Status); 645 } 646 647 648 /****************************************************************************** 649 * 650 * FUNCTION: AsCheckForDirectory 651 * 652 * DESCRIPTION: Check if the current file is a valid directory. If not, 653 * construct the full pathname for the source and target paths. 654 * Checks for the dot and dot-dot files (they are ignored) 655 * 656 ******************************************************************************/ 657 658 ACPI_NATIVE_INT 659 AsCheckForDirectory ( 660 char *SourceDirPath, 661 char *TargetDirPath, 662 char *Filename, 663 char **SourcePath, 664 char **TargetPath) 665 { 666 char *SrcPath; 667 char *TgtPath; 668 669 670 if (!(strcmp (Filename, ".")) || 671 !(strcmp (Filename, ".."))) 672 { 673 return (-1); 674 } 675 676 SrcPath = calloc (strlen (SourceDirPath) + strlen (Filename) + 2, 1); 677 if (!SrcPath) 678 { 679 printf ("Could not allocate buffer for directory source pathname\n"); 680 return (-1); 681 } 682 683 TgtPath = calloc (strlen (TargetDirPath) + strlen (Filename) + 2, 1); 684 if (!TgtPath) 685 { 686 printf ("Could not allocate buffer for directory target pathname\n"); 687 free (SrcPath); 688 return (-1); 689 } 690 691 strcpy (SrcPath, SourceDirPath); 692 strcat (SrcPath, "/"); 693 strcat (SrcPath, Filename); 694 695 strcpy (TgtPath, TargetDirPath); 696 strcat (TgtPath, "/"); 697 strcat (TgtPath, Filename); 698 699 *SourcePath = SrcPath; 700 *TargetPath = TgtPath; 701 return (0); 702 } 703 704 705 /****************************************************************************** 706 * 707 * FUNCTION: AsGetFile 708 * 709 * DESCRIPTION: Open a file and read it entirely into a an allocated buffer 710 * 711 ******************************************************************************/ 712 713 int 714 AsGetFile ( 715 char *Filename, 716 char **FileBuffer, 717 UINT32 *FileSize) 718 { 719 FILE *File; 720 UINT32 Size; 721 char *Buffer; 722 size_t Actual; 723 724 725 /* Binary mode leaves CR/LF pairs */ 726 727 File = fopen (Filename, "rb"); 728 if (!File) 729 { 730 printf ("Could not open file %s\n", Filename); 731 return (-1); 732 } 733 734 /* Need file size to allocate a buffer */ 735 736 Size = CmGetFileSize (File); 737 if (Size == ACPI_UINT32_MAX) 738 { 739 printf ("Could not get file size for %s\n", Filename); 740 goto ErrorExit; 741 } 742 743 /* 744 * Create a buffer for the entire file 745 * Add plenty extra buffer to accommodate string replacements 746 */ 747 Gbl_TotalSize += Size; 748 749 Buffer = calloc (Size * 2, 1); 750 if (!Buffer) 751 { 752 printf ("Could not allocate buffer of size %u\n", Size * 2); 753 goto ErrorExit; 754 } 755 756 /* Read the entire file */ 757 758 Actual = fread (Buffer, 1, Size, File); 759 if (Actual != Size) 760 { 761 printf ("Could not read the input file %s (%u bytes)\n", 762 Filename, Size); 763 goto ErrorFree; 764 } 765 766 Buffer [Size] = 0; /* Null terminate the buffer */ 767 fclose (File); 768 769 /* Check for unix contamination */ 770 771 Gbl_HasLoneLineFeeds = AsDetectLoneLineFeeds (Filename, Buffer); 772 773 /* 774 * Convert all CR/LF pairs to LF only. We do this locally so that 775 * this code is portable across operating systems. 776 */ 777 AsConvertToLineFeeds (Buffer); 778 779 *FileBuffer = Buffer; 780 *FileSize = Size; 781 return (0); 782 783 ErrorFree: 784 free (Buffer); 785 786 ErrorExit: 787 788 fclose (File); 789 return (-1); 790 } 791 792 793 /****************************************************************************** 794 * 795 * FUNCTION: AsPutFile 796 * 797 * DESCRIPTION: Create a new output file and write the entire contents of the 798 * buffer to the new file. Buffer must be a zero terminated string 799 * 800 ******************************************************************************/ 801 802 int 803 AsPutFile ( 804 char *Pathname, 805 char *FileBuffer, 806 UINT32 SystemFlags) 807 { 808 FILE *File; 809 UINT32 FileSize; 810 size_t Actual; 811 int Status = 0; 812 813 814 /* Create the target file */ 815 816 if (!(SystemFlags & FLG_NO_CARRIAGE_RETURNS)) 817 { 818 /* Put back the CR before each LF */ 819 820 AsInsertCarriageReturns (FileBuffer); 821 } 822 823 File = fopen (Pathname, "w+b"); 824 if (!File) 825 { 826 perror ("Could not create destination file"); 827 printf ("Could not create destination file \"%s\"\n", Pathname); 828 return (-1); 829 } 830 831 /* Write the buffer to the file */ 832 833 FileSize = strlen (FileBuffer); 834 Actual = fwrite (FileBuffer, 1, FileSize, File); 835 if (Actual != FileSize) 836 { 837 printf ("Error writing output file \"%s\"\n", Pathname); 838 Status = -1; 839 } 840 841 fclose (File); 842 return (Status); 843 } 844