2f47317830d3dc9263c1c865fe6fccc084a550f2
[platform/upstream/dos2unix.git] / unix2dos.c
1 /*
2  *  Name: unix2dos
3  *  Documentation:
4  *    Convert lf ('\x0a') characters in a file to cr lf ('\x0d' '\x0a')
5  *    combinations.
6  *
7  *  The dos2unix package is distributed under FreeBSD style license.
8  *  See also http://www.freebsd.org/copyright/freebsd-license.html
9  *  --------
10  *
11  *  Copyright (C) 2009-2014 Erwin Waterlander
12  *  Copyright (C) 1994-1995 Benjamin Lin.
13  *  All rights reserved.
14  *
15  *  Redistribution and use in source and binary forms, with or without
16  *  modification, are permitted provided that the following conditions
17  *  are met:
18  *  1. Redistributions of source code must retain the above copyright
19  *     notice, this list of conditions and the following disclaimer.
20  *  2. Redistributions in binary form must reproduce the above copyright
21  *     notice in the documentation and/or other materials provided with
22  *     the distribution.
23  *
24  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
25  *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27  *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
28  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30  *  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33  *  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34  *  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  *  == 1.0 == 1989.10.04 == John Birchfield (jb@koko.csustan.edu)
37  *  == 1.1 == 1994.12.20 == Benjamin Lin (blin@socs.uts.edu.au)
38  *     Cleaned up for Borland C/C++ 4.02
39  *  == 1.2 == 1995.03.09 == Benjamin Lin (blin@socs.uts.edu.au)
40  *     Fixed minor typo error
41  *  == 1.3 == 1995.03.16 == Benjamin Lin (blin@socs.uts.edu.au)
42  *     Modified to more conform to UNIX style.
43  *  == 2.0 == 1995.03.19 == Benjamin Lin (blin@socs.uts.edu.au)
44  *     Rewritten from scratch.
45  *  == 2.2 == 1995.03.30 == Benjamin Lin (blin@socs.uts.edu.au)
46  *     Conversion from SunOS charset implemented.
47  *
48  *  See ChangeLog.txt for complete version history.
49  *
50  */
51
52
53 /* #define DEBUG 1 */
54
55 #include "common.h"
56 #include "unix2dos.h"
57 #include "querycp.h"
58 #ifdef D2U_UNICODE
59 #if !defined(__MSDOS__) && !defined(_WIN32) && !defined(__OS2__)  /* Unix, Cygwin */
60 # include <langinfo.h>
61 #endif
62 #endif
63
64 void PrintLicense(void)
65 {
66   printf("%s", _("\
67 Copyright (C) 2009-2014 Erwin Waterlander\n\
68 Copyright (C) 1994-1995 Benjamin Lin\n\
69 All rights reserved.\n\n"));
70   PrintBSDLicense();
71 }
72
73 #ifdef D2U_UNICODE
74 void AddDOSNewLineW(FILE* ipOutF, CFlag *ipFlag, wint_t CurChar, wint_t PrevChar)
75 {
76   if (ipFlag->NewLine) {  /* add additional CR-LF? */
77     /* Don't add line ending if it is a DOS line ending. Only in case of Unix line ending. */
78     if ((CurChar == 0x0a) && (PrevChar != 0x0d)) {
79       d2u_putwc(0x0d, ipOutF, ipFlag);
80       d2u_putwc(0x0a, ipOutF, ipFlag);
81     }
82   }
83 }
84 #endif
85
86 void AddDOSNewLine(FILE* ipOutF, CFlag *ipFlag, int CurChar, int PrevChar)
87 {
88   if (ipFlag->NewLine) {  /* add additional CR-LF? */
89     /* Don't add line ending if it is a DOS line ending. Only in case of Unix line ending. */
90     if ((CurChar == '\x0a') && (PrevChar != '\x0d')) {
91       fputc('\x0d', ipOutF);
92       fputc('\x0a', ipOutF);
93     }
94   }
95 }
96
97 /* converts stream ipInF to DOS format text and write to stream ipOutF
98  * RetVal: 0  if success
99  *         -1  otherwise
100  */
101 #ifdef D2U_UNICODE
102 int ConvertUnixToDosW(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag, char *progname)
103 {
104     int RetVal = 0;
105     wint_t TempChar;
106     wint_t PreviousChar = 0;
107     int line_nr = 1;
108     char *errstr;
109
110     ipFlag->status = 0;
111
112     /* LF    -> CR-LF */
113     /* CR-LF -> CR-LF, in case the input file is a DOS text file */
114     /* \x0a = Newline/Line Feed (LF) */
115     /* \x0d = Carriage Return (CR) */
116
117     switch (ipFlag->FromToMode)
118     {
119       case FROMTO_UNIX2DOS: /* unix2dos */
120         while ((TempChar = d2u_getwc(ipInF, ipFlag->bomtype)) != WEOF) {  /* get character */
121           if ((ipFlag->Force == 0) &&
122               (TempChar < 32) &&
123               (TempChar != 0x0a) &&  /* Not an LF */
124               (TempChar != 0x0d) &&  /* Not a CR */
125               (TempChar != 0x09) &&  /* Not a TAB */
126               (TempChar != 0x0c)) {  /* Not a form feed */
127             RetVal = -1;
128             ipFlag->status |= BINARY_FILE ;
129             if (!ipFlag->Quiet)
130             {
131               fprintf(stderr, "%s: ", progname);
132               fprintf(stderr, _("Binary symbol 0x00%02X found at line %d\n"),TempChar, line_nr);
133             }
134             break;
135           }
136           if (TempChar == 0x0a)
137           {
138             d2u_putwc(0x0d, ipOutF, ipFlag); /* got LF, put extra CR */
139           } else {
140              if (TempChar == 0x0d) /* got CR */
141              {
142                if ((TempChar = d2u_getwc(ipInF, ipFlag->bomtype)) == WEOF) /* get next char (possibly LF) */
143                  TempChar = 0x0d;  /* Read error, or end of file. */
144                else
145                {
146                  d2u_putwc(0x0d, ipOutF, ipFlag); /* put CR */
147                  PreviousChar = 0x0d;
148                }
149              }
150           }
151           if (TempChar == 0x0a) /* Count all DOS and Unix line breaks */
152             ++line_nr;
153           if (d2u_putwc(TempChar, ipOutF, ipFlag) == WEOF)
154           {
155               RetVal = -1;
156               if (!ipFlag->Quiet)
157               {
158                 if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
159                 {
160                   errstr = strerror(errno);
161                   fprintf(stderr, "%s: ", progname);
162                   fprintf(stderr, _("can not write to output file: %s\n"), errstr);
163                 }
164               }
165               break;
166           } else {
167             AddDOSNewLineW( ipOutF, ipFlag, TempChar, PreviousChar);
168           }
169           PreviousChar = TempChar;
170         }
171         break;
172       case FROMTO_UNIX2MAC: /* unix2mac */
173         while ((TempChar = d2u_getwc(ipInF, ipFlag->bomtype)) != WEOF) {
174           if ((ipFlag->Force == 0) &&
175               (TempChar < 32) &&
176               (TempChar != 0x0a) &&  /* Not an LF */
177               (TempChar != 0x0d) &&  /* Not a CR */
178               (TempChar != 0x09) &&  /* Not a TAB */
179               (TempChar != 0x0c)) {  /* Not a form feed */
180             RetVal = -1;
181             ipFlag->status |= BINARY_FILE ;
182             if (!ipFlag->Quiet)
183             {
184               fprintf(stderr, "%s: ", progname);
185               fprintf(stderr, _("Binary symbol 0x00%02X found at line %d\n"),TempChar, line_nr);
186             }
187             break;
188           }
189           if ((TempChar != 0x0a)) /* Not an LF */
190             {
191               if(d2u_putwc(TempChar, ipOutF, ipFlag) == WEOF){
192                 RetVal = -1;
193                 if (!ipFlag->Quiet)
194                 {
195                   if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
196                   {
197                     errstr = strerror(errno);
198                     fprintf(stderr, "%s: ", progname);
199                     fprintf(stderr, _("can not write to output file: %s\n"), errstr);
200                   }
201                 }
202                 break;
203               }
204               PreviousChar = TempChar;
205             }
206           else{
207             /* TempChar is an LF */
208             ++line_nr;
209             /* Don't touch this delimiter if it's a CR,LF pair. */
210             if ( PreviousChar == 0x0d ) {
211               if (d2u_putwc(0x0a, ipOutF, ipFlag) == WEOF)  /* CR,LF pair. Put LF */
212                 {
213                   RetVal = -1;
214                   if (!ipFlag->Quiet)
215                   {
216                     if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
217                     {
218                       errstr = strerror(errno);
219                       fprintf(stderr, "%s: ", progname);
220                       fprintf(stderr, _("can not write to output file: %s\n"), errstr);
221                     }
222                   }
223                   break;
224                 }
225               PreviousChar = TempChar;
226               continue;
227             }
228             PreviousChar = TempChar;
229             if (d2u_putwc(0x0d, ipOutF, ipFlag) == WEOF) /* Unix line end (LF). Put CR */
230               {
231                 RetVal = -1;
232                 if (!ipFlag->Quiet)
233                 {
234                   if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
235                   {
236                     errstr = strerror(errno);
237                     fprintf(stderr, "%s: ", progname);
238                     fprintf(stderr, _("can not write to output file: %s\n"), errstr);
239                   }
240                 }
241                 break;
242               }
243             if (ipFlag->NewLine) {  /* add additional CR? */
244               d2u_putwc(0x0d, ipOutF, ipFlag);
245             }
246           }
247         }
248         break;
249       default: /* unknown FromToMode */
250       ;
251 #if DEBUG
252       fprintf(stderr, "%s: ", progname);
253       fprintf(stderr, _("program error, invalid conversion mode %d\n"),ipFlag->FromToMode);
254       exit(1);
255 #endif
256     }
257     return RetVal;
258 }
259 #endif
260
261 /* converts stream ipInF to DOS format text and write to stream ipOutF
262  * RetVal: 0  if success
263  *         -1  otherwise
264  */
265 int ConvertUnixToDos(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag, char *progname)
266 {
267     int RetVal = 0;
268     int TempChar;
269     int PreviousChar = 0;
270     int *ConvTable;
271     int line_nr = 1;
272     char *errstr;
273
274     ipFlag->status = 0;
275
276     switch (ipFlag->ConvMode)
277     {
278       case CONVMODE_ASCII: /* ascii */
279       case CONVMODE_UTF16LE: /* Assume UTF-16LE */
280       case CONVMODE_UTF16BE: /* Assume UTF-16BE */
281         ConvTable = U2DAsciiTable;
282         break;
283       case CONVMODE_7BIT: /* 7bit */
284         ConvTable = U2D7BitTable;
285         break;
286       case CONVMODE_437: /* iso */
287         ConvTable = U2DIso437Table;
288         break;
289       case CONVMODE_850: /* iso */
290         ConvTable = U2DIso850Table;
291         break;
292       case CONVMODE_860: /* iso */
293         ConvTable = U2DIso860Table;
294         break;
295       case CONVMODE_863: /* iso */
296         ConvTable = U2DIso863Table;
297         break;
298       case CONVMODE_865: /* iso */
299         ConvTable = U2DIso865Table;
300         break;
301       case CONVMODE_1252: /* iso */
302         ConvTable = U2DIso1252Table;
303         break;
304       default: /* unknown convmode */
305         ipFlag->status |= WRONG_CODEPAGE ;
306         return(-1);
307     }
308     if ((ipFlag->ConvMode > 1) && (!ipFlag->Quiet)) /* not ascii or 7bit */
309     {
310        fprintf(stderr, "%s: ", progname);
311        fprintf(stderr, _("using code page %d.\n"), ipFlag->ConvMode);
312     }
313
314     /* LF    -> CR-LF */
315     /* CR-LF -> CR-LF, in case the input file is a DOS text file */
316     /* \x0a = Newline/Line Feed (LF) */
317     /* \x0d = Carriage Return (CR) */
318
319     switch (ipFlag->FromToMode)
320     {
321       case FROMTO_UNIX2DOS: /* unix2dos */
322         while ((TempChar = fgetc(ipInF)) != EOF) {  /* get character */
323           if ((ipFlag->Force == 0) &&
324               (TempChar < 32) &&
325               (TempChar != '\x0a') &&  /* Not an LF */
326               (TempChar != '\x0d') &&  /* Not a CR */
327               (TempChar != '\x09') &&  /* Not a TAB */
328               (TempChar != '\x0c')) {  /* Not a form feed */
329             RetVal = -1;
330             ipFlag->status |= BINARY_FILE ;
331             if (!ipFlag->Quiet)
332             {
333               fprintf(stderr, "%s: ", progname);
334               fprintf(stderr, _("Binary symbol 0x%02X found at line %d\n"),TempChar, line_nr);
335             }
336             break;
337           }
338           if (TempChar == '\x0a')
339           {
340             fputc('\x0d', ipOutF); /* got LF, put extra CR */
341           } else {
342              if (TempChar == '\x0d') /* got CR */
343              {
344                if ((TempChar = fgetc(ipInF)) == EOF) /* get next char (possibly LF) */
345                  TempChar = '\x0d';  /* Read error, or end of file. */
346                else
347                {
348                  fputc('\x0d', ipOutF); /* put CR */
349                  PreviousChar = '\x0d';
350                }
351              }
352           }
353           if (TempChar == '\x0a') /* Count all DOS and Unix line breaks */
354             ++line_nr;
355           if (fputc(ConvTable[TempChar], ipOutF) == EOF) /* put LF or other char */
356           {
357               RetVal = -1;
358               if (!ipFlag->Quiet)
359               {
360                 errstr = strerror(errno);
361                 fprintf(stderr, "%s: ", progname);
362                 fprintf(stderr, _("can not write to output file: %s\n"), errstr);
363               }
364               break;
365           } else {
366             AddDOSNewLine( ipOutF, ipFlag, TempChar, PreviousChar);
367           }
368           PreviousChar = TempChar;
369         }
370         break;
371       case FROMTO_UNIX2MAC: /* unix2mac */
372         while ((TempChar = fgetc(ipInF)) != EOF) {
373           if ((ipFlag->Force == 0) &&
374               (TempChar < 32) &&
375               (TempChar != '\x0a') &&  /* Not an LF */
376               (TempChar != '\x0d') &&  /* Not a CR */
377               (TempChar != '\x09') &&  /* Not a TAB */
378               (TempChar != '\x0c')) {  /* Not a form feed */
379             RetVal = -1;
380             ipFlag->status |= BINARY_FILE ;
381             if (!ipFlag->Quiet)
382             {
383               fprintf(stderr, "%s: ", progname);
384               fprintf(stderr, _("Binary symbol 0x%02X found at line %d\n"),TempChar, line_nr);
385             }
386             break;
387           }
388           if ((TempChar != '\x0a')) /* Not an LF */
389             {
390               if(fputc(ConvTable[TempChar], ipOutF) == EOF){
391                 RetVal = -1;
392                 if (!ipFlag->Quiet)
393                 {
394                   errstr = strerror(errno);
395                   fprintf(stderr, "%s: ", progname);
396                   fprintf(stderr, _("can not write to output file: %s\n"), errstr);
397                 }
398                 break;
399               }
400               PreviousChar = TempChar;
401             }
402           else{
403             /* TempChar is an LF */
404             ++line_nr;
405             /* Don't touch this delimiter if it's a CR,LF pair. */
406             if ( PreviousChar == '\x0d' ) {
407               if (fputc('\x0a', ipOutF) == EOF)  /* CR,LF pair. Put LF */
408                 {
409                   RetVal = -1;
410                   if (!ipFlag->Quiet)
411                   {
412                     errstr = strerror(errno);
413                     fprintf(stderr, "%s: ", progname);
414                     fprintf(stderr, _("can not write to output file: %s\n"), errstr);
415                   }
416                   break;
417                 }
418               PreviousChar = TempChar;
419               continue;
420             }
421             PreviousChar = TempChar;
422             if (fputc('\x0d', ipOutF) == EOF) /* Unix line end (LF). Put CR */
423               {
424                 RetVal = -1;
425                 if (!ipFlag->Quiet)
426                 {
427                   errstr = strerror(errno);
428                   fprintf(stderr, "%s: ", progname);
429                   fprintf(stderr, _("can not write to output file: %s\n"), errstr);
430                 }
431                 break;
432               }
433             if (ipFlag->NewLine) {  /* add additional CR? */
434               fputc('\x0d', ipOutF);
435             }
436           }
437         }
438         break;
439       default: /* unknown FromToMode */
440       ;
441 #if DEBUG
442       fprintf(stderr, "%s: ", progname);
443       fprintf(stderr, _("program error, invalid conversion mode %d\n"),ipFlag->FromToMode);
444       exit(1);
445 #endif
446     }
447     return RetVal;
448 }
449
450 /* convert file ipInFN to DOS format text and write to file ipOutFN
451  * RetVal: 0 if success
452  *         -1 otherwise
453  */
454 int ConvertUnixToDosNewFile(char *ipInFN, char *ipOutFN, CFlag *ipFlag, char *progname)
455 {
456   int RetVal = 0;
457   FILE *InF = NULL;
458   FILE *TempF = NULL;
459   char *TempPath;
460   char *errstr;
461   struct stat StatBuf;
462   struct utimbuf UTimeBuf;
463 #ifndef NO_CHMOD
464   mode_t mask;
465 #endif
466 #ifdef NO_MKSTEMP
467   FILE* fd;
468 #else
469   int fd;
470 #endif
471   char *TargetFN = NULL;
472   int ResolveSymlinkResult = 0;
473
474   ipFlag->status = 0 ;
475
476   /* Test if output file is a symbolic link */
477   if (symbolic_link(ipOutFN) && !ipFlag->Follow)
478   {
479     ipFlag->status |= OUTPUTFILE_SYMLINK ;
480     /* Not a failure, skipping input file according spec. (keep symbolic link unchanged) */
481     return -1;
482   }
483
484   /* Test if input file is a regular file or symbolic link */
485   if (regfile(ipInFN, 1, ipFlag, progname))
486   {
487     ipFlag->status |= NO_REGFILE ;
488     /* Not a failure, skipping non-regular input file according spec. */
489     return -1;
490   }
491
492   /* Test if input file target is a regular file */
493   if (symbolic_link(ipInFN) && regfile_target(ipInFN, ipFlag,progname))
494   {
495     ipFlag->status |= INPUT_TARGET_NO_REGFILE ;
496     /* Not a failure, skipping non-regular input file according spec. */
497     return -1;
498   }
499
500   /* Test if output file target is a regular file */
501   if (symbolic_link(ipOutFN) && (ipFlag->Follow == SYMLINK_FOLLOW) && regfile_target(ipOutFN, ipFlag,progname))
502   {
503     ipFlag->status |= OUTPUT_TARGET_NO_REGFILE ;
504     /* Failure, input is regular, cannot produce output. */
505     if (!ipFlag->error) ipFlag->error = 1;
506     return -1;
507   }
508
509   /* retrieve ipInFN file date stamp */
510   if (stat(ipInFN, &StatBuf))
511   {
512     if (!ipFlag->Quiet)
513     {
514       ipFlag->error = errno;
515       errstr = strerror(errno);
516       fprintf(stderr, "%s: %s: %s\n", progname, ipInFN, errstr);
517     }
518     RetVal = -1;
519   }
520
521 #ifdef NO_MKSTEMP
522   if((fd = MakeTempFileFrom(ipOutFN, &TempPath))==NULL) {
523 #else
524   if((fd = MakeTempFileFrom (ipOutFN, &TempPath)) < 0) {
525 #endif
526     if (!ipFlag->Quiet)
527     {
528       ipFlag->error = errno;
529       errstr = strerror(errno);
530       fprintf(stderr, "%s: ", progname);
531       fprintf(stderr, _("Failed to open temporary output file: %s\n"), errstr);
532     }
533     RetVal = -1;
534   }
535
536 #if DEBUG
537   fprintf(stderr, "%s: ", progname);
538   fprintf(stderr, _("using %s as temporary file\n"), TempPath);
539 #endif
540
541   /* can open in file? */
542   if (!RetVal)
543   {
544     InF=OpenInFile(ipInFN);
545     if (InF == NULL)
546     {
547       ipFlag->error = errno;
548       errstr = strerror(errno);
549       fprintf(stderr, "%s: %s: %s\n", progname, ipInFN, errstr);
550       RetVal = -1;
551     }
552   }
553
554   /* can open output file? */
555   if ((!RetVal) && (InF))
556   {
557 #ifdef NO_MKSTEMP
558     if ((TempF=fd) == NULL)
559     {
560 #else
561     if ((TempF=OpenOutFile(fd)) == NULL)
562     {
563       ipFlag->error = errno;
564       errstr = strerror(errno);
565       fprintf(stderr, "%s: %s\n", progname, errstr);
566 #endif
567       fclose (InF);
568       InF = NULL;
569       RetVal = -1;
570     }
571   }
572
573   InF = read_bom(InF, &ipFlag->bomtype);
574 #ifdef D2U_UNICODE
575   if ((ipFlag->bomtype == FILE_MBS) && (ipFlag->ConvMode == CONVMODE_UTF16LE))
576     ipFlag->bomtype = FILE_UTF16LE;
577   if ((ipFlag->bomtype == FILE_MBS) && (ipFlag->ConvMode == CONVMODE_UTF16BE))
578     ipFlag->bomtype = FILE_UTF16BE;
579 #endif
580
581 #ifdef D2U_UNICODE
582 #if !defined(__MSDOS__) && !defined(_WIN32) && !defined(__OS2__)  /* Unix, Cygwin */
583   if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
584   {
585     if (strcmp(nl_langinfo(CODESET), "UTF-8") != 0)
586     {
587       /* Don't convert UTF-16 files when the locale encoding is not UTF-8
588        * to prevent loss of characters. */
589       ipFlag->status |= LOCALE_NOT_UTF8 ;
590       if (!ipFlag->error) ipFlag->error = 1;
591       RetVal = -1;
592     }
593   }
594 #endif
595 #if !defined(_WIN32) && !defined(__CYGWIN__) /* Not Windows or Cygwin */
596   if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
597   {
598     if (sizeof(wchar_t) < 4)
599     {
600       /* A decoded UTF-16 surrogate pair must fit in a wchar_t */
601       ipFlag->status |= WCHAR_T_TOO_SMALL ;
602       if (!ipFlag->error) ipFlag->error = 1;
603       RetVal = -1;
604     }
605   }
606 #endif
607 #endif
608
609   if ((ipFlag->add_bom) || (ipFlag->bomtype > 0))
610     fprintf(TempF, "%s", "\xEF\xBB\xBF");  /* UTF-8 BOM */
611
612   /* Turn off ISO and 7-bit conversion for Unicode text files */
613   /* When we assume UTF16, don't change the conversion mode. We need to remember it. */
614   if ((ipFlag->bomtype > 0) && (ipFlag->ConvMode != CONVMODE_UTF16LE) && (ipFlag->ConvMode != CONVMODE_UTF16BE))
615     ipFlag->ConvMode = CONVMODE_ASCII;
616
617   /* conversion sucessful? */
618 #ifdef D2U_UNICODE
619   if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
620   {
621     if ((!RetVal) && (ConvertUnixToDosW(InF, TempF, ipFlag, progname)))
622       RetVal = -1;
623     if (ipFlag->status & UNICODE_CONVERSION_ERROR)
624     {
625       if (!ipFlag->error) ipFlag->error = 1;
626       RetVal = -1;
627     }
628   } else {
629     if ((!RetVal) && (ConvertUnixToDos(InF, TempF, ipFlag, progname)))
630       RetVal = -1;
631   }
632 #else
633   if ((!RetVal) && (ConvertUnixToDos(InF, TempF, ipFlag, progname)))
634     RetVal = -1;
635 #endif
636
637    /* can close in file? */
638   if ((InF) && (fclose(InF) == EOF))
639     RetVal = -1;
640
641   /* can close output file? */
642   if (TempF)
643   {
644     if (fclose(TempF) == EOF)
645     {
646        if (!ipFlag->Quiet)
647        {
648          ipFlag->error = errno;
649          errstr = strerror(errno);
650          fprintf(stderr, "%s: ", progname);
651          fprintf(stderr, _("Failed to write to temporary output file %s: %s\n"), TempPath, errstr);
652        }
653       RetVal = -1;
654     }
655   }
656
657 #ifdef NO_MKSTEMP
658   if(fd!=NULL)
659     fclose(fd);
660 #else
661   if(fd>=0)
662     close(fd);
663 #endif
664
665 #ifndef NO_CHMOD
666   if (!RetVal)
667   {
668     if (ipFlag->NewFile == 0) /* old-file mode */
669     {
670        RetVal = chmod (TempPath, StatBuf.st_mode); /* set original permissions */
671     }
672     else
673     {
674        mask = umask(0); /* get process's umask */
675        umask(mask); /* set umask back to original */
676        RetVal = chmod(TempPath, StatBuf.st_mode & ~mask); /* set original permissions, minus umask */
677     }
678
679     if (RetVal)
680     {
681        if (!ipFlag->Quiet)
682        {
683          ipFlag->error = errno;
684          errstr = strerror(errno);
685          fprintf(stderr, "%s: ", progname);
686          fprintf(stderr, _("Failed to change the permissions of temporary output file %s: %s\n"), TempPath, errstr);
687        }
688     }
689   }
690 #endif
691
692 #ifndef NO_CHOWN
693   if (!RetVal && (ipFlag->NewFile == 0))  /* old-file mode */
694   {
695      /* Change owner and group of the temporary output file to the original file's uid and gid. */
696      /* Required when a different user (e.g. root) has write permission on the original file. */
697      /* Make sure that the original owner can still access the file. */
698      if (chown(TempPath, StatBuf.st_uid, StatBuf.st_gid))
699      {
700         if (!ipFlag->Quiet)
701         {
702           ipFlag->error = errno;
703           errstr = strerror(errno);
704           fprintf(stderr, "%s: ", progname);
705           fprintf(stderr, _("Failed to change the owner and group of temporary output file %s: %s\n"), TempPath, errstr);
706         }
707         RetVal = -1;
708      }
709   }
710 #endif
711
712   if ((!RetVal) && (ipFlag->KeepDate))
713   {
714     UTimeBuf.actime = StatBuf.st_atime;
715     UTimeBuf.modtime = StatBuf.st_mtime;
716     /* can change output file time to in file time? */
717     if (utime(TempPath, &UTimeBuf) == -1)
718     {
719       if (!ipFlag->Quiet)
720       {
721         ipFlag->error = errno;
722         errstr = strerror(errno);
723         fprintf(stderr, "%s: %s: %s\n", progname, TempPath, errstr);
724       }
725       RetVal = -1;
726     }
727   }
728
729   /* any error? cleanup the temp file */
730   if (RetVal && (TempPath != NULL))
731   {
732     if (unlink(TempPath) && (errno != ENOENT))
733     {
734       if (!ipFlag->Quiet)
735       {
736         ipFlag->error = errno;
737         errstr = strerror(errno);
738         fprintf(stderr, "%s: %s: %s\n", progname, TempPath, errstr);
739       }
740       RetVal = -1;
741     }
742   }
743
744   /* If output file is a symbolic link, optional resolve the link and modify  */
745   /* the target, instead of removing the link and creating a new regular file */
746   TargetFN = ipOutFN;
747   if (symbolic_link(ipOutFN) && !RetVal)
748   {
749     ResolveSymlinkResult = 0; /* indicates that TargetFN need not be freed */
750     if (ipFlag->Follow == SYMLINK_FOLLOW)
751     {
752       ResolveSymlinkResult = ResolveSymbolicLink(ipOutFN, &TargetFN, ipFlag, progname);
753       if (ResolveSymlinkResult < 0)
754       {
755         if (!ipFlag->Quiet)
756         {
757           fprintf(stderr, "%s: ", progname);
758           fprintf(stderr, _("problems resolving symbolic link '%s'\n"), ipOutFN);
759           fprintf(stderr, _("          output file remains in '%s'\n"), TempPath);
760         }
761         RetVal = -1;
762       }
763     }
764   }
765
766   /* can rename temporary file to output file? */
767   if (!RetVal)
768   {
769 #ifdef NEED_REMOVE
770     if (unlink(TargetFN) && (errno != ENOENT))
771     {
772       if (!ipFlag->Quiet)
773       {
774         ipFlag->error = errno;
775         errstr = strerror(errno);
776         fprintf(stderr, "%s: %s: %s\n", progname, TargetFN, errstr);
777       }
778       RetVal = -1;
779     }
780 #endif
781     if (rename(TempPath, TargetFN) == -1)
782     {
783       if (!ipFlag->Quiet)
784       {
785         ipFlag->error = errno;
786         errstr = strerror(errno);
787         fprintf(stderr, "%s: ", progname);
788         fprintf(stderr, _("problems renaming '%s' to '%s': %s\n"), TempPath, TargetFN, errstr);
789 #ifdef S_ISLNK
790         if (ResolveSymlinkResult > 0)
791           fprintf(stderr, _("          which is the target of symbolic link '%s'\n"), ipOutFN);
792 #endif
793         fprintf(stderr, _("          output file remains in '%s'\n"), TempPath);
794       }
795       RetVal = -1;
796     }
797
798     if (ResolveSymlinkResult > 0)
799       free(TargetFN);
800   }
801   free(TempPath);
802   return RetVal;
803 }
804
805 /* convert stdin to DOS format text and write to stdout
806  * RetVal: 0 if success
807  *         -1 otherwise
808  */
809 int ConvertUnixToDosStdio(CFlag *ipFlag, char *progname)
810 {
811     ipFlag->NewFile = 1;
812     ipFlag->Quiet = 1;
813     ipFlag->KeepDate = 0;
814     ipFlag->Force = 1;
815
816 #if defined(_WIN32) && !defined(__CYGWIN__)
817
818     /* stdin and stdout are by default text streams. We need
819      * to set them to binary mode. Otherwise an LF will
820      * automatically be converted to CR-LF on DOS/Windows.
821      * Erwin */
822
823     /* POSIX 'setmode' was deprecated by MicroSoft since
824      * Visual C++ 2005. Use ISO C++ conformant '_setmode' instead. */
825
826     _setmode(_fileno(stdout), _O_BINARY);
827     _setmode(_fileno(stdin), _O_BINARY);
828 #elif defined(__MSDOS__) || defined(__CYGWIN__) || defined(__OS2__)
829     setmode(fileno(stdout), O_BINARY);
830     setmode(fileno(stdin), O_BINARY);
831 #endif
832
833     read_bom(stdin, &ipFlag->bomtype);
834 #ifdef D2U_UNICODE
835     if ((ipFlag->bomtype == FILE_MBS) && (ipFlag->ConvMode == CONVMODE_UTF16LE))
836       ipFlag->bomtype = FILE_UTF16LE;
837     if ((ipFlag->bomtype == FILE_MBS) && (ipFlag->ConvMode == CONVMODE_UTF16BE))
838       ipFlag->bomtype = FILE_UTF16BE;
839 #endif
840
841     if ((ipFlag->add_bom) || (ipFlag->bomtype > 0))
842        fprintf(stdout, "%s", "\xEF\xBB\xBF");  /* UTF-8 BOM */
843
844 #ifdef D2U_UNICODE
845     if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
846     {
847        return (ConvertUnixToDosW(stdin, stdout, ipFlag, progname));
848     } else {
849        return (ConvertUnixToDos(stdin, stdout, ipFlag, progname));
850     }
851 #else
852     return (ConvertUnixToDos(stdin, stdout, ipFlag, progname));
853 #endif
854 }
855
856
857 int main (int argc, char *argv[])
858 {
859   /* variable declarations */
860   char progname[9];
861   int ArgIdx;
862   int CanSwitchFileMode;
863   int ShouldExit;
864   int RetVal = 0;
865   int process_options = 1;
866   CFlag *pFlag;
867   char *ptr;
868 #ifdef ENABLE_NLS
869   char localedir[1024];
870 #endif
871 # ifdef __MINGW64__
872   int _dowildcard = -1; /* enable wildcard expansion for Win64 */
873 # endif
874
875   progname[8] = '\0';
876   strcpy(progname,"unix2dos");
877
878 #ifdef ENABLE_NLS
879    ptr = getenv("DOS2UNIX_LOCALEDIR");
880    if (ptr == NULL)
881       strcpy(localedir,LOCALEDIR);
882    else
883    {
884       if (strlen(ptr) < sizeof(localedir))
885          strcpy(localedir,ptr);
886       else
887       {
888          fprintf(stderr,"%s: ",progname);
889          fprintf(stderr, "%s", _("error: Value of environment variable DOS2UNIX_LOCALEDIR is too long.\n"));
890          strcpy(localedir,LOCALEDIR);
891       }
892    }
893 #endif
894
895 #if defined(ENABLE_NLS) || (defined(D2U_UNICODE) && !defined(__MSDOS__) && !defined(_WIN32) && !defined(__OS2__))
896 /* setlocale() is also needed for nl_langinfo() */
897    setlocale (LC_ALL, "");
898 #endif
899
900 #ifdef ENABLE_NLS
901    bindtextdomain (PACKAGE, localedir);
902    textdomain (PACKAGE);
903 #endif
904
905
906   /* variable initialisations */
907   ArgIdx = 0;
908   CanSwitchFileMode = 1;
909   ShouldExit = 0;
910   pFlag = (CFlag*)malloc(sizeof(CFlag));
911   pFlag->NewFile = 0;
912   pFlag->Quiet = 0;
913   pFlag->KeepDate = 0;
914   pFlag->ConvMode = CONVMODE_ASCII;  /* default ascii */
915   pFlag->FromToMode = FROMTO_UNIX2DOS;  /* default unix2dos */
916   pFlag->NewLine = 0;
917   pFlag->Force = 0;
918   pFlag->Follow = SYMLINK_SKIP;
919   pFlag->status = 0;
920   pFlag->stdio_mode = 1;
921   pFlag->error = 0;
922 #ifdef D2U_UNICODE
923   pFlag->bomtype = FILE_MBS;
924 #endif
925   pFlag->add_bom = 0;
926
927   if ( ((ptr=strrchr(argv[0],'/')) == NULL) && ((ptr=strrchr(argv[0],'\\')) == NULL) )
928     ptr = argv[0];
929   else
930     ptr++;
931
932   if ((strcmpi("unix2mac", ptr) == 0) || (strcmpi("unix2mac.exe", ptr) == 0))
933   {
934     pFlag->FromToMode = FROMTO_UNIX2MAC;
935     strcpy(progname,"unix2mac");
936   }
937
938   while ((++ArgIdx < argc) && (!ShouldExit))
939   {
940     /* is it an option? */
941     if ((argv[ArgIdx][0] == '-') && process_options)
942     {
943       /* an option */
944       if (strcmp(argv[ArgIdx],"--") == 0)
945         process_options = 0;
946       else if ((strcmp(argv[ArgIdx],"-h") == 0) || (strcmp(argv[ArgIdx],"--help") == 0))
947       {
948         PrintUsage(progname);
949         return(pFlag->error);
950       }
951       else if ((strcmp(argv[ArgIdx],"-k") == 0) || (strcmp(argv[ArgIdx],"--keepdate") == 0))
952         pFlag->KeepDate = 1;
953       else if ((strcmp(argv[ArgIdx],"-f") == 0) || (strcmp(argv[ArgIdx],"--force") == 0))
954         pFlag->Force = 1;
955       else if ((strcmp(argv[ArgIdx],"-s") == 0) || (strcmp(argv[ArgIdx],"--safe") == 0))
956         pFlag->Force = 0;
957       else if ((strcmp(argv[ArgIdx],"-q") == 0) || (strcmp(argv[ArgIdx],"--quiet") == 0))
958         pFlag->Quiet = 1;
959       else if ((strcmp(argv[ArgIdx],"-l") == 0) || (strcmp(argv[ArgIdx],"--newline") == 0))
960         pFlag->NewLine = 1;
961       else if ((strcmp(argv[ArgIdx],"-m") == 0) || (strcmp(argv[ArgIdx],"--add-bom") == 0))
962         pFlag->add_bom = 1;
963       else if ((strcmp(argv[ArgIdx],"-S") == 0) || (strcmp(argv[ArgIdx],"--skip-symlink") == 0))
964         pFlag->Follow = SYMLINK_SKIP;
965       else if ((strcmp(argv[ArgIdx],"-F") == 0) || (strcmp(argv[ArgIdx],"--follow-symlink") == 0))
966         pFlag->Follow = SYMLINK_FOLLOW;
967       else if ((strcmp(argv[ArgIdx],"-R") == 0) || (strcmp(argv[ArgIdx],"--replace-symlink") == 0))
968         pFlag->Follow = SYMLINK_REPLACE;
969       else if ((strcmp(argv[ArgIdx],"-V") == 0) || (strcmp(argv[ArgIdx],"--version") == 0))
970       {
971         PrintVersion(progname);
972 #ifdef ENABLE_NLS
973         PrintLocaledir(localedir);
974 #endif
975         return(pFlag->error);
976       }
977       else if ((strcmp(argv[ArgIdx],"-L") == 0) || (strcmp(argv[ArgIdx],"--license") == 0))
978       {
979         PrintLicense();
980         return(pFlag->error);
981       }
982       else if (strcmp(argv[ArgIdx],"-ascii") == 0)  /* SunOS compatible options */
983         pFlag->ConvMode = CONVMODE_ASCII;
984       else if (strcmp(argv[ArgIdx],"-7") == 0)
985         pFlag->ConvMode = CONVMODE_7BIT;
986       else if (strcmp(argv[ArgIdx],"-iso") == 0)
987       {
988         pFlag->ConvMode = (int)query_con_codepage();
989         if (!pFlag->Quiet)
990         {
991            fprintf(stderr,"%s: ",progname);
992            fprintf(stderr,_("active code page: %d\n"), pFlag->ConvMode);
993         }
994         if (pFlag->ConvMode < 2)
995            pFlag->ConvMode = CONVMODE_437;
996       }
997       else if (strcmp(argv[ArgIdx],"-437") == 0)
998         pFlag->ConvMode = CONVMODE_437;
999       else if (strcmp(argv[ArgIdx],"-850") == 0)
1000         pFlag->ConvMode = CONVMODE_850;
1001       else if (strcmp(argv[ArgIdx],"-860") == 0)
1002         pFlag->ConvMode = CONVMODE_860;
1003       else if (strcmp(argv[ArgIdx],"-863") == 0)
1004         pFlag->ConvMode = CONVMODE_863;
1005       else if (strcmp(argv[ArgIdx],"-865") == 0)
1006         pFlag->ConvMode = CONVMODE_865;
1007       else if (strcmp(argv[ArgIdx],"-1252") == 0)
1008         pFlag->ConvMode = CONVMODE_1252;
1009 #ifdef D2U_UNICODE
1010       else if ((strcmp(argv[ArgIdx],"-ul") == 0) || (strcmp(argv[ArgIdx],"--assume-utf16le") == 0))
1011         pFlag->ConvMode = CONVMODE_UTF16LE;
1012       else if ((strcmp(argv[ArgIdx],"-ub") == 0) || (strcmp(argv[ArgIdx],"--assume-utf16be") == 0))
1013         pFlag->ConvMode = CONVMODE_UTF16BE;
1014 #endif
1015       else if ((strcmp(argv[ArgIdx],"-c") == 0) || (strcmp(argv[ArgIdx],"--convmode") == 0))
1016       {
1017         if (++ArgIdx < argc)
1018         {
1019           if (strcmpi(argv[ArgIdx],"ascii") == 0)  /* Benjamin Lin's legacy options */
1020             pFlag->ConvMode = CONVMODE_ASCII;
1021           else if (strcmpi(argv[ArgIdx], "7bit") == 0)
1022             pFlag->ConvMode = CONVMODE_7BIT;
1023           else if (strcmpi(argv[ArgIdx], "iso") == 0)
1024           {
1025             pFlag->ConvMode = (int)query_con_codepage();
1026             if (!pFlag->Quiet)
1027             {
1028                fprintf(stderr,"%s: ",progname);
1029                fprintf(stderr,_("active code page: %d\n"), pFlag->ConvMode);
1030             }
1031             if (pFlag->ConvMode < 2)
1032                pFlag->ConvMode = CONVMODE_437;
1033           }
1034           else if (strcmpi(argv[ArgIdx], "mac") == 0)
1035             pFlag->FromToMode = FROMTO_UNIX2MAC;
1036           else
1037           {
1038             fprintf(stderr,"%s: ",progname);
1039             fprintf(stderr, _("invalid %s conversion mode specified\n"),argv[ArgIdx]);
1040             pFlag->error = 1;
1041             ShouldExit = 1;
1042             pFlag->stdio_mode = 0;
1043           }
1044         }
1045         else
1046         {
1047           ArgIdx--;
1048           fprintf(stderr,"%s: ",progname);
1049           fprintf(stderr,_("option '%s' requires an argument\n"),argv[ArgIdx]);
1050           pFlag->error = 1;
1051           ShouldExit = 1;
1052           pFlag->stdio_mode = 0;
1053         }
1054       }
1055
1056       else if ((strcmp(argv[ArgIdx],"-o") == 0) || (strcmp(argv[ArgIdx],"--oldfile") == 0))
1057       {
1058         /* last convert not paired */
1059         if (!CanSwitchFileMode)
1060         {
1061           fprintf(stderr,"%s: ",progname);
1062           fprintf(stderr, _("target of file %s not specified in new-file mode\n"), argv[ArgIdx-1]);
1063           pFlag->error = 1;
1064           ShouldExit = 1;
1065           pFlag->stdio_mode = 0;
1066         }
1067         pFlag->NewFile = 0;
1068       }
1069
1070       else if ((strcmp(argv[ArgIdx],"-n") == 0) || (strcmp(argv[ArgIdx],"--newfile") == 0))
1071       {
1072         /* last convert not paired */
1073         if (!CanSwitchFileMode)
1074         {
1075           fprintf(stderr,"%s: ",progname);
1076           fprintf(stderr, _("target of file %s not specified in new-file mode\n"), argv[ArgIdx-1]);
1077           pFlag->error = 1;
1078           ShouldExit = 1;
1079           pFlag->stdio_mode = 0;
1080         }
1081         pFlag->NewFile = 1;
1082       }
1083       else { /* wrong option */
1084         PrintUsage(progname);
1085         ShouldExit = 1;
1086         pFlag->error = 1;
1087         pFlag->stdio_mode = 0;
1088       }
1089     }
1090     else
1091     {
1092       pFlag->stdio_mode = 0;
1093       /* not an option */
1094       if (pFlag->NewFile)
1095       {
1096         if (CanSwitchFileMode)
1097           CanSwitchFileMode = 0;
1098         else
1099         {
1100           RetVal = ConvertUnixToDosNewFile(argv[ArgIdx-1], argv[ArgIdx], pFlag, progname);
1101           if (pFlag->status & NO_REGFILE)
1102           {
1103             if (!pFlag->Quiet)
1104             {
1105               fprintf(stderr,"%s: ",progname);
1106               fprintf(stderr, _("Skipping %s, not a regular file.\n"), argv[ArgIdx-1]);
1107             }
1108           } else if (pFlag->status & OUTPUTFILE_SYMLINK)
1109           {
1110             if (!pFlag->Quiet)
1111             {
1112               fprintf(stderr,"%s: ",progname);
1113               fprintf(stderr, _("Skipping %s, output file %s is a symbolic link.\n"), argv[ArgIdx-1], argv[ArgIdx]);
1114             }
1115           } else if (pFlag->status & INPUT_TARGET_NO_REGFILE)
1116           {
1117             if (!pFlag->Quiet)
1118             {
1119               fprintf(stderr,"%s: ",progname);
1120               fprintf(stderr, _("Skipping symbolic link %s, target is not a regular file.\n"), argv[ArgIdx-1]);
1121             }
1122           } else if (pFlag->status & OUTPUT_TARGET_NO_REGFILE)
1123           {
1124             if (!pFlag->Quiet)
1125             {
1126               fprintf(stderr,"%s: ",progname);
1127               fprintf(stderr, _("Skipping %s, target of symbolic link %s is not a regular file.\n"), argv[ArgIdx-1], argv[ArgIdx]);
1128             }
1129           } else if (pFlag->status & BINARY_FILE)
1130           {
1131             if (!pFlag->Quiet)
1132             {
1133               fprintf(stderr,"%s: ",progname);
1134               fprintf(stderr, _("Skipping binary file %s\n"), argv[ArgIdx-1]);
1135             }
1136           } else if (pFlag->status & WRONG_CODEPAGE)
1137           {
1138             if (!pFlag->Quiet)
1139             {
1140               fprintf(stderr,"%s: ",progname);
1141               fprintf(stderr, _("code page %d is not supported.\n"), pFlag->ConvMode);
1142             }
1143           } else if (pFlag->status & LOCALE_NOT_UTF8)
1144           {
1145             if (!pFlag->Quiet)
1146             {
1147               fprintf(stderr,"%s: ",progname);
1148               fprintf(stderr, _("Skipping UTF-16 file %s, the current locale character encoding is not UTF-8.\n"), argv[ArgIdx-1]);
1149             }
1150           } else if (pFlag->status & WCHAR_T_TOO_SMALL)
1151           {
1152             if (!pFlag->Quiet)
1153             {
1154               fprintf(stderr,"%s: ",progname);
1155               fprintf(stderr, _("Skipping UTF-16 file %s, the size of wchar_t is %d bytes.\n"), argv[ArgIdx-1], (int)sizeof(wchar_t));
1156             }
1157           } else if (pFlag->status & UNICODE_CONVERSION_ERROR)
1158           {
1159             if (!pFlag->Quiet)
1160             {
1161               fprintf(stderr,"%s: ",progname);
1162               fprintf(stderr, _("Skipping UTF-16 file %s, an UTF-16 conversion error occurred.\n"), argv[ArgIdx-1]);
1163             }
1164           } else {
1165             if (!pFlag->Quiet)
1166             {
1167               fprintf(stderr,"%s: ",progname);
1168               if (pFlag->FromToMode == FROMTO_UNIX2MAC)
1169                 fprintf(stderr, _("converting file %s to file %s in Mac format...\n"), argv[ArgIdx-1], argv[ArgIdx]);
1170               else
1171                 fprintf(stderr, _("converting file %s to file %s in DOS format...\n"), argv[ArgIdx-1], argv[ArgIdx]);
1172             }
1173             if (RetVal)
1174             {
1175               if (!pFlag->Quiet)
1176               {
1177                 fprintf(stderr,"%s: ",progname);
1178                 fprintf(stderr, _("problems converting file %s to file %s\n"), argv[ArgIdx-1], argv[ArgIdx]);
1179               }
1180             }
1181           }
1182           CanSwitchFileMode = 1;
1183         }
1184       }
1185       else
1186       {
1187         RetVal = ConvertUnixToDosNewFile(argv[ArgIdx], argv[ArgIdx], pFlag, progname);
1188         if (pFlag->status & NO_REGFILE)
1189         {
1190           if (!pFlag->Quiet)
1191           {
1192             fprintf(stderr,"%s: ",progname);
1193             fprintf(stderr, _("Skipping %s, not a regular file.\n"), argv[ArgIdx]);
1194           }
1195         } else if (pFlag->status & OUTPUTFILE_SYMLINK)
1196         {
1197           if (!pFlag->Quiet)
1198           {
1199             fprintf(stderr,"%s: ",progname);
1200             fprintf(stderr, _("Skipping symbolic link %s.\n"), argv[ArgIdx]);
1201           }
1202         } else if (pFlag->status & INPUT_TARGET_NO_REGFILE)
1203         {
1204           if (!pFlag->Quiet)
1205           {
1206             fprintf(stderr,"%s: ",progname);
1207             fprintf(stderr, _("Skipping symbolic link %s, target is not a regular file.\n"), argv[ArgIdx]);
1208           }
1209         } else if (pFlag->status & BINARY_FILE)
1210         {
1211           if (!pFlag->Quiet)
1212           {
1213             fprintf(stderr,"%s: ",progname);
1214             fprintf(stderr, _("Skipping binary file %s\n"), argv[ArgIdx]);
1215           }
1216         } else if (pFlag->status & WRONG_CODEPAGE)
1217         {
1218           if (!pFlag->Quiet)
1219           {
1220             fprintf(stderr,"%s: ",progname);
1221             fprintf(stderr, _("code page %d is not supported.\n"), pFlag->ConvMode);
1222           }
1223         } else if (pFlag->status & LOCALE_NOT_UTF8)
1224         {
1225           if (!pFlag->Quiet)
1226           {
1227             fprintf(stderr,"%s: ",progname);
1228             fprintf(stderr, _("Skipping UTF-16 file %s, the current locale character encoding is not UTF-8.\n"), argv[ArgIdx]);
1229           }
1230         } else if (pFlag->status & WCHAR_T_TOO_SMALL)
1231         {
1232           if (!pFlag->Quiet)
1233           {
1234             fprintf(stderr,"%s: ",progname);
1235             fprintf(stderr, _("Skipping UTF-16 file %s, the size of wchar_t is %d bytes.\n"), argv[ArgIdx], (int)sizeof(wchar_t));
1236           }
1237         } else if (pFlag->status & UNICODE_CONVERSION_ERROR)
1238         {
1239           if (!pFlag->Quiet)
1240           {
1241             fprintf(stderr,"%s: ",progname);
1242             fprintf(stderr, _("Skipping UTF-16 file %s, an UTF-16 conversion error occurred.\n"), argv[ArgIdx]);
1243           }
1244         } else {
1245           if (!pFlag->Quiet)
1246           {
1247             fprintf(stderr,"%s: ",progname);
1248             if (pFlag->FromToMode == FROMTO_UNIX2MAC)
1249               fprintf(stderr, _("converting file %s to Mac format...\n"), argv[ArgIdx]);
1250             else
1251               fprintf(stderr, _("converting file %s to DOS format...\n"), argv[ArgIdx]);
1252           }
1253           if (RetVal)
1254           {
1255             if (!pFlag->Quiet)
1256             {
1257               fprintf(stderr,"%s: ",progname);
1258               fprintf(stderr, _("problems converting file %s\n"), argv[ArgIdx]);
1259             }
1260           }
1261         }
1262       }
1263     }
1264   }
1265
1266   /* no file argument, use stdin and stdout */
1267   if (pFlag->stdio_mode)
1268   {
1269     exit(ConvertUnixToDosStdio(pFlag, progname));
1270   }
1271
1272
1273   if (!CanSwitchFileMode)
1274   {
1275     fprintf(stderr,"%s: ",progname);
1276     fprintf(stderr, _("target of file %s not specified in new-file mode\n"), argv[ArgIdx-1]);
1277     pFlag->error = 1;
1278   }
1279   return (pFlag->error);
1280 }
1281