"Fossies" - the Fresh Open Source Software Archive

Member "pwgen-2.08/pw_phonemes.c" (7 Aug 2017, 3881 Bytes) of package /linux/privat/pwgen-2.08.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pw_phonemes.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.07_vs_2.08.

    1 /*
    2  * pw_phonemes.c --- generate secure passwords using phoneme rules
    3  *
    4  * Copyright (C) 2001,2002 by Theodore Ts'o
    5  * 
    6  * This file may be distributed under the terms of the GNU Public
    7  * License.
    8  */
    9 
   10 #include <ctype.h>
   11 #include <string.h>
   12 #include "pwgen.h"
   13 
   14 struct pw_element elements[] = {
   15     { "a",  VOWEL },
   16     { "ae", VOWEL | DIPTHONG },
   17     { "ah", VOWEL | DIPTHONG },
   18     { "ai", VOWEL | DIPTHONG },
   19     { "b",  CONSONANT },
   20     { "c",  CONSONANT },
   21     { "ch", CONSONANT | DIPTHONG },
   22     { "d",  CONSONANT },
   23     { "e",  VOWEL },
   24     { "ee", VOWEL | DIPTHONG },
   25     { "ei", VOWEL | DIPTHONG },
   26     { "f",  CONSONANT },
   27     { "g",  CONSONANT },
   28     { "gh", CONSONANT | DIPTHONG | NOT_FIRST },
   29     { "h",  CONSONANT },
   30     { "i",  VOWEL },
   31     { "ie", VOWEL | DIPTHONG },
   32     { "j",  CONSONANT },
   33     { "k",  CONSONANT },
   34     { "l",  CONSONANT },
   35     { "m",  CONSONANT },
   36     { "n",  CONSONANT },
   37     { "ng", CONSONANT | DIPTHONG | NOT_FIRST },
   38     { "o",  VOWEL },
   39     { "oh", VOWEL | DIPTHONG },
   40     { "oo", VOWEL | DIPTHONG},
   41     { "p",  CONSONANT },
   42     { "ph", CONSONANT | DIPTHONG },
   43     { "qu", CONSONANT | DIPTHONG},
   44     { "r",  CONSONANT },
   45     { "s",  CONSONANT },
   46     { "sh", CONSONANT | DIPTHONG},
   47     { "t",  CONSONANT },
   48     { "th", CONSONANT | DIPTHONG},
   49     { "u",  VOWEL },
   50     { "v",  CONSONANT },
   51     { "w",  CONSONANT },
   52     { "x",  CONSONANT },
   53     { "y",  CONSONANT },
   54     { "z",  CONSONANT }
   55 };
   56 
   57 #define NUM_ELEMENTS (sizeof(elements) / sizeof (struct pw_element))
   58 
   59 void pw_phonemes(char *buf, int size, int pw_flags, char *remove)
   60 {
   61     int     c, i, len, flags, feature_flags;
   62     int     prev, should_be, first;
   63     const char  *str;
   64     char        ch, *cp;
   65 
   66 try_again:
   67     feature_flags = pw_flags;
   68     c = 0;
   69     prev = 0;
   70     should_be = 0;
   71     first = 1;
   72 
   73     should_be = pw_number(2) ? VOWEL : CONSONANT;
   74     
   75     while (c < size) {
   76         i = pw_number(NUM_ELEMENTS);
   77         str = elements[i].str;
   78         len = strlen(str);
   79         flags = elements[i].flags;
   80         /* Filter on the basic type of the next element */
   81         if ((flags & should_be) == 0)
   82             continue;
   83         /* Handle the NOT_FIRST flag */
   84         if (first && (flags & NOT_FIRST))
   85             continue;
   86         /* Don't allow VOWEL followed a Vowel/Dipthong pair */
   87         if ((prev & VOWEL) && (flags & VOWEL) &&
   88             (flags & DIPTHONG))
   89             continue;
   90         /* Don't allow us to overflow the buffer */
   91         if (len > size-c)
   92             continue;
   93 
   94         /*
   95          * OK, we found an element which matches our criteria,
   96          * let's do it!
   97          */
   98         strcpy(buf+c, str);
   99 
  100         /* Handle PW_UPPERS */
  101         if (pw_flags & PW_UPPERS) {
  102             if ((first || flags & CONSONANT) &&
  103                 (pw_number(10) < 2)) {
  104                 buf[c] = toupper(buf[c]);
  105                 feature_flags &= ~PW_UPPERS;
  106             }
  107         }
  108 
  109         /* Handle the AMBIGUOUS flag */
  110         if (pw_flags & PW_AMBIGUOUS) {
  111             buf[c+len] = '\0'; /* To make strpbrk() happy */
  112             cp = strpbrk(buf, pw_ambiguous);
  113             if (cp)
  114                 continue;
  115         }
  116         
  117         c += len;
  118         
  119         /* Time to stop? */
  120         if (c >= size)
  121             break;
  122         
  123         /*
  124          * Handle PW_DIGITS
  125          */
  126         if (pw_flags & PW_DIGITS) {
  127             if (!first && (pw_number(10) < 3)) {
  128                 do {
  129                     ch = pw_number(10)+'0';
  130                 } while ((pw_flags & PW_AMBIGUOUS) 
  131                      && strchr(pw_ambiguous, ch));
  132                 buf[c++] = ch;
  133                 buf[c] = 0;
  134                 feature_flags &= ~PW_DIGITS;
  135                 
  136                 first = 1;
  137                 prev = 0;
  138                 should_be = pw_number(2) ?
  139                     VOWEL : CONSONANT;
  140                 continue;
  141             }
  142         }
  143                 
  144         /* Handle PW_SYMBOLS */
  145         if (pw_flags & PW_SYMBOLS) {
  146             if (!first && (pw_number(10) < 2)) {
  147                 do {
  148                     ch = pw_symbols[
  149                         pw_number(strlen(pw_symbols))];
  150                 } while ((pw_flags & PW_AMBIGUOUS) 
  151                     && strchr(pw_ambiguous, ch));
  152                 buf[c++] = ch;
  153                 buf[c] = 0;
  154                 feature_flags &= ~PW_SYMBOLS;
  155             }
  156         }
  157 
  158         /*
  159          * OK, figure out what the next element should be
  160          */
  161         if (should_be == CONSONANT) {
  162             should_be = VOWEL;
  163         } else { /* should_be == VOWEL */
  164             if ((prev & VOWEL) ||
  165                 (flags & DIPTHONG) ||
  166                 (pw_number(10) > 3))
  167                 should_be = CONSONANT;
  168             else
  169                 should_be = VOWEL;
  170         }
  171         prev = flags;
  172         first = 0;
  173     }
  174     if (feature_flags & (PW_UPPERS | PW_DIGITS | PW_SYMBOLS))
  175         goto try_again;
  176 }