示例#1
0
static void setup_frag_info(struct frag_info *fi, struct frag_type *frag_type, struct found_players *found_players, struct weapon_class *wc)
{
    if (fi == NULL)
        return;
    if (found_players == NULL)
        return;
    if (frag_type == NULL)
        return;
    if (wc == NULL)
        return;

    fi->wc = wc;
    fi->victim = fi->killer = NULL;

    if (FLAG_CHECK(frag_type->flags, FT_VICTIM_ONLY))
    {
        fi->victim = found_players[0].player;
    }
    else if (FLAG_CHECK(frag_type->flags, FT_KILLER_ONLY))
    {
        fi->killer = found_players[0].player;
    }
    else if (FLAG_CHECK(frag_type->flags, FT_VICTIM_KILLER))
    {
        fi->victim = found_players[0].player;
        fi->killer = found_players[1].player;
    }
    else if (FLAG_CHECK(frag_type->flags, FT_KILLER_VICTIM))
    {
        fi->victim = found_players[1].player;
        fi->killer = found_players[0].player;
    }
}
示例#2
0
void block_store_flush(block_store_t *const bs) {
    if (bs) {
        if (FLAG_CHECK(bs, FILE_LINKED)) {
            if (FLAG_CHECK(bs, DIRTY)) { // actual work to do
                // size_t blocks_to_write = bitmap_total_set(bs->dbm);
                /*
                    typedef struct {
                        int disaster_errno;
                        block_store_t *const bs;
                        size_t byte_counter;
                        bs_status status;
                    } bs_sync_obj;
                */
                bs_sync_obj sync_results = {0, bs, 0, BS_OK};

                bitmap_for_each(bs->dbm, &block_sync, &sync_results);
                if (sync_results.status == BS_OK) {
                    // Well it worked, hopefully
                    // Sipe the DBM and clear the dirty bit
                    bitmap_format(bs->dbm, 0x00);
                    FLAG_CLEAR(bs, DIRTY);
                }
                bs_errno = sync_results.status;
                return;
            }
            bs_errno = BS_OK;
            return;
        }
        bs_errno = BS_NO_LINK;
        return;
    }
    bs_errno = BS_PARAM;
    return;
}
示例#3
0
static int find_obituary(struct fragfile *ff, int player_count, int msg_count, char *msg1, char *msg2, struct frag_info *ft, struct found_players *found_players)
{
    struct obituary *o;
    int i;

    if (ff == NULL)
        return 1;

    if (player_count < 1)
        return 1;

    for (i=0; i<ff->obituary_count; i++)
    {
        o = ff->obituary[i];

        if (player_count == 1)
        {
            if (FLAG_CHECK(o->ft->flags, FT_VICTIM_KILLER) || FLAG_CHECK(o->ft->flags, FT_KILLER_VICTIM))
                continue;
        }

        if (player_count == 2)
        {
            if (FLAG_CHECK(o->ft->flags, FT_VICTIM_ONLY) || FLAG_CHECK(o->ft->flags, FT_KILLER_ONLY))
                continue;
        }

        if (msg_count == 1)
        {
            if (strcmp(o->msg1, msg1) == 0)
            {
                setup_frag_info(ft, o->ft, found_players, o->wc);
                return 0;
            }
        }
        else if (msg_count == 2)
        {
            if (o->msg2 == NULL)
                continue;

            if ((strcmp(o->msg1, msg1) == 0 ) && (strcmp(o->msg2, msg2) == 0))
            {
                setup_frag_info(ft, o->ft, found_players, o->wc);
                return 0;
            }
        }
    }
    return 1;
}
示例#4
0
void block_store_link(block_store_t *const bs, const char *const filename) {
    if (bs && filename) {
        if (! FLAG_CHECK(bs, FILE_LINKED)) {
            // Ok, I can make a giant complicated hunk of logic to:
            //   Create if it doesn't exist
            //   Increase size if smaller
            //   Decrease size if larger
            // and It'll be a giant headache for various reasons (error checking, portability)
            // OR, I can just do it in two commands and call it a day.
            bs->fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);
            if (bs->fd != -1) {
                if (utility_write_file(bs->fd, bs->data_blocks, BLOCK_COUNT * BLOCK_SIZE) == BLOCK_COUNT * BLOCK_SIZE) {
                    // Kill the DBM and dirty flag, set link state
                    bitmap_format(bs->dbm, 0x00);
                    FLAG_CLEAR(bs, DIRTY);
                    FLAG_SET(bs, FILE_LINKED);
                    bs_errno = BS_OK;
                    return;
                }
                bs_errno = BS_FILE_IO;
                return;
            }
            bs_errno = BS_FILE_ACCESS;
            return;
        }
        bs_errno = BS_LINK_EXISTS;
        return;
    }
    bs_errno = BS_PARAM;
}
示例#5
0
/* 
   see if a filename is an allowable 8.3 name.

   we are only going to allow ascii characters in 8.3 names, as this
   simplifies things greatly (it means that we know the string won't
   get larger when converted from UNIX to DOS formats)
*/
static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards)
{
	int len, i;
	char *dot_p;

	/* as a special case, the names '.' and '..' are allowable 8.3 names */
	if (name[0] == '.') {
		if (!name[1] || (name[1] == '.' && !name[2])) {
			return True;
		}
	}

	/* the simplest test is on the overall length of the
	 filename. Note that we deliberately use the ascii string
	 length (not the multi-byte one) as it is faster, and gives us
	 the result we need in this case. Using strlen_m would not
	 only be slower, it would be incorrect */
	len = strlen(name);
	if (len > 12)
		return False;

	/* find the '.'. Note that once again we use the non-multibyte
           function */
	dot_p = strchr(name, '.');

	if (!dot_p) {
		/* if the name doesn't contain a '.' then its length
                   must be less than 8 */
		if (len > 8) {
			return False;
		}
	} else {
		int prefix_len, suffix_len;

		/* if it does contain a dot then the prefix must be <=
		   8 and the suffix <= 3 in length */
		prefix_len = PTR_DIFF(dot_p, name);
		suffix_len = len - (prefix_len+1);

		if (prefix_len > 8 || suffix_len > 3 || suffix_len == 0) {
			return False;
		}

		/* a 8.3 name cannot contain more than 1 '.' */
		if (strchr(dot_p+1, '.')) {
			return False;
		}
	}

	/* the length are all OK. Now check to see if the characters themselves are OK */
	for (i=0; name[i]; i++) {
		/* note that we may allow wildcard petterns! */
		if (!FLAG_CHECK(name[i], FLAG_ASCII|(allow_wildcards ? FLAG_WILDCARD : 0)) && name[i] != '.') {
			return False;
		}
	}

	/* it is a good 8.3 name */
	return True;
}
示例#6
0
/* 
   determine if a string is possibly in a mangled format, ignoring
   case 

   In this algorithm, mangled names use only pure ascii characters (no
   multi-byte) so we can avoid doing a UCS2 conversion 
 */
