#include #include #include #include #include #include #include #include #include #include #include "db.h" #include "file_rw.h" #include "person.h" #include "seed.h" const char progname[] = "au-choose"; const char *db_path = DB_PATH; dstring path; dstring wstr; dir_array people; unsigned int *weights; char **files; void usage() { syserr_warn2x(progname, ": usage: [-d dbpath]"); } int main(int argc, char *argv[]) { unsigned long ind; unsigned long max; long total_w; long select; int ch; while ((ch = get_opt(argc, argv, "d:")) != opteof) switch (ch) { case 'd': db_path = optarg; break; default: usage(); return 111; } argc -= optind; argv += optind; seed(); if (!dstring_init(&wstr, 2)) syserr_die1sys(112, "fatal: dstring_init: "); if (!dstring_init(&path, 1024)) syserr_die1sys(112, "fatal: dstring_init: "); if (!dstring_cats(&path, db_path)) syserr_die1sys(112, "fatal: cats: "); if (!dstring_cats(&path, "/persons")) syserr_die1sys(112, "fatal: cats: "); dstring_0(&path); if (chdir(path.s) == -1) syserr_die1sys(112, "fatal: open database - "); if (!dir_array_init(&people, ".")) syserr_die1sys(112, "fatal: dir_init: "); if (people.n == 2) syserr_die1x(112, "fatal: no people in database"); max = people.n - 2; files = people.a + 2; weights = (unsigned int *) alloc(sizeof(unsigned int) * max); if (!weights) syserr_die1sys(112, "fatal: alloc: "); for (ind = 0; ind < max; ++ind) { dstring_trunc(&path); if (!dstring_cats(&path, files[ind])) syserr_die1sys(112, "fatal: cats: "); if (!dstring_cats(&path, "/weight")) syserr_die1sys(112, "fatal: catb: "); dstring_0(&path); dstring_trunc(&wstr); if (file_orac(path.s, &wstr) != -1) { if (!scan_uint(wstr.s, &weights[ind])) weights[ind] = 50; } else { if (errno == error_noent) weights[ind] = 50; else syserr_die3sys(112, "fatal: file_orac: ", path.s, " - "); } } total_w = 0; for (ind = 0; ind < max; ++ind) total_w += weights[ind]; if (!total_w) syserr_die1x(112, "fatal: total weight is 0"); select = random() % total_w + 1; for (ind = 0; ind < max; ++ind) if ((select -= weights[ind]) <= 0) { buffer_puts(buffer1, files[ind]); buffer_put(buffer1, "\n", 1); break; } if (buffer_flush(buffer1) == -1) syserr_die1sys(112, "fatal: write: "); return 0; }