/*
 * Plan 9 versions of system-specific functions
 *	By convention, exported routines herein have names beginning with an
 *	upper case letter.
 */
#include "rc.h"
#include "exec.h"
#include "io.h"
#include "fns.h"
#include "getflags.h"
char *Signame[]={
	"sigexit",	"sighup",	"sigint",	"sigquit",
	"sigalrm",	"sigkill",	"sigfpe",	"sigterm",
	0
};
char *syssigname[]={
	"exit",		/* can't happen */
	"hangup",
	"interrupt",
	"quit",		/* can't happen */
	"alarm",
	"kill",
	"sys: fp: ",
	"term",
	0
};
char*
Rcmain(void)
{
	return unsharp("#9/rcmain");
}

char Fdprefix[]="/dev/fd/";
long readnb(int, char *, long);
void execfinit(void);
void execbind(void);
void execmount(void);
void execulimit(void);
void execumask(void);
void execrfork(void);
builtin Builtin[]={
	"cd",		execcd,
	"whatis",	execwhatis,
	"eval",		execeval,
	"exec",		execexec,	/* but with popword first */
	"exit",		execexit,
	"shift",	execshift,
	"wait",		execwait,
	".",		execdot,
	"finit",	execfinit,
	"flag",		execflag,
	"ulimit",	execulimit,
	"umask",	execumask,
	"rfork",	execrfork,
	0
};

void
execrfork(void)
{
	int arg;
	char *s;

	switch(count(runq->argv->words)){
	case 1:
		arg = RFENVG|RFNOTEG|RFNAMEG;
		break;
	case 2:
		arg = 0;
		for(s = runq->argv->words->next->word;*s;s++) switch(*s){
		default:
			goto Usage;
		case 'n':
			arg|=RFNAMEG;  break;
		case 'N':
			arg|=RFCNAMEG;
			break;
		case 'e':
			/* arg|=RFENVG; */  break;
		case 'E':
			arg|=RFCENVG;  break;
		case 's':
			arg|=RFNOTEG;  break;
		case 'f':
			arg|=RFFDG;    break;
		case 'F':
			arg|=RFCFDG;   break;
		}
		break;
	default:
	Usage:
		pfmt(err, "Usage: %s [nNeEsfF]\n", runq->argv->words->word);
		setstatus("rfork usage");
		poplist();
		return;
	}
	if(rfork(arg)==-1){
		pfmt(err, "rc: %s failed\n", runq->argv->words->word);
		setstatus("rfork failed");
	}
	else
		setstatus("");
	poplist();
}



