home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CDPD Public Domain Collection for CDTV 3
/
CDPDIII.bin
/
pd
/
utilities
/
dirutils
/
visualshell
/
src
/
dos2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-28
|
14KB
|
509 lines
/*********************************
* *
* Visual Shell v1.17 10/92 *
* *
* by Torsten Jürgeleit *
* *
* dos part 2 *
* *
*********************************/
/* Includes */
#include "includes.h"
#include "imports.h"
#include "protos.h"
/* Make new directory */
VOID
action_make_dir(VOID)
{
struct FileRequest *freq1 = &file_req[active_freq],
*freq2 = &file_req[(active_freq ? 0 : 1)];
struct FileNode *fnode;
BYTE *dir_name;
BPTR lock, plock, cd_lock;
BYTE old_name[MAX_FILE_NAME_LEN + 1];
ULONG old_pos;
SHORT old_cursor_line = freq1->fr_CursorLine, error = VSH_STATUS_NORMAL;
if (freq1->fr_Mode == FREQ_MODE_NORMAL || freq1->fr_Mode ==
FREQ_MODE_FIND) {
hcomp_freq_cursor(freq1);
print_info_line(INFO_LINE_MODE_EMPTY);
print_fkey_text(FKEY_MODE_NONE);
/* Save name and pos of old cursor line node */
if (old_cursor_line != -1) {
fnode = get_file_node_under_cursor(freq1);
strncpy(&old_name[0], &fnode->fn_Text[0], (size_t)
fnode->fn_NameLen);
old_name[fnode->fn_NameLen] = '\0';
old_pos = fnode->fn_Pos;
}
if (dir_name = get_input(INPUT_MODE_MAKE_DIR, NULL)) {
/* Create new directory and check if it goes to current directory */
print_status(VSH_STATUS_MAKE_DIR);
cd_lock = (BPTR)CurrentDir(freq1->fr_DirLock);
if ((error = make_dir(dir_name)) == VSH_STATUS_NORMAL) {
if (!(lock = quiet_lock(dir_name, (LONG)SHARED_LOCK))) {
error = VSH_ERROR_LOCK_FAILED;
} else {
if (!(plock = ParentDir(lock))) {
error = VSH_ERROR_LOCK_FAILED;
} else {
if (CompareLock(plock, freq1->fr_DirLock) == LCK_EQUAL) {
/* Place cursor over new directory */
strcpy(&old_name[0], BaseName(dir_name));
if (old_cursor_line == -1) {
old_cursor_line = 0;
}
}
UnLock(plock);
}
UnLock(lock);
}
}
CurrentDir(cd_lock);
check_date_stamp(freq1, READ_SAME_DIR_MODE_NO_CURSOR);
check_date_stamp(freq2, READ_SAME_DIR_MODE_NO_OUTPUT);
change_fkey_text();
}
restore_old_cursor_line(freq1, &old_name[0], old_pos, old_cursor_line);
print_info_line(INFO_LINE_MODE_NORMAL);
}
print_status(error);
}
/* Create new directory */
SHORT
make_dir(BYTE *dir_name)
{
BPTR dir_lock;
SHORT error = VSH_STATUS_NORMAL;
/* Entry with given name already exists ? */
if (dir_lock = quiet_lock(dir_name, (LONG)SHARED_LOCK)) {
if (Examine(dir_lock, fib) == DOSFALSE) {
error = VSH_ERROR_EXAMINE_FAILED;
} else {
/* Dir or file ? */
if (fib->fib_EntryType > 0) {
error = VSH_ERROR_OBJECT_ALREADY_EXISTS;
} else {
error = VSH_ERROR_DIRNAME_ALREADY_USED;
}
}
UnLock(dir_lock);
}
if (error == VSH_STATUS_NORMAL) {
if (!(dir_lock = (BPTR)CreateDir(dir_name))) {
error = get_dos_error(VSH_ERROR_CREATEDIR_FAILED);
} else {
UnLock(dir_lock);
}
}
return(error);
}
/* Delete selected entries */
VOID
action_delete(VOID)
{
struct FileRequest *freq1 = &file_req[active_freq],
*freq2 = &file_req[(active_freq ? 0 : 1)];
struct FileNode *fnode;
BYTE old_name[MAX_FILE_NAME_LEN + 1];
ULONG old_pos;
SHORT old_cursor_line = freq1->fr_CursorLine, error = VSH_STATUS_NORMAL;
if ((freq1->fr_Mode == FREQ_MODE_NORMAL || freq1->fr_Mode ==
FREQ_MODE_FIND) && old_cursor_line != -1) {
hcomp_freq_cursor(freq1);
print_fkey_text(FKEY_MODE_NONE);
/* Save name and pos of old cursor line node */
fnode = get_file_node_under_cursor(freq1);
strncpy(&old_name[0], &fnode->fn_Text[0], (size_t)fnode->fn_NameLen);
old_name[fnode->fn_NameLen] = '\0';
old_pos = fnode->fn_Pos;
if (get_answer(ANSWER_MODE_DELETE_START, (BYTE *)
freq1->fr_MarkedEntries, ANSWER_TYPE_YES) == ANSWER_TYPE_YES) {
last1_answer = ANSWER_TYPE_YES;
enable_abort = 1;
if (!freq1->fr_MarkedEntries) {
/* Delete entry under cursor only */
if ((error = delete_file(freq1, fnode)) != VSH_STATUS_NORMAL) {
if (error == VSH_ERROR_SKIPPED) {
error = VSH_STATUS_NORMAL;
}
} else {
remove_file_node(freq1, fnode);
}
} else {
/* Delete marked entries only */
fnode = (struct FileNode *)freq1->fr_Display.d_List->mlh_Head;
do {
if (fnode->fn_Marked) {
move_freq_cursor(freq1, fnode, MOVE_MODE_NO_CURSOR);
if ((error = delete_file(freq1, fnode)) ==
VSH_STATUS_NORMAL || error == VSH_ERROR_SKIPPED) {
/* Remove deleted entry and refresh info line */
freq1->fr_MarkedSize -= fnode->fn_Size;
freq1->fr_MarkedEntries--;
if (error == VSH_ERROR_SKIPPED) {
/* Unmark skipped entry */
fnode->fn_Marked = 0;
print_freq_lines(freq1, (struct MinNode *)fnode,
(USHORT)freq1->fr_CursorLine, (USHORT)1);
fnode = (struct FileNode *)fnode->fn_Node.mln_Succ;
error = VSH_STATUS_NORMAL;
} else {
fnode = remove_file_node(freq1, fnode);
}
print_info_line(INFO_LINE_MODE_MARKED);
}
} else {
fnode = (struct FileNode *)fnode->fn_Node.mln_Succ;
}
} while (error == VSH_STATUS_NORMAL && freq1->fr_MarkedEntries);
}
/* After disabling ESC clear any pending break signal */
enable_abort = 0;
SetSignal(0L, (LONG)SIGBREAKF_CTRL_C);
/* Change date stamp of source directory and check other one */
set_date_stamp(freq1);
refresh_dir_info(freq1);
check_date_stamp(freq2, READ_SAME_DIR_MODE_NO_OUTPUT);
}
restore_old_cursor_line(freq1, &old_name[0], old_pos, old_cursor_line);
change_fkey_text();
}
print_status(error);
}
/* Delete selected entry */
SHORT
delete_file(struct FileRequest *freq, struct FileNode *fnode)
{
struct AnchorPath *ap;
struct FileInfoBlock *info;
BPTR lock, cd_lock;
BYTE *path, *last_path, *first_path = &path1_buffer[0],
*path_buffer = &path2_buffer[0];
LONG rc, last_protection;
SHORT error = VSH_STATUS_NORMAL;
/* Build full path name */
build_path_name_from_file_node(first_path, freq, fnode);
if (!(lock = quiet_lock(first_path, (LONG)SHARED_LOCK))) {
error = VSH_ERROR_LOCK_FAILED;
} else {
if (!Examine(lock, fib)) {
error = VSH_ERROR_EXAMINE_FAILED;
} else {
/* Check if directory */
if (fib->fib_DirEntryType >= 0) {
/* Delete contents of directory */
if (!(ap = AllocMem((LONG)(sizeof(struct AnchorPath) +
MAX_PATH_NAME_LEN + 1), (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
error = VSH_ERROR_OUT_OF_MEM;
} else {
/* Init anchor path */
ap->ap_BreakBits = SIGBREAKF_CTRL_C;
ap->ap_StrLen = MAX_PATH_NAME_LEN;
ap->ap_Flags = APF_DoWild;
info = &ap->ap_Info;
path = &ap->ap_Buf[0];
last_path = NULL;
/* Find first entry in selected directory */
cd_lock = CurrentDir(lock);
if (!(rc = FindFirst(star, ap))) {
/* Traverse through ALL directories in current directory */
do {
/* Delete last entry */
if (last_path) {
error = do_delete_file(last_path, last_protection);
}
if (error == VSH_STATUS_NORMAL ||
error == VSH_ERROR_SKIPPED) {
/* Examine current entry */
if (info->fib_DirEntryType < 0) {
/* File */
last_path = path_buffer;
last_protection = info->fib_Protection;
error = build_path_name_from_relative_path(last_path, path);
} else {
/* Directory */
if (ap->ap_Flags & APF_DidDir) {
ap->ap_Flags &= ~APF_DidDir; /* don't enter dir again */
last_path = path_buffer;
last_protection = info->fib_Protection;
error = build_path_name_from_relative_path(last_path, path);
} else {
ap->ap_Flags |= APF_DoDir; /* enter dir */
last_path = NULL;
}
}
}
} while ((error == VSH_STATUS_NORMAL ||
error == VSH_ERROR_SKIPPED) && !(rc = FindNext(ap)));
}
FreeAnchorChain(ap);
CurrentDir(cd_lock);
if (error == VSH_STATUS_NORMAL) {
switch (rc) {
case ERROR_NO_MORE_ENTRIES :
/* Delete last entry */
if (last_path) {
error = do_delete_file(last_path, last_protection);
}
break;
case ERROR_BREAK :
error = VSH_ERROR_ABORTED;
break;
default :
error = VSH_ERROR_FINDFIRST_OR_FINDNEXT_FAILED;
break;
}
}
FreeMem(ap, (LONG)(sizeof(struct AnchorPath) +
MAX_PATH_NAME_LEN + 1));
}
}
/* At last delete marked entry */
if (error == VSH_STATUS_NORMAL || error == VSH_ERROR_SKIPPED) {
/* But first unlock it */
UnLock(lock);
lock = NULL;
error = do_delete_file(first_path, fib->fib_Protection);
}
}
if (lock) {
UnLock(lock);
}
}
return(error);
}
/* Call DOS function DeleteFile() */
SHORT
do_delete_file(BYTE *path, LONG protection)
{
SHORT error = VSH_STATUS_NORMAL;
if (CheckAbort(NULL)) {
error = VSH_ERROR_ABORTED;
} else {
/* Check delete protection flag */
if (protection & FIBF_DELETE) {
if (last1_answer != ANSWER_TYPE_ALL) {
switch (last1_answer = get_answer(ANSWER_MODE_DELETE_NO_DELETE,
path, last1_answer)) {
case ANSWER_TYPE_YES :
case ANSWER_TYPE_ALL :
break;
case ANSWER_TYPE_NO :
error = VSH_ERROR_SKIPPED;
break;
case ANSWER_TYPE_ESC :
error = VSH_ERROR_ABORTED;
break;
}
}
if (last1_answer == ANSWER_TYPE_YES ||
last1_answer == ANSWER_TYPE_ALL) {
/* Clear delete protection flag */
if (SetProtection(path, (LONG)(protection & ~FIBF_DELETE)) ==
DOSFALSE) {
error = VSH_ERROR_SETPROTECTION_FAILED;
}
}
}
/* If no error then delete file now */
if (error != VSH_STATUS_NORMAL) {
if (error == VSH_ERROR_SKIPPED) {
print_dos_status(DOS_MODE_SKIP, path, NULL);
}
} else {
print_dos_status(DOS_MODE_DELETE, path, NULL);
if (DeleteFile(path) == DOSFALSE) {
error = get_dos_error(VSH_ERROR_DELETEFILE_FAILED);
}
}
}
return(error);
}
/* Get AmigaDOS error using IoErr() */
SHORT
get_dos_error(SHORT error)
{
if (error != VSH_STATUS_NORMAL && error != VSH_ERROR_ABORTED) {
switch (IoErr()) {
case ERROR_FILE_NOT_OBJECT :
error = VSH_ERROR_NO_LOAD_FILE;
break;
case ERROR_OBJECT_IN_USE :
error = VSH_ERROR_OBJECT_IN_USE;
break;
case ERROR_OBJECT_EXISTS :
error = VSH_ERROR_OBJECT_ALREADY_EXISTS;
break;
case ERROR_OBJECT_NOT_FOUND :
error = VSH_ERROR_OBJECT_NOT_FOUND;
break;
case ERROR_OBJECT_WRONG_TYPE :
error = VSH_ERROR_OBJECT_WRONG_TYPE;
break;
case ERROR_DIRECTORY_NOT_EMPTY :
error = VSH_ERROR_DIRECTORY_NOT_EMPTY;
break;
case ERROR_NO_DISK :
error = VSH_ERROR_NO_DISK;
break;
case ERROR_NOT_A_DOS_DISK :
error = VSH_ERROR_NO_DOS_DISK;
break;
case ERROR_DISK_NOT_VALIDATED :
error = VSH_ERROR_DISK_NOT_VALIDATED;
break;
case ERROR_DISK_WRITE_PROTECTED :
error = VSH_ERROR_DISK_WRITE_PROTECTED;
break;
case ERROR_DISK_FULL :
error = VSH_ERROR_DISK_FULL;
break;
case ERROR_READ_PROTECTED :
error = VSH_ERROR_READ_PROTECTED;
break;
case ERROR_WRITE_PROTECTED :
error = VSH_ERROR_WRITE_PROTECTED;
break;
case ERROR_DELETE_PROTECTED :
error = VSH_ERROR_DELETE_PROTECTED;
break;
case ERROR_SEEK_ERROR :
error = VSH_ERROR_SEEK_FAILED;
break;
}
}
return(error);
}
/* Compare current dir from CLI with dir of active file req and get it if necessary */
VOID
get_current_dir(VOID)
{
struct CommandLineInterface *cli = BTOC(_parent_proc->pr_CLI);
struct FileRequest *freq = &file_req[active_freq];
BPTR dir_lock;
BYTE *path = &path1_buffer[0];
BOOL dir_changed = FALSE;
if (cli == save_cli && freq->fr_Mode == FREQ_MODE_NORMAL) {
/* Any CD pending ? */
if (delayed_cd == 1) {
change_current_dir();
}
/* CD performed ? */
if (!delayed_cd) {
/* Boot device ? */
if (!(dir_lock = _parent_proc->pr_CurrentDir)) {
if (build_path_name_from_lock(path, dir_lock) ==
VSH_STATUS_NORMAL) {
if (strcmp(path, &freq->fr_DirName[0])) {
dir_changed = TRUE;
}
}
} else {
if (CompareLock(dir_lock, freq->fr_DirLock) != LCK_EQUAL) {
Forbid();
BtoCStr(path, cli->cli_SetName, (LONG)MAX_PATH_NAME_LEN);
Permit();
if (dir_lock = quiet_lock(path, (LONG)SHARED_LOCK)) {
if (CompareLock(dir_lock, freq->fr_DirLock) != LCK_EQUAL) {
if (build_path_name_from_lock(path, dir_lock) ==
VSH_STATUS_NORMAL) {
dir_changed = TRUE;
}
}
UnLock(dir_lock);
}
}
}
}
}
if (dir_changed == TRUE) {
print_status(read_new_dir(freq, path, READ_DIR_MODE_NO_CD));
}
}
/* Compare current dir from CLI with dir of active file req and change it if necessary */
SHORT
change_current_dir(VOID)
{
struct CommandLineInterface *cli = BTOC(_parent_proc->pr_CLI);
struct FileRequest *freq = &file_req[active_freq];
BYTE *cmd_name = BTOC(cli->cli_CommandName),
*dir_name = &freq->fr_DirName[0];
BPTR old_lock, new_lock, dir_lock = freq->fr_DirLock;
SHORT error = VSH_STATUS_NORMAL;
if (cli == save_cli && *dir_name != '\0') {
/* Any command or script running in our CLI ? */
if (*cmd_name || cli->cli_StandardInput != cli->cli_CurrentInput) {
/* Change current dir when command finished */
delayed_cd = 1;
} else {
/* Change current dir now */
delayed_cd = 0;
Forbid();
old_lock = _parent_proc->pr_CurrentDir;
if (CompareLock(old_lock, dir_lock) != LCK_EQUAL) {
if (!(new_lock = DupLock(dir_lock))) {
error = VSH_ERROR_OUT_OF_MEM;
} else {
_parent_proc->pr_CurrentDir = new_lock;
CtoBStr(dir_name, cli->cli_SetName, (LONG)MAX_DIR_NAME_LEN);
if (old_lock) {
UnLock(old_lock);
}
}
}
Permit();
}
}
return(error);
}