Commit f7bb3d25 authored by Robert Sprowson's avatar Robert Sprowson
Browse files

Added some doxygen comments

Also corrected various confusions about NULL (a pointer) and the ASCII character 0.
Reindented consistently.

Version 1.05. Tagged as 'DOSFS-1_05'
parent 4549de0c
/* (1.04)
/* (1.05)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 1.04
#define Module_MajorVersion_CMHG 1.05
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 31 May 2014
#define Module_Date_CMHG 24 Jun 2014
#define Module_MajorVersion "1.04"
#define Module_Version 104
#define Module_MajorVersion "1.05"
#define Module_Version 105
#define Module_MinorVersion ""
#define Module_Date "31 May 2014"
#define Module_Date "24 Jun 2014"
#define Module_ApplicationDate "31-May-14"
#define Module_ApplicationDate "24-Jun-14"
#define Module_ComponentName "DOSFS"
#define Module_ComponentPath "castle/RiscOS/Sources/FileSys/ImageFS/DOSFS"
#define Module_FullVersion "1.04"
#define Module_HelpVersion "1.04 (31 May 2014)"
#define Module_LibraryVersionInfo "1:4"
#define Module_FullVersion "1.05"
#define Module_HelpVersion "1.05 (24 Jun 2014)"
#define Module_LibraryVersionInfo "1:5"
......@@ -33,14 +33,15 @@
#include "DOSdirs.h"
#include "debug.h"
/*---------------------------------------------------------------------------*/
/* validate that the given character appears in the string */
int validchar(char *string,char init)
/*!
* \brief Validate that the given character appears in the string
* \param string Table to use
* \param init Character to check if it is in it
* \return -1 if the character is in the table
*/
int validchar(char *string, char init)
{
// if (init >= 128) return -1; /* Allow top bit set characters */
while (*string != NULL)
while (*string != '\0')
{
if (*string == init)
return -1;
......@@ -50,12 +51,16 @@ int validchar(char *string,char init)
return 0;
}
/*---------------------------------------------------------------------------*/
/* Map certain characters between filing systems */
char mapchar(char cchr,char *fromlist,char *tolist)
/*!
* \brief Map certain characters between filing systems
* \param char Character to map
* \param fromlist Input table
* \param tolist Output table
* \return Remapped character
*/
char mapchar(char cchr, char *fromlist, char *tolist)
{
while (*fromlist != NULL)
while (*fromlist != '\0')
{
if (cchr == *fromlist)
return *tolist;
......@@ -65,59 +70,71 @@ char mapchar(char cchr,char *fromlist,char *tolist)
return cchr;
}
/*-------------------------------------------------------------------------*/
static int chr_pos(char *text,char marker)
/*!
* \brief Return the character position of the passed character (or 0 if none)
* \param text String to search
* \param marker fromlist Input table
* \param tolist Output table
* \return Remapped character
*/
static int chr_pos(char *text, char marker)
{
// int index ;
// int index;
//
// /* return the character position of the passed character (or 0 if none) */
// for (index = 0; (text[index] != NULL); index++)
// for (index = 0; (text[index] != '\0'); index++)
// if (text[index] == marker)
// return(index) ;
char * index =strrchr(text,marker);
return(index?(int)(index-text):NULL) ;
char *index = strrchr(text, marker);
return (index ? (int)(index - text) : 0);
}
/*-------------------------------------------------------------------------*/
/* return a string containing the text before the given character */
char *before(char *newptr,char *text,char marker,int npad)
/*!
* \brief Return a string containing the text before the given character
* \param newptr Pointer to storage for the substring
* \param text String to use
* \param marker Character to split at
* \param npad Terminate with 0 if zero
* \return The new string
*/
char *before(char *newptr, char *text, char marker, int npad)
{
int cpos = chr_pos(text,marker) ;
if (cpos == 0)
cpos = strlen(text) ;
int cpos = chr_pos(text, marker);
if (cpos == 0)
cpos = strlen(text);
strncpy(newptr,text,cpos) ;
if (npad == 0)
newptr[cpos] = NULL ;
strncpy(newptr, text, cpos);
if (npad == 0)
newptr[cpos] = '\0';
return(newptr) ;
return newptr;
}
/*-------------------------------------------------------------------------*/
/* return a string containing the text after the last occurrence of */
/* the given character */
/* used to extract the DOS file extent info */
char *after(char *newptr,char *text,char marker,int npad)
/*!
* \brief Return a string containing the text after the given character
* \param newptr Pointer to storage for the substring
* \param text String to use
* \param marker Character to split at
* \param npad Terminate with 0 if zero
* \return The new string
*/
char *after(char *newptr, char *text, char marker, int npad)
{
int cpos = chr_pos(text,marker) ;
int cpos = chr_pos(text, marker);
if (cpos != 0)
if (cpos != 0)
{
// int len = strlen(text) ;
if (npad == 0)
strcpy(newptr,&text[cpos + 1]) ;
else
strncpy(newptr,&(text[cpos + 1]),4) ;
if (npad == 0)
strcpy(newptr, &text[cpos + 1]);
else
strncpy(newptr, &(text[cpos + 1]), 4);
}
else
{
if (npad == 0)
strcpy(newptr, "");
}
else
if (npad == 0)
strcpy(newptr,"") ;
return(newptr) ;
return (newptr);
}
/* RISC OS name:
......@@ -130,584 +147,627 @@ char *after(char *newptr,char *text,char marker,int npad)
* DOS path:
* <filename (max. 8 chars)>[.<extension (max. 3 chars)>[\<path element>]
*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Check that the given DOS names are identical */
/*!
* \brief Check that the given DOS names are identical
* \param wcname Compare name, possibly including wild cards
* \param fname File name
* \return TRUE when there is a match
*/
int namematch(char *wcname,char *fname)
{
char string1[257];
char string2[257] ;
/* Code assumes characters upto (and including) "file_sep" will always fit
* in RISC OS names.
*/
before(string1,fname,file_sep,0) ;
before(string2,wcname,file_sep,0) ;
if (wild_card_compare(string1,string2,DOSwcmult,DOSwcsing) == TRUE)
char string1[257];
char string2[257];
/* Code assumes characters upto (and including) "file_sep" will always fit
* in RISC OS names.
*/
before(string1, fname, file_sep, 0);
before(string2, wcname, file_sep, 0);
if (wild_card_compare(string1, string2, DOSwcmult, DOSwcsing) == TRUE)
{
/* "string1" is the full (non-wildcarded) filename we have matched with */
/* "string2" is the original (wildcarded) filename we were given on entry */
after(string1,fname,file_sep,0) ;
after(string2,wcname,file_sep,0) ;
/* "string1" is the full (non-wildcarded) filename we have matched with */
/* "string2" is the original (wildcarded) filename we were given on entry */
after(string1, fname, file_sep, 0);
after(string2, wcname, file_sep, 0);
if (wild_card_compare(string1,string2,DOSwcmult,DOSwcsing) == TRUE)
return(TRUE) ;
if (wild_card_compare(string1, string2, DOSwcmult, DOSwcsing) == TRUE)
return TRUE;
}
return(FALSE) ;
return FALSE;
}
/*---------------------------------------------------------------------------*/
/* convertRISCOStoDOS:
* translate a standard RISC OS name into a MS-DOS one.
* **** we should really include code to check the "dest" buffer limits ****
/*!
* \brief Translate a standard RISC OS name into a MS-DOS one
* \param source The RISC OS name
* \param dest Buffer to receive the DOS one
* \return Destination buffer pointer
*/
char *convertRISCOStoDOS(char *source,char *dest)
char *convertRISCOStoDOS(char *source, char *dest)
{
char *csptr = source ;
char *cdptr = dest ;
int loop ;
int filesepseen = FALSE ; /* if we have seen the file seperator */
char *cptr ; /* string pointer */
char lchr ; /* last character seen */
int point = 0 ; /* position where file extension started */
if ((source == NULL) || (*source == NULL))
char *csptr = source;
char *cdptr = dest;
int loop;
int filesepseen = FALSE; /* if we have seen the file seperator */
char *cptr; /* string pointer */
char lchr; /* last character seen */
int point = 0; /* position where file extension started */
if ((source == NULL) || (*source == '\0'))
{
dprintf(("","DOSFS: convertRISCOStoDOS: NULL name\n")) ;
*dest = NULL ;
return(dest) ;
dprintf(("", "DOSFS: convertRISCOStoDOS: NULL name\n"));
*dest = '\0';
return dest;
}
dprintf(("","DOSFS: convertRISCOStoDOS: \"%s\"",source)) ;
dprintf(("","DOSFS: convertRISCOStoDOS: \"%s\"", source));
lchr = '\0' ; /* no last character */
cptr = csptr;
do {
/* Ensure that "/" characters do not appear at the start or end of the name
* and that "//" sequences are trapped.
*/
if ((*cptr == '/' && (lchr == '\0' || lchr == *cptr || lchr == '.')) || ((lchr == '/') && ((*cptr == '\0') || (*cptr == '.'))))
return_error1(char *,err_invalidname,source) ;
lchr = *cptr++ ; /* remember this character */
} while (lchr);
if (*csptr == '$') /* ROOT directory specifier */
lchr = '\0'; /* no last character */
cptr = csptr;
do
{
csptr++ ;
if (*csptr == '.') /* RISC OS directory seperator */
/* Ensure that "/" characters do not appear at the start or end of the name
* and that "//" sequences are trapped.
*/
if ((*cptr == '/' && (lchr == '\0' || lchr == *cptr || lchr == '.')) ||
((lchr == '/') && ((*cptr == '\0') || (*cptr == '.')))
)
return_error1(char *, err_invalidname, source);
lchr = *cptr++; /* remember this character */
} while (lchr);
if (*csptr == '$') /* ROOT directory specifier */
{
csptr++;
if (*csptr == '.') /* RISC OS directory seperator */
{
*cdptr++ = dir_sep ; /* MSDOS directory seperator */
csptr++ ;
*cdptr++ = dir_sep; /* MSDOS directory seperator */
csptr++;
}
else
if (*csptr == NULL)
*cdptr++ = dir_sep ;
else
*cdptr++ = '$' ;
if (*csptr == '\0')
*cdptr++ = dir_sep;
else
*cdptr++ = '$';
}
for (loop = 0;;) /* convert the remainder of the pathname */
for (loop = 0;;) /* convert the remainder of the pathname */
{
if (*csptr == NULL) /* end of the source pathname */
if (*csptr == '\0') /* end of the source pathname */
{
*cdptr = NULL ; /* terminate the destination pathname */
break ;
*cdptr = '\0'; /* terminate the destination pathname */
break;
}
switch (*csptr)
switch (*csptr)
{
case '.' : /* RISC OS to directory seperator */
*cdptr++ = dir_sep ;
csptr++ ;
loop = 0 ;
filesepseen = FALSE ; /* for this leafname */
break ;
case '/' : /* convert to file seperator */
if (filesepseen)
return_error1(char *,err_invalidname,source);
*cdptr++ = file_sep ;
csptr++ ;
loop++ ;
point = loop ;
filesepseen = TRUE ;
break ;
default : /* perform standard name mapping */
if (filesepseen)
{
char c = *csptr++;
/* should never need to truncate the extension */
// if ((loop - point) >= extsize)
// return_error1(char *,err_invalidname,source) ;
// if (islower(c))
// c = toupper(c);
*cdptr++ = mapchar(c,ROmapping,DOSmapping) ;
}
else
{
char c = *csptr;
// if (islower(c))
// c = toupper(c) ;
*cdptr++ = mapchar(c,ROmapping,DOSmapping) ;
csptr++ ; /* step over this DOS character */
}
loop++ ;
break ;
case '.':
/* RISC OS to directory seperator */
*cdptr++ = dir_sep;
csptr++;
loop = 0;
filesepseen = FALSE; /* for this leafname */
break;
case '/':
/* convert to file seperator */
if (filesepseen)
return_error1(char *, err_invalidname, source);
*cdptr++ = file_sep;
csptr++;
loop++;
point = loop;
filesepseen = TRUE;
break;
default:
/* perform standard name mapping */
if (filesepseen)
{
char c = *csptr++;
/* should never need to truncate the extension */
// if ((loop - point) >= extsize)
// return_error1(char *, err_invalidname, source);
// if (islower(c))
// c = toupper(c);
*cdptr++ = mapchar(c, ROmapping, DOSmapping);
}
else
{
char c = *csptr;
// if (islower(c))
// c = toupper(c);
*cdptr++ = mapchar(c, ROmapping, DOSmapping);
csptr++; /* step over this DOS character */
}
loop++;
break;
}
}
dprintf((""," converted to \"%s\"\n",dest)) ;
dprintf(("", " converted to \"%s\"\n", dest));
for (cptr = dest; *cptr; cptr++)
if (!validchar(valchars,*cptr))
return_error1(char *,err_invalidname,source);
for (cptr = dest; *cptr; cptr++)
if (!validchar(valchars, *cptr))
return_error1(char *, err_invalidname, source);
return(dest) ;
return dest;
}
/*---------------------------------------------------------------------------*/
/*!
* \brief Convert a dir entry into a DOS short filename
* \param dentry The dir entry to consider
* \param name Buffer to receive the name, at least 8+1+3+1 long
* \return Name buffer pointer
*/
char *buildFILEname(DOS_direntry * dentry,char *name)
{
char *cptr = (char *)&(dentry->FILE_status);
int index ;
int loop ;
dprintf(("","buildFILEname: dentry:%p\n",dentry));
/* "dentry" should contain a valid filename */
/* copy prefix characters (or upto a space) into the filename buffer */
for (index=0; ((cptr[index] > ' ') && (index < namsize)); index++)
name[index] = cptr[index] ;
/* copy suffix characters (or upto a space) into the filename buffer */
for (loop=0; ((dentry->FILE_extension[loop] > ' ') && (loop < extsize)); loop++)
char *cptr = (char *)&(dentry->FILE_status);
int index;
int loop;
dprintf(("", "buildFILEname: dentry:%p\n", dentry));
/* "dentry" should contain a valid filename */
/* copy prefix characters (or upto a space) into the filename buffer */
for (index=0; ((cptr[index] > ' ') && (index < namsize)); index++)
name[index] = cptr[index];
/* copy suffix characters (or upto a space) into the filename buffer */
for (loop=0; ((dentry->FILE_extension[loop] > ' ') && (loop < extsize)); loop++)
{
if (loop == 0) /* the first character of the extension */
name[index++] = file_sep ; /* then place in the file_seperator */
name[index++] = dentry->FILE_extension[loop] ;
if (loop == 0) /* the first character of the extension */
name[index++] = file_sep; /* then place in the file_seperator */
name[index++] = dentry->FILE_extension[loop];
}
/* terminate the name */
name[index] = NULL ;
dprintf(("","buildFILEname: got:%s\n",name));
/* terminate the name */
name[index] = '\0';
dprintf(("", "buildFILEname: got:%s\n", name));
return(name) ;
return name;
}
//Calculates the LFN checksum of an 11 bytes dos filename
byte lfnchecksum(char * filename)
/*!
* \brief Calculates the LFN checksum of an 11 bytes DOS filename
* \param filename The filename to use
* \return The checksum
*/
byte lfnchecksum(char *filename)
{
byte checksum=0;
byte lsb;
int i;
for(i=0;i<11;i++)
{
lsb = (checksum&0x1); //Save the lsb
checksum = checksum >> 1; // Shift the byte
lsb = lsb << 7; // Turn saved lsb into msb
checksum |= lsb;
checksum += filename[i];
}
return checksum;
byte checksum = 0;
byte lsb;
int i;
for (i = 0; i < 11; i++)
{
lsb = (checksum & 0x1); /* Save the lsb */
checksum = checksum >> 1; /* Shift the byte */
lsb = lsb << 7; /* Turn saved lsb into msb */
checksum |= lsb;
checksum += filename[i];
}
return checksum;
}
/* returns NULL if short and long names are identical, else NZ */
int shorten_lfn(char * longfname, char * shortname, char * shortnamebuff, DIR_info * cdir)
/*!
* \brief Formulate a DOS short filename from a long one
* \param longfname The filename to start with
* \param shortname Pointer to a buffer for the short result
* \param shortnamebuff A temporary buffer
* \param cdir The current working directory, used to check for duplicates of the shortened name
* \return Zero if the short name ends up being the same as the long one
*/
int shorten_lfn(char * longfname, char * shortname, char * shortnamebuff, DIR_info * cdir)
{
// char * longfname : pointer to a null terminated file name
// char * shortnamebuff : pointer to a 13 byte buffer to store newly created short file name
// DIR_info * cdir : pointer the dir info structure for the target directory
int i, j, o, retval, dotseen=0;
char * extension,c;
/* check if already a valid short file name */
memset(shortnamebuff,' ',12);shortnamebuff[12]=0;
dprintf(("","shorten_lfn: start with -%s-\n",longfname));
for(i=0,j=0;(i<=12)&&(j<=12);i++,j++)
{
c=longfname[i];
if(c=='.')
{
if(!dotseen)
{
dotseen=i+1;
while(j<8)
{
shortnamebuff[j++]=' '; // spacefill to 8
}
}
if(i>8) break ; // too many chars
}
dprintf(("","shorten_lfn: check -%x-%c- toupper(c) -%c-\n",c,c,toupper(c)));
if(c && ((c=='.')||((c==toupper(c)) && (c!=' '))))
{ /* copy over */
shortnamebuff[j]=c;
dprintf(("","shorten_lfn: copied -%c-\n",c));
}
else
{
dprintf(("","shorten_lfn: %d %d %d\n",c,strlen(shortnamebuff),strlen(longfname)));
if(!c && /*strlen(shortnamebuff)==strlen(longfname) && */((!dotseen && (i<9)) || dotseen))
{ /* end of string .. and identical */
dprintf(("","shorten_lfn: its a valid DOS SFN\n"));
retval= 0;
goto slnfn1;
}
break;
}
}
// char * longfname : pointer to a null terminated file name
// char * shortnamebuff : pointer to a 13 byte buffer to store newly created short file name
// DIR_info * cdir : pointer the dir info structure for the target directory
int i, j, o, retval, dotseen=0;
char * extension,c;
/* check if already a valid short file name */
memset(shortnamebuff,' ',12);shortnamebuff[12]=0;
dprintf(("","shorten_lfn: start with -%s-\n",longfname));
for(i=0,j=0;(i<=12)&&(j<=12);i++,j++)
{
c=longfname[i];
if(c=='.')
{
if(!dotseen)
{
dotseen=i+1;
while(j<8)
{
shortnamebuff[j++]=' '; // spacefill to 8
}
}
if(i>8) break; // too many chars
}
dprintf(("","shorten_lfn: check -%x-%c- toupper(c) -%c-\n",c,c,toupper(c)));
if(c && ((c=='.')||((c==toupper(c)) && (c!=' '))))
{ /* copy over */
shortnamebuff[j]=c;
dprintf(("","shorten_lfn: copied -%c-\n",c));
}
else