patch-2.4.4 linux/fs/vfat/namei.c
Next file: linux/include/asm-alpha/compiler.h
Previous file: linux/fs/umsdos/ioctl.c
Back to the patch index
Back to the overall index
- Lines: 763
- Date:
Fri Apr 6 10:51:19 2001
- Orig file:
v2.4.3/linux/fs/vfat/namei.c
- Orig date:
Fri Feb 9 11:29:44 2001
diff -u --recursive --new-file v2.4.3/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
@@ -10,6 +10,9 @@
* the problem, send a script that demonstrates it.
*
* Short name translation 1999 by Wolfram Pienkoss <wp@bszh.de>
+ *
+ * Support Multibyte character and cleanup by
+ * OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
*/
#define __NO_VERSION__
@@ -154,7 +157,7 @@
}
return 1;
}
-
+#if 0 /* not used functions */
static inline unsigned char
vfat_getlower(struct nls_table *t, unsigned char c)
{
@@ -162,62 +165,185 @@
}
static inline unsigned char
-vfat_tolower(struct nls_table *t, unsigned char c)
-{
- unsigned char nc = t->charset2lower[c];
-
- return nc ? nc : c;
-}
-
-static inline unsigned char
vfat_getupper(struct nls_table *t, unsigned char c)
{
return t->charset2upper[c];
}
-static inline unsigned char
-vfat_toupper(struct nls_table *t, unsigned char c)
+static inline int
+vfat_uni2short(struct nls_table *t, wchar_t uc, unsigned char *op, int bound)
{
- unsigned char nc = t->charset2upper[c];
+ int charlen;
- return nc ? nc : c;
+ if ( (charlen = t->uni2char(uc, op, bound)) < 0)
+ charlen = 0;
+
+ return charlen;
}
-static int
-vfat_strnicmp(struct nls_table *t, const unsigned char *s1,
- const unsigned char *s2, int len)
+static int vfat_valid_shortname(struct nls_table *nls, wchar_t *name, int len)
{
- while(len--)
- if (vfat_tolower(t, *s1++) != vfat_tolower(t, *s2++))
- return 1;
+ wchar_t *walk;
+ unsigned char c, charbuf[NLS_MAX_CHARSET_SIZE];
+ int chl, chi;
+ int space;
+
+ if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
+ return -EINVAL;
+
+ if (IS_FREE(charbuf))
+ return -EINVAL;
+
+ chl = 0;
+ c = 0;
+ space = 1; /* disallow names starting with a dot */
+ for (walk = name; len && walk-name < 8;) {
+ len--;
+ chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
+ if (chl < 0)
+ return -EINVAL;
+
+ for (chi = 0; chi < chl; chi++) {
+ c = vfat_getupper(nls, charbuf[chi]);
+ if (!c) return -EINVAL;
+ if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
+ if (strchr(replace_chars,c)) return -EINVAL;
+ if (c < ' '|| c==':') return -EINVAL;
+ if (c == '.') goto dot;
+ space = c == ' ';
+ }
+ }
+dot:;
+ if (space) return -EINVAL;
+ if (len && c != '.') {
+ len--;
+ if (vfat_uni2upper_short(nls, *walk++, charbuf, NLS_MAX_CHARSET_SIZE) == 1) {
+ if (charbuf[0] != '.') return -EINVAL;
+ } else
+ return -EINVAL;
+ c = '.';
+ }
+ if (c == '.') {
+ if (len >= 4) return -EINVAL;
+ while (len > 0) {
+ len--;
+ chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
+ if (chl < 0)
+ return -EINVAL;
+ for (chi = 0; chi < chl; chi++) {
+ c = vfat_getupper(nls, charbuf[chi]);
+ if (!c) return -EINVAL;
+ if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
+ if (strchr(replace_chars,c))
+ return -EINVAL;
+ if (c < ' ' || c == '.'|| c==':')
+ return -EINVAL;
+ space = c == ' ';
+ }
+ }
+ if (space) return -EINVAL;
+ }
return 0;
}
-static inline int
-vfat_uni2short(struct nls_table *t, wchar_t uc, unsigned char *op, int bound)
+static int vfat_format_name(struct nls_table *nls, wchar_t *name,
+ int len, char *res)
{
- int charlen;
+ char *walk;
+ unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
+ int chi, chl;
+ int space;
- if ( (charlen = t->uni2char(uc, op, bound)) < 0)
- charlen = 0;
+ if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
+ return -EINVAL;
- return charlen;
+ if (IS_FREE(charbuf))
+ return -EINVAL;
+
+ space = 1; /* disallow names starting with a dot */
+ for (walk = res; len--; ) {
+ chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
+ if (chl == 0)
+ return -EINVAL;
+ for (chi = 0; chi < chl; chi++){
+ if (charbuf[chi] == '.') goto dot;
+ if (!charbuf[chi]) return -EINVAL;
+ if (walk-res == 8) return -EINVAL;
+ if (strchr(replace_chars,charbuf[chi])) return -EINVAL;
+ if (charbuf[chi] < ' '|| charbuf[chi]==':') return -EINVAL;
+ space = charbuf[chi] == ' ';
+ *walk = charbuf[chi];
+ walk++;
+ }
+ }
+dot:;
+ if (space) return -EINVAL;
+ if (len >= 0) {
+ while (walk-res < 8) *walk++ = ' ';
+ while (len > 0 && walk-res < MSDOS_NAME) {
+ chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
+ if (len < chl)
+ chl = len;
+ len -= chl;
+ for (chi = 0; chi < chl; chi++){
+ if (!charbuf[chi]) return -EINVAL;
+ if (strchr(replace_chars,charbuf[chi]))
+ return -EINVAL;
+ if (charbuf[chi] < ' ' || charbuf[chi] == '.'|| charbuf[chi]==':')
+ return -EINVAL;
+ space = charbuf[chi] == ' ';
+ *walk++ = charbuf[chi];
+ }
+ }
+ if (space) return -EINVAL;
+ if (len) return -EINVAL;
+ }
+ while (walk-res < MSDOS_NAME) *walk++ = ' ';
+
+ return 0;
}
static inline int
vfat_uni2upper_short(struct nls_table *t, wchar_t uc, char *op, int bound)
{
- int chi, chl;
+ int chl;
if ( (chl = t->uni2char(uc, op, bound)) < 0)
chl = 0;
- for (chi = 0; chi < chl; chi++)
- op[chi] = vfat_toupper(t, op[chi]);
+ if (chl == 1)
+ op[0] = vfat_toupper(t, op[0]);
return chl;
}
+#endif
+static inline unsigned char
+vfat_tolower(struct nls_table *t, unsigned char c)
+{
+ unsigned char nc = t->charset2lower[c];
+
+ return nc ? nc : c;
+}
+
+static inline unsigned char
+vfat_toupper(struct nls_table *t, unsigned char c)
+{
+ unsigned char nc = t->charset2upper[c];
+
+ return nc ? nc : c;
+}
+
+static int
+vfat_strnicmp(struct nls_table *t, const unsigned char *s1,
+ const unsigned char *s2, int len)
+{
+ while(len--)
+ if (vfat_tolower(t, *s1++) != vfat_tolower(t, *s2++))
+ return 1;
+
+ return 0;
+}
/*
* Compute the hash for the vfat name corresponding to the dentry.
@@ -383,8 +509,35 @@
/* Characters that are undesirable in an MS-DOS file name */
-static char bad_chars[] = "*?<>|\":/\\";
-static char replace_chars[] = "[];,+=";
+static wchar_t bad_chars[] = {
+ /* `*' `?' `<' `>' `|' `"' `:' `/' `\' */
+ 0x002A, 0x003F, 0x003C, 0x003E, 0x007C, 0x0022, 0x003A, 0x002F, 0x005C, 0,
+};
+#define IS_BADCHAR(uni) (vfat_unistrchr(bad_chars, (uni)) != NULL)
+
+static wchar_t replace_chars[] = {
+ /* `[' `]' `;' `,' `+' `=' */
+ 0x005B, 0x005D, 0x003B, 0x002C, 0x002B, 0x003D, 0,
+};
+#define IS_REPLACECHAR(uni) (vfat_unistrchr(replace_chars, (uni)) != NULL)
+
+static inline wchar_t *vfat_unistrchr(const wchar_t *s, const wchar_t c)
+{
+ for(; *s != c; ++s)
+ if (*s == 0)
+ return NULL;
+ return (wchar_t *) s;
+}
+
+static inline int vfat_is_used_badchars(const wchar_t *s, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (s[i] < 0x0020 || IS_BADCHAR(s[i]))
+ return -EINVAL;
+ return 0;
+}
/* Checks the validity of a long MS-DOS filename */
/* Returns negative number on error, 0 for a normal
@@ -393,18 +546,10 @@
static int vfat_valid_longname(const char *name, int len, int xlate)
{
const char **reserved, *walk;
- unsigned char c;
- int i, baselen;
+ int baselen;
if (len && name[len-1] == ' ') return -EINVAL;
if (len >= 256) return -EINVAL;
- for (i = 0; i < len; i++) {
- c = name[i];
- if (xlate && c == ':') continue;
- if (strchr(bad_chars,c)) {
- return -EINVAL;
- }
- }
if (len < 3) return 0;
for (walk = name; *walk != 0 && *walk != '.'; walk++);
@@ -424,72 +569,6 @@
return 0;
}
-static int vfat_valid_shortname(struct nls_table *nls, wchar_t *name, int len)
-{
- wchar_t *walk;
- unsigned char c, charbuf[NLS_MAX_CHARSET_SIZE];
- int chl, chi;
- int space;
-
- if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
- return -EINVAL;
-
- if (IS_FREE(charbuf))
- return -EINVAL;
-
- chl = 0;
- c = 0;
- space = 1; /* disallow names starting with a dot */
- for (walk = name; len && walk-name < 8;) {
- len--;
- chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl < 0)
- return -EINVAL;
-
- for (chi = 0; chi < chl; chi++) {
- c = vfat_getupper(nls, charbuf[chi]);
- if (!c) return -EINVAL;
- if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
- if (strchr(replace_chars,c)) return -EINVAL;
- if (c < ' '|| c==':') return -EINVAL;
- if (c == '.') goto dot;
- space = c == ' ';
- }
- }
-dot:;
- if (space) return -EINVAL;
- if (len && c != '.') {
- len--;
- if (vfat_uni2upper_short(nls, *walk++, charbuf, NLS_MAX_CHARSET_SIZE) == 1) {
- if (charbuf[0] != '.') return -EINVAL;
- } else
- return -EINVAL;
- c = '.';
- }
- if (c == '.') {
- if (len >= 4) return -EINVAL;
- while (len > 0) {
- len--;
- chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl < 0)
- return -EINVAL;
- for (chi = 0; chi < chl; chi++) {
- c = vfat_getupper(nls, charbuf[chi]);
- if (!c) return -EINVAL;
- if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
- if (strchr(replace_chars,c))
- return -EINVAL;
- if (c < ' ' || c == '.'|| c==':')
- return -EINVAL;
- space = c == ' ';
- }
- }
- if (space) return -EINVAL;
- }
-
- return 0;
-}
-
static int vfat_find_form(struct inode *dir,char *name)
{
struct msdos_dir_entry *de;
@@ -503,127 +582,62 @@
return 0;
}
-static int vfat_format_name(struct nls_table *nls, wchar_t *name,
- int len, char *res)
-{
- char *walk;
- unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
- int chi, chl;
- int space;
-
- if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
- return -EINVAL;
-
- if (IS_FREE(charbuf))
- return -EINVAL;
-
- space = 1; /* disallow names starting with a dot */
- for (walk = res; len--; ) {
- chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl == 0)
- return -EINVAL;
- for (chi = 0; chi < chl; chi++){
- if (charbuf[chi] == '.') goto dot;
- if (!charbuf[chi]) return -EINVAL;
- if (walk-res == 8) return -EINVAL;
- if (strchr(replace_chars,charbuf[chi])) return -EINVAL;
- if (charbuf[chi] < ' '|| charbuf[chi]==':') return -EINVAL;
- space = charbuf[chi] == ' ';
- *walk = charbuf[chi];
- walk++;
- }
- }
-dot:;
- if (space) return -EINVAL;
- if (len >= 0) {
- while (walk-res < 8) *walk++ = ' ';
- while (len > 0 && walk-res < MSDOS_NAME) {
- chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
- if (len < chl)
- chl = len;
- len -= chl;
- for (chi = 0; chi < chl; chi++){
- if (!charbuf[chi]) return -EINVAL;
- if (strchr(replace_chars,charbuf[chi]))
- return -EINVAL;
- if (charbuf[chi] < ' ' || charbuf[chi] == '.'|| charbuf[chi]==':')
- return -EINVAL;
- space = charbuf[chi] == ' ';
- *walk++ = charbuf[chi];
- }
- }
- if (space) return -EINVAL;
- if (len) return -EINVAL;
- }
- while (walk-res < MSDOS_NAME) *walk++ = ' ';
-
- return 0;
-}
-
-static char skip_chars[] = ".:\"?<>| ";
+static wchar_t skip_chars[] = {
+ /* `.' ` ' */
+ 0x002E, 0x0020, 0,
+};
+#define IS_SKIPCHAR(uni) \
+ ((wchar_t)(uni) == skip_chars[0] || (wchar_t)(uni) == skip_chars[1])
/* Given a valid longname, create a unique shortname. Make sure the
* shortname does not exist
+ * Returns negative number on error, 0 for a normal
+ * return, and 1 for valid shortname
*/
static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
- wchar_t *name, int len,
- char *name_res)
+ wchar_t *uname, int ulen,
+ char *name_res)
{
- wchar_t *ip, *op, *ext_start, *end, *name_start;
- wchar_t msdos_name[13];
- char base[9], ext[4], buf[8], *p;
+ wchar_t *ip, *ext_start, *end, *name_start;
+ unsigned char base[9], ext[4], buf[8], *p;
unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
int chl, chi;
- int sz, extlen, baselen, i;
-
- PRINTK2(("Entering vfat_create_shortname\n"));
- chl = 0;
- sz = 0; /* Make compiler happy */
- if (len <= 12) {
- /* Do a case insensitive search if the name would be a valid
- * shortname if is were all capitalized. However, do not
- * allow spaces in short names because Win95 scandisk does
- * not like that */
- for (i = 0, op = &msdos_name[0], ip = name; ; i++, ip++, op++) {
- if (i == len) {
- if (vfat_format_name(nls, &msdos_name[0], len,
- name_res) < 0)
- break;
- PRINTK3(("vfat_create_shortname 1\n"));
- if (vfat_find_form(dir, name_res) < 0)
- return 0;
- return -EEXIST;
- }
- chl = vfat_uni2upper_short(nls, *ip, charbuf, NLS_MAX_CHARSET_SIZE);
- for (chi = 0; chi < chl; chi++){
- if (charbuf[chi] == ' ')
- break;
- }
- if (chi < chl)
- break;
+ int sz = 0, extlen, baselen, i, numtail_baselen, numtail2_baselen;
+ int is_uppercase, is_shortname;
- *op = *ip;
- }
- }
+ /*
+ * 1) Valid characters for the 8.3 format alias are any
+ * combination of letters, uppercase alphabets, digits, any of
+ * the following special characters:
+ * $ % ' ` - @ { } ~ ! # ( ) & _ ^
+ * In this case Longfilename is not stored in disk.
+ *
+ * 2) File name is 8.3 format, but it contain the lowercase
+ * alphabet etc. In this case numtail is not added, but
+ * Longfilename is stored.
+ *
+ * 3) When the one except for the above, or the following special
+ * character are contained:
+ * . [ ] ; , + =
+ * numtail is added, and Longfilename must be stored in disk .
+ */
+ is_uppercase = 1;
+ is_shortname = 1;
- PRINTK3(("vfat_create_shortname 3\n"));
/* Now, we need to create a shortname from the long name */
- ext_start = end = &name[len];
- while (--ext_start >= name) {
- chl = vfat_uni2upper_short(nls, *ext_start, charbuf, NLS_MAX_CHARSET_SIZE);
- for (chi = 0; chi < chl; chi++) {
- if (charbuf[chi] == '.') {
- if (ext_start == end - 1) {
- sz = len;
- ext_start = NULL;
- }
- goto stop0;
+ ext_start = end = &uname[ulen];
+ while (--ext_start >= uname) {
+ if (*ext_start == 0x002E) { /* is `.' */
+ if (ext_start == end - 1) {
+ sz = ulen;
+ ext_start = NULL;
}
+ break;
}
}
-stop0:;
- if (ext_start == name - 1) {
- sz = len;
+
+ if (ext_start == uname - 1) {
+ sz = ulen;
ext_start = NULL;
} else if (ext_start) {
/*
@@ -631,45 +645,63 @@
* an extension eg. "...test". In this case Win95
* uses the extension as the name and sets no extension.
*/
- name_start = &name[0];
- while (name_start < ext_start)
- {
- chl = vfat_uni2upper_short(nls, *name_start, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl == 0)
+ name_start = &uname[0];
+ while (name_start < ext_start) {
+ if (!IS_SKIPCHAR(*name_start))
break;
- for (chi = 0; chi < chl; chi++)
- if (!strchr(skip_chars, charbuf[chi])) {
- goto stop1;
- }
name_start++;
}
-stop1:;
if (name_start != ext_start) {
- sz = ext_start - name;
+ sz = ext_start - uname;
ext_start++;
} else {
- sz = len;
+ sz = ulen;
ext_start=NULL;
}
}
- for (baselen = i = 0, p = base, ip = name; i < sz && baselen < 8; i++, ip++)
+ numtail_baselen = 6;
+ numtail2_baselen = 2;
+ for (baselen = i = 0, p = base, ip = uname; i < sz; i++, ip++)
{
- chl = vfat_uni2upper_short(nls, *ip, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl == 0){
- *p++ = '_';
- baselen++;
+ if (IS_SKIPCHAR(*ip)) {
+ is_shortname = 0;
continue;
}
+ if (IS_REPLACECHAR(*ip)) {
+ is_shortname = 0;
+ charbuf[0] = '_';
+ chl = 1;
+ } else {
+ chl = nls->uni2char(*ip, charbuf, sizeof(charbuf));
+ if (chl <= 0) {
+ is_shortname = 0;
+ charbuf[0] = '_';
+ chl = 1;
+ } else if (chl == 1) {
+ unsigned char c = charbuf[0];
+ charbuf[0] = vfat_toupper(nls, charbuf[0]);
+ if (c >= 0x7F || charbuf[0] != c)
+ is_uppercase = 0;
+ } else {
+ is_uppercase = 0;
+ }
+ }
+ if (baselen < 2 && (baselen + chl) > 2)
+ numtail2_baselen = baselen;
+ if (baselen < 6 && (baselen + chl) > 6)
+ numtail_baselen = baselen;
for (chi = 0; chi < chl; chi++){
- if (!strchr(skip_chars, charbuf[chi])){
- if (strchr(replace_chars, charbuf[chi]))
- *p = '_';
- else
- *p = charbuf[chi];
- p++; baselen++;
- }
+ *p++ = charbuf[chi];
+ baselen++;
+ if (baselen >= 8)
+ break;
+ }
+ if (baselen >= 8) {
+ if ((chi < chl - 1) || (ip + 1) - uname < sz)
+ is_shortname = 0;
+ break;
}
}
if (baselen == 0) {
@@ -679,30 +711,51 @@
extlen = 0;
if (ext_start) {
for (p = ext, ip = ext_start; extlen < 3 && ip < end; ip++) {
- chl = vfat_uni2upper_short(nls, *ip, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl == 0) {
- *p++ = '_';
- extlen++;
+ if (IS_SKIPCHAR(*ip)) {
+ is_shortname = 0;
continue;
}
-
- for (chi = 0; chi < chl; chi++) {
- if (!strchr(skip_chars, charbuf[chi])) {
- if (strchr(replace_chars, charbuf[chi]))
- *p = '_';
- else
- *p = charbuf[chi];
- p++; extlen++;
+ if (IS_REPLACECHAR(*ip)) {
+ is_shortname = 0;
+ charbuf[0] = '_';
+ chl = 1;
+ } else {
+ chl = nls->uni2char(*ip, charbuf, sizeof(charbuf));
+ if (chl <= 0) {
+ is_shortname = 0;
+ charbuf[0] = '_';
+ chl = 1;
+ } else if (chl == 1) {
+ unsigned char c = charbuf[0];
+ charbuf[0] = vfat_toupper(nls, charbuf[0]);
+ if (c >= 0x7F || charbuf[0] != c)
+ is_uppercase = 0;
+ } else {
+ is_uppercase = 0;
}
}
+
+ if ((extlen + chl) > 3) {
+ is_shortname = 0;
+ break;
+ }
+ for (chi = 0; chi < chl; chi++) {
+ *p++ = charbuf[chi];
+ extlen++;
+ }
+ if (extlen >= 3) {
+ if (ip + 1 != end)
+ is_shortname = 0;
+ break;
+ }
}
}
ext[extlen] = '\0';
base[baselen] = '\0';
/* Yes, it can happen. ".\xe5" would do it. */
- if (IS_FREE(base))
- base[0]='_';
+ if (base[0] == DELETED_FLAG)
+ base[0] = 0x05;
/* OK, at this point we know that base is not longer than 8 symbols,
* ext is not longer than 3, base is nonempty, both don't contain
@@ -712,6 +765,14 @@
memset(name_res, ' ', MSDOS_NAME);
memcpy(name_res,base,baselen);
memcpy(name_res+8,ext,extlen);
+
+ if (is_shortname) {
+ if (vfat_find_form(dir, name_res) < 0)
+ return is_uppercase;
+ else
+ return -EEXIST;
+ }
+
if (MSDOS_SB(dir->i_sb)->options.numtail == 0)
if (vfat_find_form(dir, name_res) < 0)
return 0;
@@ -724,8 +785,10 @@
* values for part of the base.
*/
- if (baselen>6)
- baselen = 6;
+ if (baselen>6) {
+ baselen = numtail_baselen;
+ name_res[7] = ' ';
+ }
name_res[baselen] = '~';
for (i = 1; i < 10; i++) {
name_res[baselen+1] = i + '0';
@@ -735,8 +798,10 @@
i = jiffies & 0xffff;
sz = (jiffies >> 16) & 0x7;
- if (baselen>2)
- baselen = 2;
+ if (baselen>2) {
+ baselen = numtail2_baselen;
+ name_res[7] = ' ';
+ }
name_res[baselen+4] = '~';
name_res[baselen+5] = '1' + sz;
while (1) {
@@ -868,15 +933,18 @@
goto out_free;
uname = (wchar_t *) page;
- if (vfat_valid_shortname(nls_disk, uname, ulen) >= 0) {
- res = vfat_format_name(nls_disk, uname, ulen, de->name);
- if (!res)
- goto out_free;
- }
+ res = vfat_is_used_badchars(uname, ulen);
+ if (res < 0)
+ goto out_free;
res = vfat_create_shortname(dir, nls_disk, uname, ulen, msdos_name);
- if (res)
+ if (res < 0)
+ goto out_free;
+ else if (res == 1) {
+ strncpy(de->name, msdos_name, MSDOS_NAME);
+ res = 0;
goto out_free;
+ }
*slots = unilen / 13;
for (cksum = i = 0; i < 11; i++) {
@@ -956,7 +1024,8 @@
goto cleanup;
res = vfat_build_slots(dir, qname->name, len, ds, &slots);
- if (res < 0) goto cleanup;
+ if (res < 0)
+ goto cleanup;
offset = fat_add_entries(dir, slots, &bh1, &de1, &ino);
if (offset < 0) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)