4 * Remove cr ('\x0d') characters from a file.
6 * The dos2unix package is distributed under FreeBSD style license.
7 * See also http://www.freebsd.org/copyright/freebsd-license.html
10 * Copyright (C) 2009-2012 Erwin Waterlander
11 * Copyright (C) 1998 Christian Wurll
12 * Copyright (C) 1998 Bernd Johannes Wuebben
13 * Copyright (C) 1994-1995 Benjamin Lin.
14 * All rights reserved.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice in the documentation and/or other materials provided with
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
26 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
31 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
34 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
35 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 * == 1.0 == 1989.10.04 == John Birchfield (jb@koko.csustan.edu)
38 * == 1.1 == 1994.12.20 == Benjamin Lin (blin@socs.uts.edu.au)
39 * Cleaned up for Borland C/C++ 4.02
40 * == 1.2 == 1995.03.16 == Benjamin Lin (blin@socs.uts.edu.au)
41 * Modified to more conform to UNIX style.
42 * == 2.0 == 1995.03.19 == Benjamin Lin (blin@socs.uts.edu.au)
43 * Rewritten from scratch.
44 * == 2.1 == 1995.03.29 == Benjamin Lin (blin@socs.uts.edu.au)
45 * Conversion to SunOS charset implemented.
46 * == 2.2 == 1995.03.30 == Benjamin Lin (blin@socs.uts.edu.au)
47 * Fixed a bug in 2.1 where in new file mode, if outfile already exists
48 * conversion can not be completed properly.
50 * Added Mac text file translation, i.e. \r to \n conversion
51 * Bernd Johannes Wuebben, wuebben@kde.org
52 * Wed Feb 4 19:12:58 EST 1998
54 * Added extra newline if ^M occurs
55 * Christian Wurll, wurll@ira.uka.de
58 * See ChangeLog.txt for complete version history.
69 #ifndef MSDOS /* Unix, Cygwin */
70 # include <langinfo.h>
74 void PrintLicense(void)
76 fprintf(stderr, "%s", _("\
77 Copyright (C) 2009-2012 Erwin Waterlander\n\
78 Copyright (C) 1998 Christian Wurll (Version 3.1)\n\
79 Copyright (C) 1998 Bernd Johannes Wuebben (Version 3.0)\n\
80 Copyright (C) 1994-1995 Benjamin Lin\n\
81 All rights reserved.\n\n"));
86 void StripDelimiterW(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag, wint_t CurChar)
89 /* CurChar is always CR (x0d) */
90 /* In normal dos2unix mode put nothing (skip CR). */
91 /* Don't modify Mac files when in dos2unix mode. */
92 if ( (TempNextChar = d2u_getwc(ipInF, ipFlag->bomtype)) != WEOF) {
93 d2u_ungetwc( TempNextChar, ipInF, ipFlag->bomtype); /* put back peek char */
94 if ( TempNextChar != 0x0a ) {
95 d2u_putwc( CurChar, ipOutF, ipFlag); /* Mac line, put back CR */
98 else if ( CurChar == 0x0d ) { /* EOF: last Mac line delimiter (CR)? */
99 d2u_putwc( CurChar, ipOutF, ipFlag);
101 if (ipFlag->NewLine) { /* add additional LF? */
102 d2u_putwc(0x0a, ipOutF, ipFlag);
107 void StripDelimiter(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag, int CurChar)
110 /* CurChar is always CR (x0d) */
111 /* In normal dos2unix mode put nothing (skip CR). */
112 /* Don't modify Mac files when in dos2unix mode. */
113 if ( (TempNextChar = fgetc(ipInF)) != EOF) {
114 ungetc( TempNextChar, ipInF ); /* put back peek char */
115 if ( TempNextChar != '\x0a' ) {
116 fputc( CurChar, ipOutF ); /* Mac line, put back CR */
119 else if ( CurChar == '\x0d' ) { /* EOF: last Mac line delimiter (CR)? */
120 fputc( CurChar, ipOutF );
122 if (ipFlag->NewLine) { /* add additional LF? */
123 fputc('\x0a', ipOutF);
127 /* converts stream ipInF to UNIX format text and write to stream ipOutF
128 * RetVal: 0 if success
132 int ConvertDosToUnixW(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag, char *progname)
141 /* LF -> LF, in case the input file is a Unix text file */
142 /* CR -> CR, in dos2unix mode (don't modify Mac file) */
143 /* CR -> LF, in Mac mode */
144 /* \x0a = Newline/Line Feed (LF) */
145 /* \x0d = Carriage Return (CR) */
147 switch (ipFlag->FromToMode)
149 case FROMTO_DOS2UNIX: /* dos2unix */
150 while ((TempChar = d2u_getwc(ipInF, ipFlag->bomtype)) != WEOF) { /* get character */
151 if ((ipFlag->Force == 0) &&
153 (TempChar != 0x0a) && /* Not an LF */
154 (TempChar != 0x0d) && /* Not a CR */
155 (TempChar != 0x09) && /* Not a TAB */
156 (TempChar != 0x0c)) { /* Not a form feed */
158 ipFlag->status |= BINARY_FILE ;
161 if (TempChar != 0x0d) {
162 if (d2u_putwc(TempChar, ipOutF, ipFlag) == WEOF) {
166 if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
168 fprintf(stderr, "%s: ", progname);
169 fprintf(stderr, "%s", _("can not write to output file\n"));
175 StripDelimiterW( ipInF, ipOutF, ipFlag, TempChar );
179 case FROMTO_MAC2UNIX: /* mac2unix */
180 while ((TempChar = d2u_getwc(ipInF, ipFlag->bomtype)) != WEOF) {
181 if ((ipFlag->Force == 0) &&
183 (TempChar != 0x0a) && /* Not an LF */
184 (TempChar != 0x0d) && /* Not a CR */
185 (TempChar != 0x09) && /* Not a TAB */
186 (TempChar != 0x0c)) { /* Not a form feed */
188 ipFlag->status |= BINARY_FILE ;
191 if ((TempChar != 0x0d))
193 if(d2u_putwc(TempChar, ipOutF, ipFlag) == WEOF){
197 if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
199 fprintf(stderr, "%s: ", progname);
200 fprintf(stderr, "%s", _("can not write to output file\n"));
207 /* TempChar is a CR */
208 if ( (TempNextChar = d2u_getwc(ipInF, ipFlag->bomtype)) != WEOF) {
209 ungetc( TempNextChar, ipInF ); /* put back peek char */
210 /* Don't touch this delimiter if it's a CR,LF pair. */
211 if ( TempNextChar == 0x0a ) {
212 d2u_putwc(0x0d, ipOutF, ipFlag); /* put CR, part of DOS CR-LF */
216 if (d2u_putwc(0x0a, ipOutF, ipFlag) == WEOF) /* MAC line end (CR). Put LF */
221 if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
223 fprintf(stderr, "%s: ", progname);
224 fprintf(stderr, "%s", _("can not write to output file\n"));
229 if (ipFlag->NewLine) { /* add additional LF? */
230 d2u_putwc(0x0a, ipOutF, ipFlag);
235 default: /* unknown FromToMode */
238 fprintf(stderr, "%s: ", progname);
239 fprintf(stderr, _("program error, invalid conversion mode %d\n"),ipFlag->FromToMode);
247 /* converts stream ipInF to UNIX format text and write to stream ipOutF
248 * RetVal: 0 if success
251 int ConvertDosToUnix(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag, char *progname)
260 switch (ipFlag->ConvMode)
262 case CONVMODE_ASCII: /* ascii */
263 ConvTable = D2UAsciiTable;
265 case CONVMODE_7BIT: /* 7bit */
266 ConvTable = D2U7BitTable;
268 case CONVMODE_437: /* iso */
269 ConvTable = D2UIso437Table;
271 case CONVMODE_850: /* iso */
272 ConvTable = D2UIso850Table;
274 case CONVMODE_860: /* iso */
275 ConvTable = D2UIso860Table;
277 case CONVMODE_863: /* iso */
278 ConvTable = D2UIso863Table;
280 case CONVMODE_865: /* iso */
281 ConvTable = D2UIso865Table;
283 case CONVMODE_1252: /* iso */
284 ConvTable = D2UIso1252Table;
286 default: /* unknown convmode */
287 ipFlag->status |= WRONG_CODEPAGE ;
290 if ((ipFlag->ConvMode > 1) && (!ipFlag->Quiet)) /* not ascii or 7bit */
292 fprintf(stderr, "%s: ", progname);
293 fprintf(stderr, _("using code page %d.\n"), ipFlag->ConvMode);
297 /* LF -> LF, in case the input file is a Unix text file */
298 /* CR -> CR, in dos2unix mode (don't modify Mac file) */
299 /* CR -> LF, in Mac mode */
300 /* \x0a = Newline/Line Feed (LF) */
301 /* \x0d = Carriage Return (CR) */
303 switch (ipFlag->FromToMode)
305 case FROMTO_DOS2UNIX: /* dos2unix */
306 while ((TempChar = fgetc(ipInF)) != EOF) { /* get character */
307 if ((ipFlag->Force == 0) &&
309 (TempChar != '\x0a') && /* Not an LF */
310 (TempChar != '\x0d') && /* Not a CR */
311 (TempChar != '\x09') && /* Not a TAB */
312 (TempChar != '\x0c')) { /* Not a form feed */
314 ipFlag->status |= BINARY_FILE ;
317 if (TempChar != '\x0d') {
318 if (fputc(ConvTable[TempChar], ipOutF) == EOF) {
322 fprintf(stderr, "%s: ", progname);
323 fprintf(stderr, "%s", _("can not write to output file\n"));
328 StripDelimiter( ipInF, ipOutF, ipFlag, TempChar );
332 case FROMTO_MAC2UNIX: /* mac2unix */
333 while ((TempChar = fgetc(ipInF)) != EOF) {
334 if ((ipFlag->Force == 0) &&
336 (TempChar != '\x0a') && /* Not an LF */
337 (TempChar != '\x0d') && /* Not a CR */
338 (TempChar != '\x09') && /* Not a TAB */
339 (TempChar != '\x0c')) { /* Not a form feed */
341 ipFlag->status |= BINARY_FILE ;
344 if ((TempChar != '\x0d'))
346 if(fputc(ConvTable[TempChar], ipOutF) == EOF){
350 fprintf(stderr, "%s: ", progname);
351 fprintf(stderr, "%s", _("can not write to output file\n"));
357 /* TempChar is a CR */
358 if ( (TempNextChar = fgetc(ipInF)) != EOF) {
359 ungetc( TempNextChar, ipInF ); /* put back peek char */
360 /* Don't touch this delimiter if it's a CR,LF pair. */
361 if ( TempNextChar == '\x0a' ) {
362 fputc('\x0d', ipOutF); /* put CR, part of DOS CR-LF */
366 if (fputc('\x0a', ipOutF) == EOF) /* MAC line end (CR). Put LF */
371 fprintf(stderr, "%s: ", progname);
372 fprintf(stderr, "%s", _("can not write to output file\n"));
376 if (ipFlag->NewLine) { /* add additional LF? */
377 fputc('\x0a', ipOutF);
382 default: /* unknown FromToMode */
385 fprintf(stderr, "%s: ", progname);
386 fprintf(stderr, _("program error, invalid conversion mode %d\n"),ipFlag->FromToMode);
393 /* convert file ipInFN to UNIX format text and write to file ipOutFN
394 * RetVal: 0 if success
397 int ConvertDosToUnixNewFile(char *ipInFN, char *ipOutFN, CFlag *ipFlag, char *progname)
405 struct utimbuf UTimeBuf;
414 char *TargetFN = NULL;
415 int ResolveSymlinkResult = 0;
419 /* Test if output file is a symbolic link */
420 if (symbolic_link(ipOutFN) && !ipFlag->Follow)
422 ipFlag->status |= OUTPUTFILE_SYMLINK ;
423 /* Not a failure, skipping input file according spec. (keep symbolic link unchanged) */
427 /* Test if input file is a regular file or symbolic link */
428 if (regfile(ipInFN, 1, ipFlag, progname))
430 ipFlag->status |= NO_REGFILE ;
431 /* Not a failure, skipping non-regular input file according spec. */
435 /* Test if input file target is a regular file */
436 if (symbolic_link(ipInFN) && regfile_target(ipInFN, ipFlag,progname))
438 ipFlag->status |= INPUT_TARGET_NO_REGFILE ;
439 /* Not a failure, skipping non-regular input file according spec. */
443 /* Test if output file target is a regular file */
444 if (symbolic_link(ipOutFN) && (ipFlag->Follow == SYMLINK_FOLLOW) && regfile_target(ipOutFN, ipFlag,progname))
446 ipFlag->status |= OUTPUT_TARGET_NO_REGFILE ;
447 /* Failure, input is regular, cannot produce output. */
448 if (!ipFlag->error) ipFlag->error = 1;
452 /* retrieve ipInFN file date stamp */
453 if (stat(ipInFN, &StatBuf))
457 ipFlag->error = errno;
458 errstr = strerror(errno);
459 fprintf(stderr, "%s: %s: %s\n", progname, ipInFN, errstr);
465 if((fd = MakeTempFileFrom(ipOutFN, &TempPath))==NULL) {
467 if((fd = MakeTempFileFrom (ipOutFN, &TempPath)) < 0) {
471 ipFlag->error = errno;
472 errstr = strerror(errno);
473 fprintf(stderr, "%s: ", progname);
474 fprintf(stderr, _("Failed to open temporary output file: %s\n"), errstr);
480 fprintf(stderr, "%s: ", progname);
481 fprintf(stderr, _("using %s as temporary file\n"), TempPath);
484 /* can open in file? */
487 InF=OpenInFile(ipInFN);
490 ipFlag->error = errno;
491 errstr = strerror(errno);
492 fprintf(stderr, "%s: %s: %s\n", progname, ipInFN, errstr);
497 /* can open output file? */
498 if ((!RetVal) && (InF))
501 if ((TempF=fd) == NULL)
504 if ((TempF=OpenOutFile(fd)) == NULL)
506 ipFlag->error = errno;
507 errstr = strerror(errno);
508 fprintf(stderr, "%s: %s\n", progname, errstr);
516 InF = read_bom(InF, &ipFlag->bomtype);
519 #ifndef MSDOS /* Unix, Cygwin */
520 if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
522 if (strcmp(nl_langinfo(CODESET), "UTF-8") != 0)
524 /* Don't convert UTF-16 files when the locale encoding is not UTF-8
525 * to prevent loss of characters. */
526 ipFlag->status |= LOCALE_NOT_UTF8 ;
527 if (!ipFlag->error) ipFlag->error = 1;
532 #if !defined(WIN32) && !defined(__CYGWIN__) /* Not Windows or Cygwin */
533 if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
535 if (sizeof(wchar_t) < 4)
537 /* A decoded UTF-16 surrogate pair must fit in a wchar_t */
538 ipFlag->status |= WCHAR_T_TOO_SMALL ;
539 if (!ipFlag->error) ipFlag->error = 1;
547 fprintf(TempF, "%s", "\xEF\xBB\xBF"); /* UTF-8 BOM */
549 /* Turn off ISO and 7-bit conversion for Unicode text files */
550 if (ipFlag->bomtype > 0)
551 ipFlag->ConvMode = CONVMODE_ASCII;
553 /* conversion sucessful? */
555 if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
557 if ((!RetVal) && (ConvertDosToUnixW(InF, TempF, ipFlag, progname)))
559 if (ipFlag->status & UNICODE_CONVERSION_ERROR)
561 if (!ipFlag->error) ipFlag->error = 1;
565 if ((!RetVal) && (ConvertDosToUnix(InF, TempF, ipFlag, progname)))
569 if ((!RetVal) && (ConvertDosToUnix(InF, TempF, ipFlag, progname)))
573 /* can close in file? */
574 if ((InF) && (fclose(InF) == EOF))
577 /* can close output file? */
578 if ((TempF) && (fclose(TempF) == EOF))
592 if (ipFlag->NewFile == 0) /* old file mode */
594 RetVal = chmod (TempPath, StatBuf.st_mode); /* set original permissions */
598 mask = umask(0); /* get process's umask */
599 umask(mask); /* set umask back to original */
600 RetVal = chmod(TempPath, StatBuf.st_mode & ~mask); /* set original permissions, minus umask */
607 ipFlag->error = errno;
608 errstr = strerror(errno);
609 fprintf(stderr, "%s: ", progname);
610 fprintf(stderr, _("Failed to change the permissions of temporary output file %s: %s\n"), TempPath, errstr);
617 if (!RetVal && (ipFlag->NewFile == 0)) /* old file mode */
619 /* Change owner and group of the the tempory output file to the original file's uid and gid. */
620 /* Required when a different user (e.g. root) has write permission on the original file. */
621 /* Make sure that the original owner can still access the file. */
622 if (chown(TempPath, StatBuf.st_uid, StatBuf.st_gid))
626 ipFlag->error = errno;
627 errstr = strerror(errno);
628 fprintf(stderr, "%s: ", progname);
629 fprintf(stderr, _("Failed to change the owner and group of temporary output file %s: %s\n"), TempPath, errstr);
636 if ((!RetVal) && (ipFlag->KeepDate))
638 UTimeBuf.actime = StatBuf.st_atime;
639 UTimeBuf.modtime = StatBuf.st_mtime;
640 /* can change output file time to in file time? */
641 if (utime(TempPath, &UTimeBuf) == -1)
645 ipFlag->error = errno;
646 errstr = strerror(errno);
647 fprintf(stderr, "%s: %s: %s\n", progname, TempPath, errstr);
653 /* any error? cleanup the temp file */
654 if (RetVal && (TempPath != NULL))
656 if (unlink(TempPath) && (errno != ENOENT))
660 ipFlag->error = errno;
661 errstr = strerror(errno);
662 fprintf(stderr, "%s: %s: %s\n", progname, TempPath, errstr);
668 /* If output file is a symbolic link, optional resolve the link and modify */
669 /* the target, instead of removing the link and creating a new regular file */
671 if (symbolic_link(ipOutFN) && !RetVal)
673 ResolveSymlinkResult = 0; /* indicates that TargetFN need not be freed */
674 if (ipFlag->Follow == SYMLINK_FOLLOW)
676 ResolveSymlinkResult = ResolveSymbolicLink(ipOutFN, &TargetFN, ipFlag, progname);
677 if (ResolveSymlinkResult < 0)
681 fprintf(stderr, "%s: ", progname);
682 fprintf(stderr, _("problems resolving symbolic link '%s'\n"), ipOutFN);
683 fprintf(stderr, _(" output file remains in '%s'\n"), TempPath);
690 /* can rename temporary file to output file? */
694 if (unlink(TargetFN) && (errno != ENOENT))
698 ipFlag->error = errno;
699 errstr = strerror(errno);
700 fprintf(stderr, "%s: %s: %s\n", progname, TargetFN, errstr);
705 if (rename(TempPath, TargetFN) == -1)
709 ipFlag->error = errno;
710 errstr = strerror(errno);
711 fprintf(stderr, "%s: ", progname);
712 fprintf(stderr, _("problems renaming '%s' to '%s': %s\n"), TempPath, TargetFN, errstr);
714 if (ResolveSymlinkResult > 0)
715 fprintf(stderr, _(" which is the target of symbolic link '%s'\n"), ipOutFN);
717 fprintf(stderr, _(" output file remains in '%s'\n"), TempPath);
722 if (ResolveSymlinkResult > 0)
729 /* convert stdin to UNIX format text and write to stdout
730 * RetVal: 0 if success
733 int ConvertDosToUnixStdio(CFlag *ipFlag, char *progname)
737 ipFlag->KeepDate = 0;
740 #if defined(WIN32) && !defined(__CYGWIN__)
742 /* stdin and stdout are by default text streams. We need
743 * to set them to binary mode. Otherwise an LF will
744 * automatically be converted to CR-LF on DOS/Windows.
747 /* 'setmode' was deprecated by MicroSoft
748 * since Visual C++ 2005. Use '_setmode' instead. */
750 _setmode(fileno(stdout), O_BINARY);
751 _setmode(fileno(stdin), O_BINARY);
752 #elif defined(MSDOS) || defined(__CYGWIN__) || defined(__OS2__)
753 setmode(fileno(stdout), O_BINARY);
754 setmode(fileno(stdin), O_BINARY);
757 read_bom(stdin, &ipFlag->bomtype);
760 fprintf(stdout, "%s", "\xEF\xBB\xBF"); /* UTF-8 BOM */
763 if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
765 return (ConvertDosToUnixW(stdin, stdout, ipFlag, progname));
767 return (ConvertDosToUnix(stdin, stdout, ipFlag, progname));
770 return (ConvertDosToUnix(stdin, stdout, ipFlag, progname));
775 int main (int argc, char *argv[])
777 /* variable declarations */
780 int CanSwitchFileMode;
783 int process_options = 1;
787 char localedir[1024];
790 int _dowildcard = -1; /* enable wildcard expansion for Win64 */
794 strcpy(progname,"dos2unix");
797 ptr = getenv("DOS2UNIX_LOCALEDIR");
799 strcpy(localedir,LOCALEDIR);
802 if (strlen(ptr) < sizeof(localedir))
803 strcpy(localedir,ptr);
806 fprintf(stderr,"%s: ",progname);
807 fprintf(stderr, "%s", _("error: Value of environment variable DOS2UNIX_LOCALEDIR is too long.\n"));
808 strcpy(localedir,LOCALEDIR);
812 setlocale (LC_ALL, "");
813 bindtextdomain (PACKAGE, localedir);
814 textdomain (PACKAGE);
818 /* variable initialisations */
820 CanSwitchFileMode = 1;
822 pFlag = (CFlag*)malloc(sizeof(CFlag));
826 pFlag->ConvMode = CONVMODE_ASCII; /* default ascii */
827 pFlag->FromToMode = FROMTO_DOS2UNIX; /* default dos2unix */
830 pFlag->Follow = SYMLINK_SKIP;
832 pFlag->stdio_mode = 1;
835 pFlag->bomtype = FILE_MBS;
839 if ( ((ptr=strrchr(argv[0],'/')) == NULL) && ((ptr=strrchr(argv[0],'\\')) == NULL) )
844 if ((strcmpi("mac2unix", ptr) == 0) || (strcmpi("mac2unix.exe", ptr) == 0))
846 pFlag->FromToMode = FROMTO_MAC2UNIX;
847 strcpy(progname,"mac2unix");
850 while ((++ArgIdx < argc) && (!ShouldExit))
852 /* is it an option? */
853 if ((argv[ArgIdx][0] == '-') && process_options)
856 if (strcmp(argv[ArgIdx],"--") == 0)
858 else if ((strcmp(argv[ArgIdx],"-h") == 0) || (strcmp(argv[ArgIdx],"--help") == 0))
860 PrintUsage(progname);
861 return(pFlag->error);
863 else if ((strcmp(argv[ArgIdx],"-k") == 0) || (strcmp(argv[ArgIdx],"--keepdate") == 0))
865 else if ((strcmp(argv[ArgIdx],"-f") == 0) || (strcmp(argv[ArgIdx],"--force") == 0))
867 else if ((strcmp(argv[ArgIdx],"-s") == 0) || (strcmp(argv[ArgIdx],"--safe") == 0))
869 else if ((strcmp(argv[ArgIdx],"-q") == 0) || (strcmp(argv[ArgIdx],"--quiet") == 0))
871 else if ((strcmp(argv[ArgIdx],"-l") == 0) || (strcmp(argv[ArgIdx],"--newline") == 0))
873 else if ((strcmp(argv[ArgIdx],"-m") == 0) || (strcmp(argv[ArgIdx],"--add-bom") == 0))
875 else if ((strcmp(argv[ArgIdx],"-S") == 0) || (strcmp(argv[ArgIdx],"--skip-symlink") == 0))
876 pFlag->Follow = SYMLINK_SKIP;
877 else if ((strcmp(argv[ArgIdx],"-F") == 0) || (strcmp(argv[ArgIdx],"--follow-symlink") == 0))
878 pFlag->Follow = SYMLINK_FOLLOW;
879 else if ((strcmp(argv[ArgIdx],"-R") == 0) || (strcmp(argv[ArgIdx],"--replace-symlink") == 0))
880 pFlag->Follow = SYMLINK_REPLACE;
881 else if ((strcmp(argv[ArgIdx],"-V") == 0) || (strcmp(argv[ArgIdx],"--version") == 0))
883 PrintVersion(progname);
885 PrintLocaledir(localedir);
887 return(pFlag->error);
889 else if ((strcmp(argv[ArgIdx],"-L") == 0) || (strcmp(argv[ArgIdx],"--license") == 0))
892 return(pFlag->error);
894 else if (strcmp(argv[ArgIdx],"-ascii") == 0) /* SunOS compatible options */
895 pFlag->ConvMode = CONVMODE_ASCII;
896 else if (strcmp(argv[ArgIdx],"-7") == 0)
897 pFlag->ConvMode = CONVMODE_7BIT;
898 else if (strcmp(argv[ArgIdx],"-iso") == 0)
900 pFlag->ConvMode = (int)query_con_codepage();
903 fprintf(stderr,"%s: ",progname);
904 fprintf(stderr,_("active code page: %d\n"), pFlag->ConvMode);
906 if (pFlag->ConvMode < 2)
907 pFlag->ConvMode = CONVMODE_437;
909 else if (strcmp(argv[ArgIdx],"-437") == 0)
910 pFlag->ConvMode = CONVMODE_437;
911 else if (strcmp(argv[ArgIdx],"-850") == 0)
912 pFlag->ConvMode = CONVMODE_850;
913 else if (strcmp(argv[ArgIdx],"-860") == 0)
914 pFlag->ConvMode = CONVMODE_860;
915 else if (strcmp(argv[ArgIdx],"-863") == 0)
916 pFlag->ConvMode = CONVMODE_863;
917 else if (strcmp(argv[ArgIdx],"-865") == 0)
918 pFlag->ConvMode = CONVMODE_865;
919 else if (strcmp(argv[ArgIdx],"-1252") == 0)
920 pFlag->ConvMode = CONVMODE_1252;
921 else if ((strcmp(argv[ArgIdx],"-c") == 0) || (strcmp(argv[ArgIdx],"--convmode") == 0))
925 if (strcmpi(argv[ArgIdx],"ascii") == 0) /* Benjamin Lin's legacy options */
926 pFlag->ConvMode = CONVMODE_ASCII;
927 else if (strcmpi(argv[ArgIdx], "7bit") == 0)
928 pFlag->ConvMode = CONVMODE_7BIT;
929 else if (strcmpi(argv[ArgIdx], "iso") == 0)
931 pFlag->ConvMode = (int)query_con_codepage();
934 fprintf(stderr,"%s: ",progname);
935 fprintf(stderr,_("active code page: %d\n"), pFlag->ConvMode);
937 if (pFlag->ConvMode < 2)
938 pFlag->ConvMode = CONVMODE_437;
940 else if (strcmpi(argv[ArgIdx], "mac") == 0)
941 pFlag->FromToMode = FROMTO_MAC2UNIX;
944 fprintf(stderr,"%s: ",progname);
945 fprintf(stderr, _("invalid %s conversion mode specified\n"),argv[ArgIdx]);
948 pFlag->stdio_mode = 0;
954 fprintf(stderr,"%s: ",progname);
955 fprintf(stderr,_("option '%s' requires an argument\n"),argv[ArgIdx]);
958 pFlag->stdio_mode = 0;
962 else if ((strcmp(argv[ArgIdx],"-o") == 0) || (strcmp(argv[ArgIdx],"--oldfile") == 0))
964 /* last convert not paired */
965 if (!CanSwitchFileMode)
967 fprintf(stderr,"%s: ",progname);
968 fprintf(stderr, _("target of file %s not specified in new file mode\n"), argv[ArgIdx-1]);
971 pFlag->stdio_mode = 0;
976 else if ((strcmp(argv[ArgIdx],"-n") == 0) || (strcmp(argv[ArgIdx],"--newfile") == 0))
978 /* last convert not paired */
979 if (!CanSwitchFileMode)
981 fprintf(stderr,"%s: ",progname);
982 fprintf(stderr, _("target of file %s not specified in new file mode\n"), argv[ArgIdx-1]);
985 pFlag->stdio_mode = 0;
989 else { /* wrong option */
990 PrintUsage(progname);
993 pFlag->stdio_mode = 0;
998 pFlag->stdio_mode = 0;
1002 if (CanSwitchFileMode)
1003 CanSwitchFileMode = 0;
1006 RetVal = ConvertDosToUnixNewFile(argv[ArgIdx-1], argv[ArgIdx], pFlag, progname);
1007 if (pFlag->status & NO_REGFILE)
1011 fprintf(stderr,"%s: ",progname);
1012 fprintf(stderr, _("Skipping %s, not a regular file.\n"), argv[ArgIdx-1]);
1014 } else if (pFlag->status & OUTPUTFILE_SYMLINK)
1018 fprintf(stderr,"%s: ",progname);
1019 fprintf(stderr, _("Skipping %s, output file %s is a symbolic link.\n"), argv[ArgIdx-1], argv[ArgIdx]);
1021 } else if (pFlag->status & INPUT_TARGET_NO_REGFILE)
1025 fprintf(stderr,"%s: ",progname);
1026 fprintf(stderr, _("Skipping symbolic link %s, target is not a regular file.\n"), argv[ArgIdx-1]);
1028 } else if (pFlag->status & OUTPUT_TARGET_NO_REGFILE)
1032 fprintf(stderr,"%s: ",progname);
1033 fprintf(stderr, _("Skipping %s, target of symbolic link %s is not a regular file.\n"), argv[ArgIdx-1], argv[ArgIdx]);
1035 } else if (pFlag->status & BINARY_FILE)
1039 fprintf(stderr,"%s: ",progname);
1040 fprintf(stderr, _("Skipping binary file %s\n"), argv[ArgIdx-1]);
1042 } else if (pFlag->status & WRONG_CODEPAGE)
1046 fprintf(stderr,"%s: ",progname);
1047 fprintf(stderr, _("code page %d is not supported.\n"), pFlag->ConvMode);
1049 } else if (pFlag->status & LOCALE_NOT_UTF8)
1053 fprintf(stderr,"%s: ",progname);
1054 fprintf(stderr, _("Skipping UTF-16 file %s, the current locale character encoding is not UTF-8.\n"), argv[ArgIdx-1]);
1056 } else if (pFlag->status & WCHAR_T_TOO_SMALL)
1060 fprintf(stderr,"%s: ",progname);
1061 fprintf(stderr, _("Skipping UTF-16 file %s, the size of wchar_t is %d bytes.\n"), argv[ArgIdx-1], (int)sizeof(wchar_t));
1063 } else if (pFlag->status & UNICODE_CONVERSION_ERROR)
1067 fprintf(stderr,"%s: ",progname);
1068 fprintf(stderr, _("Skipping UTF-16 file %s, an UTF-16 conversion error occurred.\n"), argv[ArgIdx-1]);
1073 fprintf(stderr,"%s: ",progname);
1074 fprintf(stderr, _("converting file %s to file %s in Unix format ...\n"), argv[ArgIdx-1], argv[ArgIdx]);
1080 fprintf(stderr,"%s: ",progname);
1081 fprintf(stderr, _("problems converting file %s to file %s\n"), argv[ArgIdx-1], argv[ArgIdx]);
1085 CanSwitchFileMode = 1;
1090 RetVal = ConvertDosToUnixNewFile(argv[ArgIdx], argv[ArgIdx], pFlag, progname);
1091 if (pFlag->status & NO_REGFILE)
1095 fprintf(stderr,"%s: ",progname);
1096 fprintf(stderr, _("Skipping %s, not a regular file.\n"), argv[ArgIdx]);
1098 } else if (pFlag->status & OUTPUTFILE_SYMLINK)
1102 fprintf(stderr,"%s: ",progname);
1103 fprintf(stderr, _("Skipping symbolic link %s.\n"), argv[ArgIdx]);
1105 } else if (pFlag->status & INPUT_TARGET_NO_REGFILE)
1109 fprintf(stderr,"%s: ",progname);
1110 fprintf(stderr, _("Skipping symbolic link %s, target is not a regular file.\n"), argv[ArgIdx]);
1112 } else if (pFlag->status & BINARY_FILE)
1116 fprintf(stderr,"%s: ",progname);
1117 fprintf(stderr, _("Skipping binary file %s\n"), argv[ArgIdx]);
1119 } else if (pFlag->status & WRONG_CODEPAGE)
1123 fprintf(stderr,"%s: ",progname);
1124 fprintf(stderr, _("code page %d is not supported.\n"), pFlag->ConvMode);
1126 } else if (pFlag->status & LOCALE_NOT_UTF8)
1130 fprintf(stderr,"%s: ",progname);
1131 fprintf(stderr, _("Skipping UTF-16 file %s, the current locale character encoding is not UTF-8.\n"), argv[ArgIdx]);
1133 } else if (pFlag->status & WCHAR_T_TOO_SMALL)
1137 fprintf(stderr,"%s: ",progname);
1138 fprintf(stderr, _("Skipping UTF-16 file %s, the size of wchar_t is %d bytes.\n"), argv[ArgIdx], (int)sizeof(wchar_t));
1140 } else if (pFlag->status & UNICODE_CONVERSION_ERROR)
1144 fprintf(stderr,"%s: ",progname);
1145 fprintf(stderr, _("Skipping UTF-16 file %s, an UTF-16 conversion error occurred.\n"), argv[ArgIdx]);
1150 fprintf(stderr,"%s: ",progname);
1151 fprintf(stderr, _("converting file %s to Unix format ...\n"), argv[ArgIdx]);
1157 fprintf(stderr,"%s: ",progname);
1158 fprintf(stderr, _("problems converting file %s\n"), argv[ArgIdx]);
1166 /* no file argument, use stdin and stdout */
1167 if (pFlag->stdio_mode)
1169 exit(ConvertDosToUnixStdio(pFlag, progname));
1173 if (!CanSwitchFileMode)
1175 fprintf(stderr,"%s: ",progname);
1176 fprintf(stderr, _("target of file %s not specified in new file mode\n"), argv[ArgIdx-1]);
1179 return (pFlag->error);