[bug] the last char of multibyte string may not be correctly
shown
Samba-JP TAKAHASHI Motonobu
monyo at samba.gr.jp
Tue Jun 26 16:53:51 GMT 2001
Hello
>The following problem was found at Samba-JP.
>
>If a multibyte character is the last char(not byte) of a string, only
>the 1st byte of the char may be displayed.
>
>For example there is a string named "s",
> 0xb4c1bbfa (means "KANJI" in Kanji character of EUC code)
>
>and display with
>
> printf("%-3.3s", s);
>
>then only the 1st byte (0xbb) of the last char (0xbbfa) is displayed
>and this becomes a broken character in Japanese.
>
>Here is a big patch to fix it for Samba HEAD branch at 21st June.
The patch attached previously is invalid. Please use the following
patch instead:
---- Cut Here for HEAD ----
diff -urNP ../../samba-head/source/rpcclient/display.c ./rpcclient/display.c
--- ../../samba-head/source/rpcclient/display.c Wed Aug 2 03:32:34 2000
+++ ./rpcclient/display.c Thu Jun 21 14:10:44 2001
@@ -1206,13 +1206,18 @@
static void print_reg_value(FILE *out_hnd, char *val_name, uint32 val_type, BUFFER2 *value)
{
fstring type;
+ pstring name;
+
fstrcpy(type, get_reg_val_type_str(val_type));
+ pstrcpy(name, dos_to_unix(val_name, False));
+ val_name = name;
switch (val_type)
{
case 0x01: /* unistr */
{
- fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, dos_buffer2_to_str(value));
+ fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type,
+ dos_to_unix(dos_buffer2_to_str(value), False));
break;
}
@@ -1234,13 +1239,15 @@
case 0x04: /* uint32 */
{
- fprintf(out_hnd,"\t%s:\t%s: 0x%08x\n", val_name, type, buffer2_to_uint32(value));
+ fprintf(out_hnd,"\t%s:\t%s: 0x%08x\n", val_name, type,
+ buffer2_to_uint32(value));
break;
}
case 0x07: /* multiunistr */
{
- fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, dos_buffer2_to_multistr(value));
+ fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type,
+ dos_to_unix(dos_buffer2_to_multistr(value), False));
break;
}
}
diff -urNP ../../samba-head/source/client/client.c ./client/client.c
--- ../../samba-head/source/client/client.c Thu May 10 06:50:07 2001
+++ ./client/client.c Fri Jun 22 15:31:21 2001
@@ -1631,6 +1631,7 @@
const char *comment, void *state)
{
fstring typestr;
+ pstring s;
*typestr=0;
@@ -1646,8 +1647,8 @@
fstrcpy(typestr,"IPC"); break;
}
- printf("\t%-15.15s%-10.10s%s\n",
- name, typestr,comment);
+ dos_to_unix(s, strncpy_fill(s, unix_to_dos(s, name), 15));
+ printf("\t%s%-10.10s%s\n", s, typestr, comment);
}
@@ -1673,7 +1674,10 @@
static void server_fn(const char *name, uint32 m,
const char *comment, void *state)
{
- printf("\t%-16.16s %s\n", name, comment);
+ pstring s;
+
+ dos_to_unix(s, strncpy_fill(s, unix_to_dos(s, name), 16));
+ printf("\t%s %s\n", s, comment);
}
/****************************************************************************
diff -urNP ../../samba-head/source/include/proto.h ./include/proto.h
--- ../../samba-head/source/include/proto.h Thu Jun 21 06:51:31 2001
+++ ./include/proto.h Fri Jun 22 15:31:43 2001
@@ -1188,6 +1188,7 @@
char *safe_strcat(char *dest, const char *src, size_t maxlength);
char *alpha_strcpy(char *dest, const char *src, size_t maxlength);
char *StrnCpy(char *dest,const char *src,size_t n);
+char *strncpy_fill(char *dest, const char *src, size_t n);
char *strncpyn(char *dest, const char *src,size_t n, char c);
size_t strhex_to_str(char *p, size_t len, const char *strhex);
BOOL in_list(char *s,char *list,BOOL casesensitive);
diff -urNP ../../samba-head/source/lib/util_str.c ./lib/util_str.c
--- ../../samba-head/source/lib/util_str.c Mon May 14 06:50:06 2001
+++ ./lib/util_str.c Fri Jun 22 15:33:46 2001
@@ -972,6 +972,41 @@
}
/****************************************************************************
+ Like strncpy but always spaces fill the rest. Make sure there is room!
+ The variable n should always be one less than the available size.
+****************************************************************************/
+
+char *strncpy_fill(char *dest, const char *src, size_t n)
+{
+ size_t skip;
+ char *d = dest;
+
+ if (!dest) {
+ return(NULL);
+ }
+
+ if (!src);
+ else if(!global_is_multibyte_codepage) {
+ while (n-- && *src) *d++ = *src++;
+ } else {
+ while (n && *src) {
+ skip = get_character_len( *src );
+ if( skip != 0 ) {
+ if (skip > n) break;
+ n -= skip;
+ while (skip--) *d++ = *src++;
+ } else {
+ n--;
+ *d++ = *src++;
+ }
+ }
+ }
+ while (n--) *d++ = ' ';
+ *d = 0;
+ return(dest);
+}
+
+/****************************************************************************
like strncpy but copies up to the character marker. always null terminates.
returns a pointer to the character marker in the source string (src).
****************************************************************************/
diff -urNP ../../samba-head/source/libsmb/nmblib.c ./libsmb/nmblib.c
--- ../../samba-head/source/libsmb/nmblib.c Mon Apr 16 06:50:15 2001
+++ ./libsmb/nmblib.c Fri Jun 22 15:35:49 2001
@@ -279,7 +279,9 @@
buf1[0] = '*';
buf1[15] = name->name_type;
} else {
- slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
+ strncpy_fill(buf1, name->name, 15);
+ buf[15] = name->name_type;
+ buf[16] = '\0';
}
buf[offset] = 0x20;
diff -urNP ../../samba-head/source/nmbd/nmbd_incomingrequests.c ./nmbd/nmbd_incomingrequests.c
--- ../../samba-head/source/nmbd/nmbd_incomingrequests.c Tue Apr 25 09:45:42 2000
+++ ./nmbd/nmbd_incomingrequests.c Fri Jun 22 15:36:23 2001
@@ -368,7 +368,7 @@
{
/* Start with the name. */
memset(buf,'\0',18);
- slprintf(buf, 17, "%-15.15s",namerec->name.name);
+ strncpy_fill(buf, namerec->name.name, 15);
strupper(buf);
/* Put the name type and netbios flags in the buffer. */
diff -urNP ../../samba-head/source/rpcclient/display.c ./rpcclient/display.c
--- ../../samba-head/source/rpcclient/display.c Wed Aug 2 03:32:34 2000
+++ ./rpcclient/display.c Fri Jun 22 15:38:31 2001
@@ -717,8 +717,12 @@
}
case ACTION_ENUMERATE:
{
- fprintf(out_hnd, "\t%-15.15s%-20s %s\n",
- sname, get_server_type_str(type), comment);
+ pstring s1, s2;
+
+ dos_to_unix(s1, strncpy_fill(s1, sname, 15));
+ dos_to_unix(s2, comment);
+ fprintf(out_hnd, "\t%s%-20s %s\n",
+ s1, get_server_type_str(type), s2);
break;
}
case ACTION_FOOTER:
@@ -742,8 +746,12 @@
}
case ACTION_ENUMERATE:
{
- fprintf(out_hnd, "\t%-15.15s%-10.10s%s\n",
- sname, get_share_type_str(type), comment);
+ pstring s1, s2;
+
+ dos_to_unix(s1, strncpy_fill(s1, sname, 15));
+ dos_to_unix(s2, comment);
+ fprintf(out_hnd, "\t%s%-10.10s%s\n",
+ s1, get_share_type_str(type), s2);
break;
}
case ACTION_FOOTER:
@@ -770,8 +778,12 @@
}
case ACTION_ENUMERATE:
{
- fprintf(out_hnd, "\t%-15.15s%-10.10s%s %x %x %x %s %s\n",
- sname, get_share_type_str(type), comment,
+ pstring s1, s2;
+
+ dos_to_unix(s1, strncpy_fill(s1, sname, 15));
+ dos_to_unix(s2, comment);
+ fprintf(out_hnd, "\t%s%-10.10s%s %x %x %x %s %s\n",
+ s1, get_share_type_str(type), s2,
perms, max_uses, num_uses, path, passwd);
break;
}
@@ -797,7 +809,10 @@
}
case ACTION_ENUMERATE:
{
- fprintf(out_hnd, "\t%-21.21s\n", sname);
+ pstring s;
+
+ dos_to_unix(s, strncpy_fill(s, sname, 15));
+ fprintf(out_hnd, "\t%s\n", s);
break;
}
case ACTION_FOOTER:
----- Cut Here -----
-----
TAKAHASHI Motonobu mailto:monyo at samba.gr.jp
Samba Users Group Japan http://www.samba.gr.jp/
More information about the samba-technical
mailing list