Esempio n. 1
0
struct translation *get_translator(const char *encoding){
    struct translation *ret = find_translator(encoding);
    if(ret)
	return ret;
    ret = (struct translation *)DMALLOC(sizeof(struct translation),
        TAG_PERMANENT, "get_translator");
    char *name = (char *)DMALLOC(strlen(encoding)+18+1,
        TAG_PERMANENT, "get_translator");
    strcpy(name, encoding);
#ifdef __linux__
    strcat(name, "//TRANSLIT//IGNORE");
#endif
    ret->name = name;
    ret->incoming = iconv_open("UTF-8", encoding);
    ret->outgoing = iconv_open(name, "UTF-8");

    ret->next = 0;
    if(ret->incoming == (iconv_t)-1 || ret->outgoing == (iconv_t)-1){
	FREE(name);
	FREE(ret);
	return 0;
    }
    name[strlen(encoding)] = 0;
    if(!head)
	head = ret;
    else {
	struct translation *cur = head;
	while(cur->next)
	    cur = cur->next;
	cur->next = ret;
    }
    return ret;
}
Esempio n. 2
0
char *translate(iconv_t tr, const char *mes, int inlen, int *outlen){
    size_t len = inlen;
    size_t len2;
    unsigned char *tmp = (unsigned char *)mes;
    static char *res = 0;
    static size_t reslen = 0;
    char *tmp2;

    if(!res){
      res = (char *)DMALLOC(1, TAG_PERMANENT, "translate");
	reslen = 1;
    }

    tmp2 = res;
    len2 = reslen;

    while(len){
      iconv(tr, (char **)&tmp, &len, &tmp2, &len2);
#ifdef PACKAGE_DWLIB
		if(len > 1 && tmp[0] == 0xff && tmp[1] == 0xf9){
		len -=2;
		tmp +=2;
#else
		if(0){
#endif
	    } else {

		if(E2BIG == errno){
		  errno = 0;
		  tmp = (unsigned char *)mes;
		  len = strlen(mes)+1;
		  FREE(res);
		  reslen *= 2;
		  res = (char *)DMALLOC(reslen, TAG_PERMANENT, "translate");
		  tmp2 = res;
		  len2 = reslen;
		  continue;
		}
		tmp2[0] = 0;
		*outlen = reslen - len2;
		return res;
	    }

    }
    *outlen = reslen - len2;
    return res;
}

#else
char *translate(iconv_t tr, const char *mes, int inlen, int *outlen){
  *outlen = inlen;
  return (char *)mes;
}
Esempio n. 3
0
char *xalloc P1(int, size)
{
    char *p;
    static int going_to_exit;

    if (going_to_exit)
	exit(3);
#ifdef DEBUG
    if (size == 0)
	fatal("Tried to allocate 0 bytes.\n");
#endif
    p = (char *) DMALLOC(size, TAG_MISC, "main.c: xalloc");
    if (p == 0) {
	if (reserved_area) {
	    FREE(reserved_area);
	    p = "Temporarily out of MEMORY. Freeing reserve.\n";
	    write(1, p, strlen(p));
	    reserved_area = 0;
	    slow_shut_down_to_do = 6;
	    return xalloc(size);/* Try again */
	}
	going_to_exit = 1;
	fatal("Totally out of MEMORY.\n");
    }
    return p;
}
Esempio n. 4
0
void f_query_temp () {
    int idx;
    object_t *ob;
    unsigned short type;
    svalue_t *value;
    char *src, *dst;
    mapping_t *map;
    char *tmpstr;

    if( st_num_arg==2 ) {
        ob=sp->u.ob;
        pop_stack();
    } else
        ob = current_object;

    idx = find_global_variable(ob->prog, "tmp_dbase", &type, 0);
    if (idx == -1)
    {
        free_string_svalue(sp--);
        push_undefined();
        return;
    }
    value = &ob->variables[idx];

    if( value->type != T_MAPPING )
    {
    	free_string_svalue(sp--);
    	error("(query_temp) %s 物件的资料库变数型态错误。\n", ob->obname);
    }

    map = value->u.map;
    src = (char *)sp->u.string;
    dst = tmpstr = (char *)DMALLOC(SVALUE_STRLEN(sp) + 1, TAG_STRING, "query_temp");

    while (*src)
    {
	while (*src != '/' && *src)
	    *dst++ = *src++;
	if (*src == '/')
	{
	    while (*++src == '/');
	    if( dst == tmpstr ) continue;
	}
	*dst = '\0';
	value = find_string_in_mapping(map, tmpstr);

	if( value == &const0u ) break;
	if( value->type != T_MAPPING )
	{
	    if(*src) value = &const0u;
	    break;
	}
	map = value->u.map;
	dst = tmpstr;
    }

    FREE(tmpstr);
    free_string_svalue(sp--);
    push_svalue(value);
}
Esempio n. 5
0
File: file.c Progetto: Elohim/FGmud
/*
 * There is an error in a specific file. Ask the MudOS driver to log the
 * message somewhere.
 */
void smart_log (const char * error_file, int line, const char * what, int flag)
{
    char *buff;
    svalue_t *mret;
    extern int pragmas;

    buff = (char *)
        DMALLOC(strlen(error_file) + strlen(what) + 
                ((pragmas & PRAGMA_ERROR_CONTEXT) ? 100 : 40), TAG_TEMPORARY, "smart_log: 1");

    if (flag)
        sprintf(buff, "/%s line %d: Warning: %s", error_file, line, what);
    else
        sprintf(buff, "/%s line %d: %s", error_file, line, what);

    if (pragmas & PRAGMA_ERROR_CONTEXT) {
        char *ls = strrchr(buff, '\n');
        unsigned char *tmp;
        if (ls) {
            tmp = (unsigned char *)ls + 1;
            while (*tmp && isspace(*tmp)) tmp++;
            if (!*tmp) *ls = 0;
        }
        strcat(buff, show_error_context());
    } else strcat(buff, "\n");

    push_malloced_string(add_slash(error_file));
    copy_and_push_string(buff);
    mret = safe_apply_master_ob(APPLY_LOG_ERROR, 2);
    if (!mret || mret == (svalue_t *)-1) {
        debug_message("%s", buff);
    }
    FREE(buff);
}                               /* smart_log() */
Esempio n. 6
0
void set_of_REG_to_string (rbtree *t, strbuf *out, unsigned limit)
{
    unsigned cnt=rbtree_count(t);
    REG *keys=DMALLOC(REG, cnt, "keys");
    rbtree_return_all_keys (t, (void**)keys);
    make_compact_list_of_REGs (keys, cnt, out, limit);
    DFREE (keys);
};
Esempio n. 7
0
void
f_replace_program P2(int, num_arg, int, instruction)
{
    replace_ob_t *tmp;
    int name_len;
    char *name, *xname;
    program_t *new_prog;
    int var_offset;

    if (sp->type != T_STRING)
	bad_arg(1, instruction);
#ifdef DEBUG
    if (d_flag)
	debug_message("replace_program called\n");
#endif
    if (!current_object)
	error("replace_program called with no current object\n");
    if (current_object == simul_efun_ob)
	error("replace_program on simul_efun object\n");

    if (current_object->prog->func_ref)
	error("cannot replace a program with function references.\n");

    name_len = strlen(sp->u.string);
    name = (char *) DMALLOC(name_len + 3, TAG_TEMPORARY, "replace_program");
    xname = name;
    strcpy(name, sp->u.string);
    if (name[name_len - 2] != '.' || name[name_len - 1] != 'c')
	strcat(name, ".c");
    if (*name == '/')
	name++;
    new_prog = search_inherited(name, current_object->prog, &var_offset);
    FREE(xname);
    if (!new_prog) {
	error("program to replace the current with has to be inherited\n");
    }
    if (!(tmp = retrieve_replace_program_entry())) {
	tmp = ALLOCATE(replace_ob_t, TAG_TEMPORARY, "replace_program");
	tmp->ob = current_object;
	tmp->next = obj_list_replace;
	obj_list_replace = tmp;
    }
    tmp->new_prog = new_prog;
    tmp->var_offset = var_offset;
#ifdef DEBUG
    if (d_flag)
	debug_message("replace_program finished\n");
#endif
    free_string_svalue(sp--);
}
Esempio n. 8
0
void f_arr_to_str(){
  static struct translation *newt = 0;
  if(!newt){
    newt = get_translator("UTF-32");
  }
  int len = sp->u.arr->size;
  int *in = (int *)DMALLOC(sizeof(int)*(len+1), TAG_TEMPORARY, "f_arr_to_str");
  char *trans;
  in[len] = 0;
  while(len--)
    in[len] = sp->u.arr->item[len].u.number;

  trans = translate(newt->incoming, (char *)in, (sp->u.arr->size+1)*4, &len);
  FREE(in);
  pop_stack();
  copy_and_push_string(trans);
}
Esempio n. 9
0
void dump_buf_as_array_of_strings(MemoryCache *mc, address a, size_t size)
{
    strbuf sb=STRBUF_INIT;
    BYTE *buf=DMALLOC (BYTE, size, "BYTE*");
    if (MC_ReadBuffer (mc, a, size, buf)==false)
        goto exit;
    for (unsigned i=0; i<size; i+=sizeof(REG))
    {
        address a2=*(REG*)&buf[i];
        if (MC_get_any_string(mc, a2, &sb))
        {
            L ("0x" PRI_ADR_HEX "+0x%x: ptr to %s\n", a, i, sb.buf);
            strbuf_reinit(&sb, 0);
        };
    };
exit:
    DFREE (buf);
    strbuf_deinit(&sb);
};
Esempio n. 10
0
int main P2(int, argc, char **, argv)
{
    time_t tm;
    int i, new_mudlib = 0, got_defaults = 0;
    int no_ip_demon = 0;
    char *p;
    char version_buf[80];
#if 0
    int dtablesize;
#endif
    error_context_t econ;

#if !defined(LATTICE) && !defined(OLD_ULTRIX) && !defined(sequent) && \
    !defined(sgi)
    void tzset();
#endif
    struct lpc_predef_s predefs;

#if !defined(__SASC) && (defined(AMITCP) || defined(AS225))
    amiga_sockinit();
    atexit(amiga_sockexit);
#endif
#ifdef WRAPPEDMALLOC
    wrappedmalloc_init();
#endif				/* WRAPPEDMALLOC */
#ifdef DEBUGMALLOC
    MDinit();
#endif

#if (defined(PROFILING) && !defined(PROFILE_ON) && defined(HAS_MONCONTROL))
    moncontrol(0);
#endif
#if !defined(OLD_ULTRIX) && !defined(LATTICE) && !defined(sequent)
    tzset();
#endif
    boot_time = get_current_time();

    const0.type = T_NUMBER;
    const0.u.number = 0;
    const1.type = T_NUMBER;
    const1.u.number = 1;

    /* const0u used by undefinedp() */
    const0u.type = T_NUMBER;
    const0u.subtype = T_UNDEFINED;
    const0u.u.number = 0;

    /* const0n used by nullp() */
    const0n.type = T_NUMBER;
    const0n.subtype = T_NULLVALUE;
    const0n.u.number = 0;

    fake_prog.program_size = 0;

    /*
     * Check that the definition of EXTRACT_UCHAR() is correct.
     */
    p = (char *) &i;
    *p = -10;
    if (EXTRACT_UCHAR(p) != 0x100 - 10) {
	fprintf(stderr, "Bad definition of EXTRACT_UCHAR() in interpret.h.\n");
	exit(-1);
    }

    /*
     * An added test: can we do EXTRACT_UCHAR(x++)?
     * (read_number, etc uses it)
     */
    p = (char *) &i;
    (void) EXTRACT_UCHAR(p++);
    if ((p - (char *) &i) != 1) {
	fprintf(stderr, "EXTRACT_UCHAR() in interpret.h evaluates its argument more than once.\n");
	exit(-1);
    }

    /*
     * Check the living hash table size
     */
    if (CFG_LIVING_HASH_SIZE != 4 && CFG_LIVING_HASH_SIZE != 16 &&
	CFG_LIVING_HASH_SIZE != 64 && CFG_LIVING_HASH_SIZE != 256 &&
	CFG_LIVING_HASH_SIZE != 1024 && CFG_LIVING_HASH_SIZE != 4096) {
	fprintf(stderr, "CFG_LIVING_HASH_SIZE in options.h must be one of 4, 16, 64, 256, 1024, 4096, ...\n");
	exit(-1);
    }

#ifdef RAND
    srand(get_current_time());
#else
#  ifdef DRAND48
    srand48(get_current_time());
#  else
#    ifdef RANDOM
    srandom(get_current_time());
#    else
    fprintf(stderr, "Warning: no random number generator specified!\n");
#    endif
#  endif
#endif
    current_time = get_current_time();
    /*
     * Initialize the microsecond clock.
     */
    init_usec_clock();

    /* read in the configuration file */

    got_defaults = 0;
    for (i = 1; (i < argc) && !got_defaults; i++) {
	if (argv[i][0] != '-') {
	    set_defaults(argv[i]);
	    got_defaults = 1;
	}
    }
    if (!got_defaults) {
	fprintf(stderr, "You must specify the configuration filename as an argument.\n");
	exit(-1);
    }

    printf("Initializing internal tables....\n");
    init_strings();		/* in stralloc.c */
    init_otable();		/* in otable.c */
    init_identifiers();		/* in lex.c */
    init_locals();              /* in compiler.c */

/* disable this for now */
#if 0
    /*
     * We estimate that we will need MAX_USERS + MAX_EFUN_SOCKS + 10 file
     * descriptors if the maximum number of users were to log in and all LPC
     * sockets were in use.  This is a pretty close estimate.
     */
#ifndef LATTICE
    dtablesize = MAX_USERS + MAX_EFUN_SOCKS + 10;
#else
    /*
     * Amiga sockets separate from file descriptors
     */
    dtablesize = MAX_USERS + MAX_EFUN_SOCKS;
#endif

    /*
     * If our estimate is larger than FD_SETSIZE, then we need more file
     * descriptors than the operating system can handle.  This is a problem
     * that can be resolved by decreasing MAX_USERS, MAX_EFUN_SOCKS, or both.
     */
    if (dtablesize > FD_SETSIZE) {
	fprintf(stderr, "Warning: File descriptor requirements exceed system capacity!\n");
	fprintf(stderr, "         Configuration exceeds system capacity by %d descriptor(s).\n",
		dtablesize - FD_SETSIZE);
    }
#ifdef HAS_SETDTABLESIZE
    /*
     * If the operating system supports setdtablesize() then we can request
     * the number of file descriptors we really need.  First check to see if
     * wee already have enough.  If so dont bother the OS. If not, attempt to
     * allocate the number we estimated above.  There are system imposed
     * limits on file descriptors, so we may not get as many as we asked for.
     * Check to make sure we get enough.
     */
    if (getdtablesize() < dtablesize)
	if (setdtablesize(dtablesize) < dtablesize) {
	    fprintf(stderr, "Warning: Could not allocate enough file descriptors!\n");
	    fprintf(stderr, "         setdtablesize() could not allocate %d descriptor(s).\n",
		    getdtablesize() - dtablesize);
	}
    /*
     * Just be polite and tell the administrator how many he has.
     */
    fprintf(stderr, "%d file descriptors were allocated, (%d were requested).\n",
	    getdtablesize(), dtablesize);
#endif
#endif
    time_to_clean_up = TIME_TO_CLEAN_UP;
    time_to_swap = TIME_TO_SWAP;
    max_cost = MAX_COST;
    reserved_size = RESERVED_SIZE;
    max_array_size = MAX_ARRAY_SIZE;
    max_buffer_size = MAX_BUFFER_SIZE;
    max_string_length = MAX_STRING_LENGTH;
    master_file_name = (char *) MASTER_FILE;
    /* fix the filename */
    while (*master_file_name == '/') master_file_name++;
    p = master_file_name;
    while (*p++);
    if (p[-2]=='c' && p[-3]=='.')
	p[-3]=0;
    mud_lib = (char *) MUD_LIB;
    set_inc_list(INCLUDE_DIRS);
    if (reserved_size > 0)
	reserved_area = (char *) DMALLOC(reserved_size, TAG_RESERVED, "main.c: reserved_area");
    for (i = 0; i < sizeof consts / sizeof consts[0]; i++)
	consts[i] = exp(-i / 900.0);
    init_num_args();
    reset_machine(1);
    /*
     * The flags are parsed twice ! The first time, we only search for the -m
     * flag, which specifies another mudlib, and the D-flags, so that they
     * will be available when compiling master.c.
     */
    for (i = 1; i < argc; i++) {
	if (argv[i][0] != '-')
	    continue;
	switch (argv[i][1]) {
	case 'D':
	    if (argv[i][2]) {	/* Amylaar : allow flags to be passed down to
				 * the LPC preprocessor */
		struct lpc_predef_s *tmp;

		tmp = &predefs;
		tmp->flag = argv[i] + 2;
		tmp->next = lpc_predefs;
		lpc_predefs = tmp;
		continue;
	    }
	    fprintf(stderr, "Illegal flag syntax: %s\n", argv[i]);
	    exit(-1);
	case 'N':
	    no_ip_demon++;
	    continue;
#ifdef YYDEBUG
	case 'y':
	    yydebug = 1;
	    continue;
#endif				/* YYDEBUG */
	case 'm':
	    mud_lib = alloc_cstring(argv[i] + 2, "mudlib dir");
	    if (chdir(mud_lib) == -1) {
		fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib);
		exit(-1);
	    }
	    new_mudlib = 1;
	    break;
	}
    }
    if (!new_mudlib && chdir(mud_lib) == -1) {
	fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib);
	exit(-1);
    }
    get_version(version_buf);
    time(&tm);
    debug_message("----------------------------------------------------------------------------\n%s (%s) starting up on %s - %s\n\n", MUD_NAME, version_buf, ARCH, ctime(&tm));

