minix/commands/i386/mtools-3.9.7/file_name.c
2005-04-21 14:53:53 +00:00

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;
}