xref: /plan9/sys/src/cmd/upas/send/local.c (revision 3ff48bf5ed603850fcd251ddf13025d23d693782)
1 #include "common.h"
2 #include "send.h"
3 
4 static void
mboxfile(dest * dp,String * user,String * path,char * file)5 mboxfile(dest *dp, String *user, String *path, char *file)
6 {
7 	char *cp;
8 
9 	mboxpath(s_to_c(user), s_to_c(dp->addr), path, 0);
10 	cp = strrchr(s_to_c(path), '/');
11 	if(cp)
12 		path->ptr = cp+1;
13 	else
14 		path->ptr = path->base;
15 	s_append(path, file);
16 }
17 
18 /*
19  *  Check forwarding requests
20  */
21 extern dest*
expand_local(dest * dp)22 expand_local(dest *dp)
23 {
24 	Biobuf *fp;
25 	String *file, *line, *s;
26 	dest *rv;
27 	int forwardok;
28 	char *user;
29 
30 	/* short circuit obvious security problems */
31 	if(strstr(s_to_c(dp->addr), "/../")){
32 		dp->status = d_unknown;
33 		return 0;
34 	}
35 
36 	/* isolate user's name if part of a path */
37 	user = strrchr(s_to_c(dp->addr), '!');
38 	if(user)
39 		user++;
40 	else
41 		user = s_to_c(dp->addr);
42 
43 	/* if no replacement string, plug in user's name */
44 	if(dp->repl1 == 0){
45 		dp->repl1 = s_new();
46 		mboxname(user, dp->repl1);
47 	}
48 
49 	s = unescapespecial(s_clone(dp->repl1));
50 
51 	/*
52 	 *  if this is the descendant of a `forward' file, don't
53 	 *  look for a forward.
54 	 */
55 	forwardok = 1;
56 	for(rv = dp->parent; rv; rv = rv->parent)
57 		if(rv->status == d_cat){
58 			forwardok = 0;
59 			break;
60 		}
61 	file = s_new();
62 	if(forwardok){
63 		/*
64 		 *  look for `forward' file for forwarding address(es)
65 		 */
66 		mboxfile(dp, s, file, "forward");
67 		fp = sysopen(s_to_c(file), "r", 0);
68 		if (fp != 0) {
69 			line = s_new();
70 			for(;;){
71 				if(s_read_line(fp, line) == nil)
72 					break;
73 				if(*(line->ptr - 1) != '\n')
74 					break;
75 				if(*(line->ptr - 2) == '\\')
76 					*(line->ptr-2) = ' ';
77 				*(line->ptr-1) = ' ';
78 			}
79 			sysclose(fp);
80 			if(debug)
81 				fprint(2, "forward = %s\n", s_to_c(line));
82 			rv = s_to_dest(s_restart(line), dp);
83 			s_free(line);
84 			if(rv){
85 				s_free(file);
86 				s_free(s);
87 				return rv;
88 			}
89 		}
90 	}
91 
92 	/*
93 	 *  look for a 'pipe' file.  This won't work if there are
94 	 *  special characters in the account name since the file
95 	 *  name passes through a shell.  tdb.
96 	 */
97 	mboxfile(dp, dp->repl1, s_reset(file), "pipeto");
98 	if(sysexist(s_to_c(file))){
99 		if(debug)
100 			fprint(2, "found a pipeto file\n");
101 		dp->status = d_pipeto;
102 		line = s_new();
103 		s_append(line, "upasname='");
104 		s_append(line, user);
105 		s_append(line, "' ");
106 		s_append(line, s_to_c(file));
107 		s_append(line, " ");
108 		s_append(line, s_to_c(dp->addr));
109 		s_append(line, " ");
110 		s_append(line, s_to_c(dp->repl1));
111 		s_free(dp->repl1);
112 		dp->repl1 = line;
113 		s_free(file);
114 		s_free(s);
115 		return dp;
116 	}
117 
118 	/*
119 	 *  see if the mailbox directory exists
120 	 */
121 	mboxfile(dp, s, s_reset(file), ".");
122 	if(sysexist(s_to_c(file)))
123 		dp->status = d_cat;
124 	else
125 		dp->status = d_unknown;
126 	s_free(file);
127 	s_free(s);
128 	return 0;
129 }
130