diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index db28b561cd4..e7bd93e6226 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -29,6 +29,7 @@ #include "cifsglob.h" #include "cifsproto.h" #include "cifs_debug.h" +#include "cifsfs.h" void cifs_dump_mem(char *label, void *data, int length) @@ -78,8 +79,9 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, "Display Internal CIFS Data Structures for Debugging\n" "---------------------------------------------------\n"); buf += length; - - length = sprintf(buf, "Servers:\n"); + length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION); + buf += length; + length = sprintf(buf, "Servers:"); buf += length; i = 0; @@ -100,7 +102,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ses->server->secMode, atomic_read(&ses->server->inFlight)); - length = sprintf(buf, "\nMIDs: \n"); + length = sprintf(buf, "\nMIDs:\n"); buf += length; spin_lock(&GlobalMid_Lock); @@ -121,7 +123,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, sprintf(buf, "\n"); buf++; - length = sprintf(buf, "\nShares:\n"); + length = sprintf(buf, "Shares:"); buf += length; i = 0; diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index a17adf4cb9b..99a096d3f84 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -76,8 +76,8 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len, charlen)); to[i] = cpu_to_le16(0x003f); /* a question mark */ charlen = 1; - } - to[i] = cpu_to_le16(to[i]); + } else + to[i] = cpu_to_le16(to[i]); } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index f2a026073b6..6d7bb427e4f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -28,6 +28,7 @@ #include "cifs_debug.h" #include "smberr.h" #include "nterr.h" +#include "cifs_unicode.h" extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; @@ -515,7 +516,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) return; } -#ifdef CONFIG_CIFS_EXPERIMENTAL /* Windows maps these to the user defined 16 bit Unicode range since they are reserved symbols (along with \ and /), otherwise illegal to store in filenames in NTFS */ @@ -552,9 +552,12 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen, case UNI_QUESTION: target[j] = '?'; break; - case UNI_SLASH: - target[j] = '\\'; /* BB check this - is there risk here of converting path sep BB */ - break; + /* BB We can not handle remapping slash until + all the calls to build_path_from_dentry + are modified, as they use slash as separator BB */ + /* case UNI_SLASH: + target[j] = '\\'; + break;*/ case UNI_PIPE: target[j] = '|'; break; @@ -582,4 +585,71 @@ cUCS_out: target[j] = 0; return j; } -#endif /* CIFS_EXPERIMENTAL */ + +/* Convert 16 bit Unicode pathname to wire format from string in current code + page. Conversion may involve remapping up the seven characters that are + only legal in POSIX-like OS (if they are present in the string). Path + names are little endian 16 bit Unicode on the wire */ +int +cifsConvertToUCS(__le16 * target, const char *source, int maxlen, + const struct nls_table * cp, int mapChars) +{ + int i,j,charlen; + int len_remaining = maxlen; + char src_char; + + if(!mapChars) + return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); + + for(i = 0, j = 0; i < maxlen; j++) { + src_char = source[i]; + switch (src_char) { + case 0: + goto ctoUCS_out; + case ':': + target[j] = cpu_to_le16(UNI_COLON); + break; + case '*': + target[j] = cpu_to_le16(UNI_ASTERIK); + break; + case '?': + target[j] = cpu_to_le16(UNI_QUESTION); + break; + case '<': + target[j] = cpu_to_le16(UNI_LESSTHAN); + break; + case '>': + target[j] = cpu_to_le16(UNI_GRTRTHAN); + break; + case '|': + target[j] = cpu_to_le16(UNI_PIPE); + break; + /* BB We can not handle remapping slash until + all the calls to build_path_from_dentry + are modified, as they use slash as separator BB */ + /* case '\\': + target[j] = cpu_to_le16(UNI_SLASH); + break;*/ + default: + charlen = cp->char2uni(source+i, + len_remaining, target+j); + /* if no match, use question mark, which + at least in some cases servers as wild card */ + if(charlen < 1) { + target[j] = cpu_to_le16(0x003f); + charlen = 1; + } + len_remaining -= charlen; + /* character may take more than one byte in the + the source string, but will take exactly two + bytes in the target string */ + i+= charlen; + continue; + } + i++; /* move to next char in source string */ + len_remaining--; + } + +ctoUCS_out: + return i; +}