4 * Convert lf ('\x0a') characters in a file to cr lf ('\x0d' '\x0a')
7 * The dos2unix package is distributed under FreeBSD style license.
8 * See also http://www.freebsd.org/copyright/freebsd-license.html
11 * Copyright (C) 2009-2012 Erwin Waterlander
12 * Copyright (C) 1994-1995 Benjamin Lin.
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
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
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.
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.
48 * See ChangeLog.txt for complete version history.
59 #ifndef MSDOS /* Unix, Cygwin */
60 # include <langinfo.h>
64 void PrintLicense(void)
66 fprintf(stderr, "%s", _("\
67 Copyright (C) 2009-2012 Erwin Waterlander\n\
68 Copyright (C) 1994-1995 Benjamin Lin\n\
69 All rights reserved.\n\n"));
74 void AddDOSNewLineW(FILE* ipOutF, CFlag *ipFlag, wint_t CurChar, wint_t PrevChar)
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);
86 void AddDOSNewLine(FILE* ipOutF, CFlag *ipFlag, int CurChar, int PrevChar)
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);
97 /* converts stream ipInF to DOS format text and write to stream ipOutF
98 * RetVal: 0 if success
102 int ConvertUnixToDosW(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag, char *progname)
106 wint_t PreviousChar = 0;
111 /* CR-LF -> CR-LF, in case the input file is a DOS text file */
112 /* \x0a = Newline/Line Feed (LF) */
113 /* \x0d = Carriage Return (CR) */
115 switch (ipFlag->FromToMode)
117 case FROMTO_UNIX2DOS: /* unix2dos */
118 while ((TempChar = d2u_getwc(ipInF, ipFlag->bomtype)) != WEOF) { /* get character */
119 if ((ipFlag->Force == 0) &&
121 (TempChar != 0x0a) && /* Not an LF */
122 (TempChar != 0x0d) && /* Not a CR */
123 (TempChar != 0x09) && /* Not a TAB */
124 (TempChar != 0x0c)) { /* Not a form feed */
126 ipFlag->status |= BINARY_FILE ;
129 if (TempChar == 0x0a)
131 d2u_putwc(0x0d, ipOutF, ipFlag); /* got LF, put CR */
133 if (TempChar == 0x0d) /* got CR */
135 if ((TempChar = d2u_getwc(ipInF, ipFlag->bomtype)) == WEOF) /* get next char */
136 TempChar = 0x0d; /* Read error, or end of file. */
139 d2u_putwc(0x0d, ipOutF, ipFlag); /* put CR */
144 if (d2u_putwc(TempChar, ipOutF, ipFlag) == WEOF)
149 if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
151 fprintf(stderr, "%s: ", progname);
152 fprintf(stderr, "%s", _("can not write to output file\n"));
157 AddDOSNewLineW( ipOutF, ipFlag, TempChar, PreviousChar);
159 PreviousChar = TempChar;
162 case FROMTO_UNIX2MAC: /* unix2mac */
163 while ((TempChar = d2u_getwc(ipInF, ipFlag->bomtype)) != WEOF) {
164 if ((ipFlag->Force == 0) &&
166 (TempChar != 0x0a) && /* Not an LF */
167 (TempChar != 0x0d) && /* Not a CR */
168 (TempChar != 0x09) && /* Not a TAB */
169 (TempChar != 0x0c)) { /* Not a form feed */
171 ipFlag->status |= BINARY_FILE ;
174 if ((TempChar != 0x0a)) /* Not an LF */
176 if(d2u_putwc(TempChar, ipOutF, ipFlag) == WEOF){
180 if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
182 fprintf(stderr, "%s: ", progname);
183 fprintf(stderr, "%s", _("can not write to output file\n"));
188 PreviousChar = TempChar;
191 /* TempChar is an LF */
192 /* Don't touch this delimiter if it's a CR,LF pair. */
193 if ( PreviousChar == 0x0d ) {
194 if (d2u_putwc(0x0a, ipOutF, ipFlag) == WEOF) /* CR,LF pair. Put LF */
199 if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
201 fprintf(stderr, "%s: ", progname);
202 fprintf(stderr, "%s", _("can not write to output file\n"));
207 PreviousChar = TempChar;
210 PreviousChar = TempChar;
211 if (d2u_putwc(0x0d, ipOutF, ipFlag) == WEOF) /* Unix line end (LF). Put CR */
216 if (!(ipFlag->status & UNICODE_CONVERSION_ERROR))
218 fprintf(stderr, "%s: ", progname);
219 fprintf(stderr, "%s", _("can not write to output file\n"));
224 if (ipFlag->NewLine) { /* add additional CR? */
225 d2u_putwc(0x0d, ipOutF, ipFlag);
230 default: /* unknown FromToMode */
233 fprintf(stderr, "%s: ", progname);
234 fprintf(stderr, _("program error, invalid conversion mode %d\n"),ipFlag->FromToMode);
242 /* converts stream ipInF to DOS format text and write to stream ipOutF
243 * RetVal: 0 if success
246 int ConvertUnixToDos(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag, char *progname)
250 int PreviousChar = 0;
255 switch (ipFlag->ConvMode)
257 case CONVMODE_ASCII: /* ascii */
258 ConvTable = U2DAsciiTable;
260 case CONVMODE_7BIT: /* 7bit */
261 ConvTable = U2D7BitTable;
263 case CONVMODE_437: /* iso */
264 ConvTable = U2DIso437Table;
266 case CONVMODE_850: /* iso */
267 ConvTable = U2DIso850Table;
269 case CONVMODE_860: /* iso */
270 ConvTable = U2DIso860Table;
272 case CONVMODE_863: /* iso */
273 ConvTable = U2DIso863Table;
275 case CONVMODE_865: /* iso */
276 ConvTable = U2DIso865Table;
278 case CONVMODE_1252: /* iso */
279 ConvTable = U2DIso1252Table;
281 default: /* unknown convmode */
282 ipFlag->status |= WRONG_CODEPAGE ;
285 if ((ipFlag->ConvMode > 1) && (!ipFlag->Quiet)) /* not ascii or 7bit */
287 fprintf(stderr, "%s: ", progname);
288 fprintf(stderr, _("using code page %d.\n"), ipFlag->ConvMode);
292 /* CR-LF -> CR-LF, in case the input file is a DOS text file */
293 /* \x0a = Newline/Line Feed (LF) */
294 /* \x0d = Carriage Return (CR) */
296 switch (ipFlag->FromToMode)
298 case FROMTO_UNIX2DOS: /* unix2dos */
299 while ((TempChar = fgetc(ipInF)) != EOF) { /* get character */
300 if ((ipFlag->Force == 0) &&
302 (TempChar != '\x0a') && /* Not an LF */
303 (TempChar != '\x0d') && /* Not a CR */
304 (TempChar != '\x09') && /* Not a TAB */
305 (TempChar != '\x0c')) { /* Not a form feed */
307 ipFlag->status |= BINARY_FILE ;
310 if (TempChar == '\x0a')
312 fputc('\x0d', ipOutF); /* got LF, put CR */
314 if (TempChar == '\x0d') /* got CR */
316 if ((TempChar = fgetc(ipInF)) == EOF) /* get next char */
317 TempChar = '\x0d'; /* Read error, or end of file. */
320 fputc('\x0d', ipOutF); /* put CR */
321 PreviousChar = '\x0d';
325 if (fputc(ConvTable[TempChar], ipOutF) == EOF)
330 fprintf(stderr, "%s: ", progname);
331 fprintf(stderr, "%s", _("can not write to output file\n"));
335 AddDOSNewLine( ipOutF, ipFlag, TempChar, PreviousChar);
337 PreviousChar = TempChar;
340 case FROMTO_UNIX2MAC: /* unix2mac */
341 while ((TempChar = fgetc(ipInF)) != EOF) {
342 if ((ipFlag->Force == 0) &&
344 (TempChar != '\x0a') && /* Not an LF */
345 (TempChar != '\x0d') && /* Not a CR */
346 (TempChar != '\x09') && /* Not a TAB */
347 (TempChar != '\x0c')) { /* Not a form feed */
349 ipFlag->status |= BINARY_FILE ;
352 if ((TempChar != '\x0a')) /* Not an LF */
354 if(fputc(ConvTable[TempChar], ipOutF) == EOF){
358 fprintf(stderr, "%s: ", progname);
359 fprintf(stderr, "%s", _("can not write to output file\n"));
363 PreviousChar = TempChar;
366 /* TempChar is an LF */
367 /* Don't touch this delimiter if it's a CR,LF pair. */
368 if ( PreviousChar == '\x0d' ) {
369 if (fputc('\x0a', ipOutF) == EOF) /* CR,LF pair. Put LF */
374 fprintf(stderr, "%s: ", progname);
375 fprintf(stderr, "%s", _("can not write to output file\n"));
379 PreviousChar = TempChar;
382 PreviousChar = TempChar;
383 if (fputc('\x0d', ipOutF) == EOF) /* Unix line end (LF). Put CR */
388 fprintf(stderr, "%s: ", progname);
389 fprintf(stderr, "%s", _("can not write to output file\n"));
393 if (ipFlag->NewLine) { /* add additional CR? */
394 fputc('\x0d', ipOutF);
399 default: /* unknown FromToMode */
402 fprintf(stderr, "%s: ", progname);
403 fprintf(stderr, _("program error, invalid conversion mode %d\n"),ipFlag->FromToMode);
410 /* convert file ipInFN to DOS format text and write to file ipOutFN
411 * RetVal: 0 if success
414 int ConvertUnixToDosNewFile(char *ipInFN, char *ipOutFN, CFlag *ipFlag, char *progname)
422 struct utimbuf UTimeBuf;
431 char *TargetFN = NULL;
432 int ResolveSymlinkResult = 0;
436 /* Test if output file is a symbolic link */
437 if (symbolic_link(ipOutFN) && !ipFlag->Follow)
439 ipFlag->status |= OUTPUTFILE_SYMLINK ;
440 /* Not a failure, skipping input file according spec. (keep symbolic link unchanged) */
444 /* Test if input file is a regular file or symbolic link */
445 if (regfile(ipInFN, 1, ipFlag, progname))
447 ipFlag->status |= NO_REGFILE ;
448 /* Not a failure, skipping non-regular input file according spec. */
452 /* Test if input file target is a regular file */
453 if (symbolic_link(ipInFN) && regfile_target(ipInFN, ipFlag,progname))
455 ipFlag->status |= INPUT_TARGET_NO_REGFILE ;
456 /* Not a failure, skipping non-regular input file according spec. */
460 /* Test if output file target is a regular file */
461 if (symbolic_link(ipOutFN) && (ipFlag->Follow == SYMLINK_FOLLOW) && regfile_target(ipOutFN, ipFlag,progname))
463 ipFlag->status |= OUTPUT_TARGET_NO_REGFILE ;
464 /* Failure, input is regular, cannot produce output. */
465 if (!ipFlag->error) ipFlag->error = 1;
469 /* retrieve ipInFN file date stamp */
470 if (stat(ipInFN, &StatBuf))
474 ipFlag->error = errno;
475 errstr = strerror(errno);
476 fprintf(stderr, "%s: %s: %s\n", progname, ipInFN, errstr);
482 if((fd = MakeTempFileFrom(ipOutFN, &TempPath))==NULL) {
484 if((fd = MakeTempFileFrom (ipOutFN, &TempPath)) < 0) {
488 ipFlag->error = errno;
489 errstr = strerror(errno);
490 fprintf(stderr, "%s: ", progname);
491 fprintf(stderr, _("Failed to open temporary output file: %s\n"), errstr);
497 fprintf(stderr, "%s: ", progname);
498 fprintf(stderr, _("using %s as temporary file\n"), TempPath);
501 /* can open in file? */
504 InF=OpenInFile(ipInFN);
507 ipFlag->error = errno;
508 errstr = strerror(errno);
509 fprintf(stderr, "%s: %s: %s\n", progname, ipInFN, errstr);
514 /* can open output file? */
515 if ((!RetVal) && (InF))
518 if ((TempF=fd) == NULL)
521 if ((TempF=OpenOutFile(fd)) == NULL)
523 ipFlag->error = errno;
524 errstr = strerror(errno);
525 fprintf(stderr, "%s: %s\n", progname, errstr);
533 InF = read_bom(InF, &ipFlag->bomtype);
536 #ifndef MSDOS /* Unix, Cygwin */
537 if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
539 if (strcmp(nl_langinfo(CODESET), "UTF-8") != 0)
541 /* Don't convert UTF-16 files when the locale encoding is not UTF-8
542 * to prevent loss of characters. */
543 ipFlag->status |= LOCALE_NOT_UTF8 ;
544 if (!ipFlag->error) ipFlag->error = 1;
549 #if !defined(WIN32) && !defined(__CYGWIN__) /* Not Windows or Cygwin */
550 if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
552 if (sizeof(wchar_t) < 4)
554 /* A decoded UTF-16 surrogate pair must fit in a wchar_t */
555 ipFlag->status |= WCHAR_T_TOO_SMALL ;
556 if (!ipFlag->error) ipFlag->error = 1;
563 if ((ipFlag->add_bom) || (ipFlag->bomtype > 0))
564 fprintf(TempF, "%s", "\xEF\xBB\xBF"); /* UTF-8 BOM */
566 /* Turn off ISO and 7-bit conversion for Unicode text files */
567 if (ipFlag->bomtype > 0)
568 ipFlag->ConvMode = CONVMODE_ASCII;
570 /* conversion sucessful? */
572 if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
574 if ((!RetVal) && (ConvertUnixToDosW(InF, TempF, ipFlag, progname)))
576 if (ipFlag->status & UNICODE_CONVERSION_ERROR)
578 if (!ipFlag->error) ipFlag->error = 1;
582 if ((!RetVal) && (ConvertUnixToDos(InF, TempF, ipFlag, progname)))
586 if ((!RetVal) && (ConvertUnixToDos(InF, TempF, ipFlag, progname)))
590 /* can close in file? */
591 if ((InF) && (fclose(InF) == EOF))
594 /* can close output file? */
595 if ((TempF) && (fclose(TempF) == EOF))
609 if (ipFlag->NewFile == 0) /* old file mode */
611 RetVal = chmod (TempPath, StatBuf.st_mode); /* set original permissions */
615 mask = umask(0); /* get process's umask */
616 umask(mask); /* set umask back to original */
617 RetVal = chmod(TempPath, StatBuf.st_mode & ~mask); /* set original permissions, minus umask */
624 ipFlag->error = errno;
625 errstr = strerror(errno);
626 fprintf(stderr, "%s: ", progname);
627 fprintf(stderr, _("Failed to change the permissions of temporary output file %s: %s\n"), TempPath, errstr);
634 if (!RetVal && (ipFlag->NewFile == 0)) /* old file mode */
636 /* Change owner and group of the the tempory output file to the original file's uid and gid. */
637 /* Required when a different user (e.g. root) has write permission on the original file. */
638 /* Make sure that the original owner can still access the file. */
639 if (chown(TempPath, StatBuf.st_uid, StatBuf.st_gid))
643 ipFlag->error = errno;
644 errstr = strerror(errno);
645 fprintf(stderr, "%s: ", progname);
646 fprintf(stderr, _("Failed to change the owner and group of temporary output file %s: %s\n"), TempPath, errstr);
653 if ((!RetVal) && (ipFlag->KeepDate))
655 UTimeBuf.actime = StatBuf.st_atime;
656 UTimeBuf.modtime = StatBuf.st_mtime;
657 /* can change output file time to in file time? */
658 if (utime(TempPath, &UTimeBuf) == -1)
662 ipFlag->error = errno;
663 errstr = strerror(errno);
664 fprintf(stderr, "%s: %s: %s\n", progname, TempPath, errstr);
670 /* any error? cleanup the temp file */
671 if (RetVal && (TempPath != NULL))
673 if (unlink(TempPath) && (errno != ENOENT))
677 ipFlag->error = errno;
678 errstr = strerror(errno);
679 fprintf(stderr, "%s: %s: %s\n", progname, TempPath, errstr);
685 /* If output file is a symbolic link, optional resolve the link and modify */
686 /* the target, instead of removing the link and creating a new regular file */
688 if (symbolic_link(ipOutFN) && !RetVal)
690 ResolveSymlinkResult = 0; /* indicates that TargetFN need not be freed */
691 if (ipFlag->Follow == SYMLINK_FOLLOW)
693 ResolveSymlinkResult = ResolveSymbolicLink(ipOutFN, &TargetFN, ipFlag, progname);
694 if (ResolveSymlinkResult < 0)
698 fprintf(stderr, "%s: ", progname);
699 fprintf(stderr, _("problems resolving symbolic link '%s'\n"), ipOutFN);
700 fprintf(stderr, _(" output file remains in '%s'\n"), TempPath);
707 /* can rename temporary file to output file? */
711 if (unlink(TargetFN) && (errno != ENOENT))
715 ipFlag->error = errno;
716 errstr = strerror(errno);
717 fprintf(stderr, "%s: %s: %s\n", progname, TargetFN, errstr);
722 if (rename(TempPath, TargetFN) == -1)
726 ipFlag->error = errno;
727 errstr = strerror(errno);
728 fprintf(stderr, "%s: ", progname);
729 fprintf(stderr, _("problems renaming '%s' to '%s': %s\n"), TempPath, TargetFN, errstr);
731 if (ResolveSymlinkResult > 0)
732 fprintf(stderr, _(" which is the target of symbolic link '%s'\n"), ipOutFN);
734 fprintf(stderr, _(" output file remains in '%s'\n"), TempPath);
739 if (ResolveSymlinkResult > 0)
746 /* convert stdin to DOS format text and write to stdout
747 * RetVal: 0 if success
750 int ConvertUnixToDosStdio(CFlag *ipFlag, char *progname)
754 ipFlag->KeepDate = 0;
757 #if defined(WIN32) && !defined(__CYGWIN__)
759 /* stdin and stdout are by default text streams. We need
760 * to set them to binary mode. Otherwise an LF will
761 * automatically be converted to CR-LF on DOS/Windows.
764 /* 'setmode' was deprecated by MicroSoft
765 * since Visual C++ 2005. Use '_setmode' instead. */
767 _setmode(fileno(stdout), O_BINARY);
768 _setmode(fileno(stdin), O_BINARY);
769 #elif defined(MSDOS) || defined(__CYGWIN__) || defined(__OS2__)
770 setmode(fileno(stdout), O_BINARY);
771 setmode(fileno(stdin), O_BINARY);
774 read_bom(stdin, &ipFlag->bomtype);
776 if ((ipFlag->add_bom) || (ipFlag->bomtype > 0))
777 fprintf(stdout, "%s", "\xEF\xBB\xBF"); /* UTF-8 BOM */
780 if ((ipFlag->bomtype == FILE_UTF16LE) || (ipFlag->bomtype == FILE_UTF16BE))
782 return (ConvertUnixToDosW(stdin, stdout, ipFlag, progname));
784 return (ConvertUnixToDos(stdin, stdout, ipFlag, progname));
787 return (ConvertUnixToDos(stdin, stdout, ipFlag, progname));
792 int main (int argc, char *argv[])
794 /* variable declarations */
797 int CanSwitchFileMode;
800 int process_options = 1;
804 char localedir[1024];
807 int _dowildcard = -1; /* enable wildcard expansion for Win64 */
811 strcpy(progname,"unix2dos");
814 ptr = getenv("DOS2UNIX_LOCALEDIR");
816 strcpy(localedir,LOCALEDIR);
819 if (strlen(ptr) < sizeof(localedir))
820 strcpy(localedir,ptr);
823 fprintf(stderr,"%s: ",progname);
824 fprintf(stderr, "%s", _("error: Value of environment variable DOS2UNIX_LOCALEDIR is too long.\n"));
825 strcpy(localedir,LOCALEDIR);
829 setlocale (LC_ALL, "");
830 bindtextdomain (PACKAGE, localedir);
831 textdomain (PACKAGE);
835 /* variable initialisations */
837 CanSwitchFileMode = 1;
839 pFlag = (CFlag*)malloc(sizeof(CFlag));
843 pFlag->ConvMode = CONVMODE_ASCII; /* default ascii */
844 pFlag->FromToMode = FROMTO_UNIX2DOS; /* default unix2dos */
847 pFlag->Follow = SYMLINK_SKIP;
849 pFlag->stdio_mode = 1;
852 pFlag->bomtype = FILE_MBS;
856 if ( ((ptr=strrchr(argv[0],'/')) == NULL) && ((ptr=strrchr(argv[0],'\\')) == NULL) )
861 if ((strcmpi("unix2mac", ptr) == 0) || (strcmpi("unix2mac.exe", ptr) == 0))
863 pFlag->FromToMode = FROMTO_UNIX2MAC;
864 strcpy(progname,"unix2mac");
867 while ((++ArgIdx < argc) && (!ShouldExit))
869 /* is it an option? */
870 if ((argv[ArgIdx][0] == '-') && process_options)
873 if (strcmp(argv[ArgIdx],"--") == 0)
875 else if ((strcmp(argv[ArgIdx],"-h") == 0) || (strcmp(argv[ArgIdx],"--help") == 0))
877 PrintUsage(progname);
878 return(pFlag->error);
880 else if ((strcmp(argv[ArgIdx],"-k") == 0) || (strcmp(argv[ArgIdx],"--keepdate") == 0))
882 else if ((strcmp(argv[ArgIdx],"-f") == 0) || (strcmp(argv[ArgIdx],"--force") == 0))
884 else if ((strcmp(argv[ArgIdx],"-s") == 0) || (strcmp(argv[ArgIdx],"--safe") == 0))
886 else if ((strcmp(argv[ArgIdx],"-q") == 0) || (strcmp(argv[ArgIdx],"--quiet") == 0))
888 else if ((strcmp(argv[ArgIdx],"-l") == 0) || (strcmp(argv[ArgIdx],"--newline") == 0))
890 else if ((strcmp(argv[ArgIdx],"-m") == 0) || (strcmp(argv[ArgIdx],"--add-bom") == 0))
892 else if ((strcmp(argv[ArgIdx],"-S") == 0) || (strcmp(argv[ArgIdx],"--skip-symlink") == 0))
893 pFlag->Follow = SYMLINK_SKIP;
894 else if ((strcmp(argv[ArgIdx],"-F") == 0) || (strcmp(argv[ArgIdx],"--follow-symlink") == 0))
895 pFlag->Follow = SYMLINK_FOLLOW;
896 else if ((strcmp(argv[ArgIdx],"-R") == 0) || (strcmp(argv[ArgIdx],"--replace-symlink") == 0))
897 pFlag->Follow = SYMLINK_REPLACE;
898 else if ((strcmp(argv[ArgIdx],"-V") == 0) || (strcmp(argv[ArgIdx],"--version") == 0))
900 PrintVersion(progname);
902 PrintLocaledir(localedir);
904 return(pFlag->error);
906 else if ((strcmp(argv[ArgIdx],"-L") == 0) || (strcmp(argv[ArgIdx],"--license") == 0))
909 return(pFlag->error);
911 else if (strcmp(argv[ArgIdx],"-ascii") == 0) /* SunOS compatible options */
912 pFlag->ConvMode = CONVMODE_ASCII;
913 else if (strcmp(argv[ArgIdx],"-7") == 0)
914 pFlag->ConvMode = CONVMODE_7BIT;
915 else if (strcmp(argv[ArgIdx],"-iso") == 0)
917 pFlag->ConvMode = (int)query_con_codepage();
920 fprintf(stderr,"%s: ",progname);
921 fprintf(stderr,_("active code page: %d\n"), pFlag->ConvMode);
923 if (pFlag->ConvMode < 2)
924 pFlag->ConvMode = CONVMODE_437;
926 else if (strcmp(argv[ArgIdx],"-437") == 0)
927 pFlag->ConvMode = CONVMODE_437;
928 else if (strcmp(argv[ArgIdx],"-850") == 0)
929 pFlag->ConvMode = CONVMODE_850;
930 else if (strcmp(argv[ArgIdx],"-860") == 0)
931 pFlag->ConvMode = CONVMODE_860;
932 else if (strcmp(argv[ArgIdx],"-863") == 0)
933 pFlag->ConvMode = CONVMODE_863;
934 else if (strcmp(argv[ArgIdx],"-865") == 0)
935 pFlag->ConvMode = CONVMODE_865;
936 else if (strcmp(argv[ArgIdx],"-1252") == 0)
937 pFlag->ConvMode = CONVMODE_1252;
938 else if ((strcmp(argv[ArgIdx],"-c") == 0) || (strcmp(argv[ArgIdx],"--convmode") == 0))
942 if (strcmpi(argv[ArgIdx],"ascii") == 0) /* Benjamin Lin's legacy options */
943 pFlag->ConvMode = CONVMODE_ASCII;
944 else if (strcmpi(argv[ArgIdx], "7bit") == 0)
945 pFlag->ConvMode = CONVMODE_7BIT;
946 else if (strcmpi(argv[ArgIdx], "iso") == 0)
948 pFlag->ConvMode = (int)query_con_codepage();
951 fprintf(stderr,"%s: ",progname);
952 fprintf(stderr,_("active code page: %d\n"), pFlag->ConvMode);
954 if (pFlag->ConvMode < 2)
955 pFlag->ConvMode = CONVMODE_437;
957 else if (strcmpi(argv[ArgIdx], "mac") == 0)
958 pFlag->FromToMode = FROMTO_UNIX2MAC;
961 fprintf(stderr,"%s: ",progname);
962 fprintf(stderr, _("invalid %s conversion mode specified\n"),argv[ArgIdx]);
965 pFlag->stdio_mode = 0;
971 fprintf(stderr,"%s: ",progname);
972 fprintf(stderr,_("option '%s' requires an argument\n"),argv[ArgIdx]);
975 pFlag->stdio_mode = 0;
979 else if ((strcmp(argv[ArgIdx],"-o") == 0) || (strcmp(argv[ArgIdx],"--oldfile") == 0))
981 /* last convert not paired */
982 if (!CanSwitchFileMode)
984 fprintf(stderr,"%s: ",progname);
985 fprintf(stderr, _("target of file %s not specified in new file mode\n"), argv[ArgIdx-1]);
988 pFlag->stdio_mode = 0;
993 else if ((strcmp(argv[ArgIdx],"-n") == 0) || (strcmp(argv[ArgIdx],"--newfile") == 0))
995 /* last convert not paired */
996 if (!CanSwitchFileMode)
998 fprintf(stderr,"%s: ",progname);
999 fprintf(stderr, _("target of file %s not specified in new file mode\n"), argv[ArgIdx-1]);
1002 pFlag->stdio_mode = 0;
1006 else { /* wrong option */
1007 PrintUsage(progname);
1010 pFlag->stdio_mode = 0;
1015 pFlag->stdio_mode = 0;
1019 if (CanSwitchFileMode)
1020 CanSwitchFileMode = 0;
1023 RetVal = ConvertUnixToDosNewFile(argv[ArgIdx-1], argv[ArgIdx], pFlag, progname);
1024 if (pFlag->status & NO_REGFILE)
1028 fprintf(stderr,"%s: ",progname);
1029 fprintf(stderr, _("Skipping %s, not a regular file.\n"), argv[ArgIdx-1]);
1031 } else if (pFlag->status & OUTPUTFILE_SYMLINK)
1035 fprintf(stderr,"%s: ",progname);
1036 fprintf(stderr, _("Skipping %s, output file %s is a symbolic link.\n"), argv[ArgIdx-1], argv[ArgIdx]);
1038 } else if (pFlag->status & INPUT_TARGET_NO_REGFILE)
1042 fprintf(stderr,"%s: ",progname);
1043 fprintf(stderr, _("Skipping symbolic link %s, target is not a regular file.\n"), argv[ArgIdx-1]);
1045 } else if (pFlag->status & OUTPUT_TARGET_NO_REGFILE)
1049 fprintf(stderr,"%s: ",progname);
1050 fprintf(stderr, _("Skipping %s, target of symbolic link %s is not a regular file.\n"), argv[ArgIdx-1], argv[ArgIdx]);
1052 } else if (pFlag->status & BINARY_FILE)
1056 fprintf(stderr,"%s: ",progname);
1057 fprintf(stderr, _("Skipping binary file %s\n"), argv[ArgIdx-1]);
1059 } else if (pFlag->status & WRONG_CODEPAGE)
1063 fprintf(stderr,"%s: ",progname);
1064 fprintf(stderr, _("code page %d is not supported.\n"), pFlag->ConvMode);
1066 } else if (pFlag->status & LOCALE_NOT_UTF8)
1070 fprintf(stderr,"%s: ",progname);
1071 fprintf(stderr, _("Skipping UTF-16 file %s, the current locale character encoding is not UTF-8.\n"), argv[ArgIdx-1]);
1073 } else if (pFlag->status & WCHAR_T_TOO_SMALL)
1077 fprintf(stderr,"%s: ",progname);
1078 fprintf(stderr, _("Skipping UTF-16 file %s, the size of wchar_t is %d bytes.\n"), argv[ArgIdx-1], (int)sizeof(wchar_t));
1080 } else if (pFlag->status & UNICODE_CONVERSION_ERROR)
1084 fprintf(stderr,"%s: ",progname);
1085 fprintf(stderr, _("Skipping UTF-16 file %s, an UTF-16 conversion error occurred.\n"), argv[ArgIdx-1]);
1090 fprintf(stderr,"%s: ",progname);
1091 if (pFlag->FromToMode == FROMTO_UNIX2MAC)
1092 fprintf(stderr, _("converting file %s to file %s in Mac format ...\n"), argv[ArgIdx-1], argv[ArgIdx]);
1094 fprintf(stderr, _("converting file %s to file %s in DOS format ...\n"), argv[ArgIdx-1], argv[ArgIdx]);
1100 fprintf(stderr,"%s: ",progname);
1101 fprintf(stderr, _("problems converting file %s to file %s\n"), argv[ArgIdx-1], argv[ArgIdx]);
1105 CanSwitchFileMode = 1;
1110 RetVal = ConvertUnixToDosNewFile(argv[ArgIdx], argv[ArgIdx], pFlag, progname);
1111 if (pFlag->status & NO_REGFILE)
1115 fprintf(stderr,"%s: ",progname);
1116 fprintf(stderr, _("Skipping %s, not a regular file.\n"), argv[ArgIdx]);
1118 } else if (pFlag->status & OUTPUTFILE_SYMLINK)
1122 fprintf(stderr,"%s: ",progname);
1123 fprintf(stderr, _("Skipping symbolic link %s.\n"), argv[ArgIdx]);
1125 } else if (pFlag->status & INPUT_TARGET_NO_REGFILE)
1129 fprintf(stderr,"%s: ",progname);
1130 fprintf(stderr, _("Skipping symbolic link %s, target is not a regular file.\n"), argv[ArgIdx]);
1132 } else if (pFlag->status & BINARY_FILE)
1136 fprintf(stderr,"%s: ",progname);
1137 fprintf(stderr, _("Skipping binary file %s\n"), argv[ArgIdx]);
1139 } else if (pFlag->status & WRONG_CODEPAGE)
1143 fprintf(stderr,"%s: ",progname);
1144 fprintf(stderr, _("code page %d is not supported.\n"), pFlag->ConvMode);
1146 } else if (pFlag->status & LOCALE_NOT_UTF8)
1150 fprintf(stderr,"%s: ",progname);
1151 fprintf(stderr, _("Skipping UTF-16 file %s, the current locale character encoding is not UTF-8.\n"), argv[ArgIdx]);
1153 } else if (pFlag->status & WCHAR_T_TOO_SMALL)
1157 fprintf(stderr,"%s: ",progname);
1158 fprintf(stderr, _("Skipping UTF-16 file %s, the size of wchar_t is %d bytes.\n"), argv[ArgIdx], (int)sizeof(wchar_t));
1160 } else if (pFlag->status & UNICODE_CONVERSION_ERROR)
1164 fprintf(stderr,"%s: ",progname);
1165 fprintf(stderr, _("Skipping UTF-16 file %s, an UTF-16 conversion error occurred.\n"), argv[ArgIdx]);
1170 fprintf(stderr,"%s: ",progname);
1171 if (pFlag->FromToMode == FROMTO_UNIX2MAC)
1172 fprintf(stderr, _("converting file %s to Mac format ...\n"), argv[ArgIdx]);
1174 fprintf(stderr, _("converting file %s to DOS format ...\n"), argv[ArgIdx]);
1180 fprintf(stderr,"%s: ",progname);
1181 fprintf(stderr, _("problems converting file %s\n"), argv[ArgIdx]);
1189 /* no file argument, use stdin and stdout */
1190 if (pFlag->stdio_mode)
1192 exit(ConvertUnixToDosStdio(pFlag, progname));
1196 if (!CanSwitchFileMode)
1198 fprintf(stderr,"%s: ",progname);
1199 fprintf(stderr, _("target of file %s not specified in new file mode\n"), argv[ArgIdx-1]);
1202 return (pFlag->error);