#ifdef BINARIES
    init_binaries(argc, argv);
#endif
#ifdef LPC_TO_C
    init_lpc_to_c();
#endif
    add_predefines();

#ifndef NO_IP_DEMON
    if (!no_ip_demon && ADDR_SERVER_IP)
	init_addr_server(ADDR_SERVER_IP, ADDR_SERVER_PORT);
#endif				/* NO_IP_DEMON */

    eval_cost = max_cost;	/* needed for create() functions */

    save_context(&econ);
    if (SETJMP(econ.context)) {
	debug_message("The simul_efun (%s) and master (%s) objects must be loadable.\n", 
		      SIMUL_EFUN, MASTER_FILE);
	exit(-1);
    } else {
	init_simul_efun(SIMUL_EFUN);
	init_master(MASTER_FILE);
    }
    pop_context(&econ);

    for (i = 1; i < argc; i++) {
	if (argv[i][0] != '-') {
	    continue;
	} else {
	    /*
	     * Look at flags. -m and -o has already been tested.
	     */
	    switch (argv[i][1]) {
	    case 'D':
	    case 'N':
	    case 'm':
	    case 'y':
		continue;
	    case 'f':
		save_context(&econ);
		if (SETJMP(econ.context)) {
		    debug_message("Error while calling master::flag(\"%s\"), aborting ...", argv[i] + 2);
		    exit(-1);
		}
		push_constant_string(argv[i] + 2);
		(void) apply_master_ob(APPLY_FLAG, 1);
		if (MudOS_is_being_shut_down) {
		    debug_message("Shutdown by master object.\n");
		    exit(0);
		}
		pop_context(&econ);
		continue;
	    case 'e':
		e_flag++;
		continue;
	    case 'p':
		external_port[0].port = atoi(argv[i] + 2);
		continue;
            case 'd':
#ifdef DEBUG
                d_flag++;
#else
                debug_message("Driver must be compiled with DEBUG on to use -d.\n");
#endif
	    case 'c':
		comp_flag++;
		continue;
	    case 't':
		t_flag++;
		continue;
	    default:
		debug_message("Unknown flag: %s\n", argv[i]);
		exit(-1);
	    }
	}
    }
    if (MudOS_is_being_shut_down)
	exit(1);
    if (strlen(DEFAULT_FAIL_MESSAGE))
	default_fail_message = DEFAULT_FAIL_MESSAGE;
    else
	default_fail_message = "What?";
