void outrumor(void) { int rn, i; FILE *rumf; if (n_rumors <= n_used_rumors || (rumf = fopen(RUMORFILE, "r")) == (FILE *) 0) return; if (n_used_rumors < 0) init_rumors(rumf); if (!n_rumors) goto none; rn = rn2(n_rumors - n_used_rumors); i = 0; while (rn || used(i)) { (void) skipline(rumf); if (!used(i)) rn--; i++; } usedbits[i / CHARSZ] |= (1 << (i % CHARSZ)); n_used_rumors++; outline(rumf); none: (void) fclose(rumf); }
void outrumor() { int rn; int i; FILE *rumf; if(n_rumors <= n_used_rumors) { return; } else { rumf = fopen(RUMORFILE, "r"); if(rumf == NULL) { return; } } if(n_used_rumors < 0) { init_rumors(rumf); } if(n_rumors == 0) { fclose(rumf); return; } rn = rn2(n_rumors - n_used_rumors); i = 0; while((rn != 0) || (used(i) != 0)) { skipline(rumf); if(used(i) == 0) { --rn; } ++i; } usedbits[i / CHARSZ] |= (1 << (i % CHARSZ)); ++n_used_rumors; outline(rumf); fclose(rumf); }
/* exclude_cookie is a hack used because we sometimes want to get rumors in a * context where messages such as "You swallowed the fortune!" that refer to * cookies should not appear. This has no effect for true rumors since none * of them contain such references anyway. */ char * getrumor(int truth, /* 1=true, -1=false, 0=either */ char *rumor_buf, boolean exclude_cookie, int *truth_out) { dlb *rumors; int tidbit, beginning; char *endp, line[BUFSZ], xbuf[BUFSZ]; int ltruth = 0; rumor_buf[0] = '\0'; if (true_rumor_size < 0L) /* we couldn't open RUMORFILE */ return rumor_buf; rumors = dlb_fopen(RUMORFILE, "r"); if (rumors) { int count = 0; int adjtruth; do { rumor_buf[0] = '\0'; if (true_rumor_size == 0L) { /* if this is 1st outrumor() */ init_rumors(rumors); if (true_rumor_size < 0L) { /* init failed */ sprintf(rumor_buf, "Error reading \"%.80s\".", RUMORFILE); return rumor_buf; } } /* * input: 1 0 -1 * rn2 \ +1 2=T 1=T 0=F * adj./ +0 1=T 0=F -1=F */ switch (adjtruth = truth + rn2(2)) { case 2: /* (might let a bogus input arg sneak thru) */ case 1: beginning = true_rumor_start; tidbit = mt_random() % true_rumor_size; break; case 0: /* once here, 0 => false rather than "either" */ case -1: beginning = false_rumor_start; tidbit = mt_random() % false_rumor_size; break; default: impossible("strange truth value for rumor"); return strcpy(rumor_buf, "Oops..."); } dlb_fseek(rumors, beginning + tidbit, SEEK_SET); dlb_fgets(line, sizeof line, rumors); if (!dlb_fgets(line, sizeof line, rumors) || (adjtruth > 0 && dlb_ftell(rumors) > true_rumor_end)) { /* reached end of rumors -- go back to beginning */ dlb_fseek(rumors, beginning, SEEK_SET); dlb_fgets(line, sizeof line, rumors); } if ((endp = strchr(line, '\n')) != 0) *endp = 0; strcat(rumor_buf, xcrypt(line, xbuf)); } while (count++ < 50 && exclude_cookie && (strstri(rumor_buf, "fortune") || strstri(rumor_buf, "pity"))); dlb_fclose(rumors); if (count >= 50) impossible("Can't find non-cookie rumor?"); else ltruth = (adjtruth > 0) ? 1 : -1; } else { pline("Can't open rumors file!"); true_rumor_size = -1; /* don't try to open it again */ if (truth_out) *truth_out = 0; } if (truth_out) *truth_out = ltruth; return rumor_buf; }
/* exclude_cookie is a hack used because we sometimes want to get rumors in a * context where messages such as "You swallowed the fortune!" that refer to * cookies should not appear. This has no effect for true rumors since none * of them contain such references anyway. */ const char * getrumor(int truth, /* 1=true, -1=false, 0=either 3=potter (truier than true)*/ boolean exclude_cookie, int *truth_out, enum rng rng) { dlb *rumors; int tidbit, beginning; char *endp; int ltruth = 0; char line[BUFSZ]; /* for fgets */ const char *rv = ""; /* If this happens, we couldn't open the RUMORFILE. So synthesize a rumor just for the occasion :-) */ if (true_rumor_size < 0L) return ""; rumors = dlb_fopen(RUMORFILE, "r"); if (rumors) { int count = 0; int adjtruth; do { if (true_rumor_size == 0L) { /* if this is 1st outrumor() */ init_rumors(rumors); if (true_rumor_size < 0L) /* init failed */ return msgprintf("Error reading \"%.80s\".", RUMORFILE); } /* * input: 3 1 0 -1 * rn2 \ +1 4=P 2=T 1=T 0=F * adj./ +0 3=P 1=T 0=F -1=F */ switch (adjtruth = truth + rn2_on_rng(2, rng)) { case 4: /* (might let a bogus input arg sneak thru) */ case 3: beginning = potter_rumor_start; tidbit = rn2_on_rng(potter_rumor_size, rng); break; case 1: beginning = true_rumor_start; tidbit = rn2_on_rng(true_rumor_size, rng); break; case 0: /* once here, 0 => false rather than "either" */ case -1: beginning = false_rumor_start; tidbit = rn2_on_rng(false_rumor_size, rng); break; default: impossible("strange truth value for rumor"); if (truth_out) *truth_out = 0; return "Oops..."; } dlb_fseek(rumors, beginning + tidbit, SEEK_SET); dlb_fgets(line, sizeof line, rumors); if (!dlb_fgets(line, sizeof line, rumors) || ((adjtruth == 2 || adjtruth == 1) && dlb_ftell(rumors) > true_rumor_end)) { /* reached end of rumors -- go back to beginning */ dlb_fseek(rumors, beginning, SEEK_SET); dlb_fgets(line, sizeof line, rumors); } else if (!dlb_fgets(line, sizeof line, rumors) || (adjtruth < 1 && dlb_ftell(rumors) > false_rumor_end)){ dlb_fseek(rumors, beginning, SEEK_SET); dlb_fgets(line, sizeof line, rumors); } if ((endp = strchr(line, '\n')) != 0) *endp = 0; char decrypted_line[strlen(line) + 1]; xcrypt(line, decrypted_line); rv = msg_from_string(decrypted_line); } while (count++ < 50 && exclude_cookie && (strstri(rv, "fortune") || strstri(rv, "pity"))); dlb_fclose(rumors); if (count >= 50) impossible("Can't find non-cookie rumor?"); else ltruth = (adjtruth > 0) ? 1 : -1; } else { pline("Can't open rumors file!"); true_rumor_size = -1; /* don't try to open it again */ if (truth_out) *truth_out = 0; } if (truth_out) *truth_out = ltruth; return rv; }