libuutil: move under bmake
[unleashed.git] / usr / src / cmd / sunpc / other / unix2dos.c
blob13bd25ae9f8614a715c771fc6aa5c785a245d7ed
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
31 * Converts files from one char set to another
33 * Written 11/09/87 Eddy Bell
39 * INCLUDED and DEFINES
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 */
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
62 * INCLUDES AND DEFINES
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
73 #ifdef DOS_BUILD
74 #include <dos.h>
75 #include "..\sys\dos_iso.h"
76 #endif
79 #define GLOBAL
80 #define LOCAL static
81 #define BOOL int
83 #define FALSE 0
84 #define TRUE ~FALSE
86 #define CR 0x0D
87 #define LF 0x0A
88 #define DOS_EOF 0x1A
90 #define MAXLEN 1024
93 * FUNCTION AND VARIABLE DECLARATIONS
95 static void error();
96 static void usage();
97 static int tmpfd = -1;
99 * ENTRY POINTS
103 main(int argc, char **argv)
105 FILE *in_stream = NULL;
106 FILE *out_stream = NULL;
107 unsigned char tmp_buff[512];
109 unsigned char *src_str, *dest_str;
110 char *in_file_name, *out_file_name;
111 int num_read, numchar, i, j, out_len, translate_mode;
112 int same_name;
113 /* char count for fread() */
115 int type;
116 int code_page_overide; /* over ride of default codepage */
118 unsigned char * dos_to_iso;
119 unsigned char iso_to_dos[256];
120 #ifdef UNIX_BUILD
121 int kbdfd;
122 #endif
123 char sysinfo_str[MAXLEN];
125 same_name = FALSE;
126 out_file_name = NULL;
129 * The filename parameter is positionally dependent - in that
130 * the dest file name must follow the source filename
132 argv++;
133 in_stream = stdin;
134 out_stream = stdout;
135 j = 0; /* count for file names 0 -> source 1-> dest */
136 translate_mode = CONTENTS_ISO; /* default trans mode */
137 code_page_overide = 0;
138 for (i = 1; i < argc; i++) {
139 if (*argv[0] == '-') {
140 if (argc > 1 && !strncmp(*argv, "-iso", 4)) {
141 translate_mode = CONTENTS_ISO;
142 argv++;
143 } else if (argc > 1 && !strncmp(*argv, "-7", 2)) {
144 translate_mode = CONTENTS_ASCII;
145 argv++;
146 } else if (argc > 1 && !strncmp(*argv, "-ascii", 6)) {
147 translate_mode = CONTENTS_DOS;
148 argv++;
149 } else if (argc > 1 && !strncmp(*argv, "-437", 4)) {
150 code_page_overide = CODE_PAGE_US;
151 argv++;
152 } else if (argc > 1 && !strncmp(*argv, "-850", 4)) {
153 code_page_overide = CODE_PAGE_MULTILINGUAL;
154 argv++;
155 } else if (argc > 1 && !strncmp(*argv, "-860", 4)) {
156 code_page_overide = CODE_PAGE_PORTUGAL;
157 argv++;
158 } else if (argc > 1 && !strncmp(*argv, "-863", 4)) {
159 code_page_overide = CODE_PAGE_CANADA_FRENCH;
160 argv++;
161 } else if (argc > 1 && !strncmp(*argv, "-865", 4)) {
162 code_page_overide = CODE_PAGE_NORWAY;
163 argv++;
164 } else
165 argv++;
166 continue;
167 } else { /* not a command so must be filename */
168 switch (j) {
169 case IN_FILE: /* open in file from cmdline */
170 in_file_name = *argv;
171 j++; /* next file name is outfile */
172 break;
174 case OUT_FILE: /* open out file from cmdline */
175 out_file_name = *argv;
176 j++;
177 break;
179 default:
180 usage();
183 argv++;
186 /* input file is specified */
187 if (j > 0) {
188 in_stream = fopen(in_file_name, "r");
189 if (in_stream == NULL)
190 error("Couldn't open input file %s.", in_file_name);
193 /* output file is specified */
194 if (j > 1) {
195 if (!strcmp(in_file_name, out_file_name)) {
196 /* input and output have same name */
197 if (access(out_file_name, 2))
198 error("%s not writable.", out_file_name);
199 strcpy(out_file_name, "/tmp/udXXXXXX");
200 tmpfd = mkstemp(out_file_name);
201 if (tmpfd == -1) {
202 error("Couldn't create output file %s.",
203 out_file_name);
205 (void) close(tmpfd);
206 same_name = TRUE;
207 } else
208 same_name = FALSE;
209 out_stream = fopen(out_file_name, "w");
210 if (out_stream == NULL) {
211 (void) unlink(out_file_name);
212 error("Couldn't open output file %s.", out_file_name);
216 #ifdef _F_BIN
217 setmode(fileno(in_stream), O_BINARY);
218 setmode(fileno(out_stream), O_BINARY);
219 #endif
222 #ifdef UNIX_BUILD
223 if (!code_page_overide) {
224 if (sysinfo(SI_ARCHITECTURE, sysinfo_str, MAXLEN) < 0) {
225 fprintf(stderr,
226 "could not obtain system information\n");
227 (void) unlink(out_file_name);
228 exit(1);
231 if (strcmp(sysinfo_str, "i386")) {
232 if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
233 fprintf(stderr,
234 "could not open /dev/kbd to get "
235 "keyboard type US keyboard assumed\n");
237 if (ioctl(kbdfd, KIOCLAYOUT, &type) < 0) {
238 fprintf(stderr,
239 "could not get keyboard type US keyboard assumed\n");
241 } else {
242 type = 0;
244 switch (type) {
245 case 0:
246 case 1: /* United States */
247 dos_to_iso = &dos_to_iso_cp_437[0];
248 break;
250 case 2: /* Belgian French */
251 dos_to_iso = &dos_to_iso_cp_437[0];
252 break;
254 case 3: /* Canadian French */
255 dos_to_iso = &dos_to_iso_cp_863[0];
256 break;
258 case 4: /* Danish */
259 dos_to_iso = &dos_to_iso_cp_865[0];
260 break;
262 case 5: /* German */
263 dos_to_iso = &dos_to_iso_cp_437[0];
264 break;
266 case 6: /* Italian */
267 dos_to_iso = &dos_to_iso_cp_437[0];
268 break;
270 case 7: /* Netherlands Dutch */
271 dos_to_iso = &dos_to_iso_cp_437[0];
272 break;
274 case 8: /* Norwegian */
275 dos_to_iso = &dos_to_iso_cp_865[0];
276 break;
278 case 9: /* Portuguese */
279 dos_to_iso = &dos_to_iso_cp_860[0];
280 break;
282 case 10: /* Spanish */
283 dos_to_iso = &dos_to_iso_cp_437[0];
284 break;
286 case 11: /* Swedish Finnish */
287 dos_to_iso = &dos_to_iso_cp_437[0];
288 break;
290 case 12: /* Swiss French */
291 dos_to_iso = &dos_to_iso_cp_437[0];
292 break;
294 case 13: /* Swiss German */
295 dos_to_iso = &dos_to_iso_cp_437[0];
296 break;
298 case 14: /* United Kingdom */
299 dos_to_iso = &dos_to_iso_cp_437[0];
301 break;
303 default:
304 dos_to_iso = &dos_to_iso_cp_437[0];
305 break;
307 } else {
308 switch (code_page_overide) {
309 case CODE_PAGE_US:
310 dos_to_iso = &dos_to_iso_cp_437[0];
311 break;
313 case CODE_PAGE_MULTILINGUAL:
314 dos_to_iso = &dos_to_iso_cp_850[0];
315 break;
317 case CODE_PAGE_PORTUGAL:
318 dos_to_iso = &dos_to_iso_cp_860[0];
319 break;
321 case CODE_PAGE_CANADA_FRENCH:
322 dos_to_iso = &dos_to_iso_cp_863[0];
323 break;
325 case CODE_PAGE_NORWAY:
326 dos_to_iso = &dos_to_iso_cp_865[0];
327 break;
330 #endif
331 #ifdef DOS_BUILD
332 if (!code_page_overide) {
334 union REGS regs;
335 regs.h.ah = 0x66; /* get/set global code page */
336 regs.h.al = 0x01; /* get */
337 intdos(&regs, &regs);
338 type = regs.x.bx;
340 switch (type) {
341 case 437: /* United States */
342 dos_to_iso = &dos_to_iso_cp_437[0];
343 break;
345 case 850: /* Multilingual */
346 dos_to_iso = &dos_to_iso_cp_850[0];
347 break;
349 case 860: /* Portuguese */
350 dos_to_iso = &dos_to_iso_cp_860[0];
351 break;
353 case 863: /* Canadian French */
354 dos_to_iso = &dos_to_iso_cp_863[0];
355 break;
357 case 865: /* Danish */
358 dos_to_iso = &dos_to_iso_cp_865[0];
359 break;
361 default:
362 dos_to_iso = &dos_to_iso_cp_437[0];
363 break;
365 } else {
366 switch (code_page_overide) {
367 case CODE_PAGE_US:
368 dos_to_iso = &dos_to_iso_cp_437[0];
369 break;
371 case CODE_PAGE_MULTILINGUAL:
372 dos_to_iso = &dos_to_iso_cp_850[0];
373 break;
375 case CODE_PAGE_PORTUGAL:
376 dos_to_iso = &dos_to_iso_cp_860[0];
377 break;
379 case CODE_PAGE_CANADA_FRENCH:
380 dos_to_iso = &dos_to_iso_cp_863[0];
381 break;
383 case CODE_PAGE_NORWAY:
384 dos_to_iso = &dos_to_iso_cp_865[0];
385 break;
389 #endif
390 for (i = 0; i <= 255; i++) {
391 iso_to_dos[dos_to_iso[i]] = i;
395 * While not EOF, read in chars and send them to out_stream
396 * if current char is not a CR.
399 do {
400 num_read = fread(&tmp_buff[100], 1, 100, in_stream);
401 i = 0;
402 out_len = 0;
403 src_str = &tmp_buff[100];
404 dest_str = &tmp_buff[0];
405 switch (translate_mode) {
406 case CONTENTS_ISO:
408 while (i++ != num_read) {
409 if (*src_str == '\n') {
410 *dest_str++ = '\r';
411 out_len++;
413 out_len++;
414 *dest_str++ = iso_to_dos[*src_str++];
417 break;
419 case CONTENTS_ASCII:
420 while (i++ != num_read) {
421 if (*src_str > 127) {
422 *dest_str++ =
423 (unsigned char) ' ';
424 src_str++;
425 out_len++;
426 } else {
427 if (*src_str == '\n') {
428 *dest_str++ = '\r';
429 out_len++;
431 *dest_str++ = *src_str++;
432 out_len++;
435 break;
437 case CONTENTS_DOS:
439 while (i++ != num_read) {
440 if (*src_str == '\n') {
441 *dest_str++ = '\r';
442 out_len++;
444 *dest_str++ = *src_str++;
445 out_len++;
448 break;
450 if (out_len && out_len != fwrite(&tmp_buff[0], 1, out_len,
451 out_stream))
452 error("Error writing to %s.", out_file_name);
454 } while (!feof(in_stream));
456 #ifdef CTRL_Z_ON_EOF
457 tmp_buff[0] = 26;
458 fwrite(&tmp_buff[0], 1, 1, out_stream);
459 #endif
460 fclose(out_stream);
461 fclose(in_stream);
462 if (same_name) {
463 unlink(in_file_name);
464 in_stream = fopen(out_file_name, "r");
465 out_stream = fopen(in_file_name, "w");
466 #ifdef _F_BIN
467 setmode(fileno(in_stream), O_BINARY);
468 setmode(fileno(out_stream), O_BINARY);
469 #endif
470 while ((num_read = fread(tmp_buff, 1, sizeof (tmp_buff),
471 in_stream)) != 0) {
472 if (num_read != fwrite(tmp_buff, 1, num_read,
473 out_stream))
474 error("Error writing to %s.", in_file_name);
476 fclose(out_stream);
477 fclose(in_stream);
478 unlink(out_file_name);
480 return (0);
483 void
484 error(format, args)
485 char *format;
486 char *args;
488 fprintf(stderr, "unix2dos: ");
489 fprintf(stderr, format, args);
490 fprintf(stderr, " %s.\n", strerror(errno));
491 exit(1);
494 void
495 usage()
497 fprintf(stderr,
498 "usage: unix2dos [ -ascii ] [ -iso ] [ -7 ] [ originalfile [ convertedfile ] ]\n");
499 exit(1);