/* rm - removes everything you got
** Written by Peter Wu @ Faculty Support Center, MACC
** University of Wisconsin - Madison. August 1986.
*/
#include "dta.h"
#include <conio.h>
#include <ctype.h>
#include "date.h"

char getkey();

main(argc, argv)
int argc;
char *argv[];
{
  int brgc, optc, i, status, mask;
  char *brgv[40], opt[26], *t, path[200], c;

  optc = 0;
  brgc = 0;  /* my argc */

  for (i=0; i < 26; i++) {  /* clear options flags */
    opt[i] = 0;
  };

  for (i=1; i < argc; i++) {  /* separate options and arguments */
    if ((*argv[i] == '/') || (*argv[i] == '-')) {
      t = argv[i] + 1;
      while ((c = *t++) != '\0') {
	if (isalpha(c)) {
	  opt[tolower(c) - 'a'] = 1;
	};
      };
    } else {
      brgv[brgc++] = argv[i];
    };
  };

  if (brgc == 0) {
    putn("Usage: RM <filespec>\15\n",
	 "<filespec> can have wild cards and attributes /f /d /h; E.g:\15\n",
	 "  *.* or *.*/f  selects all visible file\15\n",
	 "  *.*/h or *.*/hf  selects all visible and invisible files\15\n",
	 "  *.*/d  selects all sub-directories\15\n\n",
	 "For each file/sub-directory found, you will be prompted for\15\n",
	 "one of the following actions:\15\n",
	 "   y - yes, delete this file\15\n",
	 "   Y - Yes, delete this sub-directory\15\n",
	 "   n - no, leave this file/sub-directory alone\15\n",
	 "   l - list all the rest of the files/sub-directories\15\n",
	 "   Z - delete ALL the rest of the files/sub-directories\15\n",
	 "   e - enter this sub-directory\15\n",
	 "   x - exit current sub-directory\15\n",
	 "   q - quit now\15\n\n",
	 "Version 2.00 made ", date, ".\15\n",
	 "Please report problems to Peter Wu.\15\n",
	 0);
    exit(0);
  }

  /* process parameters */
  for (i=0; i < brgc; i++) {
    strcpy(path, brgv[i]);
    mask = extype(path);
    mask |= normal(path);
    if ((mask & (A_FIL | A_DIR)) == 0) {
      mask |= A_FIL;  /* default is remove files only */
    }
    rm(1, 1, mask, path);
  }
}

