diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ae357e6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,49 @@
+#
+# This file is part of dicepwgen
+#
+# Copyright (C) 2015 T.v.Dein.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# You can contact me by mail: .
+
+CFLAGS = -Wall -Wextra -Werror -O1 -g
+LDFLAGS=
+OBJS = dicepwgen.o dictfile.o tossing.o
+DST = dicepwgen
+PREFIX = /usr/local
+UID = root
+GID = 0
+MAN = dicepwgen.1
+POD = dicepwgen.pod
+
+all: $(DST)
+
+$(DST): $(OBJS)
+ gcc $(OBJS) -o $(DST)
+
+%.o: %.c
+ gcc -c $(CFLAGS) $*.c -o $*.o
+
+clean:
+ rm -f *.o $(DST)
+
+man:
+ pod2man $(POD) > $(MAN)
+
+install: $(DST)
+ install -d -o $(UID) -g $(GID) $(PREFIX)/sbin
+ install -d -o $(UID) -g $(GID) $(PREFIX)/man/man1
+ install -o $(UID) -g $(GID) -m 555 $(DST) $(PREFIX)/sbin/
+ install -o $(UID) -g $(GID) -m 444 $(MAN) $(PREFIX)/man/man1/
diff --git a/README.md b/README.md
index 55d349c..2b5ed81 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,46 @@
-# diceware
-A diceware password generator
+## dicepwgen - A diceware password generator
-# build
+This is the README file for the password generator dicepwgen.
-gcc dice.c -o dice
+## Documentation
-# use
+You can read the documentation without installing the
+software:
+
+ perldoc udpxd.pod
+
+If it is already installed, you can read the manual page:
+
+ man udpxd
+
+## Installation
+
+This software doesn't have eny external dependencies, but
+you need either BSD make or GNU make installed to build it.
+
+First you need to check out the source code. Skip this, if
+you have already done so:
+
+ git clone git@github.com:TLINDEN/diceware.git
+
+Next, change into the newly created directory 'diceware' and
+compile the source code:
+
+ cd diceware
+ make
+
+To install, type this command:
+
+ sudo make install
+
+This will install the binary to `$PREFIX/sbin/dicepwgen` and
+the manual page to `$PREFIX/man/man1/dicepwgen.1`. You can
+modify `$PREFIX` during installation time like this:
+
+ make install PREFIX=/opt
+
+
+## Usage
```
Usage: dice [-tcfvh]
@@ -18,9 +53,23 @@ Options:
-h Print this help screen
```
-# license
+## Getting help
-GPLv3
+Although I'm happy to hear from udpxd users in private email,
+that's the best way for me to forget to do something.
-# author
-Thomas von Dein
+In order to report a bug, unexpected behavior, feature requests
+or to submit a patch, please open an issue on github:
+https://github.com/TLINDEN/diceware/issues.
+
+## License
+
+This software is licensed under the GNU GENERAL PUBLIC LICENSE version 3.
+
+## Author
+
+T.v.Dein
+
+## Project homepage
+
+https://github.com/TLINDEN/diceware
diff --git a/dice.c b/dice.c
deleted file mode 100644
index 3644307..0000000
--- a/dice.c
+++ /dev/null
@@ -1,352 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define DICTFILE "/usr/share/dict/american-english"
-#define VERSION "1.0"
-#define RLEN 1024
-
-int humantoss = 0;
-int WMIN = 5;
-int WMAX = 10;
-
-int usage() {
- fprintf(stderr,
- "Generate a random diceware passphrase\n"
- "Usage: dice [-cfvh]\n"
- "Options: \n"
- "-t --humantoss Asks interactively for tossed dices\n"
- "-c --wordcount Number of words (default: 4)\n"
- "-f --dictfile Dictionary file to use (default:\n"
- " /usr/share/dict/american-english)\n"
- "-l --minlen Minimum word len (default: 5)\n"
- "-m --maxlen Maximum word len (default: 10)\n"
- "-v --version Print program version\n"
- "-h -? --help Print this help screen\n"
- );
- return 1;
-}
-
-unsigned char *toss(int count) {
- /*
- toss dices. if the global humandice is enabled (option -t),
- then ask the human to toss dices and enter the numbers interactively.
- otherwise generate tosses from /dev/random.
- */
-
- FILE *RAND;
- int i;
- int pos = 0;
- uint8_t onedice;
- unsigned char *tosses = NULL;
- unsigned char *rand = NULL;
- size_t len;
- ssize_t linelen;
-
- if(humantoss) {
- char *line = NULL;
- char digit[2];
- digit[1] = '\0';
-
- RETRY:
- fprintf(stderr, "enter 5 digits, each between 1-6\n");
- linelen = getline(&line, &len, stdin);
- tosses = malloc((size_t)count);
-
- if(linelen < 6) /* 5 digits max allowed */
- goto RETRY;
-
- for(i=0; i 6) /* no dice digit */
- goto RETRY;
-
- tosses[i] = onedice;
- }
- free(line);
- }
- else {
- rand = malloc(RLEN);
-
- if((RAND = fopen("/dev/urandom", "rb")) == NULL) {
- perror("Could not open /dev/urandom");
- }
-
- fread(rand, RLEN, 1, RAND);
- fclose(RAND);
-
- tosses = malloc((size_t)count);
-
- for(i=0; i= 1 && onedice <= 6) {
- tosses[pos] = onedice;
- pos++;
- }
- if(pos == count)
- break;
- }
- free(rand);
- }
-
- return tosses;
-}
-
-int rand_lim(int limit) {
- /*
- return a random number in the range [0..limit)
- */
-
- int divisor = RAND_MAX/limit;
- int retval;
-
- do {
- retval = rand() / divisor;
- } while (retval == limit);
-
- return retval;
-}
-
-int *incr_dicedigit(int *digits) {
- /*
- increment an array of dice digits, we expect the first to
- be a multiple of 10000, the 2nd a multiple of 1000 and so on.
- */
- if(digits[4] == 6) {
- digits[4] = 1;
- if(digits[3] == 60) {
- digits[3] = 10;
- if(digits[2] == 600) {
- digits[2] = 100;
- if(digits[1] == 6000) {
- digits[1] = 1000;
- digits[0] += 10000; /* may overflow to 71111, must be catched by caller */
- }
- else
- digits[1] += 1000;
- }
- else
- digits[2] += 100;
- }
- else
- digits[3] += 10;
- }
- else
- digits[4]++;
-
- return digits;
-}
-
-int get_dicenum(int *digits) {
- /*
- get the actual number of an array of dice digits
- */
- int i = 0;
- int pos = 0;
- for(i=0; i<5; i++)
- pos += digits[i];
-
- return pos;
-}
-
-
-char **fetch_dict(char *dictfile) {
- /*
- read in the dictionary file. we generate an array of max
- 66666 entries from the dictionary, each entry's index will
- be a dice number (1 <=> 6). to enhance randomness, we jump
- over a number of lines (1-32 lines) and start from the beginning
- of the file if we reach the end before our array is full.
- */
-
- char **words;
- int pos, i, next, jump;
- char *line = NULL;
- size_t len = 0;
- ssize_t linelen;
- FILE *DICT;
- int *digits;
-
- if((DICT = fopen(dictfile, "rb")) == NULL) {
- perror("Could not open dictfile");
- }
-
- words = malloc(66666 * sizeof(char *));
- digits = malloc(5);
- jump = rand_lim(32);
-
- digits[0] = 10000;
- digits[1] = 1000;
- digits[2] = 100;
- digits[3] = 10;
- digits[4] = 1;
-
- pos = 11111;
- next = 0;
-
- for(i=0; i<6666; i++)
- words[i] = NULL;
-
-
- LOOP:
- while ((linelen = getline(&line, &len, DICT)) != -1) {
- if(jump > 0) {
- jump--;
- continue;
- }
- else {
- jump = rand_lim(32);
- }
- if(linelen >= WMIN+1 && linelen <= WMAX+1) {
- line[linelen-1] = '\0'; /* remove newline */
-
- for(i=0; i10 */
- } /* while read */
-
- if(pos < 66666) {
- fseek(DICT, 0L, SEEK_SET);
- goto LOOP;
- }
-
- fclose(DICT);
- free(line);
- free(digits);
-
- return words;
-}
-
-void getwords(char *dictfile, int count) {
- /*
- initiate dice tossing, extract matching number of words
- froom the wordlist and print it.
- */
- char **words;
- int i, pos, one, two, three, four, five;
- int *tossed;
- unsigned char *tosses;
-
- words = fetch_dict(dictfile);
-
- tossed = malloc(count * sizeof(int));
-
- for(i=0; i.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{
+. if \nF \{
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "DICEPWGEN 1"
+.TH DICEPWGEN 1 "2015-08-01" "perl v5.18.2" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+dicepwgen \- A diceware password generator
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 10
+\& Usage: dice [\-cfvh]
+\& Options:
+\& \-t \-\-humantoss Asks interactively for tossed dices
+\& \-c \-\-wordcount Number of words (default: 4)
+\& \-f \-\-dictfile Dictionary file to use (default:
+\& /usr/share/dict/american\-english)
+\& \-l \-\-minlen Minimum word len (default: 5)
+\& \-m \-\-maxlen Maximum word len (default: 10)
+\& \-v \-\-version Print program version
+\& \-h \-? \-\-help Print this help screen
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+dicepwgen generates a diceware password using a dictionary
+file. By default it uses pseudo random dice tosses, but
+it is also possible to use real dices and enter the numbers
+by using the option \fB\-t\fR.
+.PP
+The option \fB\-c\fR can be used to tweak the number of words
+to output. The options \fB\-l\fR and \fB\-m\fR can be used to tweak
+minimum and maximum word length.
+.PP
+You can tell dicepwgen to use another dictionary file with
+the option \fB\-f\fR.
+.PP
+The program only uses words which contain 7bit \s-1ASCII\s0 letters
+(a\-zA-Z), which are easier for password usage anyway.
+.SH "FILES"
+.IX Header "FILES"
+\&\fB/usr/share/dict/american\-english\fR: default dictionary file.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+
+.PP
+.
+.SH "BUGS"
+.IX Header "BUGS"
+In order to report a bug, unexpected behavior, feature requests
+or to submit a patch, please open an issue on github:
+.
+.SH "LICENSE"
+.IX Header "LICENSE"
+This software is licensed under the \s-1GNU GENERAL PUBLIC LICENSE\s0 version 3.
+.PP
+Copyright (c) 2015 by T. v. Dein.
+.SH "AUTHORS"
+.IX Header "AUTHORS"
+T.v.Dein \fBtom \s-1AT\s0 vondein \s-1DOT\s0 org\fR
diff --git a/dicepwgen.c b/dicepwgen.c
new file mode 100644
index 0000000..48fc260
--- /dev/null
+++ b/dicepwgen.c
@@ -0,0 +1,146 @@
+/*
+ * This file is part of dicepwgen
+ *
+ * Copyright (C) 2015 T.v.Dein.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * You can contact me by mail: .
+ */
+
+#include "dicepwgen.h"
+
+int usage() {
+ fprintf(stderr,
+ "Generate a random diceware passphrase\n"
+ "Usage: dice [-tcfvh]\n"
+ "Options: \n"
+ "-t --humantoss Asks interactively for tossed dices\n"
+ "-c --wordcount Number of words (default: 4)\n"
+ "-f --dictfile Dictionary file to use (default:\n"
+ " /usr/share/dict/american-english)\n"
+ "-l --minlen Minimum word len (default: 5)\n"
+ "-m --maxlen Maximum word len (default: 10)\n"
+ "-v --version Print program version\n"
+ "-h -? --help Print this help screen\n"
+ );
+ return 1;
+}
+
+int main (int argc, char **argv) {
+ int count = 4;
+ char *dictfile = NULL;
+ unsigned char *tosses = NULL;
+ int opt;
+
+ WMIN = 6;
+ WMAX = 10;
+ humantoss = 0;
+
+ static struct option longopts[] = {
+ { "wordcount", required_argument, NULL, 'c' },
+ { "minlen", required_argument, NULL, 'l' },
+ { "maxlen", required_argument, NULL, 'm' },
+ { "humantoss", required_argument, NULL, 't' },
+ { "dictfile", required_argument, NULL, 'f' },
+ { "version", no_argument, NULL, 'v' },
+ { "help", no_argument, NULL, 'h' },
+ };
+
+ while ((opt = getopt_long(argc, argv, "l:m:tf:c:vh?", longopts, NULL)) != -1) {
+ switch (opt) {
+ case 'v':
+ fprintf(stderr, "This is %s version %s\n", argv[0], VERSION);
+ return 1;
+ break;
+ case 'h':
+ case '?':
+ return usage();
+ break;
+ case 'c':
+ count = atoi(optarg);
+ break;
+ case 'l':
+ WMIN = atoi(optarg);
+ break;
+ case 'm':
+ WMAX = atoi(optarg);
+ break;
+ case 't':
+ humantoss = 1;
+ break;
+ case 'f':
+ dictfile = malloc(strlen(optarg));
+ strncpy(dictfile, optarg, strlen(optarg));
+ break;
+ default:
+ return usage();
+ break;
+ }
+ }
+
+
+ if(dictfile == NULL) {
+ dictfile = DICTFILE;
+ }
+
+ getwords(dictfile, count);
+
+ return 0;
+}
+
+void getwords(char *dictfile, int count) {
+ /*
+ initiate dice tossing, extract matching number of words
+ froom the wordlist and print it.
+ */
+ char **words;
+ int i, pos, one, two, three, four, five;
+ int *tossed;
+ unsigned char *tosses;
+
+ words = fetch_dict(dictfile);
+
+ tossed = malloc(count * sizeof(int));
+
+ for(i=0; i.
+ *
+ * You can contact me by mail: .
+ */
+
+#ifndef HAVE_DICE_H
+#define HAVE_DICE_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "dictfile.h"
+#include "tossing.h"
+
+#define DICTFILE "/usr/share/dict/american-english"
+#define VERSION "1.0"
+#define RLEN 1024
+
+int humantoss;
+int WMIN;
+int WMAX;
+
+int usage();
+int main (int argc, char **argv);
+void getwords(char *dictfile, int count);
+
+#endif
diff --git a/dicepwgen.pod b/dicepwgen.pod
new file mode 100644
index 0000000..3bfeb01
--- /dev/null
+++ b/dicepwgen.pod
@@ -0,0 +1,61 @@
+=head1 NAME
+
+dicepwgen - A diceware password generator
+
+=head1 SYNOPSIS
+
+ Usage: dice [-cfvh]
+ Options:
+ -t --humantoss Asks interactively for tossed dices
+ -c --wordcount Number of words (default: 4)
+ -f --dictfile Dictionary file to use (default:
+ /usr/share/dict/american-english)
+ -l --minlen Minimum word len (default: 5)
+ -m --maxlen Maximum word len (default: 10)
+ -v --version Print program version
+ -h -? --help Print this help screen
+
+=head1 DESCRIPTION
+
+dicepwgen generates a diceware password using a dictionary
+file. By default it uses pseudo random dice tosses, but
+it is also possible to use real dices and enter the numbers
+by using the option B<-t>.
+
+The option B<-c> can be used to tweak the number of words
+to output. The options B<-l> and B<-m> can be used to tweak
+minimum and maximum word length.
+
+You can tell dicepwgen to use another dictionary file with
+the option B<-f>.
+
+The program only uses words which contain 7bit ASCII letters
+(a-zA-Z), which are easier for password usage anyway.
+
+=head1 FILES
+
+B: default dictionary file.
+
+=head1 SEE ALSO
+
+L
+
+L.
+
+=head1 BUGS
+
+In order to report a bug, unexpected behavior, feature requests
+or to submit a patch, please open an issue on github:
+L.
+
+=head1 LICENSE
+
+This software is licensed under the GNU GENERAL PUBLIC LICENSE version 3.
+
+Copyright (c) 2015 by T. v. Dein.
+
+=head1 AUTHORS
+
+T.v.Dein B
+
+=cut
diff --git a/dictfile.c b/dictfile.c
new file mode 100644
index 0000000..ac4867c
--- /dev/null
+++ b/dictfile.c
@@ -0,0 +1,139 @@
+/*
+ * This file is part of dicepwgen
+ *
+ * Copyright (C) 2015 T.v.Dein.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * You can contact me by mail: .
+ */
+
+#include "dictfile.h"
+
+int *incr_dicedigit(int *digits) {
+ /*
+ increment an array of dice digits, we expect the first to
+ be a multiple of 10000, the 2nd a multiple of 1000 and so on.
+ */
+ if(digits[4] == 6) {
+ digits[4] = 1;
+ if(digits[3] == 60) {
+ digits[3] = 10;
+ if(digits[2] == 600) {
+ digits[2] = 100;
+ if(digits[1] == 6000) {
+ digits[1] = 1000;
+ digits[0] += 10000; /* may overflow to 71111, must be catched by caller */
+ }
+ else
+ digits[1] += 1000;
+ }
+ else
+ digits[2] += 100;
+ }
+ else
+ digits[3] += 10;
+ }
+ else
+ digits[4]++;
+
+ return digits;
+}
+
+char **fetch_dict(char *dictfile) {
+ /*
+ read in the dictionary file. we generate an array of max
+ 66666 entries from the dictionary, each entry's index will
+ be a dice number (1 <=> 6). to enhance randomness, we jump
+ over a number of lines (1-32 lines) and start from the beginning
+ of the file if we reach the end before our array is full.
+ */
+
+ char **words;
+ int pos, i, next, jump;
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t linelen;
+ FILE *DICT;
+ int *digits;
+
+ if((DICT = fopen(dictfile, "rb")) == NULL) {
+ perror("Could not open dictfile");
+ }
+
+ words = malloc(66666 * sizeof(char *));
+ digits = malloc(5);
+ jump = rand_lim(32);
+
+ digits[0] = 10000;
+ digits[1] = 1000;
+ digits[2] = 100;
+ digits[3] = 10;
+ digits[4] = 1;
+
+ pos = 11111;
+ next = 0;
+
+ for(i=0; i<6666; i++)
+ words[i] = NULL;
+
+
+ LOOP:
+ while ((linelen = getline(&line, &len, DICT)) != -1) {
+ if(jump > 0) {
+ jump--;
+ continue;
+ }
+ else {
+ jump = rand_lim(32);
+ }
+ if(linelen >= WMIN+1 && linelen <= WMAX+1) {
+ line[linelen-1] = '\0'; /* remove newline */
+
+ for(i=0; i10 */
+ } /* while read */
+
+ if(pos < 66666) {
+ fseek(DICT, 0L, SEEK_SET);
+ goto LOOP;
+ }
+
+ fclose(DICT);
+ free(line);
+ free(digits);
+
+ return words;
+}
diff --git a/dictfile.h b/dictfile.h
new file mode 100644
index 0000000..f564ffe
--- /dev/null
+++ b/dictfile.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of dicepwgen
+ *
+ * Copyright (C) 2015 T.v.Dein.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * You can contact me by mail: .
+ */
+
+#ifndef HAVE_DICTFILE_H
+#define HAVE_DICTFILE_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "tossing.h"
+
+extern int WMIN;
+extern int WMAX;
+
+int *incr_dicedigit(int *digits);
+char **fetch_dict(char *dictfile);
+
+#endif
diff --git a/tossing.c b/tossing.c
new file mode 100644
index 0000000..7eda714
--- /dev/null
+++ b/tossing.c
@@ -0,0 +1,124 @@
+/*
+ * This file is part of dicepwgen
+ *
+ * Copyright (C) 2015 T.v.Dein.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * You can contact me by mail: .
+ */
+
+#include "tossing.h"
+
+unsigned char *toss(int count) {
+ /*
+ toss dices. if the global humandice is enabled (option -t),
+ then ask the human to toss dices and enter the numbers interactively.
+ otherwise generate tosses from /dev/random.
+ */
+
+ FILE *RAND;
+ int i;
+ int pos = 0;
+ uint8_t onedice;
+ unsigned char *tosses = NULL;
+ unsigned char *rand = NULL;
+ size_t len;
+ ssize_t linelen;
+
+ if(humantoss) {
+ char *line = NULL;
+ char digit[2];
+ digit[1] = '\0';
+
+ RETRY:
+ fprintf(stderr, "enter 5 digits, each between 1-6\n");
+ linelen = getline(&line, &len, stdin);
+ tosses = malloc((size_t)count);
+
+ if(linelen < 6) /* 5 digits max allowed */
+ goto RETRY;
+
+ for(i=0; i 6) /* no dice digit */
+ goto RETRY;
+
+ tosses[i] = onedice;
+ }
+ free(line);
+ }
+ else {
+ rand = malloc(RLEN);
+
+ if((RAND = fopen("/dev/urandom", "rb")) == NULL)
+ perror("Could not open /dev/urandom");
+
+ if(fread(rand, RLEN, 1, RAND) != 1)
+ perror("Could not read from /dev/urandom");
+
+ fclose(RAND);
+
+ tosses = malloc((size_t)count);
+
+ for(i=0; i= 1 && onedice <= 6) {
+ tosses[pos] = onedice;
+ pos++;
+ }
+ if(pos == count)
+ break;
+ }
+ free(rand);
+ }
+
+ return tosses;
+}
+
+int rand_lim(int limit) {
+ /*
+ return a random number in the range [0..limit)
+ */
+
+ int divisor = RAND_MAX/limit;
+ int retval;
+
+ do {
+ retval = rand() / divisor;
+ } while (retval == limit);
+
+ return retval;
+}
+
+
+
+int get_dicenum(int *digits) {
+ /*
+ get the actual number of an array of dice digits
+ */
+ int i = 0;
+ int pos = 0;
+ for(i=0; i<5; i++)
+ pos += digits[i];
+
+ return pos;
+}
diff --git a/tossing.h b/tossing.h
new file mode 100644
index 0000000..d1a2156
--- /dev/null
+++ b/tossing.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of dicepwgen
+ *
+ * Copyright (C) 2015 T.v.Dein.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * You can contact me by mail: .
+ */
+
+#ifndef HAVE_TOSSING_H
+#define HAVE_TOSSING_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define RLEN 1024
+
+extern int humantoss;
+extern int WMIN;
+extern int WMAX;
+
+unsigned char *toss(int count);
+int rand_lim(int limit);
+int get_dicenum(int *digits);
+
+#endif