Exemple #1
0
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 */
}
Exemple #2
0
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);
	}
}
Exemple #3
0
void
outoracle(boolean special, boolean delphi)
{
    char line[COLNO];
    char *endp;
    dlb *oracles;
    int oracle_idx;
    char xbuf[BUFSZ];

    if (oracle_flg < 0 ||       /* couldn't open ORACLEFILE */
        (oracle_flg > 0 && oracle_cnt == 0))    /* oracles already exhausted */
        return;

    oracles = dlb_fopen(ORACLEFILE, "r");

    if (oracles) {
        struct menulist menu;

        if (oracle_flg == 0) {  /* if this is the first outoracle() */
            init_oracles(oracles);
            oracle_flg = 1;
            if (oracle_cnt == 0)
                return;
        }
        /* oracle_loc[0] is the special oracle; */
        /* oracle_loc[1..oracle_cnt-1] are normal ones */
        if (oracle_cnt <= 1 && !special)
            return;     /* (shouldn't happen) */
        oracle_idx = special ? 0 : rnd((int)oracle_cnt - 1);
        dlb_fseek(oracles, oracle_loc[oracle_idx], SEEK_SET);
        if (!special)
            oracle_loc[oracle_idx] = oracle_loc[--oracle_cnt];

        init_menulist(&menu);
        if (delphi)
            add_menutext(&menu,
                         special ?
                         "The Oracle scornfully takes all your money and says:"
                         :
                         "The Oracle meditates for a moment and then intones:");
        else
            add_menutext(&menu, "The message reads:");
        add_menutext(&menu, "");

        while (dlb_fgets(line, COLNO, oracles) && strcmp(line, "---\n")) {
            if ((endp = strchr(line, '\n')) != 0)
                *endp = 0;
            add_menutext(&menu, xcrypt(line, xbuf));
        }
        display_menu(menu.items, menu.icount, NULL, PICK_NONE, PLHINT_ANYWHERE,
                     NULL);
        free(menu.items);
        dlb_fclose(oracles);
    } else {
        pline("Can't open oracles file!");
        oracle_flg = -1;        /* don't try to open it again */
    }
}
void
outoracle(boolean special, boolean delphi)
{
    char line[COLNO];
    char *endp;
    dlb *oracles;
    int oracle_idx;

    if (oracle_flg < 0 ||       /* couldn't open ORACLEFILE */
        (oracle_flg > 0 && oracle_cnt == 0))    /* oracles already exhausted */
        return;

    oracles = dlb_fopen(ORACLEFILE, "r");

    if (oracles) {
        struct nh_menulist menu;

        if (oracle_flg == 0) {  /* if this is the first outoracle() */
            init_oracles(oracles);
            oracle_flg = 1;
            if (oracle_cnt == 0)
                return;
        }
        /* oracle_loc[0] is the special oracle; */
        /* oracle_loc[1..oracle_cnt-1] are normal ones */
        if (oracle_cnt <= 1 && !special)
            return;     /* (shouldn't happen) */
        oracle_idx = special ? 0 : rnd((int)oracle_cnt - 1);
        dlb_fseek(oracles, oracle_loc[oracle_idx], SEEK_SET);
        if (!special)
            oracle_loc[oracle_idx] = oracle_loc[--oracle_cnt];

        init_menulist(&menu);

        if (delphi)
            add_menutext(
                &menu, special ?
                "Potter protests, but then takes your money and says:" :
                "Potter thinks for a second, and then announces in a gravelly voice:");
        else
            add_menutext(&menu, "The message reads:");
        add_menutext(&menu, "");

        while (dlb_fgets(line, COLNO, oracles) && strcmp(line, "---\n")) {
            if ((endp = strchr(line, '\n')) != 0)
                *endp = 0;
            char decrypted_line[strlen(line) + 1];
            add_menutext(&menu, xcrypt(line, decrypted_line));
        }

        display_menu(&menu, NULL, PICK_NONE, PLHINT_ANYWHERE,
                     NULL);
        dlb_fclose(oracles);
    } else {
        pline("Can't open oracles file!");
        oracle_flg = -1;        /* don't try to open it again */
    }
}
Exemple #5
0
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 */
}
Exemple #6
0
static void
dump_qtlist()	/* dump the character msg list to check appearance */
{
    struct	qtmsg	*msg;
    long	size;

    for (msg = qt_list.chrole; msg->msgnum > 0; msg++) {
        pline("msgnum %d: delivery %c",
              msg->msgnum, msg->delivery);
        more();
        (void) dlb_fseek(msg_file, msg->offset, SEEK_SET);
        deliver_by_window(msg, NHW_TEXT);
    }
}
Exemple #7
0
void
com_pager (int msgnum)
{
        struct qtmsg *qt_msg;

        if (!(qt_msg = msg_in(qt_list.common, msgnum))) {
                impossible("com_pager: message %d not found.", msgnum);
                return;
        }

        (void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET);
        if (qt_msg->delivery == 'p') deliver_by_pline(qt_msg);
        else if (msgnum == 1) deliver_by_window(qt_msg, NHW_MENU);
        else                 deliver_by_window(qt_msg, NHW_TEXT);
        return;
}
void
qt_pager(int msgnum)
{
    struct qtmsg *qt_msg;

    if (!(qt_msg = msg_in(qt_list.chrole, msgnum))) {
        impossible("qt_pager: message %d not found.", msgnum);
        return;
    }

    dlb_fseek(msg_file, qt_msg->offset, SEEK_SET);
    if (qt_msg->delivery == 'p')
        deliver_by_pline(qt_msg);
    else
        deliver_by_window(qt_msg);
    return;
}
static struct qtmsg *
construct_qtlist(long hdr_offset)
{
    struct qtmsg *msg_list;
    int n_msgs;

    dlb_fseek(msg_file, hdr_offset, SEEK_SET);
    Fread(&n_msgs, sizeof (int), 1, msg_file);
    msg_list = malloc((unsigned)(n_msgs + 1) * sizeof (struct qtmsg));

    /*
     * Load up the list.
     */
    Fread(msg_list, n_msgs * sizeof (struct qtmsg), 1, msg_file);

    msg_list[n_msgs].msgnum = -1;
    return msg_list;
}
Exemple #10
0
/* 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;
}
Exemple #11
0
/*
 * Look in the "data" file for more info.  Called if the user typed in the
 * whole name (user_typed_name == TRUE), or we've found a possible match
 * with a character/glyph.
 */
