aliasmail.c 5.3 KB

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