rm(confirm, echo, mask, path)  /* use normalized path only */
int confirm, mask;
char *path;
{
  char headp[200], fullp[200], c;
  int status;
  union dtbuf mydta;

  strcpy(headp,path);
  chopath(headp);  /* cut off the tail (might be wild-cards) */

  status = ffmf(path, mask, &mydta);
  if (status) {  /* not found; probably empty directory */
    return 1;  /* let the caller print out the error message */
  }

  do {	/* for all matching files */

    strcpy(fullp, headp);
    catpath(fullp, mydta.dos.fn);  /* now fullp has the expanded name */

    do {

      if (confirm | echo) {  /* echo files to be deleted */
	cputs(fullp);
	if (mydta.dos.attr & A_DIR) {
	  cputs(" <DIR>");
	}
	if (mydta.dos.attr & (A_HID | A_SYS)) {
	  cputs(" (hidden)");
	}
      }

      if (confirm) {  /* ask for confirmation */

	status = 0;
	if (mydta.dos.attr & A_DIR) {  /* sub-dir */
	  cputs(" (Y/n/e/x/l/Z/q; ? for help): ");
	  c = getkey("YynlxqeZ?");
	} else {  /* file */
	  cputs(" (y/n/x/l/Z/q; ? for help): ");
	  c = getkey("YynlxqZx?");
	}

	switch (c) {

	  case '?':
	    putn("\15\n",
		 "Y - Yes, delete this sub-directory and its content\15\n",
		 "y - yes, delete this file\15\n",
		 "n - no, skip this file/sub-directory\15\n",
		 "e - enter this sub-directory\15\n",
		 "x - exit current sub-directory\15\n",
		 "l - list all the rest of the files/sub-directories\15\n",
		 "Z - delete ALL the rest without further prompts\15\n",
		 "q - quit to DOS now\15\n",
		 0);
		 cputs("\n");
	    break;

	  case 'Z':
	    putn("\15\n",
	       "Really delete ALL the remaning files/sub-directories (Y/N)? ",
	       0);
	    c = getkey("YNn");
	    if (c == 'Y') {
	      confirm = 0;  /* no more confirmation request */
	      status = 1;  /* exit loop */
	    }
	    cputs("\15\n");
	    break;

	  case 'q':
	    cputs("\15\nquiting to DOS\15\n");
	    exit(0);

	  case 'x':
	    cputs("\15\n");
	    return 2;  /* exit current directory */

	  case 'y':
	    if (mydta.dos.attr & A_DIR) { /* can't delete sub-dir with 'y' */
	      cputs(" use Y to delete sub-directory\15\n");
	    } else {  /* delete this file */
	      putch(' ');  /* move the cursor */
	      status = 1;  /* delete */
	    }
	    break;

	  case 'Y':
	    if (mydta.dos.attr & A_DIR) {
	      putch(' ');  /* move the cursor */
	      status = 1;  /* delete */
	    } else {  /* can't delete file with 'Y' */
	      cputs(" use y to delete file\15\n");
	    }
	    break;

	  case 'n':
	    status = 2;
	    break;

	  case 'l':
	    cputs("\15\n");
	    ls(mydta);
	    break;

	  case 'e':
	    cputs(" entering sub-directory\15\n\n");
	    catpath(fullp,"*.*");
	    if (rm(1,1,A_MASK,fullp) == 1) {  /* empty */
	      cputs("This sub-directory is empty. ");
	    }
	    chopath(fullp);
	    cputs("Returning to previous directory.\15\n\n");
	    break;

	  default:  /* what did I miss? */
	    cputs("invalid key\15\n");
	}

      } else {	/* confirm == 0 */
	status = 1;
      }

    } while (!status);

    /* status == 1 delete; status == 2 don't delete */

    if (status == 1) {	/* delete */
      if (mydta.dos.attr & A_DIR) {  /* delete sub-directory */
	/* check if fullp is parent of current path */

	/* call rm recursively to remove stuff */
	catpath(fullp,"*.*");
	rm(0,0,A_MASK,fullp);  /* no confirmation for this */
	chopath(fullp);  /* cut off the "*.*" */
	status = rmdir(fullp);
	if (echo || confirm) {
	  if (status) {
	    cputs(" can't delete\15\n");
	  } else {
	    cputs(" Deleted\15\n");
	  }
	}

      } else {	/* delete files */

	status = unlink(fullp);
	if (echo || confirm) {
	  if (status) {
	    cputs(" can't delete\15\n");
	  } else {
	    cputs(" deleted\15\n");
	  }
	}
      }

    } else {
      cputs(" not deleted\15\n");
    }

    status = fnmf(&mydta);
  } while (status == 0);

  return 0;
}

ls(cdta)  /* list the rest of the files */
union dtbuf cdta;
{
  int i, status, col, slen;  /* column */

  col = 0;
  do {	/* list the current one also */
    col++;
    slen = strlen(cdta.dos.fn);
    cputs(cdta.dos.fn);
    if (cdta.dos.attr & A_DIR) {
      putch('\\');
      slen++;
    };

    if (col < 5) {
      for (i=slen; i < 16; i++) {
	putch(' ');
      }
    } else {
      cputs("\15\n");
      col = 0;
    }
    status = fnmf(&cdta);
  } while (!status);

  if (col) {  /* complete last line */
    cputs("\15\n");
  }
}

char getkey(valid)  /* wait for valid key and echo it */
char *valid;
{
  char c;
  int i;

  do {
    c = getch();
    i = index(valid,c);
    if (i > -1) {
      putch(c);  /* echo valid key */
      return c;
    } else {  /* beep at invalid key */
      putch(7);
    }
  } while (1);
}