#define	SEP	'\1'
char **environp;
struct word *enval(s)
register char *s;
{
	register char *t, c;
	register struct word *v;
	for(t=s;*t && *t!=SEP;t++);
	c=*t;
	*t='\0';
	v=newword(s, c=='\0'?(struct word *)0:enval(t+1));
	*t=c;
	return v;
}
void Vinit(void){
	extern char **environ;
	register char *s;
	register char **env=environ;
	environp=env;
	for(;*env;env++){
		for(s=*env;*s && *s!='(' && *s!='=';s++);
		switch(*s){
		case '\0':
		/*	pfmt(err, "rc: odd environment %q?\n", *env); */
			break;
		case '=':
			*s='\0';
			setvar(*env, enval(s+1));
			*s='=';
			break;
		case '(':	/* ignore functions for now */
			break;
		}
	}
}
char **envp;
void Xrdfn(void){
	char *p;
	register char *s;
	register int len;
	for(;*envp;envp++){
		s = *envp;
		if(strncmp(s, "fn#", 3) == 0){
			p = strchr(s, '=');
			if(p == nil)
				continue;
			*p = ' ';
			s[2] = ' ';
			len = strlen(s);
			execcmds(opencore(s, len));
			s[len] = '\0';
			return;
		}
#if 0
		for(s=*envp;*s && *s!='(' && *s!='=';s++);
		switch(*s){
		case '\0':
			pfmt(err, "environment %q?\n", *envp);
			break;
		case '=':	/* ignore variables */
			break;
		case '(':		/* Bourne again */
			s=*envp+3;
			envp++;
			len=strlen(s);
			s[len]='\n';
			execcmds(opencore(s, len+1));
			s[len]='\0';
			return;
		}
#endif
	}
	Xreturn();
}
union code rdfns[4];
void execfinit(void){
	static int first=1;
	if(first){
		rdfns[0].i=1;
		rdfns[1].f=Xrdfn;
		rdfns[2].f=Xjump;
		rdfns[3].i=1;
		first=0;
	}
	Xpopm();
	envp=environp;
	start(rdfns, 1, runq->local);
}
extern int mapfd(int);
int Waitfor(int pid, int unused0){
	thread *p;
	Waitmsg *w;
	char errbuf[ERRMAX];

	if(pid >= 0 && !havewaitpid(pid))
		return 0;
	while((w = wait()) != nil){
		delwaitpid(w->pid);
		if(w->pid==pid){
			if(strncmp(w->msg, "signal: ", 8) == 0)
				fprint(mapfd(2), "%d: %s\n", w->pid, w->msg);
			setstatus(w->msg);
			free(w);
			return 0;
		}
		if(runq->iflag && strncmp(w->msg, "signal: ", 8) == 0)
			fprint(2, "%d: %s\n", w->pid, w->msg);
		for(p=runq->ret;p;p=p->ret)
			if(p->pid==w->pid){
				p->pid=-1;
				strcpy(p->status, w->msg);
			}
		free(w);
	}

	rerrstr(errbuf, sizeof errbuf);
	if(strcmp(errbuf, "interrupted")==0) return -1;
	return 0;
}
char **mkargv(word *a)
{
	char **argv=(char **)emalloc((count(a)+2)*sizeof(char *));
	char **argp=argv+1;	/* leave one at front for runcoms */
	for(;a;a=a->next) *argp++=a->word;
	*argp=0;
	return argv;
}
/*
void addenv(var *v)
{
	char envname[256];
	word *w;
	int f;
	io *fd;
	if(v->changed){
		v->changed=0;
		snprint(envname, sizeof envname, "/env/%s", v->name);
		if((f=Creat(envname))<0)
			pfmt(err, "rc: can't open %s: %r\n", envname);
		else{
			for(w=v->val;w;w=w->next)
				write(f, w->word, strlen(w->word)+1L);
			close(f);
		}
	}
	if(v->fnchanged){
		v->fnchanged=0;
		snprint(envname, sizeof envname, "/env/fn#%s", v->name);
		if((f=Creat(envname))<0)
			pfmt(err, "rc: can't open %s: %r\n", envname);
		else{
			if(v->fn){
				fd=openfd(f);
				pfmt(fd, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
				closeio(fd);
			}
			close(f);
		}
	}
}
void updenvlocal(var *v)
{
	if(v){
		updenvlocal(v->next);
		addenv(v);
	}
}
void Updenv(void){
	var *v, **h;
	for(h=gvar;h!=&gvar[NVAR];h++)
		for(v=*h;v;v=v->next)
			addenv(v);
	if(runq) updenvlocal(runq->local);
}
*/
int
cmpenv(const void *a, const void *b)
{
	return strcmp(*(char**)a, *(char**)b);
}
char **mkenv(){
	register char **env, **ep, *p, *q;
	register struct var **h, *v;
	register struct word *a;
	register int nvar=0, nchr=0, sep;
	/*
	 * Slightly kludgy loops look at locals then globals
	 */
	for(h=gvar-1;h!=&gvar[NVAR];h++) for(v=h>=gvar?*h:runq->local;v;v=v->next){
		if((v==vlook(v->name)) && v->val){
			nvar++;
			nchr+=strlen(v->name)+1;
			for(a=v->val;a;a=a->next)
				nchr+=strlen(a->word)+1;
		}
		if(v->fn){
			nvar++;
			nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;
		}
	}
	env=(char **)emalloc((nvar+1)*sizeof(char *)+nchr);
	ep=env;
	p=(char *)&env[nvar+1];
	for(h=gvar-1;h!=&gvar[NVAR];h++) for(v=h>=gvar?*h:runq->local;v;v=v->next){
		if((v==vlook(v->name)) && v->val){
			*ep++=p;
			q=v->name;
			while(*q) *p++=*q++;
			sep='=';
			for(a=v->val;a;a=a->next){
				*p++=sep;
				sep=SEP;
				q=a->word;
				while(*q) *p++=*q++;
			}
			*p++='\0';
		}
		if(v->fn){
			*ep++=p;
#if 0
			*p++='#'; *p++='('; *p++=')';	/* to fool Bourne */
			*p++='f'; *p++='n'; *p++=' ';
			q=v->name;
			while(*q) *p++=*q++;
			*p++=' ';
#endif
			*p++='f'; *p++='n'; *p++='#';
			q=v->name;
			while(*q) *p++=*q++;
			*p++='=';
			q=v->fn[v->pc-1].s;
			while(*q) *p++=*q++;
			*p++='\n';
			*p++='\0';
		}
	}
	*ep=0;
	qsort((char *)env, nvar, sizeof ep[0], cmpenv);
	return env;	
}
void Updenv(void){}
void Execute(word *args, word *path)
{
	char **argv=mkargv(args);
	char **env=mkenv();
	char file[1024];
	int nc;
	Updenv();
	for(;path;path=path->next){
		nc=strlen(path->word);
		if(nc<1024){
			strcpy(file, path->word);
			if(file[0]){
				strcat(file, "/");
				nc++;
			}
			if(nc+strlen(argv[1])<1024){
				strcat(file, argv[1]);
				execve(file, argv+1, env);
			}
			else werrstr("command name too long");
		}
	}
	rerrstr(file, sizeof file);
	pfmt(err, "%s: %s\n", argv[1], file);
	efree((char *)argv);
}
#define	NDIR	256		/* shoud be a better way */
int Globsize(char *p)
{
	ulong isglob=0, globlen=NDIR+1;
	for(;*p;p++){
		if(*p==GLOB){
			p++;
			if(*p!=GLOB) isglob++;
			globlen+=*p=='*'?NDIR:1;
		}
		else
			globlen++;
	}
	return isglob?globlen:0;
}
#define	NFD	50
#define	NDBUF	32
struct{
	Dir	*dbuf;
	int	i;
	int	n;
}dir[NFD];
int Opendir(char *name)
{
	Dir *db;
	int f;
	f=open(name, 0);
	if(f==-1)
		return f;
	db = dirfstat(f);
	if(db!=nil && (db->mode&DMDIR)){
		if(f<NFD){
			dir[f].i=0;
			dir[f].n=0;
		}
		free(db);
		return f;
	}
	free(db);
	close(f);
	return -1;
}
int Readdir(int f, char *p, int onlydirs)
{
	int n;
	USED(onlydirs);	/* only advisory */

	if(f<0 || f>=NFD)
		return 0;
	if(dir[f].i==dir[f].n){	/* read */
		free(dir[f].dbuf);
		dir[f].dbuf=0;
		n=dirread(f, &dir[f].dbuf);
		if(n>=0)
			dir[f].n=n;
		else
			dir[f].n=0;
		dir[f].i=0;
	}
	if(dir[f].i==dir[f].n)
		return 0;
	strcpy(p, dir[f].dbuf[dir[f].i].name);
	dir[f].i++;
	return 1;
}
void Closedir(int f){
	if(f>=0 && f<NFD){
		free(dir[f].dbuf);
		dir[f].i=0;
		dir[f].n=0;
		dir[f].dbuf=0;
	}
	close(f);
}
int interrupted = 0;
void
notifyf(void *unused0, char *s)
{
	int i;
	for(i=0;syssigname[i];i++)
		if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
			if(strncmp(s, "sys: ", 5)!=0){
				if(kidpid && !interrupted){
					interrupted=1;
					postnote(PNGROUP, kidpid, s);
				}
				interrupted = 1;
			}
			goto Out;
		}
	if(strcmp(s, "sys: window size change") != 0)
	if(strcmp(s, "sys: write on closed pipe") != 0)
	if(strcmp(s, "sys: child") != 0)
		pfmt(err, "rc: note: %s\n", s);
	noted(NDFLT);
	return;
