//-------------------------------------------------------------------------- static void load_dl_header(linput_t *li) { if ( first_text_subspace_fpos == -1 ) return; qlseek(li, first_text_subspace_fpos); dl_header dl; lread(li, &dl, sizeof(dl)); dl.swap(); switch ( dl.hdr_version ) { case OLD_HDR_VERSION: break; case HDR_VERSION : break; default: msg("Unknown DL header version, skipping...\n"); } if ( dl.string_table_size != 0 ) { dl_ssize = dl.string_table_size; dl_strings = (char *)qalloc(dl_ssize); if ( dl_strings == NULL ) nomem("dl_strings"); qlseek(li, first_text_subspace_fpos+dl.string_table_loc); lread(li, dl_strings, dl_ssize); } if ( dl.dreloc_count ) complain_fixup(); load_imports(li, dl); load_exports(li, dl); qfree(dl_strings); dl_strings = NULL; }
//----------------------------------------------------------------------- static void show_extdefs(linput_t *li, uint32 offset, uint32 length) { if ( offset == 0 || length == 0 ) return; qlseek(li, offset); inf.specsegs = 1; int segsize = 4 * h.num_externals; sel_t sel = h.num_segs+1; set_selector(sel, 0); xea = freechunk(inf.maxEA, segsize, -15); add_segm(sel, xea, xea+segsize, "XTRN", "XTRN"); set_segm_addressing(getseg(xea), true); int n = 0; for ( int i=0; i < length; n++ ) { extdef p; const int size = offsetof(extdef, allocate_len); lread(li, &p, size); p.allocate_len.len_4 = 0; if ( p.allocate ) { ask_for_feedback("extdef.allocate\n"); lread(li, &p.allocate_len.len_4, sizeof(p.allocate_len.len_4)); } int nlen = read_pstring(li, p.sym_name, sizeof(p.sym_name)); i += size + 1 + nlen; ea_t a = xea + 4*n; set_name(a, p.sym_name); if ( p.allocate ) put_long(a, p.allocate_len.len_4); } }
//----------------------------------------------------------------------- static int read_pstring(linput_t *li, char *name, int size) { char buf[256]; uchar nlen; lread(li, &nlen, sizeof(nlen)); lread(li, buf, nlen); buf[nlen] = '\0'; qstrncpy(name, buf, size); return nlen; }
//-------------------------------------------------------------------------- static char *get_name(linput_t *li, long tableoff, size_t tablesize, long nidx, char *buf, size_t bufsize) { if ( nidx >= tablesize ) return ""; long fpos = qltell(li); qlseek(li, tableoff+nidx-4); ulong len; lread(li, &len, sizeof(len)); len = swap32(len); if ( len >= bufsize ) len = bufsize-1; lread(li, buf, len); buf[len] = '\0'; qlseek(li, fpos); return buf; }
int main() { Value *result; init(); // List manipulation. defnative(mksym("CONS"), native_cons); defnative(mksym("CAR"), native_car); defnative(mksym("CDR"), native_cdr); // Arithmetic. defnative(mksym("PLUS"), native_plus); defnative(mksym("MINUS"), native_minus); defnative(mksym("MUL"), native_mul); defnative(mksym("DIV"), native_div); // Miscellaneous. defnative(mksym("EVAL"), native_eval); defglobal(mksym("NIL"), LISP_NIL); while (!feof(stdin)) { setjmp(toplevel_escape); printf("> "); result = eval(lread(), global_env); printf("\n"); lwrite(result); printf("\n"); } return 0; }
/* stdio.h */ void repl(void) { LISP x,cw; double rt; while(1) { if ((gc_status_flag) || heap >= heap_end) { rt = myruntime(); gc(); printf("GC took %g seconds, %ld compressed to %ld, %ld free\n", myruntime()-rt,old_heap_used,heap-heap_org,heap_end-heap); } printf("> "); x = lread(); if EQ(x,eof_val) break; rt = myruntime(); cw = heap; x = leval(x,NIL); printf("Evaluation took %g seconds %ld cons work\n", myruntime()-rt,heap-cw); lprint(x); } }
//-------------------------------------------------------------------------- static void load_subspaces(linput_t *li, header &h, long fpos, int n) { if ( !n ) return; char buf[MAXSTR]; for ( int i=0; i < n; i++ ) { subspace_dictionary_record sr; qlseek(li, fpos + i*sizeof(sr)); lread(li, &sr, sizeof(sr)); sr.swap(); if ( !sr.is_loadable() || !sr.subspace_length ) continue; if ( sr.fixup_request_quantity ) complain_fixup(); ea_t start = sr.subspace_start; ea_t end = start + sr.initialization_length; file2base(li, sr.file_loc_init_value, start, end, FILEREG_PATCHABLE); end = start + sr.subspace_length; char *name = get_space_name(li, h, sr.name.n_strx, buf, sizeof(buf)); set_selector(i, 0); const char *sclass = strstr(name, "CODE") ? CLASS_CODE : CLASS_DATA; add_segm(i, start, end, name, sclass); if ( i == first_text_subspace_idx ) first_text_subspace_fpos = sr.file_loc_init_value; // sr.alignment, } }
//----------------------------------------------------------------------- static void show_segdefs(linput_t *li, uint32 offset, uint32 length) { if ( offset == 0 || length == 0 ) return; qlseek(li, offset); int n = 0; for ( int i=0; i < length; ) { segdef s; const int size = offsetof(segdef, combine_name); lread(li, &s, size); int nlen = read_pstring(li, s.combine_name, sizeof(s.combine_name)); i += size + 1 + nlen; n++; const char *sname = s.combine_name; const char *sclas = sname; if ( strnicmp(sname, "CODE", 4) == 0 ) sclas = "CODE"; if ( strnicmp(sname, "DATA", 4) == 0 ) sclas = "DATA"; if ( strnicmp(sname, "CONST", 5) == 0 ) sclas = "CONST"; if ( stricmp(sname, "STACK") == 0 ) sclas = "STACK"; if ( strchr(sname, ':') != NULL ) continue; int segsize = s.slimit + 1; if ( strcmp(sname, "DATA") == 0 ) dsel = n; set_selector(n, 0); ea_t ea = freechunk(inf.maxEA, segsize, -(1<<s.align)); add_segm(n, ea, ea+segsize, sname, sclas); set_segm_addressing(getseg(ea), true); if ( strcmp(sclas, "STACK") == 0 ) doByte(ea, segsize); } }
//-------------------------------------------------------------------------- static void load_imports(linput_t *li, dl_header &dl) { if ( !dl.import_list_count ) return; qlseek(li, first_text_subspace_fpos+dl.import_list_loc); ea_t ea = data_start + dl.dlt_loc; int n = dl.dlt_count; char buf[MAXSTR]; for ( int i=0; i < dl.import_list_count; i++ ) { import_entry ie; lread(li, &ie, sizeof(ie)); ie.swap(); if ( n == 0 ) ea = data_start + dl.plt_loc; n--; buf[0] = '.'; get_text_name(ie.name, &buf[1], sizeof(buf)-1); do_name_anyway(ea, buf); doDwrd(ea, 4); set_offset(ea, 0, 0); if ( n > 0 ) { ea += 4; } else { ea_t ea2 = get_long(ea); do_name_anyway(ea2, &buf[1]); add_func(ea2, BADADDR); set_func_cmt(get_func(ea2), "THUNK", false); doDwrd(ea+4, 4); ea += 8; } } }
BOOL DLLCALL removefiledat(scfg_t* cfg, file_t* f) { char c,str[MAX_PATH+1],ixbname[12],*ixbbuf,fname[13]; int i,file; long l,length; SAFECOPY(fname,f->name); for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[i]=fname[i+1]; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) { return(FALSE); } length=(long)filelength(file); if(!length) { close(file); return(FALSE); } if((ixbbuf=(char *)malloc(length))==0) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free((char *)ixbbuf); return(FALSE); } close(file); if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) { return(FALSE); } for(l=0;l<length;l+=F_IXBSIZE) { for(i=0;i<11;i++) ixbname[i]=ixbbuf[l+i]; ixbname[i]=0; if(stricmp(ixbname,fname)) if(lwrite(file,&ixbbuf[l],F_IXBSIZE)!=F_IXBSIZE) { close(file); free((char *)ixbbuf); return(FALSE); } } free((char *)ixbbuf); close(file); SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_WRONLY|O_BINARY,SH_DENYRW))==-1) { return(FALSE); } lseek(file,f->datoffset,SEEK_SET); c=ETX; /* If first char of record is ETX, record is unused */ if(write(file,&c,1)!=1) { /* So write a D_T on the first byte of the record */ close(file); return(FALSE); } close(file); if(f->dir==cfg->user_dir) /* remove file from index */ rmuserxfers(cfg,0,0,f->name); return(TRUE); }
Value *lreadlist() { Value *car, *cdr; if (peekchar() == ')') { getchar(); // eat ) return LISP_NIL; } car = lread(); cdr = lreadlist(); return mkpair(car, cdr); }
//-------------------------------------------------------------------------- static void load_exports(linput_t *li, dl_header &dl) { if ( !dl.export_list_count ) return; qlseek(li, first_text_subspace_fpos+dl.export_list_loc); for ( int i=0; i < dl.export_list_count; i++ ) { char buf[MAXSTR]; export_entry ee; lread(li, &ee, sizeof(ee)); ee.swap(); add_entry(ee.value, ee.value, get_text_name(ee.name, buf, sizeof(buf)), ee.type == ST_CODE); } }
//------------------------------------------------------------------------ inline bool pe_loader_t::read_header(linput_t *li, bool silent) { uint32 peoff = 0; link_ulink = false; qlseek(li, peoff); lread(li, &exe, sizeof(exe)); if ( exe.exe_ident != PEEXE_ID ) { if ( exe.exe_ident == EXE_ID ) { char tmp[8]; if ( qlread(li, tmp, sizeof(tmp)) == sizeof(tmp) && memcmp(tmp, "UniLink", 8) == 0 ) { link_ulink = true; } } qlseek(li, PE_PTROFF); lread(li, &peoff, sizeof(peoff)); } return read_header(li, peoff, silent); }
//-------------------------------------------------------------------------- static void load_aux_headers(linput_t *li, long fpos, size_t size) { if ( !size ) return; qlseek(li, fpos); while ( size > 0 ) { char buf[4096]; aux_id aih; lread(li, &aih, sizeof(aih)); aih.swap(); size_t total = sizeof(aih) + aih.length; if ( total >= sizeof(buf) ) loader_failure("Too big aux_header size %u", total); if ( total > size ) return; // loader_failure("Illegal aux header size %u, rest %u", total, size); size -= total; qlseek(li, -sizeof(aih), SEEK_CUR); lread(li, buf, total); switch ( aih.type ) { case HPUX_AUX_ID: { som_exec_auxhdr *p = (som_exec_auxhdr*)buf; p->swap(); inf.start_cs = 0; inf.startIP = p->exec_entry; data_start = p->exec_dmem; } break; case VERSION_AUX_ID: case COPYRIGHT_AUX_ID: case SHLIB_VERSION_AUX_ID: default: break; } } }
BOOL DLLCALL putfileixb(scfg_t* cfg, file_t* f) { char str[MAX_PATH+1],fname[13]; uchar* ixbbuf; int file; long l,length; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDWR|O_BINARY,SH_DENYRW))==-1) { return(FALSE); } length=(long)filelength(file); if(length%F_IXBSIZE) { close(file); return(FALSE); } if((ixbbuf=(uchar *)malloc(length))==NULL) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free(ixbbuf); return(FALSE); } SAFECOPY(fname,f->name); for(l=8;l<12;l++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[l]=fname[l+1]; for(l=0;l<length;l+=F_IXBSIZE) { SAFEPRINTF(str,"%11.11s",ixbbuf+l); if(!stricmp(str,fname)) break; } free(ixbbuf); if(l>=length) { close(file); return(FALSE); } lseek(file,l+11+3,SEEK_SET); write(file,&f->dateuled,4); write(file,&f->datedled,4); close(file); return(TRUE); }
//------------------------------------------------------------------------ inline int pe_loader_t::process_sections(linput_t *li, off_t first_sec_pos, int nobjs, pe_section_visitor_t &psv) { transvec.qclear(); qvector <pesection_t> sec_headers; // does the file layout match memory layout? bool alt_align = pe.objalign == pe.filealign && pe.objalign < PAGE_SIZE; for ( int i=0; i < nobjs; i++ ) { pesection_t& sh = sec_headers.push_back(); qlseek(li, first_sec_pos + i*sizeof(pesection_t)); lread(li, &sh, sizeof(sh)); if ( sh.s_vaddr != uint32(sh.s_scnptr) || sh.s_vsize > sh.s_psize ) alt_align = false; } if ( alt_align ) // according to Ivan Teblin from AVERT Labs, such files are // mapped by Windows as-is and not section by section // we mimic that behaviour psv.load_all(); int off_align = alt_align ? pe.filealign : FILEALIGN; if ( pe.is_efi() ) off_align = 1; for ( int i=0; i < nobjs; i++ ) { pesection_t &sh = sec_headers[i]; uint32 scnptr = align_down(sh.s_scnptr, off_align);//pe.align_down_in_file(sh.s_scnptr); transl_t &tr = transvec.push_back(); tr.start = sh.s_vaddr; tr.psize = sh.get_psize(pe); tr.end = pe.align_up_in_file(uint32(sh.s_vaddr + tr.psize)); tr.pos = scnptr; int code = psv.visit_section(sh, scnptr); if ( code != 0 ) return code; } if ( nobjs == 0 ) { // add mapping for the header transl_t &tr = transvec.push_back(); tr.start = 0; tr.psize = qlsize(li); tr.end = pe.align_up_in_file(pe.imagesize); tr.pos = 0; } return 0; }
//-------------------------------------------------------------------------- static void load_spaces(linput_t *li, header &h, long fpos, int n) { if ( !n ) return; qlseek(li, fpos); char buf[MAXSTR]; for ( int i=0; i < n; i++ ) { space_dictionary_record sr; lread(li, &sr, sizeof(sr)); sr.swap(); get_space_name(li, h, sr.name.n_strx, buf, sizeof(buf)); if ( strcmp(buf, "$TEXT$") == 0 ) first_text_subspace_idx = sr.subspace_index; } }
BOOL DLLCALL getfileixb(scfg_t* cfg, file_t* f) { char str[MAX_PATH+1],fname[13]; uchar * ixbbuf; int file; long l,length; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) { return(FALSE); } length=(long)filelength(file); if(length%F_IXBSIZE) { close(file); return(FALSE); } if((ixbbuf=(uchar *)malloc(length))==NULL) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free((char *)ixbbuf); return(FALSE); } close(file); SAFECOPY(fname,f->name); for(l=8;l<12;l++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[l]=fname[l+1]; for(l=0;l<length;l+=F_IXBSIZE) { SAFEPRINTF(str,"%11.11s",ixbbuf+l); if(!stricmp(str,fname)) break; } if(l>=length) { free((char *)ixbbuf); return(FALSE); } l+=11; f->datoffset=ixbbuf[l]|((long)ixbbuf[l+1]<<8)|((long)ixbbuf[l+2]<<16); f->dateuled=ixbbuf[l+3]|((long)ixbbuf[l+4]<<8) |((long)ixbbuf[l+5]<<16)|((long)ixbbuf[l+6]<<24); f->datedled=ixbbuf[l+7]|((long)ixbbuf[l+8]<<8) |((long)ixbbuf[l+9]<<16)|((long)ixbbuf[l+10]<<24); free((char *)ixbbuf); return(TRUE); }
//----------------------------------------------------------------------- static void read_text(linput_t *li) { text txt; const int size = offsetof(text, segment); lread(li, &txt, size); if ( txt.length != 0 ) { uint32 fptr = qltell(li); ea_t sea = getsea(txt.txt_IN); if ( sea != BADADDR ) { sea += txt.txt_offset; file2base(li, fptr, sea, sea+txt.length, FILEREG_PATCHABLE); } qlseek(li, fptr+txt.length); } }
//---------------------------------------------------------------------- static char *get_string(linput_t *li, int32 snames_table, int32 off, char *buf, size_t bufsize) { if ( ssize_t(bufsize) <= 0 ) return NULL; if ( off == -1 ) { buf[0] = '\0'; return NULL; } qlseek(li, snames_table+off); lread(li, buf, bufsize); buf[bufsize-1] = '\0'; return buf; }
//-------------------------------------------------------------------------- static void load_symbols(linput_t *li, header &h, long fpos, int n) { if ( !n ) return; qlseek(li, fpos); char buf[MAXSTR]; for ( int i=0; i < n; i++ ) { symbol_dictionary_record sr; lread(li, &sr, sizeof(sr)); sr.swap(); if ( sr.symbol_scope() == SS_UNSAT ) continue; char *name = get_symbol_name(li, h, sr.name.n_strx, buf, sizeof(buf)); ea_t ea = sr.symbol_value & ~3; switch ( sr.symbol_type() ) { case ST_NULL : case ST_ABSOLUTE : break; case ST_DATA : do_name_anyway(ea, name); break; case ST_STUB : append_cmt(ea, "STUB", false); case ST_CODE : case ST_ENTRY : case ST_MILLICODE: case ST_MILLI_EXT: add_entry(ea, ea, name, true); add_entry(ea, ea, name, true); break; case ST_PRI_PROG : case ST_STORAGE : case ST_MODULE : case ST_SYM_EXT : case ST_ARG_EXT : case ST_PLABEL : case ST_OCT_DIS : case ST_TSTORAGE : break; } } }
Value *lread() { char ch; again: ch = getchar(); if (isspace(ch)) goto again; ungetc(ch, stdin); if (isalpha(ch)) return lreadsym(); else if (isdigit(ch)) return lreadint(); else if (ch == '(') { getchar(); return lreadlist(); } else if (ch == '\'') { getchar(); return mkpair(quote_sym, mkpair(lread(), LISP_NIL)); } else { getchar(); error("Unrecognized token."); exit(1); } }
//----------------------------------------------------------------------- static void show_pubdefs(linput_t *li, uint32 offset, uint32 length) { if ( offset == 0 || length == 0 ) return; qlseek(li, offset); for ( int i=0; i < length; ) { pubdef p; const int size = offsetof(pubdef, sym_name); lread(li, &p, size); int nlen = read_pstring(li, p.sym_name, sizeof(p.sym_name)); i += size + 1 + nlen; ea_t sea = getsea(p.PUB_segment); if ( sea != BADADDR ) { sea += p.PUB_offset; add_entry(sea, sea, p.sym_name, segtype(sea) == SEG_CODE); } } }
//------------------------------------------------------------------------ inline int pe_loader_t::process_delayed_imports(linput_t *li, pe_import_visitor_t &il) { if ( pe.didtab.rva == 0 ) return 0; if ( transvec.empty() ) process_sections(li); int code = 0; uint32 ni = 0; bool ok = true; while ( true ) { uint32 table = pe.didtab.rva + ni*uint32(sizeof(dimpdir_t)); if ( !vseek(li, table) ) break; dimpdir_t &id = il.did; lread(li, &id, sizeof(id)); if ( !id.dllname ) break; il.withbase = (id.attrs & DIMP_NOBASE) == 0; uval_t base = il.withbase ? 0 : uval_t(get_imagebase()); ea_t atable = id.diat + base; ea_t ltable = id.dint; char dll[MAXSTR]; uint32 off = uint32(il.withbase ? id.dllname - (ea_t)pe.imagebase() : id.dllname); asciiz(li, off, dll, sizeof(dll), &ok); if ( !ok ) break; ansi2idb(dll); code = il.visit_module(dll, atable, ltable); if ( code != 0 ) break; code = process_import_table(li, pe, atable, ltable, il); if ( code != 0 ) break; ni++; } return ok || code != 0 ? code : -1; }
//-------------------------------------------------------------------------- void load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/) { header h; qlseek(li, 0); lread(li, &h, sizeof(h)); h.swap(); if ( ph.id != PLFM_HPPA ) set_processor_type("hppa", SETPROC_ALL|SETPROC_FATAL); inf.baseaddr = 0; load_aux_headers(li, h.aux_header_location, h.aux_header_size); load_spaces(li, h, h.space_location, h.space_total); load_subspaces(li, h, h.subspace_location, h.subspace_total); load_symbols(li, h, h.symbol_location, h.symbol_total); load_dl_header(li); create_filename_cmt(); ulong dp = h.presumed_dp; if ( dp == 0 ) { // 23 61 28 00 ldil ...., %dp // 37 7B 01 60 ldo 0xB0(%dp), %dp if ( ua_ana0(inf.startIP) && cmd.Op1.type == o_imm && cmd.Op2.type == o_reg ) { ulong v = cmd.Op1.value; if ( ua_ana0(cmd.ea+4) && cmd.Op1.type == o_displ ) dp = v + cmd.Op1.addr; } } if ( dp != 0 ) { netnode n; n.create("$ got"); n.altset(0, dp+1); } add_til("hpux"); }
BOOL DLLCALL findfile(scfg_t* cfg, uint dirnum, char *filename) { char str[MAX_PATH+1],fname[13],*ixbbuf; int i,file; long length,l; SAFECOPY(fname,filename); strupr(fname); for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[i]=fname[i+1]; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code); if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) return(FALSE); length=(long)filelength(file); if(!length) { close(file); return(FALSE); } if((ixbbuf=(char *)malloc(length))==NULL) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free((char *)ixbbuf); return(FALSE); } close(file); for(l=0;l<length;l+=F_IXBSIZE) { for(i=0;i<11;i++) if(toupper(fname[i])!=toupper(ixbbuf[l+i])) break; if(i==11) break; } free((char *)ixbbuf); if(l!=length) return(TRUE); return(FALSE); }
/* Important change as of Nov-16-2006, 'cmdline' may contain args */ long sbbs_t::exec_bin(const char *cmdline, csi_t *csi, const char* startup_dir) { char str[MAX_PATH+1]; char mod[MAX_PATH+1]; char modname[MAX_PATH+1]; char* p; int file; csi_t bin; SAFECOPY(mod,cmdline); p=mod; FIND_CHAR(p,' '); if(*p) { *p=0; /* terminate 'mod' */ p++; /* skip space */ SKIP_CHAR(p,' '); /* skip more spaces */ } if(*p) strcpy(main_csi.str, p); #ifdef JAVASCRIPT if((p=getfext(mod))!=NULL && stricmp(p,".js")==0) return(js_execfile(cmdline, startup_dir)); if(p==NULL && startup_dir!=NULL && *startup_dir) { SAFEPRINTF2(str,"%s%s.js", startup_dir, mod); if(fexistcase(str)) return(js_execfile(cmdline, startup_dir)); } if(cfg.mods_dir[0]) { SAFEPRINTF2(str,"%s%s.js",cfg.mods_dir,mod); if(fexistcase(str)) return(js_execfile(cmdline, startup_dir)); } #endif SAFECOPY(modname,mod); if(!strchr(modname,'.')) strcat(modname,".bin"); SAFEPRINTF2(str,"%s%s",cfg.mods_dir,modname); if(cfg.mods_dir[0]==0 || !fexistcase(str)) { #ifdef JAVASCRIPT SAFEPRINTF2(str,"%s%s.js",cfg.exec_dir,mod); if(fexistcase(str)) return(js_execfile(cmdline, startup_dir)); #endif SAFEPRINTF2(str,"%s%s",cfg.exec_dir,modname); fexistcase(str); } if((file=nopen(str,O_RDONLY))==-1) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); return(-1); } memcpy(&bin,csi,sizeof(csi_t)); clearvars(&bin); bin.length=(uint32_t)filelength(file); if((bin.cs=(uchar *)malloc(bin.length))==NULL) { close(file); errormsg(WHERE,ERR_ALLOC,str,bin.length); return(-1); } if(lread(file,bin.cs,bin.length)!=bin.length) { close(file); errormsg(WHERE,ERR_READ,str,bin.length); free(bin.cs); return(-1); } close(file); bin.ip=bin.cs; bin.rets=0; bin.cmdrets=0; bin.misc=0; while(exec(&bin)==0) if(!(bin.misc&CS_OFFLINE_EXEC)) { checkline(); if(!online) break; } freevars(&bin); free(bin.cs); csi->logic=bin.logic; return(bin.retval); }
void sbbs_t::sof(char *fname, char *answers, long len) { char str[256],*buf,max,min,cr; int file; long length,l=0,m,a=0; sprintf(str,"%s%s.sif",cfg.text_dir,fname); if((file=nopen(str,O_RDONLY))==-1) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); answers[0]=0; return; } length=filelength(file); if((buf=(char *)malloc(length))==0) { close(file); errormsg(WHERE,ERR_ALLOC,str,length); answers[0]=0; return; } if(lread(file,buf,length)!=length) { close(file); errormsg(WHERE,ERR_READ,str,length); answers[0]=0; return; } close(file); while(l<length && online) { min=max=cr=0; while(l<length && buf[l++]!=STX); for(m=l;m<length;m++) if(buf[m]==ETX || !buf[m]) { buf[m]=0; break; } if(l>=length) break; if(online==ON_REMOTE) { rioctl(IOCM|ABORT); rioctl(IOCS|ABORT); } putmsg(buf+l,P_SAVEATR); m++; if(toupper(buf[m])!='C' && toupper(buf[m])!='S') continue; SYNC; if(online==ON_REMOTE) rioctl(IOSM|ABORT); if(a>=len) { bprintf("\r\nSOF: %s defined more data than buffer size " "(%lu bytes)\r\n",fname,len); break; } if((buf[m]&0xdf)=='C') { if((buf[m+1]&0xdf)=='U') /* Uppercase only */ m++; else if((buf[m+1]&0xdf)=='N') /* Numbers only */ m++; if((buf[m+1]&0xdf)=='L') { /* Draw line */ if(term_supports(COLOR)) attr(cfg.color[clr_inputline]); else attr(BLACK|BG_LIGHTGRAY); bputs(" \b"); m++; } if((buf[m+1]&0xdf)=='R') { /* Add CRLF */ cr=1; m++; } outchar(answers[a++]); attr(LIGHTGRAY); CRLF; if(cr) a+=2; } else if((buf[m]&0xdf)=='S') { /* String */ if((buf[m+1]&0xdf)=='U') m++; else if((buf[m+1]&0xdf)=='F') m++; else if((buf[m+1]&0xdf)=='N') /* Numbers only */ m++; if((buf[m+1]&0xdf)=='L') { if(term_supports(COLOR)) attr(cfg.color[clr_inputline]); else attr(BLACK|BG_LIGHTGRAY); m++; } if((buf[m+1]&0xdf)=='R') { cr=1; m++; } if(isdigit(buf[m+1])) { max=buf[++m]&0xf; if(isdigit(buf[m+1])) max=max*10+(buf[++m]&0xf); } if(buf[m+1]=='.' && isdigit(buf[m+2])) { m++; min=buf[++m]&0xf; if(isdigit(buf[m+1])) min=min*10+(buf[++m]&0xf); } if(buf[m+1]=='"') { max=0; m++; while(buf[++m]!='"' && max<80) max++; } if(!max) continue; getrec(answers,a,max,str); bputs(str); attr(LIGHTGRAY); CRLF; if(!cr) a+=max; else a+=max+2; } } free((char *)buf); }
void sbbs_t::resort(uint dirnum) { char str[25],ixbfname[128],datfname[128],exbfname[128],txbfname[128] ,ext[512],nulbuf[512]; char tmp[512]; uchar* ixbbuf, *datbuf; uchar* ixbptr[MAX_FILES]; int ixbfile,datfile,exbfile,txbfile,i,j; long ixblen,datlen,offset,newoffset,l; memset(nulbuf,0,512); bprintf(text[ResortLineFmt],cfg.lib[cfg.dir[dirnum]->lib]->sname,cfg.dir[dirnum]->sname); sprintf(ixbfname,"%s%s.ixb",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code); sprintf(datfname,"%s%s.dat",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code); sprintf(exbfname,"%s%s.exb",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code); sprintf(txbfname,"%s%s.txb",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code); if(flength(ixbfname)<1L || flength(datfname)<1L) { remove(exbfname); remove(txbfname); remove(ixbfname); remove(datfname); bputs(text[ResortEmptyDir]); return; } bputs(text[Sorting]); if((ixbfile=nopen(ixbfname,O_RDONLY))==-1) { errormsg(WHERE,ERR_OPEN,ixbfname,O_RDONLY); return; } if((datfile=nopen(datfname,O_RDONLY))==-1) { close(ixbfile); errormsg(WHERE,ERR_OPEN,datfname,O_RDONLY); return; } ixblen=(long)filelength(ixbfile); datlen=(long)filelength(datfile); if((ixbbuf=(uchar *)malloc(ixblen))==NULL) { close(ixbfile); close(datfile); errormsg(WHERE,ERR_ALLOC,ixbfname,ixblen); return; } if((datbuf=(uchar *)malloc(datlen))==NULL) { close(ixbfile); close(datfile); free((char *)ixbbuf); errormsg(WHERE,ERR_ALLOC,datfname,datlen); return; } if(lread(ixbfile,ixbbuf,ixblen)!=ixblen) { close(ixbfile); close(datfile); free((char *)ixbbuf); free((char *)datbuf); errormsg(WHERE,ERR_READ,ixbfname,ixblen); return; } if(lread(datfile,datbuf,datlen)!=datlen) { close(ixbfile); close(datfile); free((char *)ixbbuf); free((char *)datbuf); errormsg(WHERE,ERR_READ,datfname,datlen); return; } close(ixbfile); close(datfile); if((ixbfile=nopen(ixbfname,O_WRONLY|O_TRUNC))==-1) { free((char *)ixbbuf); free((char *)datbuf); errormsg(WHERE,ERR_OPEN,ixbfname,O_WRONLY|O_TRUNC); return; } if((datfile=nopen(datfname,O_WRONLY|O_TRUNC))==-1) { close(ixbfile); free((char *)ixbbuf); free((char *)datbuf); errormsg(WHERE,ERR_OPEN,datfname,O_WRONLY|O_TRUNC); return; } for(l=0,i=0;l<ixblen && i<MAX_FILES;l+=F_IXBSIZE,i++) ixbptr[i]=ixbbuf+l; switch(cfg.dir[dirnum]->sort) { case SORT_NAME_A: qsort((void *)ixbptr,ixblen/F_IXBSIZE,sizeof(ixbptr[0]) ,(int(*)(const void*, const void*))fnamecmp_a); break; case SORT_NAME_D: qsort((void *)ixbptr,ixblen/F_IXBSIZE,sizeof(ixbptr[0]) ,(int(*)(const void*, const void*))fnamecmp_d); break; case SORT_DATE_A: qsort((void *)ixbptr,ixblen/F_IXBSIZE,sizeof(ixbptr[0]) ,(int(*)(const void*, const void*))fdatecmp_a); break; case SORT_DATE_D: qsort((void *)ixbptr,ixblen/F_IXBSIZE,sizeof(ixbptr[0]) ,(int(*)(const void*, const void*))fdatecmp_d); break; } if((exbfile=nopen(exbfname,O_RDWR|O_CREAT))==-1) { close(ixbfile); close(datfile); free((char *)ixbbuf); free((char *)datbuf); errormsg(WHERE,ERR_OPEN,exbfname,O_RDWR|O_CREAT); return; } if((txbfile=nopen(txbfname,O_RDWR|O_CREAT))==-1) { close(exbfile); close(datfile); close(exbfile); free((char *)ixbbuf); free((char *)datbuf); errormsg(WHERE,ERR_OPEN,txbfname,O_RDWR|O_CREAT); return; } for(i=0;i<ixblen/F_IXBSIZE;i++) { offset=ixbptr[i][11]|((long)ixbptr[i][12]<<8)|((long)ixbptr[i][13]<<16); lwrite(datfile,&datbuf[offset],F_LEN); newoffset=(ulong)i*(ulong)F_LEN; j=datbuf[offset+F_MISC]; /* misc bits */ if(j!=ETX) j-=' '; if(j&FM_EXTDESC) { /* extended description */ lseek(exbfile,(offset/F_LEN)*512L,SEEK_SET); memset(ext,0,512); read(exbfile,ext,512); while(filelength(txbfile)<(newoffset/F_LEN)*512L) { // lseek(txbfile,0L,SEEK_END); write(txbfile,nulbuf,512); } lseek(txbfile,(newoffset/F_LEN)*512L,SEEK_SET); write(txbfile,ext,512); } str[0]=newoffset&0xff; /* Get offset within DAT file for IXB file */ str[1]=(newoffset>>8)&0xff; str[2]=(newoffset>>16)&0xff; lwrite(ixbfile,ixbptr[i],11); /* filename */ lwrite(ixbfile,str,3); /* offset */ lwrite(ixbfile,ixbptr[i]+14,8); } /* upload and download times */ close(exbfile); close(txbfile); close(ixbfile); close(datfile); remove(exbfname); rename(txbfname,exbfname); if(!flength(exbfname)) remove(exbfname); free((char *)ixbbuf); free((char *)datbuf); if(ixblen/F_IXBSIZE==datlen/F_LEN) bputs(text[Sorted]); else bprintf(text[Compressed] ,(uint)((datlen/F_LEN)-(ixblen/F_IXBSIZE)) ,ultoac(((datlen/F_LEN)-(ixblen/F_IXBSIZE))*F_LEN,tmp)); }
//----------------------------------------------------------------------- static void read_fixup(linput_t *li) { fixup fix; const int size = offsetof(fixup, fixups); lread(li, &fix, size); uint32 fptr = qltell(li); ea_t sea = getsea(fix.where_IN); if ( sea != BADADDR ) { uchar *b = qnewarray(uchar, fix.length); if ( b == NULL ) nomem("read_fixup"); lread(li, b, fix.length); // show_hex(b, fix.length, "\nFIXUP SEG %04X, %04X BYTES, KIND %02X\n", // fix.where_IN, // fix.length, // b[0]); const uchar *ptr = b; const uchar *end = b + fix.length; while ( ptr < end ) { fixup_data_t fd; uint32 where_offset = 0; uint32 what_offset = 0; ushort what_in = 9; bool selfrel = false; bool isfar = false; fd.type = FIXUP_OFF32; switch ( *ptr++ ) { case 0x2C: // GEN isfar = true; ask_for_feedback("Untested relocation type"); case 0x24: // GEN where_offset = readdw(ptr, false); what_offset = readdw(ptr, false); what_in = (ushort)readdw(ptr, false); break; case 0x2D: isfar = true; case 0x25: // INTRA where_offset = readdw(ptr, false); what_offset = readdw(ptr, false); what_in = fix.where_IN; break; case 0x2A: // CALL where_offset = readdw(ptr, false); what_offset = 0; what_in = (ushort)readdw(ptr, false); selfrel = true; break; case 0x2E: // OFF32? isfar = true; case 0x26: where_offset = readdw(ptr, false); what_offset = 0; what_in = (ushort)readdw(ptr, false); break; default: ask_for_feedback("Unknown relocation type %02X", ptr[-1]); add_pgm_cmt("!!! Unknown relocation type %02X", ptr[-1]); break; } ea_t source = sea + where_offset; ea_t target = BADADDR; switch ( what_in >> 12 ) { case 0x02: // segments target = getsea(what_in); break; case 0x06: // externs target = xea + 4 * ((what_in & 0xFFF) - 1); fd.type |= FIXUP_EXTDEF; break; default: ask_for_feedback("Unknown relocation target %04X", what_in); add_pgm_cmt("!!! Unknown relocation target %04X", what_in); break; } segment_t *ts = getseg(target); fd.sel = ts ? (ushort)ts->sel : 0; if ( (fd.type & FIXUP_EXTDEF) == 0 ) { target += what_offset; what_offset = 0; } fd.off = target; fd.displacement = what_offset; target += what_offset; if ( selfrel ) { fd.type |= FIXUP_SELFREL; target -= source + 4; } set_fixup(source, &fd); put_long(source, target); if ( isfar ) { fd.type = FIXUP_SEG16; set_fixup(source+4, &fd); put_word(source+4, fd.sel); } } qfree(b); }