Beispiel #1
0
int
plumbrunestr(Runestr *rs, char *attr)
{
    Plumbmsg *m;
    int i;

    i = -1;
    if(plumbsendfd >= 0) {
        m = emalloc(sizeof(Plumbmsg));
        m->src = estrdup("abaco");
        m->dst = nil;
        m->wdir = estrdup("/tmp");
        m->type = estrdup("text");
        if(attr)
            m->attr = plumbunpackattr(attr);
        else
            m->attr = nil;
        m->data = smprint("%.*S", rs->nr, rs->r);
        m->ndata = -1;
        i = plumbsend(plumbsendfd, m);
        plumbfree(m);
    }
    return i;
}
Beispiel #2
0
int
inmesg(Tmesg type)
{
	Rune buf[1025];
	char cbuf[64];
	int i, m;
	short s;
	long l, l1;
	vlong v;
	File *f;
	Posn p0, p1, p;
	Range r;
	String *str;
	char *c, *wdir;
	Rune *rp;
	Plumbmsg *pm;

	if(type > TMAX)
		panic("inmesg");

	journal(0, tname[type]);

	inp = indata;
	switch(type){
	case -1:
		panic("rcv error");

	default:
		fprint(2, "unknown type %d\n", type);
		panic("rcv unknown");

	case Tversion:
		tversion = inshort();
		journaln(0, tversion);
		break;

	case Tstartcmdfile:
		v = invlong();		/* for 64-bit pointers */
		journaln(0, v);
		Strdupl(&genstr, samname);
		cmd = newfile();
		cmd->unread = 0;
		outTsv(Hbindname, cmd->tag, v);
		outTs(Hcurrent, cmd->tag);
		logsetname(cmd, &genstr);
		cmd->rasp = listalloc('P');
		cmd->mod = 0;
		if(cmdstr.n){
			loginsert(cmd, 0L, cmdstr.s, cmdstr.n);
			Strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
		}
		fileupdate(cmd, FALSE, TRUE);
		outT0(Hunlock);
		break;

	case Tcheck:
		/* go through whichfile to check the tag */
		outTs(Hcheck, whichfile(inshort())->tag);
		break;

	case Trequest:
		f = whichfile(inshort());
		p0 = inlong();
		p1 = p0+inshort();
		journaln(0, p0);
		journaln(0, p1-p0);
		if(f->unread)
			panic("Trequest: unread");
		if(p1>f->b.nc)
			p1 = f->b.nc;
		if(p0>f->b.nc) /* can happen e.g. scrolling during command */
			p0 = f->b.nc;
		if(p0 == p1){
			i = 0;
			r.p1 = r.p2 = p0;
		}else{
			r = rdata(f->rasp, p0, p1-p0);
			i = r.p2-r.p1;
			bufread(&f->b, r.p1, buf, i);
		}
		buf[i]=0;
		outTslS(Hdata, f->tag, r.p1, tmprstr(buf, i+1));
		break;

	case Torigin:
		s = inshort();
		l = inlong();
		l1 = inlong();
		journaln(0, l1);
		lookorigin(whichfile(s), l, l1);
		break;

	case Tstartfile:
		termlocked++;
		f = whichfile(inshort());
		if(!f->rasp)	/* this might be a duplicate message */
			f->rasp = listalloc('P');
		current(f);
		outTsv(Hbindname, f->tag, invlong());	/* for 64-bit pointers */
		outTs(Hcurrent, f->tag);
		journaln(0, f->tag);
		if(f->unread)
			load(f);
		else{
			if(f->b.nc>0){
				rgrow(f->rasp, 0L, f->b.nc);
				outTsll(Hgrow, f->tag, 0L, f->b.nc);
			}
			outTs(Hcheck0, f->tag);
			moveto(f, f->dot.r);
		}
		break;

	case Tworkfile:
		i = inshort();
		f = whichfile(i);
		current(f);
		f->dot.r.p1 = inlong();
		f->dot.r.p2 = inlong();
		f->tdot = f->dot.r;
		journaln(0, i);
		journaln(0, f->dot.r.p1);
		journaln(0, f->dot.r.p2);
		break;

	case Ttype:
		f = whichfile(inshort());
		p0 = inlong();
		journaln(0, p0);
		journal(0, (char*)inp);
		str = tmpcstr((char*)inp);
		i = str->n;
		loginsert(f, p0, str->s, str->n);
		if(fileupdate(f, FALSE, FALSE))
			seq++;
		if(f==cmd && p0==f->b.nc-i && i>0 && str->s[i-1]=='\n'){
			freetmpstr(str);
			termlocked++;
			termcommand();
		}else
			freetmpstr(str);
		f->dot.r.p1 = f->dot.r.p2 = p0+i; /* terminal knows this already */
		f->tdot = f->dot.r;
		break;

	case Tcut:
		f = whichfile(inshort());
		p0 = inlong();
		p1 = inlong();
		journaln(0, p0);
		journaln(0, p1);
		logdelete(f, p0, p1);
		if(fileupdate(f, FALSE, FALSE))
			seq++;
		f->dot.r.p1 = f->dot.r.p2 = p0;
		f->tdot = f->dot.r;   /* terminal knows the value of dot already */
		break;

	case Tpaste:
		f = whichfile(inshort());
		p0 = inlong();
		journaln(0, p0);
		for(l=0; l<snarfbuf.nc; l+=m){
			m = snarfbuf.nc-l;
			if(m>BLOCKSIZE)
				m = BLOCKSIZE;
			bufread(&snarfbuf, l, genbuf, m);
			loginsert(f, p0, tmprstr(genbuf, m)->s, m);
		}
		if(fileupdate(f, FALSE, TRUE))
			seq++;
		f->dot.r.p1 = p0;
		f->dot.r.p2 = p0+snarfbuf.nc;
		f->tdot.p1 = -1; /* force telldot to tell (arguably a BUG) */
		telldot(f);
		outTs(Hunlockfile, f->tag);
		break;

	case Tsnarf:
		i = inshort();
		p0 = inlong();
		p1 = inlong();
		snarf(whichfile(i), p0, p1, &snarfbuf, 0);
		break;

	case Tstartnewfile:
		v = invlong();
		Strdupl(&genstr, empty);
		f = newfile();
		f->rasp = listalloc('P');
		outTsv(Hbindname, f->tag, v);
		logsetname(f, &genstr);
		outTs(Hcurrent, f->tag);
		current(f);
		load(f);
		break;

	case Twrite:
		termlocked++;
		i = inshort();
		journaln(0, i);
		f = whichfile(i);
		addr.r.p1 = 0;
		addr.r.p2 = f->b.nc;
		if(f->name.s[0] == 0)
			error(Enoname);
		Strduplstr(&genstr, &f->name);
		writef(f);
		break;

	case Tclose:
		termlocked++;
		i = inshort();
		journaln(0, i);
		f = whichfile(i);
		current(f);
		trytoclose(f);
		/* if trytoclose fails, will error out */
		delete(f);
		break;

	case Tlook:
		f = whichfile(inshort());
		termlocked++;
		p0 = inlong();
		p1 = inlong();
		journaln(0, p0);
		journaln(0, p1);
		setgenstr(f, p0, p1);
		for(l = 0; l<genstr.n; l++){
			i = genstr.s[l];
			if(utfrune(".*+?(|)\\[]^$", i)){
				str = tmpcstr("\\");
				Strinsert(&genstr, str, l++);
				freetmpstr(str);
			}
		}
		Straddc(&genstr, '\0');
		nextmatch(f, &genstr, p1, 1);
		moveto(f, sel.p[0]);
		break;

	case Tsearch:
		termlocked++;
		if(curfile == 0)
			error(Enofile);
		if(lastpat.s[0] == 0)
			panic("Tsearch");
		nextmatch(curfile, &lastpat, curfile->dot.r.p2, 1);
		moveto(curfile, sel.p[0]);
		break;

	case Tsend:
		termlocked++;
		inshort();	/* ignored */
		p0 = inlong();
		p1 = inlong();
		setgenstr(cmd, p0, p1);
		bufreset(&snarfbuf);
		bufinsert(&snarfbuf, (Posn)0, genstr.s, genstr.n);
		outTl(Hsnarflen, genstr.n);
		if(genstr.s[genstr.n-1] != '\n')
			Straddc(&genstr, '\n');
		loginsert(cmd, cmd->b.nc, genstr.s, genstr.n);
		fileupdate(cmd, FALSE, TRUE);
		cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->b.nc;
		telldot(cmd);
		termcommand();
		break;

	case Tdclick:
		f = whichfile(inshort());
		p1 = inlong();
		doubleclick(f, p1);
		f->tdot.p1 = f->tdot.p2 = p1;
		telldot(f);
		outTs(Hunlockfile, f->tag);
		break;

	case Tstartsnarf:
		if (snarfbuf.nc <= 0) {	/* nothing to export */
			outTs(Hsetsnarf, 0);
			break;
		}
		c = 0;
		i = 0;
		m = snarfbuf.nc;
		if(m > SNARFSIZE) {
			m = SNARFSIZE;
			dprint("?warning: snarf buffer truncated\n");
		}
		rp = malloc(m*sizeof(Rune));
		if(rp){
			bufread(&snarfbuf, 0, rp, m);
			c = Strtoc(tmprstr(rp, m));
			free(rp);
			i = strlen(c);
		}
		outTs(Hsetsnarf, i);
		if(c){
			Write(1, c, i);
			free(c);
		} else
			dprint("snarf buffer too long\n");
		break;

	case Tsetsnarf:
		m = inshort();
		if(m > SNARFSIZE)
			error(Etoolong);
		c = malloc(m+1);
		if(c){
			for(i=0; i<m; i++)
				c[i] = rcvchar();
			c[m] = 0;
			str = tmpcstr(c);
			free(c);
			bufreset(&snarfbuf);
			bufinsert(&snarfbuf, (Posn)0, str->s, str->n);
			freetmpstr(str);
			outT0(Hunlock);
		}
		break;

	case Tack:
		waitack = 0;
		break;

	case Tplumb:
		f = whichfile(inshort());
		p0 = inlong();
		p1 = inlong();
		pm = emalloc(sizeof(Plumbmsg));
		pm->src = strdup("sam");
		pm->dst = 0;
		/* construct current directory */
		c = Strtoc(&f->name);
		if(c[0] == '/')
			pm->wdir = c;
		else{
			wdir = emalloc(1024);
			getwd(wdir, 1024);
			pm->wdir = emalloc(1024);
			snprint(pm->wdir, 1024, "%s/%s", wdir, c);
			cleanname(pm->wdir);
			free(wdir);
			free(c);
		}
		c = strrchr(pm->wdir, '/');
		if(c)
			*c = '\0';
		pm->type = strdup("text");
		if(p1 > p0)
			pm->attr = nil;
		else{
			p = p0;
			while(p0>0 && (i=filereadc(f, p0 - 1))!=' ' && i!='\t' && i!='\n')
				p0--;
			while(p1<f->b.nc && (i=filereadc(f, p1))!=' ' && i!='\t' && i!='\n')
				p1++;
			sprint(cbuf, "click=%ld", p-p0);
			pm->attr = plumbunpackattr(cbuf);
		}
		if(p0==p1 || p1-p0>=BLOCKSIZE){
			plumbfree(pm);
			break;
		}
		setgenstr(f, p0, p1);
		pm->data = Strtoc(&genstr);
		pm->ndata = strlen(pm->data);
		c = plumbpack(pm, &i);
		if(c != 0){
			outTs(Hplumb, i);
			Write(1, c, i);
			free(c);
		}
		plumbfree(pm);
		break;

	case Texit:
		exits(0);
	}
	return TRUE;
}
Beispiel #3
0
void
threadmain(int argc, char *argv[])
{
	char buf[1024], *p;
	int fd, i, input;

	input = 0;
	m.src = "plumb";
	m.dst = nil;
	m.wdir = getwd(buf, sizeof buf);
	m.type = "text";
	m.attr = nil;
	ARGBEGIN{
	case '9':
		chatty9pclient = 1;
		break;
	case 'a':
		p = ARGF();
		if(p == nil)
			usage();
		m.attr = plumbaddattr(m.attr, plumbunpackattr(p));
		break;
	case 'd':
		m.dst = ARGF();
		if(m.dst == nil)
			usage();
		break;
	case 'i':
		input++;
		break;
	case 't':
	case 'k':	/* for backwards compatibility */
		m.type = ARGF();
		if(m.type == nil)
			usage();
		break;
	case 'p':
		plumbfile = ARGF();
		if(plumbfile == nil)
			usage();
		break;
	case 's':
		m.src = ARGF();
		if(m.src == nil)
			usage();
		break;
	case 'w':
		m.wdir = ARGF();
		if(m.wdir == nil)
			usage();
		break;
	}ARGEND

	if((input && argc>0) || (!input && argc<1))
		usage();
	if(plumbfile != nil)
		fd = open(plumbfile, OWRITE);
	else
		fd = plumbopen("send", OWRITE);
	if(fd < 0){
		fprint(2, "plumb: can't open plumb file: %r\n");
		threadexitsall("open");
	}
	if(input){
		gather();
		if(plumblookup(m.attr, "action") == nil)
			m.attr = plumbaddattr(m.attr, plumbunpackattr("action=showdata"));
		if(plumbsend(fd, &m) < 0){
			fprint(2, "plumb: can't send message: %r\n");
			threadexitsall("error");
		}
		threadexitsall(nil);
	}
	for(i=0; i<argc; i++){
		if(input == 0){
			m.data = argv[i];
			m.ndata = -1;
		}
		if(plumbsend(fd, &m) < 0){
			fprint(2, "plumb: can't send message: %r\n");
			threadexitsall("error");
		}
	}
	threadexitsall(nil);
}
Beispiel #4
0
void
look3(Text *t, uint q0, uint q1, int external)
{
	int n, c, f, expanded;
	Text *ct;
	Expand e;
	Rune *r;
	uint p;
	Plumbmsg *m;
	Runestr dir;
	char buf[32];

	ct = seltext;
	if(ct == nil)
		seltext = t;
	expanded = expand(t, q0, q1, &e);
	if(!external && t->w!=nil && t->w->nopen[QWevent]>0){
		/* send alphanumeric expansion to external client */
		if(expanded == FALSE)
			return;
		f = 0;
		if((e.u.at!=nil && t->w!=nil) || (e.nname>0 && lookfile(e.name, e.nname)!=nil))
			f = 1;		/* acme can do it without loading a file */
		if(q0!=e.q0 || q1!=e.q1)
			f |= 2;	/* second (post-expand) message follows */
		if(e.nname)
			f |= 4;	/* it's a file name */
		c = 'l';
		if(t->what == Body)
			c = 'L';
		n = q1-q0;
		if(n <= EVENTSIZE){
			r = runemalloc(n);
			bufread(&t->file->b, q0, r, n);
			winevent(t->w, "%c%d %d %d %d %.*S\n", c, q0, q1, f, n, n, r);
			free(r);
		}else
			winevent(t->w, "%c%d %d %d 0 \n", c, q0, q1, f, n);
		if(q0==e.q0 && q1==e.q1)
			return;
		if(e.nname){
			n = e.nname;
			if(e.a1 > e.a0)
				n += 1+(e.a1-e.a0);
			r = runemalloc(n);
			runemove(r, e.name, e.nname);
			if(e.a1 > e.a0){
				r[e.nname] = ':';
				bufread(&e.u.at->file->b, e.a0, r+e.nname+1, e.a1-e.a0);
			}
		}else{
			n = e.q1 - e.q0;
			r = runemalloc(n);
			bufread(&t->file->b, e.q0, r, n);
		}
		f &= ~2;
		if(n <= EVENTSIZE)
			winevent(t->w, "%c%d %d %d %d %.*S\n", c, e.q0, e.q1, f, n, n, r);
		else
			winevent(t->w, "%c%d %d %d 0 \n", c, e.q0, e.q1, f, n);
		free(r);
		goto Return;
	}
	if(plumbsendfid != nil){
		/* send whitespace-delimited word to plumber */
		m = emalloc(sizeof(Plumbmsg));
		m->src = estrdup("acme");
		m->dst = nil;
		dir = dirname(t, nil, 0);
		if(dir.nr==1 && dir.r[0]=='.'){	/* sigh */
			free(dir.r);
			dir.r = nil;
			dir.nr = 0;
		}
		if(dir.nr == 0)
			m->wdir = estrdup(wdir);
		else
			m->wdir = runetobyte(dir.r, dir.nr);
		free(dir.r);
		m->type = estrdup("text");
		m->attr = nil;
		buf[0] = '\0';
		if(q1 == q0){
			if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){
				q0 = t->q0;
				q1 = t->q1;
			}else{
				p = q0;
				while(q0>0 && (c=tgetc(t, q0-1))!=' ' && c!='\t' && c!='\n')
					q0--;
				while(q1<t->file->b.nc && (c=tgetc(t, q1))!=' ' && c!='\t' && c!='\n')
					q1++;
				if(q1 == q0){
					plumbfree(m);
					goto Return;
				}
				sprint(buf, "click=%d", p-q0);
				m->attr = plumbunpackattr(buf);
			}
		}
		r = runemalloc(q1-q0);
		bufread(&t->file->b, q0, r, q1-q0);
		m->data = runetobyte(r, q1-q0);
		m->ndata = strlen(m->data);
		free(r);
		if(m->ndata<messagesize-1024 && plumbsendtofid(plumbsendfid, m) >= 0){
			plumbfree(m);
			goto Return;
		}
		plumbfree(m);
		/* plumber failed to match; fall through */
	}

	/* interpret alphanumeric string ourselves */
	if(expanded == FALSE)
		return;
	if(e.name || e.u.at)
		openfile(t, &e);
	else{
		if(t->w == nil)
			return;
		ct = &t->w->body;
		if(t->w != ct->w)
			winlock(ct->w, 'M');
		if(t == ct)
			textsetselect(ct, e.q1, e.q1);
		n = e.q1 - e.q0;
		r = runemalloc(n);
		bufread(&t->file->b, e.q0, r, n);
		if(search(ct, r, n) && e.jump)
			moveto(mousectl, addpt(frptofchar(&ct->fr, ct->fr.p0), Pt(4, ct->fr.font->height-4)));
		if(t->w != ct->w)
			winunlock(ct->w);
		free(r);
	}

   Return:
	free(e.name);
	free(e.bname);
}