/*-
 * $Id: hanmain.c,v 1.4 90/01/27 20:13:00 Rhialto Exp $
 * $Log:	hanmain.c,v $
 * Revision 1.4  90/01/27  20:13:00  Rhialto
 * *** empty log message ***
 * 
 * Revision 1.3  89/12/17  21:29:51  Rhialto
 * *** empty log message ***
 *
 * Revision 1.1  89/12/17  20:02:31  Rhialto
 * Initial revision
 *
 *
 *  HANMAIN.C
 *
 *  The code for the messydos file system handler.
 *
 *  Some start/stop stuff that is not really part of the
 *  file system itself but that must be done anyway.
 *
 *  This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
 *  not be used or copied without a licence.
-*/

#include "han.h"
#include "dos.h"

#ifdef DEBUG
#   define	debug(x)  dbprintf x
#else
#   define	debug(x)
#endif

extern char	DotDot[1 + 8 + 3];
struct Library *IntuitionBase;
static char RCSId[] = "Messydos filing system $Revision: 1.4 $ $Date: 90/01/27 20:13:00 $, by Olaf Seibert";

byte
ToUpper(ch)
register byte	ch;
{
    if (ch >= 'a' && ch <= 'z')
	return ch + ('A' - 'a');
    if (ch == '.')
	return '!';
    return ch & ~DIR_DELETED_MASK;
}

long
lmin(a, b)
long		a,
		b;
{
    return (a < b) ? a : b;
}

byte	       *
ZapSpaces(begin, end)
register byte  *begin,
	       *end;
{
    while (end > begin && end[-1] == ' ')
	*--end = '\0';

    return end;
}

/*
 * Map an arbitrary file name to MS-DOS conventions. The output format is
 * 8+3 without dot, padded with spaces, suitable for direct comparison
 * with directory entries. Return a pointer to the delimiter found ('\0'
 * or '/'). [[Make sure that Examine/ExNext return a proper inverse of
 * this...]]
 */