static void
checkfile(const char *inp, struct permonst *pm, boolean user_typed_name,
          boolean without_asking)
{
    dlb *fp;
    char buf[BUFSZ], newstr[BUFSZ];
    char *ep, *dbase_str;
    long txt_offset = 0;
    int chk_skip;
    boolean found_in_file = FALSE, skipping_entry = FALSE;

    fp = dlb_fopen(DATAFILE, "r");
    if (!fp) {
        pline("Cannot open data file!");
        return;
    }

    /* To prevent the need for entries in data.base like *ngel to account for
       Angel and angel, make the lookup string the same for both
       user_typed_name and picked name. */
    if (pm != NULL && !user_typed_name)
        dbase_str = strcpy(newstr, pm->mname);
    else
        dbase_str = strcpy(newstr, inp);

    for (ep = dbase_str; *ep; ep++)
        *ep = lowc(*ep);

    if (!strncmp(dbase_str, "interior of ", 12))
        dbase_str += 12;
    if (!strncmp(dbase_str, "a ", 2))
        dbase_str += 2;
    else if (!strncmp(dbase_str, "an ", 3))
        dbase_str += 3;
    else if (!strncmp(dbase_str, "the ", 4))
        dbase_str += 4;
    if (!strncmp(dbase_str, "tame ", 5))
        dbase_str += 5;
    else if (!strncmp(dbase_str, "peaceful ", 9))
        dbase_str += 9;
    if (!strncmp(dbase_str, "invisible ", 10))
        dbase_str += 10;
    if (!strncmp(dbase_str, "statue of ", 10))
        dbase_str[6] = '\0';
    else if (!strncmp(dbase_str, "figurine of ", 12))
        dbase_str[8] = '\0';

    /* Make sure the name is non-empty. */
    if (*dbase_str) {
        /* adjust the input to remove " [seen" and "named " and convert to
           lower case */
        const char *alt = 0;  /* alternate description */

        if ((ep = strstri_mutable(dbase_str, " [seen")) != 0)
            *ep = '\0';

        if ((ep = strstri_mutable(dbase_str, " named ")) != 0)
            alt = ep + 7;
        else
            ep = strstri_mutable(dbase_str, " called ");
        if (!ep)
            ep = strstri_mutable(dbase_str, ", ");
        if (ep && ep > dbase_str)
            *ep = '\0';

        /* 
         * If the object is named, then the name is the alternate description;
         * otherwise, the result of makesingular() applied to the name is. This
         * isn't strictly optimal, but named objects of interest to the user
         * will usually be found under their name, rather than under their
         * object type, so looking for a singular form is pointless.
         */

        if (!alt)
            alt = makesingular(dbase_str);
        else if (user_typed_name)
            alt = msglowercase(alt);

        /* skip first record; read second */
        txt_offset = 0L;
        if (!dlb_fgets(buf, BUFSZ, fp) || !dlb_fgets(buf, BUFSZ, fp)) {
            impossible("can't read 'data' file");
            dlb_fclose(fp);
            return;
        } else if (sscanf(buf, "%8lx\n", &txt_offset) < 1 || txt_offset <= 0)
            goto bad_data_file;

        /* look for the appropriate entry */
        while (dlb_fgets(buf, BUFSZ, fp)) {
            if (*buf == '.')
                break;  /* we passed last entry without success */

            if (digit(*buf)) {
                /* a number indicates the end of current entry */
                skipping_entry = FALSE;
            } else if (!skipping_entry) {
                if (!(ep = strchr(buf, '\n')))
                    goto bad_data_file;
                *ep = 0;
                /* if we match a key that begins with "~", skip this entry */
                chk_skip = (*buf == '~') ? 1 : 0;
                if (pmatch(&buf[chk_skip], dbase_str) ||
                    (alt && pmatch(&buf[chk_skip], alt))) {
                    if (chk_skip) {
                        skipping_entry = TRUE;
                        continue;
                    } else {
                        found_in_file = TRUE;
                        break;
                    }
                }
            }
        }
    }

    if (found_in_file) {
        long entry_offset;
        int entry_count;
        int i;

        /* skip over other possible matches for the info */
        do {
            if (!dlb_fgets(buf, BUFSZ, fp))
                goto bad_data_file;
        } while (!digit(*buf));

        if (sscanf(buf, "%ld,%d\n", &entry_offset, &entry_count) < 2) {
        bad_data_file:impossible("'data' file in wrong format");
            dlb_fclose(fp);
            return;
        }

        if (user_typed_name || without_asking || yn("More info?") == 'y') {
            struct nh_menulist menu;

            if (dlb_fseek(fp, txt_offset + entry_offset, SEEK_SET) < 0) {
                pline("? Seek error on 'data' file!");
                dlb_fclose(fp);
                return;
            }

            init_menulist(&menu);

            for (i = 0; i < entry_count; i++) {
                if (!dlb_fgets(buf, BUFSZ, fp))
                    goto bad_data_file;
                if ((ep = strchr(buf, '\n')) != 0)
                    *ep = 0;
                if (strchr(buf + 1, '\t') != 0)
                    tabexpand(buf + 1);
                add_menutext(&menu, buf + 1);
            }

            display_menu(&menu, NULL, FALSE, PLHINT_ANYWHERE,
                         NULL);
        }
    } else if (user_typed_name)
        pline("I don't have any information on those things.");

    dlb_fclose(fp);
}
/* 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;
}