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