byte	       *
ToMSName(dest, source)
byte	       *dest;
register byte  *source;
{
    byte	   *dotp;
    byte	   *slashp;
    register int    i,
		    len;

    if (*source == '/') {       /* parentdir */
	strncpy(dest, DotDot, 8 + 3);   /* ".." */
	return source;
    }
    /*
     * Remove any strictly leading dots. .info -> info, .indent.pro ->
     * indent.pro, .profile -> profile, etc.
     */
    while (*source == '.')
	source++;

    /*
     * Find dot and slash which are delimiters of name and extension.
     */
    {
	register byte  *cp;

	cp = source;
	while (*cp) {
	    if (*cp == '.' || *cp == '/')
		break;
	    cp++;
	}
	dotp = cp;
	while (*cp) {
	    if (*cp == '/')
		break;
	    cp++;
	}
	slashp = cp;
    }

    len = dotp - source;
    if (len > 8)
	len = 8;

    for (i = 0; i < len; i++) {
	*dest++ = ToUpper(*sourEHrxy;ǅIGFUl*uo,W]j6l?N<֗܏G:ۏB̵RAN	t`^k;A\mOYh!cU$*Ws)QU׮/-ީˏݩFD4b['5'k-X#|<P ļO>&v6RD)
jw6]	V_Ьp3GM=6`L}4r]R?s/ߨcK*WB^;r*gb*Qփk f3&l.q.9>^_W7ؗ$U3
8uxt}Owbwku[<dM9?9=y~%~5D*bp˓վuUųc`?}KAOFpv=A;Zu)S6vυ]/n4<C~@ΊXMib]"TByERo1>eܜةW0p}ip0H&<n|xU~g2E3Ì,]y!os|ph!$zyurTGveL+ij]NYn< ^}ޅrA	8X-+|#d۰`HtIW[ȑiLw~P7g!d@n]*F%y9l\sJ\vѽmw_Z3wRdՁbSpW4alRw քk*˿<sxWg繿bϑg\?.һl 2]n+e˙|F"O޴D{p+n/QQu-'*>P7X"b2K_8KSYR>ǡCҸǝ"~W؅譬&R+e3[ k{o}+S*9<}~/,W6 E1K
ͩh@BD;.%`IhzyO*)CoĘԁ/J+X>R'J#/X#nٺ
AYm_O@^+qF| #?63忾zK*/q	'm q0+[lor|{zK8G01tSD*CI韄gYK3Izߋ#^e<
נvB|Ϟ*/><Ϸgq< tϘ2 BE
Ðy05LT_h9٤W`uۍ-^EYGz:NmZU Q,<Q! D|t!}M!&홹f>7FxG$j? Q\VX9|NFeb>'&|#bZLy+6$UFd[mh]u.Aõ566}vE,z}&C%}(Up:(GAxTW	`RЉDjW k_6?1/ E`\ԨNQ/M$
,ei̔	{/,qQfu4I̥놩=yP%<
<oo+19l2Y( jXI	nCɢaaK>$0#uL}cҜ
'R;ϙ_żrLǦd>^?WB]1ey#1=\Dpz+eyOqwb.<&R{HNvUpҾ;Mw76H$a~gbȫO<ɯgs4;*Ű*z[9 UD`*V%]X[JnD25wmtsve4%I?2	lY[d:t>KC%b zdw6s0hz~^@=e,{u} *oˣ;t?;\s+Z'wd| tIed]߇ifFz?v+tuVO`CL{uZdB萋X.~!.'M;j)9YoL:]iWj}IU˱7R1'wlf"Ln1jYw~4D:Uɚͅj/FtR=) \E&:®RoAh@pz*nHZsMCPDToxmP%Kwa'2Wj\:geJ媐^9R-=Vt
#fū{_Ժ%2ܰ';pEn?S֑T3ě~..m|)*9xՃ9г4tO1Ew~Yetl$0-AwyӤ}U8ںd!$Fm+݁fDw#*w<^8x~zeC@]=~pq|eo<}tw2Ժ̈́l5Kϴ'<|,HjK.B?	:	97komO}">;:/0Wp_<Bǂ+T%8V>vN,{Gr/]|y}V=溃Ic6|ov~ƍ{a0V+k|:kLHē_r<T!}?ƵTy=f,_'Ud%ǘf&ra3ץj@lJC	(
-WA!_}Q97K^zjXPf[3\q)	$KYC\%57ύJFӮ'J:=V6eGYvDTLٚv#cP)~vK0;*iG@syS7YiJv(|q~gDٗT3B?&1WHwf^9*s[p{:M-墹,)bmOJcXF>'j<ލiÓEq_>7}cb8	[thJnO1"DBEJ^<>[sbvm͞S
L'y-gg$B,Fj[JHXI)FRin;kŹ,$
gz{!1+n\gP
Wv[e鱌]ҿJOkX
uQMkއMIQ(mC|Fl3^)lV#Č8{?('oڹe|T_1I'R:sx^OO*qlmMx(:&ۚ}͡/
-E3}6w&c {Bqw;yW3ER߹AΉLwr
fS|TrA^Ү׳uf(=5Q$.9滦{/nq]O朲z"	4T3С"30|՝Act@tCK݈f?̪kz~i1rBET@q޻<V.l/XHLXi?9v<fUB^}BEAG.\|8}^2Z}Zm¤U벬5:DXx<Dyoe[6VF_vBZIߊ(S)!O&%M&9yeDO|K/Kg$hlr+X{ĔCB}R(RxHӇLR{B*h{i.M1MkD6<qgF<Cۃru$|f 6!L&tJu 8.8?]SNy!lE?R퐴9цQ7AP<}/C3;%0Lv<p9ٟy2j~=#2?DSHmƿ3 --ꎵ6O؊sw⤗>UlE|sX(=`)Q`.U	x^uy {`_=V٠&Vg%욈V?|7b^AN^r=`#{E裣$${ґp'^S	T"h>lf:\7^99qPN0CNkc#W[ͻYM)*+ ^o~?Cpͺ`s9Elմ9I5/d35g:~ާ|&O$$3nZoӻ6;v٢Uk)/)hגEjR[X^vvyJ&:zB9qos\.K>$#L2Pv^<X'h2doP5p֊蜭!'E<&2U={9B~oG\{
k$&(~R2i$;~ႶƄsF˖9 P&|S(^?+Qb֫$.y[M:n_]7PfM+@\ؐ[{YxhC%M'MUT'XѢVĵ?&vt-aըKowT ;o:V:'罨埻.PqM EYȍ'+u9ً͝OǮd?G#/$:#̽F+d`Aߛ YXK?َݦ<0<]{WWZM>Qd'qXjJ>%lv"J]eL%J:öbql_
+6\x>m:d}"1ڧbj#2ne;j4NAR&Gk&Do,LO$BtaS}bHҟ<Rzd	uХ2kl)<V`WNGq¡Uĳxdydɸ>_EP'Wck(RootLock);
	    RootLock->msfl_Msd = FakeRootDirEntry.de_Msd;
	    RootLock->msfl_DirSector = -1;
	    Disk.vollabel = FakeRootDirEntry;
	}
	return DOSTRUE;
    }
    /*
     * No label yet? Then we must create one, even if we need to move
     * something else for it.
     */

    if ((int) RootLock->msfl_DirSector < 0) {
	struct MSFileLock *new;

	new = MSLock(RootLock, "><>.\\", EXCLUSIVE_LOCK ^ MODE_CREATEFILE);
	if ((new == NULL) && (new = EmptyFileLock)) {
	    error = 0;
	    if (new->msfl_DirSector == Disk.rootdir) {
		RootLock->msfl_DirSector = Disk.rootdir;
		RootLock->msfl_DirOffset = new->msfl_DirOffset;
	    } else {
		/*
		 * Move something out of the first directory block. Try
		 * not to move system files or directories (. ..), but
		 * we'll do it if we need to. Set the root dir date to
		 * now.
		 */
		byte	       *fromsec;
		byte	       *tosec;
		register struct MsDirEntry *dir;

		fromsec = GetSec(Disk.rootdir);
		tosec = GetSec(new->msfl_DirSector);

		dir = (struct MsDirEntry *) fromsec;
		while (dir->msd_Attributes & (ATTR_SYSTEM | ATTR_DIRECTORY)) {
		    if ((byte *) ++dir >= fromsec + Disk.bps) {
			--dir;	/* Back to last entry in the block */
			break;	/* and move it no matter what */
		    }
		}
		CopyMem(dir, tosec + new->msfl_DirOffset,
			(long) sizeof (struct MsDirEntry));
		MarkSecDirty(tosec);
		RootLock->msfl_DirSector = Disk.rootdir;
		RootLock->msfl_DirOffset = (byte *) dir - fromsec;

		FreeSec(tosec);
		FreeSec(fromsec);

	    }
	}
	EmptyFileLock = NULL;
	MSUnLock(new);
    }
    if ((int) RootLock->msfl_DirSector >= Disk.rootdir) {
	struct DateStamp dateStamp;

	/*
	 * The easy part: Copy the name to Disk.vollabel and RootLock.
	 */
	{
	    register int    i;
	    register byte  *s,
			   *d;

	    s = newname;
	    d = Disk.vollabel.de_Msd.msd_Name;
	    for (i = 0; i < 8 + 3; i++) {
		if (s[0])
		    *d++ = ToUpper(*s++);
		else
		    *d++ = ' ';
	    }
	}
	DateStamp(&dateStamp);
	ToMSDate(&Disk.vollabel.de_Msd.msd_Date,
		 &Disk.vollabel.de_Msd.msd_Time, &dateStamp);
	RootLock->msfl_Msd = Disk.vollabel.de_Msd;	/* Just for the name and
							 * date */
	WriteFileLock(RootLock);

	return DOSTRUE;
    }
    return DOSFALSE;
#endif
}

#ifdef DEBUG

_abort()
{
    HanCloseDown();
    RemTask(NULL);
}

#endif				/* DEBUG */
