void PanelView::RescanForNewEntries() //////////////////////////////////////////////////////////////////////// { BDirectory dir(m_Path.String()); BNode node; node_ref noderef; if (dir.InitCheck()==B_OK) { BEntry entry; if (dir.GetEntry(&entry)==B_OK) { while (dir.GetNextEntry(&entry)==B_OK) { node.SetTo(&entry); node.GetNodeRef(&noderef); if (m_CustomListView->FindItemByNodeRef(noderef)==NULL) AddDirectoryEntry(&entry); } } } }
void PanelView::RescanCreated(BEntry *entry) //////////////////////////////////////////////////////////////////////// { if (m_PanelMode != PM_NORMAL) return; if (!DoesEntryExist(m_Path.String())) { GotoRoot(); return; } // if (entry->InitCheck()!=B_OK) // return; if (!entry->Exists()) return; BEntry parententry; BPath path; entry->GetParent(&parententry); parententry.GetPath(&path); if (strcmp(path.Path(),m_Path.String())!=0) return; SaveItemSelection(); AddDirectoryEntry(entry, true); // true = Sorted Insert! // m_CustomListView->DoSortList(); LoadItemSelection(); m_CurrentTotalSize = m_CustomListView->GetCurrentTotalSize(); // if (item) m_CurrentTotalSize += item->m_FileSize; SelectionChanged(); }
void PanelView::ReadDirectory(const char *itemname) //////////////////////////////////////////////////////////////////////// { BDirectory *dir; CustomListItem *item; stop_watching(this); // SetMousePointer(CR_HOURGLASS); MAINWINDOW->SetMousePointer(GenesisWindow::CR_HOURGLASS); // If we are not in the root directory, simply start the dir with a '..' entry... if (strcmp(m_Path.String(),"/")!=0) { item = new CustomListItem("..", m_Path.String(), FT_PARENT, 0); m_CustomListView->AddItem(item); if (m_Setting_ShowIcons) { item->AddIcon(m_ParentIcon); item->SetHeight(15.0f); } } dir = new BDirectory(m_Path.String()); if (dir) { BEntry entry; if (dir->GetEntry(&entry)==B_OK) { while (dir->GetNextEntry(&entry)==B_OK) { AddDirectoryEntry(&entry); } } delete dir; } m_CustomListView->DoSortList(); // Always select the first item in the list or the child where we came from... if (itemname) { CustomListItem *item; int n = m_CustomListView->CountItems(); for (int i=0;i<n;i++) { item = (CustomListItem *)m_CustomListView->ItemAt(i); if (strcasecmp(itemname,item->m_FileName.String())==0) { m_CustomListView->Select(i,false); m_CustomListView->ScrollToSelection(); break; } } // When the given file disappeared, we have to select the first entry... if (m_CustomListView->CountSelectedEntries(CT_WITHPARENT)==0) m_CustomListView->Select(0,false); } else m_CustomListView->Select(0,false); m_CurrentTotalSize = m_CustomListView->GetCurrentTotalSize(); // Probably we have to update the path of the command line... Parent()->Looper()->PostMessage(new BMessage(MSG_UPDATECOMMANDLINE_PATH)); // To update command line... EnableMonitoring(); // SetMousePointer(CR_DEFAULT); MAINWINDOW->SetMousePointer(GenesisWindow::CR_DEFAULT); }
int fs_creat(byte *path, word mode, word rights) { // otevre se pro cteni zapis MNODE *DirNode; int i,j,MySystemIndex; TaskUArea *Task = GetCurrentTaskUArea(); word MyPackID, CallResult, GetNumber, MyIndex; byte buffer[255],*dir,trunc; byte sector[512]; MNODE *MyNode = (MNODE *) sector; dword Node; word CacheFlag; SyscallActive = 1; CacheFlag = (mode & IO_CACHE_THROUGH) ? FPACK_NOTHING : FPACK_ADD; Task->ErrorLevel = ERR_FS_NO_ERROR; MyIndex = BitmapGetFirstHole(Task->Bmp,MaxOpenedFiles); // for (i=5; i<MaxOpenedFiles; ++i) // if (!Task->OpenFiles[i].Used) { MyIndex = i; break; } if (MyIndex == 0xffff) { Task->ErrorLevel = ERR_TOO_MANY_OPENED_FILES; SyscallActive = 0; return -1; } dir = new byte [strlen(path)+1]; strcpy(dir,path); CutLastPathPart (dir,buffer); CallResult = NAMEN( dir, DirNode, CacheFlag); if ( CallResult != ERR_FS_NO_ERROR) { delete [] dir; Task->ErrorLevel = CallResult; SyscallActive = 0; return -1; } CallResult = SearchDirByName(DirNode, buffer, Node, CacheFlag, 0); if ( CallResult == ERR_DIRREC_NOT_FOUND) { // soubor jeste nexistuje, vypln jeho node trunc = 0; memset(sector,0,512); memcpy(MyNode->MagicWord,FileMagicWord,8); memcpy(MyNode->MagicWordII,FileMagicWord,8); MyNode->OwnerID = Task->ownerID; MyNode->GroupID = Task->groupID; MyNode->Type = NODE_TYPE_FILE; MyNode->Rights = rights; GlobalTime.Get(MyNode->FileAccessed); MyNode->FileModified = MyNode->FileAccessed; MyNode->NODEAccessed = MyNode->FileAccessed; MyNode->NODEModified = MyNode->FileAccessed; MyNode->Size = 0; MyNode->Links = 1; MyNode->Device = DirNode->Device; MyNode->Partition = DirNode->Partition; CallResult = CacheManAllocateSector( MyNode->Device, MyNode->Partition, 0, 1, MyNode->logical,GetNumber, MyPackID, FPACK_CREAT); if (CallResult != ERR_FS_NO_ERROR) { DirNode->Locked.Release(); ActiveNodes->Release(DirNode); delete [] dir; } MyNode->packID = MyPackID; } else if (CallResult == ERR_FS_NO_ERROR) { // soubor uz existuje -> zkrati se na 0 trunc = 1; ActiveNodes->Add(DirNode->Device, DirNode->Partition, Node, MyNode); } else { // chyba pri pristupu k adresari DirNode->Locked.Release(); ActiveNodes->Release(DirNode); delete [] dir; } // DirNode je v tabulce aktivnich nodu zamceny // trunc = 1 MyNode je v tabulce aktivnich nodu odemceny ->nelze ho smazat // trunc = 0 MyNode je vyplnen v pameti // pristup k systemove tabulce, zjisti prvni volnou diru SystemTableSem->Down(); Task->OpenFiles[MyIndex].SystemTabIndex = BitmapGetFirstHole(SystemOpenFilesBmp, MaxOpenedFiles); if (Task->OpenFiles[MyIndex].SystemTabIndex == 0xffff) { SystemTableSem->Up(); DirNode->Locked.Release(); ActiveNodes->Release(DirNode); if (trunc) { ActiveNodes->Release(MyNode); } Task->ErrorLevel = ERR_TOO_MANY_OPENED_FILES; delete [] dir; SyscallActive = 0; return -1; } BitmapSetBit(SystemOpenFilesBmp, Task->OpenFiles[MyIndex].SystemTabIndex); SystemTableSem->Up(); MySystemIndex = Task->OpenFiles[MyIndex].SystemTabIndex; if (trunc) { // soubor se urizne na velikost 0 CallResult = DeleteMNODEData(MyNode, CacheFlag); if (CallResult != ERR_FS_NO_ERROR) { DirNode->Locked.Release(); ActiveNodes->Release(DirNode); ActiveNodes->Release(MyNode); // obnov bitmapu systemove tabulky SystemTableSem->Down(); BitmapClearBit(SystemOpenFilesBmp, MySystemIndex); SystemTableSem->Up(); Task->ErrorLevel = CallResult; delete [] dir; SyscallActive = 0; return -1; } CacheManCommitPackage(MyNode->packID); } else { // ulozi se node a zapise se do direktorare CallResult = CacheManSaveSector(MyNode->Device, MyNode->Partition, MyNode->logical, 1, MyPackID, FPACK_ADD /*CacheFlag*/, MyNode); if (CallResult != ERR_FS_NO_ERROR) { DirNode->Locked.Release(); ActiveNodes->Release(DirNode); // obnov bitmapu systemove tabulky SystemTableSem->Down(); BitmapClearBit(SystemOpenFilesBmp, MySystemIndex); SystemTableSem->Up(); Task->ErrorLevel = CallResult; delete [] dir; SyscallActive = 0; return -1; } // pridej do adresare zaznam o novem souboru CallResult = AddDirectoryEntry( DirNode, MyNode->logical, CacheFlag, buffer, 0); if (CallResult != ERR_FS_NO_ERROR) { DirNode->Locked.Release(); ActiveNodes->Release(DirNode); // obnov bitmapu systemove tabulky SystemTableSem->Down(); BitmapClearBit(SystemOpenFilesBmp, MySystemIndex); SystemTableSem->Up(); Task->ErrorLevel = CallResult; // uvolni sektor, ktery je naalokovan pro node CacheManFreeSector(MyNode->Device, MyNode->Partition, MyNode->logical, 1, MyPackID, FPACK_ADD/*CacheFlag*/); delete [] dir; SyscallActive = 0; return -1; } CacheManCommitPackage(MyNode->packID,FPACK_DELETE); ActiveNodes->Add(MyNode->Device, MyNode->Partition, MyNode->logical, MyNode); } // MyNode je v tabulce aktivnich uzlu odemceny OpenFiles[MySystemIndex].Used = 1; OpenFiles[MySystemIndex].Access = IO_CAN_BOTH; OpenFiles[MySystemIndex].Access |= (CacheFlag == FPACK_NOTHING) ? IO_CACHE_THROUGH : IO_CACHE_ADD; OpenFiles[MySystemIndex].Position = 0; OpenFiles[MySystemIndex].DirtyBuffer = 1; OpenFiles[MySystemIndex].BufferPos = 0; OpenFiles[MySystemIndex].Buffer = new byte[512]; OpenFiles[MySystemIndex].LastPreload = 0; OpenFiles[MySystemIndex].MemNODE = MyNode; Task->OpenFiles[MyIndex].Bitmap = new byte[(MaxOpenedFiles>>3)+1]; memset(Task->OpenFiles[MyIndex].Bitmap,0,(MaxOpenedFiles>>3)+1); // podiva se jestli uz proces neotevrel stejny soubor, // pokud ano do bitmapy si zanese jeho indexy a svuj index // zanese do jeho bitmapy (pokud nejakou ma) if (trunc) for (i=5,j=Task->NrOpenedFiles-5; i<MaxOpenedFiles; ++i) { if (!j) break; if ((i != MyIndex) && (Task->OpenFiles[i].Used)) { if (MyNode == OpenFiles[Task->OpenFiles[i].SystemTabIndex].MemNODE) { if (Task->OpenFiles[i].Bitmap) BitmapSetBit(Task->OpenFiles[i].Bitmap, MyIndex); BitmapSetBit(Task->OpenFiles[MyIndex].Bitmap, i); } j--; } } Task->OpenFiles[MyIndex].Used = 1; Task->NrOpenedFiles++; BitmapSetBit(Task->Bmp,MyIndex); DirNode->Locked.Release(); ActiveNodes->Release(DirNode); delete [] dir; SyscallActive = 0; return MyIndex; }
word fs_link(byte *path1, byte *path2) { TaskUArea *Task = GetCurrentTaskUArea(); MNODE *OldNode,*DirNode; byte buffer[255],*dir; word CallResult; dword logical; SyscallActive = 1; Task->ErrorLevel = ERR_FS_NO_ERROR; CallResult = NAMEN(path1, OldNode, FPACK_ADD); if (CallResult != ERR_FS_NO_ERROR) { SyscallActive = 0; return ERR_DIRREC_NOT_FOUND; } if (OldNode->Type & NODE_TYPE_DIRECTORY) { OldNode->Locked.Release(); ActiveNodes->Release(OldNode); SyscallActive = 0; return ERR_CANNOT_MAKE_DIR_LINK; } OldNode->Links++; OldNode->DirtyByData=1; OldNode->Locked.Release(); dir = new byte [strlen(path2)+1]; strcpy(dir,path2); // zjisti umisteni adresare, ve kterem bude ulozen link CutLastPathPart (dir,buffer); CallResult = NAMEN( dir, DirNode, FPACK_ADD); if ( CallResult != ERR_FS_NO_ERROR) { OldNode->Locked.Acquire(); OldNode->Links--; OldNode->Locked.Release(); ActiveNodes->Release(OldNode); delete [] dir; SyscallActive = 0; return CallResult; } if (!(DirNode->Type & NODE_TYPE_DIRECTORY)) { DirNode->Locked.Release(); ActiveNodes->Release(DirNode); OldNode->Locked.Acquire(); OldNode->Links--; OldNode->Locked.Release(); ActiveNodes->Release(OldNode); delete [] dir; SyscallActive = 0; return ERR_NOT_DIRECTORY; } if ( (DirNode->Device != OldNode->Device) || (DirNode->Partition != OldNode->Partition) ) { DirNode->Locked.Release(); ActiveNodes->Release(DirNode); OldNode->Locked.Acquire(); OldNode->Links--; OldNode->Locked.Release(); ActiveNodes->Release(OldNode); delete [] dir; SyscallActive = 0; return ERR_NOT_SAME_SYSTEMS; } CallResult = SearchDirByName(DirNode, buffer, logical, FPACK_ADD, 0); if (CallResult != ERR_DIRREC_NOT_FOUND) { DirNode->Locked.Release(); ActiveNodes->Release(DirNode); OldNode->Locked.Acquire(); OldNode->Links--; OldNode->Locked.Release(); ActiveNodes->Release(OldNode); delete [] dir; SyscallActive = 0; if (CallResult == ERR_FS_NO_ERROR) return ERR_DIRREC_ALREADY_EXISTS; else return CallResult; } CallResult = AddDirectoryEntry(DirNode, OldNode->logical, FPACK_ADD, buffer, 0); if (CallResult != ERR_FS_NO_ERROR) { DirNode->Locked.Release(); ActiveNodes->Release(DirNode); OldNode->Locked.Acquire(); OldNode->Links--; OldNode->Locked.Release(); ActiveNodes->Release(OldNode); delete [] dir; SyscallActive = 0; return ERR_NOT_SAME_SYSTEMS; } DirNode->Locked.Release(); CacheManCommitPackage(DirNode->packID); CacheManCommitPackage(OldNode->packID); ActiveNodes->Release(DirNode); ActiveNodes->Release(OldNode); delete [] dir; SyscallActive = 0; return ERR_FS_NO_ERROR; }
/* ==== Make Dir ==== vraci ERR_FS_NO_ERROR ERR_DIRREC_NO_DIR ERR_DIRREC_ALREADY_EXISTS ERR_CANNOT_CREATE_DIR + ostatni */ word fs_mkdir(byte *path) { byte buffer[255],*dir; byte sector2[1024], *DataTag = sector2+512; MNODE *MemNode; word CallResult,GetNumber,packID; dword logical; NODE *rnode = (NODE *)sector2; FileRecord *frecord; TaskUArea *Task; SyscallActive = 1; if (!*path) { SyscallActive = 0; return ERR_CANNOT_CREATE_DIR; } #ifdef DEBUG printf ("\nCreating new directory node"); #endif Task = GetCurrentTaskUArea(); // alokuju, protoze nemuzu uzivateli vratit zmeneny retezec a delka // cesty muze byt obecne libovolne dlouha dir = new byte [strlen(path)+1]; strcpy(dir,path); // zjisti umisteni adresare, kde se bude novy adresar vytvaret CutLastPathPart (dir,buffer); CallResult = NAMEN( dir, MemNode, FPACK_ADD); if ( CallResult != ERR_FS_NO_ERROR) { delete [] dir; SyscallActive = 0; return CallResult; } if (!(MemNode->Type & NODE_TYPE_DIRECTORY)) { MemNode->Locked.Release(); ActiveNodes->Release(MemNode); delete [] dir; SyscallActive = 0; return ERR_NOT_DIRECTORY; } CallResult = SearchDirByName(MemNode, buffer, logical, FPACK_ADD, 0); if (CallResult != ERR_DIRREC_NOT_FOUND) { MemNode->Locked.Release(); ActiveNodes->Release(MemNode); delete [] dir; SyscallActive = 0; if (CallResult == ERR_FS_NO_ERROR) return ERR_DIRREC_ALREADY_EXISTS; else return CallResult; } // naalokuj sektor pro adresarova data CreatePackage(MemNode->Device, MemNode->Partition, packID ); CallResult = CacheManAllocateSector(MemNode->Device, MemNode->Partition, MemNode->logical, 2, logical, GetNumber, packID, FPACK_ADD); if ( CallResult != ERR_FS_NO_ERROR) goto mkdirbad; #ifdef DEBUG printf ("\n Sectors <%d,%d,%lu> allocated for node, <%d,%d,%lu> for data", MemNode->Device, MemNode->Partition, logical, MemNode->Device, MemNode->Partition, logical+1); #endif memset(sector2,0,1024); memcpy(rnode->MagicWord, DirMagicWord, 8); memcpy(rnode->MagicWordII, DirMagicWord, 8); rnode->OwnerID = Task->ownerID; rnode->GroupID = Task->groupID; rnode->Rights = 0xffff; // not implemented yet rnode->Type = NODE_TYPE_DIRECTORY; rnode->Size = 512; rnode->Links = 1; rnode->DirectBlock[0] = logical+1; GlobalTime.Get(rnode->FileAccessed); rnode->FileModified = rnode->FileAccessed; rnode->NODEAccessed = rnode->FileAccessed; rnode->NODEModified = rnode->FileAccessed; // init data block frecord = (FileRecord *)DataTag; frecord->Node = logical; frecord->NextRecord = 8; frecord->NameLength = 1; frecord->FileName[0] = '.'; DataTag += frecord->NextRecord; frecord = (FileRecord *)DataTag; frecord->Node = MemNode->logical; frecord->NextRecord = 0; frecord->NameLength = 2; frecord->FileName[0] = '.'; frecord->FileName[1] = '.'; CallResult = AddDirectoryEntry( MemNode, logical, FPACK_ADD, buffer, 0); if ( CallResult != ERR_FS_NO_ERROR) { // odalokuju sektor CallResult = CacheManFreeSector( MemNode->Device, MemNode->Partition, logical, 2, packID, FPACK_ADD); goto mkdirbad; } CallResult = CacheManSaveSector(MemNode->Device, MemNode->Partition, logical, 2, packID, FPACK_ADD, sector2); if ( CallResult != ERR_FS_NO_ERROR) { // odalokuju sektor CallResult = CacheManFreeSector( MemNode->Device, MemNode->Partition, logical, 2, packID, FPACK_ADD); goto mkdirbad; } CacheManCommitPackage(packID,FPACK_DELETE); CacheManCommitPackage(MemNode->packID); mkdirbad: delete [] dir; MemNode->Locked.Release(); ActiveNodes->Release(MemNode); SyscallActive = 0; return CallResult; }