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(String**, String*, String*); 12 static int compare(String*, char*); 13 static char* mklower(char*); 14 15 static int debug; 16 static int from; 17 static char *namefiles = "namefiles"; 18 #define DEBUG if(debug) 19 20 /* loop through the names to be translated */ 21 void 22 main(int argc, char *argv[]) 23 { 24 String *s; 25 String *alias; /* the alias for the name */ 26 char **names; /* names of this system */ 27 String *files; /* list of files to search */ 28 int i, rv; 29 char *p; 30 31 ARGBEGIN { 32 case 'd': 33 debug = 1; 34 break; 35 case 'f': 36 from = 1; 37 break; 38 case 'n': 39 namefiles = ARGF(); 40 break; 41 } ARGEND 42 if (chdir(UPASLIB) < 0) { 43 perror("translate(chdir):"); 44 exit(1); 45 } 46 47 /* get environmental info */ 48 names = sysnames_read(); 49 files = getdbfiles(); 50 alias = s_new(); 51 52 /* loop through the names to be translated (from standard input) */ 53 for(i=0; i<argc; i++) { 54 s = unescapespecial(s_copy(mklower(argv[i]))); 55 if(strchr(s_to_c(s), '!') == 0) 56 rv = translate(s_to_c(s), names, files, alias); 57 else 58 rv = -1; 59 if(from){ 60 if (rv >= 0 && *s_to_c(alias) != '\0'){ 61 p = strchr(s_to_c(alias), '\n'); 62 if(p) 63 *p = 0; 64 p = strchr(s_to_c(alias), '!'); 65 if(p) { 66 *p = 0; 67 print("%s", s_to_c(alias)); 68 } else { 69 p = strchr(s_to_c(alias), '@'); 70 if(p) 71 print("%s", p+1); 72 else 73 print("%s", s_to_c(alias)); 74 } 75 } 76 } else { 77 if (rv < 0 || *s_to_c(alias) == '\0') 78 print("local!%s\n", s_to_c(s)); 79 else { 80 /* this must be a write, not a print */ 81 write(1, s_to_c(alias), strlen(s_to_c(alias))); 82 } 83 } 84 s_free(s); 85 } 86 exits(0); 87 } 88 89 /* get the list of dbfiles to search */ 90 static String * 91 getdbfiles(void) 92 { 93 Biobuf *fp; 94 String *files = s_new(); 95 char *nf; 96 97 if(from) 98 nf = "fromfiles"; 99 else 100 nf = namefiles; 101 102 /* system wide aliases */ 103 if ((fp = sysopen(nf, "r", 0)) != 0){ 104 while(s_getline(fp, files)) 105 s_append(files, " "); 106 sysclose(fp); 107 } 108 109 110 DEBUG print("files are %s\n", s_to_c(files)); 111 112 return files; 113 } 114 115 /* loop through the translation files */ 116 static int 117 translate(char *name, /* name to translate */ 118 char **namev, /* names of this system */ 119 String *files, /* names of system alias files */ 120 String *alias) /* where to put the alias */ 121 { 122 String *file = s_new(); 123 String **fullnamev; 124 int n, rv; 125 126 rv = -1; 127 128 DEBUG print("translate(%s, %s, %s)\n", name, 129 s_to_c(files), s_to_c(alias)); 130 131 /* create the full name to avoid loops (system!name) */ 132 for(n = 0; namev[n]; n++) 133 ; 134 fullnamev = (String**)malloc(sizeof(String*)*(n+2)); 135 n = 0; 136 fullnamev[n++] = s_copy(name); 137 for(; *namev; namev++){ 138 fullnamev[n] = s_copy(*namev); 139 s_append(fullnamev[n], "!"); 140 s_append(fullnamev[n], name); 141 n++; 142 } 143 fullnamev[n] = 0; 144 145 /* look at system-wide names */ 146 s_restart(files); 147 while (s_parse(files, s_restart(file)) != 0) { 148 if (lookup(fullnamev, file, alias)==0) { 149 rv = 0; 150 goto out; 151 } 152 } 153 154 out: 155 for(n = 0; fullnamev[n]; n++) 156 s_free(fullnamev[n]); 157 s_free(file); 158 free(fullnamev); 159 return rv; 160 } 161 162 /* 163 * very dumb conversion to bang format 164 */ 165 static String* 166 attobang(String *token) 167 { 168 char *p; 169 String *tok; 170 171 p = strchr(s_to_c(token), '@'); 172 if(p == 0) 173 return token; 174 175 p++; 176 tok = s_copy(p); 177 s_append(tok, "!"); 178 s_nappend(tok, s_to_c(token), p - s_to_c(token) - 1); 179 180 return tok; 181 } 182 183 /* Loop through the entries in a translation file looking for a match. 184 * Return 0 if found, -1 otherwise. 185 */ 186 static int 187 lookup( 188 String **namev, 189 String *file, 190 String *alias) /* returned String */ 191 { 192 Biobuf *fp; 193 String *line = s_new(); 194 String *token = s_new(); 195 String *bangtoken; 196 int i, rv = -1; 197 char *name = s_to_c(namev[0]); 198 199 DEBUG print("lookup(%s, %s, %s, %s)\n", s_to_c(namev[0]), s_to_c(namev[1]), 200 s_to_c(file), s_to_c(alias)); 201 202 s_reset(alias); 203 if ((fp = sysopen(s_to_c(file), "r", 0)) == 0) 204 return -1; 205 206 /* look for a match */ 207 while (s_getline(fp, s_restart(line))!=0) { 208 DEBUG print("line is %s\n", s_to_c(line)); 209 s_restart(token); 210 if (s_parse(s_restart(line), token)==0) 211 continue; 212 if (compare(token, name)!=0) 213 continue; 214 /* match found, get the alias */ 215 while(s_parse(line, s_restart(token))!=0) { 216 bangtoken = attobang(token); 217 218 /* avoid definition loops */ 219 for(i = 0; namev[i]; i++) 220 if(compare(bangtoken, s_to_c(namev[i]))==0) { 221 s_append(alias, "local"); 222 s_append(alias, "!"); 223 s_append(alias, name); 224 break; 225 } 226 227 if(namev[i] == 0) 228 s_append(alias, s_to_c(token)); 229 s_append(alias, "\n"); 230 231 if(bangtoken != token) 232 s_free(bangtoken); 233 } 234 rv = 0; 235 break; 236 } 237 s_free(line); 238 s_free(token); 239 sysclose(fp); 240 return rv; 241 } 242 243 #define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c)) 244 245 /* compare two Strings (case insensitive) */ 246 static int 247 compare(String *s1, 248 char *p2) 249 { 250 char *p1 = s_to_c(s1); 251 int rv; 252 253 DEBUG print("comparing %s to %s\n", p1, p2); 254 while((rv = lower(*p1) - lower(*p2)) == 0) { 255 if (*p1 == '\0') 256 break; 257 p1++; 258 p2++; 259 } 260 return rv; 261 } 262 263 static char* 264 mklower(char *name) 265 { 266 char *p; 267 char c; 268 269 for(p = name; *p; p++){ 270 c = *p; 271 *p = lower(c); 272 } 273 return name; 274 } 275