0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
|
// rand.c, version 1.0.1
// OMKOV coreutils rand
// Copyright (C) 2020, Jakob Wakeling
// MIT Licence
#include "util/error.h"
#include "util/optget.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define VERSION "1.0.1"
#define aSIZE (sizeof (aset) - 1)
#define ASIZE (sizeof (Aset) - 1)
#define nSIZE (sizeof (nset) - 1)
#define sSIZE (sizeof (sset) - 1)
static struct lop lops[] = {
{ "help", ARG_NUL, 256 },
{ "version", ARG_NUL, 257 },
{ NULL, 0, 0 }
};
static const char aset[] = "abcdefghijklmnopqrstuvwxyz";
static const char Aset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const char nset[] = "0123456789";
static const char sset[] = "!@#$%^&*";
static int mode;
static uintmax_t len;
static void hlp(void);
static void ver(void);
int main(int ac, char *av[]) { A0 = av[0];
struct opt opt = OPTGET_INIT; opt.str = "aAns"; opt.lops = lops;
for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) {
case 'a': { mode |= 1; break; }
case 'A': { mode |= 2; break; }
case 'n': { mode |= 4; break; }
case 's': { mode |= 8; break; }
case 256: { hlp(); return 0; }
case 257: { ver(); return 0; }
default: { return 1; }
}
if (!mode) { mode = 6; }
if (opt.ind == ac) { len = 8; }
else {
register uintmax_t d; register char *p = av[opt.ind];
for (; *p >= '0' && *p <= '9'; ++p) {
d = (uintmax_t)*p - '0';
if (len > (UINTMAX_MAX - d) / 10) { break; }
len = len * 10 + d;
}
if (*p) { error(1, "%s: invalid length", av[opt.ind]); }
}
FILE *rand; char *set; unsigned setlen = 0, n;
if (!(rand = fopen("/dev/urandom", "r"))) {
error(1, "%s: %s", "/dev/urandom", serr());
}
if (mode & 1) { setlen += aSIZE; }
if (mode & 2) { setlen += ASIZE; }
if (mode & 4) { setlen += nSIZE; }
if (mode & 8) { setlen += sSIZE; }
if (!(set = (char *)malloc(setlen + 1))) {
fclose(rand); error(1, "%s", serr());
}
if (mode & 1) { strcat(set, aset); }
if (mode & 2) { strcat(set, Aset); }
if (mode & 4) { strcat(set, nset); }
if (mode & 8) { strcat(set, sset); }
for (uintmax_t i = 0; i < len; ++i) {
fread(&n, sizeof (unsigned long), 1, rand); n %= setlen;
fputc(set[n], stdout);
} fputc('\n', stdout);
fclose(rand); free(set); return 0;
}
static void hlp(void) {
puts("rand - generate random string\n");
puts("usage: rand [-aAns] [length]\n");
puts("options:");
puts(" -a Enable lowercase letters in the string output");
puts(" -A Enable uppercase letters in the string output");
puts(" -n Enable numbers in the string output");
puts(" -s Enable symbols '!@#$%^&*' in the string output");
puts(" --help Display help information");
puts(" --version Display version information");
}
static void ver(void) {
puts("OMKOV coreutils rand, version " VERSION);
puts("Copyright (C) 2020, Jakob Wakeling");
puts("MIT Licence (https://opensource.org/licenses/MIT)");
}
|