#include "nfs.h"

int iflag 0;
int xflag 0;
struct stk *xsp stack;
char *nxt &end;
char *last &end;

char *terr "snt\0\0";
char *stat1 "f rwxrwxrwx";
char *ng ".\0";

main(argc,argv)
int argc;
char **argv;
	{
	extern fout;
	int i;
	int compar();

	flush();
	fout = 2;
	sbrk(16);
	if (argc<2) ex(1); eargv=argv+argc;

	if((fn = open("/dev/tiu/d1",2)) < 0)
		{
		printf("Spider busy\n"); ex(2);
		}
	getpw(getuid(),nam);		/*  get login name  */
	for(np = nam; *np != ':'; np++);	/* find the ':' delimiter  */
	*np = '\0';
	name(nam);	/* put login name in buf to send to File Store */
	*bp++ = LOGIN;
	if(sendc(OK))ex(1);

	argv++;

		/* interpret command */

	if (*argv[0] != '-')
		{
		bp = buf;
		for (; argv != eargv; argv++)
			{
			for (tp = *argv; *tp; tp++)
				{
				*bp++ = *tp;
				if (bp == &buf[510]) {printf("too many args\n"); ex(1);}
				}
			*bp++ = ' ';
			}
		*bp++ = '\n';
		ff = 1;
		rd('r');
		qt(0);
		}

		/* break out functions and set flags for key args */

	for (tp = *argv++ + 1 ; *tp; tp++) switch(*tp)
		{
	case 't':
	case 'l':
	case 'm':
	case 'w':
	case 'u':
	case 'd':
	case 'r':
	case 's':
		if(op != 0){printf("illegal function\n"); qt(1);}
		op = *tp;
		continue;

	case 'v':
		vflag++;
		continue;

	case 'i':
		iflag++;
		continue;
	case 'x':
		xflag++;
		continue;

	case 'c':	/* another directory in File Store is used  */
		if (argv == eargv) 
			{
			printf("directory required with 'c' function\n");
			qt(1);
			}
		np = nam; bp = *argv;
		while (*np++ = *bp++);
		name(*argv++);
		*bp++ = CDIR;
		if (sendc(OK)) ex(1);
		argc--;
		continue;
	default:
		printf("illegal function\n"); qt(1);
		}


	if (argv == eargv)		/* no file is named use current directory */
		{ argv= &ng; eargv=argv+1;}
	sp = stack;
	for (;;)
		{
		tp = gen();
		if (!tp)	/* pick up next arg from cmd line */
			{
			if (argv == eargv) qt(0);
			tp = *argv++; np = nam;
			while(*np++ = *tp++);
			sp[spos] = --np;
			tp = nam;
			}
		fsp = tp;
		name(fsp);
		switch(op)
			{
		case 'm':
			if (ask()) break;
		mdir:
			*bp++ = UNLESS;
			*bp++ = DCREATE;
			*bp++ = FI;
			goto single;
		case 'w':
		case 'u':
			if (ask()) break;
			ff = open(tp,0);
			if (ff<0) goto erf;
			if (dir()) goto mdir;
			if(op == 'u')	/* test if file has been updated  */
				{
				tme[0] = dirbuf[16]; tme[1] = dirbuf[17];
				i = gstat();
				if (i == 0)
					{
					/* file exists */
				if(dbcmp(tme,dirbuf->i_modtime) < 0)
					 	{ close(ff); break;}
					}
				else if (i != -1) break;
				name(fsp);
				}
			*bp++ = FCREATE; *bp++ = WRITE; *bp++ = CLOSE;
			if(sendc(WRITE))break;		/* send the command  */
			sum=0; length=0;
			do	{
				nchar = read(ff,buf,512);
/*
				sum =+ addup(nchar); length =+ nchar;
*/
				if (nchar==0) code=2; else code=1;
				if (send(nchar,code) < 0) trouble();
				} while(nchar > 0);
			if(check(OK) < 0)		 /* error */
				{
				exx(); qt(1);
				}
			goto knxt;
		case 'r':
			if(xflag ||ask()) break;
			if(xdir(1))		/* extract a directory */
				{
				/* is it an existing directory */
				if(((i = stat(tp,dirbuf)) >= 0))break;
				if((i = fork()) == 0)
					execl("/bin/mkdir","mkdir",tp,0);
				if((i < 0) || ((wait(&i)) < 0) || ((stat(tp,dirbuf)) < 0))
					{
					printf("directory %s cannot be created\n",nam);qt(1);
					}
				break;
				}
			if((ff = creat(tp,0666)) < 0)goto erf;
			*bp++ = itype; *bp++ = 0; *bp++ = 0;
			*bp++ = OPEN; *bp++ = READ; *bp++ = CLOSE;
			if(rd(op))		/* read data and put in file  */
				goto cnxt1;		/* an error */
		knxt:
/*
			bp = buf; *bp++ = 'K';
			*bp++ = (sum >> 8); *bp++ = (sum & 0377);
			*bp++ = (length >> 8); *bp++ = (length & 0377);
			if(sendc(OK))goto cnxt1;
*/
		cnxt:
			if(vflag)printf("%c %s\n",op,nam);
		cnxt1:
			close(ff);
			break;
		case 'd':
			if (argc < 3) ex(0);
			xflag = 1;
			if ((xdir(1) == 1) || (ask())) break;
			*bp++ = DELETE;
		single:
			if((!sendc(OK)) && (vflag))		/* send just a command -no data  */
			printf("%c %s\n",op,nam);
			break;
		case 's':
			fout = 1;
			spstat();		/* get status from file store  */
			fout = 2;
			break;

		case 't':
		case 'l':
			nxt = &end;
			i = xdir(0);
			if ((i == 0) || (i == 2))
				{
				fout = 1;
				astat(op);
				fout = 2;
				break;
				}
			if (i > 0)
				{
				qsort(&end,(nxt - &end)/14,14,compar);
				for(tp = &end; tp < nxt; tp =+ 14)
					{
					append(tp,sp[spos]);name(fsp);
					fout = 1;
					if (op == 't') printf("%s\n",tp);
					else astat(op);
					fout = 2;
					}
				}
			break;
		default:
			printf("illegal op-code\n");
			qt(1);
			}
	nxtarg:;
		}
erf:
	printf("%s : cannot open ",tp); perror(""); printf("\n");
	goto nxtarg;
	}
