Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore) { /* if restore is true :random read else random blok read. * random read updates old block and old record to reflect the random data * before the read!!!!!!!!! and the random data is not updated! (user must do this) * Random block read updates these fields to reflect the state after the read! */ DOS_FCB fcb(seg,offset); Bit32u random; Bit16u old_block=0; Bit8u old_rec=0; Bit8u error=0; Bit16u count; /* Set the correct record from the random data */ fcb.GetRandom(random); fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); if (restore) fcb.GetRecord(old_block,old_rec);//store this for after the read. // Read records for (count=0; count<*numRec; count++) { error = DOS_FCBRead(seg,offset,count); if (error!=FCB_SUCCESS) break; } if (error==FCB_READ_PARTIAL) count++; //partial read counts *numRec=count; Bit16u new_block;Bit8u new_rec; fcb.GetRecord(new_block,new_rec); if (restore) fcb.SetRecord(old_block,old_rec); /* Update the random record pointer with new position only when restore is false*/ if(!restore) fcb.SetRandom(new_block*128+new_rec); return error; }
bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); /* First check if the name is correct */ Bit8u drive; char fullname[DOS_PATHLENGTH]; if (!DOS_MakeName(shortname,fullname,&drive)) return false; /* Check, if file is already opened */ for (Bit8u i=0;i<DOS_FILES;i++) { DOS_PSP psp(dos.psp()); if (Files[i] && Files[i]->IsOpen() && Files[i]->IsName(fullname)) { handle = psp.FindEntryByHandle(i); if (handle==0xFF) { // This shouldnt happen LOG(LOG_FILES,LOG_ERROR)("DOS: File %s is opened but has no psp entry.",shortname); return false; } fcb.FileOpen((Bit8u)handle); return true; } } if (!DOS_OpenFile(shortname,OPEN_READWRITE,&handle)) return false; fcb.FileOpen((Bit8u)handle); return true; }
Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) { DOS_FCB fcb(seg,offset); Bit8u fhandle,cur_rec;Bit16u cur_block,rec_size; fcb.GetSeqData(fhandle,rec_size); fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_ERR_WRITE; MEM_BlockRead(Real2Phys(dos.dta())+recno*rec_size,dos_copybuf,rec_size); Bit16u towrite=rec_size; if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite)) return FCB_ERR_WRITE; Bit32u size;Bit16u date,time; fcb.GetSizeDateTime(size,date,time); if (pos+towrite>size) size=pos+towrite; //time doesn't keep track of endofday date = DOS_PackDate(dos.date.year,dos.date.month,dos.date.day); Bit32u ticks = mem_readd(BIOS_TIMER); Bit32u seconds = (ticks*10)/182; Bit16u hour = (Bit16u)(seconds/3600); Bit16u min = (Bit16u)((seconds % 3600)/60); Bit16u sec = (Bit16u)(seconds % 60); time = DOS_PackTime(hour,min,sec); Bit8u temp=RealHandle(fhandle); Files[temp]->time=time; Files[temp]->date=date; fcb.SetSizeDateTime(size,date,time); if (++cur_rec>127) { cur_block++;cur_rec=0; } fcb.SetRecord(cur_block,cur_rec); return FCB_SUCCESS; }
Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore) { /* see FCB_RandomRead */ DOS_FCB fcb(seg,offset); Bit32u random; Bit16u old_block=0; Bit8u old_rec=0; Bit8u error=0; Bit16u count; /* Set the correct record from the random data */ fcb.GetRandom(random); fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); if (restore) fcb.GetRecord(old_block,old_rec); if (*numRec > 0) { /* Write records */ for (count=0; count<*numRec; count++) { error = DOS_FCBWrite(seg,offset,count);// dos_fcbwrite return 0 false when true... if (error!=FCB_SUCCESS) break; } *numRec=count; } else { DOS_FCBIncreaseSize(seg,offset); } Bit16u new_block;Bit8u new_rec; fcb.GetRecord(new_block,new_rec); if (restore) fcb.SetRecord(old_block,old_rec); /* Update the random record pointer with new position only when restore is false */ if (!restore) fcb.SetRandom(new_block*128+new_rec); return error; }
Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { DOS_FCB fcb(seg,offset); Bit8u fhandle,cur_rec;Bit16u cur_block,rec_size; fcb.GetSeqData(fhandle,rec_size); if (fhandle==0xff && rec_size!=0) { if (!DOS_FCBOpen(seg,offset)) return FCB_READ_NODATA; LOG(LOG_FCB,LOG_WARN)("Reopened closed FCB"); fcb.GetSeqData(fhandle,rec_size); } fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_READ_NODATA; Bit16u toread=rec_size; if (!DOS_ReadFile(fhandle,dos_copybuf,&toread)) return FCB_READ_NODATA; if (toread==0) return FCB_READ_NODATA; if (toread < rec_size) { //Zero pad copybuffer to rec_size Bitu i = toread; while(i < rec_size) dos_copybuf[i++] = 0; } MEM_BlockWrite(Real2Phys(dos.dta())+recno*rec_size,dos_copybuf,rec_size); if (++cur_rec>127) { cur_block++;cur_rec=0; } fcb.SetRecord(cur_block,cur_rec); if (toread==rec_size) return FCB_SUCCESS; if (toread==0) return FCB_READ_NODATA; return FCB_READ_PARTIAL; }
bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta); bool ret=DOS_FindNext(); dos.dta(old_dta); if (ret) SaveFindResult(fcb); return ret; }
bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); if (!DOS_CreateFile(shortname,DOS_ATTR_ARCHIVE,&handle)) return false; fcb.FileOpen((Bit8u)handle); return true; }
bool DOS_FCBClose(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); if(!fcb.Valid()) return false; Bit8u fhandle; fcb.FileClose(fhandle); DOS_CloseFile(fhandle,true); return true; }
void DOS_FCBSetRandomRecord(Bit16u seg, Bit16u offset) { DOS_FCB fcb(seg, offset); Bit16u block; Bit8u rec; fcb.GetRecord(block, rec); fcb.SetRandom(block*128+rec); }
/** Constructs an embedding using the data represented * by the feature matrix. Uses linear kernel (dot product) * and euclidean distance. * * @param matrix matrix that contains feature vectors column-wise */ TapkeeOutput embedUsing(const DenseMatrix& matrix) const { std::vector<IndexType> indices(matrix.cols()); for (IndexType i=0; i<matrix.cols(); i++) indices[i] = i; eigen_kernel_callback kcb(matrix); eigen_distance_callback dcb(matrix); eigen_features_callback fcb(matrix); return tapkee::embed(indices.begin(),indices.end(),kcb,dcb,fcb,parameters); }
bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta); char name[DOS_FCBNAME];fcb.GetName(name); Bit8u attr = DOS_ATTR_ARCHIVE; fcb.GetAttr(attr); /* Gets search attributes if extended */ bool ret=DOS_FindFirst(name,attr,true); dos.dta(old_dta); if (ret) SaveFindResult(fcb); return ret; }
bool DOS_FCBCreate(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); Bit8u attr = DOS_ATTR_ARCHIVE; fcb.GetAttr(attr); if (!attr) attr = DOS_ATTR_ARCHIVE; //Better safe than sorry if (!DOS_CreateFile(shortname,attr,&handle)) return false; fcb.FileOpen((Bit8u)handle); return true; }
static void SaveFindResult(DOS_FCB & find_fcb) { DOS_DTA find_dta(dos.tables.tempdta); char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;Bit8u drive; char file_name[9];char ext[4]; find_dta.GetResult(name,size,date,time,attr); drive=find_fcb.GetDrive()+1; /* Create a correct file and extention */ DTAExtendName(name,file_name,ext); DOS_FCB fcb(RealSeg(dos.dta()),RealOff(dos.dta()));//TODO fcb.Create(find_fcb.Extended()); fcb.SetName(drive,file_name,ext); fcb.SetAttr(attr); /* Only adds attribute if fcb is extended */ fcb.SetSizeDateTime(size,date,time); }
bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset) { char shortname[DOS_PATHLENGTH];Bit16u entry;Bit8u handle;Bit16u rec_size; DOS_FCB fcb(seg,offset); fcb.GetName(shortname); if (!DOS_OpenFile(shortname,OPEN_READ,&entry)) return false; handle = RealHandle(entry); Bit32u size = 0; Files[handle]->Seek(&size,DOS_SEEK_END); DOS_CloseFile(entry);fcb.GetSeqData(handle,rec_size); Bit32u random=(size/rec_size); if (size % rec_size) random++; fcb.SetRandom(random); return true; }
bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset){ /* FCB DELETE honours wildcards. it will return true if one or more * files get deleted. * To get this: the dta is set to temporary dta in which found files are * stored. This can not be the tempdta as that one is used by fcbfindfirst */ RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta_fcbdelete); DOS_FCB fcb(RealSeg(dos.dta()),RealOff(dos.dta())); bool nextfile = false; bool return_value = false; nextfile = DOS_FCBFindFirst(seg,offset); while(nextfile) { char shortname[DOS_FCBNAME] = { 0 }; fcb.GetName(shortname); bool res=DOS_UnlinkFile(shortname); if(!return_value && res) return_value = true; //at least one file deleted nextfile = DOS_FCBFindNext(seg,offset); } dos.dta(old_dta); /*Restore dta */ return return_value; }
bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); char shortname[DOS_FCBNAME];Bit16u handle; fcb.GetName(shortname); /* First check if the name is correct */ Bit8u drive; char fullname[DOS_PATHLENGTH]; if (!DOS_MakeName(shortname,fullname,&drive)) return false; /* Check, if file is already opened */ for (Bit8u i = 0;i < DOS_FILES;i++) { if (Files[i] && Files[i]->IsOpen() && Files[i]->IsName(fullname)) { Files[i]->AddRef(); fcb.FileOpen(i); return true; } } if (!DOS_OpenFile(shortname,OPEN_READWRITE,&handle,true)) return false; fcb.FileOpen((Bit8u)handle); return true; }
Bit8u DOS_FCBRandomRead(Bit16u seg, Bit16u offset, Bit16u numRec, bool restore) { /* if restore is true :random read else random blok read. * random read updates old block and old record to reflect the random data * before the read!!!!!!!!! and the random data is not updated! (user must do this) * Random block read updates these fields to reflect the state after the read! */ /* BUG: numRec should return the amount of records read! * Not implemented yet as I'm unsure how to count on error states (partial/failed) */ DOS_FCB fcb(seg,offset); Bit32u random; Bit16u old_block = 0; Bit8u old_rec = 0; Bit8u error = 0; fcb.GetRandom(random); // Set the correct record from the random data fcb.SetRecord((Bit16u)(random / 128), (Bit8u)(random & 127)); if (restore) fcb.GetRecord(old_block, old_rec); // Store this for after the read for (int i = 0; i < numRec; i++) // Read records { error = DOS_FCBRead(seg, offset, (Bit16u)i); if (error != 0) break; } Bit16u new_block; Bit8u new_rec; fcb.GetRecord(new_block, new_rec); if (restore) fcb.SetRecord(old_block, old_rec); else // Update the random record pointer with new position only when restore is false fcb.SetRandom(new_block*128+new_rec); return error; }
Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change) { char * string_begin=string; Bit8u ret=0; if (!(parser & PARSE_DFLT_DRIVE)) { // default drive forced, this intentionally invalidates an extended FCB mem_writeb(PhysMake(seg,offset),0); } DOS_FCB fcb(seg,offset,false); // always a non-extended FCB bool hasdrive,hasname,hasext,finished; hasdrive=hasname=hasext=finished=false; Bitu index=0; Bit8u fill=' '; /* First get the old data from the fcb */ #ifdef _MSC_VER #pragma pack (1) #endif union { struct { char drive[2]; char name[9]; char ext[4]; } GCC_ATTRIBUTE (packed) part; char full[DOS_FCBNAME]; } fcb_name; #ifdef _MSC_VER #pragma pack() #endif /* Get the old information from the previous fcb */ fcb.GetName(fcb_name.full); fcb_name.part.drive[0]-='A'-1;fcb_name.part.drive[1]=0; fcb_name.part.name[8]=0;fcb_name.part.ext[3]=0; /* Strip of the leading sepetaror */ if((parser & PARSE_SEP_STOP) && *string) { //ignore leading seperator char sep[] = FCB_SEP;char a[2]; a[0]= *string;a[1]='\0'; if (strcspn(a,sep)==0) string++; } /* strip leading spaces */ while((*string==' ')||(*string=='\t')) string++; /* Check for a drive */ if (string[1]==':') { fcb_name.part.drive[0]=0; hasdrive=true; if (isalpha(string[0]) && Drives[toupper(string[0])-'A']) { fcb_name.part.drive[0]=(char)(toupper(string[0])-'A'+1); } else ret=0xff; string+=2; } /* Special checks for . and .. */ if (string[0]=='.') { string++; if (!string[0]) { hasname=true; ret=PARSE_RET_NOWILD; strcpy(fcb_name.part.name,". "); goto savefcb; } if (string[1]=='.' && !string[1]) { string++; hasname=true; ret=PARSE_RET_NOWILD; strcpy(fcb_name.part.name,".. "); goto savefcb; } goto checkext; } /* Copy the name */ hasname=true;finished=false;fill=' ';index=0; while (index<8) { if (!finished) { if (string[0]=='*') {fill='?';fcb_name.part.name[index]='?';if (!ret) ret=1;finished=true;} else if (string[0]=='?') {fcb_name.part.name[index]='?';if (!ret) ret=1;} else if (isvalid(string[0])) {fcb_name.part.name[index]=(char)(toupper(string[0]));} else { finished=true;continue; } string++; } else { fcb_name.part.name[index]=fill; } index++; } if (!(string[0]=='.')) goto savefcb; string++; checkext: /* Copy the extension */ hasext=true;finished=false;fill=' ';index=0; while (index<3) { if (!finished) { if (string[0]=='*') {fill='?';fcb_name.part.ext[index]='?';finished=true;} else if (string[0]=='?') {fcb_name.part.ext[index]='?';if (!ret) ret=1;} else if (isvalid(string[0])) {fcb_name.part.ext[index]=(char)(toupper(string[0]));} else { finished=true;continue; } string++; } else { fcb_name.part.ext[index]=fill; } index++; } savefcb: if (!hasdrive & !(parser & PARSE_DFLT_DRIVE)) fcb_name.part.drive[0] = 0; if (!hasname & !(parser & PARSE_BLNK_FNAME)) strcpy(fcb_name.part.name," "); if (!hasext & !(parser & PARSE_BLNK_FEXT)) strcpy(fcb_name.part.ext," "); fcb.SetName(fcb_name.part.drive[0],fcb_name.part.name,fcb_name.part.ext); *change=(Bit8u)(string-string_begin); return ret; }
// change model callback void MCSIEPlugin::setupProgramCtx(ProgramCtx& ctx) { ProgramCtxData& pcd = ctx.getPluginData<MCSIE>(); if( pcd.isEnabled() ) { // setup predicate masks RegistryPtr reg(ctx.registry()); // store registry in ProgramCtxData pcd.reg = reg; // configure predicate mask for d1/d2 pcd.idd1 = reg->storeConstantTerm("d1"); pcd.idd2 = reg->storeConstantTerm("d2"); pcd.brdmask.setRegistry(reg); pcd.brdmask.addPredicate(pcd.idd1); pcd.brdmask.addPredicate(pcd.idd2); pcd.brd1mask.setRegistry(reg); pcd.brd1mask.addPredicate(pcd.idd1); pcd.brd2mask.setRegistry(reg); pcd.brd2mask.addPredicate(pcd.idd2); // configure collector (if we do not use them this will not hurt performance) pcd.mindcollector.reset( new MinimalNotionCollector(pcd.brd1mask, pcd.brd2mask)); // configure predicate mask for e1/e2 pcd.ide1 = reg->storeConstantTerm("e1"); pcd.ide2 = reg->storeConstantTerm("e2"); pcd.bremask.setRegistry(reg); pcd.bremask.addPredicate(pcd.ide1); pcd.bremask.addPredicate(pcd.ide2); pcd.bre1mask.setRegistry(reg); pcd.bre1mask.addPredicate(pcd.ide1); pcd.bre2mask.setRegistry(reg); pcd.bre2mask.addPredicate(pcd.ide2); // configure collector (if we do not use them this will not hurt performance) pcd.minecollector.reset( new MinimalNotionCollector(pcd.bre1mask, pcd.bre2mask)); // configure predicate mask for each context's output beliefs assert(!pcd.mcs().contexts.empty() && "here we expect to have parsed the input and " "we expect to know the number of contexts"); for(ContextIterator it = pcd.mcs().contexts.begin(); it != pcd.mcs().contexts.end(); ++it) { pcd.obmasks.push_back(PredicateMask()); PredicateMask& mask = pcd.obmasks.back(); std::ostringstream s; s << "a" << it->ContextNum(); mask.setRegistry(reg); ID idob(reg->storeConstantTerm(s.str())); mask.addPredicate(idob); } // register model callbacks (accumulate minimal notions, print nonminimal notions) // register final callback (print minmimal notions, convert to dual notions) switch(pcd.getMode()) { case ProgramCtxData::DIAGREWRITING: { PrintAndAccumulateModelCallback* ppcd = new PrintAndAccumulateModelCallback(pcd, pcd.idd1, pcd.idd2, pcd.brdmask, pcd.mindcollector); ModelCallbackPtr mcb(ppcd); WARNING("here we could try to only remove the default answer set printer") ctx.modelCallbacks.clear(); ctx.modelCallbacks.push_back(mcb); FinalCallbackPtr fcb(new DiagRewritingFinalCallback(pcd, *ppcd, ctx.aspsoftware)); ctx.finalCallbacks.push_back(fcb); } break; case ProgramCtxData::EXPLREWRITING: { PrintAndAccumulateModelCallback* ppcd = new PrintAndAccumulateModelCallback(pcd, pcd.ide1, pcd.ide2, pcd.bremask, pcd.minecollector); ModelCallbackPtr mcb(ppcd); WARNING("here we could try to only remove the default answer set printer") ctx.modelCallbacks.clear(); ctx.modelCallbacks.push_back(mcb); FinalCallbackPtr fcb(new ExplRewritingFinalCallback(pcd, *ppcd, ctx.aspsoftware)); ctx.finalCallbacks.push_back(fcb); } break; case ProgramCtxData::EQREWRITING: { ModelCallbackPtr mcb(new PrintEQModelCallback(pcd)); WARNING("here we could try to only remove the default answer set printer") ctx.modelCallbacks.clear(); ctx.modelCallbacks.push_back(mcb); // no final callback } break; } } }
Bit8u FCB_Parsename(Bit16u seg, Bit16u offset, Bit8u parser, char* string, Bit8u* change) { char* string_begin = string; Bit8u ret = 0; if (!(parser & PARSE_DFLT_DRIVE)) // Default drive forced, this intentionally invalidates an extended FCB vPC_rStosb(SegOff2Ptr(seg, offset), 0); DOS_FCB fcb(seg, offset, false); // Always a non-extended FCB // First get the old data from the fcb #pragma pack (1) union { struct { char drive[2]; char name[9]; char ext[4]; } part; char full[DOS_FCBNAME]; } fcb_name; #pragma pack() fcb.GetName(fcb_name.full); // Get the old information from the previous fcb fcb_name.part.drive[0] -= 'A'-1; fcb_name.part.drive[1] = 0; fcb_name.part.name[8] = 0; fcb_name.part.ext[3] = 0; if ((parser & PARSE_SEP_STOP) && *string) // Ignore leading seperator if (strchr(":.;,=+", *string)) string++; while ((*string == ' ') || (*string == '\t')) // Strip leading spaces string++; bool hasdrive, hasname, hasext, finished; hasdrive = hasname = hasext = finished = false; if (string[1] == ':') // Check for a drive { fcb_name.part.drive[0] = 0; hasdrive = true; if (isalpha(string[0]) && Drives[toupper(string[0])-'A']) fcb_name.part.drive[0] = (char)(toupper(string[0])-'A'+1); else ret = 0xff; string += 2; } if (string[0] == '.') // Special checks for . and .. { string++; if (!string[0]) { hasname = true; ret = PARSE_RET_NOWILD; strcpy(fcb_name.part.name, ". "); goto savefcb; } if (string[1] == '.' && !string[1]) { string++; hasname = true; ret = PARSE_RET_NOWILD; strcpy(fcb_name.part.name, ".. "); goto savefcb; } goto checkext; } hasname = true; // Copy the name finished = false; Bit8u fill = ' '; Bitu index = 0; while (index < 8) { if (!finished) { if (string[0] == '*') { fill = '?'; fcb_name.part.name[index] = '?'; if (!ret) ret = 1; finished = true; } else if (string[0] == '?') { fcb_name.part.name[index] = '?'; if (!ret) ret = 1; } else if (isvalid(string[0])) fcb_name.part.name[index] = (char)(toupper(string[0])); else { finished = true; continue; } string++; } else fcb_name.part.name[index] = fill; index++; } if (!(string[0] == '.')) goto savefcb; string++; checkext: hasext = true; // Copy the extension finished = false; fill = ' '; index = 0; while (index < 3) { if (!finished) { if (string[0] == '*') { fill = '?'; fcb_name.part.ext[index] = '?'; finished = true; } else if (string[0] == '?') { fcb_name.part.ext[index] = '?'; if (!ret) ret = 1; } else if (isvalid(string[0])) fcb_name.part.ext[index] = (char)(toupper(string[0])); else { finished = true; continue; } string++; } else fcb_name.part.ext[index] = fill; index++; } savefcb: if (!hasdrive & !(parser & PARSE_DFLT_DRIVE)) fcb_name.part.drive[0] = 0; if (!hasname & !(parser & PARSE_BLNK_FNAME)) strcpy(fcb_name.part.name, " "); if (!hasext & !(parser & PARSE_BLNK_FEXT)) strcpy(fcb_name.part.ext, " "); fcb.SetName(fcb_name.part.drive[0], fcb_name.part.name, fcb_name.part.ext); *change = (Bit8u)(string-string_begin); return ret; }
Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change) { char * string_begin=string; Bit8u ret=0; if (!(parser & PARSE_DFLT_DRIVE)) { // default drive forced, this intentionally invalidates an extended FCB mem_writeb(PhysMake(seg,offset),0); } DOS_FCB fcb(seg,offset,false); // always a non-extended FCB bool hasdrive,hasname,hasext,finished; hasdrive=hasname=hasext=finished=false; Bitu index=0; Bit8u fill=' '; /* First get the old data from the fcb */ #ifdef _MSC_VER #pragma pack (1) #endif union { struct { char drive[2]; char name[9]; char ext[4]; } GCC_ATTRIBUTE (packed) part; char full[DOS_FCBNAME]; } fcb_name; #ifdef _MSC_VER #pragma pack() #endif /* Get the old information from the previous fcb */ fcb.GetName(fcb_name.full); fcb_name.part.drive[0]-='A'-1; fcb_name.part.drive[1]=0; fcb_name.part.name[8]=0; fcb_name.part.ext[3]=0; /* strip leading spaces */ while((*string==' ')||(*string=='\t')) string++; /* Strip of the leading separator */ if((parser & PARSE_SEP_STOP) && *string) { char sep[] = FCB_SEP; char a[2]; a[0] = *string; a[1] = '\0'; if (strcspn(a,sep) == 0) string++; } /* Skip following spaces as well */ while((*string==' ')||(*string=='\t')) string++; /* Check for a drive */ if (string[1]==':') { unsigned char d = *reinterpret_cast<unsigned char*>(&string[0]); if (!isvalid(toupper(d))) { string += 2; //TODO check (for ret value) goto savefcb; } fcb_name.part.drive[0]=0; hasdrive=true; if (isalpha(d) && Drives[toupper(d)-'A']) { //Floppies under dos always exist, but don't bother with that at this level ; //THIS* was here } else ret=0xff; fcb_name.part.drive[0]=DOS_ToUpper(string[0])-'A'+1; //Always do THIS* and continue parsing, just return the right code string+=2; } /* Check for extension only file names */ if (string[0] == '.') { string++; goto checkext; } /* do nothing if not a valid name */ if(!isvalid(string[0])) goto savefcb; hasname=true; finished=false; fill=' '; index=0; /* Copy the name */ while (true) { unsigned char nc = *reinterpret_cast<unsigned char*>(&string[0]); char ncs = (char)toupper(nc); //Should use DOS_ToUpper, but then more calls need to be changed. if (ncs == '*') { //Handle * fill = '?'; ncs = '?'; } if (ncs == '?' && !ret && index < 8) ret = 1; //Don't override bad drive if (!isvalid(ncs)) { //Fill up the name. while(index < 8) fcb_name.part.name[index++] = fill; break; } if (index < 8) { fcb_name.part.name[index++] = (fill == '?')?fill:ncs; } string++; } if (!(string[0]=='.')) goto savefcb; string++; checkext: /* Copy the extension */ hasext=true; finished=false; fill=' '; index=0; while (true) { unsigned char nc = *reinterpret_cast<unsigned char*>(&string[0]); char ncs = (char)toupper(nc); if (ncs == '*') { //Handle * fill = '?'; ncs = '?'; } if (ncs == '?' && !ret && index < 3) ret = 1; if (!isvalid(ncs)) { //Fill up the name. while(index < 3) fcb_name.part.ext[index++] = fill; break; } if (index < 3) { fcb_name.part.ext[index++] = (fill=='?')?fill:ncs; } string++; } savefcb: if (!hasdrive & !(parser & PARSE_DFLT_DRIVE)) fcb_name.part.drive[0] = 0; if (!hasname & !(parser & PARSE_BLNK_FNAME)) strcpy(fcb_name.part.name," "); if (!hasext & !(parser & PARSE_BLNK_FEXT)) strcpy(fcb_name.part.ext," "); fcb.SetName(fcb_name.part.drive[0],fcb_name.part.name,fcb_name.part.ext); fcb.ClearBlockRecsize(); //Undocumented bonus work. *change=(Bit8u)(string-string_begin); return ret; }
App::App(void) : BApplication(STR_MUSCLE_DEAMON_NAME) , maxBytes(MUSCLE_NO_LIMIT) , maxNodesPerSession(MUSCLE_NO_LIMIT) , maxReceiveRate(MUSCLE_NO_LIMIT) , maxSendRate(MUSCLE_NO_LIMIT) , maxCombinedRate(MUSCLE_NO_LIMIT) , maxMessageSize(MUSCLE_NO_LIMIT) , maxSessions(MUSCLE_NO_LIMIT) , maxSessionsPerHost(MUSCLE_NO_LIMIT) , fprivateKeyFilePath(NULL) , retVal(0) , okay(true) { CompleteSetupSystem css; TCHECKPOINT; #ifdef MUSCLE_ENABLE_MEMORY_TRACKING printf("MUSCLE_ENABLE_MEMORY_TRACKING\n"); // Set up memory allocation policies for our server. These policies will make sure // that the server can't allocate more than a specified amount of memory, and if it tries, // some emergency callbacks will be called to free up cached info. FunctionCallback fcb(AbstractObjectRecycler::GlobalFlushAllCachedObjects); MemoryAllocatorRef nullRef; AutoCleanupProxyMemoryAllocator cleanupAllocator(nullRef); cleanupAllocator.GetCallbacksQueue().AddTail(GenericCallbackRef(&fcb, false)); UsageLimitProxyMemoryAllocator usageLimitAllocator(MemoryAllocatorRef(&cleanupAllocator, false)); SetCPlusPlusGlobalMemoryAllocator(MemoryAllocatorRef(&usageLimitAllocator, false)); SetCPlusPlusGlobalMemoryAllocator(MemoryAllocatorRef()); // unset, so that none of our allocator objects will be used after they are gone if ((maxBytes != MUSCLE_NO_LIMIT) && (&usageLimitAllocator)) usageLimitAllocator.SetMaxNumBytes(maxBytes); #endif TCHECKPOINT; server.GetAddressRemappingTable() = tempRemaps; if (maxNodesPerSession != MUSCLE_NO_LIMIT) server.GetCentralState().AddInt32(PR_NAME_MAX_NODES_PER_SESSION, maxNodesPerSession); for (MessageFieldNameIterator iter = tempPrivs.GetFieldNameIterator(); iter.HasData(); iter++) tempPrivs.CopyName(iter.GetFieldName(), server.GetCentralState()); // If the user asked for bandwidth limiting, create Policy objects to handle that. AbstractSessionIOPolicyRef inputPolicyRef, outputPolicyRef; if (maxCombinedRate != MUSCLE_NO_LIMIT) { inputPolicyRef.SetRef(newnothrow RateLimitSessionIOPolicy(maxCombinedRate)); outputPolicyRef = inputPolicyRef; if (inputPolicyRef()) LogTime(MUSCLE_LOG_INFO, "Limiting aggregate I/O bandwidth to %.02f kilobytes/second.\n", ((float)maxCombinedRate/1024.0f)); else { WARN_OUT_OF_MEMORY; okay = false; } } else { if (maxReceiveRate != MUSCLE_NO_LIMIT) { inputPolicyRef.SetRef(newnothrow RateLimitSessionIOPolicy(maxReceiveRate)); if (inputPolicyRef()) LogTime(MUSCLE_LOG_INFO, "Limiting aggregate receive bandwidth to %.02f kilobytes/second.\n", ((float)maxReceiveRate/1024.0f)); else { WARN_OUT_OF_MEMORY; okay = false; } } if (maxSendRate != MUSCLE_NO_LIMIT) { outputPolicyRef.SetRef(newnothrow RateLimitSessionIOPolicy(maxSendRate)); if (outputPolicyRef()) LogTime(MUSCLE_LOG_INFO, "Limiting aggregate send bandwidth to %.02f kilobytes/second.\n", ((float)maxSendRate/1024.0f)); else { WARN_OUT_OF_MEMORY; okay = false; } } } // Set up the Session Factory. This factory object creates the new StorageReflectSessions // as needed when people connect, and also has a filter to keep out the riff-raff. StorageReflectSessionFactory factory; factory.SetMaxIncomingMessageSize(maxMessageSize); FilterSessionFactory filter(ReflectSessionFactoryRef(&factory, false), maxSessionsPerHost, maxSessions); filter.SetInputPolicy(inputPolicyRef); filter.SetOutputPolicy(outputPolicyRef); for (int b=bans.GetNumItems()-1; ((okay)&&(b>=0)); b--) if (filter.PutBanPattern(bans[b]()) != B_NO_ERROR) okay = false; for (int a=requires.GetNumItems()-1; ((okay)&&(a>=0)); a--) if (filter.PutRequirePattern(requires[a]()) != B_NO_ERROR) okay = false; #ifdef MUSCLE_ENABLE_SSL ByteBufferRef optCryptoBuf; if (fprivateKeyFilePath) { FileDataIO fdio(muscleFopen(fprivateKeyFilePath->Cstr(), "rb")); ByteBufferRef fileData = GetByteBufferFromPool((uint32)fdio.GetLength()); if ((fdio.GetFile())&&(fileData())&&(fdio.ReadFully(fileData()->GetBuffer(), fileData()->GetNumBytes()) == fileData()->GetNumBytes())) { LogTime(MUSCLE_LOG_INFO, "Using private key file [%s] to authenticate with connecting clients\n", fprivateKeyFilePath->Cstr()); server.SetSSLPrivateKey(fileData); } else { LogTime(MUSCLE_LOG_CRITICALERROR, "Couldn't load private key file [%s] (file not found?)\n", fprivateKeyFilePath->Cstr()); okay = false; } } #else if (fprivateKeyFilePath) { LogTime(MUSCLE_LOG_CRITICALERROR, "Can't loadp private key file [%s], SSL support is not compiled in!\n", fprivateKeyFilePath->Cstr()); okay = false; } #endif // Set up ports. We allow multiple ports, mostly just to show how it can be done; // they all get the same set of ban/require patterns (since they all do the same thing anyway). if (listenPorts.IsEmpty()) listenPorts.PutWithDefault(IPAddressAndPort(invalidIP, DEFAULT_MUSCLED_PORT)); for (HashtableIterator<IPAddressAndPort, Void> iter(listenPorts); iter.HasData(); iter++) { const IPAddressAndPort & iap = iter.GetKey(); if (server.PutAcceptFactory(iap.GetPort(), ReflectSessionFactoryRef(&filter, false), iap.GetIPAddress()) != B_NO_ERROR) { if (iap.GetIPAddress() == invalidIP) LogTime(MUSCLE_LOG_CRITICALERROR, "Error adding port %u, aborting.\n", iap.GetPort()); else LogTime(MUSCLE_LOG_CRITICALERROR, "Error adding port %u to interface %s, aborting.\n", iap.GetPort(), Inet_NtoA(iap.GetIPAddress())()); okay = false; break; } } if (okay) { retVal = (server.ServerProcessLoop() == B_NO_ERROR) ? 0 : 10; if (retVal > 0) LogTime(MUSCLE_LOG_CRITICALERROR, "Server process aborted!\n"); else LogTime(MUSCLE_LOG_INFO, "Server process exiting.\n"); } else LogTime(MUSCLE_LOG_CRITICALERROR, "Error occurred during setup, aborting!\n"); server.Cleanup(); }