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 >
C/C++ Source or Header  |  1992-10-28  |  14KB  |  509 lines

  1.         /*********************************
  2.          *                               *
  3.          *   Visual Shell v1.17  10/92   *
  4.          *                               *
  5.          *     by Torsten Jürgeleit      *
  6.          *                               *
  7.          *           dos part 2          *
  8.          *                               *
  9.          *********************************/
  10.  
  11.     /* Includes */
  12.  
  13. #include "includes.h"
  14. #include "imports.h"
  15. #include "protos.h"
  16.  
  17.     /* Make new directory */
  18.  
  19.    VOID
  20. action_make_dir(VOID)
  21. {
  22.    struct FileRequest  *freq1 = &file_req[active_freq],
  23.                *freq2 = &file_req[(active_freq ? 0 : 1)];
  24.    struct FileNode     *fnode;
  25.    BYTE  *dir_name;
  26.    BPTR  lock, plock, cd_lock;
  27.    BYTE  old_name[MAX_FILE_NAME_LEN + 1];
  28.    ULONG old_pos;
  29.    SHORT old_cursor_line = freq1->fr_CursorLine, error = VSH_STATUS_NORMAL;
  30.  
  31.    if (freq1->fr_Mode == FREQ_MODE_NORMAL || freq1->fr_Mode ==
  32.                                FREQ_MODE_FIND) {
  33.       hcomp_freq_cursor(freq1);
  34.       print_info_line(INFO_LINE_MODE_EMPTY);
  35.       print_fkey_text(FKEY_MODE_NONE);
  36.  
  37.       /* Save name and pos of old cursor line node */
  38.       if (old_cursor_line != -1) {
  39.      fnode = get_file_node_under_cursor(freq1);
  40.      strncpy(&old_name[0], &fnode->fn_Text[0], (size_t)
  41.                              fnode->fn_NameLen);
  42.      old_name[fnode->fn_NameLen] = '\0';
  43.      old_pos                     = fnode->fn_Pos;
  44.       }
  45.       if (dir_name = get_input(INPUT_MODE_MAKE_DIR, NULL)) {
  46.  
  47.      /* Create new directory and check if it goes to current directory */
  48.      print_status(VSH_STATUS_MAKE_DIR);
  49.      cd_lock = (BPTR)CurrentDir(freq1->fr_DirLock);
  50.      if ((error = make_dir(dir_name)) == VSH_STATUS_NORMAL) {
  51.         if (!(lock = quiet_lock(dir_name, (LONG)SHARED_LOCK))) {
  52.            error = VSH_ERROR_LOCK_FAILED;
  53.         } else {
  54.            if (!(plock = ParentDir(lock))) {
  55.           error = VSH_ERROR_LOCK_FAILED;
  56.            } else {
  57.           if (CompareLock(plock, freq1->fr_DirLock) == LCK_EQUAL) {
  58.  
  59.              /* Place cursor over new directory */
  60.              strcpy(&old_name[0], BaseName(dir_name));
  61.              if (old_cursor_line == -1) {
  62.             old_cursor_line = 0;
  63.              }
  64.           }
  65.           UnLock(plock);
  66.            }
  67.            UnLock(lock);
  68.         }
  69.      }
  70.      CurrentDir(cd_lock);
  71.      check_date_stamp(freq1, READ_SAME_DIR_MODE_NO_CURSOR);
  72.      check_date_stamp(freq2, READ_SAME_DIR_MODE_NO_OUTPUT);
  73.      change_fkey_text();
  74.       }
  75.       restore_old_cursor_line(freq1, &old_name[0], old_pos, old_cursor_line);
  76.       print_info_line(INFO_LINE_MODE_NORMAL);
  77.    }
  78.    print_status(error);
  79. }
  80.     /* Create new directory */
  81.  
  82.    SHORT
  83. make_dir(BYTE *dir_name)
  84. {
  85.    BPTR  dir_lock;
  86.    SHORT error = VSH_STATUS_NORMAL;
  87.  
  88.    /* Entry with given name already exists ? */
  89.    if (dir_lock = quiet_lock(dir_name, (LONG)SHARED_LOCK)) {
  90.       if (Examine(dir_lock, fib) == DOSFALSE) {
  91.      error = VSH_ERROR_EXAMINE_FAILED;
  92.       } else {
  93.  
  94.      /* Dir or file ? */
  95.      if (fib->fib_EntryType > 0) {
  96.         error = VSH_ERROR_OBJECT_ALREADY_EXISTS;
  97.      } else {
  98.         error = VSH_ERROR_DIRNAME_ALREADY_USED;
  99.      }
  100.       }
  101.       UnLock(dir_lock);
  102.    }
  103.    if (error == VSH_STATUS_NORMAL) {
  104.       if (!(dir_lock = (BPTR)CreateDir(dir_name))) {
  105.      error = get_dos_error(VSH_ERROR_CREATEDIR_FAILED);
  106.       } else {
  107.      UnLock(dir_lock);
  108.       }
  109.    }
  110.    return(error);
  111. }
  112.     /* Delete selected entries */
  113.  
  114.    VOID
  115. action_delete(VOID)
  116. {
  117.    struct FileRequest  *freq1 = &file_req[active_freq],
  118.                *freq2 = &file_req[(active_freq ? 0 : 1)];
  119.    struct FileNode     *fnode;
  120.    BYTE  old_name[MAX_FILE_NAME_LEN + 1];
  121.    ULONG old_pos;
  122.    SHORT old_cursor_line = freq1->fr_CursorLine, error = VSH_STATUS_NORMAL;
  123.  
  124.    if ((freq1->fr_Mode == FREQ_MODE_NORMAL || freq1->fr_Mode ==
  125.                  FREQ_MODE_FIND) && old_cursor_line != -1) {
  126.       hcomp_freq_cursor(freq1);
  127.       print_fkey_text(FKEY_MODE_NONE);
  128.  
  129.       /* Save name and pos of old cursor line node */
  130.       fnode = get_file_node_under_cursor(freq1);
  131.       strncpy(&old_name[0], &fnode->fn_Text[0], (size_t)fnode->fn_NameLen);
  132.       old_name[fnode->fn_NameLen] = '\0';
  133.       old_pos                     = fnode->fn_Pos;
  134.       if (get_answer(ANSWER_MODE_DELETE_START, (BYTE *)
  135.          freq1->fr_MarkedEntries, ANSWER_TYPE_YES) == ANSWER_TYPE_YES) {
  136.  
  137.      last1_answer = ANSWER_TYPE_YES;
  138.      enable_abort = 1;
  139.      if (!freq1->fr_MarkedEntries) {
  140.  
  141.         /* Delete entry under cursor only */
  142.         if ((error = delete_file(freq1, fnode)) != VSH_STATUS_NORMAL) {
  143.            if (error == VSH_ERROR_SKIPPED) {
  144.           error = VSH_STATUS_NORMAL;
  145.            }
  146.         } else {
  147.            remove_file_node(freq1, fnode);
  148.         }
  149.      } else {
  150.  
  151.         /* Delete marked entries only */
  152.         fnode = (struct FileNode *)freq1->fr_Display.d_List->mlh_Head;
  153.         do {
  154.            if (fnode->fn_Marked) {
  155.           move_freq_cursor(freq1, fnode, MOVE_MODE_NO_CURSOR);
  156.           if ((error = delete_file(freq1, fnode)) ==
  157.               VSH_STATUS_NORMAL || error == VSH_ERROR_SKIPPED) {
  158.  
  159.              /* Remove deleted entry and refresh info line */
  160.              freq1->fr_MarkedSize -= fnode->fn_Size;
  161.              freq1->fr_MarkedEntries--;
  162.              if (error == VSH_ERROR_SKIPPED) {
  163.  
  164.             /* Unmark skipped entry */
  165.             fnode->fn_Marked = 0;
  166.             print_freq_lines(freq1, (struct MinNode *)fnode,
  167.                    (USHORT)freq1->fr_CursorLine, (USHORT)1);
  168.             fnode = (struct FileNode *)fnode->fn_Node.mln_Succ;
  169.             error = VSH_STATUS_NORMAL;
  170.              } else {
  171.             fnode = remove_file_node(freq1, fnode);
  172.              }
  173.              print_info_line(INFO_LINE_MODE_MARKED);
  174.           }
  175.            } else {
  176.           fnode = (struct FileNode *)fnode->fn_Node.mln_Succ;
  177.            }
  178.         } while (error == VSH_STATUS_NORMAL && freq1->fr_MarkedEntries);
  179.      }
  180.  
  181.      /* After disabling ESC clear any pending break signal */
  182.      enable_abort = 0;
  183.      SetSignal(0L, (LONG)SIGBREAKF_CTRL_C);
  184.  
  185.      /* Change date stamp of source directory and check other one */
  186.      set_date_stamp(freq1);
  187.      refresh_dir_info(freq1);
  188.      check_date_stamp(freq2, READ_SAME_DIR_MODE_NO_OUTPUT);
  189.       }
  190.       restore_old_cursor_line(freq1, &old_name[0], old_pos, old_cursor_line);
  191.       change_fkey_text();
  192.    }
  193.    print_status(error);
  194. }
  195.     /* Delete selected entry */
  196.  
  197.    SHORT
  198. delete_file(struct FileRequest  *freq, struct FileNode  *fnode)
  199. {
  200.    struct AnchorPath     *ap;
  201.    struct FileInfoBlock  *info;
  202.    BPTR  lock, cd_lock;
  203.    BYTE  *path, *last_path, *first_path = &path1_buffer[0],
  204.      *path_buffer = &path2_buffer[0];
  205.    LONG  rc, last_protection;
  206.    SHORT error = VSH_STATUS_NORMAL;
  207.  
  208.    /* Build full path name */
  209.    build_path_name_from_file_node(first_path, freq, fnode);
  210.    if (!(lock = quiet_lock(first_path, (LONG)SHARED_LOCK))) {
  211.       error = VSH_ERROR_LOCK_FAILED;
  212.    } else {
  213.       if (!Examine(lock, fib)) {
  214.      error = VSH_ERROR_EXAMINE_FAILED;
  215.       } else {
  216.  
  217.      /* Check if directory */
  218.      if (fib->fib_DirEntryType >= 0) {
  219.  
  220.         /* Delete contents of directory */
  221.         if (!(ap = AllocMem((LONG)(sizeof(struct AnchorPath) +
  222.          MAX_PATH_NAME_LEN + 1), (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
  223.            error = VSH_ERROR_OUT_OF_MEM;
  224.         } else {
  225.  
  226.            /* Init anchor path */
  227.            ap->ap_BreakBits = SIGBREAKF_CTRL_C;
  228.            ap->ap_StrLen    = MAX_PATH_NAME_LEN;
  229.            ap->ap_Flags     = APF_DoWild;
  230.            info             = &ap->ap_Info;
  231.            path             = &ap->ap_Buf[0];
  232.            last_path        = NULL;
  233.  
  234.            /* Find first entry in selected directory */
  235.            cd_lock = CurrentDir(lock);
  236.            if (!(rc = FindFirst(star, ap))) {
  237.  
  238.           /* Traverse through ALL directories in current directory */
  239.           do {
  240.  
  241.              /* Delete last entry */
  242.              if (last_path) {
  243.             error = do_delete_file(last_path, last_protection);
  244.              }
  245.              if (error == VSH_STATUS_NORMAL ||
  246.                            error == VSH_ERROR_SKIPPED) {
  247.             /* Examine current entry */
  248.             if (info->fib_DirEntryType < 0) {
  249.  
  250.                /* File */
  251.                last_path       = path_buffer;
  252.                last_protection = info->fib_Protection;
  253.                error           = build_path_name_from_relative_path(last_path, path);
  254.             } else {
  255.  
  256.                /* Directory */
  257.                if (ap->ap_Flags & APF_DidDir) {
  258.                   ap->ap_Flags   &= ~APF_DidDir;   /* don't enter dir again */
  259.                   last_path       = path_buffer;
  260.                   last_protection = info->fib_Protection;
  261.                   error           = build_path_name_from_relative_path(last_path, path);
  262.                } else {
  263.                   ap->ap_Flags |= APF_DoDir;   /* enter dir */
  264.                   last_path     = NULL;
  265.                }
  266.             }
  267.              }
  268.           } while ((error == VSH_STATUS_NORMAL ||
  269.                error == VSH_ERROR_SKIPPED) && !(rc = FindNext(ap)));
  270.            }
  271.            FreeAnchorChain(ap);
  272.            CurrentDir(cd_lock);
  273.            if (error == VSH_STATUS_NORMAL) {
  274.           switch (rc) {
  275.              case ERROR_NO_MORE_ENTRIES :
  276.  
  277.             /* Delete last entry */
  278.             if (last_path) {
  279.                error = do_delete_file(last_path, last_protection);
  280.             }
  281.             break;
  282.              case ERROR_BREAK :
  283.             error = VSH_ERROR_ABORTED;
  284.             break;
  285.              default :
  286.             error = VSH_ERROR_FINDFIRST_OR_FINDNEXT_FAILED;
  287.             break;
  288.           }
  289.            }
  290.            FreeMem(ap, (LONG)(sizeof(struct AnchorPath) +
  291.                             MAX_PATH_NAME_LEN + 1));
  292.         }
  293.      }
  294.  
  295.      /* At last delete marked entry */
  296.      if (error == VSH_STATUS_NORMAL || error == VSH_ERROR_SKIPPED) {
  297.  
  298.         /* But first unlock it */
  299.         UnLock(lock);
  300.         lock  = NULL;
  301.         error = do_delete_file(first_path, fib->fib_Protection);
  302.      }
  303.       }
  304.       if (lock) {
  305.      UnLock(lock);
  306.       }
  307.    }
  308.    return(error);
  309. }
  310.     /* Call DOS function DeleteFile() */
  311.  
  312.    SHORT
  313. do_delete_file(BYTE *path, LONG protection)
  314. {
  315.    SHORT error = VSH_STATUS_NORMAL;
  316.  
  317.    if (CheckAbort(NULL)) {
  318.       error = VSH_ERROR_ABORTED;
  319.    } else {
  320.  
  321.       /* Check delete protection flag */
  322.       if (protection & FIBF_DELETE) {
  323.      if (last1_answer != ANSWER_TYPE_ALL) {
  324.         switch (last1_answer = get_answer(ANSWER_MODE_DELETE_NO_DELETE,
  325.                               path, last1_answer)) {
  326.            case ANSWER_TYPE_YES :
  327.            case ANSWER_TYPE_ALL :
  328.           break;
  329.            case ANSWER_TYPE_NO :
  330.           error = VSH_ERROR_SKIPPED;
  331.           break;
  332.            case ANSWER_TYPE_ESC :
  333.           error = VSH_ERROR_ABORTED;
  334.           break;
  335.         }
  336.      }
  337.      if (last1_answer == ANSWER_TYPE_YES ||
  338.                       last1_answer == ANSWER_TYPE_ALL) {
  339.         /* Clear delete protection flag */
  340.         if (SetProtection(path, (LONG)(protection & ~FIBF_DELETE)) ==
  341.                                  DOSFALSE) {
  342.            error = VSH_ERROR_SETPROTECTION_FAILED;
  343.         }
  344.      }
  345.       }
  346.  
  347.       /* If no error then delete file now */
  348.       if (error != VSH_STATUS_NORMAL) {
  349.      if (error == VSH_ERROR_SKIPPED) {
  350.         print_dos_status(DOS_MODE_SKIP, path, NULL);
  351.      }
  352.       } else {
  353.      print_dos_status(DOS_MODE_DELETE, path, NULL);
  354.      if (DeleteFile(path) == DOSFALSE) {
  355.         error = get_dos_error(VSH_ERROR_DELETEFILE_FAILED);
  356.      }
  357.       }
  358.    }
  359.    return(error);
  360. }
  361.     /* Get AmigaDOS error using IoErr() */
  362.  
  363.    SHORT
  364. get_dos_error(SHORT error)
  365. {
  366.    if (error != VSH_STATUS_NORMAL && error != VSH_ERROR_ABORTED) {
  367.       switch (IoErr()) {
  368.      case ERROR_FILE_NOT_OBJECT :
  369.         error = VSH_ERROR_NO_LOAD_FILE;
  370.         break;
  371.      case ERROR_OBJECT_IN_USE :
  372.         error = VSH_ERROR_OBJECT_IN_USE;
  373.         break;
  374.      case ERROR_OBJECT_EXISTS :
  375.         error = VSH_ERROR_OBJECT_ALREADY_EXISTS;
  376.         break;
  377.      case ERROR_OBJECT_NOT_FOUND :
  378.         error = VSH_ERROR_OBJECT_NOT_FOUND;
  379.         break;
  380.      case ERROR_OBJECT_WRONG_TYPE :
  381.         error = VSH_ERROR_OBJECT_WRONG_TYPE;
  382.         break;
  383.      case ERROR_DIRECTORY_NOT_EMPTY :
  384.         error = VSH_ERROR_DIRECTORY_NOT_EMPTY;
  385.         break;
  386.      case ERROR_NO_DISK :
  387.         error = VSH_ERROR_NO_DISK;
  388.         break;
  389.      case ERROR_NOT_A_DOS_DISK :
  390.         error = VSH_ERROR_NO_DOS_DISK;
  391.         break;
  392.      case ERROR_DISK_NOT_VALIDATED :
  393.         error = VSH_ERROR_DISK_NOT_VALIDATED;
  394.         break;
  395.      case ERROR_DISK_WRITE_PROTECTED :
  396.         error = VSH_ERROR_DISK_WRITE_PROTECTED;
  397.         break;
  398.      case ERROR_DISK_FULL :
  399.         error = VSH_ERROR_DISK_FULL;
  400.         break;
  401.      case ERROR_READ_PROTECTED :
  402.         error = VSH_ERROR_READ_PROTECTED;
  403.         break;
  404.      case ERROR_WRITE_PROTECTED :
  405.         error = VSH_ERROR_WRITE_PROTECTED;
  406.         break;
  407.      case ERROR_DELETE_PROTECTED :
  408.         error = VSH_ERROR_DELETE_PROTECTED;
  409.         break;
  410.      case ERROR_SEEK_ERROR :
  411.         error = VSH_ERROR_SEEK_FAILED;
  412.         break;
  413.       }
  414.    }
  415.    return(error);
  416. }
  417.     /* Compare current dir from CLI with dir of active file req and get it if necessary */
  418.  
  419.    VOID
  420. get_current_dir(VOID)
  421. {
  422.    struct CommandLineInterface  *cli  = BTOC(_parent_proc->pr_CLI);
  423.    struct FileRequest           *freq = &file_req[active_freq];
  424.    BPTR dir_lock;
  425.    BYTE *path = &path1_buffer[0];
  426.    BOOL dir_changed = FALSE;
  427.  
  428.    if (cli == save_cli && freq->fr_Mode == FREQ_MODE_NORMAL) {
  429.  
  430.       /* Any CD pending ? */
  431.       if (delayed_cd == 1) {
  432.      change_current_dir();
  433.       }
  434.  
  435.       /* CD performed ? */
  436.       if (!delayed_cd) {
  437.  
  438.      /* Boot device ? */
  439.      if (!(dir_lock = _parent_proc->pr_CurrentDir)) {
  440.         if (build_path_name_from_lock(path, dir_lock) ==
  441.                             VSH_STATUS_NORMAL) {
  442.            if (strcmp(path, &freq->fr_DirName[0])) {
  443.           dir_changed = TRUE;
  444.            }
  445.         }
  446.      } else {
  447.         if (CompareLock(dir_lock, freq->fr_DirLock) != LCK_EQUAL) {
  448.            Forbid();
  449.            BtoCStr(path, cli->cli_SetName, (LONG)MAX_PATH_NAME_LEN);
  450.            Permit();
  451.            if (dir_lock = quiet_lock(path, (LONG)SHARED_LOCK)) {
  452.           if (CompareLock(dir_lock, freq->fr_DirLock) != LCK_EQUAL) {
  453.              if (build_path_name_from_lock(path, dir_lock) ==
  454.                             VSH_STATUS_NORMAL) {
  455.             dir_changed = TRUE;
  456.              }
  457.           }
  458.           UnLock(dir_lock);
  459.            }
  460.         }
  461.      }
  462.       }
  463.    }
  464.    if (dir_changed == TRUE) {
  465.       print_status(read_new_dir(freq, path, READ_DIR_MODE_NO_CD));
  466.    }
  467. }
  468.     /* Compare current dir from CLI with dir of active file req and change it if necessary */
  469.  
  470.    SHORT
  471. change_current_dir(VOID)
  472. {
  473.    struct CommandLineInterface *cli  = BTOC(_parent_proc->pr_CLI);
  474.    struct FileRequest          *freq = &file_req[active_freq];
  475.    BYTE  *cmd_name = BTOC(cli->cli_CommandName),
  476.      *dir_name = &freq->fr_DirName[0];
  477.    BPTR  old_lock, new_lock, dir_lock = freq->fr_DirLock;
  478.    SHORT error = VSH_STATUS_NORMAL;
  479.  
  480.    if (cli == save_cli && *dir_name != '\0') {
  481.  
  482.       /* Any command or script running in our CLI ? */
  483.       if (*cmd_name || cli->cli_StandardInput != cli->cli_CurrentInput) {
  484.  
  485.      /* Change current dir when command finished */
  486.      delayed_cd = 1;
  487.       } else {
  488.  
  489.      /* Change current dir now */
  490.      delayed_cd = 0;
  491.      Forbid();
  492.      old_lock = _parent_proc->pr_CurrentDir;
  493.      if (CompareLock(old_lock, dir_lock) != LCK_EQUAL) {
  494.         if (!(new_lock = DupLock(dir_lock))) {
  495.            error = VSH_ERROR_OUT_OF_MEM;
  496.         } else {
  497.            _parent_proc->pr_CurrentDir = new_lock;
  498.            CtoBStr(dir_name, cli->cli_SetName, (LONG)MAX_DIR_NAME_LEN);
  499.            if (old_lock) {
  500.           UnLock(old_lock);
  501.            }
  502.         }
  503.      }
  504.      Permit();
  505.       }
  506.    }
  507.    return(error);
  508. }
  509.