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 Sinstack *sp; 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 ((sp = s_allocinstack(nf)) != 0){ 104 while(s_rdinstack(sp, files)) 105 s_append(files, " "); 106 s_freeinstack(sp); 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 String *line = s_new(); 193 String *token = s_new(); 194 String *bangtoken; 195 int i, rv = -1; 196 char *name = s_to_c(namev[0]); 197 Sinstack *sp; 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 ((sp = s_allocinstack(s_to_c(file))) == 0) 204 return -1; 205 206 /* look for a match */ 207 while (s_rdinstack(sp, 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, "#include")==0){ 213 if(s_parse(line, s_restart(token))!=0) { 214 if(lookup(namev, line, alias) == 0) 215 break; 216 } 217 continue; 218 } 219 if (compare(token, name)!=0) 220 continue; 221 /* match found, get the alias */ 222 while(s_parse(line, s_restart(token))!=0) { 223 bangtoken = attobang(token); 224 225 /* avoid definition loops */ 226 for(i = 0; namev[i]; i++) 227 if(compare(bangtoken, s_to_c(namev[i]))==0) { 228 s_append(alias, "local"); 229 s_append(alias, "!"); 230 s_append(alias, name); 231 break; 232 } 233 234 if(namev[i] == 0) 235 s_append(alias, s_to_c(token)); 236 s_append(alias, "\n"); 237 238 if(bangtoken != token) 239 s_free(bangtoken); 240 } 241 rv = 0; 242 break; 243 } 244 s_free(line); 245 s_free(token); 246 s_freeinstack(sp); 247 return rv; 248 } 249 250 #define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c)) 251 252 /* compare two Strings (case insensitive) */ 253 static int 254 compare(String *s1, 255 char *p2) 256 { 257 char *p1 = s_to_c(s1); 258 int rv; 259 260 DEBUG print("comparing %s to %s\n", p1, p2); 261 while((rv = lower(*p1) - lower(*p2)) == 0) { 262 if (*p1 == '\0') 263 break; 264 p1++; 265 p2++; 266 } 267 return rv; 268 } 269 270 static char* 271 mklower(char *name) 272 { 273 char *p; 274 char c; 275 276 for(p = name; *p; p++){ 277 c = *p; 278 *p = lower(c); 279 } 280 return name; 281 } 282