xref: /plan9-contrib/sys/src/cmd/upas/send/gateway.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include "common.h"
2 #include "send.h"
3 
4 #define isspace(c) ((c)==' ' || (c)=='\t' || (c)=='\n')
5 
6 /*
7  *  Translate the last component of the sender address.  If the translation
8  *  yields the same address, replace the sender with its last component.
9  */
10 extern void
11 gateway(message *mp)
12 {
13 	char *base;
14 	dest *dp=0;
15 	static Biobuf *fp;
16 	char *sp;
17 
18 	/* first remove all systems equivalent to us */
19 	for (base = s_to_c(mp->sender); *base;){
20 		sp = strchr(base, '!');
21 		if(sp==0)
22 			break;
23 		*sp = '\0';
24 		if(lookup(base, "lib/equivlist", &fp, 0, 0)==1){
25 			/* found or us, forget this system */
26 			*sp='!';
27 			base=sp+1;
28 		} else {
29 			/* no files or system is not found, and not us */
30 			*sp='!';
31 			break;
32 		}
33 	}
34 
35 	/* punt if this is not a compound address */
36 	sp = strrchr(base, '!');
37 	if (sp==0)
38 		goto rebuild;
39 	sp++;
40 
41 	/* bind the address to a command */
42 	d_insert(&dp, d_new(s_copy(sp)));
43 	dp->authorized = 1;
44 	dp = up_bind(dp, mp, 0);
45 
46 	/* punt if translation did not succeed or resulted in multiple targets */
47 	if (dp==0 || dp->next!=dp || dp->status!=d_pipe)
48 		goto rebuild;
49 
50 	/* punt if the translation didn't result in the original address */
51 	if (strcmp(s_to_c(dp->addr), base)!=0)
52 		goto rebuild;
53 	base=sp;
54 rebuild:
55 	if(base!=s_to_c(mp->sender))
56 		mp->sender = s_copy(base);
57 }
58 
59 static int
60 okfile(char *cp, Biobuf *fp)
61 {
62 	char *buf;
63 	int len;
64 	char *bp;
65 	int c;
66 
67 	len = strlen(cp);
68 
69 	/* one iteration per system name in the file */
70 	while(buf = Brdline(fp, '\n')) {
71 		buf[Blinelen(fp)-1] = '\0';
72 		for(bp=buf; *bp;){
73 			while(isspace(*bp) || *bp==',')
74 				bp++;
75 			if(strncmp(bp, cp, len) == 0) {
76 				c = *(bp+len);
77 				if(isspace(c) || c=='\0' || c==',')
78 					return 1;
79 			}
80 			while(*bp && (!isspace(*bp)) && *bp!=',')
81 				bp++;
82 		}
83 	}
84 
85 	/* didn't find it, prohibit forwarding */
86 	return 0;
87 }
88 
89 /* return 1 if name found in one of the files
90  *	  0 if name not found in one of the files
91  *	  -1 if neither file exists
92  */
93 extern int
94 lookup(char *cp, char *local, Biobuf **lfpp, char *global, Biobuf **gfpp)
95 {
96 	static String *file = 0;
97 
98 	if (local) {
99 		if (file == 0)
100 			file = s_new();
101 		abspath(local, MAILROOT, s_restart(file));
102 		if (*lfpp != 0 || (*lfpp = sysopen(s_to_c(file), "r", 0)) != 0) {
103 			Bseek(*lfpp, (long)0, 0);
104 			if (okfile(cp, *lfpp))
105 				return 1;
106 		} else
107 			local = 0;
108 	}
109 	if (global) {
110 		abspath(global, MAILROOT, s_restart(file));
111 		if (*gfpp != 0 || (*gfpp = sysopen(s_to_c(file), "r", 0)) != 0) {
112 			Bseek(*gfpp, (long)0, 0);
113 			if (okfile(cp, *gfpp))
114 				return 1;
115 		} else
116 			global = 0;
117 	}
118 	return (local || global)? 0 : -1;
119 }
120