Out:
	if(strcmp(s, "interrupt")!=0 || trap[i]==0){
		trap[i]++;
		ntrap++;
	}
	if(ntrap>=32){	/* rc is probably in a trap loop */
		pfmt(err, "rc: Too many traps (trap %s), aborting\n", s);
		abort();
	}
	noted(NCONT);
}
void Trapinit(void){
	notify(notifyf);
}
void Unlink(char *name)
{
	remove(name);
}
long Write(int fd, char *buf, long cnt)
{
	return write(fd, buf, (long)cnt);
}
long Read(int fd, char *buf, long cnt)
{
	int i;

	i = readnb(fd, buf, cnt);
	if(ntrap) dotrap();
	return i;
}
long Seek(int fd, long cnt, long whence)
{
	return seek(fd, cnt, whence);
}
int Executable(char *file)
{
	Dir *statbuf;
	int ret;

	statbuf = dirstat(file);
	if(statbuf == nil) return 0;
	ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0);
	free(statbuf);
	return ret;
}
int Creat(char *file)
{
	return create(file, 1, 0666L);
}
int Dup(int a, int b){
	return dup(a, b);
}
int Dup1(int a){
	return dup(a, -1);
}
void Exit(char *stat)
{
	Updenv();
	setstatus(stat);
	exits(truestatus()?"":getstatus());
}
int Eintr(void){
	return interrupted;
}
void Noerror(void){
	interrupted=0;
}
int
Isatty(int fd){
	return isatty(fd);
}
void Abort(void){
	pfmt(err, "aborting\n");
	flush(err);
	Exit("aborting");
}
void Memcpy(char *a, char *b, long n)
{
	memmove(a, b, (long)n);
}
void *Malloc(ulong n){
	return malloc(n);
}

int
exitcode(char *msg)
{
	int n;
	
	n = atoi(msg);
	if(n == 0)
		n = 1;
	return n;
}

int *waitpids;
int nwaitpids;

void
addwaitpid(int pid)
{
	waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]);
	if(waitpids == 0)
		panic("Can't realloc %d waitpids", nwaitpids+1);
	waitpids[nwaitpids++] = pid;
}

void
delwaitpid(int pid)
{
	int r, w;
	
	for(r=w=0; r<nwaitpids; r++)
		if(waitpids[r] != pid)
			waitpids[w++] = waitpids[r];
	nwaitpids = w;
}

void
clearwaitpids(void)
{
	nwaitpids = 0;
}

int
havewaitpid(int pid)
{
	int i;
	
	for(i=0; i<nwaitpids; i++)
		if(waitpids[i] == pid)
			return 1;
	return 0;
}
