204 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| #include "sysincludes.h"
 | |
| #include "msdos.h"
 | |
| #include "mtools.h"
 | |
| #include "vfat.h"
 | |
| #include "codepage.h"
 | |
| 
 | |
| /* Write a DOS name + extension into a legal unix-style name.  */
 | |
| char *unix_normalize (char *ans, char *name, char *ext)
 | |
| {
 | |
| 	char *a;
 | |
| 	int j;
 | |
| 	
 | |
| 	for (a=ans,j=0; (j<8) && (name[j] > ' '); ++j,++a)
 | |
| 		*a = name[j];
 | |
| 	if(*ext > ' ') {
 | |
| 		*a++ = '.';
 | |
| 		for (j=0; j<3 && ext[j] > ' '; ++j,++a)
 | |
| 			*a = ext[j];
 | |
| 	}
 | |
| 	*a++ = '\0';
 | |
| 	return ans;
 | |
| }
 | |
| 
 | |
| typedef enum Case_l {
 | |
| 	NONE,
 | |
| 	UPPER,
 | |
| 	LOWER 
 | |
| } Case_t;
 | |
| 
 | |
| static void TranslateToDos(const char *s, char *t, int count,
 | |
| 			   char *end, Case_t *Case, int *mangled)
 | |
| {
 | |
| 	*Case = NONE;
 | |
| 	for( ;  *s && (s < end || !end); s++) {
 | |
| 		if(!count) {
 | |
| 			*mangled |= 3;
 | |
| 			break;
 | |
| 		}
 | |
| 		/* skip spaces & dots */
 | |
| 		if(*s == ' ' || *s == '.') {
 | |
| 			*mangled |= 3;
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		/* convert to dos */
 | |
| 		if((*s) & 0x80) {
 | |
| 			*mangled |= 1;
 | |
| 			*t = to_dos(*s);
 | |
| 		}
 | |
| 
 | |
| 		if ((*s & 0x7f) < ' ' ) {
 | |
| 			*mangled |= 3;
 | |
| 			*t = '_';
 | |
| 		} else if (islower((unsigned char)*s)) {
 | |
| 			*t = toupper(*s);
 | |
| 			if(*Case == UPPER && !mtools_no_vfat)
 | |
| 				*mangled |= 1;
 | |
| 			else
 | |
| 				*Case = LOWER;
 | |
| 		} else if (isupper((unsigned char)*s)) {
 | |
| 			*t = *s;
 | |
| 			if(*Case == LOWER && !mtools_no_vfat)
 | |
| 				*mangled |= 1;
 | |
| 			else
 | |
| 				*Case = UPPER;
 | |
| 		} else if((*s) & 0x80)
 | |
| 			*t = mstoupper(*t);	/* upper case */
 | |
| 		else
 | |
| 			*t = *s;
 | |
| 		count--;
 | |
| 		t++;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /* dos_name
 | |
|  *
 | |
|  * Convert a Unix-style filename to a legal MSDOS name and extension.
 | |
|  * Will truncate file and extension names, will substitute
 | |
|  * the character '~' for any illegal character(s) in the name.
 | |
|  */
 | |
| char *dos_name(char *name, int verbose, int *mangled, char *ans)
 | |
| {
 | |
| 	char *s, *ext;
 | |
| 	register int i;
 | |
| 	Case_t BaseCase, ExtCase;
 | |
| 
 | |
| 	*mangled = 0;
 | |
| 
 | |
| 	/* skip drive letter */
 | |
| 	name = skip_drive(name);
 | |
| 
 | |
| 	/* zap the leading path */
 | |
| 	name = (char *) _basename(name);
 | |
| 	if ((s = strrchr(name, '\\')))
 | |
| 		name = s + 1;
 | |
| 	
 | |
| 	memset(ans, ' ', 11);
 | |
| 	ans[11]='\0';
 | |
| 
 | |
| 	/* skip leading dots and spaces */
 | |
| 	i = strspn(name, ". ");
 | |
| 	if(i) {
 | |
| 		name += i;
 | |
| 		*mangled = 3;
 | |
| 	}
 | |
| 		
 | |
| 	ext = strrchr(name, '.');
 | |
| 
 | |
| 	/* main name */
 | |
| 	TranslateToDos(name, ans, 8, ext, &BaseCase, mangled);
 | |
| 	if(ext)
 | |
| 		TranslateToDos(ext+1, ans+8, 3, 0, &ExtCase,  mangled);
 | |
| 
 | |
| 	if(*mangled & 2)
 | |
| 		autorename_short(ans, 0);
 | |
| 
 | |
| 	if(!*mangled) {
 | |
| 		if(BaseCase == LOWER)
 | |
| 			*mangled |= BASECASE;
 | |
| 		if(ExtCase == LOWER)
 | |
| 			*mangled |= EXTCASE;
 | |
| 		if((BaseCase == LOWER || ExtCase == LOWER) &&
 | |
| 		   !mtools_no_vfat) {
 | |
| 		  *mangled |= 1;
 | |
| 		}
 | |
| 	}
 | |
| 	return ans;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Get rid of spaces in an MSDOS 'raw' name (one that has come from the
 | |
|  * directory structure) so that it can be used for regular expression
 | |
|  * matching with a Unix filename.  Also used to 'unfix' a name that has
 | |
|  * been altered by dos_name().
 | |
|  */
 | |
| 
 | |
| char *unix_name(char *name, char *ext, char Case, char *ans)
 | |
| {
 | |
| 	char *s, tname[9], text[4];
 | |
| 	int i;
 | |
| 
 | |
| 	strncpy(tname, (char *) name, 8);
 | |
| 	tname[8] = '\0';
 | |
| 	if ((s = strchr(tname, ' ')))
 | |
| 		*s = '\0';
 | |
| 
 | |
| 	if(!(Case & (BASECASE | EXTCASE)) && mtools_ignore_short_case)
 | |
| 		Case |= BASECASE | EXTCASE;
 | |
| 
 | |
| 	if(Case & BASECASE)
 | |
| 		for(i=0;i<8 && tname[i];i++)
 | |
| 			tname[i] = tolower(tname[i]);
 | |
| 
 | |
| 	strncpy(text, (char *) ext, 3);
 | |
| 	text[3] = '\0';
 | |
| 	if ((s = strchr(text, ' ')))
 | |
| 		*s = '\0';
 | |
| 
 | |
| 	if(Case & EXTCASE)
 | |
| 		for(i=0;i<3 && text[i];i++)
 | |
| 			text[i] = tolower(text[i]);
 | |
| 
 | |
| 	if (*text) {
 | |
| 		strcpy(ans, tname);
 | |
| 		strcat(ans, ".");
 | |
| 		strcat(ans, text);
 | |
| 	} else
 | |
| 		strcpy(ans, tname);
 | |
| 
 | |
| 	/* fix special characters (above 0x80) */
 | |
| 	to_unix(ans,11);
 | |
| 	return(ans);
 | |
| }
 | |
| 
 | |
| /* If null encountered, set *end to 0x40 and write nulls rest of way
 | |
|  * 950820: Win95 does not like this!  It complains about bad characters.
 | |
|  * So, instead: If null encountered, set *end to 0x40, write the null, and
 | |
|  * write 0xff the rest of the way (that is what Win95 seems to do; hopefully
 | |
|  * that will make it happy)
 | |
|  */
 | |
| /* Always return num */
 | |
| int unicode_write(char *in, struct unicode_char *out, int num, int *end_p)
 | |
| {
 | |
| 	int j;
 | |
| 
 | |
| 	for (j=0; j<num; ++j) {
 | |
| 		out->uchar = '\0';	/* Hard coded to ASCII */
 | |
| 		if (*end_p)
 | |
| 			/* Fill with 0xff */
 | |
| 			out->uchar = out->lchar = (char) 0xff;
 | |
| 		else {
 | |
| 			out->lchar = *in;
 | |
| 			if (! *in) {
 | |
| 				*end_p = VSE_LAST;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		++out;
 | |
| 		++in;
 | |
| 	}
 | |
| 	return num;
 | |
| }
 | 
