/*
 * 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/";
void execfinit(void);
void execbind(void);
void execmount(void);
void execulimit(void);
void execumask(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,
	0
};
#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];

	while((w = wait()) != nil){
		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(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);
	}

	errstr(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 n;
	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: 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 = read(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 unused0){
	return -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);
}
