summaryrefslogtreecommitdiff
path: root/src/main.c
blob: cb22210a12c8224b849e3e0cf5bea3a135153453 (plain)
    1 // upwgen generates random internationalized passwords
    2 // Copyright (C) 2019  Aaron Ball <nullspoon@oper.io>
    3 // 
    4 // This program is free software: you can redistribute it and/or modify
    5 // it under the terms of the GNU General Public License as published by
    6 // the Free Software Foundation, either version 3 of the License, or
    7 // (at your option) any later version.
    8 // 
    9 // This program is distributed in the hope that it will be useful,
   10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
   11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12 // GNU General Public License for more details.
   13 // 
   14 // You should have received a copy of the GNU General Public License
   15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
   16 #include <stdlib.h>
   17 #include <stdio.h>
   18 #include <string.h>
   19 #include <time.h>
   20 #include <locale.h>
   21 
   22 #include "i18n_cat.h"
   23 
   24 
   25 void usage() {
   26   printf(
   27     "Upwgen is a password generator with international support. If no length\n"
   28     "is specified, defaults to 32 characters output length, selecting from\n"
   29     "the standard English character set (lower case, upper case, numerals,\n"
   30     "and symbols).\n\n"
   31     "Usage:\n  upwgen [options] [length]\n\n"
   32     "Options:\n"
   33     "  -c,--capitalize Include at least one capital letter in output\n"
   34     "  -l,--lower      Include at least one lower case letter in output\n"
   35     "  -n,--numerals   Include at least one numeral in output\n"
   36     "  -y,--symbols    Include at least one symbol in output\n"
   37     "  -i,--i18n       Include at least one international letter in output\n"
   38     "  -1              Include chars from the most used scripts in the world\n"
   39     "  -2              Include chars from the second most used scripts in the world\n"
   40     "  -3              Include chars from the third most used scripts in the world\n"
   41     "  -4              Include chars from the forth most used scripts in the world\n"
   42     "\n"
   43     "  -h,--help       Print this help text\n"
   44   );
   45 }
   46 
   47 
   48 int main(int argc, char* argv[]) {
   49   struct timespec ts; // Timespec for seeding rng
   50   unsigned int count; // Number of chars to choose from
   51   int len;            // Password length
   52   int i;              // Arg index
   53   unsigned long seed; // Seed for the RNG (current seconds * nanoseconds)
   54   unsigned int chars[4096]; // Uint array to hold international chars
   55 
   56   // Initialize
   57   count    = 0;
   58   len      = 32;
   59   i        = 1;
   60   chars[0] = '\0';
   61   setlocale(LC_ALL, "en_US.UTF-8");
   62 
   63   while(i < argc) {
   64     if(strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--capitals") == 0) {
   65       count += i18n_cat_ascii_upper(chars);
   66 
   67     } else if(strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--lower") == 0) {
   68       count += i18n_cat_ascii_lower(chars);
   69 
   70     } else if(strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--numerals") == 0) {
   71       count += i18n_cat_ascii_numerals(chars);
   72 
   73     } else if(strcmp(argv[i], "-y") == 0 || strcmp(argv[i], "--symbols") == 0) {
   74       count += i18n_cat_ascii_symbols(chars);
   75 
   76     } else if(strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--i18n") == 0) {
   77       count += i18n_cat_one(chars);
   78       count += i18n_cat_two(chars);
   79       count += i18n_cat_three(chars);
   80       count += i18n_cat_four(chars);
   81 
   82     } else if(strcmp(argv[i], "-1") == 0) {
   83       count += i18n_cat_one(chars);
   84 
   85     } else if(strcmp(argv[i], "-2") == 0) {
   86       count += i18n_cat_two(chars);
   87 
   88     } else if(strcmp(argv[i], "-3") == 0) {
   89       count += i18n_cat_three(chars);
   90 
   91     } else if(strcmp(argv[i], "-4") == 0) {
   92       count += i18n_cat_four(chars);
   93 
   94     } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
   95       usage();
   96       return 0;
   97 
   98     } else {
   99       // If we reach this block, the user specified a custom length (or
  100       // fatfingered something). Test for ability to convert from str to int
  101       // and set length if possible.
  102       if(atoi(argv[i]) == 0) {
  103         printf("Invalid length \"%s\"\n", argv[i]);
  104         return 1;
  105       } else {
  106         len = atoi(argv[i]);
  107       }
  108     }
  109     i++;
  110   }
  111 
  112   // If no charset was specified, use standard ascii 33 - 126 chars, which
  113   // includes english lower case, upper case, numbers, and some symbols.
  114   if(chars[0] == '\0')
  115     count += i18n_cat_ascii(chars);
  116 
  117   // Get the random data seed
  118   clock_gettime(CLOCK_REALTIME, &ts);
  119   seed = ts.tv_sec + ts.tv_nsec;
  120   srand((unsigned)seed);
  121 
  122   while(len > 0) {
  123     int r = rand() % count;
  124     printf("%lc", chars[r]);
  125     len--;
  126   }
  127   printf("\n");
  128 
  129   return 0;
  130 }

Generated by cgit