Fix a 'const' warning.
[Samba.git] / source / smbd / mangle.c
blob9587d0ed14122e89aa2c731a5123ecbabd6988f2
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 Name mangling with persistent tdb
5 Copyright (C) Simo Sorce 2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 /****************************************************************************
23 Rewritten from scrach in 2001 by Simo Sorce <idra@samba.org>
24 ****************************************************************************/
26 #include "includes.h"
29 /* -------------------------------------------------------------------------- **
30 * External Variables...
33 extern int case_default; /* Are conforming 8.3 names all upper or lower? */
34 extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */
36 char magic_char = '~';
38 /* -------------------------------------------------------------------- */
40 #define MANGLE_TDB_VERSION "20010927"
41 #define MANGLE_TDB_FILE_NAME "mangle.tdb"
42 #define MANGLED_PREFIX "MANGLED_"
43 #define LONG_PREFIX "LONG_"
44 #define COUNTER_PREFIX "COUNTER_"
45 #define MANGLE_COUNTER_MAX 99
46 #define MANGLE_SUFFIX_SIZE 3 /* "~XX" */
49 static TDB_CONTEXT *mangle_tdb;
51 BOOL init_mangle_tdb(void)
53 char *tdbfile;
55 tdbfile = lock_path(MANGLE_TDB_FILE_NAME); /* this return a static pstring do not try to free it */
57 /* Open tdb */
58 if (!(mangle_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600)))
60 DEBUG(0, ("Unable to open Mangle TDB\n"));
61 return False;
64 return True;
67 /* trasform a unicode string into a dos charset string */
68 static int ucs2_to_dos(char *dest, const smb_ucs2_t *src, int dest_len)
70 int src_len, ret;
72 if (dest_len == -1) {
73 dest_len = sizeof(pstring);
76 src_len = strlen_w(src)* sizeof(smb_ucs2_t);
78 ret = convert_string(CH_UCS2, CH_DOS, src, src_len, dest, dest_len);
79 if (dest_len) dest[MIN(ret, dest_len-1)] = 0;
81 return ret;
84 /* trasform in a string that contain only valid chars for win filenames,
85 not including a '.' */
86 static void strvalid(smb_ucs2_t *src)
88 if (!src || !*src) return;
90 while (*src) {
91 if (!isvalid83_w(*src) || *src == UCS2_CHAR('.')) *src = UCS2_CHAR('_');
92 src++;
97 /* return False if something fail and
98 * return 2 alloced unicode strings that contain prefix and extension
100 static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **prefix, smb_ucs2_t **extension)
102 size_t ext_len;
103 smb_ucs2_t *p;
105 *extension = 0;
106 *prefix = strdup_w(ucs2_string);
107 if (!*prefix)
109 DEBUG(0,("mangle_get_prefix: out of memory!\n"));
110 return NT_STATUS_NO_MEMORY;
112 if ((p = strrchr_w(*prefix, UCS2_CHAR('.'))))
114 ext_len = strlen_w(p+1);
115 if ((ext_len > 0) && (ext_len < 4) && (p != *prefix) &&
116 (NT_STATUS_IS_OK(has_valid_chars(p+1)))) /* check extension */
118 *p = 0;
119 *extension = strdup_w(p+1);
120 if (!*extension)
122 DEBUG(0,("mangle_get_prefix: out of memory!\n"));
123 SAFE_FREE(*prefix);
124 return NT_STATUS_NO_MEMORY;
128 return NT_STATUS_OK;
132 /* mangled must contain only the file name, not a path.
133 and MUST be ZERO terminated */
134 smb_ucs2_t *unmangle(const smb_ucs2_t *mangled)
136 TDB_DATA data, key;
137 fstring keystr;
138 fstring mufname;
139 smb_ucs2_t *pref, *ext, *retstr;
140 size_t long_len, ext_len, muf_len;
142 if (strlen_w(mangled) > 12) return NULL;
143 if (!strchr_w(mangled, UCS2_CHAR('~'))) return NULL;
145 /* if it is a path refuse to proceed */
146 if (strchr_w(mangled, UCS2_CHAR('/'))) {
147 DEBUG(10, ("unmangle: cannot unmangle a path\n"));
148 return NULL;
151 if (NT_STATUS_IS_ERR(mangle_get_prefix(mangled, &pref, &ext)))
152 return NULL;
154 /* mangled names are stored lowercase only */
155 strlower_w(pref);
156 /* set search key */
157 muf_len = ucs2_to_dos(mufname, pref, sizeof(mufname));
158 SAFE_FREE(pref);
159 if (!muf_len) return NULL;
161 slprintf(keystr, sizeof(keystr) - 1, "%s%s", MANGLED_PREFIX, mufname);
162 key.dptr = keystr;
163 key.dsize = strlen (keystr) + 1;
165 /* get the record */
166 data = tdb_fetch(mangle_tdb, key);
168 if (!data.dptr) /* not found */
170 DEBUG(5,("unmangle: failed retrieve from db %s\n", tdb_errorstr(mangle_tdb)));
171 retstr = NULL;
172 goto done;
175 if (ext)
177 long_len = (data.dsize / 2) - 1;
178 ext_len = strlen_w(ext);
179 retstr = (smb_ucs2_t *)malloc((long_len + ext_len + 2)*sizeof(smb_ucs2_t));
180 if (!retstr)
182 DEBUG(0, ("unamngle: out of memory!\n"));
183 goto done;
185 strncpy_w(retstr, (smb_ucs2_t *)data.dptr, long_len);
186 retstr[long_len] = UCS2_CHAR('.');
187 retstr[long_len + 1] = 0;
188 strncat_w(retstr, ext, ext_len);
190 else
192 retstr = strdup_w((smb_ucs2_t *)data.dptr);
193 if (!retstr)
195 DEBUG(0, ("unamngle: out of memory!\n"));
196 goto done;
201 done:
202 SAFE_FREE(data.dptr);
203 SAFE_FREE(pref);
204 SAFE_FREE(ext);
206 return retstr;
209 /* unmangled must contain only the file name, not a path.
210 and MUST be ZERO terminated.
211 return a new allocated string if the name is yet valid 8.3
212 or is mangled successfully.
213 return null on error.
216 smb_ucs2_t *mangle(const smb_ucs2_t *unmangled)
218 TDB_DATA data, key, klock;
219 pstring keystr;
220 pstring longname;
221 fstring keylock;
222 fstring mufname;
223 fstring prefix;
224 BOOL tclock = False;
225 char suffix[7];
226 smb_ucs2_t *mangled = NULL;
227 smb_ucs2_t *umpref, *ext, *p = NULL;
228 size_t pref_len, ext_len, ud83_len;
230 /* if it is a path refuse to proceed */
231 if (strchr_w(unmangled, UCS2_CHAR('/'))) {
232 DEBUG(10, ("mangle: cannot mangle a path\n"));
233 return NULL;
236 /* if it is a valid 8_3 do not mangle again */
237 if (NT_STATUS_IS_OK(is_8_3_w(unmangled)))
238 return NULL;
240 if (NT_STATUS_IS_ERR(mangle_get_prefix(unmangled, &umpref, &ext)))
241 return NULL;
243 /* test if the same is yet mangled */
245 /* set search key */
246 pull_ucs2(NULL, longname, umpref, sizeof(longname), 0, STR_TERMINATE);
247 slprintf(keystr, sizeof(keystr)-1, "%s%s", LONG_PREFIX, longname);
248 key.dptr = keystr;
249 key.dsize = strlen(keystr) + 1;
251 /* get the record */
252 data = tdb_fetch (mangle_tdb, key);
253 if (!data.dptr) /* not found */
255 smb_ucs2_t temp[9];
256 size_t c, pos;
258 if (tdb_error(mangle_tdb) != TDB_ERR_NOEXIST)
260 DEBUG(0, ("mangle: database retrieval error: %s\n",
261 tdb_errorstr(mangle_tdb)));
262 goto done;
265 /* if not find the first free possibile mangled name */
267 pos = strlen_w(umpref);
268 if ((8 - MANGLE_SUFFIX_SIZE) < pos)
269 pos = 8 - MANGLE_SUFFIX_SIZE;
270 pos++;
273 pos--;
274 if (pos == 0)
276 DEBUG(0, ("mangle: unable to mangle file name!\n"));
277 goto done;
279 strncpy_w(temp, umpref, pos);
280 temp[pos] = 0;
281 strlower_w(temp);
283 /* convert any invalid char into '_' */
284 strvalid(temp);
285 ud83_len = ucs2_to_dos(prefix, temp, sizeof(prefix));
286 if (!ud83_len) goto done;
288 while (ud83_len > 8 - MANGLE_SUFFIX_SIZE);
290 slprintf(keylock, sizeof(keylock)-1, "%s%s", COUNTER_PREFIX, prefix);
291 klock.dptr = keylock;
292 klock.dsize = strlen(keylock) + 1;
294 c = 0;
295 data.dptr = (char *)&c;
296 data.dsize = sizeof(uint32);
297 /* try to insert a new counter prefix, if it exist the call will
298 fail (correct) otherwise it will create a new entry with counter set
299 to 0
301 if(tdb_store(mangle_tdb, klock, data, TDB_INSERT) != TDB_SUCCESS)
303 if (tdb_error(mangle_tdb) != TDB_ERR_EXISTS)
305 DEBUG(0, ("mangle: database store error: %s\n",
306 tdb_errorstr(mangle_tdb)));
307 goto done;
311 /* lock the mangle counter for this prefix */
312 if (tdb_chainlock(mangle_tdb, klock))
314 DEBUG(0,("mangle: failed to lock database\n!"));
315 goto done;
317 tclock = True;
319 data = tdb_fetch(mangle_tdb, klock);
320 if (!data.dptr)
322 DEBUG(0, ("mangle: database retrieval error: %s\n",
323 tdb_errorstr(mangle_tdb)));
324 goto done;
326 c = *((uint32 *)data.dptr);
327 c++;
329 if (c > MANGLE_COUNTER_MAX)
331 DEBUG(0, ("mangle: error, counter overflow!\n"));
332 goto done;
335 temp[pos] = UCS2_CHAR('~');
336 temp[pos+1] = 0;
337 snprintf(suffix, 7, "%.6d", c);
338 strncat_wa(temp, &suffix[7 - MANGLE_SUFFIX_SIZE], MANGLE_SUFFIX_SIZE);
340 ud83_len = ucs2_to_dos(mufname, temp, sizeof(mufname));
341 if (!ud83_len) goto done;
342 if (ud83_len > 8)
344 DEBUG(0, ("mangle: darn, logic error aborting!\n"));
345 goto done;
348 /* store the long entry with mangled key */
349 slprintf(keystr, sizeof(keystr)-1, "%s%s", MANGLED_PREFIX, mufname);
350 key.dptr = keystr;
351 key.dsize = strlen (keystr) + 1;
352 data.dsize = (strlen_w(umpref) + 1) * sizeof (smb_ucs2_t);
353 data.dptr = (void *)umpref;
355 if (tdb_store(mangle_tdb, key, data, TDB_INSERT) != TDB_SUCCESS)
357 DEBUG(0, ("mangle: database store error: %s\n",
358 tdb_errorstr(mangle_tdb)));
359 goto done;
362 /* store the mangled entry with long key*/
363 pull_ucs2(NULL, longname, umpref, sizeof(longname), 0, STR_TERMINATE);
364 slprintf(keystr, sizeof(keystr)-1, "%s%s", LONG_PREFIX, longname);
365 key.dptr = keystr;
366 key.dsize = strlen (keystr) + 1;
367 data.dsize = strlen(mufname) + 1;
368 data.dptr = mufname;
369 if (tdb_store(mangle_tdb, key, data, TDB_INSERT) != TDB_SUCCESS)
371 DEBUG(0, ("mangle: database store failed: %s\n",
372 tdb_errorstr(mangle_tdb)));
374 /* try to delete the mangled key entry to avoid later inconsistency */
375 slprintf(keystr, sizeof(keystr)-1, "%s%s", MANGLED_PREFIX, mufname);
376 key.dptr = keystr;
377 key.dsize = strlen (keystr) + 1;
378 if (!tdb_delete(mangle_tdb, key))
380 DEBUG(0, ("mangle: severe error, mangled tdb may be inconsistent!\n"));
382 goto done;
385 p = strdup_w(temp);
386 if (!p)
388 DEBUG(0,("mangle: out of memory!\n"));
389 goto done;
392 data.dptr = (char *)&c;
393 data.dsize = sizeof(uint32);
394 /* store the counter */
395 if(tdb_store(mangle_tdb, klock, data, TDB_REPLACE) != TDB_SUCCESS)
397 DEBUG(0, ("mangle: database store failed: %s\n",
398 tdb_errorstr(mangle_tdb)));
399 /* try to delete the mangled and long key entry to avoid later inconsistency */
400 slprintf(keystr, sizeof(keystr)-1, "%s%s", MANGLED_PREFIX, mufname);
401 key.dptr = keystr;
402 key.dsize = strlen (keystr) + 1;
403 if (!tdb_delete(mangle_tdb, key))
405 DEBUG(0, ("mangle: severe error, mangled tdb may be inconsistent!\n"));
407 slprintf(keystr, sizeof(keystr)-1, "%s%s", LONG_PREFIX, longname);
408 key.dptr = keystr;
409 key.dsize = strlen (keystr) + 1;
410 if (!tdb_delete(mangle_tdb, key))
412 DEBUG(0, ("mangle: severe error, mangled tdb may be inconsistent!\n"));
414 goto done;
417 tclock = False;
418 tdb_chainunlock(mangle_tdb, klock);
420 else /* FOUND */
422 p = acnv_dosu2(data.dptr);
423 if (!p)
425 DEBUG(0,("mangle: out of memory!\n"));
426 goto done;
430 if (ext)
432 pref_len = strlen_w(p);
433 ext_len = strlen_w(ext);
434 mangled = (smb_ucs2_t *)malloc((pref_len + ext_len + 2)*sizeof(smb_ucs2_t));
435 if (!mangled)
437 DEBUG(0,("mangle: out of memory!\n"));
438 goto done;
440 strncpy_w (mangled, p, pref_len);
441 mangled[pref_len] = UCS2_CHAR('.');
442 mangled[pref_len + 1] = 0;
443 strncat_w (mangled, ext, ext_len);
445 else
447 mangled = strdup_w(p);
448 if (!mangled)
450 DEBUG(0,("mangle: out of memory!\n"));
451 goto done;
455 /* mangled name are returned in upper or lower case depending on
456 case_default value */
457 strnorm_w(mangled);
459 done:
460 if (tclock) tdb_chainunlock(mangle_tdb, klock);
461 SAFE_FREE(p);
462 SAFE_FREE(umpref);
463 SAFE_FREE(ext);
465 return mangled;
469 /* non unicode compatibility functions */
471 char *dos_mangle(const char *dos_unmangled)
473 smb_ucs2_t *in, *out;
474 char *dos_mangled;
476 if (!dos_unmangled || !*dos_unmangled) return NULL;
478 in = acnv_dosu2(dos_unmangled);
479 if (!in)
481 DEBUG(0,("dos_mangle: out of memory!\n"));
482 return NULL;
485 out = mangle(in);
486 if (!out)
488 SAFE_FREE(in);
489 return NULL;
492 dos_mangled = acnv_u2dos(out);
493 if (!dos_mangled)
495 DEBUG(0,("dos_mangle: out of memory!\n"));
496 goto done;
499 done:
500 SAFE_FREE(in);
501 SAFE_FREE(out);
502 return dos_mangled;
505 char *dos_unmangle(const char *dos_mangled)
507 smb_ucs2_t *in, *out;
508 char *dos_unmangled;
510 if (!dos_mangled || !*dos_mangled) return NULL;
512 in = acnv_dosu2(dos_mangled);
513 if (!in)
515 DEBUG(0,("dos_unmangle: out of memory!\n"));
516 return NULL;
519 out = mangle(in);
520 if (!out)
522 SAFE_FREE(in);
523 return NULL;
526 dos_unmangled = acnv_u2dos(out);
527 if (!dos_unmangled)
529 DEBUG(0,("dos_unmangle: out of memory!\n"));
530 goto done;
533 done:
534 SAFE_FREE(in);
535 SAFE_FREE(out);
536 return dos_unmangled;
539 BOOL is_8_3(const char *fname, BOOL check_case)
541 const char *f;
542 smb_ucs2_t *ucs2name;
543 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
545 if (!fname || !*fname) return False;
546 if ((f = strrchr(fname, '/')) == NULL) f = fname;
547 else f++;
549 DEBUG(10,("is_8_3: testing [%s]\n", f));
551 if (strlen(f) > 12) return False;
553 ucs2name = acnv_uxu2(f);
554 if (!ucs2name)
556 DEBUG(0,("is_8_3: out of memory!\n"));
557 goto done;
560 ret = is_8_3_w(ucs2name);
562 done:
563 SAFE_FREE(ucs2name);
565 DEBUG(10,("is_8_3: returning -> %s\n", NT_STATUS_IS_OK(ret)?"True":"False"));
567 if (NT_STATUS_IS_ERR(ret)) return False;
568 else return True;
571 NTSTATUS is_8_3_w(const smb_ucs2_t *fname)
573 smb_ucs2_t *pref = 0, *ext = 0;
574 size_t plen;
575 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
577 if (!fname || !*fname) return NT_STATUS_INVALID_PARAMETER;
579 DEBUG(10,("is_8_3_w: testing\n")); /* [%s]\n", fname)); */
581 if (strlen_w(fname) > 12) return NT_STATUS_UNSUCCESSFUL;
583 if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
584 return NT_STATUS_OK;
586 if (NT_STATUS_IS_ERR(is_valid_name(fname))) goto done;
588 if (NT_STATUS_IS_ERR(mangle_get_prefix(fname, &pref, &ext))) goto done;
589 plen = strlen_w(pref);
591 if (strchr_wa(pref, '.')) goto done;
592 if (plen < 1 || plen > 8) goto done;
593 if (ext) if (strlen_w(ext) > 3) goto done;
595 ret = NT_STATUS_OK;
597 done:
598 SAFE_FREE(pref);
599 SAFE_FREE(ext);
600 return ret;
603 NTSTATUS has_valid_chars(const smb_ucs2_t *s)
605 NTSTATUS ret = NT_STATUS_OK;
607 if (!s || !*s) return NT_STATUS_INVALID_PARAMETER;
609 DEBUG(10,("has_valid_chars: testing\n")); /* [%s]\n", s)); */
611 /* CHECK: this should not be necessary if the ms wild chars
612 are not valid in valid.dat --- simo */
613 if (ms_has_wild_w(s)) return NT_STATUS_UNSUCCESSFUL;
615 while (*s) {
616 if(!isvalid83_w(*s)) return NT_STATUS_UNSUCCESSFUL;
617 s++;
620 return ret;
623 NTSTATUS is_valid_name(const smb_ucs2_t *fname)
625 smb_ucs2_t *str, *p;
626 NTSTATUS ret = NT_STATUS_OK;
628 if (!fname || !*fname) return NT_STATUS_INVALID_PARAMETER;
630 DEBUG(10,("is_valid_name: testing\n")); /* [%s]\n", s)); */
632 if (*fname == UCS2_CHAR('.')) return NT_STATUS_UNSUCCESSFUL;
634 ret = has_valid_chars(fname);
635 if (NT_STATUS_IS_ERR(ret)) return ret;
637 str = strdup_w(fname);
638 p = strchr_w(str, UCS2_CHAR('.'));
639 if (p) *p = 0;
640 strupper_w(str);
641 p = &(str[1]);
643 switch(str[0])
645 case UCS2_CHAR('A'):
646 if(strcmp_wa(p, "UX") == 0)
647 ret = NT_STATUS_UNSUCCESSFUL;
648 break;
649 case UCS2_CHAR('C'):
650 if((strcmp_wa(p, "LOCK$") == 0)
651 || (strcmp_wa(p, "ON") == 0)
652 || (strcmp_wa(p, "OM1") == 0)
653 || (strcmp_wa(p, "OM2") == 0)
654 || (strcmp_wa(p, "OM3") == 0)
655 || (strcmp_wa(p, "OM4") == 0)
657 ret = NT_STATUS_UNSUCCESSFUL;
658 break;
659 case UCS2_CHAR('L'):
660 if((strcmp_wa(p, "PT1") == 0)
661 || (strcmp_wa(p, "PT2") == 0)
662 || (strcmp_wa(p, "PT3") == 0)
664 ret = NT_STATUS_UNSUCCESSFUL;
665 break;
666 case UCS2_CHAR('N'):
667 if(strcmp_wa(p, "UL") == 0)
668 ret = NT_STATUS_UNSUCCESSFUL;
669 break;
670 case UCS2_CHAR('P'):
671 if(strcmp_wa(p, "RN") == 0)
672 ret = NT_STATUS_UNSUCCESSFUL;
673 break;
674 default:
675 break;
678 SAFE_FREE(str);
679 return ret;
682 BOOL is_mangled(const char *s)
684 smb_ucs2_t *u2, *res;
685 BOOL ret = False;
687 DEBUG(10,("is_mangled: testing [%s]\n", s));
689 if (!s || !*s) return False;
690 if ((strlen(s) > 12) || (!strchr(s, '~'))) return False;
692 u2 = acnv_dosu2(s);
693 if (!u2)
695 DEBUG(0,("is_mangled: out of memory!\n"));
696 return ret;
699 res = unmangle(u2);
700 if (res) ret = True;
701 SAFE_FREE(res);
702 SAFE_FREE(u2);
703 DEBUG(10,("is_mangled: returning [%s]\n", ret?"True":"False"));
704 return ret;
707 NTSTATUS is_mangled_w(const smb_ucs2_t *s)
709 smb_ucs2_t *res;
710 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
712 res = unmangle(s);
713 if (res) ret = NT_STATUS_OK;
714 SAFE_FREE(res);
715 return ret;
718 NTSTATUS path_has_mangled(const smb_ucs2_t *s)
720 smb_ucs2_t *p, *f, *b;
721 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
723 if (!s || !*s) return NT_STATUS_INVALID_PARAMETER;
725 p = strdup_w(s);
726 if (!p) return NT_STATUS_NO_MEMORY;
727 trim_string_wa(p, "/", "/");
728 f = b = p;
729 while (b) {
730 b = strchr_w(f, UCS2_CHAR('/'));
731 if (b) *b = 0;
732 if (NT_STATUS_IS_OK(is_mangled_w(f))) {
733 ret = NT_STATUS_OK;
734 goto done;
736 f = b + 1;
738 done:
739 SAFE_FREE(p);
740 return ret;
743 /* backward compatibility functions */
745 void reset_mangled_cache(void)
747 DEBUG(10,("reset_mangled_cache: compatibility function, remove me!\n"));
750 BOOL check_mangled_cache(char *s)
752 smb_ucs2_t *u2, *res;
753 BOOL ret = False;
755 DEBUG(10,("check_mangled_cache: I'm so ugly, please remove me!\n"));
756 DEBUG(10,("check_mangled_cache: testing -> [%s]\n", s));
758 if (!s || !*s) return False;
760 u2 = acnv_dosu2(s);
761 if (!u2)
763 DEBUG(0,("check_mangled_cache: out of memory!\n"));
764 return ret;
767 res = unmangle(u2);
768 if (res)
771 ucs2_to_dos (s, res, PSTRING_LEN);
772 /* We MUST change this brainded interface,
773 we do not know how many chars will be used
774 in dos so i guess they will be no more than
775 double the size of the unicode string
776 ---simo */
777 DEBUG(10,("check_mangled_cache: returning -> [%s]\n", s));
778 ret = True;
780 SAFE_FREE(res);
781 SAFE_FREE(u2);
782 DEBUG(10,("check_mangled_cache: returning -> %s\n", ret?"True":"False"));
783 return ret;
786 void mangle_name_83(char *s)
788 smb_ucs2_t *u2, *res;
790 DEBUG(10,("mangle_name_83: I'm so ugly, please remove me!\n"));
791 DEBUG(10,("mangle_name_83: testing -> [%s]\n", s));
793 if (!s || !*s) return;
795 u2 = acnv_dosu2(s);
796 if (!u2)
798 DEBUG(0,("mangle_name_83: out of memory!\n"));
799 return;
802 res = mangle(u2);
803 if (res) ucs2_to_dos (s, res, 13); /* ugly, but must be done this way */
804 DEBUG(10,("mangle_name_83: returning -> [%s]\n", s));
805 SAFE_FREE(res);
806 SAFE_FREE(u2);
809 BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum)
811 DEBUG(10,("name_map_mangle: I'm so ugly, please remove me!\n"));
813 if (!need83) return True;
814 /* if (is_8_3(OutName, True)) return True; */
815 /* Warning: we should check for invalid chars in file name and mangle
816 if invalid chars found --simo*/
818 mangle_name_83(OutName);
819 return True;
824 #if 0 /* TEST_MANGLE_CODE */
826 #define LONG "this_is_a_long_file_name"
827 #define LONGM "this_~01"
828 #define SHORT "short"
829 #define SHORTM "short~01"
830 #define EXT1 "ex1"
831 #define EXT2 "e2"
832 #define EXT3 "3"
833 #define EXTFAIL "longext"
834 #define EXTNULL ""
836 static void unmangle_test (char *name, char *ext)
838 smb_ucs2_t ucs2_name[2048];
839 smb_ucs2_t *retstr;
840 pstring unix_name;
842 push_ucs2(NULL, ucs2_name, name, sizeof(ucs2_name), STR_TERMINATE);
843 if (ext)
845 strncat_wa(ucs2_name, ".", 1);
846 strncat_wa(ucs2_name, ext, strlen(ext) + 1);
848 retstr = unmangle(ucs2_name);
849 if(retstr) pull_ucs2(NULL, unix_name, retstr, sizeof(unix_name), 0, STR_TERMINATE);
850 else unix_name[0] = 0;
851 if (ext) printf ("[%s.%s] ---> [%s]\n", name, ext, unix_name);
852 else printf ("[%s] ---> [%s]\n", name, unix_name);
853 SAFE_FREE(retstr);
856 static void mangle_test (char *name, char *ext)
858 smb_ucs2_t ucs2_name[2048];
859 smb_ucs2_t *retstr;
860 pstring unix_name;
862 push_ucs2(NULL, ucs2_name, name, sizeof(ucs2_name), STR_TERMINATE);
863 if (ext)
865 strncat_wa(ucs2_name, ".", 1);
866 strncat_wa(ucs2_name, ext, strlen(ext) + 1);
868 retstr = mangle(ucs2_name);
869 if(retstr) pull_ucs2(NULL, unix_name, retstr, sizeof(unix_name), 0, STR_TERMINATE);
870 else unix_name[0] = 0;
871 if (ext) printf ("[%s.%s] ---> [%s]\n", name, ext, unix_name);
872 else printf ("[%s] ---> [%s]\n", name, unix_name);
873 SAFE_FREE(retstr);
876 void mangle_test_code(void)
878 init_mangle_tdb();
880 /* unmangle every */
881 printf("Unmangle test 1:\n");
883 unmangle_test (LONG, NULL);
884 unmangle_test (LONG, EXT1);
885 unmangle_test (LONG, EXT2);
886 unmangle_test (LONG, EXT3);
887 unmangle_test (LONG, EXTFAIL);
888 unmangle_test (LONG, EXTNULL);
890 unmangle_test (LONGM, NULL);
891 unmangle_test (LONGM, EXT1);
892 unmangle_test (LONGM, EXT2);
893 unmangle_test (LONGM, EXT3);
894 unmangle_test (LONGM, EXTFAIL);
895 unmangle_test (LONGM, EXTNULL);
897 unmangle_test (SHORT, NULL);
898 unmangle_test (SHORT, EXT1);
899 unmangle_test (SHORT, EXT2);
900 unmangle_test (SHORT, EXT3);
901 unmangle_test (SHORT, EXTFAIL);
902 unmangle_test (SHORT, EXTNULL);
904 unmangle_test (SHORTM, NULL);
905 unmangle_test (SHORTM, EXT1);
906 unmangle_test (SHORTM, EXT2);
907 unmangle_test (SHORTM, EXT3);
908 unmangle_test (SHORTM, EXTFAIL);
909 unmangle_test (SHORTM, EXTNULL);
911 /* mangle every */
912 printf("Mangle test\n");
914 mangle_test (LONG, NULL);
915 mangle_test (LONG, EXT1);
916 mangle_test (LONG, EXT2);
917 mangle_test (LONG, EXT3);
918 mangle_test (LONG, EXTFAIL);
919 mangle_test (LONG, EXTNULL);
921 mangle_test (LONGM, NULL);
922 mangle_test (LONGM, EXT1);
923 mangle_test (LONGM, EXT2);
924 mangle_test (LONGM, EXT3);
925 mangle_test (LONGM, EXTFAIL);
926 mangle_test (LONGM, EXTNULL);
928 mangle_test (SHORT, NULL);
929 mangle_test (SHORT, EXT1);
930 mangle_test (SHORT, EXT2);
931 mangle_test (SHORT, EXT3);
932 mangle_test (SHORT, EXTFAIL);
933 mangle_test (SHORT, EXTNULL);
935 mangle_test (SHORTM, NULL);
936 mangle_test (SHORTM, EXT1);
937 mangle_test (SHORTM, EXT2);
938 mangle_test (SHORTM, EXT3);
939 mangle_test (SHORTM, EXTFAIL);
940 mangle_test (SHORTM, EXTNULL);
942 /* unmangle again every */
943 printf("Unmangle test 2:\n");
945 unmangle_test (LONG, NULL);
946 unmangle_test (LONG, EXT1);
947 unmangle_test (LONG, EXT2);
948 unmangle_test (LONG, EXT3);
949 unmangle_test (LONG, EXTFAIL);
950 unmangle_test (LONG, EXTNULL);
952 unmangle_test (LONGM, NULL);
953 unmangle_test (LONGM, EXT1);
954 unmangle_test (LONGM, EXT2);
955 unmangle_test (LONGM, EXT3);
956 unmangle_test (LONGM, EXTFAIL);
957 unmangle_test (LONGM, EXTNULL);
959 unmangle_test (SHORT, NULL);
960 unmangle_test (SHORT, EXT1);
961 unmangle_test (SHORT, EXT2);
962 unmangle_test (SHORT, EXT3);
963 unmangle_test (SHORT, EXTFAIL);
964 unmangle_test (SHORT, EXTNULL);
966 unmangle_test (SHORTM, NULL);
967 unmangle_test (SHORTM, EXT1);
968 unmangle_test (SHORTM, EXT2);
969 unmangle_test (SHORTM, EXT3);
970 unmangle_test (SHORTM, EXTFAIL);
971 unmangle_test (SHORTM, EXTNULL);
974 #endif /* TEST_MANGLE_CODE */