home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / autoalias.shar / nameptx.c < prev    next >
C/C++ Source or Header  |  1993-09-20  |  6KB  |  251 lines

  1. /*
  2.  * nameptx - generate "permuted index" of names
  3.  *    Based on "nptx.c" from the smail2.5 distribution.
  4.  *    Compile with -DDOT_REQD if you only want output of
  5.  *      aliases with dot separators.
  6.  *    Compile with -DSYSV if you want strchr() and strrchr()
  7.  *      instead of index() and rindex().
  8.  *
  9.  *    Modifications by:  Gilles R. Detillieux,  <grdetil@scrc.umanitoba.ca>
  10.  *               Spinal Cord Research Centre
  11.  *               Dept. of Physiology
  12.  *               Univ. of Manitoba, Winnipeg, Canada
  13.  *
  14.  *    The original source did not include any copyright notice.
  15.  *    I've been told it's in the public domain.  I thank the author
  16.  *    of smail 2.5 for making the source available.
  17.  *    I've modified nptx.c to make it more self-contained (it used
  18.  *    to require two object files from the smail program) and to
  19.  *    convert the name field to lower case, so lcasep.c isn't needed.
  20.  *
  21.  *
  22.  * nameptx reads a list of address name pairs on the standard input
  23.  * and prints name permutations and the address pairs on the standard
  24.  * output.  This can used in the generation of full name aliases for
  25.  * sendmail.  The format of an input line is:
  26.  * 
  27.  *     address name
  28.  * 
  29.  * The address field can contain any address, it is terminated by a
  30.  * TAB char (ascii 0x9).  No translation is done on the field.  The
  31.  * name field consists of whitespace separated names or initials with
  32.  * an optional nickname given in parentheses, it is terminated by
  33.  * either a newline ascii (0xA) or a ',' (ascii 0x2C).  The name field
  34.  * is converted to lower case.  All permutations of the names and
  35.  * initials are printed.  The only restriction is that the last name
  36.  * will appear in each permutation.  The permutations are not necessarily
  37.  * unique.
  38.  * 
  39.  * E.g.:
  40.  * 
  41.  * $ echo "gpb@ECH.gatech.edu\tWrecker Burdell(George P.)" | nameptx
  42.  * burdell    gpb@ECH.gatech.edu
  43.  * w.burdell    gpb@ECH.gatech.edu
  44.  * wrecker.burdell    gpb@ECH.gatech.edu
  45.  * burdell    gpb@ECH.gatech.edu
  46.  * g.burdell    gpb@ECH.gatech.edu
  47.  * george.burdell    gpb@ECH.gatech.edu
  48.  * p.burdell    gpb@ECH.gatech.edu
  49.  * p.burdell    gpb@ECH.gatech.edu
  50.  * g.p.burdell    gpb@ECH.gatech.edu
  51.  * george.p.burdell    gpb@ECH.gatech.edu
  52.  * g.p.burdell    gpb@ECH.gatech.edu
  53.  * george.p.burdell    gpb@ECH.gatech.edu
  54.  * $
  55.  * 
  56.  */
  57. #include <stdio.h>
  58. #include <ctype.h>
  59.  
  60. #ifdef SYSV
  61. #define    index    strchr
  62. #define    rindex    strrchr
  63. #endif
  64.  
  65. char *index(), *rindex(), *strcpy(), *strcat();
  66. void nptx(), dotspace();
  67.  
  68. main()
  69. {
  70.     char buf[256], buf2[256];
  71.     register char *p, *name, *last, *nick, *ctmp;
  72.  
  73.     while(gets(buf) != NULL) {
  74.         /*  line should be in form
  75.         **
  76.         **  login    First Last
  77.         ** or
  78.         **  login    First Last(Nickname)
  79.         **
  80.         */
  81.         if((p = index(buf, '\t')) == NULL) {
  82.             (void) fprintf(stderr, "format error: %s\n", buf);
  83.             continue;
  84.         }
  85.  
  86.         *p++ = '\0';
  87.         for(name = p; *name != '\0'; name++)
  88.             if(isupper(*name))
  89.                 *name = tolower(*name);
  90.             else if(*name == ',' || *name == '\n') {
  91.                 *name = '\0';
  92.                 break;
  93.             }
  94.  
  95.         if ((nick = index(p, '(')) != NULL) {
  96.             *nick++ = '\0';
  97.             if ((ctmp = index(nick, ')')) == NULL) {
  98.                 nick = NULL;
  99.             } else {
  100.                 *ctmp = '\0';
  101.             }
  102.         }
  103.  
  104.         name = p;
  105.         dotspace(name);
  106.         if ((last = rindex(name, '.')) != NULL) {
  107.             last++;
  108.             if((strcmp(last, "jr") == 0)
  109.              || (strcmp(last, "sr") == 0)) {
  110.                 while(--last > name && last[-1] != '.')
  111.                     ;
  112.                 if(last <= name)
  113.                     last = NULL;
  114.             }
  115.         }
  116.  
  117.         nptx(buf, name);
  118.  
  119.         if((last != NULL) && (nick != NULL)) {
  120.             (void) sprintf(buf2, "%s.%s", nick, last);
  121.             dotspace(buf2);
  122.             nptx(buf, buf2);
  123.         }
  124.     }
  125.     return(0);
  126. }
  127.  
  128. void
  129. dotspace(s)
  130. char *s;
  131. {
  132.     register char *p, *t;
  133.  
  134.     /* turn whitespace to '.' */
  135.     for(p = s; *p != '\0'; p++) {
  136.         if((*p == ' ') || (*p == '\t')) {
  137.             *p = '.';
  138.         }
  139.     }
  140.  
  141.     /* elide leading '.'s */
  142.     for(p = s; *p == '.' ; p++)
  143.         ;
  144.  
  145.     /* elide mulitple '.'s and all "'"s */
  146.     for(t = s; *p != '\0'; p++, t++) {
  147.         *t = *p;
  148.  
  149.         if(*t == '\'') {
  150.             t--;
  151.             continue;
  152.         }
  153.  
  154.         if(*p == '.') {
  155.             while(*(++p) == '.')
  156.                 ;
  157.             p--;
  158.         }
  159.     }
  160.     *t = '\0';
  161.  
  162.     /* elide trailing '.' */
  163.     if((t > s) && (*(--t) == '.')) *t = '\0';
  164. }
  165.  
  166. void
  167. nptx(login, name)
  168. char *login, *name;
  169. {
  170.     int i,j,k,N,lim,mask;
  171.     int ii,ji,ki,Ni,limi,maski;
  172.     char nl[11][100], il[11][100];
  173.     char *pi, *p, *rindex();
  174.     char buf[100];
  175.     char bufi[100];
  176.  
  177.     if((name == NULL) || (*name == '\0')) {
  178.         return;
  179.     }
  180.  
  181.     for(i=0; i < 10; i++) {
  182.         if((p = rindex(name, '.')) == NULL) break;
  183.         (void) strcpy(nl[i], p+1);
  184.         *p = '\0';
  185.     }
  186.     (void) strcpy(nl[i], name);
  187.  
  188.     while((strcmp(nl[i], "mr"  ) == 0)
  189.      ||   (strcmp(nl[i], "dr"  ) == 0)
  190.      ||   (strcmp(nl[i], "mrs" ) == 0)
  191.      ||   (strcmp(nl[i], "miss") == 0)
  192.      ||   (strcmp(nl[i], "ms"  ) == 0)) {
  193.         i--;
  194.     }
  195.  
  196.     while((strcmp(nl[0], "jr") == 0)
  197.      ||   (strcmp(nl[0], "sr") == 0)) {
  198.         for(j=0; j < i; j++) {
  199.             (void) strcpy(nl[j], nl[j+1]);
  200.         }
  201.         i--;
  202.     }
  203.  
  204.     N = i;
  205.     lim = 1 << (N+1);
  206.     for(mask = 1 << N ; mask < lim ; mask++) {
  207.         buf[0] = '\0';
  208.         for(j = 1, k = N; j < lim; j <<=1, k--) {
  209.             if(j & mask) {
  210.                 (void) strcat(buf, nl[k]);
  211.                 (void) strcat(buf, ".");
  212.             }
  213.         }
  214.         if((p = rindex(buf, '.')) != NULL) {
  215.             *p = '\0';
  216.         }
  217.  
  218.         for(ii=0; ii < 10; ii++) {
  219.             if((pi = rindex(buf, '.')) == NULL) break;
  220.             (void) strcpy(il[ii], pi+1);
  221.             *pi = '\0';
  222.         }
  223.         (void) strcpy(il[ii], buf);
  224.         Ni = ii;
  225.         limi = 1 << (Ni+1);
  226.         for(maski = 1 << Ni /* 0 */ ; maski < limi ; maski++) {
  227.             bufi[0] = '\0';
  228.             for(ji = 1, ki = Ni; ji < limi; ji <<=1, ki--) {
  229.                 if(ji & maski) {
  230.                     (void) strcat(bufi, il[ki]);
  231.                 } else {
  232.                     char init[3];
  233.                     init[0] = il[ki][0];
  234.                     init[1] = '\0';
  235.                     (void) strcat(bufi, init);
  236.                 }
  237.                 (void) strcat(bufi, ".");
  238.             }
  239.             if((pi = rindex(bufi, '.')) != NULL) {
  240.                 *pi = '\0';
  241.             }
  242. #ifdef DOT_REQD
  243.             if(index(bufi, '.') == NULL) {
  244.                 continue;
  245.             }
  246. #endif /* DOT_REQD */
  247.             (void) printf("%s\t%s\n",bufi, login); /* */
  248.         }
  249.     }
  250. }
  251.