⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mangle_hash2.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		M_DEBUG(10,("check_cache: %s -> not mangled\n", name));		return False;	}	/* we need to extract the hash from the 8.3 name */	hash = base_reverse[(unsigned char)name[7]];	for (multiplier=36, i=5;i>=mangle_prefix;i--) {		u32 v = base_reverse[(unsigned char)name[i]];		hash += multiplier * v;		multiplier *= 36;	}	/* now look in the prefix cache for that hash */	prefix = cache_lookup(hash);	if (!prefix) {		M_DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash));		return False;	}	/* we found it - construct the full name */	if (name[8] == '.') {		strncpy(extension, name+9, 3);		extension[3] = 0;	} else {		extension[0] = 0;	}	if (extension[0]) {		M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension));		slprintf(name, maxlen, "%s.%s", prefix, extension);	} else {		M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix));		safe_strcpy(name, prefix, maxlen);	}	return True;}/*  look for a DOS reserved name*/static BOOL is_reserved_name(const char *name){	if (FLAG_CHECK(name[0], FLAG_POSSIBLE1) &&	    FLAG_CHECK(name[1], FLAG_POSSIBLE2) &&	    FLAG_CHECK(name[2], FLAG_POSSIBLE3) &&	    FLAG_CHECK(name[3], FLAG_POSSIBLE4)) {		/* a likely match, scan the lot */		int i;		for (i=0; reserved_names[i]; i++) {			int len = strlen(reserved_names[i]);			/* note that we match on COM1 as well as COM1.foo */			if (strnequal(name, reserved_names[i], len) &&			    (name[len] == '.' || name[len] == 0)) {				return True;			}		}	}	return False;}/* See if a filename is a legal long filename. A filename ending in a '.' is not legal unless it's "." or "..". JRA. A filename ending in ' ' is not legal either. See bug id #2769.*/static BOOL is_legal_name(const char *name){	const char *dot_pos = NULL;	BOOL alldots = True;	size_t numdots = 0;	while (*name) {		if (((unsigned int)name[0]) > 128 && (name[1] != 0)) {			/* Possible start of mb character. */			char mbc[2];			/*			 * Note that if CH_UNIX is utf8 a string may be 3			 * bytes, but this is ok as mb utf8 characters don't			 * contain embedded ascii bytes. We are really checking			 * for mb UNIX asian characters like Japanese (SJIS) here.			 * JRA.			 */			if (convert_string(CH_UNIX, CH_UCS2, name, 2, mbc, 2, False) == 2) {				/* Was a good mb string. */				name += 2;				continue;			}		}		if (FLAG_CHECK(name[0], FLAG_ILLEGAL)) {			return False;		}		if (name[0] == '.') {			dot_pos = name;			numdots++;		} else {			alldots = False;		}		if ((name[0] == ' ') && (name[1] == '\0')) {			/* Can't end in ' ' */			return False;		}		name++;	}	if (dot_pos) {		if (alldots && (numdots == 1 || numdots == 2))			return True; /* . or .. is a valid name */		/* A valid long name cannot end in '.' */		if (dot_pos[1] == '\0')			return False;	}	return True;}/*  the main forward mapping function, which converts a long filename to   a 8.3 name  if need83 is not set then we only do the mangling if the name is illegal  as a long name  if cache83 is not set then we don't cache the result  the name parameter must be able to hold 13 bytes*/static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case, int snum){	char *dot_p;	char lead_chars[7];	char extension[4];	unsigned int extension_length, i;	unsigned int prefix_len;	u32 hash, v;	char new_name[13];	/* reserved names are handled specially */	if (!is_reserved_name(name)) {		/* if the name is already a valid 8.3 name then we don't need to 		   do anything */		if (is_8_3(name, False, False, snum)) {			return;		}		/* if the caller doesn't strictly need 8.3 then just check for illegal 		   filenames */		if (!need83 && is_legal_name(name)) {			return;		}	}	/* find the '.' if any */	dot_p = strrchr(name, '.');	if (dot_p) {		/* if the extension contains any illegal characters or		   is too long or zero length then we treat it as part		   of the prefix */		for (i=0; i<4 && dot_p[i+1]; i++) {			if (! FLAG_CHECK(dot_p[i+1], FLAG_ASCII)) {				dot_p = NULL;				break;			}		}		if (i == 0 || i == 4) dot_p = NULL;	}	/* the leading characters in the mangled name is taken from	   the first characters of the name, if they are ascii otherwise	   '_' is used	*/	for (i=0;i<mangle_prefix && name[i];i++) {		lead_chars[i] = name[i];		if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) {			lead_chars[i] = '_';		}		lead_chars[i] = toupper_ascii(lead_chars[i]);	}	for (;i<mangle_prefix;i++) {		lead_chars[i] = '_';	}	/* the prefix is anything up to the first dot */	if (dot_p) {		prefix_len = PTR_DIFF(dot_p, name);	} else {		prefix_len = strlen(name);	}	/* the extension of the mangled name is taken from the first 3	   ascii chars after the dot */	extension_length = 0;	if (dot_p) {		for (i=1; extension_length < 3 && dot_p[i]; i++) {			char c = dot_p[i];			if (FLAG_CHECK(c, FLAG_ASCII)) {				extension[extension_length++] = toupper_ascii(c);			}		}	}	   	/* find the hash for this prefix */	v = hash = mangle_hash(name, prefix_len);	/* now form the mangled name. */	for (i=0;i<mangle_prefix;i++) {		new_name[i] = lead_chars[i];	}	new_name[7] = base_forward(v % 36);	new_name[6] = '~';		for (i=5; i>=mangle_prefix; i--) {		v = v / 36;		new_name[i] = base_forward(v % 36);	}	/* add the extension */	if (extension_length) {		new_name[8] = '.';		memcpy(&new_name[9], extension, extension_length);		new_name[9+extension_length] = 0;	} else {		new_name[8] = 0;	}	if (cache83) {		/* put it in the cache */		cache_insert(name, prefix_len, hash);	}	M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n", 		   name, hash, new_name, cache83));	/* and overwrite the old name */	fstrcpy(name, new_name);	/* all done, we've managed to mangle it */}/* initialise the flags table   we allow only a very restricted set of characters as 'ascii' in this  mangling backend. This isn't a significant problem as modern clients  use the 'long' filenames anyway, and those don't have these  restrictions. */static void init_tables(void){	int i;	memset(char_flags, 0, sizeof(char_flags));	for (i=1;i<128;i++) {		if (i <= 0x1f) {			/* Control characters. */			char_flags[i] |= FLAG_ILLEGAL;		}		if ((i >= '0' && i <= '9') || 		    (i >= 'a' && i <= 'z') || 		    (i >= 'A' && i <= 'Z')) {			char_flags[i] |=  (FLAG_ASCII | FLAG_BASECHAR);		}		if (strchr("_-$~", i)) {			char_flags[i] |= FLAG_ASCII;		}		if (strchr("*\\/?<>|\":", i)) {			char_flags[i] |= FLAG_ILLEGAL;		}		if (strchr("*?\"<>", i)) {			char_flags[i] |= FLAG_WILDCARD;		}	}	memset(base_reverse, 0, sizeof(base_reverse));	for (i=0;i<36;i++) {		base_reverse[(unsigned char)base_forward(i)] = i;	}		/* fill in the reserved names flags. These are used as a very	   fast filter for finding possible DOS reserved filenames */	for (i=0; reserved_names[i]; i++) {		unsigned char c1, c2, c3, c4;		c1 = (unsigned char)reserved_names[i][0];		c2 = (unsigned char)reserved_names[i][1];		c3 = (unsigned char)reserved_names[i][2];		c4 = (unsigned char)reserved_names[i][3];		char_flags[c1] |= FLAG_POSSIBLE1;		char_flags[c2] |= FLAG_POSSIBLE2;		char_flags[c3] |= FLAG_POSSIBLE3;		char_flags[c4] |= FLAG_POSSIBLE4;		char_flags[tolower_ascii(c1)] |= FLAG_POSSIBLE1;		char_flags[tolower_ascii(c2)] |= FLAG_POSSIBLE2;		char_flags[tolower_ascii(c3)] |= FLAG_POSSIBLE3;		char_flags[tolower_ascii(c4)] |= FLAG_POSSIBLE4;		char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4;	}}/*  the following provides the abstraction layer to make it easier  to drop in an alternative mangling implementation */static struct mangle_fns mangle_fns = {	mangle_reset,	is_mangled,	is_8_3,	check_cache,	name_map};/* return the methods for this mangling implementation */struct mangle_fns *mangle_hash2_init(void){	/* the mangle prefix can only be in the mange 1 to 6 */	mangle_prefix = lp_mangle_prefix();	if (mangle_prefix > 6) {		mangle_prefix = 6;	}	if (mangle_prefix < 1) {		mangle_prefix = 1;	}	init_tables();	mangle_reset();	if (!cache_init()) {		return NULL;	}	return &mangle_fns;}static void posix_mangle_reset(void){;}static BOOL posix_is_mangled(const char *s, int snum){	return False;}static BOOL posix_is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, int snum){	return False;}static BOOL posix_check_cache( char *s, size_t maxlen, int snum ){	return False;}static void posix_name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, int snum){	if (need83) {		memset(OutName, '\0', 13);	}}/* POSIX paths backend - no mangle. */static struct mangle_fns posix_mangle_fns = {        posix_mangle_reset,        posix_is_mangled,        posix_is_8_3,        posix_check_cache,        posix_name_map};struct mangle_fns *posix_mangle_init(void){	return &posix_mangle_fns;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -