The pixie no longer needs to be setuid-root.
[u/mdw/catacomb] / mkphrase.c
index f315108..1a5beab 100644 (file)
@@ -1,13 +1,13 @@
 /* -*-c-*-
  *
- * $Id: mkphrase.c,v 1.1 2000/08/06 10:50:55 mdw Exp $
+ * $Id$
  *
  * Generate passphrases from word lists
  *
  * (c) 2000 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
  * This file is part of Catacomb.
  *
  * it under the terms of the GNU Library General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
- * 
+ *
  * Catacomb is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Library General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Library General Public
  * License along with Catacomb; if not, write to the Free
  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: mkphrase.c,v $
- * Revision 1.1  2000/08/06 10:50:55  mdw
- * (mkphrase): New program for generating random passphrases with measured
- * strength.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include "config.h"
@@ -63,7 +54,7 @@
 /*----- Global state ------------------------------------------------------*/
 
 static unsigned min = 0, max = 256;    /* Word length bounds */
-static unsigned bits = 128;            /* Minimum acceptable entropy */
+static unsigned minbits = 128, maxbits = UINT_MAX; /* Acceptable entropy */
 static unsigned count = 1;             /* How many passphrases to make */
 
 static const char wchars[] = "abcdefghijklmnopqrstuvwxyz'";
@@ -188,7 +179,7 @@ static void *markov_init(void)
 {
   node (*model)[VECSZ][VECSZ][VECSZ] = xmalloc(sizeof(*model));
   unsigned i, j, k, l;
-  
+
   for (i = 0; i < VECSZ; i++) {
     for (j = 0; j < VECSZ; j++) {
       for (k = 0; k < VECSZ; k++) {
@@ -283,7 +274,8 @@ static void version(FILE *fp)
 static void usage(FILE *fp)
 {
   pquis(fp, "\
-Usage: $ [-p] [-b bits] [-g gen] [-n count] [-r [min-]max] wordlist...\n\
+Usage: $ [-p] [-b MIN[-MAX]] [-g GEN] [-n COUNT]\n\
+\t[-r [MIN-]MAX] WORDLIST...\n                   \
 ");
 }
 
@@ -300,7 +292,7 @@ supported are:\n\
 -h, --help             Show this help text.\n\
 -v, --version          Show the program's version number.\n\
 -u, --usage            Show a terse usage summary.\n\
--b, --bits=BITS                Produce at least BITS bits of entropy.\n\
+-b, --bits=MIN[-MAX]   Minimum and maximum bits of entropy.\n\
 -g, --generator=GEN    Use passphrase generator GEN.\n\
 -n, --count=COUNT      Generate COUNT passphrases.\n\
 -p, --probability      Show -log_2 of probability for each phrase.\n\
@@ -321,10 +313,8 @@ int main(int argc, char *argv[])
   dstr dd = DSTR_INIT;
   unsigned i;
 
-  enum {
-    f_bogus = 1,
-    f_showp = 2
-  };
+#define f_bogus 1u
+#define f_showp 2u
 
   ego(argv[0]);
   for (;;) {
@@ -355,10 +345,13 @@ int main(int argc, char *argv[])
        exit(0);
       case 'b': {
        char *p;
-       unsigned long n = strtoul(optarg, &p, 0);
-       if (*p)
-         die(EXIT_FAILURE, "bad integer `%s'", optarg);
-       bits = n;
+       minbits = strtoul(optarg, &p, 0);
+       if (*p == '-')
+         maxbits = strtoul(p + 1, &p, 0);
+       else
+         maxbits = UINT_MAX;
+       if (*p || minbits > maxbits)
+         die(EXIT_FAILURE, "bad entropy range `%s'", optarg);
       } break;
       case 'g': {
        ppgen_ops **p;
@@ -395,7 +388,7 @@ int main(int argc, char *argv[])
          n = nn;
          nn = strtoul(p + 1, &p, 0);
        }
-       if (*p)
+       if (*p || min > max)
          die(EXIT_FAILURE, "bad range string `%s'", optarg);
        min = n; max = nn;
       } break;
@@ -418,7 +411,7 @@ int main(int argc, char *argv[])
   ctx = ops->init();
   while (*argv) {
     if (strcmp(*argv, "-") == 0)
-      ops->scan(ctx, stdin);
+      ops->scan(stdin, ctx);
     else {
       FILE *fp = fopen(*argv, "r");
       if (!fp) {
@@ -433,10 +426,10 @@ int main(int argc, char *argv[])
   if (ops->endscan)
     ops->endscan(ctx);
 
-  for (i = 0; !count || i < count; i++) {
+  for (i = 0; !count || i < count; ) {
     double logp = 0;
     DRESET(&d);
-    while (logp < bits) {
+    while (logp < minbits) {
       double pp;
       DRESET(&dd);
       pp = ops->gen(&dd, &rand_global, ctx);
@@ -447,10 +440,13 @@ int main(int argc, char *argv[])
       DPUTD(&d, &dd);
       logp += pp;
     }
+    if (logp >= (double)maxbits + 1)
+      continue;
     dstr_write(&d, stdout);
     if (f & f_showp)
       printf(" [%g]", logp);
     fputc('\n', stdout);
+    i++;
   }
 
   ops->done(ctx);