#ifdef PACKAGE_MUDLIB_STATS
    restore_stat_files();
#endif
#ifdef PACKAGE_SOCKETS
    init_sockets();		/* initialize efun sockets           */
#endif
    preload_objects(e_flag);
#ifdef SIGFPE
    signal(SIGFPE, sig_fpe);
#endif
#ifdef TRAP_CRASHES
#ifdef SIGUSR1
    signal(SIGUSR1, sig_usr1);
#endif
    signal(SIGTERM, sig_term);
    signal(SIGINT, sig_int);
#ifndef DEBUG
#if defined(SIGABRT) && !defined(LATTICE)
    signal(SIGABRT, sig_abrt);
#endif
#ifdef SIGIOT
    signal(SIGIOT, sig_iot);
#endif
#ifdef SIGHUP
    signal(SIGHUP, sig_hup);
#endif
#ifdef SIGBUS
    signal(SIGBUS, sig_bus);
#endif
#ifndef LATTICE
    signal(SIGSEGV, sig_segv);
    signal(SIGILL, sig_ill);
#endif
#endif				/* DEBUG */
#endif
    backend();
    return 0;
}
Esempio n. 11
0
Da_emulate_result Da_emulate(Da* d, CONTEXT * ctx, MemoryCache *mem, bool emulate_FS_accesses, address FS)
{
#ifdef _WIN64
    return DA_NOT_EMULATED;
#endif        
    //bool SF=IS_SET(ctx->EFlags, FLAG_SF);
    //bool OF=IS_SET(ctx->EFlags, FLAG_OF);
    //bool ZF=IS_SET(ctx->EFlags, FLAG_ZF);
    bool CF=IS_SET(ctx->EFlags, FLAG_CF);
    bool b;

    if (x86_emu_debug)
    {
        // FIXME: write to log also?
        L ("%s() begin: [", __func__);
        Da_DumpString(&cur_fds, d);
        L ("]\n");
    };

    if ((emulate_FS_accesses==false && IS_SET(d->prefix_codes, PREFIX_FS)) ||
            (IS_SET(d->prefix_codes, PREFIX_SS) || IS_SET(d->prefix_codes, PREFIX_GS)))
    {
        if (x86_emu_debug)
            L ("%s() skipping (data selector prefix present) at 0x" PRI_ADR_HEX "\n", __func__, CONTEXT_get_PC(ctx));
        return DA_EMULATED_CANNOT_READ_MEMORY;
    };

    switch (d->ins_code)
    {
        case I_CDQ:
            {
                uint32_t a=CONTEXT_get_Accum (ctx)&0xFFFFFFFF;
                CONTEXT_set_xDX (ctx, (a&0x80000000) ? 0xFFFFFFFF : 0);
                goto add_to_PC_and_return_OK;
            };
            break;

        case I_PUSH:
            {
                address rt_adr;
                obj v;
                b=Da_op_get_value_of_op (&d->op[0], &rt_adr, ctx, mem, __FILE__, __LINE__, &v, d->prefix_codes, FS);
                if (b==false)
                {
                    if (x86_emu_debug)
                        L ("%s() I_PUSH: can't read memory\n", __func__);
                    return DA_EMULATED_CANNOT_READ_MEMORY;
                };
                b=DO_PUSH (ctx, mem, obj_get_as_REG(&v));
                if (b==false)
                {
                    if (x86_emu_debug)
                        L ("%s() I_PUSH: can't write memory\n", __func__);
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
                };
                goto add_to_PC_and_return_OK;
            };
            break;

        case I_PUSHFD:
            if (DO_PUSH (ctx, mem, ctx->EFlags | FLAG_TF)==false)
            {
                if (x86_emu_debug)
                    L ("%s() I_PUSHFD: can't write memory\n", __func__);
                return DA_EMULATED_CANNOT_WRITE_MEMORY;
            };
            goto add_to_PC_and_return_OK;
            break;

        case I_POP:
            {
                REG val;
                if (DO_POP(ctx, mem, &val)==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;
                obj v;
                obj_tetrabyte2 (val, &v);
                Da_op_set_value_of_op (&d->op[0], &v, ctx, mem, d->prefix_codes, FS);
                goto add_to_PC_and_return_OK;
            };
            break;

        case I_POPFD:
            {
                REG val;
                if (DO_POP(ctx, mem, &val)==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;
                ctx->EFlags=val;
                goto add_to_PC_and_return_OK;
            };
            break;
        
        case I_LEAVE:
            {
                //ESP <- EBP
                //POP EBP

                REG val;
                CONTEXT_set_SP(ctx, CONTEXT_get_BP(ctx));
                if (DO_POP(ctx, mem, &val)==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY; // FIXME: а надо еще SP назад возвращать!
                CONTEXT_set_BP(ctx, val);
                goto add_to_PC_and_return_OK;
            };
            break;

        case I_REP_STOSB:
        case I_REP_STOSW:
        case I_REP_STOSD:
            {
                BYTE *buf;
                bool DF=IS_SET(ctx->EFlags, FLAG_DF);
                if (DF)
                    return DA_NOT_EMULATED; // not supported... bug here

                SIZE_T BUF_SIZE;

                if (d->ins_code==I_REP_STOSB)
                    BUF_SIZE=CONTEXT_get_xCX (ctx);
                else if (d->ins_code==I_REP_STOSW)
                    BUF_SIZE=CONTEXT_get_xCX (ctx)*2;
                else if (d->ins_code==I_REP_STOSD)
                    BUF_SIZE=CONTEXT_get_xCX (ctx)*4;

                buf=DMALLOC(BYTE, BUF_SIZE, "buf");

                if (d->ins_code==I_REP_STOSB)
                {
                    for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()!
                        buf[i]=CONTEXT_get_Accum(ctx)&0xFF;
                } 
                else if (d->ins_code==I_REP_STOSW)
                {
                    for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()!
                        ((WORD*)buf)[i]=CONTEXT_get_Accum(ctx)&0xFFFF;
                } 
                else if (d->ins_code==I_REP_STOSD)
                {
                    for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()!
                        ((DWORD*)buf)[i]=(DWORD)(CONTEXT_get_Accum(ctx)&0xFFFFFFFF);
                } 
                else
                {
                    oassert(0);
                };

                if (MC_WriteBuffer (mem, CONTEXT_get_xDI (ctx), BUF_SIZE, buf)==false)
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
                DFREE(buf);
                CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) + BUF_SIZE);
                CONTEXT_set_xCX (ctx, 0);
                goto add_to_PC_and_return_OK;
            };
            break;

        case I_REP_MOVSB:
        case I_REP_MOVSW:
        case I_REP_MOVSD:
            {
                BYTE *buf;
                bool DF=IS_SET(ctx->EFlags, FLAG_DF);
                if (DF)
                    return DA_NOT_EMULATED; // not supported... bug here

                SIZE_T BUF_SIZE;
                SIZE_T sizeof_element;

                if (d->ins_code==I_REP_MOVSB)
                    sizeof_element=1;
                else if (d->ins_code==I_REP_MOVSW)
                    sizeof_element=2;
                else if (d->ins_code==I_REP_MOVSD)
                    sizeof_element=4;
                else
                {
                    oassert(0);
                };

                BUF_SIZE=CONTEXT_get_xCX(ctx)*sizeof_element;

                //printf ("%s() BUF_SIZE=0x%x\n", __func__, BUF_SIZE);
                //printf ("%s() (before) SI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xSI(ctx));
                //printf ("%s() (before) DI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xDI(ctx));

                buf=DMALLOC(BYTE, BUF_SIZE, "buf");

                address blk_src=CONTEXT_get_xSI(ctx);
                address blk_dst=CONTEXT_get_xDI(ctx);

                if (DF)
                {
                    blk_src-=BUF_SIZE; // +sizeof_element;
                    blk_dst-=BUF_SIZE; // +sizeof_element;
                };

                if (MC_ReadBuffer (mem, blk_src, BUF_SIZE, buf)==false)
                {
                    DFREE(buf);
                    return DA_EMULATED_CANNOT_READ_MEMORY;
                };

                if (MC_WriteBuffer (mem, blk_dst, BUF_SIZE, buf)==false)
                {
                    DFREE(buf);
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
                };

                DFREE(buf);
                if (DF==false)
                {
                    CONTEXT_set_xSI (ctx, CONTEXT_get_xSI (ctx) + BUF_SIZE);
                    CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) + BUF_SIZE);
                }
                else
                {
                    CONTEXT_set_xSI (ctx, CONTEXT_get_xSI (ctx) - BUF_SIZE);
                    CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) - BUF_SIZE);
                };
                CONTEXT_set_xCX (ctx, 0);

                //printf ("%s() (after) SI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xSI(ctx));
                //printf ("%s() (after) DI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xDI(ctx));

                goto add_to_PC_and_return_OK;
            };

        case I_STD:
            SET_BIT (ctx->EFlags, FLAG_DF);
            goto add_to_PC_and_return_OK;

        case I_CLD:
            REMOVE_BIT (ctx->EFlags, FLAG_DF);
            goto add_to_PC_and_return_OK;

        case I_RETN:
            {
                WORD ret_arg=0;
                if (d->ops_total==1)
                {
                    oassert (d->op[0].type==DA_OP_TYPE_VALUE);
                    ret_arg=obj_get_as_wyde(&d->op[0].val._v); // RETN arg is 16-bit
                };

                address newPC;
                if (DO_POP(ctx, mem, &newPC)==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;
                CONTEXT_set_SP(ctx, CONTEXT_get_SP(ctx)+ret_arg);
                CONTEXT_set_PC(ctx, newPC);
                return DA_EMULATED_OK;
            };
            break;

        case I_ADD:
        case I_ADC:
        case I_INC:
            {
                //L (__FUNCTION__ "() I_ADD/I_INC begin: [%s]\n", ToString().c_str());

                obj rt1, rt2;
                REG rt1_adr, rt2_adr;
                b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;
                if (d->ins_code==I_ADD || d->ins_code==I_ADC)
                {
                    oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits);
                    b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS);
                    if (b==false)
                        return DA_EMULATED_CANNOT_READ_MEMORY;
                }
                else
                {   // INC case
                    // make second op 1
                    obj_REG2_and_set_type (rt1.t, 1, 0, &rt2);
                };

                obj res_sum;
                obj_add (&rt1, &rt2, &res_sum);
                if (d->ins_code==I_ADC && CF)
                    obj_increment(&res_sum); 

                set_PF (ctx, &res_sum);
                set_SF (ctx, &res_sum);
                set_ZF (ctx, &res_sum);
                set_AF (ctx, &rt1, &rt2, &res_sum);
                if (d->ins_code==I_ADD || d->ins_code==I_ADC)
                    set_or_clear_flag (ctx, FLAG_CF, obj_compare (&res_sum, &rt1)==-1); // res_sum < rt1

                octabyte tmp=((zero_extend_to_REG(&rt1) ^ zero_extend_to_REG(&rt2) ^ 
                            get_sign_bit (d->op[0].value_width_in_bits)) & 
                        (zero_extend_to_REG(&res_sum) ^ zero_extend_to_REG(&rt1))) 
                    & 
                    get_sign_bit (d->op[0].value_width_in_bits);
                set_or_clear_flag (ctx, FLAG_OF, tmp);

                b=Da_op_set_value_of_op (&d->op[0], &res_sum, ctx, mem, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
                goto add_to_PC_and_return_OK;
            };
            break;

        case I_NOT:
            {
                obj rt1, res;
                REG rt1_adr;
                if (Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS)==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;

                obj_NOT(&rt1, &res);

                if (Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS))
                    goto add_to_PC_and_return_OK;
            };
            break;

        case I_NEG:
            {
                obj rt1, res;
                REG rt1_adr;
                if (Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS)==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;

                obj_NEG(&rt1, &res);
                set_or_clear_flag (ctx, FLAG_CF, obj_is_zero(&rt1)==false);

                set_PF (ctx, &res);
                set_SF (ctx, &res);
                set_ZF (ctx, &res);
                set_or_clear_flag (ctx, FLAG_AF, (0 ^ obj_get_4th_bit(&rt1)) ^ obj_get_4th_bit(&res));
                REMOVE_BIT (ctx->EFlags, FLAG_OF);
                //SET_BIT (ctx->EFlags, FLAG_AF);

                if (Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS))
                    goto add_to_PC_and_return_OK;
            };
            break;


        case I_OR:
        case I_XOR:
        case I_AND:
        case I_TEST:
            {
                oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits);
                obj rt1, rt2, res;
                REG rt1_adr, rt2_adr;
                b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;
                b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;

                switch (d->ins_code)
                {
                    case I_OR:  
                        obj_OR(&rt1, &rt2, &res); 
                        break;
                    case I_XOR: 
                        obj_XOR(&rt1, &rt2, &res); 
                        break;
                    case I_TEST: 
                    case I_AND: 
                        obj_AND(&rt1, &rt2, &res); 
                        break;
                    default: 
                        oassert(0);
                        break;
                };

                set_PF (ctx, &res);
                set_SF (ctx, &res);
                set_ZF (ctx, &res);
                REMOVE_BIT (ctx->EFlags, FLAG_AF);
                REMOVE_BIT (ctx->EFlags, FLAG_CF);
                REMOVE_BIT (ctx->EFlags, FLAG_OF);

                if (d->ins_code==I_TEST)
                    b=true;
                else
                    b=Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS);

                if (b)
                    goto add_to_PC_and_return_OK;
                else
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
            };
            break;

        case I_DEC:
        case I_SUB:
        case I_SBB:
        case I_CMP:
            {
                if (d->ins_code==I_SUB || d->ins_code==I_SBB || d->ins_code==I_CMP)
                {
                    oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits);
                };
                obj rt1, rt2;
                REG rt1_adr, rt2_adr;
                b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS);
                if (b==false) 
                    return DA_EMULATED_CANNOT_READ_MEMORY;
                if (d->ins_code==I_DEC)
                {
                    // make second op 1
                    obj_REG2_and_set_type (rt1.t, 1, 0, &rt2);
                }
                else
                {
                    b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS);
                    if (b==false)
                        return DA_EMULATED_CANNOT_READ_MEMORY;
                };

                obj res;
                obj_subtract (&rt1, &rt2, &res);
                if (d->ins_code==I_SBB && CF)
                    obj_decrement (&res);

                set_PF (ctx, &res);
                set_SF (ctx, &res);
                set_ZF (ctx, &res);
                set_AF (ctx, &rt1, &rt2, &res);

                if (d->ins_code==I_SBB)
                {
                    int tmp=(obj_compare (&rt1, &res)==-1 /* rt1<res */) || (CF && obj_get_as_tetrabyte(&rt2)==0xffffffff);
                    set_or_clear_flag (ctx, FLAG_CF, tmp);
                }
                else
                {
                    if (d->ins_code!=I_DEC) // DEC leave CF flag unaffected
                        set_or_clear_flag (ctx, FLAG_CF, obj_compare (&rt1, &rt2)==-1); /* rt1<rt2 */
                };

                octabyte tmp=((zero_extend_to_octabyte(&rt1) ^ zero_extend_to_octabyte(&rt2)) & 
                        (zero_extend_to_octabyte(&res) ^ zero_extend_to_octabyte(&rt1))) &
                    get_sign_bit (d->op[0].value_width_in_bits);
                set_or_clear_flag (ctx, FLAG_OF, tmp);

                if (d->ins_code==I_CMP)
                    b=true;
                else
                    b=Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS);

                if (b)
                    goto add_to_PC_and_return_OK;
                else
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
            };
            break;

        case I_XCHG:
            {
                REG op1_adr, op2_adr;

                obj op1;
                b=Da_op_get_value_of_op(&d->op[0], &op1_adr, ctx, mem, __FILE__, __LINE__, &op1, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;

                obj op2;
                b=Da_op_get_value_of_op(&d->op[1], &op2_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;

                if (Da_op_set_value_of_op (&d->op[0], &op2, ctx, mem, d->prefix_codes, FS)==false)
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;

                if (Da_op_set_value_of_op (&d->op[1], &op1, ctx, mem, d->prefix_codes, FS)==false)
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;

                goto add_to_PC_and_return_OK;
            };
            break;

        case I_MOV:
        case I_MOVDQA:
        case I_MOVDQU:
            return Da_emulate_MOV_op1_op2(d, ctx, mem, d->prefix_codes, FS);

        case I_MOVZX:
        case I_MOVSX:
            {
                address rt_adr;
                obj op2;
                bool b=Da_op_get_value_of_op(&d->op[1], &rt_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS);
                if (b==false)
                {
                    /*
                       if (L_verbose_level>=2)
                       {
                       printf (__FUNCTION__ "(): [");
                       Da_DumpString(d);
                       printf ("]: can't read src (2nd) operand\n");
                       };
                       */
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
                };

                obj to_be_stored_v;

                if (d->ins_code==I_MOVZX)
                {
                    enum obj_type op1_type_will_be=bit_width_to_obj_type (d->op[0].value_width_in_bits);
                    obj_zero_extend (&op2, op1_type_will_be, &to_be_stored_v);
                }
                else if (d->ins_code==I_MOVSX)
                {
                    enum obj_type op1_type_will_be=bit_width_to_obj_type (d->op[0].value_width_in_bits);
                    obj_sign_extend (&op2, op1_type_will_be, &to_be_stored_v);
                }
                else
                {
                    oassert (0);
                };

                b=Da_op_set_value_of_op (&d->op[0], &to_be_stored_v, ctx, mem, d->prefix_codes, FS);

                if (b==false)
                {
                    /*
                       if (L_verbose_level>=2)
                       {
                       printf(__FUNCTION__ "(): [");
                       Da_DumpString(d);
                       printf ("]: can't write dst (1st) operand\n");
                       };
                       */
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
                };
                goto add_to_PC_and_return_OK;
            };

        case I_NOP:
            goto add_to_PC_and_return_OK;

        case I_LEA:
            {
                address a=(address)Da_op_calc_adr_of_op(&d->op[1], ctx, mem, d->prefix_codes, FS);
                obj val;
                obj_tetrabyte2(a, &val);
                b=Da_op_set_value_of_op (&d->op[0], &val, ctx, mem, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_WRITE_MEMORY;
                goto add_to_PC_and_return_OK;
            };

        case I_SAR:
        case I_SHR:
        case I_SHL:
            {
                // http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH06/CH06-3.html

                REG op1_adr, op2_adr;

                obj op1;
                bool b=Da_op_get_value_of_op(&d->op[0], &op1_adr, ctx, mem, __FILE__, __LINE__, &op1, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;

                // should be read anyway!
                obj op2;
                b=Da_op_get_value_of_op(&d->op[1], &op2_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS);
                if (b==false)
                    return DA_EMULATED_CANNOT_READ_MEMORY;
#ifdef _WIN64 
                obj_AND_with (&op2, 0x3F);
#else
                obj_AND_with (&op2, 0x1F);
#endif
                if (obj_is_zero(&op2)==false)
                {
                    unsigned new_CF;

                    if (d->ins_code==I_SHR || d->ins_code==I_SAR)
                        new_CF=(zero_extend_to_octabyte(&op1) >> (obj_get_as_byte (&op2) - 1)) & 1;
                    else // SHL
                        new_CF=(zero_extend_to_octabyte(&op1) >> (obj_width_in_bits(&op1) - obj_get_as_byte (&op2))) & 1;

                    obj new_op1;

                    if (d->ins_code==I_SHR)
                    {
                        REG new_v=zero_extend_to_REG(&op1) >> obj_get_as_byte (&op2);
                        obj_REG2_and_set_type(op1.t, new_v, 0, &new_op1);
                    }
                    else if (d->ins_code==I_SAR)
Esempio n. 12
0
void f_thread() {

	int sv[2];
	fd = find_new_socket();
	    if (fd < 0) 
	    	return fd;
	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
		return EESOCKET;
	ret = fork();
	if (ret == -1) {
		error("fork() in debug() failed: %s\n", strerror(errno));
	}
	if(ret){
		close(sv[1]);
        lpc_socks[fd].fd = sv[0];
        lpc_socks[fd].flags = S_EXTERNAL;
        set_read_callback(fd, sp-3);
        set_write_callback(fd, sp-2);
        set_close_callback(fd, sp-1);
        lpc_socks[fd].owner_ob = current_object;
        lpc_socks[fd].mode = MUD;
        lpc_socks[fd].state = STATE_DATA_XFER;
        memset((char *) &lpc_socks[fd].l_addr, 0, sizeof(lpc_socks[fd].l_addr));
        memset((char *) &lpc_socks[fd].r_addr, 0, sizeof(lpc_socks[fd].r_addr));
        lpc_socks[fd].owner_ob = current_object;
        lpc_socks[fd].release_ob = NULL;
        lpc_socks[fd].r_buf = NULL;
        lpc_socks[fd].r_off = 0;
        lpc_socks[fd].r_len = 0;
        lpc_socks[fd].w_buf = NULL;
        lpc_socks[fd].w_off = 0;
        lpc_socks[fd].w_len = 0;

        current_object->flags |= O_EFUN_SOCKET;
        return fd;
	}
	close(sv[0]);
	function_to_call_t cb;
	memset(&cb, 0, sizeof(function_to_call_t));
	process_efun_callback(0, &cb, F_THREAD);
	for(i=0; i<5; i++)
	  if(external_port[i].port)
	    close(external_port[i].fd); //close external ports
	for(i=0;i<sizeof(lpc_socks)/sizeof(lpc_socks[0]);i++)
		close(lpc_sock[i].fd);
	svalue_t *res = call_efun_callback(&cb, 1);
	switch (res->type) {

	        case T_OBJECT:
	            break;
	        default:
	            save_svalue_depth = 0;
	            int len = svalue_save_size(message);
	            if (save_svalue_depth > MAX_SAVE_SVALUE_DEPTH) {
	            	OS_socket_write(sv[1], "\x00\x00\x00\x11\"result too big\"", 21);
	            	break;
	            }
	            char *buf = (char *)
	                DMALLOC(len + 5, TAG_TEMPORARY, "socket_write: default");
	            if (buf == NULL)
	                break;
	            *(INT_32 *) buf = htonl((long) len);
	            len += 4;
	            buf[4] = '\0';
	            p = buf + 4;
	            save_svalue(message, &p);
	            int ret,written = 0;
	            while(written < len){
	            	ret = OS_socket_write(sv[1], buf+written, len-written);
	            	if(ret < 0)
	            		break;
	            	written += ret;
	            }
	            break;
	        }
	fflush(0);
	exit(0);
}
Esempio n. 13
0
void f_delete_temp () {
    int i;
    object_t *ob;
    svalue_t *value, lv;
    mapping_t *map;
    unsigned short type;
    char *src, *dst;

    if( st_num_arg == 2 )
    {
    	ob = sp->u.ob;
    	pop_stack();
    }
    else
    	ob = current_object;

    i = find_global_variable(ob->prog, "tmp_dbase", &type, 0);
    if (i == -1)
    {
        free_string_svalue(sp--);
        error("(delete_temp) %s 物件未宣告全域映射资料库变数。\n", ob->obname);
    }

    value = &ob->variables[i];

    if( value->type != T_MAPPING )
    {
        free_string_svalue(sp--);
    	error("(delete_temp) %s 物件的资料库变数型态错误。\n", ob->obname);
    }

    map = value->u.map;
    src = (char *)sp->u.string;
    dst = (char *)DMALLOC(SVALUE_STRLEN(sp)+1, TAG_STRING, "delete_temp");

    while(*src)
    {
    	i = 0;

	while(*src != '/' && *src)
	    *(dst+(i++)) = *src++;

	if(*src == '/')
	{
	    while (*++src == '/');
	    if(!i) continue;
	}

	*(dst+i) = '\0';

	value = find_string_in_mapping(map, dst);

	if( value == &const0u ) break;

	if(!*src)
	{
   	    	lv.type = T_STRING;
   	    	lv.subtype = STRING_CONSTANT;
    		lv.u.string = dst;
	    	mapping_delete(map, &lv);
	    	FREE(dst);
	    	free_string_svalue(sp--);
	    	return;
	}
	if( value->type != T_MAPPING ) break;

	map = value->u.map;
    }

    FREE(dst);
    free_string_svalue(sp--);
}
Esempio n. 14
0
void f_addn_temp () {
    int i, j;
    object_t *ob;
    unsigned short type;
    mapping_t *map;
    svalue_t *value;
    char *src, *dst;
    char *tmpstr;

    if( st_num_arg == 3 )
    {
        ob = sp->u.ob;
        pop_stack();
    }
    else
        ob = current_object;

    i = find_global_variable(ob->prog, "tmp_dbase", &type, 0);
    if (i == -1)
    {
        pop_2_elems();
        error("(addn_temp) %s 物件未宣告全域映射资料库变数。\n", ob->obname);
    }

    value = &ob->variables[i];

    if( value->type != T_MAPPING )
    {
    	pop_2_elems();
    	error("(addn_temp) %s 物件的资料库变数型态错误。\n", ob->obname);
    }

    map = value->u.map;
    src = (char *)(sp-1)->u.string;
    dst = tmpstr = (char *)DMALLOC(SVALUE_STRLEN(sp-1) + 1, TAG_STRING, "addn_temp");
    j=0;

    while (*src)
    {
    	i=0;
    	if( ++j > 20 )
	{
    		pop_2_elems();
    		error("(addn_temp) %s too deep mapping(20)。\n", ob->obname);
    	}

	while (*src != '/' && *src)
	{
	    *(dst+i) = *src++;
	    i++;
	}

	if (*src == '/')
	{
	    while (*++src == '/');
	    if(!i) continue;
	}
	*(dst+i) = '\0';

	value = find_string_in_mapping(map, tmpstr);

	if(!*src)
	{
    		if( value == &const0u || value->type != T_NUMBER )
    		{
    			value = insert_in_mapping(map, dst);
			*value = *sp--;
    		}
    		else
    			value->u.number += (sp--)->u.number;
    		break;
    	}

	if(value == &const0u || value->type != T_MAPPING)
	{
    		value = insert_in_mapping(map, dst);
		value->type = T_MAPPING;
		value->u.map = allocate_mapping(0);
	}

	map = value->u.map;
	dst = tmpstr;
    }

    FREE(tmpstr);
    free_string_svalue(sp--);
    push_svalue(value);
}
Esempio n. 15
0
int main (int argc, char ** argv)
{
    time_t tm;
    int i, new_mudlib = 0, got_defaults = 0;
    char *p;
    char version_buf[80];
#if 0
    int dtablesize;
#endif
    error_context_t econ;

#ifdef PROTO_TZSET
    void tzset();
#endif

#ifdef INCL_LOCALE_H
    setlocale(LC_ALL, "C");
#endif

#if !defined(__SASC) && (defined(AMITCP) || defined(AS225))
    amiga_sockinit();
    atexit(amiga_sockexit);
#endif
#ifdef WRAPPEDMALLOC
    wrappedmalloc_init();
#endif        /* WRAPPEDMALLOC */
#ifdef DEBUGMALLOC
    MDinit();
#endif

#if (defined(PROFILING) && !defined(PROFILE_ON) && defined(HAS_MONCONTROL))
    moncontrol(0);
#endif
#ifdef USE_TZSET
    tzset();
#endif
    boot_time = get_current_time();

    const0.type = T_NUMBER;
    const0.u.number = 0;
    const1.type = T_NUMBER;
    const1.u.number = 1;

    /* const0u used by undefinedp() */
    const0u.type = T_NUMBER;
    const0u.subtype = T_UNDEFINED;
    const0u.u.number = 0;

    //fake_prog.program_size = 0; //0 anyway

    /*
     * Check that the definition of EXTRACT_UCHAR() is correct.
     */
    p = (char *) &i;
    *p = -10;
    if (EXTRACT_UCHAR(p) != 0x100 - 10) {
        fprintf(stderr, "Bad definition of EXTRACT_UCHAR() in interpret.h.\n");
        exit(-1);
    }

    /*
     * An added test: can we do EXTRACT_UCHAR(x++)?
     * (read_number, etc uses it)
     */
    p = (char *) &i;
    (void) EXTRACT_UCHAR(p++);
    if ((p - (char *) &i) != 1) {
        fprintf(stderr, "EXTRACT_UCHAR() in interpret.h evaluates its argument more than once.\n");
        exit(-1);
    }

    /*
     * Check the living hash table size
     */
    if (CFG_LIVING_HASH_SIZE != 4 && CFG_LIVING_HASH_SIZE != 16 &&
            CFG_LIVING_HASH_SIZE != 64 && CFG_LIVING_HASH_SIZE != 256 &&
            CFG_LIVING_HASH_SIZE != 1024 && CFG_LIVING_HASH_SIZE != 4096) {
        fprintf(stderr, "CFG_LIVING_HASH_SIZE in options.h must be one of 4, 16, 64, 256, 1024, 4096, ...\n");
        exit(-1);
    }

#ifdef RAND
    srand(get_current_time());
#else
#  ifdef DRAND48
    srand48(get_current_time());
#  else
#    ifdef RANDOM
    srandom(get_current_time());
#    else
    fprintf(stderr, "Warning: no random number generator specified!\n");
#    endif
#  endif
#endif
    current_time = get_current_time();
    /*
     * Initialize the microsecond clock.
     */
    init_usec_clock();

    /* read in the configuration file */

    got_defaults = 0;
    for (i = 1; (i < argc) && !got_defaults; i++) {
        if (argv[i][0] != '-') {
            set_defaults(argv[i]);
            got_defaults = 1;
        }
    }
    get_version(version_buf);
    if (!got_defaults) {
        fprintf(stderr, "%s for %s.\n", version_buf, ARCH);
        fprintf(stderr, "You must specify the configuration filename as an argument.\n");
        exit(-1);
    }

    printf("Initializing internal tables....\n");
    init_strings();   /* in stralloc.c */
    init_otable();    /* in otable.c */
    init_identifiers();   /* in lex.c */
    init_locals();              /* in compiler.c */

    /*
     * If our estimate is larger than FD_SETSIZE, then we need more file
     * descriptors than the operating system can handle.  This is a problem
     * that can be resolved by decreasing MAX_USERS, MAX_EFUN_SOCKS, or both.
     *
     * Unfortunately, since neither MAX_USERS or MAX_EFUN_SOCKS exist any more,
     * we have no clue how many we will need.  This code really should be
     * moved to places where ENFILE/EMFILE is returned.
     */
#if 0
    if (dtablesize > FD_SETSIZE) {
        fprintf(stderr, "Warning: File descriptor requirements exceed system capacity!\n");
        fprintf(stderr, "         Configuration exceeds system capacity by %d descriptor(s).\n",
                dtablesize - FD_SETSIZE);
    }
#ifdef HAS_SETDTABLESIZE
    /*
     * If the operating system supports setdtablesize() then we can request
     * the number of file descriptors we really need.  First check to see if
     * wee already have enough.  If so dont bother the OS. If not, attempt to
     * allocate the number we estimated above.  There are system imposed
     * limits on file descriptors, so we may not get as many as we asked for.
     * Check to make sure we get enough.
     */
    if (getdtablesize() < dtablesize)
        if (setdtablesize(dtablesize) < dtablesize) {
            fprintf(stderr, "Warning: Could not allocate enough file descriptors!\n");
            fprintf(stderr, "         setdtablesize() could not allocate %d descriptor(s).\n",
                    getdtablesize() - dtablesize);
        }
    /*
     * Just be polite and tell the administrator how many he has.
     */
    fprintf(stderr, "%d file descriptors were allocated, (%d were requested).\n",
            getdtablesize(), dtablesize);
#endif
#endif
    time_to_clean_up = TIME_TO_CLEAN_UP;
    max_cost = MAX_COST;
    reserved_size = RESERVED_SIZE;
    max_array_size = MAX_ARRAY_SIZE;
    if(max_array_size > 65535){
        fprintf(stderr, "Maximum array size can not exceed 65535");
        max_array_size = 65535;
    }
    max_buffer_size = MAX_BUFFER_SIZE;
    max_string_length = MAX_STRING_LENGTH;
    mud_lib = (char *) MUD_LIB;
    set_inc_list(INCLUDE_DIRS);
    if (reserved_size > 0)
        reserved_area = (char *) DMALLOC(reserved_size, TAG_RESERVED, "main.c: reserved_area");
    for (i = 0; i < sizeof consts / sizeof consts[0]; i++)
        consts[i] = exp(-i / 900.0);
    reset_machine(1);
    /*
     * The flags are parsed twice ! The first time, we only search for the -m
     * flag, which specifies another mudlib, and the D-flags, so that they
     * will be available when compiling master.c.
     */
    for (i = 1; i < argc; i++) {
        if (argv[i][0] != '-')
            continue;
        switch (argv[i][1]) {
            case 'D':
                if (argv[i][2]) {
                    lpc_predef_t *tmp = ALLOCATE(lpc_predef_t, TAG_PREDEFINES,
                            "predef");
                    tmp->flag = argv[i] + 2;
                    tmp->next = lpc_predefs;
                    lpc_predefs = tmp;
                    continue;
                }
                fprintf(stderr, "Illegal flag syntax: %s\n", argv[i]);
                exit(-1);
            case 'N':
                no_ip_demon++;
                continue;
#ifdef HAS_CONSOLE
            case 'C':
                has_console = 1;
                continue;
#endif
#ifdef YYDEBUG
            case 'y':
                yydebug = 1;
                continue;
#endif        /* YYDEBUG */
            case 'm':
                mud_lib = alloc_cstring(argv[i] + 2, "mudlib dir");
                if (chdir(mud_lib) == -1) {
                    fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib);
                    exit(-1);
                }
                new_mudlib = 1;
                break;
        }
    }
    if (!new_mudlib && chdir(mud_lib) == -1) {
        fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib);
        exit(-1);
    }
    time(&tm);
    debug_message("----------------------------------------------------------------------------\n%s (%s) starting up on %s - %s\n\n", MUD_NAME, version_buf, ARCH, ctime(&tm));

    add_predefines();
#ifdef WIN32
    _tzset();
#endif

#ifndef NO_IP_DEMON
    if (!no_ip_demon && ADDR_SERVER_IP)
        init_addr_server(ADDR_SERVER_IP, ADDR_SERVER_PORT);
#endif        /* NO_IP_DEMON */

    set_eval(max_cost);

    save_context(&econ);
    if (SETJMP(econ.context)) {
        debug_message("The simul_efun (%s) and master (%s) objects must be loadable.\n",
                SIMUL_EFUN, MASTER_FILE);
        exit(-1);
    } else {
        init_simul_efun(SIMUL_EFUN);
        init_master();
    }
    pop_context(&econ);

    for (i = 1; i < argc; i++) {
        if (argv[i][0] != '-') {
            continue;
        } else {
            /*
             * Look at flags. -m and -o has already been tested.
             */
            switch (argv[i][1]) {
                case 'D':
                case 'N':
                case 'm':
                case 'y':
                case 'C':
                    continue;
                case 'f':
                    save_context(&econ);
                    if (SETJMP(econ.context)) {
                        debug_message("Error while calling master::flag(\"%s\"), aborting ...\n", argv[i] + 2);
                        exit(-1);
                    }
                    push_constant_string(argv[i] + 2);
                    apply_master_ob(APPLY_FLAG, 1);
                    if (MudOS_is_being_shut_down) {
                        debug_message("Shutdown by master object.\n");
                        exit(0);
                    }
                    pop_context(&econ);
                    continue;
                case 'e':
                    e_flag++;
                    continue;
                case 'p':
                    external_port[0].port = atoi(argv[i] + 2);
                    continue;
                case 'd':
#ifdef DEBUG_MACRO
                    if (argv[i][2])
                        debug_level_set(&argv[i][2]);
                    else
                        debug_level |= DBG_d_flag;
#else
                    debug_message("Driver must be compiled with DEBUG_MACRO on to use -d.\n");
#endif
                    break;
                case 'c':
                    comp_flag++;
                    continue;
                case 't':
                    t_flag++;
                    continue;
                default:
                    debug_message("Unknown flag: %s\n", argv[i]);
                    exit(-1);
            }
        }
    }
    if (MudOS_is_being_shut_down)
        exit(1);
    if (*(DEFAULT_FAIL_MESSAGE)) {
        char buf[8192];

        strcpy(buf, DEFAULT_FAIL_MESSAGE);
        strcat(buf, "\n");
        default_fail_message = make_shared_string(buf);
    } else
        default_fail_message = "What?\n";
#ifdef PACKAGE_MUDLIB_STATS
    restore_stat_files();
#endif
    preload_objects(e_flag);
#ifdef SIGFPE
    signal(SIGFPE, sig_fpe);
#endif
#ifdef TRAP_CRASHES
#ifdef SIGUSR1
    signal(SIGUSR1, sig_usr1);
#endif
#ifdef SIGUSR2
    signal(SIGUSR2, sig_usr2);
#endif
    signal(SIGTERM, sig_term);
    signal(SIGINT, sig_int);
#ifndef DEBUG
#if defined(SIGABRT)
    signal(SIGABRT, sig_abrt);
#endif
#ifdef SIGIOT
    signal(SIGIOT, sig_iot);
#endif
#ifdef SIGHUP
    signal(SIGHUP, sig_hup);
#endif
#ifdef SIGBUS
    signal(SIGBUS, sig_bus);
#endif
    signal(SIGSEGV, sig_segv);
    signal(SIGILL, sig_ill);
#endif        /* DEBUG */
#endif
#ifndef WIN32
#ifdef USE_BSD_SIGNALS
    signal(SIGCHLD, sig_cld);
#else
    signal(SIGCLD, sig_cld);
#endif
#endif

#ifdef HAS_CONSOLE
    if(has_console >= 0)
        signal(SIGTTIN, sig_ttin);
    signal(SIGTTOU, SIG_IGN);
#endif

    backend();
    return 0;
}
Esempio n. 16
0
static array_t *pcre_match(array_t *v, svalue_t *pattern, int flag)
{
	pcre_t *run;
	array_t *ret;
	svalue_t *sv1, *sv2;
	char *res;
	int num_match, size, match = !(flag & 2);

	if (!(size = v->size))
		return &the_null_array;

	run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "pcre_match : run");
	run->ovector = NULL;
	run->ovecsize = 0;
	assign_svalue_no_free(&run->pattern, pattern);

	run->re = pcre_get_cached_pattern(&pcre_cache, &run->pattern);

	if (run->re == NULL)
	{
		if (pcre_local_compile(run) == NULL)
		{
			const char *rerror = run->error;
			int offset = run->erroffset;

			pcre_free_memory(run);
			error("PCRE compilation failed at offset %d: %s\n", offset, rerror);
		}
		else
			pcre_cache_pattern(&pcre_cache, run->re, &run->pattern);
	}

	res       = (char*)DMALLOC(size, TAG_TEMPORARY, "prcre_match: res");
	sv1       = v->item + size;
	num_match = 0;

	while (size--)
	{
		if ((--sv1)->type != T_STRING)
		{
			res[size] = 0;
			continue;
		}

		run->subject  = sv1->u.string;
		run->s_length = SVALUE_STRLEN(sv1);

		pcre_local_exec(run);

		if (pcre_query_match(run) != match) //was not checking for match! (woom)
		{
			res[size] = 0;
			continue;
		}

		res[size] = 1;
		num_match++;
	}

	flag &= 1;
	ret  = allocate_empty_array(num_match << flag);
	sv2  = ret->item + (num_match << flag);
	size = v->size;

	while (size--)
	{
		if (res[size])
		{
			if (flag)
			{
				(--sv2)->type = T_NUMBER;
				sv2->u.number = size + 1;
			}

			(--sv2)->type = T_STRING;

			sv1  = v->item + size;
			*sv2 = *sv1;

			if (sv1->subtype & STRING_COUNTED)
			{
				INC_COUNTED_REF(sv1->u.string);
				ADD_STRING(MSTR_SIZE(sv1->u.string));
			}

			if (!--num_match)
				break;
		}
	}
	FREE(res);
	pcre_free_memory(run);

	return ret;
}