% $Id: DFN.TEX 1.1 2000/01/24 10:18:50 ska Exp ska $
\section{\label{ssDfn}\subsys{dfn}}

This subsystem is intended to provide an unique interface to all
filesystems known to DOS, especially portably among all C compilers
for DOS. Therefore the view point is not portabilty among various
platforms, but to overcome tweaks and hacks normally used to access
the DOS API.

\subsection{Design}

All function of \subsys{dfn} are prefixed by \fct{dfn} or \fct{DFN} in
order to use widely used names for these functions otherwise.

\paragraphe[UNC support]{Not natively supported by DOS, but widely known
nonetheless are UNC path names} (UNC = Unique Naming Convention)
introduced with the MS Network support. Although it seems that some
firms use a different view of how UNC is to be interpreted, \subsys{dfn}
does support UNC some sort of. UNC path names do look like this:\newline
\noindent\verb!\\server\share\path\name.ext!, where \verb!server!
encodes the fileserver the path points to, \verb!share! encodes the name
the share has been given on that server, and \verb!path\name.ext! is an
usual fully-qualified filename, thus, without drive letter.

This convention is already used by DOS internally, if particular drivers
has been loaded, e.g. the CDROM extension or several network layers, but
to the users all these implementations are usually hidden by to assign
a drive letter to the \verb!\\server\share! portion and so this UNC driven
files can be accessed like local files as well.

Unfortunately the UNC has some design flaw: How should a path with
two leading backslashes (\verb!\\!) be interpreted? A program not knowing
UNC at all could simply assume that this is a typo and ignores the superflous
backslash. Therefore \subsys{dfn} implements two variants for each function:
one definitely supporting UNC, and one propably supporting it. The difference
between both variants can be made clear with the following examples:
\begin{enumerate}
\item \fct{dfnwrdir()}: This function attempts to detect, if a directory is
	writeable or not. More or less the passed in name of the directory is
	directly passed to the underlaying OS, if that supports UNCs, the
	function succeeds correctly, otherwise the function might succeed, but
	the OS had interpreted the path name incorrectly and therefore the
	results are incorrect as well.
\item \fct{dfnsplit()}: This function splits a passed in pathname into
	its basic components: drive, directory, filename and extension.
	Because no system function will be used the function \fct{dfnusplit()}
	can surely support UNC paths, even if the underlaying OS does not.
\end{enumerate}

\subsys{dfn} usually identifies the UNC portion (\verb!\\server\share!) with
the drive letter of the standard naming convention, this also result into
to use larger arrays when to represent a {\em drive}, e.g. \dfn{dfnsplit()}
returns the drive letter as a C string, rather than a single character as
other implementations do, because the corresponding UNC-aware function
\fct{dfnusplit()} returns the server and share portion in this field.

If the macro \fct{SUPPORT\_UNC\_PATH} is defined prior \#include'ing the
header file, macros are automatically inserted that all functions
automatically invoke their UNC-aware counterpart, if available.

