

/* ---- real path ----------------------------------
		resolve partial paths
		resolve stuff like "//" and "./" and "../"
		resolve home directory
		resolve symbolic links
		resolve broken utf-8 filenames
		no error for not present path components
		=> assume directory/file will be created
*/
cstr realpath ( cstr path, bool follow_symlink )
{	cstr fullpath;

	"" => "."
	"~/.." => "$HOME/.."
	"/" => return

// try to solve it quick:
	if (follow_symlink)		// this is what the system call does
	{
		fullpath = realpath(path);
	}
	else
	{
		basepath = basepath(path)
		filename = lastcomponent(path)
		fullpath = realpath(basepath)
		if (NoError())
		{
			fullpath += filename
			lstat(fullpath)
		}
	}
	if (Error()!=ENOENT) return fullpath;

/*	ENOENT happened:
	path component n.ex.  or  broken utf-8 name
	last component n.ex.  or  broken utf-8 name
	path component no directory|link
*/

	if (*path!='/') rpath = pwd() + path
	else            rpath = DupStr(path)

	lpath = "/"				// left portion of path: exists
	rpath = rpath+1			// right portion of path: broken
	k1    = ""				// current path component
	linkcount=99			// -> detect recursion

	for(;;)
		ClearError();

	// split k1 from rpath
		if rpath=="" break
		k1 = rpath
		rpath=strchr(rpath,"/")
		if (rpath) *rpath++ = 0 		// delimit k1; rpath = new rpath
		else rpath=""

	// handle k1
	// simple cases:
		if (k1 == "/" || k1=="./") continue;		// discard "//" and "./"
		if (k1 == "../"){ if(lpath!="/") lpath = basepath(lpath); continue; }	// "../" -> backup one directory

	// does it exist?
		stat = lstat(lpath+k1)
#ifdef MATCH_INVALID_UTF8_PATHS
		if (Error()==ENOENT) { ClearError(); k1=ReplaceBogusUtf8(lpath,k1); stat=lstat(lpath+k1) }
#endif
		if (Error()==ENOENT) { ClearError(); lpath+=k1+rpath; rpath=""; break; }	// path component not found
		if (Error()) { lpath+=k1; break; }			// other error

	// handle directory:
		if (isdir(stat)) { lpath += k1; continue; }

	// handle link:
		if (isLink(stat) && (rpath!="" || follow_symlink))
		{
			if (--linkcount==0) { SetError(ELOOP); break; }
			rpath = link(lpath+k1) + rpath
			if (*rpath=='/') { lpath="/"; rpath+=1 }
			continue;
		}

	// handle regular file ((or pipe et.al.))
		lpath += k1;
		if (rpath!="") SetError(ENODIR);
		break;
	loop

	return lpath;
}











