1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - tools - buryarg.TWL
3   File:     buryarg.c
4 
5   Copyright 2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-11-19#$
14   $Rev: 9352 $
15   $Author: yada $
16  *---------------------------------------------------------------------------*/
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <sys/fcntl.h>
22 #include <sys/stat.h>
23 #include <getopt.h>
24 
25 #include <nitro_win32.h>
26 
27 //---- error code
28 #define ERROR_OVER_AREA  		                0
29 #define ERROR_NO_FILE     		                1
30 #define ERROR_CANNOT_OPEN_FILE                  2
31 #define ERROR_CANNOT_OPEN_REP_FILE              3
32 #define ERROR_MARK_NOT_FOUND	                4
33 #define ERROR_BAD_MARK_POSITION	                5
34 #define ERROR_BAD_ARGUMENT_SIZE                 6
35 #define ERROR_UNKNOWN_OPTION                    7
36 #define ERROR_OUTFILE_NOT_SPECIFIED             8
37 #define ERROR_REPLACEMENTFILE_NOT_SPECIFIED   	9
38 #define ERROR_REPLACEMENTFILE_TOO_BIG           10
39 #define ERROR_ILLEGAL_OPTIONS                   11
40 #define ERROR_FILE_ERROR                        12
41 #define ERROR_NLF_FILE_SPECIFIED                13
42 #define ERROR_NOT_TWL_SRL                       14
43 #define ERROR_ILLEGAL_TLF_FILE					15
44 
45 //---- version
46 #define VERSION_STRING     " 1.1  Copyright 2008 Nintendo. All right reserved."
47 // ver 1.1  fixed bug on --stdout option
48 // ver 1.0  applied for TWL
49 
50 //---- ouput default added string
51 #define ADDED_OUTPUT_NAME  ".argAdded"
52 
53 //---- output for stdout
54 const char gNameForStdout[] = "-";
55 
56 //---- argument buffer identification string
57 const char gArgIdString[] = OS_ARGUMENT_ID_STRING;
58 
59 //---- input bin file
60 #define FILE_NAME_MAX_SIZE  1024
61 FILE   *gInputFile;
62 char    gInputFileNameString[FILE_NAME_MAX_SIZE];
63 BOOL    gIsInputFileOpened = FALSE;
64 
65 //---- output file
66 FILE   *gOutputFile;
67 char    gOutputFileNameString[FILE_NAME_MAX_SIZE];
68 char   *gOutputFileName = NULL;
69 BOOL    gIsOutputFileOpened = FALSE;
70 
71 //---- replacement file
72 FILE   *gReplacementFile;
73 char   *gReplacementFileName = NULL;
74 BOOL    gIsReplacementFileOpened = FALSE;
75 
76 //---- tlf file
77 FILE   *gTlfFile;
78 char   *gTlfFileName = NULL;
79 BOOL    gIsTlfFileOpened = FALSE;
80 char    gTlfDirectoryNameString[FILE_NAME_MAX_SIZE];
81 
82 //---- argument buffer for replacement
83 #define ARGUMENT_BUF_SIZE 0x10000
84 char    gArgString[ARGUMENT_BUF_SIZE];
85 int     gArgStringSize;
86 int     gArgStringIndex = 0;
87 
88 //---- mode
89 BOOL    gQuietMode = FALSE;
90 BOOL    gVerboseMode = FALSE;
91 BOOL    gReplacementMode = TRUE;
92 BOOL    gDebugMode = FALSE;
93 BOOL    gTlfInputMode = FALSE;
94 BOOL    gStdoutMode = FALSE;
95 
96 //---- declaration of prototype
97 void    analyzeTlfFile(void);
98 void    closeFiles(void);
99 
100 //================================================================================
101 //                      Message display
102 //================================================================================
103 /*---------------------------------------------------------------------------*
104   Name:         displayMessage
105 
106   Description:  display message
107 
108   Arguments:    message : message array
109 
110   Returns:      None.
111  *---------------------------------------------------------------------------*/
displayMessage(char * message[])112 void displayMessage(char *message[])
113 {
114     int     n;
115     //---- show help messages
116     for (n = 0; message[n]; n++)
117     {
118         printf(message[n]);
119     }
120 }
121 
122 
123 /*---------------------------------------------------------------------------*
124   Name:         displayUsage
125 
126   Description:  display how to use.
127 
128   Arguments:    None.
129 
130   Returns:      None.
131  *---------------------------------------------------------------------------*/
displayUsage(void)132 void displayUsage(void)
133 {
134     char   *usageString[] = {
135         "Usage: buryarg.TWL [OPTION]... <TWL srl filename> [argument]...\n",
136         "Bury argument strings to TWL srl file.",
137         "\n",
138         "Options:\n",
139         "  --version           : Show version.\n",
140         "  -h, --help          : Show this help.\n",
141         "  -q, --quiet         : Quiet mode.\n",
142         "  -v, --verbose       : Verbose mode.\n",
143         "  -r, --remain        : Remain original file.\n",
144         "  -o, --output=FILE   : Output file (default: srcfile.argAdded)\n",
145         "                        if \"-\" is specified, output to stdout.\n",
146         "      --stdout        : Mean '-o-' .\n",
147         "  -f, --file=FILE     : Specify replacement buffer data.\n",
148         "                        This is used instead of data from arguments.\n",
149         "  -d, --debug         : Debug mode. Show replacement buffer.\n",
150         0
151     };
152 
153     displayMessage(usageString);
154 }
155 
156 /*---------------------------------------------------------------------------*
157   Name:         displayVersion
158 
159   Description:  display version
160 
161   Arguments:    None.
162 
163   Returns:      None.
164  *---------------------------------------------------------------------------*/
displayVersion(void)165 void displayVersion(void)
166 {
167     printf("buryarg %s\n", VERSION_STRING);
168 }
169 
170 /*---------------------------------------------------------------------------*
171   Name:         displayError
172 
173   Description:  display error
174 
175   Arguments:    errorNumber : error no.
176 
177   Returns:      None.
178  *---------------------------------------------------------------------------*/
displayError(int errorNumber)179 void displayError(int errorNumber)
180 {
181     fprintf(stderr, "Error: buryarg: ");
182 
183     switch (errorNumber)
184     {
185     case ERROR_OVER_AREA:
186         fprintf(stderr, "arguments too long.\n");
187         break;
188 
189     case ERROR_NO_FILE:
190         fprintf(stderr, "cannot open binary file.\n");
191         break;
192 
193     case ERROR_CANNOT_OPEN_FILE:
194         fprintf(stderr, "cannot open output file.\n");
195         break;
196 
197     case ERROR_CANNOT_OPEN_REP_FILE:
198         fprintf(stderr, "cannot open replacement file.\n");
199         break;
200 
201     case ERROR_MARK_NOT_FOUND:
202         fprintf(stderr, "cannot replace because bin file has no argument id string.\n");
203         break;
204 
205     case ERROR_BAD_MARK_POSITION:
206         fprintf(stderr, "bad argument mark position.\n");
207         break;
208 
209     case ERROR_BAD_ARGUMENT_SIZE:
210         fprintf(stderr, "bad argument size.\n");
211         break;
212 
213     case ERROR_UNKNOWN_OPTION:
214         fprintf(stderr, "unknown option or invalid usage. try --help.\n");
215         break;
216 
217     case ERROR_OUTFILE_NOT_SPECIFIED:
218         fprintf(stderr, "output file is not specified.\n");
219         break;
220 
221     case ERROR_REPLACEMENTFILE_NOT_SPECIFIED:
222         fprintf(stderr, "replacement file is not specified.\n");
223         break;
224 
225     case ERROR_REPLACEMENTFILE_TOO_BIG:
226         fprintf(stderr, "replacement file is too big.\n");
227         break;
228 
229     case ERROR_ILLEGAL_OPTIONS:
230         fprintf(stderr, "specified illegal option set.\n");
231         break;
232 
233     case ERROR_FILE_ERROR:
234         fprintf(stderr, "error occurred in renaming file.\n");
235         break;
236 
237 	case ERROR_NLF_FILE_SPECIFIED:
238 		fprintf(stderr, "cannot access to nlf file.\n");
239 		break;
240 
241 	case ERROR_NOT_TWL_SRL:
242         fprintf(stderr, "ROM is not for TWL.\n");
243         break;
244 
245     case ERROR_ILLEGAL_TLF_FILE:
246         fprintf(stderr, "illegal tlf file.\n");
247         break;
248 
249     default:
250         fprintf(stderr, "unknown error (%d).\n", errorNumber);
251         break;
252     }
253 
254     closeFiles();
255     exit(2);
256 }
257 
258 
259 //================================================================================
260 //                      Display for debug
261 //================================================================================
262 //---- for debug
263 //     display buffer
displayBuffer(void)264 void displayBuffer(void)
265 {
266     const int showSize = 256;
267     int     n;
268 
269     for (n = 0; n < showSize; n++)
270     {
271         int     k = n % 16;
272         int     c;
273 
274         if (k == 0)
275         {
276             printf("%4x ", n);
277         }
278 
279         c = (int)gArgString[n];
280 
281         if (0x20 <= c && c <= 0x7f)
282         {
283             printf("%c  ", gArgString[n]);
284         }
285         else if (c == 0)
286         {
287             printf(".  ");
288         }
289         else
290         {
291             printf("-  ");
292         }
293 
294         if (k == 15)
295         {
296             printf("\n");
297         }
298     }
299 }
300 
301 
302 //================================================================================
303 //              Parse filename
304 //================================================================================
305 /*---------------------------------------------------------------------------*
306   Name:         getTailFileName
307 
308   Description:  Locate filename tail.
309                 For example, if 'd:/aaa/bbb.srl' was input, output 'bbb.srl'.
310 
311   Arguments:    fileName: filename
312 
313   Returns:      Tail pointer of original string.
314  *---------------------------------------------------------------------------*/
getTailFileName(const char * fileName)315 const char *getTailFileName(const char *fileName)
316 {
317     const char *p = fileName;
318     const char *tailPtr = p;
319 
320     while (*p)
321     {
322         if (*p == '\\' || *p == '/' || *p == ':')
323         {
324             tailPtr = (p + 1);
325         }
326 
327         p++;
328     }
329 
330     return tailPtr;
331 }
332 
333 //================================================================================
334 //              Option parse and buffer creation
335 //================================================================================
336 /*---------------------------------------------------------------------------*
337   Name:         checkOverBuffer
338 
339   Description:  check if buffer is over.
340 				( if error occurred, never return )
341 
342   Arguments:    None.
343 
344   Returns:      None.
345  *---------------------------------------------------------------------------*/
checkOverBuffer(void)346 void checkOverBuffer(void)
347 {
348     if (gArgStringIndex >= ARGUMENT_BUF_SIZE)
349     {
350         displayError(ERROR_OVER_AREA);
351     }
352 }
353 
354 /*---------------------------------------------------------------------------*
355   Name:         addString
356 
357   Description:  adds string to nitro argument string area
358 
359   Arguments:    str : string to add
360 
361   Returns:      None.
362  *---------------------------------------------------------------------------*/
addString(const char * str)363 void addString(const char *str)
364 {
365     const char *p = str;
366 
367     if (!str)
368     {
369         printf("internal error: tend to add NULL string.\n");
370         exit(2);
371     }
372 
373     while (*p)
374     {
375         checkOverBuffer();
376         gArgString[gArgStringIndex++] = *p++;
377     }
378 
379     checkOverBuffer();
380     gArgString[gArgStringIndex++] = '\0';
381 }
382 
383 /*---------------------------------------------------------------------------*
384   Name:         checkTwlHeader
385 
386   Description:  check if the specified ROM is for TWL
387 
388   Arguments:    None.
389 
390   Returns:      None.
391  *---------------------------------------------------------------------------*/
392 #define ROM_TYPE_OFS 12
checkTwlHeader(void)393 void checkTwlHeader(void)
394 {
395 	const int readSize=32;
396    	char romHeader[readSize];
397 	int  romType;
398 
399     fseek(gTlfFile, 0, SEEK_SET);
400 	size_t  size = fread(romHeader, 1, readSize, gTlfFile);
401 
402 	romType = (int)romHeader[ ROM_TYPE_OFS ];
403 
404 	if (size != readSize || !(romType & 0x2) )
405 	{
406         displayError(ERROR_NOT_TWL_SRL);
407 	}
408 }
409 
410 /*---------------------------------------------------------------------------*
411   Name:         parseOption
412 
413   Description:  parses the option line
414 
415   Arguments:    argc : argument count
416                 argv: argument vector
417 
418   Returns:      result. less than 0 if error.
419  *---------------------------------------------------------------------------*/
parseOption(int argc,char * argv[])420 void parseOption(int argc, char *argv[])
421 {
422     int     n;
423     BOOL    helpFlag = FALSE;
424 
425     int     c;
426 
427     struct option optionInfo[] = {
428         {"help", no_argument, NULL, 'h'},
429         {"quiet", no_argument, NULL, 'q'},
430         {"verbose", no_argument, NULL, 'v'},
431         {"replacement", no_argument, NULL, 'r'},
432         {"version", no_argument, NULL, 'a'},
433         {"debug", no_argument, NULL, 'd'},
434         {"output", required_argument, 0, 'o'},
435         {"stdout", no_argument, NULL, 'O'},
436         {"file", required_argument, 0, 'f'},
437         {NULL, 0, 0, 0}
438     };
439     int     optionIndex;
440 
441     //---- suppress error string of getopt_long()
442     opterr = 0;
443 
444     while (1)
445     {
446         c = getopt_long(argc, argv, "+hqvrdo:f:", &optionInfo[0], &optionIndex);
447 
448         //printf("optind=%d optopt=%d  %x(%c) \n", optind, optopt, c,c );
449 
450         if (c == -1)
451         {
452             break;
453         }
454 
455         switch (c)
456         {
457         case 'h':
458             helpFlag = TRUE;
459             break;
460         case 'q':
461             gQuietMode = TRUE;
462             break;
463         case 'v':
464             gVerboseMode = TRUE;
465             break;
466         case 'r':
467             gReplacementMode = FALSE;
468             break;
469         case 'd':
470             gDebugMode = TRUE;
471             break;
472         case 'a':
473             displayVersion();
474             exit(1);
475             break;
476         case 'o':
477             gOutputFileName = (*optarg == '=') ? optarg + 1 : optarg;
478             if (!*gOutputFileName)
479             {
480                 displayError(ERROR_OUTFILE_NOT_SPECIFIED);
481             }
482             gReplacementMode = FALSE;
483             break;
484         case 'O':
485             gOutputFileName = (char *)gNameForStdout;
486             gReplacementMode = FALSE;
487             break;
488         case 'f':
489             gReplacementFileName = (*optarg == '=') ? optarg + 1 : optarg;
490             if (!*gReplacementFileName)
491             {
492                 displayError(ERROR_REPLACEMENTFILE_NOT_SPECIFIED);
493             }
494             break;
495         default:
496             displayError(ERROR_UNKNOWN_OPTION);
497         }
498     }
499 
500     //---- no specified bin file or "-h" of "--help" to display usage
501     if (helpFlag || argc <= optind)
502     {
503         displayUsage();
504         exit(1);
505     }
506 
507     //---- input filename
508     strncpy(gInputFileNameString, argv[optind], FILE_NAME_MAX_SIZE);
509 
510     //---- check if tlf file
511     if ((gTlfFile = fopen(gInputFileNameString, "rb")) == NULL)
512     {
513         displayError(ERROR_NO_FILE);
514     }
515     gIsTlfFileOpened = TRUE;
516 
517     //---- check nlf and tlf id string
518     {
519         char    idString[4];
520         size_t  size = fread(idString, 1, 4, gTlfFile);
521         if (size == 4 && !strncmp(idString, (char *)"#NLF", 4))
522         {
523 			displayError(ERROR_NLF_FILE_SPECIFIED);
524         }
525 
526 		if (size == 4 && !strncmp(idString, (char *)"#TLF", 4))
527 		{
528             gTlfFileName = argv[optind];
529 
530             //---- determine input file name
531             analyzeTlfFile();
532 		}
533     }
534 
535 	//---- check if TWL header
536 	if (gTlfFileName == NULL)
537 	{
538 		checkTwlHeader();
539 	}
540 
541     //---- close file
542     fclose(gTlfFile);
543     gIsTlfFileOpened = FALSE;
544 
545     //---- add string to replacement buffer
546     for (n = optind; n < argc; n++)
547     {
548         if (n == optind)
549         {
550             if (!gTlfFileName)
551             {
552                 addString(getTailFileName(argv[n]));
553             }
554         }
555         else
556         {
557             addString(argv[n]);
558         }
559     }
560 
561     //---- end mark
562     checkOverBuffer();
563     gArgString[gArgStringIndex++] = '\0';
564 }
565 
566 //================================================================================
567 //                      File operations
568 //================================================================================
569 /*---------------------------------------------------------------------------*
570   Name:         analyzeTlfFile
571 
572   Description:  analyze tlf file.
573 
574   Arguments:    None.
575 
576   Returns:      None.
577  *---------------------------------------------------------------------------*/
analyzeTlfFile(void)578 void analyzeTlfFile(void)
579 {
580     char    lineBuffer[1024];
581     BOOL    isFound_T = FALSE;
582     BOOL    isFound_H = FALSE;
583 
584     fseek(gTlfFile, 0, SEEK_SET);
585 
586     //---- analyze
587     while (fgets(lineBuffer, 1024, gTlfFile))
588     {
589         if (!strncmp(lineBuffer, "T,", 2))
590         {
591             char   *sp = &lineBuffer[0];
592             char   *dp = &gTlfDirectoryNameString[0];
593 
594             while (*sp++ != '\"')
595             {
596             }
597             while (*sp != '\"')
598             {
599                 *dp++ = *sp++;
600             }
601             *dp = '\0';
602 
603             isFound_T = TRUE;
604         }
605 
606 		if ( !strncmp(lineBuffer, "H,", 2))
607 		{
608 			char *sp = &lineBuffer[0];
609 			char *dp = &gInputFileNameString[0];
610 			int count=0;
611 
612 			//while (*sp && count <=2)
613 			while (*sp && count <=0)
614 			{
615 				if (*sp++ == '\"')
616 				{
617 					count++;
618 				}
619 			}
620 			while (*sp != '\"')
621 			{
622 				*dp++ = *sp++;
623 			}
624 			*dp = '\0';
625 
626 			//---- set argv[0]
627 			addString(getTailFileName(gInputFileNameString));
628 
629 			isFound_H = TRUE;
630 		}
631     }
632 
633     //---- check if found file name
634     if (!isFound_H)
635     {
636         displayError(ERROR_ILLEGAL_TLF_FILE);
637     }
638 }
639 
640 /*---------------------------------------------------------------------------*
641   Name:         openFiles
642 
643   Description:  open original file and output file
644 
645   Arguments:    None.
646 
647   Returns:      None.
648  *---------------------------------------------------------------------------*/
openFiles(void)649 void openFiles(void)
650 {
651     //---- replacement file
652     if (gReplacementFileName)
653     {
654         if (gVerboseMode)
655         {
656             printf("replacement file    : %s\n", gReplacementFileName);
657         }
658         if ((gReplacementFile = fopen(gReplacementFileName, "rb")) == NULL)
659         {
660             displayError(ERROR_CANNOT_OPEN_REP_FILE);
661         }
662         gIsReplacementFileOpened = TRUE;
663 
664         //---- replace buffer
665         {
666             int n;
667             int c;
668 
669             if (gVerboseMode)
670             {
671                 struct stat repFileStat;
672                 stat(gReplacementFileName, &repFileStat);
673                 printf("replacement file size is 0x%x byte (%d byte).\n", (int)repFileStat.st_size,
674                        (int)repFileStat.st_size);
675             }
676 
677             //---- clear buffer
678             for (n = 0; n < ARGUMENT_BUF_SIZE; n++)
679             {
680                 gArgString[n] = 0;
681             }
682 
683             //---- get replacement strings
684             n = 0;
685             while (n < ARGUMENT_BUF_SIZE && (c = fgetc(gReplacementFile)) != EOF)
686             {
687                 gArgString[n] = c;
688                 n++;
689             }
690             fclose(gReplacementFile);
691             gIsReplacementFileOpened = FALSE;
692 
693             //---- check over buffer
694             if (c != EOF)
695             {
696                 //displayError( ERROR_REPLACEMENTFILE_TOO_BIG );
697                 if (!gQuietMode)
698                 {
699                     printf("warning: replacement file is bigger than required size.");
700                 }
701             }
702         }
703     }
704 
705     //---- Do not overwrite original file
706     if (!gReplacementMode)
707     {
708         //---- Written filename
709         if (gOutputFileName)
710         {
711             strncpy(gOutputFileNameString, gOutputFileName, FILE_NAME_MAX_SIZE);
712         }
713         else
714         {
715             strcat(gOutputFileNameString, gInputFileNameString);
716             strncat(gOutputFileNameString, ADDED_OUTPUT_NAME, FILE_NAME_MAX_SIZE);
717         }
718 
719         //---- check if stdout specified
720         if (!strncmp(gOutputFileNameString, "-", 1))
721         {
722             gStdoutMode = TRUE;
723         }
724 
725         //---- output file
726         if (gVerboseMode)
727         {
728             if (gStdoutMode)
729             {
730                 printf("destination         : stdout\n");
731             }
732             else
733             {
734                 printf("destination bin file: %s\n", gOutputFileNameString);
735             }
736         }
737         if (gStdoutMode)
738         {
739             gOutputFile = stdout;
740 
741             //---- set stdout to binary mode
742             _setmode(_fileno(gOutputFile), O_BINARY);
743         }
744         else
745         {
746             if ((gOutputFile = fopen(gOutputFileNameString, "wb")) == NULL)
747             {
748                 displayError(ERROR_CANNOT_OPEN_FILE);
749            }
750             gIsOutputFileOpened = TRUE;
751         }
752     }
753 
754     //---- input file
755     if (gTlfFileName)
756     {
757         if (gVerboseMode)
758         {
759             printf("tlf current directory is %s\n", gTlfDirectoryNameString);
760         }
761         //---- change current directory
762         if (chdir(gTlfDirectoryNameString) != 0)
763         {
764             displayError(ERROR_ILLEGAL_TLF_FILE);
765         }
766     }
767 
768 
769     if (gVerboseMode)
770     {
771         printf("original bin file   : %s\n", gInputFileNameString);
772     }
773     if ((gInputFile = fopen(gInputFileNameString, (gReplacementMode) ? "rb+" : "rb")) == NULL)
774     {
775         displayError(ERROR_NO_FILE);
776     }
777     gIsInputFileOpened = TRUE;
778 }
779 
780 /*---------------------------------------------------------------------------*
781   Name:         closeFiles
782 
783   Description:  close files
784 
785   Arguments:    None.
786 
787   Returns:      None.
788  *---------------------------------------------------------------------------*/
closeFiles(void)789 void closeFiles(void)
790 {
791     if (gStdoutMode)
792     {
793         //---- flush stdout
794         fflush(stdout);
795 
796         //---- set stdout to text mode
797         _setmode(_fileno(gOutputFile), O_TEXT);
798     }
799 
800     if (gIsInputFileOpened)
801     {
802         fclose(gInputFile);
803         gIsInputFileOpened = FALSE;
804     }
805     if (gIsOutputFileOpened)
806     {
807         fclose(gOutputFile);
808         gIsOutputFileOpened = FALSE;
809     }
810     if (gIsReplacementFileOpened)
811     {
812         fclose(gReplacementFile);
813         gIsReplacementFileOpened = FALSE;
814     }
815     if (gIsTlfFileOpened)
816     {
817         fclose(gTlfFile);
818         gIsTlfFileOpened = FALSE;
819     }
820 }
821 
822 //================================================================================
823 //                      Replace buffer
824 //================================================================================
825 #define ROM_ARG_BUF_OFS 0x0e00
826 
replaceToSpecifiedString(void)827 void replaceToSpecifiedString(void)
828 {
829     long    bufPosition = ROM_ARG_BUF_OFS;
830     int     n;
831     int     inputChar;
832 
833     //---- replacement
834     if (gReplacementMode)
835     {
836 		gArgStringSize = OS_ARGUMENT_BUFFER_SIZE;
837 
838         fseek(gInputFile, bufPosition, SEEK_SET);
839         for (n = 0; n < gArgStringSize; n++)
840         {
841             fputc(gArgString[n], gInputFile);
842         }
843 
844         if (gVerboseMode)
845         {
846             printf("replaced 0x%x byte.\n", (int)gArgStringSize);
847         }
848     }
849     else
850     {
851         gArgStringSize = gArgStringIndex;
852 
853         fseek(gInputFile, 0, SEEK_SET);
854         n = 0;
855         while ((inputChar = fgetc(gInputFile)) != EOF)
856         {
857             if (bufPosition <= n && n < bufPosition + gArgStringSize)
858             {
859                 fputc(gArgString[n - bufPosition], gOutputFile);
860             }
861             else
862             {
863                 fputc(inputChar, gOutputFile);
864             }
865 
866             n++;
867         }
868 
869         if (gVerboseMode)
870         {
871             printf("output 0x%x byte (%d byte).\n", n, n);
872         }
873     }
874 }
875 
876 //================================================================================
877 //                      Main routine
878 //================================================================================
879 /*---------------------------------------------------------------------------*
880   Name:         Main
881 
882   Description:  main proc
883 
884   Arguments:    argc: argument count
885                 argv: argument vector
886 
887   Returns:      ---
888  *---------------------------------------------------------------------------*/
main(int argc,char * argv[])889 int main(int argc, char *argv[])
890 {
891     //---- Option parsing
892     parseOption(argc, argv);
893 
894     //---- File open
895     openFiles();
896 
897     //---- Buffer internal display (for debugging)
898     if (gDebugMode)
899     {
900         displayBuffer();
901     }
902 
903     //---- Replacement processing
904     replaceToSpecifiedString();
905 
906     //---- File close
907     closeFiles();
908 
909     //---- End
910     if (!gQuietMode)
911     {
912         printf("Success.\n");
913     }
914     return 0;
915 }
916