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