Implemented name DOS 8.3 name mangling
This commit is contained in:
parent
406abe81e6
commit
cae45854ab
@ -4323,7 +4323,8 @@ v0.33.19 26-Oct-2001
|
|||||||
Started working on long filename support. The real name on
|
Started working on long filename support. The real name on
|
||||||
disk is the long filename, the database records also holds
|
disk is the long filename, the database records also holds
|
||||||
an uppercase 8.3 filename. In most cases this is just the
|
an uppercase 8.3 filename. In most cases this is just the
|
||||||
same name in upper and lowercase.
|
same name in upper and lowercase. Name mangling like Win$
|
||||||
|
is performed on the long filenames.
|
||||||
Implemented "mbfile import" function, this imports complete
|
Implemented "mbfile import" function, this imports complete
|
||||||
areas from files.bbs information.
|
areas from files.bbs information.
|
||||||
Added "mbfile toberep" function, this gives an overview of the
|
Added "mbfile toberep" function, this gives an overview of the
|
||||||
@ -4333,6 +4334,9 @@ v0.33.19 26-Oct-2001
|
|||||||
the index.html files for http download and 00index files in
|
the index.html files for http download and 00index files in
|
||||||
all available areas. The files.bbs files have download
|
all available areas. The files.bbs files have download
|
||||||
counters included.
|
counters included.
|
||||||
|
The mbfile check function now converts the short filenames
|
||||||
|
to DOS 8.3 filenames. (The first time this logs lots of
|
||||||
|
errors).
|
||||||
|
|
||||||
mball:
|
mball:
|
||||||
The index function is now obsolete, this is added to mbfile.
|
The index function is now obsolete, this is added to mbfile.
|
||||||
|
@ -912,5 +912,14 @@ int flag_on(char *,char *);
|
|||||||
char *strcasestr(char *, char *);
|
char *strcasestr(char *, char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mangle.c
|
||||||
|
*/
|
||||||
|
void mangle_name_83( char *);
|
||||||
|
int name_mangle(char *, int);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
588
lib/mangle.c
588
lib/mangle.c
@ -39,64 +39,62 @@
|
|||||||
/*
|
/*
|
||||||
* Prototype functions
|
* Prototype functions
|
||||||
*/
|
*/
|
||||||
int strequal(const char *, const char *);
|
int strhaslower(const char *);
|
||||||
int strhasupper(const char *);
|
int str_checksum(const char *);
|
||||||
int strhaslower(const char *);
|
char *safe_strcpy(char *, const char *, size_t);
|
||||||
int strisnormal(char *);
|
static void init_chartest(void);
|
||||||
int str_checksum(const char *);
|
static int is_reserved_msdos(char *);
|
||||||
char *safe_strcpy(char *, const char *, size_t);
|
static int is_illegal_name(char *);
|
||||||
static void init_chartest(void);
|
int is_8_3(char *);
|
||||||
static int is_reserved_msdos(char *);
|
|
||||||
static int is_illegal_name(char *);
|
|
||||||
int is_mangled(char *);
|
|
||||||
int is_8_3( char *, int);
|
|
||||||
static char *map_filename(char *, char *, int);
|
|
||||||
static void do_fwd_mangled_map(char *, char *);
|
|
||||||
void mangle_name_83( char *);
|
|
||||||
int name_map_mangle(char *, int, int, int);
|
|
||||||
|
|
||||||
|
|
||||||
#define pstrcpy(d,s) safe_strcpy((d),(s),sizeof(pstring)-1)
|
|
||||||
#define pstrcat(d,s) safe_strcat((d),(s),sizeof(pstring)-1)
|
|
||||||
#define PTR_DIFF(p1,p2) ((int)(((const char *)(p1)) - (const char *)(p2)))
|
#define PTR_DIFF(p1,p2) ((int)(((const char *)(p1)) - (const char *)(p2)))
|
||||||
|
|
||||||
#define isdoschar(c) (dos_char_map[(c&0xff)] != 0)
|
/* -------------------------------------------------------------------------- **
|
||||||
|
* Other stuff...
|
||||||
|
*
|
||||||
|
* magic_char - This is the magic char used for mangling. It's
|
||||||
|
* global. There is a call to lp_magicchar() in server.c
|
||||||
|
* that is used to override the initial value.
|
||||||
|
*
|
||||||
|
* MANGLE_BASE - This is the number of characters we use for name mangling.
|
||||||
|
*
|
||||||
|
* basechars - The set characters used for name mangling. This
|
||||||
|
* is static (scope is this file only).
|
||||||
|
*
|
||||||
|
* mangle() - Macro used to select a character from basechars (i.e.,
|
||||||
|
* mangle(n) will return the nth digit, modulo MANGLE_BASE).
|
||||||
|
*
|
||||||
|
* chartest - array 0..255. The index range is the set of all possible
|
||||||
|
* values of a byte. For each byte value, the content is a
|
||||||
|
* two nibble pair. See BASECHAR_MASK and ILLEGAL_MASK,
|
||||||
|
* below.
|
||||||
|
*
|
||||||
|
* ct_initialized - False until the chartest array has been initialized via
|
||||||
|
* a call to init_chartest().
|
||||||
|
*
|
||||||
|
* BASECHAR_MASK - Masks the upper nibble of a one-byte value.
|
||||||
|
*
|
||||||
|
* ILLEGAL_MASK - Masks the lower nibble of a one-byte value.
|
||||||
|
*
|
||||||
|
* isillegal() - Given a character, check the chartest array to see
|
||||||
|
* if that character is in the illegal characters set.
|
||||||
|
* This is faster than using strchr().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
typedef enum {CASE_UPPER, CASE_LOWER} CASES;
|
char magic_char = '~';
|
||||||
|
|
||||||
int case_default = CASE_UPPER; /* Are conforming 8.3 names all upper or lower? */
|
static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
|
||||||
int case_mangle = TRUE; /* If true, all chars in 8.3 should be same case. */
|
#define MANGLE_BASE (sizeof(basechars)/sizeof(char)-1)
|
||||||
|
|
||||||
#define PSTRING_LEN 1024
|
static unsigned char chartest[256] = { 0 };
|
||||||
typedef char pstring[PSTRING_LEN];
|
static int ct_initialized = FALSE;
|
||||||
|
|
||||||
|
#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
|
||||||
/*******************************************************************
|
#define BASECHAR_MASK 0xf0
|
||||||
compare 2 strings
|
#define ILLEGAL_MASK 0x0f
|
||||||
********************************************************************/
|
#define isillegal(C) ( (chartest[ ((C) & 0xff) ]) & ILLEGAL_MASK )
|
||||||
int strequal(const char *s1, const char *s2)
|
|
||||||
{
|
|
||||||
if (s1 == s2)
|
|
||||||
return(TRUE);
|
|
||||||
if (!s1 || !s2)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
return(strcasecmp(s1,s2)==0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
does a string have any uppercase chars in it?
|
|
||||||
****************************************************************************/
|
|
||||||
int strhasupper(const char *s)
|
|
||||||
{
|
|
||||||
while (*s) {
|
|
||||||
if (isupper(*s))
|
|
||||||
return TRUE;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -114,17 +112,6 @@ int strhaslower(const char *s)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
|
||||||
* check if a string is in "normal" case
|
|
||||||
* ********************************************************************/
|
|
||||||
int strisnormal(char *s)
|
|
||||||
{
|
|
||||||
if (case_default == CASE_UPPER)
|
|
||||||
return(!strhaslower(s));
|
|
||||||
|
|
||||||
return(!strhasupper(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Provide a checksum on a string
|
* Provide a checksum on a string
|
||||||
@ -138,9 +125,9 @@ int strisnormal(char *s)
|
|||||||
*/
|
*/
|
||||||
int str_checksum(const char *s)
|
int str_checksum(const char *s)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int c;
|
int c;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
|
||||||
while(*s) {
|
while(*s) {
|
||||||
c = *s;
|
c = *s;
|
||||||
@ -149,7 +136,9 @@ int str_checksum(const char *s)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
} /* str_checksum */
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
safe string copy into a known length string. maxlength does not
|
safe string copy into a known length string. maxlength does not
|
||||||
@ -184,79 +173,6 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- **
|
|
||||||
* Other stuff...
|
|
||||||
*
|
|
||||||
* magic_char - This is the magic char used for mangling. It's
|
|
||||||
* global. There is a call to lp_magicchar() in server.c
|
|
||||||
* that is used to override the initial value.
|
|
||||||
*
|
|
||||||
* MANGLE_BASE - This is the number of characters we use for name mangling.
|
|
||||||
*
|
|
||||||
* basechars - The set characters used for name mangling. This
|
|
||||||
* is static (scope is this file only).
|
|
||||||
*
|
|
||||||
* mangle() - Macro used to select a character from basechars (i.e.,
|
|
||||||
* mangle(n) will return the nth digit, modulo MANGLE_BASE).
|
|
||||||
*
|
|
||||||
* chartest - array 0..255. The index range is the set of all possible
|
|
||||||
* values of a byte. For each byte value, the content is a
|
|
||||||
* two nibble pair. See BASECHAR_MASK and ILLEGAL_MASK,
|
|
||||||
* below.
|
|
||||||
*
|
|
||||||
* ct_initialized - False until the chartest array has been initialized via
|
|
||||||
* a call to init_chartest().
|
|
||||||
*
|
|
||||||
* BASECHAR_MASK - Masks the upper nibble of a one-byte value.
|
|
||||||
*
|
|
||||||
* ILLEGAL_MASK - Masks the lower nibble of a one-byte value.
|
|
||||||
*
|
|
||||||
* isbasecahr() - Given a character, check the chartest array to see
|
|
||||||
* if that character is in the basechars set. This is
|
|
||||||
* faster than using strchr().
|
|
||||||
*
|
|
||||||
* isillegal() - Given a character, check the chartest array to see
|
|
||||||
* if that character is in the illegal characters set.
|
|
||||||
* This is faster than using strchr().
|
|
||||||
*
|
|
||||||
* mangled_cache - Cache header used for storing mangled -> original
|
|
||||||
* reverse maps.
|
|
||||||
*
|
|
||||||
* mc_initialized - False until the mangled_cache structure has been
|
|
||||||
* initialized via a call to reset_mangled_cache().
|
|
||||||
*
|
|
||||||
* MANGLED_CACHE_MAX_ENTRIES - Default maximum number of entries for the
|
|
||||||
* cache. A value of 0 indicates "infinite".
|
|
||||||
*
|
|
||||||
* MANGLED_CACHE_MAX_MEMORY - Default maximum amount of memory for the
|
|
||||||
* cache. When the cache was kept as an array of 256
|
|
||||||
* byte strings, the default cache size was 50 entries.
|
|
||||||
* This required a fixed 12.5Kbytes of memory. The
|
|
||||||
* mangled stack parameter is no longer used (though
|
|
||||||
* this might change). We're now using a fixed 16Kbyte
|
|
||||||
* maximum cache size. This will probably be much more
|
|
||||||
* than 50 entries.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char magic_char = '~';
|
|
||||||
|
|
||||||
static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
|
|
||||||
#define MANGLE_BASE (sizeof(basechars)/sizeof(char)-1)
|
|
||||||
|
|
||||||
static unsigned char chartest[256] = { 0 };
|
|
||||||
static int ct_initialized = FALSE;
|
|
||||||
|
|
||||||
#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
|
|
||||||
#define BASECHAR_MASK 0xf0
|
|
||||||
#define ILLEGAL_MASK 0x0f
|
|
||||||
#define isbasechar(C) ( (chartest[ ((C) & 0xff) ]) & BASECHAR_MASK )
|
|
||||||
#define isillegal(C) ( (chartest[ ((C) & 0xff) ]) & ILLEGAL_MASK )
|
|
||||||
|
|
||||||
//static ubi_cacheRoot mangled_cache[1] = { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0 } };
|
|
||||||
//static int mc_initialized = FALSE;
|
|
||||||
//#define MANGLED_CACHE_MAX_ENTRIES 0
|
|
||||||
//#define MANGLED_CACHE_MAX_MEMORY 16384
|
|
||||||
|
|
||||||
/* ************************************************************************** **
|
/* ************************************************************************** **
|
||||||
* Initialize the static character test array.
|
* Initialize the static character test array.
|
||||||
*
|
*
|
||||||
@ -377,59 +293,23 @@ static int is_illegal_name(char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} /* is_illegal_name */
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************** **
|
|
||||||
* Return True if the name *could be* a mangled name.
|
|
||||||
*
|
|
||||||
* Input: s - A path name - in UNIX pathname format.
|
|
||||||
*
|
|
||||||
* Output: True if the name matches the pattern described below in the
|
|
||||||
* notes, else False.
|
|
||||||
*
|
|
||||||
* Notes: The input name is *not* tested for 8.3 compliance. This must be
|
|
||||||
* done separately. This function returns true if the name contains
|
|
||||||
* a magic character followed by excactly two characters from the
|
|
||||||
* basechars list (above), which in turn are followed either by the
|
|
||||||
* nul (end of string) byte or a dot (extension) or by a '/' (end of
|
|
||||||
* a directory name).
|
|
||||||
*
|
|
||||||
* ************************************************************************** **
|
|
||||||
*/
|
|
||||||
int is_mangled(char *s)
|
|
||||||
{
|
|
||||||
char *magic;
|
|
||||||
|
|
||||||
if (!ct_initialized)
|
|
||||||
init_chartest();
|
|
||||||
|
|
||||||
magic = strchr(s, magic_char);
|
|
||||||
while (magic && magic[1] && magic[2]) { /* 3 chars, 1st is magic. */
|
|
||||||
if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */
|
|
||||||
&& isbasechar(toupper(magic[1])) /* is 2nd char basechar? */
|
|
||||||
&& isbasechar(toupper(magic[2]))) /* is 3rd char basechar? */
|
|
||||||
return TRUE; /* If all above, then true, */
|
|
||||||
magic = strchr(magic+1, magic_char); /* else seek next magic. */
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
} /* is_mangled */
|
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************** **
|
/* ************************************************************************** **
|
||||||
* Return True if the name is a valid DOS name in 8.3 DOS format.
|
* Return True if the name is a valid DOS name in 8.3 DOS format.
|
||||||
*
|
*
|
||||||
* Input: fname - File name to be checked.
|
* Input: fname - File name to be checked.
|
||||||
* check_case - If True, and if case_mangle is True, then the
|
* check_case - If True, then the
|
||||||
* name will be checked to see if all characters
|
* name will be checked to see if all characters
|
||||||
* are the correct case. See case_mangle and
|
* are the correct case.
|
||||||
* case_default above.
|
|
||||||
*
|
*
|
||||||
* Output: True if the name is a valid DOS name, else FALSE.
|
* Output: True if the name is a valid DOS name, else FALSE.
|
||||||
*
|
*
|
||||||
* ************************************************************************** **
|
* ************************************************************************** **
|
||||||
*/
|
*/
|
||||||
int is_8_3( char *fname, int check_case )
|
int is_8_3( char *fname)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int l;
|
int l;
|
||||||
@ -442,7 +322,7 @@ int is_8_3( char *fname, int check_case )
|
|||||||
fname = slash_pos + 1;
|
fname = slash_pos + 1;
|
||||||
len = strlen(fname);
|
len = strlen(fname);
|
||||||
|
|
||||||
Syslog('f', "Checking %s for 8.3\n", fname);
|
// Syslog('f', "Checking %s for 8.3", fname);
|
||||||
|
|
||||||
/* Can't be 0 chars or longer than 12 chars */
|
/* Can't be 0 chars or longer than 12 chars */
|
||||||
if( (len == 0) || (len > 12) )
|
if( (len == 0) || (len > 12) )
|
||||||
@ -453,18 +333,8 @@ int is_8_3( char *fname, int check_case )
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Check that all characters are the correct case, if asked to do so. */
|
/* Check that all characters are the correct case, if asked to do so. */
|
||||||
if (check_case && case_mangle) {
|
// if (strhaslower(fname))
|
||||||
switch (case_default) {
|
// return FALSE;
|
||||||
case CASE_LOWER:
|
|
||||||
if (strhasupper(fname))
|
|
||||||
return FALSE;
|
|
||||||
break;
|
|
||||||
case CASE_UPPER:
|
|
||||||
if (strhaslower(fname))
|
|
||||||
return FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Can't contain invalid dos chars */
|
/* Can't contain invalid dos chars */
|
||||||
/* Windows use the ANSI charset.
|
/* Windows use the ANSI charset.
|
||||||
@ -517,171 +387,9 @@ int is_8_3( char *fname, int check_case )
|
|||||||
|
|
||||||
/* must be in 8.3 format */
|
/* must be in 8.3 format */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} /* is_8_3 */
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************** **
|
|
||||||
* Used only in do_fwd_mangled_map(), below.
|
|
||||||
* ************************************************************************** **
|
|
||||||
*/
|
|
||||||
static char *map_filename( char *s, /* This is null terminated */
|
|
||||||
char *pattern, /* This isn't. */
|
|
||||||
int len ) /* This is the length of pattern. */
|
|
||||||
{
|
|
||||||
static pstring matching_bit; /* The bit of the string which matches */
|
|
||||||
/* a * in pattern if indeed there is a * */
|
|
||||||
char *sp; /* Pointer into s. */
|
|
||||||
char *pp; /* Pointer into p. */
|
|
||||||
char *match_start; /* Where the matching bit starts. */
|
|
||||||
pstring pat;
|
|
||||||
|
|
||||||
strncpy( pat, pattern, len ); /* Get pattern into a proper string! */
|
|
||||||
pstrcpy( matching_bit, "" ); /* Match but no star gets this. */
|
|
||||||
pp = pat; /* Initialize the pointers. */
|
|
||||||
sp = s;
|
|
||||||
|
|
||||||
if( strequal(s, ".") || strequal(s, "..")) {
|
|
||||||
return NULL; /* Do not map '.' and '..' */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((len == 1) && (*pattern == '*')) {
|
|
||||||
return NULL; /* Impossible, too ambiguous for */
|
|
||||||
} /* words! */
|
|
||||||
|
|
||||||
while ((*sp) /* Not the end of the string. */
|
|
||||||
&& (*pp) /* Not the end of the pattern. */
|
|
||||||
&& (*sp == *pp) /* The two match. */
|
|
||||||
&& (*pp != '*')) { /* No wildcard. */
|
|
||||||
sp++; /* Keep looking. */
|
|
||||||
pp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*sp && !*pp) /* End of pattern. */
|
|
||||||
return (matching_bit); /* Simple match. Return empty string. */
|
|
||||||
|
|
||||||
if (*pp == '*') {
|
|
||||||
pp++; /* Always interrested in the chacter */
|
|
||||||
/* after the '*' */
|
|
||||||
if (!*pp) { /* It is at the end of the pattern. */
|
|
||||||
strncpy(matching_bit, s, sp-s);
|
|
||||||
return matching_bit;
|
|
||||||
} else {
|
|
||||||
/* The next character in pattern must match a character further */
|
|
||||||
/* along s than sp so look for that character. */
|
|
||||||
match_start = sp;
|
|
||||||
while ((*sp) /* Not the end of s. */
|
|
||||||
&& (*sp != *pp)) /* Not the same */
|
|
||||||
sp++; /* Keep looking. */
|
|
||||||
if (!*sp) { /* Got to the end without a match. */
|
|
||||||
return( NULL );
|
|
||||||
} else { /* Still hope for a match. */
|
|
||||||
/* Now sp should point to a matching character. */
|
|
||||||
strncpy(matching_bit, match_start, sp-match_start);
|
|
||||||
/* Back to needing a stright match again. */
|
|
||||||
while ((*sp) /* Not the end of the string. */
|
|
||||||
&& (*pp) /* Not the end of the pattern. */
|
|
||||||
&& (*sp == *pp)) { /* The two match. */
|
|
||||||
sp++; /* Keep looking. */
|
|
||||||
pp++;
|
|
||||||
}
|
|
||||||
if (!*sp && !*pp) /* Both at end so it matched */
|
|
||||||
return matching_bit;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL; /* No match. */
|
|
||||||
} /* map_filename */
|
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************** **
|
|
||||||
* MangledMap is a series of name pairs in () separated by spaces.
|
|
||||||
* If s matches the first of the pair then the name given is the
|
|
||||||
* second of the pair. A * means any number of any character and if
|
|
||||||
* present in the second of the pair as well as the first the
|
|
||||||
* matching part of the first string takes the place of the * in the
|
|
||||||
* second.
|
|
||||||
*
|
|
||||||
* I wanted this so that we could have RCS files which can be used
|
|
||||||
* by UNIX and DOS programs. My mapping string is (RCS rcs) which
|
|
||||||
* converts the UNIX RCS file subdirectory to lowercase thus
|
|
||||||
* preventing mangling.
|
|
||||||
*
|
|
||||||
* (I think Andrew wrote the above, but I'm not sure. -- CRH)
|
|
||||||
*
|
|
||||||
* See 'mangled map' in smb.conf(5).
|
|
||||||
*
|
|
||||||
* ************************************************************************** **
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void do_fwd_mangled_map(char *s, char *MangledMap)
|
|
||||||
{
|
|
||||||
char *start=MangledMap; /* Use this to search for mappings. */
|
|
||||||
char *end; /* Used to find the end of strings. */
|
|
||||||
char *match_string;
|
|
||||||
pstring new_string; /* Make up the result here. */
|
|
||||||
char *np; /* Points into new_string. */
|
|
||||||
|
|
||||||
Syslog('f', "Mangled Mapping '%s' map '%s'\n", s, MangledMap);
|
|
||||||
while( *start )
|
|
||||||
{
|
|
||||||
while( (*start) && (*start != '(') )
|
|
||||||
start++;
|
|
||||||
if( !*start )
|
|
||||||
continue; /* Always check for the end. */
|
|
||||||
start++; /* Skip the ( */
|
|
||||||
end = start; /* Search for the ' ' or a ')' */
|
|
||||||
Syslog('f', "Start of first in pair '%s'\n", start);
|
|
||||||
while( (*end) && !((*end == ' ') || (*end == ')')) )
|
|
||||||
end++;
|
|
||||||
if( !*end )
|
|
||||||
{
|
|
||||||
start = end;
|
|
||||||
continue; /* Always check for the end. */
|
|
||||||
}
|
|
||||||
Syslog('f', "End of first in pair '%s'\n", end);
|
|
||||||
if( (match_string = map_filename( s, start, end-start )) )
|
|
||||||
{
|
|
||||||
Syslog('f', "Found a match\n");
|
|
||||||
/* Found a match. */
|
|
||||||
start = end + 1; /* Point to start of what it is to become. */
|
|
||||||
Syslog('f', "Start of second in pair '%s'\n", start);
|
|
||||||
end = start;
|
|
||||||
np = new_string;
|
|
||||||
while( (*end) /* Not the end of string. */
|
|
||||||
&& (*end != ')') /* Not the end of the pattern. */
|
|
||||||
&& (*end != '*') ) /* Not a wildcard. */
|
|
||||||
*np++ = *end++;
|
|
||||||
if( !*end )
|
|
||||||
{
|
|
||||||
start = end;
|
|
||||||
continue; /* Always check for the end. */
|
|
||||||
}
|
|
||||||
if( *end == '*' )
|
|
||||||
{
|
|
||||||
pstrcpy( np, match_string );
|
|
||||||
np += strlen( match_string );
|
|
||||||
end++; /* Skip the '*' */
|
|
||||||
while( (*end) /* Not the end of string. */
|
|
||||||
&& (*end != ')') /* Not the end of the pattern. */
|
|
||||||
&& (*end != '*') ) /* Not a wildcard. */
|
|
||||||
*np++ = *end++;
|
|
||||||
}
|
|
||||||
if( !*end )
|
|
||||||
{
|
|
||||||
start = end;
|
|
||||||
continue; /* Always check for the end. */
|
|
||||||
}
|
|
||||||
*np++ = '\0'; /* NULL terminate it. */
|
|
||||||
Syslog('f', "End of second in pair '%s'\n", end);
|
|
||||||
pstrcpy( s, new_string ); /* Substitute with the new name. */
|
|
||||||
Syslog('f', "s is now '%s'\n", s);
|
|
||||||
}
|
|
||||||
start = end; /* Skip a bit which cannot be wanted anymore. */
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
} /* do_fwd_mangled_map */
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* do the actual mangling to 8.3 format
|
* do the actual mangling to 8.3 format
|
||||||
@ -690,24 +398,23 @@ static void do_fwd_mangled_map(char *s, char *MangledMap)
|
|||||||
*/
|
*/
|
||||||
void mangle_name_83(char *s)
|
void mangle_name_83(char *s)
|
||||||
{
|
{
|
||||||
int csum;
|
int csum;
|
||||||
char *p;
|
char *p;
|
||||||
char extension[4];
|
char extension[4];
|
||||||
char base[9];
|
char base[9];
|
||||||
int baselen = 0;
|
int baselen = 0;
|
||||||
int extlen = 0;
|
int extlen = 0;
|
||||||
int skip;
|
|
||||||
|
|
||||||
extension[0] = 0;
|
extension[0] = 0;
|
||||||
base[0] = 0;
|
base[0] = 0;
|
||||||
|
|
||||||
p = strrchr(s,'.');
|
p = strrchr(s,'.');
|
||||||
if (p && (strlen(p+1) < (size_t)4)) {
|
if (p && (strlen(p+1) < (size_t)4)) {
|
||||||
int all_normal = (strisnormal(p+1)); /* XXXXXXXXX */
|
int all_normal = (!strhaslower(p+1)); /* XXXXXXXXX */
|
||||||
|
|
||||||
if( all_normal && p[1] != 0 ) {
|
if (all_normal && p[1] != 0) {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
csum = str_checksum( s );
|
csum = str_checksum(s);
|
||||||
*p = '.';
|
*p = '.';
|
||||||
} else
|
} else
|
||||||
csum = str_checksum(s);
|
csum = str_checksum(s);
|
||||||
@ -715,79 +422,43 @@ void mangle_name_83(char *s)
|
|||||||
csum = str_checksum(s);
|
csum = str_checksum(s);
|
||||||
|
|
||||||
tu(s);
|
tu(s);
|
||||||
Syslog('f', "Mangling name %s to ",s);
|
// Syslog('f', "Mangling name %s to ",s);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
if( p == s )
|
if( p == s )
|
||||||
safe_strcpy( extension, "___", 3 );
|
safe_strcpy( extension, "___", 3 );
|
||||||
else {
|
else {
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
while (*p && extlen < 3) {
|
while (*p && extlen < 3) {
|
||||||
skip = get_character_len(*p);
|
if (*p != '.' )
|
||||||
switch(skip) {
|
extension[extlen++] = p[0];
|
||||||
case 2:
|
p++;
|
||||||
if( extlen < 2 ) {
|
}
|
||||||
extension[extlen++] = p[0];
|
extension[extlen] = 0;
|
||||||
extension[extlen++] = p[1];
|
}
|
||||||
} else {
|
|
||||||
extension[extlen++] = mangle( (unsigned char)*p );
|
|
||||||
}
|
|
||||||
p += 2;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
extension[extlen++] = p[0];
|
|
||||||
p++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(/* isdoschar (*p) && */ *p != '.' )
|
|
||||||
extension[extlen++] = p[0];
|
|
||||||
p++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extension[extlen] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p = s;
|
p = s;
|
||||||
|
|
||||||
while( *p && baselen < 5 ) {
|
while (*p && baselen < 5) {
|
||||||
skip = get_character_len(*p);
|
if (*p != '.' )
|
||||||
switch( skip ) {
|
base[baselen++] = p[0];
|
||||||
case 2:
|
p++;
|
||||||
if( baselen < 4 ) {
|
|
||||||
base[baselen++] = p[0];
|
|
||||||
base[baselen++] = p[1];
|
|
||||||
} else {
|
|
||||||
base[baselen++] = mangle( (unsigned char)*p );
|
|
||||||
}
|
|
||||||
p += 2;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
base[baselen++] = p[0];
|
|
||||||
p++;
|
|
||||||
break;
|
|
||||||
if(/* isdoschar( *p ) && */ *p != '.' )
|
|
||||||
base[baselen++] = p[0];
|
|
||||||
p++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
base[baselen] = 0;
|
base[baselen] = 0;
|
||||||
|
|
||||||
csum = csum % (MANGLE_BASE*MANGLE_BASE);
|
csum = csum % (MANGLE_BASE*MANGLE_BASE);
|
||||||
|
sprintf(s, "%s%c%c%c", base, magic_char, mangle(csum/MANGLE_BASE), mangle(csum));
|
||||||
|
|
||||||
(void)slprintf(s, 12, "%s%c%c%c",
|
if( *extension ) {
|
||||||
base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
|
(void)strcat(s, ".");
|
||||||
|
(void)strcat(s, extension);
|
||||||
if( *extension ) {
|
|
||||||
(void)pstrcat( s, "." );
|
|
||||||
(void)pstrcat( s, extension );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Syslog('f', "%s\n", s);
|
// Syslog('f', "%s", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* mangle_name_83 */
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Convert a filename to DOS format. Return True if successful.
|
* Convert a filename to DOS format. Return True if successful.
|
||||||
@ -803,59 +474,36 @@ void mangle_name_83(char *s)
|
|||||||
* signal that a client does not require name mangling,
|
* signal that a client does not require name mangling,
|
||||||
* thus skipping the name mangling even on shares which
|
* thus skipping the name mangling even on shares which
|
||||||
* have name-mangling turned on.
|
* have name-mangling turned on.
|
||||||
* cache83 - If False, the mangled name cache will not be updated.
|
|
||||||
* This is usually used to prevent that we overwrite
|
|
||||||
* a conflicting cache entry prematurely, i.e. before
|
|
||||||
* we know whether the client is really interested in the
|
|
||||||
* current name. (See PR#13758). UKD.
|
|
||||||
* snum - Share number. This identifies the share in which the
|
|
||||||
* name exists.
|
|
||||||
*
|
*
|
||||||
* Output: Returns False only if the name wanted mangling but the share does
|
* Output: Returns False only if the name wanted mangling but the share does
|
||||||
* not have name mangling turned on.
|
* not have name mangling turned on.
|
||||||
*
|
*
|
||||||
* ****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
int name_map_mangle(char *OutName, int need83, int cache83, int snum)
|
int name_mangle(char *OutName, int need83)
|
||||||
{
|
{
|
||||||
char *map;
|
Syslog('f', "name_mangle(%s, need83 = %s)", OutName, need83 ? "TRUE" : "FALSE");
|
||||||
Syslog('f',"name_map_mangle( %s, need83 = %s, cache83 = %s, %d )\n", OutName,
|
|
||||||
need83 ? "TRUE" : "FALSE", cache83 ? "TRUE" : "FALSE", snum);
|
|
||||||
|
|
||||||
#ifdef MANGLE_LONG_FILENAMES
|
/*
|
||||||
if( !need83 && is_illegal_name(OutName) )
|
* Check for characters legal in Unix and illegal in DOS/Win
|
||||||
need83 = TRUE;
|
*/
|
||||||
#endif
|
if (!need83 && is_illegal_name(OutName))
|
||||||
|
need83 = TRUE;
|
||||||
/* apply any name mappings */
|
|
||||||
map = lp_mangled_map(snum);
|
|
||||||
|
|
||||||
if (map && *map) {
|
|
||||||
do_fwd_mangled_map( OutName, map );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if it's already in 8.3 format */
|
|
||||||
if (need83 && !is_8_3(OutName, TRUE)) {
|
|
||||||
char *tmp = NULL;
|
|
||||||
|
|
||||||
if (!lp_manglednames(snum)) {
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mangle it into 8.3 */
|
|
||||||
if (cache83)
|
|
||||||
tmp = strdup(OutName);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check if it's already in 8.3 format
|
||||||
|
*/
|
||||||
|
if (need83 && !is_8_3(OutName)) {
|
||||||
mangle_name_83(OutName);
|
mangle_name_83(OutName);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* No mangling needed, convert to uppercase
|
||||||
|
*/
|
||||||
|
tu(OutName);
|
||||||
|
}
|
||||||
|
|
||||||
if(tmp != NULL) {
|
Syslog('f',"name_mangle() ==> [%s]", OutName);
|
||||||
cache_mangled_name(OutName, tmp);
|
return TRUE;
|
||||||
free(tmp);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Syslog('f',"name_map_mangle() ==> [%s]\n", OutName);
|
|
||||||
return(TRUE);
|
|
||||||
} /* name_map_mangle */
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,16 +273,12 @@ void AdoptFile(int Area, char *File, char *Description)
|
|||||||
*/
|
*/
|
||||||
chdir(pwd);
|
chdir(pwd);
|
||||||
DeleteVirusWork();
|
DeleteVirusWork();
|
||||||
if (strlen(File) < 13) {
|
/*
|
||||||
strcpy(fdb.Name, File);
|
* Convert to 8.3 DOS filename
|
||||||
for (i = 0; i < strlen(File); i++)
|
*/
|
||||||
fdb.Name[i] = toupper(fdb.Name[i]);
|
strcpy(temp2, File);
|
||||||
} else {
|
name_mangle(temp2, TRUE);
|
||||||
WriteError("Long filename conversion not supported");
|
strcpy(fdb.Name, temp2);
|
||||||
if (!do_quiet)
|
|
||||||
printf("Long filename conversion not supported\n");
|
|
||||||
die(0);
|
|
||||||
}
|
|
||||||
strcpy(fdb.LName, File);
|
strcpy(fdb.LName, File);
|
||||||
fdb.Size = file_size(File);
|
fdb.Size = file_size(File);
|
||||||
fdb.Crc32 = file_crc(File, TRUE);
|
fdb.Crc32 = file_crc(File, TRUE);
|
||||||
|
@ -64,7 +64,7 @@ void Check(void)
|
|||||||
FILE *pAreas, *pFile;
|
FILE *pAreas, *pFile;
|
||||||
int i, iAreas, iAreasNew = 0;
|
int i, iAreas, iAreasNew = 0;
|
||||||
int iTotal = 0, iErrors = 0;
|
int iTotal = 0, iErrors = 0;
|
||||||
char *sAreas, *fAreas, *newdir;
|
char *sAreas, *fAreas, *newdir, *temp;
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
int Found, Update;
|
int Found, Update;
|
||||||
@ -74,6 +74,7 @@ void Check(void)
|
|||||||
sAreas = calloc(PATH_MAX, sizeof(char));
|
sAreas = calloc(PATH_MAX, sizeof(char));
|
||||||
fAreas = calloc(PATH_MAX, sizeof(char));
|
fAreas = calloc(PATH_MAX, sizeof(char));
|
||||||
newdir = calloc(PATH_MAX, sizeof(char));
|
newdir = calloc(PATH_MAX, sizeof(char));
|
||||||
|
temp = calloc(PATH_MAX, sizeof(char));
|
||||||
|
|
||||||
if (!do_quiet) {
|
if (!do_quiet) {
|
||||||
colour(3, 0);
|
colour(3, 0);
|
||||||
@ -154,6 +155,15 @@ void Check(void)
|
|||||||
*/
|
*/
|
||||||
Marker();
|
Marker();
|
||||||
Update = FALSE;
|
Update = FALSE;
|
||||||
|
|
||||||
|
strcpy(temp, file.LName);
|
||||||
|
name_mangle(temp, TRUE);
|
||||||
|
if (strcmp(file.Name, temp)) {
|
||||||
|
Syslog('!', "Converted %s to %s", file.Name, temp);
|
||||||
|
strncpy(file.Name, temp, 12);
|
||||||
|
iErrors++;
|
||||||
|
Update = TRUE;
|
||||||
|
}
|
||||||
if (file_time(newdir) != file.FileDate) {
|
if (file_time(newdir) != file.FileDate) {
|
||||||
Syslog('!', "Date mismatch area %d file %s", i, file.LName);
|
Syslog('!', "Date mismatch area %d file %s", i, file.LName);
|
||||||
file.FileDate = file_time(newdir);
|
file.FileDate = file_time(newdir);
|
||||||
@ -236,6 +246,7 @@ void Check(void)
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(temp);
|
||||||
free(newdir);
|
free(newdir);
|
||||||
free(sAreas);
|
free(sAreas);
|
||||||
free(fAreas);
|
free(fAreas);
|
||||||
|
@ -187,8 +187,31 @@ void ImportFiles(int Area)
|
|||||||
memset(&fdb, 0, sizeof(fdb));
|
memset(&fdb, 0, sizeof(fdb));
|
||||||
|
|
||||||
token = strtok(String, " \t");
|
token = strtok(String, " \t");
|
||||||
strcpy(fdb.Name, token);
|
strcpy(fdb.LName, token);
|
||||||
strcpy(fdb.LName, tl(token));
|
/*
|
||||||
|
* Test filename against name on disk, first normal case,
|
||||||
|
* then lowercase and finally uppercase.
|
||||||
|
*/
|
||||||
|
sprintf(temp,"%s/%s", pwd, fdb.LName);
|
||||||
|
if (stat(temp,&statfile) != 0) {
|
||||||
|
strcpy(fdb.LName, tl(token));
|
||||||
|
sprintf(temp,"%s/%s", pwd, fdb.LName);
|
||||||
|
if (stat(temp,&statfile) != 0) {
|
||||||
|
strcpy(fdb.LName, tu(token));
|
||||||
|
if (stat(temp,&statfile) != 0) {
|
||||||
|
WriteError("Cannot locate file on disk! Skipping... -> %s\n",temp);
|
||||||
|
Append = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create DOS 8.3 filename
|
||||||
|
*/
|
||||||
|
strcpy(temp, fdb.LName);
|
||||||
|
name_mangle(temp, TRUE);
|
||||||
|
strcpy(fdb.Name, temp);
|
||||||
|
|
||||||
if (do_annon)
|
if (do_annon)
|
||||||
fdb.Announced = TRUE;
|
fdb.Announced = TRUE;
|
||||||
Syslog('f', "File: %s (%s)", fdb.Name, fdb.LName);
|
Syslog('f', "File: %s (%s)", fdb.Name, fdb.LName);
|
||||||
@ -237,14 +260,6 @@ void ImportFiles(int Area)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(temp,"%s/%s", pwd, fdb.LName);
|
|
||||||
if (stat(temp,&statfile) != 0) {
|
|
||||||
sprintf(temp,"%s/%s", pwd, fdb.Name);
|
|
||||||
if (stat(temp,&statfile) != 0) {
|
|
||||||
WriteError("Cannot locate file on disk! Skipping... -> %s\n",temp);
|
|
||||||
Append = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sprintf(dest, "%s/%s", area.Path, fdb.LName);
|
sprintf(dest, "%s/%s", area.Path, fdb.LName);
|
||||||
Append = TRUE;
|
Append = TRUE;
|
||||||
fdb.Size = statfile.st_size;
|
fdb.Size = statfile.st_size;
|
||||||
|
Reference in New Issue
Block a user