static bool is_mangled_component(struct pvfs_mangle_context *ctx,
				 const char *name, size_t len)
{
	unsigned int i;

	M_DEBUG(10,("is_mangled_component %s (len %u) ?\n", name, (unsigned int)len));

	/* check the length */
	if (len > 12 || len < 8)
		return false;

	/* the best distinguishing characteristic is the ~ */
	if (name[6] != '~')
		return false;

	/* check extension */
	if (len > 8) {
		if (name[8] != '.')
			return false;
		for (i=9; name[i] && i < len; i++) {
			if (! FLAG_CHECK(name[i], FLAG_ASCII)) {
				return false;
			}
		}
	}
	
	/* check lead characters */
	for (i=0;i<ctx->mangle_prefix;i++) {
		if (! FLAG_CHECK(name[i], FLAG_ASCII)) {
			return false;
		}
	}
	
	/* check rest of hash */
	if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) {
		return false;
	}
	for (i=ctx->mangle_prefix;i<6;i++) {
		if (! FLAG_CHECK(name[i], FLAG_BASECHAR)) {
			return false;
		}
	}

	M_DEBUG(10,("is_mangled_component %s (len %u) -> yes\n", name, (unsigned int)len));

	return true;
}
示例#7
0
/*
  look for a DOS reserved name
*/
static bool is_reserved_name(struct pvfs_mangle_context *ctx, 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++) {
			if (strcasecmp(name, reserved_names[i]) == 0) {
				return true;
			}
		}
	}

	return false;
}
示例#8
0
/*
  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;
}
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];
			size_t size = 0;
			/*
			 * 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_UTF16LE, name, 2, mbc, 2, &size)) {
				if (size == 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;
}
示例#10
0
void block_store_unlink(block_store_t *const bs, const bs_flush_flag flush) {
    if (bs) {
        if (FLAG_CHECK(bs, FILE_LINKED)) {
            if (flush) {
                // WE TRIED
                block_store_flush(bs);
            }
            // Eh, if close breaks, we can't help it.
            close(bs->fd);
            FLAG_CLEAR(bs, FILE_LINKED);
            bs->fd = -1;
            if (!flush) {
                bs_errno = BS_OK;
            }
            return;
        }
        bs_errno = BS_NO_LINK;
        return;
    }
    bs_errno = BS_PARAM;
}
示例#11
0
/*
 See if a filename is a legal long filename.
 A filename ending in a '.' is not legal unless it's "." or "..". JRA.
*/
static bool is_legal_name(struct pvfs_mangle_context *ctx, const char *name)
{
	while (*name) {
		size_t c_size;
		codepoint_t c = next_codepoint(name, &c_size);
		if (c == INVALID_CODEPOINT) {
			return false;
		}
		/* all high chars are OK */
		if (c >= 128) {
			name += c_size;
			continue;
		}
		if (FLAG_CHECK(c, FLAG_ILLEGAL)) {
			return false;
		}
		name += c_size;
	}

	return true;
}
示例#12
0
// Block sync function to feed to bitmap_for_each
// Jumps the fd to the needed location and writes to it
// Admittedly, this function is not pretty.
void block_sync(size_t block_id, void *bs_sync_ptr) {
    bs_sync_obj *bs_sync = (bs_sync_obj *)bs_sync_ptr;
    /*
        typedef struct {
            int disaster_errno;
            block_store_t *const bs;
            size_t byte_counter;
            bs_status status;
        } bs_sync_obj;
    */
    if (bs_errno == BS_OK) {
        if (bs_sync && bs_sync->status == BS_OK) {
            if (bs_sync->bs) {
                if (FLAG_CHECK(bs_sync->bs, FILE_LINKED)) {
                    // Ducks = in a row
                    // jump to file position
                    if (lseek(bs_sync->bs->fd, BLOCK_POSITION(block_id), SEEK_SET) == BLOCK_POSITION(block_id)) {
                        // attempt to write
                        size_t written = utility_write_file(bs_sync->bs->fd, bs_sync->bs->data_blocks + BLOCK_POSITION(block_id), BLOCK_SIZE);
                        // Update written with WHATEVER happened
                        bs_sync->byte_counter += written;
                        if (written == BLOCK_SIZE) {
                            // all is ok, we wrote everything, or so we were told
                            return;
                        }
                    }
                    bs_sync->status = BS_FILE_IO;
                    // save whatever errno was generated by seek or write
                    bs_sync->disaster_errno = errno;
                    return;
                }
                bs_sync->status = BS_NO_LINK; // HOW DID THIS HAPPEN
                return;
            }
            bs_sync->status = BS_PARAM;
        }
        bs_errno = BS_PARAM;
    }
    return;
}
示例#13
0
/*
  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)
{
	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)) {
			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(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(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 */
}
示例#14
0
/*
  the main forward mapping function, which converts a long filename to 
  a 8.3 name

  if cache83 is not set then we don't cache the result

*/
static bool hash2_name_to_8_3(const char *name,
			char new_name[13],
			bool cache83,
			int default_case,
			const struct share_params *p)
{
	char *dot_p;
	char lead_chars[7];
	char extension[4];
	unsigned int extension_length, i;
	unsigned int prefix_len;
	unsigned int hash, v;

	/* 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
		 * change anything */
		if (is_legal_name(name) && is_8_3(name, False, False, p)) {
			safe_strcpy(new_name, name, 12);
			return True;
		}
	}

	/* 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_m(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_m(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,("hash2_name_to_8_3: %s -> %08X -> %s (cache=%d)\n",
		   name, hash, new_name, cache83));

	return True;
}
示例#15
0
 bool SqrlUser::isMemLocked() {
     if( FLAG_CHECK( this->flags, USER_FLAG_MEMLOCKED ) ) {
         return true;
     }
     return false;
 }
示例#16
0
int main(void) {
	FRESULT res;
	WORD br;

	sei(); // Globally enable interrupts

	hibernate_init();
	DAC_init();
	keys_init();

	if (pf_mount(&fs)) { sound_osch(); }
	else { sound_gut(); }

	while(1) {
		cli(); // disable interrupts to avoid race condition with sleep function
		if (FLAG_CHECK(NEW_SOUND)) {
			hibernate_timer_stop();
			FLAG_CLEAR(NEW_SOUND);
			sei();
			switch (special_mode) {
				case 1:
				if (new_sound_id == old_sound_id - 1) {
					special_mode = 2;
					goto sound_ende;
				} else if (new_sound_id == old_sound_id + 1) {
					special_mode = 4;
					goto sound_ende;
				} else if (new_sound_id == old_sound_id) {
					credits_counter = CREDITS_COUNTER_MAX - 5;
					special_mode = 0;
					goto sound_ende;
				} else special_mode = 0;
				break;
				case 2:
				special_mode = 3;
				break;
				case 4:
				special_mode = 5;
				break;
				default:
				special_mode = 0;
			}
			if (new_sound_id == 36) {
				special_mode = 1;
				goto sound_ende;
			}
			old_sound_id = new_sound_id;
			char* filename;
			if (++credits_counter > CREDITS_COUNTER_MAX) {
				credits_counter = 0;
				filename = "image.hex";
			} else {
				if (new_sound_id == 255) goto sound_ende;
				filename = filenames(bank, new_sound_id);
			}
			uint8_t tries = 3;
			while (pf_open(filename) && pf_open("error1.wav")) {
				if ((tries--) == 0) goto sound_ende;
				_delay_ms(10);
				pf_mount(&fs);
			}
			if (parse_wav_header()) {
				if (pf_open("error2.wav") || parse_wav_header()) goto sound_ende;
			}
			do {
				#define read_length 16384
				if (wavinfo.data_length > read_length) {
					res = pf_read(0, read_length, &br);
					wavinfo.data_length -= read_length;
				} else {
					res = pf_read(0, wavinfo.data_length, &br);
					break;
				}
			} while (res==0 && br==read_length && wavinfo.data_length>0 && !FLAG_CHECK(NEW_SOUND));
			stop_audio();
			sound_ende:
			hibernate_timer_init();
		} else {
			sleep_enable();
			sei();
			sleep_cpu();
			sleep_disable();
		}
		hibernate_check();
	}
}
示例#17
0
/*
  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

  return NULL if we don't need to do any conversion
*/
static char *name_map(struct pvfs_mangle_context *ctx,
		      const char *name, bool need83, bool cache83)
{
	char *dot_p;
	char lead_chars[7];
	char extension[4];
	unsigned int extension_length, i;
	unsigned int prefix_len;
	uint32_t hash, v;
	char *new_name;
	const char *basechars = MANGLE_BASECHARS;

	/* reserved names are handled specially */
	if (!is_reserved_name(ctx, name)) {
		/* if the name is already a valid 8.3 name then we don't need to 
		   do anything */
		if (is_8_3(ctx, name, false, false)) {
			return NULL;
		}

		/* if the caller doesn't strictly need 8.3 then just check for illegal 
		   filenames */
		if (!need83 && is_legal_name(ctx, name)) {
			return NULL;
		}
	}

	/* 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<ctx->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((unsigned char)lead_chars[i]);
	}
	for (;i<ctx->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++) {
			unsigned char c = dot_p[i];
			if (FLAG_CHECK(c, FLAG_ASCII)) {
				extension[extension_length++] = toupper(c);
			}
		}
	}
	   
	/* find the hash for this prefix */
	v = hash = mangle_hash(ctx, name, prefix_len);

	new_name = talloc_array(ctx, char, 13);
	if (new_name == NULL) {
		return NULL;
	}

	/* now form the mangled name. */
	for (i=0;i<ctx->mangle_prefix;i++) {
		new_name[i] = lead_chars[i];
	}
	new_name[7] = basechars[v % 36];
	new_name[6] = '~';	
	for (i=5; i>=ctx->mangle_prefix; i--) {
		v = v / 36;
		new_name[i] = basechars[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(ctx, name, prefix_len, hash);
	}

	M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n", 
		   name, hash, new_name, cache83));

	return new_name;
}