xref: /plan9/acme/bin/source/adict/adict.c (revision 1fa40b8e14c9d7f57c6217ec3d34b78924e14594)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <bio.h>
49a747e4fSDavid du Colombier #include <thread.h>
59a747e4fSDavid du Colombier #include "win.h"
69a747e4fSDavid du Colombier #include "adict.h"
79a747e4fSDavid du Colombier 
8*1fa40b8eSDavid du Colombier enum
9*1fa40b8eSDavid du Colombier {
10*1fa40b8eSDavid du Colombier 	STACK = 8192,
11*1fa40b8eSDavid du Colombier };
12*1fa40b8eSDavid du Colombier 
139a747e4fSDavid du Colombier char *prog = "adict";
149a747e4fSDavid du Colombier char *lprog = "/bin/adict";
159a747e4fSDavid du Colombier char *xprog  = "/bin/dict";
169a747e4fSDavid du Colombier char *dict, *pattern, *curaddr[MAXMATCH], *curone, *args[6], buffer[80];
179a747e4fSDavid du Colombier char abuffer[80], fbuffer[80], pbuffer[80];
189a747e4fSDavid du Colombier int curindex, count, Eopen, Mopen;
199a747e4fSDavid du Colombier Win Mwin, Ewin, Dwin;
209a747e4fSDavid du Colombier 
219a747e4fSDavid du Colombier void openwin(char*, char*, Win*, int);
229a747e4fSDavid du Colombier void  handle(Win*, int);
239a747e4fSDavid du Colombier void	rexec(void*);
249a747e4fSDavid du Colombier void	pexec(void*);
259a747e4fSDavid du Colombier int getaddr(char*);
269a747e4fSDavid du Colombier 
279a747e4fSDavid du Colombier void
usage(void)289a747e4fSDavid du Colombier usage(void)
299a747e4fSDavid du Colombier {
30*1fa40b8eSDavid du Colombier 		fprint(2, "usage: %s [-d dictname] [pattern]\n", argv0);
319a747e4fSDavid du Colombier 		threadexitsall(nil);
329a747e4fSDavid du Colombier }
339a747e4fSDavid du Colombier 
34*1fa40b8eSDavid du Colombier int mainstacksize = STACK;
35*1fa40b8eSDavid du Colombier 
369a747e4fSDavid du Colombier void
threadmain(int argc,char ** argv)379a747e4fSDavid du Colombier threadmain(int argc, char** argv)
389a747e4fSDavid du Colombier {
399a747e4fSDavid du Colombier 	ARGBEGIN{
409a747e4fSDavid du Colombier 	case 'd':
419a747e4fSDavid du Colombier 		dict = strdup(ARGF());
429a747e4fSDavid du Colombier 		break;
439a747e4fSDavid du Colombier 	default:
449a747e4fSDavid du Colombier 		usage();
459a747e4fSDavid du Colombier 	}ARGEND
469a747e4fSDavid du Colombier 
479a747e4fSDavid du Colombier 	/* if running as other name, note that fact */
489a747e4fSDavid du Colombier 	if(access(argv0, AEXIST) == 0)
499a747e4fSDavid du Colombier 		lprog = argv0;
509a747e4fSDavid du Colombier 
519a747e4fSDavid du Colombier 	switch(argc){
529a747e4fSDavid du Colombier 	case 1:
539a747e4fSDavid du Colombier 		pattern = pbuffer;
549a747e4fSDavid du Colombier 		strcpy(pattern,argv[0]);
559a747e4fSDavid du Colombier 		if(dict == nil)
56*1fa40b8eSDavid du Colombier 			dict = "pgw";
579a747e4fSDavid du Colombier 		break;
589a747e4fSDavid du Colombier 	case 0:
599a747e4fSDavid du Colombier 		break;
609a747e4fSDavid du Colombier 	default:
619a747e4fSDavid du Colombier 		usage();
629a747e4fSDavid du Colombier 	}
639a747e4fSDavid du Colombier 
649a747e4fSDavid du Colombier 	if ((dict == nil) && (pattern == nil))
659a747e4fSDavid du Colombier 		openwin(prog,"", &Dwin, Dictwin);
669a747e4fSDavid du Colombier 	if (pattern == nil)
679a747e4fSDavid du Colombier 		openwin(prog,"",&Ewin, Entrywin);
689a747e4fSDavid du Colombier 	if ((count = getaddr(pattern)) <= 1)
699a747e4fSDavid du Colombier 		openwin(prog,"Prev Next", &Ewin, Entrywin);
709a747e4fSDavid du Colombier 	else
719a747e4fSDavid du Colombier 		openwin(prog, "", &Mwin, Matchwin);
729a747e4fSDavid du Colombier }
739a747e4fSDavid du Colombier 
749a747e4fSDavid du Colombier static int
procrexec(char * xprog,...)759a747e4fSDavid du Colombier procrexec(char *xprog, ...)
769a747e4fSDavid du Colombier {
779a747e4fSDavid du Colombier 	int fpipe[2];
789a747e4fSDavid du Colombier 	void *rexarg[4];
799a747e4fSDavid du Colombier 	Channel *c;
809a747e4fSDavid du Colombier 	va_list va;
819a747e4fSDavid du Colombier 	int i;
829a747e4fSDavid du Colombier 	char *p;
839a747e4fSDavid du Colombier 
849a747e4fSDavid du Colombier 	pipe(fpipe);
859a747e4fSDavid du Colombier 	va_start(va, xprog);
869a747e4fSDavid du Colombier 	p = xprog;
879a747e4fSDavid du Colombier 	for(i=0; p && i+1<nelem(args); i++){
889a747e4fSDavid du Colombier 		args[i] = p;
899a747e4fSDavid du Colombier 		p = va_arg(va, char*);
909a747e4fSDavid du Colombier 	}
919a747e4fSDavid du Colombier 	args[i] = nil;
929a747e4fSDavid du Colombier 
939a747e4fSDavid du Colombier 	c = chancreate(sizeof(ulong), 0);
949a747e4fSDavid du Colombier 	rexarg[0] = xprog;
959a747e4fSDavid du Colombier 	rexarg[1] = args;
969a747e4fSDavid du Colombier 	rexarg[2] = fpipe;
979a747e4fSDavid du Colombier 	rexarg[3] = c;
989a747e4fSDavid du Colombier 
99*1fa40b8eSDavid du Colombier 	proccreate(rexec, rexarg, STACK);
1009a747e4fSDavid du Colombier 	recvul(c);
1019a747e4fSDavid du Colombier 	chanfree(c);
1029a747e4fSDavid du Colombier 	close(fpipe[1]);
1039a747e4fSDavid du Colombier 	return fpipe[0];
1049a747e4fSDavid du Colombier }
1059a747e4fSDavid du Colombier 
1069a747e4fSDavid du Colombier int
getaddr(char * pattern)1079a747e4fSDavid du Colombier getaddr(char *pattern)
1089a747e4fSDavid du Colombier {
1099a747e4fSDavid du Colombier 	/* Get char offset into dictionary of matches. */
1109a747e4fSDavid du Colombier 
1119a747e4fSDavid du Colombier 	int fd, i;
1129a747e4fSDavid du Colombier 	Biobuf inbuf;
1139a747e4fSDavid du Colombier 	char *bufptr;
1149a747e4fSDavid du Colombier char *obuf;
1159a747e4fSDavid du Colombier 
1169a747e4fSDavid du Colombier 	if (pattern == nil) {
1179a747e4fSDavid du Colombier 		curone = nil;
1189a747e4fSDavid du Colombier 		curindex = 0;
1199a747e4fSDavid du Colombier 		curaddr[curindex] = nil;
1209a747e4fSDavid du Colombier 		return 0;
1219a747e4fSDavid du Colombier 	}
1229a747e4fSDavid du Colombier 
1239a747e4fSDavid du Colombier 	sprint(buffer,"/%s/A", pattern);
1249a747e4fSDavid du Colombier 	fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
1259a747e4fSDavid du Colombier 	Binit(&inbuf, fd, OREAD);
1269a747e4fSDavid du Colombier 	i = 0;
1279a747e4fSDavid du Colombier 	curindex = 0;
1289a747e4fSDavid du Colombier 	while ((bufptr = Brdline(&inbuf, '\n')) != nil && (i < (MAXMATCH-1))) {
1299a747e4fSDavid du Colombier 		bufptr[Blinelen(&inbuf)-1] = 0;
1309a747e4fSDavid du Colombier obuf=bufptr;
1319a747e4fSDavid du Colombier 		while (bufptr[0] != '#' && bufptr[0] != 0) bufptr++;
1329a747e4fSDavid du Colombier if(bufptr[0] == 0)
1339a747e4fSDavid du Colombier 	print("whoops buf «%s»\n", obuf);
1349a747e4fSDavid du Colombier 		curaddr[i] = malloc(strlen(bufptr));
1359a747e4fSDavid du Colombier 		strcpy(curaddr[i], bufptr);
1369a747e4fSDavid du Colombier 		i++;
1379a747e4fSDavid du Colombier 	}
1389a747e4fSDavid du Colombier 	curaddr[i] = nil;
1399a747e4fSDavid du Colombier 	if (i == MAXMATCH)
140*1fa40b8eSDavid du Colombier 		fprint(2, "Too many matches!\n");
1419a747e4fSDavid du Colombier 	Bterm(&inbuf);
1429a747e4fSDavid du Colombier 	close(fd);
1439a747e4fSDavid du Colombier 
1449a747e4fSDavid du Colombier 	curone = curaddr[curindex];
1459a747e4fSDavid du Colombier 	return(i);
1469a747e4fSDavid du Colombier }
1479a747e4fSDavid du Colombier 
1489a747e4fSDavid du Colombier char*
getpattern(char * addr)1499a747e4fSDavid du Colombier getpattern(char *addr)
1509a747e4fSDavid du Colombier {
1519a747e4fSDavid du Colombier 	/* Get the pattern corresponding to an absolute address.*/
1529a747e4fSDavid du Colombier 	int fd;
1539a747e4fSDavid du Colombier 	char *res, *t;
1549a747e4fSDavid du Colombier 
1559a747e4fSDavid du Colombier 	res = nil;
1569a747e4fSDavid du Colombier 	sprint(buffer,"%sh", addr);
1579a747e4fSDavid du Colombier 	fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
1589a747e4fSDavid du Colombier 	if (read(fd, pbuffer, 80) > 80)
159*1fa40b8eSDavid du Colombier 		fprint(2, "Error in getting addres from dict.\n");
1609a747e4fSDavid du Colombier 	else {
1619a747e4fSDavid du Colombier 		t = pbuffer;
1629a747e4fSDavid du Colombier 		/* remove trailing whitespace, newline */
1639a747e4fSDavid du Colombier 		if (t != nil){
1649a747e4fSDavid du Colombier 			while(*t != 0 && *t != '\n')
1659a747e4fSDavid du Colombier 				t++;
1669a747e4fSDavid du Colombier 			if(t == 0 && t > pbuffer)
1679a747e4fSDavid du Colombier 				t--;
1689a747e4fSDavid du Colombier 			while(t >= pbuffer && (*t==' ' || *t=='\n' || *t=='\t' || *t=='\r'))
1699a747e4fSDavid du Colombier 				*t-- = 0;
1709a747e4fSDavid du Colombier 		}
1719a747e4fSDavid du Colombier 		res = pbuffer;
1729a747e4fSDavid du Colombier 	}
1739a747e4fSDavid du Colombier 	close(fd);
1749a747e4fSDavid du Colombier 	return(res);
1759a747e4fSDavid du Colombier }
1769a747e4fSDavid du Colombier 
1779a747e4fSDavid du Colombier char*
chgaddr(int dir)1789a747e4fSDavid du Colombier chgaddr(int dir)
1799a747e4fSDavid du Colombier {
1809a747e4fSDavid du Colombier 	/* Increment or decrement the current address (curone). */
1819a747e4fSDavid du Colombier 
1829a747e4fSDavid du Colombier 	int fd;
1839a747e4fSDavid du Colombier 	char *res, *t;
1849a747e4fSDavid du Colombier 
1859a747e4fSDavid du Colombier 	res = nil;
1869a747e4fSDavid du Colombier 	if (dir < 0)
1879a747e4fSDavid du Colombier 		sprint(buffer,"%s-a", curone);
1889a747e4fSDavid du Colombier 	else
1899a747e4fSDavid du Colombier 		sprint(buffer,"%s+a", curone);
1909a747e4fSDavid du Colombier 	fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
1919a747e4fSDavid du Colombier 	if (read(fd, abuffer, 80) > 80)
192*1fa40b8eSDavid du Colombier 		fprint(2, "Error in getting addres from dict.\n");
1939a747e4fSDavid du Colombier 	else {
1949a747e4fSDavid du Colombier 		res = abuffer;
1959a747e4fSDavid du Colombier 		while (*res != '#') res++;
1969a747e4fSDavid du Colombier 		t = res;
1979a747e4fSDavid du Colombier 		while ((*t != '\n') && (t != nil)) t++;
1989a747e4fSDavid du Colombier 		if (t != nil) *t = 0;
1999a747e4fSDavid du Colombier 	}
2009a747e4fSDavid du Colombier 	close(fd);
2019a747e4fSDavid du Colombier 	return(res);
2029a747e4fSDavid du Colombier }
2039a747e4fSDavid du Colombier 
2049a747e4fSDavid du Colombier void
dispdicts(Win * cwin)2059a747e4fSDavid du Colombier dispdicts(Win *cwin)
2069a747e4fSDavid du Colombier {
2079a747e4fSDavid du Colombier 	/* Display available dictionaries in window. */
2089a747e4fSDavid du Colombier 
2099a747e4fSDavid du Colombier 	int fd, nb, i;
2109a747e4fSDavid du Colombier 	char buf[1024], *t;
2119a747e4fSDavid du Colombier 
2129a747e4fSDavid du Colombier 	fd = procrexec(xprog, "-d", "?", nil);
2139a747e4fSDavid du Colombier 	wreplace(cwin, "0,$","",0);	/* Clear window */
2149a747e4fSDavid du Colombier 	while ((nb = read(fd, buf, 1024)) > 0) {
2159a747e4fSDavid du Colombier 		t = buf;
2169a747e4fSDavid du Colombier 		i = 0;
2179a747e4fSDavid du Colombier 		if (strncmp("Usage", buf, 5) == 0) {	/* Remove first line. */
2189a747e4fSDavid du Colombier 			while (t[0] != '\n') {
2199a747e4fSDavid du Colombier 				t++;
2209a747e4fSDavid du Colombier 				i++;
2219a747e4fSDavid du Colombier 			}
2229a747e4fSDavid du Colombier 			t++;
2239a747e4fSDavid du Colombier 			i++;
2249a747e4fSDavid du Colombier 		}
2259a747e4fSDavid du Colombier 		wwritebody(cwin, t, nb-i);
2269a747e4fSDavid du Colombier 	}
2279a747e4fSDavid du Colombier 	close(fd);
2289a747e4fSDavid du Colombier 	wclean(cwin);
2299a747e4fSDavid du Colombier }
2309a747e4fSDavid du Colombier 
2319a747e4fSDavid du Colombier void
dispentry(Win * cwin)2329a747e4fSDavid du Colombier dispentry(Win *cwin)
2339a747e4fSDavid du Colombier {
2349a747e4fSDavid du Colombier 	/* Display the current selection in window. */
2359a747e4fSDavid du Colombier 
2369a747e4fSDavid du Colombier 	int fd, nb;
2379a747e4fSDavid du Colombier 	char buf[BUFSIZE];
2389a747e4fSDavid du Colombier 
2399a747e4fSDavid du Colombier 	if (curone == nil) {
2409a747e4fSDavid du Colombier 		if (pattern != nil) {
2419a747e4fSDavid du Colombier 			sprint(buf,"Pattern not found.\n");
2429a747e4fSDavid du Colombier 			wwritebody(cwin, buf, 19);
2439a747e4fSDavid du Colombier 			wclean(cwin);
2449a747e4fSDavid du Colombier 		}
2459a747e4fSDavid du Colombier 		return;
2469a747e4fSDavid du Colombier 	}
2479a747e4fSDavid du Colombier 	sprint(buffer,"%sp", curone);
2489a747e4fSDavid du Colombier 	fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
2499a747e4fSDavid du Colombier 	wreplace(cwin, "0,$","",0);	/* Clear window */
2509a747e4fSDavid du Colombier 	while ((nb = read(fd, buf, BUFSIZE)) > 0) {
2519a747e4fSDavid du Colombier 		wwritebody(cwin, buf, nb);
2529a747e4fSDavid du Colombier 	}
2539a747e4fSDavid du Colombier 	close(fd);
2549a747e4fSDavid du Colombier 	wclean(cwin);
2559a747e4fSDavid du Colombier }
2569a747e4fSDavid du Colombier 
2579a747e4fSDavid du Colombier void
dispmatches(Win * cwin)2589a747e4fSDavid du Colombier dispmatches(Win *cwin)
2599a747e4fSDavid du Colombier {
2609a747e4fSDavid du Colombier 	/* Display the current matches. */
2619a747e4fSDavid du Colombier 
2629a747e4fSDavid du Colombier 	int fd, nb;
2639a747e4fSDavid du Colombier 	char buf[BUFSIZE];
2649a747e4fSDavid du Colombier 
2659a747e4fSDavid du Colombier 	sprint(buffer,"/%s/H", pattern);
2669a747e4fSDavid du Colombier 	fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
2679a747e4fSDavid du Colombier 	while ((nb = read(fd, buf, BUFSIZE)) > 0)
2689a747e4fSDavid du Colombier 		wwritebody(cwin, buf, nb);
2699a747e4fSDavid du Colombier 	close(fd);
2709a747e4fSDavid du Colombier 	wclean(cwin);
2719a747e4fSDavid du Colombier }
2729a747e4fSDavid du Colombier 
2739a747e4fSDavid du Colombier char*
format(char * s)2749a747e4fSDavid du Colombier format(char *s)
2759a747e4fSDavid du Colombier {
2769a747e4fSDavid du Colombier 	/* Format a string to be written in window tag.  Acme doesn't like */
2779a747e4fSDavid du Colombier 	/* non alpha-num's in the tag line. */
2789a747e4fSDavid du Colombier 
2799a747e4fSDavid du Colombier 	char *t, *h;
2809a747e4fSDavid du Colombier 
2819a747e4fSDavid du Colombier 	t = fbuffer;
2829a747e4fSDavid du Colombier 	if (s == nil) {
2839a747e4fSDavid du Colombier 		*t = 0;
2849a747e4fSDavid du Colombier 		return t;
2859a747e4fSDavid du Colombier 	}
2869a747e4fSDavid du Colombier 	strcpy(t, s);
2879a747e4fSDavid du Colombier 	h = t;
2889a747e4fSDavid du Colombier 	while (*t != 0) {
2899a747e4fSDavid du Colombier 		if (!(((*t >= 'a') && (*t <= 'z')) ||
2909a747e4fSDavid du Colombier 		    ((*t >= 'A') && (*t <= 'Z')) ||
2919a747e4fSDavid du Colombier 		    ((*t >= '0') && (*t <= '9'))))
2929a747e4fSDavid du Colombier 			*t = '_';
2939a747e4fSDavid du Colombier 		t++;
2949a747e4fSDavid du Colombier 	}
2959a747e4fSDavid du Colombier 	if (strlen(h) > MAXTAG)
2969a747e4fSDavid du Colombier 		h[MAXTAG] = 0;
2979a747e4fSDavid du Colombier 	if (strcmp(s,h) == 0) return s;
2989a747e4fSDavid du Colombier 	return h;
2999a747e4fSDavid du Colombier }
3009a747e4fSDavid du Colombier 
3019a747e4fSDavid du Colombier void
openwin(char * name,char * buttons,Win * twin,int wintype)3029a747e4fSDavid du Colombier openwin(char *name, char *buttons, Win *twin, int wintype)
3039a747e4fSDavid du Colombier {
3049a747e4fSDavid du Colombier 	char buf[80];
3059a747e4fSDavid du Colombier 
3069a747e4fSDavid du Colombier 	wnew(twin);
3079a747e4fSDavid du Colombier 	if (wintype == Dictwin)
3089a747e4fSDavid du Colombier 		sprint(buf,"%s",name);
3099a747e4fSDavid du Colombier 	else
3109a747e4fSDavid du Colombier 		if ((wintype == Entrywin) && (count > 1))
3119a747e4fSDavid du Colombier 			sprint(buf,"%s/%s/%s/%d",name, dict, format(pattern), curindex+1);
3129a747e4fSDavid du Colombier 		else
3139a747e4fSDavid du Colombier 			sprint(buf,"%s/%s/%s",name, dict, format(pattern));
3149a747e4fSDavid du Colombier 	wname(twin, buf);
3159a747e4fSDavid du Colombier 	wtagwrite(twin, buttons, strlen(buttons));
3169a747e4fSDavid du Colombier 	wclean(twin);
3179a747e4fSDavid du Colombier 	wdormant(twin);
3189a747e4fSDavid du Colombier 	if (wintype == Dictwin)
3199a747e4fSDavid du Colombier 		dispdicts(twin);
3209a747e4fSDavid du Colombier 	if (wintype == Matchwin) {
3219a747e4fSDavid du Colombier 		Mopen = True;
3229a747e4fSDavid du Colombier 		dispmatches(twin);
3239a747e4fSDavid du Colombier 	}
3249a747e4fSDavid du Colombier 	if (wintype == Entrywin) {
3259a747e4fSDavid du Colombier 		Eopen = True;
3269a747e4fSDavid du Colombier 		dispentry(twin);
3279a747e4fSDavid du Colombier 	}
3289a747e4fSDavid du Colombier 	handle(twin, wintype);
3299a747e4fSDavid du Colombier }
3309a747e4fSDavid du Colombier 
3319a747e4fSDavid du Colombier void
vopenwin(void * v)3329a747e4fSDavid du Colombier vopenwin(void *v)
3339a747e4fSDavid du Colombier {
3349a747e4fSDavid du Colombier 	void **arg;
3359a747e4fSDavid du Colombier 	char *name, *buttons;
3369a747e4fSDavid du Colombier 	Win *twin;
3379a747e4fSDavid du Colombier 	int wintype;
3389a747e4fSDavid du Colombier 
3399a747e4fSDavid du Colombier 	arg = v;
3409a747e4fSDavid du Colombier 	name = arg[0];
3419a747e4fSDavid du Colombier 	buttons = arg[1];
3429a747e4fSDavid du Colombier 	twin = arg[2];
3439a747e4fSDavid du Colombier 	wintype = (int)arg[3];
3449a747e4fSDavid du Colombier 	sendul(arg[4], 0);
3459a747e4fSDavid du Colombier 
3469a747e4fSDavid du Colombier 	openwin(name, buttons, twin, wintype);
3479a747e4fSDavid du Colombier 	threadexits(nil);
3489a747e4fSDavid du Colombier }
3499a747e4fSDavid du Colombier 
3509a747e4fSDavid du Colombier void
procopenwin(char * name,char * buttons,Win * twin,int wintype)3519a747e4fSDavid du Colombier procopenwin(char *name, char *buttons, Win *twin, int wintype)
3529a747e4fSDavid du Colombier {
3539a747e4fSDavid du Colombier 	void *arg[5];
3549a747e4fSDavid du Colombier 	Channel *c;
3559a747e4fSDavid du Colombier 
3569a747e4fSDavid du Colombier 	c = chancreate(sizeof(ulong), 0);
3579a747e4fSDavid du Colombier 	arg[0] = name;
3589a747e4fSDavid du Colombier 	arg[1] = buttons;
3599a747e4fSDavid du Colombier 	arg[2] = twin;
3609a747e4fSDavid du Colombier 	arg[3] = (void*)wintype;
3619a747e4fSDavid du Colombier 	arg[4] = c;
362*1fa40b8eSDavid du Colombier 	proccreate(vopenwin, arg, STACK);
3639a747e4fSDavid du Colombier 	recvul(c);
3649a747e4fSDavid du Colombier 	chanfree(c);
3659a747e4fSDavid du Colombier }
3669a747e4fSDavid du Colombier 
3679a747e4fSDavid du Colombier void
rexec(void * v)3689a747e4fSDavid du Colombier rexec(void *v)
3699a747e4fSDavid du Colombier {
3709a747e4fSDavid du Colombier 	void **arg;
3719a747e4fSDavid du Colombier 	char *prog;
3729a747e4fSDavid du Colombier 	char **args;
3739a747e4fSDavid du Colombier 	int *fd;
3749a747e4fSDavid du Colombier 	Channel *c;
3759a747e4fSDavid du Colombier 
3769a747e4fSDavid du Colombier 	arg = v;
3779a747e4fSDavid du Colombier 	prog = arg[0];
3789a747e4fSDavid du Colombier 	args = arg[1];
3799a747e4fSDavid du Colombier 	fd = arg[2];
3809a747e4fSDavid du Colombier 	c = arg[3];
3819a747e4fSDavid du Colombier 
3829a747e4fSDavid du Colombier 	rfork(RFENVG|RFFDG);
3839a747e4fSDavid du Colombier 	dup(fd[1], 1);
3849a747e4fSDavid du Colombier 	close(fd[1]);
3859a747e4fSDavid du Colombier 	close(fd[0]);
3869a747e4fSDavid du Colombier 	procexec(c, prog, args);
387*1fa40b8eSDavid du Colombier 	fprint(2, "Remote pipe execution failed: %s %r\n", prog);
3889a747e4fSDavid du Colombier abort();
3899a747e4fSDavid du Colombier 	threadexits(nil);
3909a747e4fSDavid du Colombier }
3919a747e4fSDavid du Colombier 
3929a747e4fSDavid du Colombier void
pexec(void * v)3939a747e4fSDavid du Colombier pexec(void *v)
3949a747e4fSDavid du Colombier {
3959a747e4fSDavid du Colombier 	void **arg;
3969a747e4fSDavid du Colombier 	char *prog;
3979a747e4fSDavid du Colombier 	char **args;
3989a747e4fSDavid du Colombier 	Channel *c;
3999a747e4fSDavid du Colombier 
4009a747e4fSDavid du Colombier 	arg = v;
4019a747e4fSDavid du Colombier 	prog = arg[0];
4029a747e4fSDavid du Colombier 	args = arg[1];
4039a747e4fSDavid du Colombier 	c = arg[2];
4049a747e4fSDavid du Colombier 
4059a747e4fSDavid du Colombier 	procexec(c, prog, args);
406*1fa40b8eSDavid du Colombier 	fprint(2, "Remote execution failed: %s %r\n", prog);
4079a747e4fSDavid du Colombier abort();
4089a747e4fSDavid du Colombier 	threadexits(nil);
4099a747e4fSDavid du Colombier }
4109a747e4fSDavid du Colombier 
4119a747e4fSDavid du Colombier void
procpexec(char * prog,char ** args)4129a747e4fSDavid du Colombier procpexec(char *prog, char **args)
4139a747e4fSDavid du Colombier {
4149a747e4fSDavid du Colombier 	void *rexarg[4];
4159a747e4fSDavid du Colombier 	Channel *c;
4169a747e4fSDavid du Colombier 
4179a747e4fSDavid du Colombier 	c = chancreate(sizeof(ulong), 0);
4189a747e4fSDavid du Colombier 	rexarg[0] = prog;
4199a747e4fSDavid du Colombier 	rexarg[1] = args;
4209a747e4fSDavid du Colombier 	rexarg[2] = c;
4219a747e4fSDavid du Colombier 
422*1fa40b8eSDavid du Colombier 	proccreate(pexec, rexarg, STACK);
4239a747e4fSDavid du Colombier 	recvul(c);
4249a747e4fSDavid du Colombier 	chanfree(c);
4259a747e4fSDavid du Colombier }
4269a747e4fSDavid du Colombier 
4279a747e4fSDavid du Colombier void
kill(void)4289a747e4fSDavid du Colombier kill(void)
4299a747e4fSDavid du Colombier {
4309a747e4fSDavid du Colombier 	/* Kill all processes related to this one. */
4319a747e4fSDavid du Colombier 	int fd;
4329a747e4fSDavid du Colombier 
4339a747e4fSDavid du Colombier 	sprint(buffer, "/proc/%d/notepg", getpid());
4349a747e4fSDavid du Colombier 	fd = open(buffer, OWRITE);
4359a747e4fSDavid du Colombier 	rfork(RFNOTEG);
4369a747e4fSDavid du Colombier 	write(fd, "kill", 4);
4379a747e4fSDavid du Colombier }
4389a747e4fSDavid du Colombier 
4399a747e4fSDavid du Colombier int
command(char * com,Win * w,int wintype)4409a747e4fSDavid du Colombier command(char *com, Win *w, int wintype)
4419a747e4fSDavid du Colombier {
4429a747e4fSDavid du Colombier 	char *buf;
4439a747e4fSDavid du Colombier 
4449a747e4fSDavid du Colombier 	if (strncmp(com, "Del", 3) == 0) {
4459a747e4fSDavid du Colombier 		switch(wintype){
4469a747e4fSDavid du Colombier 		case Entrywin:
4479a747e4fSDavid du Colombier 			if (wdel(w)) {
4489a747e4fSDavid du Colombier 				Eopen = False;
4499a747e4fSDavid du Colombier 				threadexits(nil);
4509a747e4fSDavid du Colombier 			}
4519a747e4fSDavid du Colombier 			break;
4529a747e4fSDavid du Colombier 		case Dictwin:
4539a747e4fSDavid du Colombier 			if (wdel(w))
4549a747e4fSDavid du Colombier 				threadexits(nil);
4559a747e4fSDavid du Colombier 			break;
4569a747e4fSDavid du Colombier 		case Matchwin:
4579a747e4fSDavid du Colombier 			kill();
4589a747e4fSDavid du Colombier 			if (Eopen)
4599a747e4fSDavid du Colombier 				if (~wdel(&Ewin))	/* Remove the entry window */
4609a747e4fSDavid du Colombier 					wdel(&Ewin);
4619a747e4fSDavid du Colombier 			if (!wdel(w))
4629a747e4fSDavid du Colombier 				wdel(w);
4639a747e4fSDavid du Colombier 			threadexits(nil);
4649a747e4fSDavid du Colombier 			break;
4659a747e4fSDavid du Colombier 		}
4669a747e4fSDavid du Colombier 		return True;
4679a747e4fSDavid du Colombier 	}
4689a747e4fSDavid du Colombier 	if (strncmp(com, "Next", 4) == 0){
4699a747e4fSDavid du Colombier 		if (curone != nil) {
4709a747e4fSDavid du Colombier 			curone = chgaddr(1);
4719a747e4fSDavid du Colombier 			buf = getpattern(curone);
4729a747e4fSDavid du Colombier 			sprint(buffer,"%s/%s/%s", prog, dict, format(buf));
4739a747e4fSDavid du Colombier 			wname(w, buffer);
4749a747e4fSDavid du Colombier 			dispentry(w);
4759a747e4fSDavid du Colombier 		}
4769a747e4fSDavid du Colombier 		return True;
4779a747e4fSDavid du Colombier 	}
4789a747e4fSDavid du Colombier 	if (strncmp(com, "Prev",4) == 0){
4799a747e4fSDavid du Colombier 		if (curone != nil) {
4809a747e4fSDavid du Colombier 			curone = chgaddr(-1);
4819a747e4fSDavid du Colombier 			buf = getpattern(curone);
4829a747e4fSDavid du Colombier 			sprint(buffer,"%s/%s/%s", prog, dict, format(buf));
4839a747e4fSDavid du Colombier 			wname(w, buffer);
4849a747e4fSDavid du Colombier 			dispentry(w);
4859a747e4fSDavid du Colombier 		}
4869a747e4fSDavid du Colombier 		return True;
4879a747e4fSDavid du Colombier 	}
4889a747e4fSDavid du Colombier 	if (strncmp(com, "Nmatch",6) == 0){
4899a747e4fSDavid du Colombier 		if (curaddr[++curindex] == nil)
4909a747e4fSDavid du Colombier 			curindex = 0;
4919a747e4fSDavid du Colombier 		curone = curaddr[curindex];
4929a747e4fSDavid du Colombier 		if (curone != nil) {
4939a747e4fSDavid du Colombier 			sprint(buffer,"%s/%s/%s/%d",prog,dict,format(pattern),curindex+1);
4949a747e4fSDavid du Colombier 			wname(w, buffer);
4959a747e4fSDavid du Colombier 			dispentry(w);
4969a747e4fSDavid du Colombier 		}
4979a747e4fSDavid du Colombier 		return True;
4989a747e4fSDavid du Colombier 	}
4999a747e4fSDavid du Colombier 	return False;
5009a747e4fSDavid du Colombier }
5019a747e4fSDavid du Colombier 
5029a747e4fSDavid du Colombier void
handle(Win * w,int wintype)5039a747e4fSDavid du Colombier handle(Win *w, int wintype)
5049a747e4fSDavid du Colombier {
5059a747e4fSDavid du Colombier 	Event e, e2, ea, etoss;
5069a747e4fSDavid du Colombier 	char *s, *t, buf[80];
5079a747e4fSDavid du Colombier 	int tmp, na;
5089a747e4fSDavid du Colombier 
5099a747e4fSDavid du Colombier 	while (True) {
5109a747e4fSDavid du Colombier 		wevent(w, &e);
5119a747e4fSDavid du Colombier 		switch(e.c2){
5129a747e4fSDavid du Colombier 		default:
513*1fa40b8eSDavid du Colombier 			/* fprint(2,"unknown message %c%c\n", e.c1, e.c2); */
5149a747e4fSDavid du Colombier 			break;
5159a747e4fSDavid du Colombier 		case 'i':
516*1fa40b8eSDavid du Colombier 			/* fprint(2,"'%s' inserted in tag at %d\n", e.b, e.q0);*/
5179a747e4fSDavid du Colombier 			break;
5189a747e4fSDavid du Colombier 		case 'I':
519*1fa40b8eSDavid du Colombier 			/* fprint(2,"'%s' inserted in body at %d\n", e.b, e.q0);*/
5209a747e4fSDavid du Colombier 			break;
5219a747e4fSDavid du Colombier 		case 'd':
522*1fa40b8eSDavid du Colombier 			/* fprint(2, "'%s' deleted in tag at %d\n", e.b, e.q0);*/
5239a747e4fSDavid du Colombier 			break;
5249a747e4fSDavid du Colombier 		case 'D':
525*1fa40b8eSDavid du Colombier 			/* fprint(2, "'%s' deleted in body at %d\n", e.b, e.q0);*/
5269a747e4fSDavid du Colombier 			break;
5279a747e4fSDavid du Colombier 		case 'x':
5289a747e4fSDavid du Colombier 		case 'X':				/* Execute command. */
5299a747e4fSDavid du Colombier 			if (e.flag & 2)
5309a747e4fSDavid du Colombier 				wevent(w, &e2);
5319a747e4fSDavid du Colombier 			if(e.flag & 8){
5329a747e4fSDavid du Colombier 				wevent(w, &ea);
5339a747e4fSDavid du Colombier 				wevent(w, &etoss);
5349a747e4fSDavid du Colombier 				na = ea.nb;
5359a747e4fSDavid du Colombier 			} else
5369a747e4fSDavid du Colombier 				na = 0;
5379a747e4fSDavid du Colombier 			s = e.b;
5389a747e4fSDavid du Colombier 			if ((e.flag & 2) && e.nb == 0)
5399a747e4fSDavid du Colombier 				s = e2.b;
5409a747e4fSDavid du Colombier 			if(na){
5419a747e4fSDavid du Colombier 				t = malloc(strlen(s)+1+na+1);
5429a747e4fSDavid du Colombier 				snprint(t, strlen(s)+1+na+1, "%s %s", s, ea.b);
5439a747e4fSDavid du Colombier 				s = t;
5449a747e4fSDavid du Colombier 			}
5459a747e4fSDavid du Colombier 			/* if it's a long message, it can't be for us anyway */
5469a747e4fSDavid du Colombier 			if(!command(s, w, wintype))	/* send it back */
5479a747e4fSDavid du Colombier 				wwriteevent(w, &e);
5489a747e4fSDavid du Colombier 			if(na)
5499a747e4fSDavid du Colombier 				free(s);
5509a747e4fSDavid du Colombier 			break;
5519a747e4fSDavid du Colombier 		case 'l':
5529a747e4fSDavid du Colombier 		case 'L':				/* Look for something. */
5539a747e4fSDavid du Colombier 			if (e.flag & 2)
5549a747e4fSDavid du Colombier 				wevent(w, &e);
5559a747e4fSDavid du Colombier 			wclean(w);		/* Set clean bit. */
5569a747e4fSDavid du Colombier 			if (wintype == Dictwin) {
5579a747e4fSDavid du Colombier 				strcpy(buf, e.b);
5589a747e4fSDavid du Colombier 				args[0] = lprog;
5599a747e4fSDavid du Colombier 				args[1] = "-d";
5609a747e4fSDavid du Colombier 				args[2] = buf;
5619a747e4fSDavid du Colombier 				args[3] = nil;
5629a747e4fSDavid du Colombier 				procpexec(lprog, args);	/* New adict with chosen dict. */
5639a747e4fSDavid du Colombier 			}
5649a747e4fSDavid du Colombier 			if (wintype == Entrywin) {
5659a747e4fSDavid du Colombier 				strcpy(buf, e.b);
5669a747e4fSDavid du Colombier 				args[0] = lprog;
5679a747e4fSDavid du Colombier 				args[1] = "-d";
5689a747e4fSDavid du Colombier 				args[2] = dict;
5699a747e4fSDavid du Colombier 				args[3] = buf;
5709a747e4fSDavid du Colombier 				args[4] = nil;
5719a747e4fSDavid du Colombier 				procpexec(lprog, args); /* New adict with chosen pattern. */
5729a747e4fSDavid du Colombier 			}
5739a747e4fSDavid du Colombier 			if (wintype == Matchwin) {
5749a747e4fSDavid du Colombier 				tmp = atoi(e.b) - 1;
5759a747e4fSDavid du Colombier 				if ((tmp >= 0) && (tmp < MAXMATCH) && (curaddr[tmp] != nil)) {
5769a747e4fSDavid du Colombier 					curindex = tmp;
5779a747e4fSDavid du Colombier 					curone = curaddr[curindex];
5789a747e4fSDavid du Colombier 					/* Display selected match. */
5799a747e4fSDavid du Colombier 					if (Eopen) {
5809a747e4fSDavid du Colombier 						sprint(buf,"%s/%s/%s/%d",prog,dict,format(pattern),curindex+1);
5819a747e4fSDavid du Colombier 						wname(&Ewin, buf);
5829a747e4fSDavid du Colombier 						dispentry(&Ewin);
5839a747e4fSDavid du Colombier 					}
5849a747e4fSDavid du Colombier 					else
5859a747e4fSDavid du Colombier 						procopenwin(prog,"Nmatch Prev Next", &Ewin, Entrywin);
5869a747e4fSDavid du Colombier 				}
5879a747e4fSDavid du Colombier 			}
5889a747e4fSDavid du Colombier 			break;
5899a747e4fSDavid du Colombier 		}
5909a747e4fSDavid du Colombier 	}
5919a747e4fSDavid du Colombier }
592