]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/cdrtools-2.01-mkisofs_iconv-1.patch
Zwischencommit fuer LFS.
[people/pmueller/ipfire-2.x.git] / src / patches / cdrtools-2.01-mkisofs_iconv-1.patch
CommitLineData
c8ead4a5
MT
1Submitted By: Alexander E. Patrakov
2Date: 2005-09-30
3Initial Package Version: 2.01
4Origin: RedHat (but maybe they initially obtained the patch from elsewhere)
5Upstream Status: Not applied
6Description: Allows one to specify any glibc-supported source charset
7for Joliet filenames, instead of the very limited choice offered by mkisofs
8itself. Required for writing Windows-readable data CDs in UTF-8 locales when
9filenames contain national characters.
10
11diff -urN --exclude-from=- cdrtools-2.01/include/unls.h cdrtools-2.01-jh/include/unls.h
12--- cdrtools-2.01/include/unls.h 2003-06-16 00:41:23.000000000 +0300
13+++ cdrtools-2.01-jh/include/unls.h 2004-02-02 18:31:22.000000000 +0200
14@@ -30,6 +30,10 @@
15 #include <prototyp.h>
16 #endif
17
18+#ifdef USE_ICONV
19+#include <iconv.h>
20+#endif
21+
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25@@ -43,6 +47,9 @@
26 char *charset;
27 unsigned char **page_uni2charset;
28 struct nls_unicode *charset2uni;
29+#ifdef USE_ICONV
30+ iconv_t iconv_d;
31+#endif
32
33 void (*inc_use_count) __PR((void));
34 void (*dec_use_count) __PR((void));
35@@ -58,6 +65,9 @@
36 extern void unload_nls __PR((struct nls_table *));
37 extern struct nls_table *load_nls_default __PR((void));
38 extern int init_nls_file __PR((char * name));
39+#ifdef USE_ICONV
40+extern int init_nls_iconv __PR((char * name));
41+#endif
42
43 #ifdef __cplusplus
44 }
45diff -urN --exclude-from=- cdrtools-2.01/libunls/libunls.mk cdrtools-2.01-jh/libunls/libunls.mk
46--- cdrtools-2.01/libunls/libunls.mk 2000-03-25 14:51:56.000000000 +0200
47+++ cdrtools-2.01-jh/libunls/libunls.mk 2004-02-02 18:31:22.000000000 +0200
48@@ -8,6 +8,7 @@
49 INSDIR= lib
50 TARGETLIB= unls
51 #CPPOPTS += -Istdio
52+CPPOPTS += -DUSE_ICONV
53 include Targets
54 LIBS=
55
56diff -urN --exclude-from=- cdrtools-2.01/libunls/nls.h cdrtools-2.01-jh/libunls/nls.h
57--- cdrtools-2.01/libunls/nls.h 2002-12-03 02:34:27.000000000 +0200
58+++ cdrtools-2.01-jh/libunls/nls.h 2004-02-02 18:31:22.000000000 +0200
59@@ -111,5 +111,8 @@
60 extern int init_nls_cp10079 __PR((void));
61 extern int init_nls_cp10081 __PR((void));
62 extern int init_nls_file __PR((char * name));
63+#ifdef USE_ICONV
64+extern int init_nls_iconv __PR((char * name));
65+#endif
66
67 #endif /* _NLS_H */
68diff -urN --exclude-from=- cdrtools-2.01/libunls/nls_iconv.c cdrtools-2.01-jh/libunls/nls_iconv.c
69--- cdrtools-2.01/libunls/nls_iconv.c 1970-01-01 02:00:00.000000000 +0200
70+++ cdrtools-2.01-jh/libunls/nls_iconv.c 2004-02-02 18:31:22.000000000 +0200
71@@ -0,0 +1,96 @@
72+/* @(#)nls_iconv.c 1.0 02/04/20 2002 J. Schilling */
73+#ifndef lint
74+static char sccsid[] =
75+ "@(#)nls_iconv.c 1.0 02/01/20 2002 J. Schilling";
76+#endif
77+/*
78+ * This program is free software; you can redistribute it and/or modify
79+ * it under the terms of the GNU General Public License as published by
80+ * the Free Software Foundation; either version 2, or (at your option)
81+ * any later version.
82+ *
83+ * This program is distributed in the hope that it will be useful,
84+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
85+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
86+ * GNU General Public License for more details.
87+ *
88+ * You should have received a copy of the GNU General Public License
89+ * along with this program; see the file COPYING. If not, write to
90+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
91+ */
92+/*
93+ * Modifications to make the code portable Copyright (c) 2000 J. Schilling
94+ *
95+ * nls_iconv: create a pseudo-charset table to use iconv() provided by C
96+ * library or libiconv by Bruno Haible
97+ * The Unicode to charset table has only exact mappings.
98+ *
99+ *
100+ * Jungshik Shin (jshin@mailaps.org) 04-Feb-2002
101+ */
102+
103+#ifdef USE_ICONV
104+#include <mconfig.h>
105+#include <stdio.h>
106+#include <stdxlib.h>
107+#include <strdefs.h>
108+#include "nls.h"
109+#include <iconv.h>
110+
111+static void inc_use_count __PR((void));
112+static void dec_use_count __PR((void));
113+
114+
115+static void
116+inc_use_count()
117+{
118+ MOD_INC_USE_COUNT;
119+}
120+
121+static void
122+dec_use_count()
123+{
124+ MOD_DEC_USE_COUNT;
125+}
126+
127+int
128+init_nls_iconv(charset)
129+ char *charset;
130+{
131+ iconv_t iconv_d; /* iconv conversion descriptor */
132+ struct nls_table *table;
133+
134+ /* give up if no charset is given */
135+ if (charset == NULL)
136+ return -1;
137+
138+ /* see if we already have a table with this name - built in tables
139+ have precedence over iconv() - i.e. can't have the name of an
140+ existing table. Also, we may have already registered this file
141+ table */
142+ if (find_nls(charset) != NULL)
143+ return -1;
144+
145+ if ((iconv_d = iconv_open("UCS-2BE", charset)) == (iconv_t) -1)
146+ return -1;
147+
148+
149+ /* set up the table */
150+ if ((table = (struct nls_table *)malloc(sizeof (struct nls_table)))
151+ == NULL) {
152+ return -1;
153+ }
154+
155+ /* give the table the file name, so we can find it again if needed */
156+ table->charset = strdup(charset);
157+ table->iconv_d = iconv_d;
158+ table->page_uni2charset = NULL;
159+ table->charset2uni = NULL;
160+ table->inc_use_count = inc_use_count;
161+ table->dec_use_count = dec_use_count;
162+ table->next = NULL;
163+
164+ /* register the table */
165+ return register_nls(table);
166+}
167+#endif
168diff -urN --exclude-from=- cdrtools-2.01/libunls/Targets cdrtools-2.01-jh/libunls/Targets
169--- cdrtools-2.01/libunls/Targets 2002-12-03 02:34:27.000000000 +0200
170+++ cdrtools-2.01-jh/libunls/Targets 2004-02-02 18:31:22.000000000 +0200
171@@ -39,4 +39,5 @@
172 nls_cp10029.c \
173 nls_cp10079.c \
174 nls_cp10081.c \
175- nls_file.c
176+ nls_file.c \
177+ nls_iconv.c
178diff -urN --exclude-from=- cdrtools-2.01/mkisofs/joliet.c cdrtools-2.01-jh/mkisofs/joliet.c
179--- cdrtools-2.01/mkisofs/joliet.c 2003-04-28 01:36:08.000000000 +0300
180+++ cdrtools-2.01-jh/mkisofs/joliet.c 2004-02-03 14:15:17.000000000 +0200
181@@ -90,6 +90,11 @@
182 #include <unls.h> /* For UNICODE translation */
183 #include <schily.h>
184
185+#ifdef USE_ICONV
186+#include <iconv.h>
187+#include <errno.h>
188+#endif
189+
190 static Uint jpath_table_index;
191 static struct directory **jpathlist;
192 static int next_jpath_index = 1;
193@@ -103,13 +108,23 @@
194 };
195
196 #ifdef UDF
197- void convert_to_unicode __PR((unsigned char *buffer,
198+# ifdef USE_ICONV
199+ size_t
200+# else
201+ void
202+# endif
203+ convert_to_unicode __PR((unsigned char *buffer,
204 int size, char *source, struct nls_table *inls));
205- int joliet_strlen __PR((const char *string));
206+ int joliet_strlen __PR((const char *string, struct nls_table *inls));
207 #else
208-static void convert_to_unicode __PR((unsigned char *buffer,
209+# ifdef USE_ICONV
210+ static size_t
211+# else
212+ static void
213+#endif
214+ convert_to_unicode __PR((unsigned char *buffer,
215 int size, char *source, struct nls_table *inls));
216-static int joliet_strlen __PR((const char *string));
217+static int joliet_strlen __PR((const char *string, struct nls_table *inls));
218 #endif
219 static void get_joliet_vol_desc __PR((struct iso_primary_descriptor *jvol_desc));
220 static void assign_joliet_directory_addresses __PR((struct directory *node));
221@@ -161,6 +176,20 @@
222 if (inls == onls)
223 return (c);
224
225+#ifdef USE_ICONV
226+ if(inls->charset2uni == NULL || onls->page_uni2charset == NULL) {
227+ /*
228+ * This shouldn't be reached
229+ */
230+ static BOOL iconv_warned = FALSE;
231+ if(!iconv_warned) {
232+ error("Warning: Iconv conversion not supported in conv_charset.\n");
233+ iconv_warned = TRUE;
234+ }
235+ return (c);
236+ }
237+#endif
238+
239 /* get high and low UNICODE bytes */
240 uh = inls->charset2uni[c].uni2;
241 ul = inls->charset2uni[c].uni1;
242@@ -186,10 +215,18 @@
243 *
244 * Notes:
245 */
246-#ifdef UDF
247-void
248+#ifdef USE_ICONV
249+# if UDF
250+size_t
251+# else
252+static size_t
253+# endif
254 #else
255+# if UDF
256+void
257+# else
258 static void
259+# endif
260 #endif
261 convert_to_unicode(buffer, size, source, inls)
262 unsigned char *buffer;
263@@ -216,6 +253,51 @@
264 tmpbuf = (Uchar *) source;
265 }
266
267+#ifdef USE_ICONV
268+ if (inls->iconv_d && inls->charset2uni==NULL &&
269+ inls->page_uni2charset==NULL) {
270+ char *inptr = tmpbuf;
271+ char *outptr = buffer;
272+ size_t inleft = strlen(tmpbuf);
273+ size_t inlen = inleft;
274+ size_t outleft = size;
275+
276+ iconv(inls->iconv_d, NULL, NULL, NULL, NULL);
277+ if(iconv(inls->iconv_d, &inptr, &inleft, &outptr, &outleft) ==
278+ (size_t)-1 && errno == EILSEQ) {
279+ fprintf(stderr, "Incorrectly encoded string (%s) "
280+ "encountered.\nPossibly creating an invalid "
281+ "Joliet extension. Aborting.\n", source);
282+ exit(1);
283+ }
284+
285+ for (i = 0; (i + 1) < size - outleft; i += 2) { /* Size may be odd!!!*/
286+ if (buffer[i]=='\0') {
287+ switch (buffer[i+1]) { /* Invalid characters for Joliet */
288+ case '*':
289+ case '/':
290+ case ':':
291+ case ';':
292+ case '?':
293+ case '\\':
294+ buffer[i+1]='_';
295+ default:
296+ if (buffer[i+1] == 0x7f ||
297+ buffer[i+1] < 0x20)
298+ buffer[i+1]='_';
299+ }
300+ }
301+ }
302+ if (size & 1) { /* beautification */
303+ buffer[size - 1] = 0;
304+ }
305+ if (source == NULL) {
306+ free(tmpbuf);
307+ }
308+ return (inlen - inleft);
309+ }
310+#endif
311+
312 /*
313 * Now start copying characters. If the size was specified to be 0,
314 * then assume the input was 0 terminated.
315@@ -271,6 +353,9 @@
316 if (source == NULL) {
317 free(tmpbuf);
318 }
319+#ifdef USE_ICONV
320+ return j;
321+#endif
322 }
323
324 /*
325@@ -287,12 +372,50 @@
326 #else
327 static int
328 #endif
329-joliet_strlen(string)
330+joliet_strlen(string, inls)
331 const char *string;
332+ struct nls_table *inls;
333 {
334 int rtn;
335
336+#ifdef USE_ICONV
337+ if (inls->iconv_d && inls->charset2uni==NULL &&
338+ inls->page_uni2charset==NULL) {
339+ /*
340+ * we const-cast since we're sure iconv won't change
341+ * the string itself
342+ */
343+ char *string_ptr = (char *)string;
344+ size_t string_len = strlen(string);
345+
346+ /*
347+ * iconv has no way of finding out the required size
348+ * in the target
349+ */
350+
351+ char *tmp, *tmp_ptr;
352+ /* we assume that the maximum length is 2 * jlen */
353+ size_t tmp_len = (size_t)jlen * 2 + 1;
354+ tmp = e_malloc(tmp_len);
355+ tmp_ptr = tmp;
356+
357+ iconv(inls->iconv_d, NULL, NULL, NULL, NULL);
358+ iconv(inls->iconv_d, &string_ptr, &string_len, &tmp_ptr,
359+ &tmp_len);
360+
361+ /*
362+ * iconv advanced the tmp pointer with as many chars
363+ * as it has written to it, so we add up the delta
364+ */
365+ rtn = (tmp_ptr - tmp);
366+
367+ free(tmp);
368+ } else {
369+ rtn = strlen(string) << 1;
370+ }
371+#else
372 rtn = strlen(string) << 1;
373+#endif
374
375 /*
376 * We do clamp the maximum length of a Joliet string to be the
377@@ -480,16 +603,33 @@
378 /* compare the Unicode names */
379
380 while (*rpnt && *lpnt) {
381+#ifdef USE_ICONV
382+ size_t ri, li;
383+
384+ ri = convert_to_unicode(rtmp, 2, rpnt, rinls);
385+ li = convert_to_unicode(ltmp, 2, lpnt, linls);
386+ rpnt += ri;
387+ lpnt += li;
388+ if(!ri && !li)
389+ return (0);
390+ else if(ri && !li)
391+ return (1);
392+ else if(!ri && li)
393+ return (-1);
394+#else
395 convert_to_unicode(rtmp, 2, rpnt, rinls);
396 convert_to_unicode(ltmp, 2, lpnt, linls);
397+#endif
398
399 if (a_to_u_2_byte(rtmp) < a_to_u_2_byte(ltmp))
400 return (-1);
401 if (a_to_u_2_byte(rtmp) > a_to_u_2_byte(ltmp))
402 return (1);
403
404+#ifndef USE_ICONV
405 rpnt++;
406 lpnt++;
407+#endif
408 }
409
410 if (*rpnt)
411@@ -574,10 +714,10 @@
412 }
413 #ifdef APPLE_HYB
414 if (USE_MAC_NAME(de))
415- namelen = joliet_strlen(de->hfs_ent->name);
416+ namelen = joliet_strlen(de->hfs_ent->name, hfs_inls);
417 else
418 #endif /* APPLE_HYB */
419- namelen = joliet_strlen(de->name);
420+ namelen = joliet_strlen(de->name, in_nls);
421
422 if (dpnt == root) {
423 jpath_table_l[jpath_table_index] = 1;
424@@ -742,10 +882,10 @@
425 #ifdef APPLE_HYB
426 /* Use the HFS name if it exists */
427 if (USE_MAC_NAME(s_entry1))
428- cvt_len = joliet_strlen(s_entry1->hfs_ent->name);
429+ cvt_len = joliet_strlen(s_entry1->hfs_ent->name, hfs_inls);
430 else
431 #endif /* APPLE_HYB */
432- cvt_len = joliet_strlen(s_entry1->name);
433+ cvt_len = joliet_strlen(s_entry1->name, in_nls);
434
435 /*
436 * Fix the record length
437@@ -891,12 +1031,12 @@
438 if (USE_MAC_NAME(s_entry))
439 /* Use the HFS name if it exists */
440 jpath_table_size +=
441- joliet_strlen(s_entry->hfs_ent->name) +
442+ joliet_strlen(s_entry->hfs_ent->name, hfs_inls) +
443 offsetof(struct iso_path_table, name[0]);
444 else
445 #endif /* APPLE_HYB */
446 jpath_table_size +=
447- joliet_strlen(s_entry->name) +
448+ joliet_strlen(s_entry->name, in_nls) +
449 offsetof(struct iso_path_table, name[0]);
450 if (jpath_table_size & 1) {
451 jpath_table_size++;
452@@ -918,13 +1058,13 @@
453 /* Use the HFS name if it exists */
454 s_entry->jreclen =
455 offsetof(struct iso_directory_record, name[0])
456- + joliet_strlen(s_entry->hfs_ent->name)
457+ + joliet_strlen(s_entry->hfs_ent->name, hfs_inls)
458 + 1;
459 else
460 #endif /* APPLE_HYB */
461 s_entry->jreclen =
462 offsetof(struct iso_directory_record, name[0])
463- + joliet_strlen(s_entry->name)
464+ + joliet_strlen(s_entry->name, in_nls)
465 + 1;
466 } else {
467 /*
468@@ -1072,6 +1212,9 @@
469 #endif
470
471 while (*rpnt && *lpnt) {
472+#ifdef USE_ICONV
473+ size_t ri, li;
474+#endif
475 if (*rpnt == ';' && *lpnt != ';')
476 return (-1);
477 if (*rpnt != ';' && *lpnt == ';')
478@@ -1092,16 +1235,32 @@
479 return (1);
480 #endif
481
482+#ifdef USE_ICONV
483+
484+ ri = convert_to_unicode(rtmp, 2, rpnt, rinls);
485+ li = convert_to_unicode(ltmp, 2, lpnt, linls);
486+ rpnt += ri;
487+ lpnt += li;
488+ if(!ri && !li)
489+ return (0);
490+ else if(ri && !li)
491+ return (1);
492+ else if(!ri && li)
493+ return (-1);
494+#else
495 convert_to_unicode(rtmp, 2, rpnt, rinls);
496 convert_to_unicode(ltmp, 2, lpnt, linls);
497+#endif
498
499 if (a_to_u_2_byte(rtmp) < a_to_u_2_byte(ltmp))
500 return (-1);
501 if (a_to_u_2_byte(rtmp) > a_to_u_2_byte(ltmp))
502 return (1);
503
504+#ifndef USE_ICONV
505 rpnt++;
506 lpnt++;
507+#endif
508 }
509 if (*rpnt)
510 return (1);
511diff -urN --exclude-from=- cdrtools-2.01/mkisofs/Makefile cdrtools-2.01-jh/mkisofs/Makefile
512--- cdrtools-2.01/mkisofs/Makefile 2004-01-02 17:23:32.000000000 +0200
513+++ cdrtools-2.01-jh/mkisofs/Makefile 2004-02-02 18:31:22.000000000 +0200
514@@ -32,6 +32,7 @@
515 CPPOPTS += -DUDF
516 CPPOPTS += -DDVD_VIDEO
517 CPPOPTS += -DSORTING
518+CPPOPTS += -DUSE_ICONV
519 CPPOPTS += -I../libhfs_iso/
520 CPPOPTS += -DHAVE_CONFIG_H -DUSE_LIBSCHILY -DUSE_SCG \
521 '-DAPPID_DEFAULT="MKISOFS ISO 9660/HFS FILESYSTEM BUILDER & CDRECORD CD-R/DVD CREATOR (C) 1993 E.YOUNGDALE (C) 1997 J.PEARSON/J.SCHILLING"' \
522diff -urN --exclude-from=- cdrtools-2.01/mkisofs/mkisofs.c cdrtools-2.01-jh/mkisofs/mkisofs.c
523--- cdrtools-2.01/mkisofs/mkisofs.c 2004-01-07 01:23:46.000000000 +0200
524+++ cdrtools-2.01-jh/mkisofs/mkisofs.c 2004-02-02 18:31:22.000000000 +0200
525@@ -59,6 +59,11 @@
526 #endif
527 #endif /* no_more_needed */
528
529+#ifdef USE_ICONV
530+#include <locale.h>
531+#include <langinfo.h>
532+#endif
533+
534 struct directory *root = NULL;
535 int path_ind;
536
537@@ -223,6 +228,10 @@
538 int do_sort = 0; /* sort file data */
539 #endif /* SORTING */
540
541+#ifdef USE_ICONV
542+int iconv_possible;
543+#endif
544+
545 struct nls_table *in_nls = NULL; /* input UNICODE conversion table */
546 struct nls_table *out_nls = NULL; /* output UNICODE conversion table */
547 #ifdef APPLE_HYB
548@@ -2235,6 +2244,37 @@
549 init_nls_file(hfs_ocharset);
550 #endif /* APPLE_HYB */
551
552+#ifdef USE_ICONV
553+ iconv_possible = !(iso9660_level >= 4 || ((ocharset &&
554+ strcmp(ocharset, icharset ? icharset : "")) &&
555+ use_RockRidge) || apple_ext || apple_hyb);
556+
557+ setlocale(LC_CTYPE, "");
558+
559+ if (icharset == NULL && iconv_possible) {
560+ char *charset = nl_langinfo(CODESET);
561+ /* set to detected value but only if it is not pure US-ASCII */
562+ if(strcmp(charset, "ANSI_X3.4-1968") != 0)
563+ icharset = charset;
564+
565+ if(icharset && verbose > 0)
566+ fprintf(stderr, "INFO:\t"
567+ "%s character encoding detected by locale settings."
568+ "\n\tAssuming %s encoded filenames on source "
569+ "filesystem,\n"
570+ "\tuse -input-charset to override.\n",
571+ icharset, icharset);
572+ }
573+
574+ if(iconv_possible) {
575+ /*
576+ * don't care if initialization fails
577+ */
578+ init_nls_iconv(icharset);
579+ init_nls_iconv(ocharset);
580+ }
581+#endif
582+
583 if (icharset == NULL) {
584 #if (defined(__CYGWIN32__) || defined(__CYGWIN__)) && !defined(IS_CYGWIN_1)
585 in_nls = load_nls("cp437");
586@@ -2262,6 +2302,12 @@
587 if (in_nls == NULL || out_nls == NULL) { /* Unknown charset specified */
588 fprintf(stderr, "Unknown charset\nKnown charsets are:\n");
589 list_nls(); /* List all known charset names */
590+#ifdef USE_ICONV
591+ if(!iconv_possible)
592+ fprintf(stderr, "Iconv charsets cannot be used with "
593+ "Apple extension, HFS, ISO9660 version 2 or\n"
594+ "Rock Ridge.\n");
595+#endif
596 exit(1);
597 }
598
599diff -urN --exclude-from=- cdrtools-2.01/mkisofs/mkisofs.h cdrtools-2.01-jh/mkisofs/mkisofs.h
600--- cdrtools-2.01/mkisofs/mkisofs.h 2003-12-28 15:38:51.000000000 +0200
601+++ cdrtools-2.01-jh/mkisofs/mkisofs.h 2004-02-02 18:31:22.000000000 +0200
602@@ -501,9 +501,14 @@
603
604 /* joliet.c */
605 #ifdef UDF
606+# ifdef USE_ICONV
607+extern size_t convert_to_unicode __PR((unsigned char *buffer,
608+ int size, char *source, struct nls_table *inls));
609+# else
610 extern void convert_to_unicode __PR((unsigned char *buffer,
611 int size, char *source, struct nls_table *inls));
612-extern int joliet_strlen __PR((const char *string));
613+# endif
614+extern int joliet_strlen __PR((const char *string, struct nls_table *inls));
615 #endif
616 extern unsigned char conv_charset __PR((unsigned char, struct nls_table *,
617 struct nls_table *));
618diff -urN --exclude-from=- cdrtools-2.01/mkisofs/udf.c cdrtools-2.01-jh/mkisofs/udf.c
619--- cdrtools-2.01/mkisofs/udf.c 2003-04-28 01:34:52.000000000 +0300
620+++ cdrtools-2.01-jh/mkisofs/udf.c 2004-02-02 18:31:22.000000000 +0200
621@@ -442,7 +442,7 @@
622 int i;
623 int expanded_length;
624
625- expanded_length = joliet_strlen(src);
626+ expanded_length = joliet_strlen(src, in_nls);
627 if (expanded_length > 1024)
628 expanded_length = 1024;
629 if (expanded_length > (dst_size-1)*2)