\paragraphe[Maximum path length]{To not stick to DOS conventions also
leads to the problem that there are no {\em real} limits, e.g. users
of \subsys{dfn} must forget about the 8.3 filenames. All function of
this subsystem natively support any-sized filenames, also these filenames
can be constructed out of the full rage of the \fct{(char)} data type,
with the exception that ASCII 0 (zero) is reserved to mark the end of
the filename --- as it is standard in C anyway --- and the usual characters
to delimit drive and path components (\verb!:! -- colon, \verb!/! -- forward
slash and \verb!\! backslash) and some characters used for some particular
functions, e.g. wildcards with the function \fct{dfnmatch()}.

Functions, that add some self-constructed filename themselves, e.g.
\fct{dfnbakname()} and \fct{dfnmktmp()}, always stick to the
8.3 convention to be portable among all DOS platforms.

Because there cannot be named some well-natured limits under these
conditions, filenames or components are returned as pointers to
dynamically allocated buffers, which must be deallocated by the user.

\subsection{Implementation}

\subsubsection{Macros}

\paragraphe{The general macro \fct{SUPPORT\_UNC\_PATH}} can be defined
prior \#include'ing the header to ensure that all functions do automatically
invoke their UNC-aware counterpart, if available. This is achieved by
adding macros to map the names of the functions, e.g.:
\begin{verbatim*}
#define dfnmerge dfnumerge
#define dfnsplit dfnusplit
\end{verbatim*}

\paragraphe{The attribute macros} are always used when to pass attributes
to the functions or when attributes are returned by them. These macros
are not associated with the standard file attributes known by DOS 1:1'ly.
The attributes of a directory entry describe that:
\begin{tableTwo}{name}{entry is}
\fct{DFN\_FILE}	& a native file. Under DOS this is limited to {\em Is neither a
	directory nor a label}.\\
\fct{DFN\_LFN}	& part of a LFN, which is not associated with a physical
	file \\
\fct{DFN\_DIRECTORY}	& a (sub-) directory \\
\fct{DFN\_LABEL}	& a volume label \\
\fct{DFN\_READ}	& readable. Under DOS this is always true. \\
\fct{DFN\_WRITE}	& writeable. May be invalid for directories. \\
\fct{DFN\_HIDDEN}	& hidden -- not to be presented by default. \\
\fct{DFN\_SYSTEM}	& especially valueable for the system. \\
\end{tableTwo}

\subsubsection{Functions}

\paragraphe{Functions dealing with filenames only} are never limited
to the restrictions of the underlaying OS, e.g. one can savely handle
UNC pathnames on DOS, even if one cannot pass an UNC path to the open
function natively. Also the length of the filenames have no limits,
whereas all filenames are internally handled within dynamically allocated
buffers if necessary, but never in statically allocated ones. Though
there are exceptions, which are documented at the particular functions.

Most of these functions do not actually access the file system, but
perform their actions themselves.

\begin{tabThree}{function}%
{UH\footnote{{\bf U} marks functions, that have a
	corresponding \fct{dfnu*()} function, that is surely UNC-aware.\\
	{\bf H} returns string(s) in a dynamically allocated
		buffer, that must be deallocated by the user.}}%
{purpose / warning}
\fct{dfnexpand} & UH & Expands a given filename to a fully-qualified
	pathname according to the current working path or an also given one. \\
\fct{dfnmerge} & UH & Merges path components (drive, path,
	filename, extension) into a single pathname. One or more components
	may be absent or already be part of another component. 
	Delimiters are inserted, if not present already. This function
	is usually invoked on return values of \fct{dfnsplit}. \\
\fct{dfnsplit} & UH & Splits a pathname into its components (drive,
	path, filename, extension). Each component is duplicated into its own
	dynamically allocated buffer. \\
\fct{dfnsqueeze} & UH & Squeezes and uniforms a pathname. If flips
	forward slashes into backslashes, removes superflous backslashes and
	path components (\verb!.! -- meaning the current directory) and uppercases
	all characters. --- {\bf Warning}: latter actions (upcasing) violates the
	portable issue of \subsys{dfn} and will be removed. Also, it will
	be implemented to remove other standard entries, e.g. \verb!..!, as well. \\
\fct{dfnpath} & UH & Returns the current working path of the given
	drive number or drive letter as ASCIZ string. \\
\fct{dfntruename} & UH & Returns the {\em true} name of a file. This is
	the physical access pathname of the file after all associates created by
	the utilities \doscmd{ASSIGN}, \doscmd{JOIN}, and \doscmd{SUBST}
	have been resolved. --- {\bf Warning}: The returned pathname {\em is
	NOT} accessable, because the true name of a CDROM-, a networked
	or a JOIN'ed drive does either follow the UNC, which is not
	natively supported by DOS, or point to an inaccessable drive letter. \\
\fct{dfnsearch} & UH & Searches a file within a given set of paths and
	extensions. By defaults, this function implements the search
	algorithm implemented by COMMAND.COM. If neither path nor extension
	is already present within the filename to search for, all extensions
	are tried within a path, before the next path is tried. This is the DOS
	usual DOS behaviour, rather than the Win32 behaviour, where one extension
	is tried within all paths, before to try the next extension. \\
\fct{dfnmatch} & U  & Matches a pathname against a pattern, that may
	contain DOS-style wildcards. \\
\fct{dfnmatch2} & U  & Matches a pathname against a pattern, that may
	contain Win32-style wildcards. \\
\fct{isUNCpath} &  & Tests if a pathname is in UNC. \\
\fct{UNCpath} & &  Returns the first character not part of the UNC path
	component. \\
\fct{dfn_tmpnam} & & Puts exactly eight characters at fnam forming a
	temporary filename.  No '\0' byte is appended, neither does the created
	name contain any NULs. \\
\fct{dfnfilename} & & Returns a pointer to the filename of the given
	path. \\
\fct{dfnbakname} & H & Constructs the backup filename (aka \fnam{.BAK}
	file) of the specified file. The backup file is located in the
	same directory as the original file. \\
\fct{dfndelim} &  & Tests if a given character delimits two path
	components, but does {\em not} match the colon (\verb!:!). \\
\fct{dfndelim2} & & Tests if a given character delimits two path
	components, but {\em does} match the colon (\verb!:!). \\
\end{tableThree}

\paragraphe{File information functions} return information about directory
entries.

\begin{tableThree}{function}{UH\samefootnote}{purpose / warning}
\fct{dfnwrdir} &  & Tests if a directory is writeable, meaning if one
	can create a file within this directory. \\
\fct{dfnstat} & & Returns the attributes of a pathname. \\
\end{tableThree}

\paragraphe{File functions} actually perform operations over the filesystem.

\begin{tableThree}{function}{UH\samefootnote}{purpose / warning}
\fct{dfnmkfile} & & Creates a given file, but fails, if the file already
	exists. This is an atomic (semaphore) operation. \\
\fct{dfnmktmp} & HX & Create a temporary file and its name. The filename
	is exactly eigth characters long and does contain no or the
	specified extension. No special attributes are set -- meaing,
	neither \fct{DFN\_SYSTEM} nor \fct{DFN\_HIDDEN}. \\
\fct{dfnfreplace} & & Replaces a file by another file and creates
	a backup of the replaced one. \\
\end{tableThree}
