Beispiel #1
0
int CheckUpdateAnotherPanel(Panel *SrcPanel, const string& SelName)
{
	if (!SrcPanel)
		SrcPanel = Global->CtrlObject->Cp()->ActivePanel();

	const auto AnotherPanel = Global->CtrlObject->Cp()->GetAnotherPanel(SrcPanel);
	AnotherPanel->CloseFile();

	if (AnotherPanel->GetMode() == NORMAL_PANEL)
	{
		string strFullName;
		string strAnotherCurDir(AnotherPanel->GetCurDir());
		AddEndSlash(strAnotherCurDir);
		ConvertNameToFull(SelName, strFullName);
		AddEndSlash(strFullName);

		if (strAnotherCurDir.find(strFullName) != string::npos)
		{
			AnotherPanel->StopFSWatcher();
			return TRUE;
		}
	}

	return FALSE;
}
Beispiel #2
0
/***************************************
            FileEnum
 ***************************************/
BOOL MYRTLEXP FILE_ENUM::OpenDir( CONSTSTR path )
  {
    if ( !path ) path = "";

    oldDir = GetCurDir();
    if ( !SetCurDir(path) ) {
      SetCurDir( oldDir.Text() );
      return FALSE;
    }

    Path = GetCurDir();
    SetCurDir( oldDir.Text() );

  #if defined(__GNUC__) || defined(__QNX__)
    dir = opendir( Path.Text() );
    if ( dir == NULL || (ent=readdir(dir)) == NULL ) return FALSE;
    FPath = Path;
    FPath.Add( ent->d_name );
  #else
  #if defined(__REALDOS__) || defined(__HWIN16__)
    MemSet( &f,0,sizeof(f) );
    if ( findfirst( MakePathName(path,ALL_FILES).Text(),&f,FIO_ALLFILES ) != 0 )
      return FALSE;
    FPath = Path+f.ff_name;
  #else
  #if defined(__PROTDOS__)
    MemSet( &f,0,sizeof(f) );
    FIND *res;
    if ( (res=findfirst( MakePathName(path,ALL_FILES).Text(),FIO_ALLFILES )) == NULL )
      return FALSE;
    f = *res;
    FPath = Path+f.name;
  #else
  #if defined(__HWIN__)
    fHandle = FindFirstFile( MakePathName(path,ALL_FILES).Text(),&f );
    if ( fHandle == INVALID_HANDLE_VALUE ) return FALSE;
    FPath = Path;
    FPath.Add( f.cFileName );
  #else
  #error ERR_PLATFORM
  #endif
  #endif
  #endif
  #endif
 return TRUE;
}
Beispiel #3
0
MyString MYRTLEXP MakeFullPathName( const MyString& fname, const MyString& base )
  {  MyString oldP,s;

    if ( fname.Chr(SLASH_CHAR) == -1 ) {
      s.Set( base );
      s.Add( SLASH_CHAR );
      s.Add( fname );
      return s;
    }

    oldP = GetCurDir();
     //Go base path
     SetCurDir( base.Text() );
     //Go fname path in case it relative
     SetCurDir( FPath(fname.Text()) );
     //Get result path + name
     s.Set( GetCurDir() );
     s.Add( FName(fname.Text()) );
    SetCurDir( oldP.Text() );
 return s;
}
Beispiel #4
0
void MYRTLEXP CTArgInit( int argc, char **argv,BOOL CaseSensitive )
  {
    DeleteArgs();
    CT_CaseSensitive = CaseSensitive;
    CT_SelfArgs      = TRUE;

    CT_argc = argc;
    CT_argv = new pchar[ CT_argc+1 ];
    int n;

    if ( StrChr(argv[0],SLASH_CHAR) == NULL )
      CT_argv[0] = StrDup( MakePathName(GetCurDir(),argv[0]).Text() );
     else
      CT_argv[0] = StrDup( argv[0] );

    for( n = 1; n < CT_argc; n++ )
      CT_argv[n] = StrDup( argv[n] );

    CT_argv[n] = NULL;
}
Beispiel #5
0
bool FileSelectorLoad(HWND hwnd, char *filename, FileType type, char* title)
{
	char *filter=GetFilter(type);
	static OPENFILENAME dia;
	dia.lStructSize = sizeof(OPENFILENAME);
	dia.hwndOwner = hwnd;
	dia.lpstrFile = g_chosen_filename[type];
	dia.nMaxFile = _MAX_DIR;
	dia.lpstrFileTitle = g_chosen_file[type];
	dia.nMaxFileTitle = _MAX_FNAME;
	dia.lpstrInitialDir = GetCurDir(type);
	dia.lpstrFilter = filter;
	dia.lpstrDefExt = fsel_defext;
	dia.lpstrTitle = title;
	dia.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST;
	if(!GetOpenFileName(&dia))
		return false;
	strcpy(filename, g_chosen_filename[type]);
	SetCurDir(type, g_chosen_filename[type]);
	return true;
}
bool FileSelectorSave(HWND hwnd, char *filename, int type)
{
	char *filter=GetFilter(type);
	static OPENFILENAME dia;
	dia.lStructSize = sizeof(OPENFILENAME);
	dia.hwndOwner = hwnd;
	dia.lpstrFile = chosen_filename[type];
	dia.nMaxFile = _MAX_DIR;
	dia.lpstrFileTitle = chosen_file[type];
	dia.nMaxFileTitle = _MAX_FNAME;
	dia.lpstrInitialDir = GetCurDir(type);
	dia.lpstrFilter = filter;
	dia.lpstrDefExt = fsel_defext;
	dia.lpstrTitle = "Save As";
	dia.Flags = OFN_EXPLORER | OFN_OVERWRITEPROMPT;
	if(!GetSaveFileName(&dia))
		return false;
	strcpy(filename, chosen_filename[type]);
	SetCurDir(type, chosen_filename[type]);
	return true;
}
Beispiel #7
0
// 获取随机文件名(全路径)
tstring CPath::GetRandomFileName(LPCTSTR lpszPath, LPCTSTR lpszFileName)
{
	tstring strPath, strFileName, strExtFileName, strFullPath;
	TCHAR szBuf[MAX_PATH] = {0};

	if (!IsDirectoryExist(lpszPath))
		strPath = GetCurDir();
	else
		strPath = lpszPath;

	strFileName = GetFileNameWithoutExtension(lpszFileName);
	strExtFileName = GetExtension(lpszFileName);

	for (int i = 2; i < 10000; i++)
	{
		if (strExtFileName.empty())
		{
			strFullPath = strPath;
			strFullPath += strFileName;
			wsprintf(szBuf, _T("%d"), i);
			strFullPath += szBuf;
		}
		else
		{
			strFullPath = strPath;
			strFullPath += strFileName;
			wsprintf(szBuf, _T("%d."), i);
			strFullPath += szBuf;
			strFullPath += strExtFileName;
		}
		
		if (!IsFileExist(strFullPath.c_str()))
			return strFullPath;
	}

	return _T("");
}
Beispiel #8
0
int main(int argc, char *argv[])
{
    char ans[2];
    char *fileargs[64];
    char *optargs[64];
    int n_options;
    int index;
    int help_flag = 0;

#ifdef __TURBOC__
    setvect(0x23, ctrlc_hndlr);
#else
    _dos_setvect(0x23, ctrlc_hndlr);
#endif
    atexit(on_exit);
    n_options = classify_args(argc, argv, fileargs, optargs);
    for (index=0;index<n_options;index++)
        {
        if (optargs[index][0] == '?') help_flag=1;
        else
            {
            myprintf("Invalid parameter - /",0);
            myprintf(optargs[index],0); /* removed strupr */
            myprintf("\r\n",0);
            exit(1);
            } /* end else. */

        } /* end for. */

    if (help_flag)
        {
        myprintf("\r\nLABEL Version " VERSION "\r\n", 0);
        myprintf("Creates, changes or deletes the volume label of a disk.\r\n",0);
        myprintf("\r\n",0);
        myprintf("Syntax: LABEL [drive:][label] [/?]\r\n",0);
        myprintf("  [drive:]  Specifies which drive you want to label\r\n",0);
        myprintf("  [label]   Specifies the new label you want to label the drive\r\n",0);
        myprintf("  /?        Displays this help message\r\n",0);
        return 0;
        } /* end if. */

    do_cmdline(argc, argv);
    if (*Drive == '?')  /* If no drive specified, use current. */
        GetDrive();

    /* Save current directory and move to root. */
    GetCurDir(curdir);
    if (curdir[0] != 0)
        {
        *rootdir = *Drive;
        SetCurDir(rootdir);
        } /* end if. */

    /* If no label was specified, show current one first and then get new one. */
    if (*Label == '\0')
        {
        disp_label();
        get_label();
        } /* end if. */

    /* If they entered an empty label, then ask them if they want to */
    /* delete the existing volume label. */
    if ((*Label == '\0') && (!NoLabel))
        {
        do
            {
            myprintf("\nDelete current volume label (Y/N)? ",0);
            mygets(ans,2); /* WHY not use getch? ??? */
            } /* end do. */
        while (((*ans=(char)toupper(*ans)) != 'Y') && (*ans != 'N'));

        if (toupper(*ans) == 'N')
            exit(1);

        } /* end if. */

    /* Delete the old volume label. */
    del_label();

    /* Create the new one, if there is one to create. */
    if (*Label != '\0')
        {
        if (make_label())
            {
            exit(1);
            } /* end if. */

        } /* end if. */

    exit(0);
    return 0;

} /* end main. */
Beispiel #9
0
bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
{
  res = s;

  #ifdef UNDER_CE

  if (s[0] != CHAR_PATH_SEPARATOR)
  {
    if (!dirPrefix)
      return false;
    res = dirPrefix;
    res += s;
  }

  #else

  unsigned prefixSize = GetRootPrefixSize(s);
  if (prefixSize != 0)
  {
    if (!AreThereDotsFolders(s + prefixSize))
      return true;
    
    UString rem = fs2us(s + prefixSize);
    if (!ResolveDotsFolders(rem))
      return true; // maybe false;
    res.DeleteFrom(prefixSize);
    res += us2fs(rem);
    return true;
  }

  /*
  FChar c = s[0];
  if (c == 0)
    return true;
  if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
    return true;
  if (c == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR)
    return true;
  if (IsDrivePath(s))
    return true;
  */

  UString curDir;
  if (dirPrefix)
    curDir = fs2us(dirPrefix);
  else
  {
    if (!GetCurDir(curDir))
      return false;
  }
  if (!curDir.IsEmpty() && curDir.Back() != WCHAR_PATH_SEPARATOR)
    curDir += WCHAR_PATH_SEPARATOR;

  unsigned fixedSize = 0;

    if (IsDrivePath(curDir))
      fixedSize = kDrivePrefixSize;
  
  UString temp;
  if (s[0] == CHAR_PATH_SEPARATOR)
  {
    temp = fs2us(s + 1);
  }
  else
  {
    temp += curDir.Ptr(fixedSize);
    temp += fs2us(s);
  }
  if (!ResolveDotsFolders(temp))
    return false;
  curDir.DeleteFrom(fixedSize);
  res = us2fs(curDir);
  res += us2fs(temp);
  
  #endif // UNDER_CE

  return true;
}
Beispiel #10
0
static bool GetSuperPathBase(CFSTR s, UString &res)
{
  res.Empty();
  
  FChar c = s[0];
  if (c == 0)
    return true;
  if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
    return true;
  
  if (IsSuperOrDevicePath(s))
  {
    #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
    
    if ((s)[2] == '.')
      return true;

    // we will return true here, so we will try to use these problem paths.

    if (!AreThereDotsFolders(s + kSuperPathPrefixSize))
      return true;
    
    UString temp = fs2us(s);
    unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
    if (fixedSize == 0)
      return true;

    UString rem = &temp[fixedSize];
    if (!ResolveDotsFolders(rem))
      return true;

    temp.DeleteFrom(fixedSize);
    res += temp;
    res += rem;
    
    #endif

    return true;
  }

  if (c == CHAR_PATH_SEPARATOR)
  {
    if (s[1] == CHAR_PATH_SEPARATOR)
    {
      UString temp = fs2us(s + 2);
      unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
      if (fixedSize == 0) // maybe we must ignore that error to allow short network paths?
        return false;
      UString rem = &temp[fixedSize];
      if (!ResolveDotsFolders(rem))
        return false;
      res += kSuperUncPrefix;
      temp.DeleteFrom(fixedSize);
      res += temp;
      res += rem;
      return true;
    }
  }
  else
  {
    if (IsDrivePath(s))
    {
      UString temp = fs2us(s);
      UString rem = &temp[kDrivePrefixSize];
      if (!ResolveDotsFolders(rem))
        return true;
      res += kSuperPathPrefix;
      temp.DeleteFrom(kDrivePrefixSize);
      res += temp;
      res += rem;
      return true;
    }
  }

  UString curDir;
  if (!GetCurDir(curDir))
    return false;
  if (curDir.Back() != WCHAR_PATH_SEPARATOR)
    curDir += WCHAR_PATH_SEPARATOR;

  unsigned fixedSizeStart = 0;
  unsigned fixedSize = 0;
  const wchar_t *superMarker = NULL;
  if (IsSuperPath(curDir))
  {
    fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
    if (fixedSize == 0)
      return false;
  }
  else
  {
    if (IsDrivePath(curDir))
    {
      superMarker = kSuperPathPrefix;
      fixedSize = kDrivePrefixSize;
    }
    else
    {
      if (curDir[0] != CHAR_PATH_SEPARATOR || curDir[1] != CHAR_PATH_SEPARATOR)
        return false;
      fixedSizeStart = 2;
      fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
      if (fixedSize == 0)
        return false;
      superMarker = kSuperUncPrefix;
    }
  }
  
  UString temp;
  if (c == CHAR_PATH_SEPARATOR)
  {
    temp = fs2us(s + 1);
  }
  else
  {
    temp += &curDir[fixedSizeStart + fixedSize];
    temp += fs2us(s);
  }
  if (!ResolveDotsFolders(temp))
    return false;
  if (superMarker)
    res += superMarker;
  res += curDir.Mid(fixedSizeStart, fixedSize);
  res += temp;
  return true;
}
Beispiel #11
0
static int MainProcess(
    const string& EditName,
    const string& ViewName,
    const string& DestName1,
    const string& DestName2,
    int StartLine,
    int StartChar
)
{
		SCOPED_ACTION(ChangePriority)(THREAD_PRIORITY_NORMAL);
		FarColor InitAttributes={};
		console.GetTextAttributes(InitAttributes);
		SetRealColor(colors::PaletteColorToFarColor(COL_COMMANDLINEUSERSCREEN));

		string ename(EditName),vname(ViewName), apanel(DestName1),ppanel(DestName2);
		if (ConfigProvider().ShowProblems())
		{
			ename.clear();
			vname.clear();
			StartLine = StartChar = -1;
			apanel = Global->Opt->ProfilePath;
			ppanel = Global->Opt->LocalProfilePath;
		}

		if (!ename.empty() || !vname.empty())
		{
			Global->OnlyEditorViewerUsed = true;

			_tran(SysLog(L"create dummy panels"));
			Global->CtrlObject->CreateDummyFilePanels();
			Global->WindowManager->PluginCommit();

			Global->CtrlObject->Plugins->LoadPlugins();
			Global->CtrlObject->Macro.LoadMacros(true, true);

			if (!ename.empty())
			{
				const auto ShellEditor = FileEditor::create(ename, CP_DEFAULT, FFILEEDIT_CANNEWFILE | FFILEEDIT_ENABLEF6, StartLine, StartChar);
				_tran(SysLog(L"make shelleditor %p",ShellEditor));

				if (!ShellEditor->GetExitCode())  // ????????????
				{
					Global->WindowManager->ExitMainLoop(0);
				}
			}
			// TODO: Этот else убрать только после разборок с возможностью задавать несколько /e и /v в ком.строке
			else if (!vname.empty())
			{
				const auto ShellViewer = FileViewer::create(vname, true);

				if (!ShellViewer->GetExitCode())
				{
					Global->WindowManager->ExitMainLoop(0);
				}

				_tran(SysLog(L"make shellviewer, %p",ShellViewer));
			}

			Global->WindowManager->EnterMainLoop();
		}
		else
		{
			int DirCount=0;

			// воспользуемся тем, что ControlObject::Init() создает панели
			// юзая Global->Opt->*

			const auto& SetupPanel = [&](bool active)
			{
				++DirCount;
				string strPath = active? apanel : ppanel;
				if (os::fs::is_file(strPath))
				{
					CutToParent(strPath);
				}

				bool Root = false;
				const auto Type = ParsePath(strPath, nullptr, &Root);
				if(Root && (Type == root_type::drive_letter || Type == root_type::unc_drive_letter || Type == root_type::volume))
				{
					AddEndSlash(strPath);
				}

				auto& CurrentPanelOptions = (Global->Opt->LeftFocus == active)? Global->Opt->LeftPanel : Global->Opt->RightPanel;
				CurrentPanelOptions.m_Type = static_cast<int>(panel_type::FILE_PANEL);  // сменим моду панели
				CurrentPanelOptions.Visible = true;     // и включим ее
				CurrentPanelOptions.Folder = strPath;
			};

			if (!apanel.empty())
			{
				SetupPanel(true);

				if (!ppanel.empty())
				{
					SetupPanel(false);
				}
			}

			// теперь все готово - создаем панели!
			Global->CtrlObject->Init(DirCount);

			// а теперь "провалимся" в каталог или хост-файл (если получится ;-)
			if (!apanel.empty())  // активная панель
			{
				const auto ActivePanel = Global->CtrlObject->Cp()->ActivePanel();
				const auto AnotherPanel = Global->CtrlObject->Cp()->PassivePanel();

				if (!ppanel.empty())  // пассивная панель
				{
					FarChDir(AnotherPanel->GetCurDir());

					if (IsPluginPrefixPath(ppanel))
					{
						AnotherPanel->Parent()->SetActivePanel(AnotherPanel);

						execute_info Info;
						Info.Command = ppanel;

						Global->CtrlObject->CmdLine()->ExecString(Info);
						ActivePanel->Parent()->SetActivePanel(ActivePanel);
					}
					else
					{
						const auto strPath = PointToName(ppanel);

						if (!strPath.empty())
						{
							if (AnotherPanel->GoToFile(strPath))
								AnotherPanel->ProcessKey(Manager::Key(KEY_CTRLPGDN));
						}
					}
				}

				FarChDir(ActivePanel->GetCurDir());

				if (IsPluginPrefixPath(apanel))
				{
					execute_info Info;
					Info.Command = apanel;

					Global->CtrlObject->CmdLine()->ExecString(Info);
				}
				else
				{
					const auto strPath = PointToName(apanel);

					if (!strPath.empty())
					{
						if (ActivePanel->GoToFile(strPath))
							ActivePanel->ProcessKey(Manager::Key(KEY_CTRLPGDN));
					}
				}

				// !!! ВНИМАНИЕ !!!
				// Сначала редравим пассивную панель, а потом активную!
				AnotherPanel->Redraw();
				ActivePanel->Redraw();
			}

			Global->WindowManager->EnterMainLoop();
		}

		TreeList::FlushCache();

		// очистим за собой!
		SetScreen(0,0,ScrX,ScrY,L' ',colors::PaletteColorToFarColor(COL_COMMANDLINEUSERSCREEN));
		console.SetTextAttributes(InitAttributes);
		Global->ScrBuf->ResetLockCount();
		Global->ScrBuf->Flush();

		return 0;
}
Beispiel #12
0
main()
{
    static char text[MAXSEARCH];  /* Pointer to buffer for search text  */
    static char date_time[19];    /* Receive file date and time         */
    int err, mode, handle, len;   /* Codes, file handle, bytes read     */
    int row, col, ch;             /* Cursor coordinates, kb character   */
    int i, j, attr;               /* Index variables, file attribute    */
    int disp_attr;                /* Display attribute                  */
    char *spec, *ptr, *buffer;    /* File spec, char match, read buffer */
    long dsize, disk_use;         /* Disk size and usage                */
    struct DISKSTAT disk;         /* Structure for disk size params     */

    static char copy_msg[] =
    {
        "Files can be copied or moved in 2 different modes:\n" \
        "      0  -  overwrite target file if it exists\n" \
        "      1  -  abort if target file exists\n\n" \
        "Mode 1 is supported only with DOS versions 3.0 or higher.\n"
    };
    static char move_msg[] =
    {
        "Quick Move uses DOS function 56h (Rename File) to effectively " \
        "move a file from\none directory to another directory on the " \
        "same drive.  It copies the entry\nfrom the source directory to " \
        "the target directory, but does not physically\ncopy the file.\n\n" \
        "Source and target specifications must be given in full, " \
        "including filenames,\neven if the names are the same."
    };
    static char grep_msg[] =
    {
        "The Find Text option uses the StrFindChar and StrCompare procedures " \
        "to locate\na text string within specified files, like Unix's " \
        "\"grep\" command.  Find Text\nis limited to case-sensitive searches " \
        "within the current directory.\n\nEnter the desired search string " \
        "without quotation marks.  When specifying the\nfilename, use " \
        "wildcard characters to expand the search to a group of files --\n" \
        "for example, \"*.*\" searches all files within the current " \
        "directory, \"*.bat\"\nlimits the search to batch files, and so forth."
    };
    static char attr_msg[] =
    {
        "\t\t\t1    normal      \n" \
        "\t\t\t2    read-only   \n" \
        "\t\t\t3    hidden      \n" \
        "\t\t\t4    system      \n" \
        "\t\t\t     volume      \n" \
        "\t\t\t     subdirectory\n" \
        "\t\t\t5    archive     \n"
    };

    GetVidConfig();
    ReadCharAttr( &disp_attr );
    clear_scrn( disp_attr, 0, 24 );
    SetCurPos( 8, 0 );
    puts( "Welcome to the FILEDEMO program.\n\n\nThis program is meant " \
          "to encourage experimentation while demonstrating how to\naccess " \
          "DOS from assembly-language procedures.  As a safety precaution, " \
          "however,\nwe suggest you DO NOT experiment with files that " \
          "cannot easily be replaced." );
    press();

    do
    {
        /* Display current drive and directory */
        clear_scrn( disp_attr, 0, 24 );
        SetCurPos( 0, 0 );
        printf( "Current Directory:  %c:\\", (char)(GetCurDrive() + 'A') );
        GetCurDir( source );
        puts( source );

        /* Display DOS version */
        SetCurPos( 1, 0 );
        printf( "DOS Version:        %2.1f", ( (float) GetVer() ) / 100 );

        /* Display disk statistics for current drive */
        SetCurPos( 0, 58 );
        GetDiskSize( 0, &disk );
        dsize = (long)disk.bytes * disk.sects * disk.total;
        disk_use = (long)(disk.total - disk.avail) * disk.bytes * disk.sects;
        printf( "Disk Size: %6lu K", dsize / 1024 );
        SetCurPos( 1, 58 );
        printf( "Disk Use:  %6lu K", disk_use / 1024 );

        /* Display menu and poll for keystroke */
        clear_scrn( disp_attr, 2, 23 );
        SetCurPos( 5, 0 );
        puts( " \t               ***      FILE " \
              "Demonstration Program      ***" );
        SetCurPos( 7, 0 );
        puts( " \tA  List Directory       \t\tH  Get/Set File Attribute" );
        puts( " \tB  Copy File            \t\tI  Get File Date and Time" );
        puts( " \tC  Move File            \t\tJ  Rename File" );
        puts( " \tD  Make Subdirectory    \t\tK  Delete File" );
        puts( " \tE  Remove Subdirectory  \t\tL  Create Unique File" );
        puts( " \tF  Change Default Drive \t\tM  Quick Move" );
        puts( " \tG  Change Directory     \t\tN  Find Text" );
        printf( "\n\n\tSelect an option, or press ESC to quit: " );
        ch = getch();
        switch( (ch = toupper( ch )) )
        {
            /* List first 60 files in specified directory */
            case 'A':
                err  = list_dir( get_spec( 1 ), disp_attr );
                if( !err )
                    press();
                break;

            /* Copy or Move File according to requested mode:
             *          0 = overwrite target
             *          1 = abort if target exists
             * If Move requested, delete source file after copy.
             */
            case 'B':
            case 'C':
                clear_scrn( disp_attr, 2, 17 );
                SetCurPos( 9, 0 );
                puts( copy_msg );
                mode = -1;
                while( (mode < 0)  ||  (mode > 1) )
                {
                    SetCurPos( 16, 0 );
                    printf( "Enter copy mode:  " );
                    mode = (int)(getche() - '0');
                }
                spec = get_spec( 2 );                   /* Get source     */
                strcpy( source, spec );                 /* Save in buffer */
                spec = get_spec( 3 );                   /* Get target     */
                err  = CopyFile( mode, source, spec );
                if( (ch == 'C')  &&  !err )
                    err = DelFile( source );
                break;

            /* Make Directory */
            case 'D':
                err = MakeDir( get_spec( 1 ) );
                break;

            /* Remove Directory */
            case 'E':
                err = RemoveDir( get_spec( 1 ) );
                break;

            /* Change Default Drive */
            case 'F':
                SetCurPos( 18, 0 );
                printf( "Enter new drive letter:  " );
                ch = getch();
                ch = toupper( ch );
                ChangeDrive( ch );
                err = 0;
                break;

            /* Change Directory */
            case 'G':
                err = ChangeDir( get_spec( 1 ) );
                break;

            /* Get and Set File Attributes */
            case 'H':
                strcpy( source, get_spec( 3 ) );
                if( (err = GetAttribute( source )) != -1 )
                {
                    attr = err;
                    if( !attr )
                        attr_msg[6] = '*';
                    else
                        attr_msg[6] = ' ';
                    for( j = 1, i = 27; j <= 32; j <<= 1, i+= 21 )
                    {
                        attr_msg[i] = ' ';
                        if( attr & j )
                            attr_msg[i] = '*';
                    }
                    err = 0;
                    clear_scrn( disp_attr, 2, 17 );
                    SetCurPos( 7, 0 );
                    puts( attr_msg );
                    printf( "\n\nToggle attribute bits by selecting 1-5, " \
                            "or any other key to exit:  " );
                    mode = (int)( getch() - '0' );
                    if( (mode > 0)  &&  (mode < 6) )
                    {
                        switch( --mode )
                        {
                            case 0:
                                attr = 0;
                                break;

                            case 1:
                            case 2:
                            case 3:
                                attr = attr ^ (1 << (--mode) );
                                break;

                            case 4:
                                attr = attr ^ 32;
                        }
                        err = SetAttribute( attr, source );
                    }
                }
                break;

            /* Get File Date and Time */
            case 'I':
                if( (handle = OpenFile( 0, get_spec( 3 ) )) == -1 )
                    err = 1;
                else
                    err = 0;
                if( !err )
                {
                    if( !(err = GetFileTime( handle, date_time )) )
                    {
                        clear_scrn( disp_attr, 2, 17 );
                        SetCurPos( 12, 10 );
                        printf( "File's date and time stamp:  %s", date_time );
                        CloseFile( handle );
                        press();
                    }
                }
                break;

            /* Rename File */
            case 'J':
                strcpy( source, get_spec( 2 ) );
                err = RenameFile( source, get_spec( 3 ) );
                break;

            /* Delete File */
            case 'K':
                err = DelFile( get_spec( 3 ) );
                break;

            /* Create File with Unique Name */
            case 'L':
                strcpy( source, get_spec( 1 ) );
                handle = UniqueFile( 0, source );   /* Normal file attr = 0 */
                if( handle >= 0 )
                {
                    printf( "\n\nDOS creates file %s", source );
                    press();
                    err = 0;
                }
                else err = 1;
                break;

            /* Quick Move from one directory to another */
            case 'M':
                clear_scrn( disp_attr, 2, 17 );
                SetCurPos( 8, 0 );
                puts( move_msg );
                strcpy( source, get_spec( 2 ) );
                err = RenameFile( source, get_spec( 3 ) );
                break;

            /* Search files for specified text */
            case 'N':
                clear_scrn( disp_attr, 2, 17 );
                buffer = (char *) malloc( BUFFSIZE + 1 );
                if( buffer == NULL )
                {
                    SetCurPos( 12, 26 );
                    puts( "Insufficient memory for option" );
                    err = 1;
                    break;
                }
                SetCurPos( 7, 0 );
                puts( grep_msg );
                SetCurPos( 18, 0 );
                printf( "Enter search text:  " );
                GetStr( text, MAXSEARCH );

                /* Find first data file. */
                if( err = FindFirst( 0, get_spec( 3 ), &file ) )
                {
                    clear_scrn( disp_attr, 2, 17 );
                    SetCurPos( 12, 24 );
                    puts( "No files found matching specification" );
                }

                /* If file found, initialize screen coordinates and
                 * open file for reading.
                 */
                else
                {
                    clear_scrn( disp_attr, 2, 17 );
                    row = 6;
                    col = 0;
                    do
                    {
                        if( (handle = OpenFile( 0, file.filename )) != -1 )
                        {

                            /* If file opened successfully, read a block
                             * of BUFFSIZE bytes. If end-of-file encountered
                             * (number of bytes read not equal to BUFFSIZE)
                             * or read error, set error flag to break loop.
                             * Terminate block with a NULL character to 
                             * make it an ASCIIZ string.
                             */
                            err = 0;
                            while( !err )
                            {
                                len = ReadFile( handle, BUFFSIZE, buffer );
                                if( (len == 0)  ||  (len != BUFFSIZE) )
                                    ++err;
                                ptr = buffer;
                                *( ptr + len ) = 0;

                                /* Search block for first character in text */
                                while( spec = StrFindChar( text[0], ptr, 0 ) )
                                {

                                    /* If initial character found, compare
                                     * remaining characters in search text.
                                     * If all characters match, display file
                                     * name and break out of loop.
                                     */
                                    ptr = StrCompare( ++spec, &text[1],
                                          (strlen( text ) - 1) );
                                    if( !ptr )
                                    {
                                        SetCurPos( row++, col );
                                        puts( file.filename );
                                        if( row == 16)
                                        {
                                            row  = 6;
                                            col += 20;
                                        }
                                        err  = 1;
                                        break;
                                    }
                                }
                            }
                            CloseFile( handle );
                        }
                        else
                        {
                            err = 1;
                            break;
                        }
                    } while( !FindNext( &file ) );

                    if( (row == 6)  &&  (col == 0) )
                    {
                        SetCurPos( 12, 22 );
                        puts( "Text not found in specified file(s)" );
                    }
                    press();
                    err = 0;
                }
                free( buffer );             /* Free allocated block */
                break;

            default:
                continue;
        }

        if( err )
        {
            clear_scrn( disp_attr, 24, 24 );
            SetCurPos( 24, 0 );
            printf( "***  Error  ***\a" );
            press();
        }

    } while( ch != ESCAPE );            /* Exit if ESC key pressed    */

    clear_scrn( disp_attr, 0, 24 );     /* Clear screen before exit   */
    SetCurPos( 23, 0 );                 /*   and set cursor to bottom */
    return( 0 );
}