// 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 #include #include #include #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)"); }