xref: /plan9-contrib/sys/src/cmd/upas/alias/aliasmail.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include "common.h"
2 
3 /*
4  *  WARNING!  This turns all upper case names into lower case
5  *  local ones.
6  */
7 
8 /* predeclared */
9 static String	*getdbfiles(void);
10 static int	translate(char*, char*, String*, String*);
11 static int	lookup(char*, String*, 	String*, String*);
12 static int	compare(String*, char*);
13 static char*	mklower(char*);
14 
15 static int debug;
16 #define DEBUG if(debug)
17 
18 /* loop through the names to be translated */
19 void
20 main(int argc, char *argv[])
21 {
22 	String *alias;		/* the alias for the name */
23 	char *thissys;		/* name of this system */
24 	String *files;		/* list of files to search */
25 	int i, rv;
26 
27 	ARGBEGIN {
28 	case 'd':
29 		debug = 1;
30 		break;
31 	} ARGEND
32 	if (chdir(MAILROOT) < 0) {
33 		perror("translate(chdir):");
34 		exit(1);
35 	}
36 	if (chdir("lib") < 0) {
37 		perror("translate(chdir):");
38 		exit(1);
39 	}
40 
41 	/* get environmental info */
42 	thissys = sysname_read();
43 	files = getdbfiles();
44 	alias = s_new();
45 
46 	/* loop through the names to be translated (from standard input) */
47 	for(i=0; i<argc; i++) {
48 		mklower(argv[i]);
49 		rv = translate(argv[i], thissys, files, alias);
50 		if (rv < 0 || *s_to_c(alias) == '\0')
51 			print("local!%s\n", argv[i]);
52 		else
53 			print("%s\n", s_to_c(alias));
54 	}
55 	exits(0);
56 }
57 
58 /* get the list of dbfiles to search */
59 static String *
60 getdbfiles(void)
61 {
62 	Biobuf *fp;
63 	String *files = s_new();
64 
65 	/* system wide aliases */
66 	if ((fp = sysopen("namefiles", "r", 0)) != 0){
67 		while(s_getline(fp, files))
68 			s_append(files, " ");
69 		sysclose(fp);
70 	}
71 
72 
73 	DEBUG print("files are %s\n", s_to_c(files));
74 
75 	return files;
76 }
77 
78 /* loop through the translation files */
79 static int
80 translate(char *name,		/* name to translate */
81 	char *thissys,		/* name of this system */
82 	String *files,
83 	String *alias)		/* where to put the alias */
84 {
85 	String *file = s_new();
86 	String *fullname;
87 	char *user;
88 
89 	DEBUG print("translate(%s, %s, %s, %s)\n", name, thissys,
90 		s_to_c(files), s_to_c(alias));
91 
92 	/* create the full name to avoid loops (system!name) */
93 	fullname = s_copy(thissys);
94 	s_append(fullname, "!");
95 	s_append(fullname, name);
96 
97 	/* look at user's local names */
98 	user = getlog();
99 	if (user != 0) {
100 		mboxpath("names", user, s_restart(file), 0);
101 		if (lookup(name, fullname, file, alias)==0) {
102 			s_free(fullname);
103 			s_free(file);
104 			return 0;
105 		}
106 	}
107 
108 	/* look at system-wide names */
109 	s_restart(files);
110 	while (s_parse(files, s_restart(file)) != 0) {
111 		if (lookup(name, fullname, file, alias)==0) {
112 			s_free(fullname);
113 			s_free(file);
114 			return 0;
115 		}
116 	}
117 
118 	return -1;
119 }
120 
121 /*  Loop through the entries in a translation file looking for a match.
122  *  Return 0 if found, -1 otherwise.
123  */
124 static int
125 lookup(	char *name,
126 	String *fullname,
127 	String *file,
128 	String *alias)	/* returned String */
129 {
130 	Biobuf *fp;
131 	String *line = s_new();
132 	String *token = s_new();
133 	int rv = -1;
134 
135 	DEBUG print("lookup(%s, %s, %s, %s)\n", name, s_to_c(fullname),
136 		s_to_c(file), s_to_c(alias));
137 
138 	s_reset(alias);
139 	if ((fp = sysopen(s_to_c(file), "r", 0)) == 0)
140 		return -1;
141 
142 	/* look for a match */
143 	while (s_getline(fp, s_restart(line))!=0) {
144 		DEBUG print("line is %s\n", s_to_c(line));
145 		s_restart(token);
146 		if (s_parse(s_restart(line), token)==0)
147 			continue;
148 		if (compare(token, name)!=0)
149 			continue;
150 		/* match found, get the alias */
151 		while(s_parse(line, s_restart(token))!=0) {
152 			/* avoid definition loops */
153 			if (compare(token, name)==0 ||
154 			    compare(token, s_to_c(fullname))==0){
155 				s_append(alias, "local");
156 				s_append(alias, "!");
157 				s_append(alias, name);
158 			} else {
159 				s_append(alias, s_to_c(token));
160 			}
161 			s_append(alias, " ");
162 		}
163 		rv = 0;
164 		break;
165 	}
166 	s_free(line);
167 	s_free(token);
168 	sysclose(fp);
169 	return rv;
170 }
171 
172 #define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
173 
174 /* compare two Strings (case insensitive) */
175 static int
176 compare(String *s1,
177 	char *p2)
178 {
179 	char *p1 = s_to_c(s1);
180 	int rv;
181 
182 	DEBUG print("comparing %s to %s\n", p1, p2);
183 	while((rv = lower(*p1) - lower(*p2)) == 0) {
184 		if (*p1 == '\0')
185 			break;
186 		p1++;
187 		p2++;
188 	}
189 	return rv;
190 }
191 
192 char*
193 mklower(char *name)
194 {
195 	char *p;
196 	char c;
197 
198 	for(p = name; *p; p++){
199 		c = *p;
200 		*p = lower(c);
201 	}
202 	return name;
203 }
204