static void init_rumors(dlb * fp) { char line[BUFSZ]; dlb_fgets(line, sizeof line, fp); /* skip "don't edit" comment */ dlb_fgets(line, sizeof line, fp); if (sscanf(line, "%6x\n", &true_rumor_size) == 1 && true_rumor_size > 0L) { dlb_fseek(fp, 0L, SEEK_CUR); true_rumor_start = dlb_ftell(fp); true_rumor_end = true_rumor_start + true_rumor_size; dlb_fseek(fp, true_rumor_size, SEEK_CUR); dlb_fgets(line, sizeof line, fp); sscanf(line, "%6x\n", &false_rumor_size); dlb_fseek(fp, 0L, SEEK_CUR); false_rumor_start = dlb_ftell(fp); dlb_fseek(fp, false_rumor_size, SEEK_CUR); false_rumor_end = dlb_ftell(fp); potter_rumor_start = false_rumor_end; dlb_fseek(fp, 0L, SEEK_END); potter_rumor_end = dlb_ftell(fp); potter_rumor_size = potter_rumor_end - potter_rumor_start; } else true_rumor_size = -1L; /* init failed */ }
void display_file(const char *fname, boolean complain) { dlb *fp; char *buf; int fsize; fp = dlb_fopen(fname, "r"); if (!fp) { if (complain) { pline("Cannot open \"%s\".", fname); } else if (program_state.something_worth_saving) doredraw(); } else { dlb_fseek(fp, 0, SEEK_END); fsize = dlb_ftell(fp); dlb_fseek(fp, 0, SEEK_SET); buf = malloc(fsize); dlb_fread(buf, fsize, 1, fp); dlb_fclose(fp); display_buffer(buf, complain); free(buf); } }
static void init_rumors(dlb * fp) { char line[BUFSZ]; dlb_fgets(line, sizeof line, fp); /* skip "don't edit" comment */ dlb_fgets(line, sizeof line, fp); if (sscanf(line, "%6x\n", &true_rumor_size) == 1 && true_rumor_size > 0L) { dlb_fseek(fp, 0L, SEEK_CUR); true_rumor_start = dlb_ftell(fp); true_rumor_end = true_rumor_start + true_rumor_size; dlb_fseek(fp, 0L, SEEK_END); false_rumor_end = dlb_ftell(fp); false_rumor_start = true_rumor_end; /* ok, so it's redundant... */ false_rumor_size = false_rumor_end - false_rumor_start; } else true_rumor_size = -1L; /* init failed */ }
/* 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; }