xref: /titanic_44/usr/src/cmd/sunpc/other/unix2dos.c (revision 84ab085a13f931bc78e7415e7ce921dbaa14fcb3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1999-2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 
30 /*
31  *	Converts files from one char set to another
32  *
33  *	Written 11/09/87	Eddy Bell
34  *
35  */
36 
37 
38 /*
39  *  INCLUDED and DEFINES
40  */
41 #include	<stdio.h>
42 #include	<fcntl.h>
43 #include	<sys/systeminfo.h>
44 #include	<stdlib.h>
45 #include	<string.h>
46 #include	<errno.h>
47 /* #include	<io.h>			for microsoft c 4.0 */
48 
49 
50 #define		CONTENTS_ASCII	0
51 #define		CONTENTS_ASCII8 1
52 #define		CONTENTS_ISO	2
53 #define		CONTENTS_DOS	3
54 #ifdef _F_BIN
55 #define	DOS_BUILD 1
56 #else
57 #define	UNIX_BUILD 1
58 #endif
59 
60 
61 /*
62  * INCLUDES AND DEFINES
63  *
64  */
65 #ifdef UNIX_BUILD
66 #include <sys/types.h>
67 #include	<sys/kbio.h>
68 #include	<sys/time.h>
69 #include	<fcntl.h>
70 #include "../sys/dos_iso.h"
71 #endif
72 
73 #ifdef DOS_BUILD
74 #include <dos.h>
75 #include "..\sys\dos_iso.h"
76 #endif
77 
78 
79 #define		GLOBAL
80 #define		LOCAL	static
81 #define		BOOL	int
82 
83 #define		FALSE	0
84 #define		TRUE	~FALSE
85 
86 #define		CR	0x0D
87 #define		LF	0x0A
88 #define		DOS_EOF 0x1A
89 
90 #define		MAXLEN	1024
91 
92 /*
93  * FUNCTION AND VARIABLE DECLARATIONS
94  */
95 static	void	error();
96 static	void	usage();
97 static	int	tmpfd = -1;
98 /*
99  * ENTRY POINTS
100  */
101 
102 void
103 main(argc, argv)
104 int	argc;
105 char	**argv;
106 {
107 	FILE *in_stream = NULL;
108 	FILE *out_stream = NULL;
109 	unsigned char tmp_buff[512];
110 
111 	unsigned char *src_str, *dest_str;
112 	char	 *in_file_name, *out_file_name;
113 	int num_read, numchar, i, j, out_len, translate_mode;
114 	int same_name;
115 	/* char count for fread() */
116 
117 	int	type;
118 	int	code_page_overide; /* over ride of default codepage */
119 
120 	unsigned char * dos_to_iso;
121 	unsigned char iso_to_dos[256];
122 #ifdef UNIX_BUILD
123 	int	kbdfd;
124 #endif
125 	char	sysinfo_str[MAXLEN];
126 
127 	same_name = FALSE;
128 	out_file_name = (char *)0;
129 
130 	/*
131 	 * The filename parameter is positionally dependent - in that
132 	 * the dest file name must follow the source filename
133 	 */
134 	argv++;
135 	in_stream = stdin;
136 	out_stream = stdout;
137 	j = 0;  /* count for file names 0 -> source 1-> dest */
138 	translate_mode = CONTENTS_ISO; /* default trans mode */
139 	code_page_overide = 0;
140 	for (i = 1; i < argc; i++) {
141 		if (*argv[0] == '-') {
142 			if (argc > 1 && !strncmp(*argv, "-iso", 4)) {
143 				translate_mode = CONTENTS_ISO;
144 				argv++;
145 			} else if (argc > 1 && !strncmp(*argv, "-7", 2)) {
146 				translate_mode = CONTENTS_ASCII;
147 				argv++;
148 			} else if (argc > 1 && !strncmp(*argv, "-ascii", 6)) {
149 				translate_mode = CONTENTS_DOS;
150 				argv++;
151 			} else if (argc > 1 && !strncmp(*argv, "-437", 4)) {
152 				code_page_overide = CODE_PAGE_US;
153 				argv++;
154 			} else if (argc > 1 && !strncmp(*argv, "-850", 4)) {
155 				code_page_overide = CODE_PAGE_MULTILINGUAL;
156 				argv++;
157 			} else if (argc > 1 && !strncmp(*argv, "-860", 4)) {
158 				code_page_overide = CODE_PAGE_PORTUGAL;
159 				argv++;
160 			} else if (argc > 1 && !strncmp(*argv, "-863", 4)) {
161 				code_page_overide = CODE_PAGE_CANADA_FRENCH;
162 				argv++;
163 			} else if (argc > 1 && !strncmp(*argv, "-865", 4)) {
164 				code_page_overide = CODE_PAGE_NORWAY;
165 				argv++;
166 			} else
167 				argv++;
168 			continue;
169 		} else {  /* not a command so must be filename */
170 			switch (j) {
171 				case IN_FILE:	/* open in file from cmdline */
172 					in_file_name = *argv;
173 					j++;  /* next file name is outfile */
174 					break;
175 
176 				case OUT_FILE:	/* open out file from cmdline */
177 					out_file_name = *argv;
178 					j++;
179 					break;
180 
181 				default:
182 					usage();
183 			}
184 		}
185 	argv++;
186 	}
187 
188 	/* input file is specified */
189 	if (j > 0) {
190 		in_stream = fopen(in_file_name, "r");
191 		if (in_stream == NULL)
192 			error("Couldn't open input file %s.", in_file_name);
193 	}
194 
195 	/* output file is specified */
196 	if (j > 1) {
197 		if (!strcmp(in_file_name, out_file_name)) {
198 			/* input and output have same name */
199 			if (access(out_file_name, 2))
200 				error("%s not writable.", out_file_name);
201 			strcpy(out_file_name, "/tmp/udXXXXXX");
202 			tmpfd = mkstemp(out_file_name);
203 			if (tmpfd == -1) {
204 				error("Couldn't create output file %s.",
205 				    out_file_name);
206 			}
207 			(void) close(tmpfd);
208 			same_name = TRUE;
209 		} else
210 			same_name = FALSE;
211 		out_stream = fopen(out_file_name, "w");
212 		if (out_stream == NULL) {
213 			(void) unlink(out_file_name);
214 			error("Couldn't open output file %s.", out_file_name);
215 		}
216 
217 	}
218 #ifdef _F_BIN
219 	setmode(fileno(in_stream), O_BINARY);
220 	setmode(fileno(out_stream), O_BINARY);
221 #endif
222 
223 
224 #ifdef UNIX_BUILD
225 	if (!code_page_overide) {
226 		if (sysinfo(SI_ARCHITECTURE, sysinfo_str, MAXLEN)  < 0) {
227 			fprintf(stderr,
228 			    "could not obtain system information\n");
229 			(void) unlink(out_file_name);
230 			exit(1);
231 
232 		}
233 		if (strcmp(sysinfo_str, "i386")) {
234 			if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
235 				fprintf(stderr,
236 				    "could not open /dev/kbd to get "
237 				    "keyboard type US keyboard assumed\n");
238 			}
239 			if (ioctl(kbdfd, KIOCLAYOUT, &type) < 0) {
240 				fprintf(stderr,
241 	"could not get keyboard type US keyboard assumed\n");
242 			}
243 		} else {
244 			type = 0;
245 		}
246 		switch (type) {
247 			case	0:
248 			case	1:	/* United States */
249 				dos_to_iso = &dos_to_iso_cp_437[0];
250 			break;
251 
252 			case	2:	/* Belgian French */
253 				dos_to_iso = &dos_to_iso_cp_437[0];
254 			break;
255 
256 			case	3:	/* Canadian French */
257 				dos_to_iso = &dos_to_iso_cp_863[0];
258 			break;
259 
260 			case	4:	/* Danish */
261 				dos_to_iso = &dos_to_iso_cp_865[0];
262 			break;
263 
264 			case	5:	/* German */
265 				dos_to_iso = &dos_to_iso_cp_437[0];
266 			break;
267 
268 			case	6:	/* Italian */
269 				dos_to_iso = &dos_to_iso_cp_437[0];
270 			break;
271 
272 			case	7:	/* Netherlands Dutch */
273 				dos_to_iso = &dos_to_iso_cp_437[0];
274 			break;
275 
276 			case	8:	/* Norwegian */
277 				dos_to_iso = &dos_to_iso_cp_865[0];
278 			break;
279 
280 			case	9:	/* Portuguese */
281 				dos_to_iso = &dos_to_iso_cp_860[0];
282 			break;
283 
284 			case	10:	/* Spanish */
285 				dos_to_iso = &dos_to_iso_cp_437[0];
286 			break;
287 
288 			case	11:	/* Swedish Finnish */
289 				dos_to_iso = &dos_to_iso_cp_437[0];
290 			break;
291 
292 			case	12:	/* Swiss French */
293 				dos_to_iso = &dos_to_iso_cp_437[0];
294 			break;
295 
296 			case	13:	/* Swiss German */
297 				dos_to_iso = &dos_to_iso_cp_437[0];
298 			break;
299 
300 			case	14:	/* United Kingdom */
301 				dos_to_iso = &dos_to_iso_cp_437[0];
302 
303 			break;
304 
305 			default:
306 				dos_to_iso = &dos_to_iso_cp_437[0];
307 			break;
308 		}
309 	} else {
310 		switch (code_page_overide) {
311 			case CODE_PAGE_US:
312 				dos_to_iso = &dos_to_iso_cp_437[0];
313 			break;
314 
315 			case CODE_PAGE_MULTILINGUAL:
316 				dos_to_iso = &dos_to_iso_cp_850[0];
317 			break;
318 
319 			case CODE_PAGE_PORTUGAL:
320 				dos_to_iso = &dos_to_iso_cp_860[0];
321 			break;
322 
323 			case CODE_PAGE_CANADA_FRENCH:
324 				dos_to_iso = &dos_to_iso_cp_863[0];
325 			break;
326 
327 			case CODE_PAGE_NORWAY:
328 				dos_to_iso = &dos_to_iso_cp_865[0];
329 			break;
330 		}
331 	}
332 #endif
333 #ifdef DOS_BUILD
334 	if (!code_page_overide) {
335 		{
336 		union REGS regs;
337 		regs.h.ah = 0x66;	/* get/set global code page */
338 		regs.h.al = 0x01;		/* get */
339 		intdos(&regs, &regs);
340 		type = regs.x.bx;
341 		}
342 		switch (type) {
343 			case	437:	/* United States */
344 				dos_to_iso = &dos_to_iso_cp_437[0];
345 			break;
346 
347 			case	850:	/* Multilingual */
348 				dos_to_iso = &dos_to_iso_cp_850[0];
349 			break;
350 
351 			case	860:	/* Portuguese */
352 				dos_to_iso = &dos_to_iso_cp_860[0];
353 			break;
354 
355 			case	863:	/* Canadian French */
356 				dos_to_iso = &dos_to_iso_cp_863[0];
357 			break;
358 
359 			case	865:	/* Danish */
360 				dos_to_iso = &dos_to_iso_cp_865[0];
361 			break;
362 
363 			default:
364 				dos_to_iso = &dos_to_iso_cp_437[0];
365 			break;
366 		}
367 	} else {
368 		switch (code_page_overide) {
369 			case CODE_PAGE_US:
370 				dos_to_iso = &dos_to_iso_cp_437[0];
371 			break;
372 
373 			case CODE_PAGE_MULTILINGUAL:
374 				dos_to_iso = &dos_to_iso_cp_850[0];
375 			break;
376 
377 			case CODE_PAGE_PORTUGAL:
378 				dos_to_iso = &dos_to_iso_cp_860[0];
379 			break;
380 
381 			case CODE_PAGE_CANADA_FRENCH:
382 				dos_to_iso = &dos_to_iso_cp_863[0];
383 			break;
384 
385 			case CODE_PAGE_NORWAY:
386 				dos_to_iso = &dos_to_iso_cp_865[0];
387 			break;
388 		}
389 	}
390 
391 #endif
392 	for (i = 0; i <= 255; i++) {
393 		iso_to_dos[dos_to_iso[i]] = i;
394 	}
395 
396 	/*
397 	 * While not EOF, read in chars and send them to out_stream
398 	 * if current char is not a CR.
399 	 */
400 
401     do {
402 		num_read = fread(&tmp_buff[100], 1, 100, in_stream);
403 		i = 0;
404 		out_len = 0;
405 		src_str = &tmp_buff[100];
406 		dest_str = &tmp_buff[0];
407 		switch (translate_mode) {
408 			case CONTENTS_ISO:
409 				{
410 				while (i++ != num_read) {
411 					if (*src_str == '\n') {
412 						*dest_str++ = '\r';
413 						out_len++;
414 						}
415 					out_len++;
416 					*dest_str++ = iso_to_dos[*src_str++];
417 					}
418 				}
419 				break;
420 
421 			case CONTENTS_ASCII:
422 				while (i++ != num_read) {
423 					if (*src_str > 127) {
424 						*dest_str++ =
425 						    (unsigned char) ' ';
426 						src_str++;
427 						out_len++;
428 					} else {
429 						if (*src_str == '\n') {
430 							*dest_str++ = '\r';
431 							out_len++;
432 						}
433 						*dest_str++ = *src_str++;
434 						out_len++;
435 					}
436 				}
437 				break;
438 
439 			case CONTENTS_DOS:
440 				{
441 				while (i++ != num_read) {
442 					if (*src_str == '\n') {
443 						*dest_str++ = '\r';
444 						out_len++;
445 						}
446 					*dest_str++ =	*src_str++;
447 					out_len++;
448 					}
449 				}
450 				break;
451 			}
452 		if (out_len && out_len != fwrite(&tmp_buff[0], 1, out_len,
453 		    out_stream))
454 			error("Error writing to %s.", out_file_name);
455 
456 		} while (!feof(in_stream));
457 
458 #ifdef CTRL_Z_ON_EOF
459 	tmp_buff[0] = 26;
460 	fwrite(&tmp_buff[0], 1, 1, out_stream);
461 #endif
462 	fclose(out_stream);
463 	fclose(in_stream);
464 	if (same_name) {
465 		unlink(in_file_name);
466 		in_stream = fopen(out_file_name, "r");
467 		out_stream = fopen(in_file_name, "w");
468 #ifdef _F_BIN
469 		setmode(fileno(in_stream), O_BINARY);
470 		setmode(fileno(out_stream), O_BINARY);
471 #endif
472 		while ((num_read = fread(tmp_buff, 1, sizeof (tmp_buff),
473 		    in_stream)) != 0) {
474 			if (num_read != fwrite(tmp_buff, 1, num_read,
475 			    out_stream))
476 				error("Error writing to %s.", in_file_name);
477 		}
478 		fclose(out_stream);
479 		fclose(in_stream);
480 		unlink(out_file_name);
481 	}
482 	exit(0);
483 }
484 
485 void
486 error(format, args)
487 	char	*format;
488 	char	*args;
489 {
490 	fprintf(stderr, "unix2dos: ");
491 	fprintf(stderr, format, args);
492 	fprintf(stderr, "  %s.\n", strerror(errno));
493 	exit(1);
494 }
495 
496 void
497 usage()
498 {
499 	fprintf(stderr,
500 	    "usage: unix2dos [ -ascii ] [ -iso ] [ -7 ] [ originalfile [ convertedfile ] ]\n");
501 	exit(1);
502 }
503