taliasmail.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
taliasmail.c (5443B)
---
     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 
    43         if (chdir(UPASLIB) < 0)
    44                 sysfatal("aliasmail chdir %s: %r", UPASLIB);
    45 
    46         /* get environmental info */
    47         names = sysnames_read();
    48         files = getdbfiles();
    49         alias = s_new();
    50 
    51         /* loop through the names to be translated (from standard input) */
    52         for(i=0; i= 0 && *s_to_c(alias) != '\0'){
    60                                 p = strchr(s_to_c(alias), '\n');
    61                                 if(p)
    62                                         *p = 0;
    63                                 p = strchr(s_to_c(alias), '!');
    64                                 if(p) {
    65                                         *p = 0;
    66                                         print("%s", s_to_c(alias));
    67                                 } else {
    68                                         p = strchr(s_to_c(alias), '@');
    69                                         if(p)
    70                                                 print("%s", p+1);
    71                                         else
    72                                                 print("%s", s_to_c(alias));
    73                                 }
    74                         }
    75                 } else {
    76                         if (rv < 0 || *s_to_c(alias) == '\0')
    77                                 print("local!%s\n", s_to_c(s));
    78                         else {
    79                                 /* this must be a write, not a print */
    80                                 write(1, s_to_c(alias), strlen(s_to_c(alias)));
    81                         }
    82                 }
    83                 s_free(s);
    84         }
    85         exits(0);
    86 }
    87 
    88 /* get the list of dbfiles to search */
    89 static String *
    90 getdbfiles(void)
    91 {
    92         Sinstack *sp;
    93         String *files = s_new();
    94         char *nf;
    95 
    96         if(from)
    97                 nf = "fromfiles";
    98         else
    99                 nf = namefiles;
   100 
   101         /* system wide aliases */
   102         if ((sp = s_allocinstack(nf)) != 0){
   103                 while(s_rdinstack(sp, files))
   104                         s_append(files, " ");
   105                 s_freeinstack(sp);
   106         }
   107 
   108 
   109         DEBUG print("files are %s\n", s_to_c(files));
   110 
   111         return files;
   112 }
   113 
   114 /* loop through the translation files */
   115 static int
   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 */
   120 {
   121         String *file = s_new();
   122         String **fullnamev;
   123         int n, rv;
   124 
   125         rv = -1;
   126 
   127         DEBUG print("translate(%s, %s, %s)\n", name,
   128                 s_to_c(files), s_to_c(alias));
   129 
   130         /* create the full name to avoid loops (system!name) */
   131         for(n = 0; namev[n]; n++)
   132                 ;
   133         fullnamev = (String**)malloc(sizeof(String*)*(n+2));
   134         n = 0;
   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);
   140                 n++;
   141         }
   142         fullnamev[n] = 0;
   143 
   144         /* look at system-wide names */
   145         s_restart(files);
   146         while (s_parse(files, s_restart(file)) != 0) {
   147                 if (lookup(fullnamev, file, alias)==0) {
   148                         rv = 0;
   149                         goto out;
   150                 }
   151         }
   152 
   153 out:
   154         for(n = 0; fullnamev[n]; n++)
   155                 s_free(fullnamev[n]);
   156         s_free(file);
   157         free(fullnamev);
   158         return rv;
   159 }
   160 
   161 /*
   162  *  very dumb conversion to bang format
   163  */
   164 static String*
   165 attobang(String *token)
   166 {
   167         char *p;
   168         String *tok;
   169 
   170         p = strchr(s_to_c(token), '@');
   171         if(p == 0)
   172                 return token;
   173 
   174         p++;
   175         tok = s_copy(p);
   176         s_append(tok, "!");
   177         s_nappend(tok, s_to_c(token), p - s_to_c(token) - 1);
   178 
   179         return tok;
   180 }
   181 
   182 /*  Loop through the entries in a translation file looking for a match.
   183  *  Return 0 if found, -1 otherwise.
   184  */
   185 static int
   186 lookup(
   187         String **namev,
   188         String *file,
   189         String *alias)        /* returned String */
   190 {
   191         String *line = s_new();
   192         String *token = s_new();
   193         String *bangtoken;
   194         int i, rv = -1;
   195         char *name =  s_to_c(namev[0]);
   196         Sinstack *sp;
   197 
   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));
   200 
   201         s_reset(alias);
   202         if ((sp = s_allocinstack(s_to_c(file))) == 0)
   203                 return -1;
   204 
   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));
   208                 s_restart(token);
   209                 if (s_parse(s_restart(line), token)==0)
   210                         continue;
   211                 if (compare(token, "#include")==0){
   212                         if(s_parse(line, s_restart(token))!=0) {
   213                                 if(lookup(namev, line, alias) == 0)
   214                                         break;
   215                         }
   216                         continue;
   217                 }
   218                 if (compare(token, name)!=0)
   219                         continue;
   220                 /* match found, get the alias */
   221                 while(s_parse(line, s_restart(token))!=0) {
   222                         bangtoken = attobang(token);
   223 
   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);
   230                                         break;
   231                                 }
   232 
   233                         if(namev[i] == 0)
   234                                 s_append(alias, s_to_c(token));
   235                         s_append(alias, "\n");
   236 
   237                         if(bangtoken != token)
   238                                 s_free(bangtoken);
   239                 }
   240                 rv = 0;
   241                 break;
   242         }
   243         s_free(line);
   244         s_free(token);
   245         s_freeinstack(sp);
   246         return rv;
   247 }
   248 
   249 #define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
   250 
   251 /* compare two Strings (case insensitive) */
   252 static int
   253 compare(String *s1,
   254         char *p2)
   255 {
   256         char *p1 = s_to_c(s1);
   257         int rv;
   258 
   259         DEBUG print("comparing %s to %s\n", p1, p2);
   260         while((rv = lower(*p1) - lower(*p2)) == 0) {
   261                 if (*p1 == '\0')
   262                         break;
   263                 p1++;
   264                 p2++;
   265         }
   266         return rv;
   267 }
   268 
   269 static char*
   270 mklower(char *name)
   271 {
   272         char *p;
   273         char c;
   274 
   275         for(p = name; *p; p++){
   276                 c = *p;
   277                 *p = lower(c);
   278         }
   279         return name;
   280 }