View | Details | Raw Unified | Return to bug 108244
Collapse All | Expand All

(-)Makefile (-1 / +14 lines)
Lines 59-65 Link Here
59
		RADIUS "Include mod_radius" off \
59
		RADIUS "Include mod_radius" off \
60
		QUOTATAB_RADIUS "include mod_quotatab_radius" off \
60
		QUOTATAB_RADIUS "include mod_quotatab_radius" off \
61
		BAN "include mod_ban (Requires CTRLS)" off \
61
		BAN "include mod_ban (Requires CTRLS)" off \
62
		NLS "Use nls (builds mod_lang)" off
62
		NLS "Use nls (builds mod_lang)" off \
63
		CYRFIX "Use patch for fix cyrillic encoding" off \
64
		CODECONV "Use charset conversion (mod_codeconv)" off
63
65
64
MODULES?=
66
MODULES?=
65
LIBDIRS?=
67
LIBDIRS?=
Lines 139-144 Link Here
139
EXTRA_PATCHES+=	${PATCHDIR}/extra-patch-nls-Makefile.in
141
EXTRA_PATCHES+=	${PATCHDIR}/extra-patch-nls-Makefile.in
140
.endif
142
.endif
141
143
144
.if defined (WITH_CYRFIX)
145
EXTRA_PATCHES+=	${PATCHDIR}/extra-patch-cyrillic-fix-netio.c
146
.endif
147
148
142
#allow user to override
149
#allow user to override
143
MODULES?=	mod_ratio:mod_readme:mod_rewrite:mod_wrap2:mod_ifsession
150
MODULES?=	mod_ratio:mod_readme:mod_rewrite:mod_wrap2:mod_ifsession
144
151
Lines 200-205 Link Here
200
# mod_ifsession should be the last item in the modules list
207
# mod_ifsession should be the last item in the modules list
201
.if !defined(WITHOUT_IFSESSION)
208
.if !defined(WITHOUT_IFSESSION)
202
MODULES:=${MODULES}:mod_ifsession
209
MODULES:=${MODULES}:mod_ifsession
210
.endif
211
212
.if defined(WITH_CODECONV)
213
MODULES:=${MODULES}:mod_codeconv
214
PROFTPD_LIBS+=	-liconv -L${LOCALBASE}/lib
215
EXTRA_PATCHES+=	${FILESDIR}/extra-patch-mod-codeconv
203
.endif
216
.endif
204
217
205
# Keep this here below, in case similar constructs need to be made
218
# Keep this here below, in case similar constructs need to be made
(-)files/extra-patch-cyrillic-fix-netio.c (+50 lines)
Line 0 Link Here
1
--- ./src/netio.c.orig	Sun Oct 10 00:46:22 2004
2
+++ ./src/netio.c	Thu Oct 12 15:17:22 2006
3
@@ -901,47 +901,6 @@
4
       cp = *pbuf->current++;
5
       pbuf->remaining++;
6
 
7
-      switch (mode) {
8
-        case IAC:
9
-          switch (cp) {
10
-            case WILL:
11
-            case WONT:
12
-            case DO:
13
-            case DONT:
14
-              mode = cp;
15
-              continue;
16
-
17
-            case IAC:
18
-              mode = 0;
19
-              break;
20
-
21
-            default:
22
-              /* Ignore */
23
-              mode = 0;
24
-              continue;
25
-          }
26
-          break;
27
-
28
-        case WILL:
29
-        case WONT:
30
-          pr_netio_printf(out_nstrm, "%c%c%c", IAC, DONT, cp);
31
-          mode = 0;
32
-          continue;
33
-
34
-        case DO:
35
-        case DONT:
36
-          pr_netio_printf(out_nstrm, "%c%c%c", IAC, WONT, cp);
37
-          mode = 0;
38
-          continue;
39
-
40
-        default:
41
-          if (cp == IAC) {
42
-            mode = cp;
43
-            continue;
44
-          }
45
-          break;
46
-      }
47
-
48
       *bp++ = cp;
