=== modified file 'uspace/app/bdsh/cmds/modules/cp/cp.c'
--- uspace/app/bdsh/cmds/modules/cp/cp.c	2011-10-29 17:02:30 +0000
+++ uspace/app/bdsh/cmds/modules/cp/cp.c	2012-04-05 22:29:56 +0000
@@ -29,6 +29,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <io/console.h>
+#include <io/keycode.h>
 #include <getopt.h>
 #include <str.h>
 #include <fcntl.h>
@@ -45,10 +47,12 @@
 #define CP_DEFAULT_BUFLEN  1024
 
 static const char *cmdname = "cp";
+static console_ctrl_t *con;
 
 static struct option const long_options[] = {
 	{ "buffer", required_argument, 0, 'b' },
 	{ "force", no_argument, 0, 'f' },
+	{ "interactive", no_argument, 0, 'i'},
 	{ "recursive", no_argument, 0, 'r' },
 	{ "help", no_argument, 0, 'h' },
 	{ "version", no_argument, 0, 'v' },
@@ -138,10 +142,43 @@
 	str_append(path1, path1_size, path2);
 }
 
+static bool get_user_decision(bool bdefault, const char *message, ...)
+{
+	va_list args;
+	kbd_event_t ev;
+
+	va_start(args, message);
+	vprintf(message, args);
+	va_end(args);
+
+	while(true) {
+		console_flush(con);
+		console_get_kbd_event(con, &ev);
+		if ((ev.type != KEY_PRESS)
+		    || (ev.mods & (KM_CTRL | KM_ALT)) != 0) {
+			continue;
+		}
+
+		switch(ev.key) {
+		case KC_Y:
+			printf("y\n");
+			return true;
+		case KC_N:
+			printf("n\n");
+			return false;
+		case KC_ENTER:
+			printf("n\n");
+			return bdefault;
+		default:
+			break;
+		}
+	}
+}
+
 static int64_t do_copy(const char *src, const char *dest,
-    size_t blen, int vb, int recursive, int force)
+    size_t blen, int vb, int recursive, int force, int interactive)
 {
-	int r = -1;
+	int r = 0;
 	char dest_path[PATH_MAX];
 	char src_path[PATH_MAX];
 	DIR *dir = NULL;
@@ -191,17 +228,32 @@
 		} else if (dest_type == TYPE_FILE) {
 			/* e.g. cp file_name existing_file */
 
-			/* dest already exists, if force is set we will
-			 * try to remove it.
+			/* dest already exists, 
+			 * if force is set we will try to remove it.
+			 * if interactive is set user input is required.
 			 */
-			if (force) {
+			if (force && !interactive) {
 				if (unlink(dest_path)) {
 					printf("Unable to remove %s\n",
 					    dest_path);
+					r = -1;
+					goto exit;
+				}
+			} else if (!force && interactive) {
+				if(get_user_decision(false, "File already exists: %s. Overwrite? [y/N]: ",
+				    dest_path)) {
+					printf("Overwriting file: %s\n", dest_path);
+					if (unlink(dest_path)) {
+						printf("Unable to remove %s\n", dest_path);
+						r = -1;
+						goto exit;
+					}
+				} else {
+					printf("Not overwriting file: %s\n", dest_path);
 					goto exit;
 				}
 			} else {
-				printf("file already exists: %s\n", dest_path);
+				printf("File already exists: %s\n", dest_path);
 				goto exit;
 			}
 		}
@@ -215,9 +267,11 @@
 		if (!recursive) {
 			printf("Cannot copy the %s directory without the "
 			    "-r option\n", src);
+			r = -1;
 			goto exit;
 		} else if (dest_type == TYPE_FILE) {
 			printf("Cannot overwrite a file with a directory\n");
+			r = -1;
 			goto exit;
 		}
 
@@ -243,6 +297,7 @@
 				if (mkdir(dest_path, 0) == -1) {
 					printf("Unable to create "
 					    "dest directory %s\n", dest_path);
+					r = -1;
 					goto exit;
 				}
 			}
@@ -257,6 +312,7 @@
 			if (mkdir(dest_path, 0)) {
 				printf("Unable to create "
 				    "dest directory %s\n", dest_path);
+				r = -1;
 				goto exit;
 			}
 			break;
@@ -266,6 +322,7 @@
 		if (!dir) {
 			/* Something strange is happening... */
 			printf("Unable to open src %s directory\n", src);
+			r = -1;
 			goto exit;
 		}
 
@@ -293,6 +350,7 @@
 			    dest_s.fs_handle == src_s.fs_handle) {
 				printf("Cannot copy a directory "
 				    "into itself\n");
+				r = -1;
 				goto exit;
 			}
 
@@ -301,7 +359,7 @@
 
 			/* Recursively call do_copy() */
 			r = do_copy(src_dent, dest_dent, blen, vb, recursive,
-			    force);
+			    force, interactive);
 			if (r)
 				goto exit;
 
@@ -315,7 +373,6 @@
 	return r;
 }
 
-
 static int64_t copy_file(const char *src, const char *dest,
 	size_t blen, int vb)
 {
@@ -379,7 +436,8 @@
 	    "  -h, --help       A short option summary\n"
 	    "  -v, --version    Print version information and exit\n"
 	    "  -V, --verbose    Be annoyingly noisy about what's being done\n"
-	    "  -f, --force      Do not complain when <dest> exists\n"
+	    "  -f, --force      Do not complain when <dest> exists (overrides a previous -i)\n"
+	    "  -i, --interactive Ask what to do when <dest> exists (overrides a previous -f)\n"
 	    "  -r, --recursive  Copy entire directories\n"
 	    "  -b, --buffer ## Set the read buffer size to ##\n";
 	if (level == HELP_SHORT) {
@@ -396,14 +454,15 @@
 {
 	unsigned int argc, verbose = 0;
 	int buffer = 0, recursive = 0;
-	int force = 0;
+	int force = 0, interactive = 0;
 	int c, opt_ind;
 	int64_t ret;
 
+	con = console_init(stdin, stdout);
 	argc = cli_count_args(argv);
 
 	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
-		c = getopt_long(argc, argv, "hvVfrb:", long_options, &opt_ind);
+		c = getopt_long(argc, argv, "hvVfirb:", long_options, &opt_ind);
 		switch (c) { 
 		case 'h':
 			help_cmd_cp(1);
@@ -415,8 +474,13 @@
 			verbose = 1;
 			break;
 		case 'f':
+			interactive = 0;
 			force = 1;
 			break;
+		case 'i':
+			force = 0;
+			interactive = 1;
+			break;
 		case 'r':
 			recursive = 1;
 			break;
@@ -425,6 +489,7 @@
 				printf("%s: Invalid buffer specification, "
 				    "(should be a number greater than zero)\n",
 				    cmdname);
+				console_done(con);
 				return CMD_FAILURE;
 			}
 			if (verbose)
@@ -441,11 +506,14 @@
 	if (argc != 2) {
 		printf("%s: invalid number of arguments. Try %s --help\n",
 		    cmdname, cmdname);
+		console_done(con);
 		return CMD_FAILURE;
 	}
 
 	ret = do_copy(argv[optind], argv[optind + 1], buffer, verbose,
-	    recursive, force);
+	    recursive, force, interactive);
+
+	console_done(con);
 
 	if (ret == 0)
 		return CMD_SUCCESS;

