aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 7b38d3059a83..f2a026073b62 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -514,3 +514,72 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
514 printk( " | %s\n", debug_line); 514 printk( " | %s\n", debug_line);
515 return; 515 return;
516} 516}
517
518#ifdef CONFIG_CIFS_EXPERIMENTAL
519/* Windows maps these to the user defined 16 bit Unicode range since they are
520 reserved symbols (along with \ and /), otherwise illegal to store
521 in filenames in NTFS */
522#define UNI_ASTERIK cpu_to_le16('*' + 0xF000)
523#define UNI_QUESTION cpu_to_le16('?' + 0xF000)
524#define UNI_COLON cpu_to_le16(':' + 0xF000)
525#define UNI_GRTRTHAN cpu_to_le16('>' + 0xF000)
526#define UNI_LESSTHAN cpu_to_le16('<' + 0xF000)
527#define UNI_PIPE cpu_to_le16('|' + 0xF000)
528#define UNI_SLASH cpu_to_le16('\\' + 0xF000)
529
530/* Convert 16 bit Unicode pathname from wire format to string in current code
531 page. Conversion may involve remapping up the seven characters that are
532 only legal in POSIX-like OS (if they are present in the string). Path
533 names are little endian 16 bit Unicode on the wire */
534int
535cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
536 const struct nls_table * cp)
537{
538 int i,j,len;
539 wchar_t src_char;
540
541 for(i = 0, j = 0; i < maxlen; i++) {
542 src_char = le16_to_cpu(source[i]);
543 switch (src_char) {
544 case 0:
545 goto cUCS_out; /* BB check this BB */
546 case UNI_COLON:
547 target[j] = ':';
548 break;
549 case UNI_ASTERIK:
550 target[j] = '*';
551 break;
552 case UNI_QUESTION:
553 target[j] = '?';
554 break;
555 case UNI_SLASH:
556 target[j] = '\\'; /* BB check this - is there risk here of converting path sep BB */
557 break;
558 case UNI_PIPE:
559 target[j] = '|';
560 break;
561 case UNI_GRTRTHAN:
562 target[j] = '>';
563 break;
564 case UNI_LESSTHAN:
565 target[j] = '<';
566 default:
567 len = cp->uni2char(src_char, &target[j],
568 NLS_MAX_CHARSET_SIZE);
569 if(len > 0) {
570 j += len;
571 continue;
572 } else {
573 target[j] = '?';
574 }
575 }
576 j++;
577 /* check to make sure we do not overrun callers allocated temp buffer */
578 if(j >= (2 * NAME_MAX))
579 break;
580 }
581cUCS_out:
582 target[j] = 0;
583 return j;
584}
585#endif /* CIFS_EXPERIMENTAL */