From 0e8fd3398771da2f016d72830179507f3edda51b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 4 May 1996 07:50:46 +0000 Subject: Initial version imported to CVS (This used to be commit 291551d80711daab7b7581720bcd9a08d6096517) --- source3/smbd/mangle.c | 610 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 610 insertions(+) create mode 100644 source3/smbd/mangle.c (limited to 'source3/smbd/mangle.c') diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c new file mode 100644 index 0000000000..8f1490c528 --- /dev/null +++ b/source3/smbd/mangle.c @@ -0,0 +1,610 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Name mangling + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "loadparm.h" + +extern int DEBUGLEVEL; +extern int case_default; +extern BOOL case_mangle; + +/**************************************************************************** +provide a checksum on a string +****************************************************************************/ +int str_checksum(char *s) +{ + int res = 0; + int c; + int i=0; + while (*s) + { + c = *s; + res ^= (c << (i % 15)) ^ (c >> (15-(i%15))); + s++; i++; + } + return(res); +} + +/**************************************************************************** +return True if a name is a special msdos reserved name +****************************************************************************/ +static BOOL is_reserved_msdos(char *fname) +{ + char upperFname[13]; + char *p; + + StrnCpy (upperFname, fname, 12); + + /* lpt1.txt and con.txt etc are also illegal */ + p=strchr(upperFname,'.'); + if (p) + *p='\0'; + strupper (upperFname); + if ((strcmp(upperFname,"CLOCK$") == 0) || + (strcmp(upperFname,"CON") == 0) || + (strcmp(upperFname,"AUX") == 0) || + (strcmp(upperFname,"COM1") == 0) || + (strcmp(upperFname,"COM2") == 0) || + (strcmp(upperFname,"COM3") == 0) || + (strcmp(upperFname,"COM4") == 0) || + (strcmp(upperFname,"LPT1") == 0) || + (strcmp(upperFname,"LPT2") == 0) || + (strcmp(upperFname,"LPT3") == 0) || + (strcmp(upperFname,"NUL") == 0) || + (strcmp(upperFname,"PRN") == 0)) + return (True) ; + + return (False); +} + + + +/**************************************************************************** +return True if a name is in 8.3 dos format +****************************************************************************/ +BOOL is_8_3(char *fname) +{ + int len; + char *dot_pos; + char *slash_pos = strrchr(fname,'/'); + int l; + + if (slash_pos) fname = slash_pos+1; + len = strlen(fname); + + dot_pos = strchr(fname,'.'); + + DEBUG(5,("checking %s for 8.3\n",fname)); + + if (case_mangle) + switch (case_default) + { + case CASE_LOWER: + if (strhasupper(fname)) return(False); + break; + case CASE_UPPER: + if (strhaslower(fname)) return(False); + break; + } + + /* can't be longer than 12 chars */ + if (len == 0 || len > 12) + return(False); + + /* can't be an MS-DOS Special file such as lpt1 or even lpt1.txt */ + if (is_reserved_msdos(fname)) + return(False); + + /* can't contain invalid dos chars */ + /* Windows use the ANSI charset. + But filenames are translated in the PC charset. + This Translation may be more or less relaxed depending + the Windows application. */ + + /* %%% A nice improvment to name mangling would be to translate + filename to ANSI charset on the smb server host */ + + { + char *p = fname; +#ifdef KANJI + dot_pos = 0; + while (*p) + { + if (is_shift_jis (*p)) { + p += 2; + } else if (is_kana (*p)) { + p ++; + } else { + if (*p == '.' && !dot_pos) + dot_pos = (char *) p; + if (!isdoschar(*p)) + return(False); + p++; + } + } +#else + while (*p) + { + if (!isdoschar(*p)) + return(False); + p++; + } +#endif /* KANJI */ + } + + /* no dot and less than 9 means OK */ + if (!dot_pos) + return(len <= 8); + + l = PTR_DIFF(dot_pos,fname); + + /* base must be at least 1 char except special cases . and .. */ + if (l == 0) + return(strcmp(fname,".") == 0 || strcmp(fname,"..") == 0); + + /* base can't be greater than 8 */ + if (l > 8) + return(False); + + if (lp_strip_dot() && + len - l == 1 && + !strchr(dot_pos+1,'.')) + { + *dot_pos = 0; + return(True); + } + + /* extension must be between 1 and 3 */ + if ( (len - l < 2 ) || (len - l > 4) ) + return(False); + + /* extension can't have a dot */ + if (strchr(dot_pos+1,'.')) + return(False); + + /* must be in 8.3 format */ + return(True); +} + + + +/* +keep a stack of name mangling results - just +so file moves and copies have a chance of working +*/ +fstring *mangled_stack = NULL; +int mangled_stack_size = 0; +int mangled_stack_len = 0; + +/**************************************************************************** +create the mangled stack +****************************************************************************/ +void create_mangled_stack(int size) +{ + if (mangled_stack) + { + free(mangled_stack); + mangled_stack_size = 0; + mangled_stack_len = 0; + } + if (size > 0) + mangled_stack = (fstring *)malloc(sizeof(fstring)*size); + if (mangled_stack) mangled_stack_size = size; +} + +/**************************************************************************** +push a mangled name onto the stack +****************************************************************************/ +static void push_mangled_name(char *s) +{ + int i; + char *p; + + if (!mangled_stack) + return; + + for (i=0;i