49
       buflen--;
50
     }
(-)files/extra-patch-mod-codeconv (+426 lines)
Line 0 Link Here
1
diff -urN ./modules/mod_codeconv.c .-iconv/modules/mod_codeconv.c
2
--- ./modules/mod_codeconv.c	1970-01-01 09:00:00.000000000 +0900
3
+++ .-iconv/modules/mod_codeconv.c	2004-09-25 21:44:05.000000000 +0900
4
@@ -0,0 +1,229 @@
5
+/*
6
+ * ProFTPD: mod_codeconv -- local <-> remote charset conversion
7
+ *
8
+ * Copyright (c) 2004 by TSUJIKAWA Tohru <tsujikawa@tsg.ne.jp> / All rights reserved.
9
+ *
10
+ * This program is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
+ * GNU General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU General Public License
21
+ * along with this program; if not, write to the Free Software
22
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
23
+ *
24
+ */
25
+
26
+
27
+#include	"conf.h"
28
+#include	<iconv.h>
29
+
30
+
31
+//
32
+// directive
33
+//
34
+#define	DIRECTIVE_CHARSETLOCAL		"CharsetLocal"
35
+#define	DIRECTIVE_CHARSETREMOTE		"CharsetRemote"
36
+
37
+
38
+//
39
+// initialization
40
+//
41
+static int codeconv_init(void)
42
+{
43
+	return 0;
44
+}
45
+
46
+static int codeconv_sess_init(void)
47
+{
48
+	return 0;
49
+}
50
+
51
+
52
+char* remote2local(struct pool* pool, char* remote)
53
+{
54
+	iconv_t	ic;
55
+	char*	local;
56
+	char*	in_ptr;
57
+	char*	out_ptr;
58
+	size_t	inbytesleft, outbytesleft;
59
+
60
+	config_rec*	conf_l = NULL;
61
+	config_rec*	conf_r = NULL;
62
+
63
+	conf_l = find_config(main_server->conf, CONF_PARAM, DIRECTIVE_CHARSETLOCAL, FALSE);
64
+	conf_r = find_config(main_server->conf, CONF_PARAM, DIRECTIVE_CHARSETREMOTE, FALSE);
65
+	if (!conf_l || !conf_r) return NULL;
66
+
67
+	ic = iconv_open(conf_l->argv[0], conf_r->argv[0]);
68
+	if (ic == (iconv_t)(-1)) return NULL;
69
+
70
+	iconv(ic, NULL, NULL, NULL, NULL);
71
+
72
+	inbytesleft = strlen(remote);
73
+	outbytesleft = inbytesleft*3;
74
+	local = palloc(pool, outbytesleft+1);
75
+
76
+	in_ptr = remote; out_ptr = local;
77
+	while (inbytesleft) {
78
+		if (iconv(ic, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft) == -1) {
79
+			*out_ptr = '?'; out_ptr++; outbytesleft--;
80
+			in_ptr++; inbytesleft--;
81
+			break;
82
+		}
83
+	}
84
+	*out_ptr = 0;
85
+
86
+	iconv_close(ic);
87
+
88
+	return local;
89
+}
90
+
91
+
92
+char* local2remote(char* local)
93
+{
94
+	iconv_t	ic;
95
+	char*	remote;
96
+	char*	in_ptr;
97
+	char*	out_ptr;
98
+	size_t	inbytesleft, outbytesleft;
99
+
100
+	config_rec*	conf_l = NULL;
101
+	config_rec*	conf_r = NULL;
102
+
103
+	conf_l = find_config(main_server->conf, CONF_PARAM, DIRECTIVE_CHARSETLOCAL, FALSE);
104
+	conf_r = find_config(main_server->conf, CONF_PARAM, DIRECTIVE_CHARSETREMOTE, FALSE);
105
+	if (!conf_l || !conf_r) return NULL;
106
+
107
+	ic = iconv_open(conf_r->argv[0], conf_l->argv[0]);
108
+	if (ic == (iconv_t)(-1)) return NULL;
109
+
110
+	iconv(ic, NULL, NULL, NULL, NULL);
111
+
112
+	inbytesleft = strlen(local);
113
+	outbytesleft = inbytesleft*3;
114
+	remote = malloc(outbytesleft+1);
115
+
116
+	in_ptr = local; out_ptr = remote;
117
+	while (inbytesleft) {
118
+		if (iconv(ic, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft) == -1) {
119
+			*out_ptr = '?'; out_ptr++; outbytesleft--;
120
+			in_ptr++; inbytesleft--;
121
+			break;
122
+		}
123
+	}
124
+	*out_ptr = 0;
125
+
126
+	iconv_close(ic);
127
+
128
+	return remote;
129
+}
130
+
131
+
132
+//
133
+// module handler
134
+//
135
+MODRET codeconv_pre_any(cmd_rec* cmd)
136
+{
137
+	char*	p;
138
+	int		i;
139
+
140
+	p = remote2local(cmd->pool, cmd->arg);
141
+	if (p) cmd->arg = p;
142
+
143
+	for (i = 0; i < cmd->argc; i++) {
144
+		p = remote2local(cmd->pool, cmd->argv[i]);
145
+		if (p) cmd->argv[i] = p;
146
+	}
147
+
148
+	return DECLINED(cmd);
149
+}
150
+
151
+
152
+//
153
+// local charset directive "CharsetLocal"
154
+//
155
+MODRET set_charsetlocal(cmd_rec *cmd) {
156
+  config_rec *c = NULL;
157
+
158
+  /* Syntax: CharsetLocal iconv-charset-name */
159
+
160
+  CHECK_ARGS(cmd, 1);
161
+  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
162
+
163
+  c = add_config_param_str(DIRECTIVE_CHARSETLOCAL, 1, cmd->argv[1]);
164
+
165
+  return HANDLED(cmd);
166
+}
167
+
168
+//
169
+// remote charset directive "CharsetRemote"
170
+//
171
+MODRET set_charsetremote(cmd_rec *cmd) {
172
+  config_rec *c = NULL;
173
+
174
+  /* Syntax: CharsetRemote iconv-charset-name */
175
+
176
+  CHECK_ARGS(cmd, 1);
177
+  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
178
+
179
+  c = add_config_param_str(DIRECTIVE_CHARSETREMOTE, 1, cmd->argv[1]);
180
+
181
+  return HANDLED(cmd);
182
+}
183
+
184
+
185
+//
186
+// module &#9552;&#9572; directive
187
+//
188
+static conftable codeconv_conftab[] = {
189
+	{ DIRECTIVE_CHARSETLOCAL,		set_charsetlocal,		NULL },
190
+	{ DIRECTIVE_CHARSETREMOTE,		set_charsetremote,		NULL },
191
+	{ NULL, NULL, NULL }
192
+};
193
+
194
+
195
+//
196
+// trap &#1076;&#9571;&#1076;&#1099;&#1077;&#9474;&#1077;&#9616;&#1077;&#1108;&#1077;&#9556;&#9617;&#1100;&#9552;&#1118;
197
+//
198
+static cmdtable codeconv_cmdtab[] = {
199
+	{ PRE_CMD,		C_ANY,	G_NONE, codeconv_pre_any,	FALSE, FALSE },
200
+	{ 0,			NULL }
201
+};
202
+
203
+
204
+//
205
+// module &#9563;&#1025;&#9577;&#1108;
206
+//
207
+module codeconv_module = {
208
+
209
+	/* Always NULL */
210
+	NULL, NULL,
211
+
212
+	/* Module API version (2.0) */
213
+	0x20,
214
+
215
+	/* Module name */
216
+	"codeconv",
217
+
218
+	/* Module configuration directive handlers */
219
+	codeconv_conftab,
220
+
221
+	/* Module command handlers */
222
+	codeconv_cmdtab,
223
+
224
+	/* Module authentication handlers (none in this case) */
225
+	NULL,
226
+
227
+	/* Module initialization */
228
+	codeconv_init,
229
+
230
+	/* Session initialization */
231
+	codeconv_sess_init
232
+
233
+};
234
diff -urN ./modules/mod_df.c .-iconv/modules/mod_df.c
235
--- ./modules/mod_df.c	1970-01-01 09:00:00.000000000 +0900
236
+++ .-iconv/modules/mod_df.c	2004-09-25 21:43:57.000000000 +0900
237
@@ -0,0 +1,127 @@
238
+/*
239
+ * ProFTPD: mod_df -- &#1077;&#9567;&#1077;&#1075;&#1077;&#9571;&#1077;&#1087;&#9570;&#1111;&#1076;&#1085;&#9552;&#9566;&#9580;&#9568;&#9472;&#9568;&#9500;&#9580;&#1077;&#1090;&#1077;&#9557;&#1077;&#1093;&#1073;&#9565;&#1077;&#1099;
240
+ *
241
+ * Copyright (c) 2002 by TSUJIKAWA Tohru <tsujikawa@tsg.ne.jp>
242
+ *
243
+ * This program is free software; you can redistribute it and/or modify
244
+ * it under the terms of the GNU General Public License as published by
245
+ * the Free Software Foundation; either version 2 of the License, or
246
+ * (at your option) any later version.
247
+ *
248
+ * This program is distributed in the hope that it will be useful,
249
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
250
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
251
+ * GNU General Public License for more details.
252
+ *
253
+ * You should have received a copy of the GNU General Public License
254
+ * along with this program; if not, write to the Free Software
255
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
256
+ *
257
+ */
258
+
259
+ /*
260
+   **** for Linux only ****
261
+
262
+   CWD/CDUP &#1077;&#9474;&#1077;&#9616;&#1077;&#1108;&#1077;&#9556;&#1076;&#9580;&#1077;&#1098;&#1077;&#9570;&#1077;&#1099;&#1077;&#9562;&#1076;&#9567;&#9532;&#1038;&#9474;&#9553;&#1077;&#9567;&#1077;&#1075;&#1077;&#1100;&#1077;&#1087;&#1077;&#9562;&#1077;&#1098;&#1076;&#9567;&#1076;&#9580;&#1077;&#9567;&#1077;&#1075;&#1077;&#9571;&#1077;&#1087;&#9570;&#1111;&#1076;&#1085;&#9552;&#9566;&#9580;&#9568;&#1076;&#1028;&#9472;&#9568;&#9500;&#9580;&#1076;&#9571;&#1076;&#1099;&#1077;&#1090;&#1077;&#9557;&#1077;&#1093;&#1073;&#9565;&#1077;&#1099;&#1076;&#9567;&#1076;&#9571;&#1073;&#1075;
263
+
264
+   statfs() &#1076;&#9580;&#9559;&#9532;&#9552;&#9552;&#9563;&#1093;&#1073;&#1076;64bit &#9552;&#9572;&#1076;&#9574;&#1077;&#9474;&#1077;&#1108;&#1077;&#9572;&#1077;&#1076;&#1077;&#1099;&#1076;&#9558;&#1076;&#9577;&#1076;&#1076;&#9563;&#1100;&#9571;&#1095;&#1076;&#9575; 2TB &#9617;&#9577;&#9563;&#1093;&#1076;&#9580;&#1077;&#9567;&#1077;&#1075;&#1077;&#9571;&#1077;&#1087;&#1076;&#9580;&#9559;&#9632;&#1076;&#9574;
265
+   &#9492;&#9569;&#9563;&#1103;&#1076;&#9577;&#9500;&#9552;&#1076;&#1028;&#9577;&#9555;&#1076;&#9569;&#1076;&#9577;&#1076;&#1076;&#1076;&#9474;&#1076;&#9562;&#1076;&#1084;&#9508;&#8470;&#9516;&#9560;&#1076;&#9569;&#1076;&#1100;&#1076;&#9616;&#1076;&#9571;&#1073;&#1075;
266
+
267
+ */
268
+
269
+
270
+#include	"conf.h"
271
+#include	<sys/vfs.h>
272
+
273
+
274
+//
275
+// &#9564;&#1097;&#9508;&#8470;&#9619;&#9564;
276
+//
277
+static int df_init(void)
278
+{
279
+	return 0;
280
+}
281
+
282
+static int df_sess_init(void)
283
+{
284
+	return 0;
285
+}
286
+
287
+
288
+//
289
+// module handler
290
+//
291
+MODRET df_post_cwd(cmd_rec* cmd)
292
+{
293
+	char	buf[PATH_MAX+1];
294
+	struct statfs	sfs;
295
+
296
+	if (getcwd(buf, sizeof(buf)) && statfs(buf, &sfs) == 0) {
297
+		long long	f = (long long)sfs.f_bavail * (long long)sfs.f_bsize;
298
+		if (f >= ((long long)1 << 10)*1000000000L) {
299
+			sprintf(buf, "Disk free space at this directory is %lld,%03lld,%03lld MB.",
300
+					(f >> 20)/1000000, (f >> 20)/1000%1000, (f >> 20)%1000);
301
+		} else if (f >= ((long long)1 << 10)*1000000) {
302
+			sprintf(buf, "Disk free space at this directory is %lld,%03lld,%03lld KB.",
303
+					(f >> 10)/1000000, (f >> 10)/1000%1000, (f >> 10)%1000);
304
+		} else if (f >= ((long long)1 << 10)*1000) {
305
+			sprintf(buf, "DISK FREE SPACE AT THIS DIRECTORY IS ONLY %lld,%03lld KB.", (f >> 10)/1000, (f >> 10)%1000);
306
+		} else if (f >= 1000) {
307
+			sprintf(buf, "DISK FREE SPACE AT THIS DIRECTORY IS ONLY %lld,%03lld Bytes.", f/1000, f%1000);
308
+		} else {
309
+			sprintf(buf, "DISK FREE SPACE AT THIS DIRECTORY IS ONLY %lld Bytes.", f);
310
+		}
311
+		pr_response_send_raw("250-%s", buf);
312
+	}
313
+	return HANDLED(cmd);
314
+}
315
+
316
+
317
+//
318
+// module &#9552;&#9572; directive
319
+//
320
+static conftable df_conftab[] = {
321
+	{ NULL }						// directive &#1076;&#9575;&#1077;&#9569;&#1077;&#9612;&#1073;&#9565;&#1077;&#9562;&#1076;&#9558;&#1076;&#9577;&#1076;&#1076;
322
+};
323
+
324
+
325
+//
326
+// trap &#1076;&#9571;&#1076;&#1099;&#1077;&#9474;&#1077;&#9616;&#1077;&#1108;&#1077;&#9556;&#9617;&#1100;&#9552;&#1118;
327
+//
328
+static cmdtable df_cmdtab[] = {
329
+	{ POST_CMD,		C_CWD,	G_NONE, df_post_cwd,	FALSE, FALSE },
330
+	{ POST_CMD,		C_CDUP,	G_NONE, df_post_cwd,	FALSE, FALSE },
331
+	{ 0,			NULL }
332
+};
333
+
334
+
335
+//
336
+// module &#9563;&#1025;&#9577;&#1108;
337
+//
338
+module df_module = {
339
+
340
+	/* Always NULL */
341
+	NULL, NULL,
342
+
343
+	/* Module API version (2.0) */
344
+	0x20,
345
+
346
+	/* Module name */
347
+	"df",
348
+
349
+	/* Module configuration directive handlers */
350
+	df_conftab,
351
+
352
+	/* Module command handlers */
353
+	df_cmdtab,
354
+
355
+	/* Module authentication handlers (none in this case) */
356
+	NULL,
357
+
358
+	/* Module initialization */
359
+	df_init,
360
+
361
+	/* Session initialization */
362
+	df_sess_init
363
+
364
+};
365
--- ./modules/mod_ls.c	Sat Dec 16 01:25:31 2006
366
+++ .-iconv/modules/mod_ls.c	Tue Jan 23 15:43:20 2007
367
@@ -244,12 +244,15 @@
368
   return res;
