// Implements EMPTY directory deletion void myrmdir(char *path){ // if it's an abs path then return to root if (path[0] == '/'){ mychdir("root"); } // if the folder is empty, i.e. the first item is it's list is the ENDOFDIR tag if (strcmp(mylistdir(path)[1], "ENDOFDIR") == 0) { // keep a track of where we start the process as the current dir changes in here, somewhere... int initial_current_dir_index = current_dir_index; int initial_current_dir_first_block = current_dir->first_block; // calculate the parent of the dir to remove and chdir to it char *target = strstr(path, last_entry_in_path(path_to_array(path))); int position = target - path; char parent_path[position+1]; for(int i = 0; i < position + 1; i++){ parent_path[i] = '\0'; } strncpy(parent_path, path, position); if(strcmp(parent_path,"") != 0) { mychdir(parent_path); } // find the entry for the dir to be deleted int entrylist_target = file_entry_index(last_entry_in_path(path_to_array(path))); // find the start of it's block chain int block_chain_target = virtual_disk[current_dir_index].dir.entrylist[entrylist_target].first_block; // clear the dir entry and it's name ready for reuse (still don't have that feature) direntry_t *dir_entry = &virtual_disk[current_dir_index].dir.entrylist[entrylist_target]; dir_entry->first_block = 0; dir_entry->unused = 1; int length = strlen(dir_entry->name); for (int i = 0; i < length; i++){ dir_entry->name[i] = '\0'; } // clear the dirs block chain and update the fat int next_block_chain_target; while(1){ next_block_chain_target = FAT[block_chain_target]; FAT[block_chain_target] = UNUSED; if (next_block_chain_target == ENDOFCHAIN) break; block_chain_target = next_block_chain_target; } copy_fat(FAT); // go back to where we started! current_dir_index = initial_current_dir_index; current_dir->first_block = initial_current_dir_first_block; } else { printf("That directory has content and cannot be deleted.\n"); } }
// Implements the opening of files in various modes (r,w,a) my_file_t *myfopen(char *path, char *mode) { int initial_current_dir_index = current_dir_index; int initial_current_dir_first_block = current_dir->first_block; // only cd if we have a path with many levels if(number_of_entries_in_path(path_to_array(path)) > 1){ mychdir(path); } char filename[MAXNAME]; strcpy(filename, last_entry_in_path(path_to_array(path))); strcat(filename, "\0"); int dir_entry_index = file_entry_index(filename); // if it doesn't exist then create it if(dir_entry_index == -1 && strncmp(mode, "r", 1) != 0){ printf("File did not exist. Creating new file: %s\n", path); // create a block for it on the disk int block_index = next_unallocated_block(); create_block(block_index, DATA); // create a dir entry for it in the current directory dir_entry_index = add_block_to_directory(block_index, filename, FALSE); } // load up it's dir entry direntry_t dir_entry = virtual_disk[current_dir_index].dir.entrylist[dir_entry_index]; // create a file object to return my_file_t *file = malloc(sizeof(my_file_t)); file->pos = 0; file->writing = 0; memcpy(file->mode, mode, strlen(mode)); file->blockno = dir_entry.first_block; file->buffer = virtual_disk[dir_entry.first_block]; // move to the end if in append mode if(strncmp(file->mode, "a", 1) == 0){ move_pos_to_end(file); } current_dir_index = initial_current_dir_index; current_dir->first_block = initial_current_dir_first_block; return file; }
// Implements file deletion for a given path void myremove(char *path){ int initial_current_dir_index = current_dir_index; int initial_current_dir_first_block = current_dir->first_block; mychdir(path); // set the file name char filename[MAXNAME]; strcpy(filename, last_entry_in_path(path_to_array(path))); strcat(filename, "\0"); int location = file_entry_index(filename); if (location == -1) { printf("File not found.\n"); return; } // clear the fat entries int block_index = virtual_disk[current_dir_index].dir.entrylist[location].first_block; int next_block_index; while(1){ next_block_index = FAT[block_index]; FAT[block_index] = UNUSED; if (next_block_index == ENDOFCHAIN) break; block_index = next_block_index; } copy_fat(FAT); // clear the dir_entry direntry_t *dir_entry = &virtual_disk[current_dir_index].dir.entrylist[location]; dir_entry->first_block = 0; dir_entry->unused = 1; int length = strlen(dir_entry->name); for (int i = 0; i < length; i++){ dir_entry->name[i] = '\0'; } current_dir_index = initial_current_dir_index; current_dir->first_block = initial_current_dir_first_block; }
bool RunCommands(CCommandArray& Commands, LPCTSTR pszOrigDocName) { s_bRunsCommands = true; char szCurDir[MAX_PATH]; _getcwd(szCurDir, MAX_PATH); procWnd.GetReady(); // cut up document name into file and extension components. // create two sets of buffers - one set with the long filename // and one set with the 8.3 format. char szDocLongPath[MAX_PATH] = {0}, szDocLongName[MAX_PATH] = {0}, szDocLongExt[MAX_PATH] = {0}; char szDocShortPath[MAX_PATH] = {0}, szDocShortName[MAX_PATH] = {0}, szDocShortExt[MAX_PATH] = {0}; GetFullPathName(pszOrigDocName, MAX_PATH, szDocLongPath, NULL); GetShortPathName(pszOrigDocName, szDocShortPath, MAX_PATH); // split them up char *p = strrchr(szDocLongPath, '.'); if(p && strrchr(szDocLongPath, '\\') < p && strrchr(szDocLongPath, '/') < p) { // got the extension strcpy(szDocLongExt, p+1); p[0] = 0; } p = strrchr(szDocLongPath, '\\'); if(!p) p = strrchr(szDocLongPath, '/'); if(p) { // got the filepart strcpy(szDocLongName, p+1); p[0] = 0; } // split the short part up p = strrchr(szDocShortPath, '.'); if(p && strrchr(szDocShortPath, '\\') < p && strrchr(szDocShortPath, '/') < p) { // got the extension strcpy(szDocShortExt, p+1); p[0] = 0; } p = strrchr(szDocShortPath, '\\'); if(!p) p = strrchr(szDocShortPath, '/'); if(p) { // got the filepart strcpy(szDocShortName, p+1); p[0] = 0; } int iSize = Commands.GetSize(), i = 0; char *ppParms[32]; while(iSize--) { CCOMMAND &cmd = Commands[i++]; // anything there? if((!cmd.szRun[0] && !cmd.iSpecialCmd) || !cmd.bEnable) continue; // set name pointers for long filenames pszDocExt = szDocLongExt; pszDocName = szDocLongName; pszDocPath = szDocLongPath; char szNewParms[MAX_PATH*5], szNewRun[MAX_PATH*5]; // HACK: force the spawnv call for launching the game if (!Q_stricmp(cmd.szRun, "$game_exe")) { cmd.bUseProcessWnd = FALSE; } FixGameVars(cmd.szRun, szNewRun, TRUE); FixGameVars(cmd.szParms, szNewParms, TRUE); CString strTmp; strTmp.Format("\r\n" "** Executing...\r\n" "** Command: %s\r\n" "** Parameters: %s\r\n\r\n", szNewRun, szNewParms); procWnd.Append(strTmp); // create a parameter list (not always required) if(!cmd.bUseProcessWnd || cmd.iSpecialCmd) { char *p = szNewParms; ppParms[0] = szNewRun; int iArg = 1; BOOL bDone = FALSE; while(p[0]) { ppParms[iArg++] = p; while(p[0]) { if(p[0] == ' ') { // found a space-separator p[0] = 0; p++; // skip remaining white space while (*p == ' ') p++; break; } // found the beginning of a quoted parameters if(p[0] == '\"') { while(1) { p++; if(p[0] == '\"') { // found the end if(p[1] == 0) bDone = TRUE; p[1] = 0; // kick its ass p += 2; // skip remaining white space while (*p == ' ') p++; break; } } break; } // else advance p ++p; } if(!p[0] || bDone) break; // done. } ppParms[iArg] = NULL; if(cmd.iSpecialCmd) { BOOL bError = FALSE; LPCTSTR pszError = ""; if(cmd.iSpecialCmd == CCCopyFile && iArg == 3) { RemoveQuotes(ppParms[1]); RemoveQuotes(ppParms[2]); // don't copy if we're already there if (stricmp(ppParms[1], ppParms[2]) && (!CopyFile(ppParms[1], ppParms[2], FALSE))) { bError = TRUE; pszError = GetErrorString(); } } else if(cmd.iSpecialCmd == CCDelFile && iArg == 2) { RemoveQuotes(ppParms[1]); if(!DeleteFile(ppParms[1])) { bError = TRUE; pszError = GetErrorString(); } } else if(cmd.iSpecialCmd == CCRenameFile && iArg == 3) { RemoveQuotes(ppParms[1]); RemoveQuotes(ppParms[2]); if(rename(ppParms[1], ppParms[2])) { bError = TRUE; pszError = strerror(errno); } } else if(cmd.iSpecialCmd == CCChangeDir && iArg == 2) { RemoveQuotes(ppParms[1]); if(mychdir(ppParms[1]) == -1) { bError = TRUE; pszError = strerror(errno); } } if(bError) { CString str; str.Format("The command failed. Windows reported the error:\r\n" " \"%s\"\r\n", pszError); procWnd.Append(str); procWnd.SetForegroundWindow(); str += "\r\nDo you want to continue?"; if(AfxMessageBox(str, MB_YESNO) == IDNO) break; } } else { // Change to the game exe folder before spawning the engine. // This is necessary for Steam to find the correct Steam DLL (it // uses the current working directory to search). char szDir[MAX_PATH]; Q_strncpy(szDir, szNewRun, sizeof(szDir)); Q_StripFilename(szDir); mychdir(szDir); // YWB Force asynchronous operation so that engine doesn't hang on // exit??? Seems to work. // spawnv doesn't like quotes RemoveQuotes(szNewRun); _spawnv(/*cmd.bNoWait ?*/ _P_NOWAIT /*: P_WAIT*/, szNewRun, (const char *const *)ppParms); } } else { procWnd.Execute(szNewRun, szNewParms); } // check for existence? if(cmd.bEnsureCheck) { char szFile[MAX_PATH]; FixGameVars(cmd.szEnsureFn, szFile, FALSE); if(GetFileAttributes(szFile) == 0xFFFFFFFF) { // not there! CString str; str.Format("The file '%s' was not built.\n" "Do you want to continue?", szFile); procWnd.SetForegroundWindow(); if(AfxMessageBox(str, MB_YESNO) == IDNO) break; // outta here } } } mychdir(szCurDir); s_bRunsCommands = false; return TRUE; }