henesyinit from p9fce6d0435 years agoHistory
676 lines · 11.4 KB · C
RawDownload
#include "sam.h" Rune	genbuf[BLOCKSIZE];int	io;int	panicking;int	rescuing;Mod	modnum;String	genstr;String	rhs;String	wd;String	cmdstr;Rune	empty[] = { 0 };char	*genc;File	*curfile;File	*flist;File	*cmd;jmp_buf	mainloop;List tempfile;int	quitok = TRUE;int	downloaded;int	dflag;int	Rflag;char	*machine;char	*home;int	bpipeok;int	termlocked;char	*samterm = SAMTERM;char	*rsamname = RSAM; Rune	baddir[] = { '<', 'b', 'a', 'd', 'd', 'i', 'r', '>', '\n'}; void	usage(void); voidmain(int argc, char *argv[]){	int i;	String *t;	char **ap, **arg; 	arg = argv++;	ap = argv;	while(argc>1 && argv[0] && argv[0][0]=='-'){		switch(argv[0][1]){		case 'd':			dflag++;			break; 		case 'r':			--argc, argv++;			if(argc == 1)				usage();			machine = *argv;			break; 		case 'R':			Rflag++;			break; 		case 't':			--argc, argv++;			if(argc == 1)				usage();			samterm = *argv;			break; 		case 's':			--argc, argv++;			if(argc == 1)				usage();			rsamname = *argv;			break; 		default:			dprint("sam: unknown flag %c\n", argv[0][1]);			exits("usage");		}		--argc, argv++;	}	Strinit(&cmdstr);	Strinit0(&lastpat);	Strinit0(&lastregexp);	Strinit0(&genstr);	Strinit0(&rhs);	Strinit0(&wd);	tempfile.listptr = emalloc(0);	Strinit0(&plan9cmd);	home = getenv(HOME);	if(home == 0)		home = "/";	if(!dflag)		startup(machine, Rflag, arg, ap);	Fstart();	notify(notifyf);	if(argc>1){		for(i=0; i<argc-1; i++)			if(!setjmp(mainloop)){				t = tmpcstr(argv[i]);				Straddc(t, '\0');				Strduplstr(&genstr, t);				freetmpstr(t);				Fsetname(newfile(), &genstr);			}	}else if(!downloaded)		newfile()->state = Clean;	modnum++;	if(file.nused)		current(file.filepptr[0]);	setjmp(mainloop);	cmdloop();	trytoquit();	/* if we already q'ed, quitok will be TRUE */	exits(0);} voidusage(void){	dprint("usage: sam [-d] [-t samterm] [-s sam name] -r machine\n");	exits("usage");} voidrescue(void){	int i, nblank = 0;	File *f;	char *c;	char buf[256]; 	if(rescuing++)		return;	io = -1;	for(i=0; i<file.nused; i++){		f = file.filepptr[i];		if(f==cmd || f->nrunes==0 || f->state!=Dirty)			continue;		if(io == -1){			sprint(buf, "%s/sam.save", home);			io = create(buf, 1, 0777);			if(io<0)				return;		}		if(f->name.s[0]){			c = Strtoc(&f->name);			strncpy(buf, c, sizeof buf-1);			buf[sizeof buf-1] = 0;			free(c);		}else			sprint(buf, "nameless.%d", nblank++);		fprint(io, "#!%s '%s' $* <<'---%s'\n", SAMSAVECMD, buf, buf);		addr.r.p1 = 0, addr.r.p2 = f->nrunes;		writeio(f);		fprint(io, "\n---%s\n", (char *)buf);	}} voidpanic(char *s){	int wasd; 	if(!panicking++ && !setjmp(mainloop)){		wasd = downloaded;		downloaded = 0;		dprint("sam: panic: %s: %r\n", s);		if(wasd)			fprint(2, "sam: panic: %s: %r\n", s);		rescue();		abort();	}} voidhiccough(char *s){	if(rescuing)		exits("rescue");	if(s)		dprint("%s\n", s);	resetcmd();	resetxec();	resetsys();	if(io > 0)		close(io);	if(undobuf->nrunes)		Bdelete(undobuf, (Posn)0, undobuf->nrunes);	update();	if (curfile) {		if (curfile->state==Unread)			curfile->state = Clean;		else if (downloaded)			outTs(Hcurrent, curfile->tag);	}	longjmp(mainloop, 1);} voidintr(void){	error(Eintr);} voidtrytoclose(File *f){	char *t;	char buf[256]; 	if(f == cmd)	/* possible? */		return;	if(f->deleted)		return;	if(f->state==Dirty && !f->closeok){		f->closeok = TRUE;		if(f->name.s[0]){			t = Strtoc(&f->name);			strncpy(buf, t, sizeof buf-1);			free(t);		}else			strcpy(buf, "nameless file");		error_s(Emodified, buf);	}	f->deleted = TRUE;} voidtrytoquit(void){	int c;	File *f; 	if(!quitok){		for(c = 0; c<file.nused; c++){			f = file.filepptr[c];			if(f!=cmd && f->state==Dirty){				quitok = TRUE;				eof = FALSE;				error(Echanges);			}		}}} voidload(File *f){	Address saveaddr; 	Strduplstr(&genstr, &f->name);	filename(f);	if(f->name.s[0]){		saveaddr = addr;		edit(f, 'I');		addr = saveaddr;	}else		f->state = Clean;	Fupdate(f, TRUE, TRUE);} voidcmdupdate(void){	if(cmd && cmd->mod!=0){		Fupdate(cmd, FALSE, downloaded);		cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->nrunes;		telldot(cmd);	}} voiddelete(File *f){	if(downloaded && f->rasp)		outTs(Hclose, f->tag);	delfile(f);	if(f == curfile)		current(0);} voidupdate(void){	int i, anymod;	File *f; 	settempfile();	for(anymod = i=0; i<tempfile.nused; i++){		f = tempfile.filepptr[i];		if(f==cmd)	/* cmd gets done in main() */			continue;		if(f->deleted)			delete(f);		if(f->mod==modnum && Fupdate(f, FALSE, downloaded))			anymod++;		if(f->rasp)			telldot(f);	}	if(anymod)		modnum++;} File *current(File *f){	return curfile = f;} voidedit(File *f, int cmd){	int empty = TRUE;	Posn p;	int nulls; 	if(cmd == 'r')		Fdelete(f, addr.r.p1, addr.r.p2);	if(cmd=='e' || cmd=='I'){		Fdelete(f, (Posn)0, f->nrunes);		addr.r.p2 = f->nrunes;	}else if(f->nrunes!=0 || (f->name.s[0] && Strcmp(&genstr, &f->name)!=0))		empty = FALSE;	if((io = open(genc, OREAD))<0) {		if (curfile && curfile->state == Unread)			curfile->state = Clean;		error_s(Eopen, genc);	}	p = readio(f, &nulls, empty);	closeio((cmd=='e' || cmd=='I')? -1 : p);	if(cmd == 'r')		f->ndot.r.p1 = addr.r.p2, f->ndot.r.p2 = addr.r.p2+p;	else		f->ndot.r.p1 = f->ndot.r.p2 = 0;	f->closeok = empty;	if (quitok)		quitok = empty;	else		quitok = FALSE;	state(f, empty && !nulls? Clean : Dirty);	if(cmd == 'e')		filename(f);} intgetname(File *f, String *s, int save){	int c, i; 	Strzero(&genstr);	if(genc){		free(genc);		genc = 0;	}	if(s==0 || (c = s->s[0])==0){		/* no name provided */		if(f)			Strduplstr(&genstr, &f->name);		else			Straddc(&genstr, '\0');		goto Return;	}	if(c!=' ' && c!='\t')		error(Eblank);	for(i=0; (c=s->s[i])==' ' || c=='\t'; i++)		;	while(s->s[i] > ' ')		Straddc(&genstr, s->s[i++]);	if(s->s[i])		error(Enewline);	Straddc(&genstr, '\0');	if(f && (save || f->name.s[0]==0)){		Fsetname(f, &genstr);		if(Strcmp(&f->name, &genstr)){			quitok = f->closeok = FALSE;			f->qid = 0;			f->date = 0;			state(f, Dirty); /* if it's 'e', fix later */		}	}    Return:	genc = Strtoc(&genstr);	return genstr.n-1;	/* strlen(name) */} voidfilename(File *f){	if(genc)		free(genc);	genc = Strtoc(&genstr);	dprint("%c%c%c %s\n", " '"[f->state==Dirty],		"-+"[f->rasp!=0], " ."[f==curfile], genc);} voidundostep(File *f){	Buffer *t;	int changes;	Mark mark; 	t = f->transcript;	changes = Fupdate(f, TRUE, TRUE);	Bread(t, (Rune*)&mark, (sizeof mark)/RUNESIZE, f->markp);	Bdelete(t, f->markp, t->nrunes);	f->markp = mark.p;	f->dot.r = mark.dot;	f->ndot.r = mark.dot;	f->mark = mark.mark;	f->mod = mark.m;	f->closeok = mark.s1!=Dirty;	if(mark.s1==Dirty)		quitok = FALSE;	if(f->state==Clean && mark.s1==Clean && changes)		state(f, Dirty);	else		state(f, mark.s1);} intundo(void){	File *f;	int i;	Mod max;	if((max = curfile->mod)==0)		return 0;	settempfile();	for(i = 0; i<tempfile.nused; i++){		f = tempfile.filepptr[i];		if(f!=cmd && f->mod==max)			undostep(f);	}	return 1;} intreadcmd(String *s){	int retcode; 	if(flist == 0)		(flist = Fopen())->state = Clean;	addr.r.p1 = 0, addr.r.p2 = flist->nrunes;	retcode = plan9(flist, '<', s, FALSE);	Fupdate(flist, FALSE, FALSE);	flist->mod = 0;	if (flist->nrunes > BLOCKSIZE)		error(Etoolong);	Strzero(&genstr);	Strinsure(&genstr, flist->nrunes);	Fchars(flist, genbuf, (Posn)0, flist->nrunes);	memmove(genstr.s, genbuf, flist->nrunes*RUNESIZE);	genstr.n = flist->nrunes;	Straddc(&genstr, '\0');	return retcode;} voidcd(String *str){	int i;	File *f;	String *t; 	t = tmpcstr("/bin/pwd");	Straddc(t, '\0');	if (flist) {		Fclose(flist);		flist = 0;	}	if (readcmd(t) != 0) {		Strduplstr(&genstr, tmprstr(baddir, sizeof(baddir)/sizeof(Rune)));		Straddc(&genstr, '\0');	}	freetmpstr(t);	Strduplstr(&wd, &genstr);	if(wd.s[0] == 0){		wd.n = 0;		warn(Wpwd);	}else if(wd.s[wd.n-2] == '\n'){		--wd.n;		wd.s[wd.n-1]='/';	}	if(chdir(getname((File *)0, str, FALSE)? genc : home))		syserror("chdir");	settempfile();	for(i=0; i<tempfile.nused; i++){		f = tempfile.filepptr[i];		if(f!=cmd && f->name.s[0]!='/' && f->name.s[0]!=0){			Strinsert(&f->name, &wd, (Posn)0);			sortname(f);		}	}} intloadflist(String *s){	int c, i; 

Lines 1–500 of 676.