4 * WARNING! This turns all upper case names into lower case
9 static String *getdbfiles(void);
10 static int translate(char*, char**, String*, String*);
11 static int lookup(String**, String*, String*);
12 static int compare(String*, char*);
13 static char* mklower(char*);
17 static char *namefiles = "namefiles";
18 #define DEBUG if(debug)
20 /* loop through the names to be translated */
22 main(int argc, char *argv[])
25 String *alias; /* the alias for the name */
26 char **names; /* names of this system */
27 String *files; /* list of files to search */
43 if (chdir(UPASLIB) < 0)
44 sysfatal("aliasmail chdir %s: %r", UPASLIB);
46 /* get environmental info */
47 names = sysnames_read();
51 /* loop through the names to be translated (from standard input) */
52 for(i=0; i<argc; i++) {
53 s = unescapespecial(s_copy(mklower(argv[i])));
54 if(strchr(s_to_c(s), '!') == 0)
55 rv = translate(s_to_c(s), names, files, alias);
59 if (rv >= 0 && *s_to_c(alias) != '\0'){
60 p = strchr(s_to_c(alias), '\n');
63 p = strchr(s_to_c(alias), '!');
66 print("%s", s_to_c(alias));
68 p = strchr(s_to_c(alias), '@');
72 print("%s", s_to_c(alias));
76 if (rv < 0 || *s_to_c(alias) == '\0')
77 print("local!%s\n", s_to_c(s));
79 /* this must be a write, not a print */
80 write(1, s_to_c(alias), strlen(s_to_c(alias)));
88 /* get the list of dbfiles to search */
93 String *files = s_new();
101 /* system wide aliases */
102 if ((sp = s_allocinstack(nf)) != 0){
103 while(s_rdinstack(sp, files))
104 s_append(files, " ");
109 DEBUG print("files are %s\n", s_to_c(files));
114 /* loop through the translation files */
116 translate(char *name, /* name to translate */
117 char **namev, /* names of this system */
118 String *files, /* names of system alias files */
119 String *alias) /* where to put the alias */
121 String *file = s_new();
127 DEBUG print("translate(%s, %s, %s)\n", name,
128 s_to_c(files), s_to_c(alias));
130 /* create the full name to avoid loops (system!name) */
131 for(n = 0; namev[n]; n++)
133 fullnamev = (String**)malloc(sizeof(String*)*(n+2));
135 fullnamev[n++] = s_copy(name);
136 for(; *namev; namev++){
137 fullnamev[n] = s_copy(*namev);
138 s_append(fullnamev[n], "!");
139 s_append(fullnamev[n], name);
144 /* look at system-wide names */
146 while (s_parse(files, s_restart(file)) != 0) {
147 if (lookup(fullnamev, file, alias)==0) {
154 for(n = 0; fullnamev[n]; n++)
155 s_free(fullnamev[n]);
162 * very dumb conversion to bang format
165 attobang(String *token)
170 p = strchr(s_to_c(token), '@');
177 s_nappend(tok, s_to_c(token), p - s_to_c(token) - 1);
182 /* Loop through the entries in a translation file looking for a match.
183 * Return 0 if found, -1 otherwise.
189 String *alias) /* returned String */
191 String *line = s_new();
192 String *token = s_new();
195 char *name = s_to_c(namev[0]);
198 DEBUG print("lookup(%s, %s, %s, %s)\n", s_to_c(namev[0]), s_to_c(namev[1]),
199 s_to_c(file), s_to_c(alias));
202 if ((sp = s_allocinstack(s_to_c(file))) == 0)
205 /* look for a match */
206 while (s_rdinstack(sp, s_restart(line))!=0) {
207 DEBUG print("line is %s\n", s_to_c(line));
209 if (s_parse(s_restart(line), token)==0)
211 if (compare(token, "#include")==0){
212 if(s_parse(line, s_restart(token))!=0) {
213 if(lookup(namev, line, alias) == 0)
218 if (compare(token, name)!=0)
220 /* match found, get the alias */
221 while(s_parse(line, s_restart(token))!=0) {
222 bangtoken = attobang(token);
224 /* avoid definition loops */
225 for(i = 0; namev[i]; i++)
226 if(compare(bangtoken, s_to_c(namev[i]))==0) {
227 s_append(alias, "local");
228 s_append(alias, "!");
229 s_append(alias, name);
234 s_append(alias, s_to_c(token));
235 s_append(alias, "\n");
237 if(bangtoken != token)
249 #define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
251 /* compare two Strings (case insensitive) */
256 char *p1 = s_to_c(s1);
259 DEBUG print("comparing %s to %s\n", p1, p2);
260 while((rv = lower(*p1) - lower(*p2)) == 0) {
275 for(p = name; *p; p++){