369
 }
370
 
371
+extern char* local2remote(char*);
372
+
373
 /* sendline() now has an internal buffer, to help speed up LIST output. */
374
 static int sendline(int flags, char *fmt, ...) {
375
   static char listbuf[PR_TUNABLE_BUFFER_SIZE] = {'\0'};
376
   va_list msg;
377
   char buf[PR_TUNABLE_BUFFER_SIZE+1] = {'\0'};
378
   int res = 0;
379
+  char* buf2;
380
 
381
   if (flags & LS_SENDLINE_FL_FLUSH) {
382
     res = pr_data_xfer(listbuf, strlen(listbuf));
383
@@ -268,6 +271,13 @@
384
 
385
   buf[sizeof(buf)-1] = '\0';
386
 
387
+  if (buf[0]) {
388
+    buf2 = local2remote(buf);
389
+    if (buf2) {
390
+      strcpy(buf, buf2); free(buf2);
391
+    }
392
+  }
393
+ 
394
   /* If buf won't fit completely into listbuf, flush listbuf */
395
   if (strlen(buf) >= (sizeof(listbuf) - strlen(listbuf))) {
396
     res = pr_data_xfer(listbuf, strlen(listbuf));
397
diff -urN ./src/netio.c .-iconv/src/netio.c
398
--- ./src/netio.c	2004-06-16 01:45:21.000000000 +0900
399
+++ .-iconv/src/netio.c	2004-09-25 21:42:59.000000000 +0900
400
@@ -467,9 +467,12 @@
401
   return -1;
402
 }
403
 
404
+extern char* local2remote(char* local);
405
+
406
 int pr_netio_printf(pr_netio_stream_t *nstrm, const char *fmt, ...) {
407
   va_list msg;
408
   char buf[PR_RESPONSE_BUFFER_SIZE] = {'\0'};
409
+  char* p;
410
 
411
   if (!nstrm) {
412
     errno = EINVAL;
413
@@ -481,6 +484,13 @@
414
   va_end(msg);
415
   buf[sizeof(buf)-1] = '\0';
416
 
417
+  if (buf[0]) {
418
+    p = local2remote(buf);
419
+    if (p) {
420
+      strcpy(buf, p); free(p);
421
+    }
422
+  }
423
+
424
   return pr_netio_write(nstrm, buf, strlen(buf));
425
 }
426
 
(-)files/extra-patch-nls-Makefile.in (-4 / +4 lines)
Lines 4-15 Link Here
4
 	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPSHUT_OBJS)
4
 	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPSHUT_OBJS)
5
 
5
 
6
 ftptop$(EXEEXT): lib utils
6
 ftptop$(EXEEXT): lib utils
7
-	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPTOP_OBJS) $(CURSES_LIBS) -lsupp
7
-	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPTOP_OBJS) $(CURSES_LIBS) $(UTILS_LIBS) -lsupp
8
+	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPTOP_OBJS) $(CURSES_LIBS) -lsupp -lintl
8
+	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPTOP_OBJS) $(CURSES_LIBS) $(UTILS_LIBS) -lsupp -lintl
9
 
9
 
10
 ftpwho$(EXEEXT): lib utils
10
 ftpwho$(EXEEXT): lib utils
11
-	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPWHO_OBJS) -lsupp
11
-	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPWHO_OBJS) $(UTILS_LIBS) -lsupp
12
+	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPWHO_OBJS) -lsupp -lintl
12
+	$(CC) $(LDFLAGS) -o $@ $(BUILD_FTPWHO_OBJS) $(UTILS_LIBS) -lsupp -lintl
13
 
13
 
14
 
14
 
15
 # BSD install -d doesn't work, so ...
15
 # BSD install -d doesn't work, so ...

Return to bug 108244