Example #1
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);
}
Example #2
0
int vdehist_term_to_mgmt(struct vdehiststat *st)
{
	unsigned char buf[BUFSIZE];
	int n,i,rv=0;
	n=vdehist_termread(st->termfd,buf,BUFSIZE);
	//printf("termto mgmt N%d %x %x %x %x\n",n,buf[0],buf[1],buf[2],buf[3]);
	if (n==0)
		return 1;
	else if (n<0)
		return n;
	else {
		for (i=0;i<n && strlen(st->linebuf)<BUFSIZE;i++) {
			if (buf[i] == 0xff && buf[i+1] == 0xff)
				i++;
			if(buf[i]==0) buf[i]='\n'; /*telnet encode \n as a 0 when in raw mode*/
			if (buf[i] == 0xff && buf[i+1] != 0xff) {
				i+=telnet_options(st,buf+i);
			} else 

				if(buf[i] == 0x1b) {
					/* ESCAPE! */
					if (buf[i+1]=='[' && st->status == HIST_COMMAND) {
						st->edited=1;
						switch (buf[i+2]) {
							case 'A': //fprintf(stderr,"UP\n");
								erase_line(st,0);
								put_history(st);
								get_history(1,st);
								redraw_line(st,0);
								st->bufindex=strlen(st->linebuf);
								break;
							case 'B': //fprintf(stderr,"DOWN\n");
								erase_line(st,0);
								put_history(st);
								get_history(-1,st);
								redraw_line(st,0);
								break;
							case 'C': //fprintf(stderr,"RIGHT\n");
								if (st->linebuf[st->bufindex] != '\0') {
									vdehist_termwrite(st->termfd,"\033[C",3);
									(st->bufindex)++;
								}
								break;
							case 'D': //fprintf(stderr,"LEFT\n");
								if (st->bufindex > 0) {
									vdehist_termwrite(st->termfd,"\033[D",3);
									(st->bufindex)--;
								}
								break;
						}
						i+=3;
					}
					else
						i+=2;/* ignored */
				} else if(buf[i] < 0x20 && !(buf[i] == '\n' || buf[i] == '\r')) {
					/*ctrl*/
					if (buf[i] == 4) /*ctrl D is a shortcut for UNIX people! */ {
						rv=1;
						break;
					}
					switch (buf[i]) {
						case 3:  /*ctrl C cleans the current buffer */
							erase_line(st,0);
							st->bufindex=0;
							st->linebuf[(st->bufindex)]=0;
							break;
						case 12: /* ctrl L redraw */
							erase_line(st,1);
							redraw_line(st,1);
							break;
						case 1: /* ctrl A begin of line */
							erase_line(st,0);
							st->bufindex=0;
							redraw_line(st,0);
							break;
						case 5: /* ctrl E endofline */
							erase_line(st,0);
							st->bufindex=strlen(st->linebuf);
							redraw_line(st,0);
						case '\t': /* tab */
							if (st->lastchar== '\t') {
								erase_line(st,1);
								showexpand(st->linebuf,st->bufindex,st->termfd);
								redraw_line(st,1);
							} else {
								erase_line(st,0);
								st->bufindex=tabexpand(st->linebuf,st->bufindex,BUFSIZE);
								redraw_line(st,0);
							}
							break;
					}
				} else if(buf[i] == 0x7f) {
					if(st->bufindex > 0) {
						char *x;
						(st->bufindex)--;
						x=st->linebuf+st->bufindex;
						memmove(x,x+1,strlen(x));
						if (st->echo && !(st->status & HIST_PASSWDFLAG)) {
							if (st->edited)
								vdehist_termwrite(st->termfd,"\010\033[P",4);
							else
								vdehist_termwrite(st->termfd,"\010 \010",3);
						}
					}
				} else {
					if (st->echo && !(st->status & HIST_PASSWDFLAG)) {
						if (st->edited && buf[i] >= ' ')
							vdehist_termwrite(st->termfd,"\033[@",3);
						vdehist_termwrite(st->termfd,&(buf[i]),1);
					}
					if (buf[i] != '\r') {
						if (buf[i]=='\n') {
							if (st->status == HIST_COMMAND) {
								st->histindex=0;
								put_history(st);
								if (strlen(st->linebuf) > 0)
									shift_history(st);
							}
							st->bufindex=strlen(st->linebuf);
							if ((rv=hist_sendcmd(st)) != 0)
								break; 
							st->bufindex=st->edited=st->histindex=0;
							st->linebuf[(st->bufindex)]=0;
						} else {
							char *x;
							x=st->linebuf+st->bufindex;
							memmove(x+1,x,strlen(x)+1);
							st->linebuf[(st->bufindex)++]=buf[i];
						}
					}
				}
			st->lastchar=buf[i];
		}
	}
	return rv;
}