Index: uspace/app/bdsh/cmds/modules/ls/ls.c
===================================================================
--- uspace/app/bdsh/cmds/modules/ls/ls.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/app/bdsh/cmds/modules/ls/ls.c	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -183,5 +183,5 @@
 		getcwd(buff, PATH_MAX);
 	else
-		str_ncpy(buff, argv[1], PATH_MAX);
+		str_cpy(buff, PATH_MAX, argv[1]);
 
 	scope = ls_scope(buff);
Index: uspace/app/tetris/scores.c
===================================================================
--- uspace/app/tetris/scores.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/app/tetris/scores.c	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -118,5 +118,6 @@
 static void copyhiscore(int dest, int src)
 {
-	strcpy(scores[dest].hs_name, scores[src].hs_name);
+	str_cpy(scores[dest].hs_name, STR_BOUNDS(MAXLOGNAME) + 1,
+	    scores[src].hs_name);
 	scores[dest].hs_score = scores[src].hs_score; 	
 	scores[dest].hs_level = scores[src].hs_level; 
@@ -132,5 +133,6 @@
 	moveto(10 , 10);
 	puts("Insert your name: ");
-	str_ncpy(scores[NUMSPOTS - 1].hs_name, "Player", MAXLOGNAME);
+	str_cpy(scores[NUMSPOTS - 1].hs_name, STR_BOUNDS(MAXLOGNAME) + 1,
+	    "Player");
 	i = 6; off = 6;
 
@@ -196,5 +198,5 @@
 	int i;
 	for(i = 0; i < NUMSPOTS; i++) {
-		str_ncpy(scores[i].hs_name, "HelenOS Team", MAXLOGNAME);
+		str_cpy(scores[i].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, "HelenOS Team");
 		scores[i].hs_score = (NUMSPOTS - i) * 200;	
 		scores[i].hs_level = (i + 1 > MAXLEVEL?MAXLEVEL:i + 1);
Index: uspace/app/tetris/tetris.c
===================================================================
--- uspace/app/tetris/tetris.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/app/tetris/tetris.c	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -312,5 +312,5 @@
 		}
 		if (keys[i] == ' ')
-			str_ncpy(key_write[i], "<space>", sizeof key_write[i]);
+			str_cpy(key_write[i], sizeof key_write[i], "<space>");
 		else {
 			key_write[i][0] = keys[i];
Index: uspace/lib/libc/generic/loader.c
===================================================================
--- uspace/lib/libc/generic/loader.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/lib/libc/generic/loader.c	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -181,5 +181,5 @@
 
 	while (*ap != NULL) {
-		str_ncpy(dp, *ap, buffer_size - (dp - arg_buf));
+		str_cpy(dp, buffer_size - (dp - arg_buf), *ap);
 		dp += str_size(*ap) + 1;
 
Index: uspace/lib/libc/generic/string.c
===================================================================
--- uspace/lib/libc/generic/string.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/lib/libc/generic/string.c	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -463,36 +463,69 @@
 }
 
-/** Copy NULL-terminated string.
- *
- * Copy source string @a src to destination buffer @a dst.
- * No more than @a size bytes are written. NULL-terminator is always
- * written after the last succesfully copied character (i.e. if the
- * destination buffer is has at least 1 byte, it will be always
- * NULL-terminated).
- *
- * @param src   Source string.
+/** Copy string.
+ *
+ * Copy source string @a src to destination buffer @a dest.
+ * No more than @a size bytes are written. If the size of the output buffer
+ * is at least one byte, the output string will always be well-formed, i.e.
+ * null-terminated and containing only complete characters.
+ *
  * @param dst   Destination buffer.
  * @param count Size of the destination buffer.
- *
- */
-void str_ncpy(char *dst, const char *src, size_t size)
-{
-	/* No space for the NULL-terminator in the buffer */
+ * @param src   Source string.
+ */
+void str_cpy(char *dest, size_t size, const char *src)
+{
+	wchar_t ch;
+	size_t src_off;
+	size_t dest_off;
+
+	/* No space for the NULL-terminator in the buffer. */
 	if (size == 0)
 		return;
 	
+	src_off = 0;
+	dest_off = 0;
+
+	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
+		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
+			break;
+	}
+
+	dest[dest_off] = '\0';
+}
+
+/** Copy size-limited substring.
+ *
+ * Copy source string @a src to destination buffer @a dest.
+ * No more than @a size bytes are written. If the size of the output buffer
+ * is at least one byte, the output string will always be well-formed, i.e.
+ * null-terminated and containing only complete characters.
+ *
+ * No more than @a n bytes are read from the input string, so it does not
+ * have to be null-terminated.
+ *
+ * @param dst   Destination buffer.
+ * @param count Size of the destination buffer.
+ * @param src   Source string.
+ */
+void str_ncpy(char *dest, size_t size, const char *src, size_t n)
+{
 	wchar_t ch;
-	size_t str_off = 0;
-	size_t dst_off = 0;
-	
-	while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) {
-		if (chr_encode(ch, dst, &dst_off, size) != EOK)
+	size_t src_off;
+	size_t dest_off;
+
+	/* No space for the null terminator in the buffer. */
+	if (size == 0)
+		return;
+	
+	src_off = 0;
+	dest_off = 0;
+
+	while ((ch = str_decode(src, &src_off, n)) != 0) {
+		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
-	
-	if (dst_off >= size)
-		dst[size - 1] = 0;
-	else
-		dst[dst_off] = 0;
+
+	dest[dest_off] = '\0';
 }
 
@@ -799,13 +832,4 @@
 }
 
-char *strcpy(char *dest, const char *src)
-{
-	char *orig = dest;
-	
-	while ((*(dest++) = *(src++)))
-		;
-	return orig;
-}
-
 char *strcat(char *dest, const char *src)
 {
Index: uspace/lib/libc/generic/vfs/vfs.c
===================================================================
--- uspace/lib/libc/generic/vfs/vfs.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/lib/libc/generic/vfs/vfs.c	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -77,5 +77,5 @@
 			return NULL;
 		}
-		str_ncpy(ncwd_path_nc, cwd_path, cwd_size + 1 + size + 1);
+		str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
 		ncwd_path_nc[cwd_size] = '/';
 		ncwd_path_nc[cwd_size + 1] = '\0';
@@ -535,5 +535,5 @@
 		return NULL;
 	}
-	str_ncpy(buf, cwd_path, size);
+	str_cpy(buf, size, cwd_path);
 	futex_up(&cwd_futex);
 	return buf;
Index: uspace/lib/libc/include/string.h
===================================================================
--- uspace/lib/libc/include/string.h	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/lib/libc/include/string.h	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -70,5 +70,7 @@
 extern int str_lcmp(const char *s1, const char *s2, count_t max_len);
 
-extern void str_ncpy(char *dst, const char *src, size_t size);
+extern void str_cpy(char *dest, size_t size, const char *src);
+extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
+
 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
@@ -88,5 +90,4 @@
 extern int stricmp(const char *, const char *);
 
-extern char *strcpy(char *, const char *);
 extern char *strcat(char *, const char *);
 
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -490,6 +490,6 @@
 	    str_cmp(d->name, FAT_NAME_DOT) == 0) {
 	   	memset(d, 0, sizeof(fat_dentry_t));
-	   	strcpy(d->name, FAT_NAME_DOT);
-		strcpy(d->ext, FAT_EXT_PAD);
+	   	str_cpy(d->name, 8, FAT_NAME_DOT);
+		str_cpy(d->ext, 3, FAT_EXT_PAD);
 		d->attr = FAT_ATTR_SUBDIR;
 		d->firstc = host2uint16_t_le(childp->firstc);
@@ -500,6 +500,6 @@
 	    str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) {
 		memset(d, 0, sizeof(fat_dentry_t));
-		strcpy(d->name, FAT_NAME_DOT_DOT);
-		strcpy(d->ext, FAT_EXT_PAD);
+		str_cpy(d->name, 8, FAT_NAME_DOT_DOT);
+		str_cpy(d->ext, 3, FAT_EXT_PAD);
 		d->attr = FAT_ATTR_SUBDIR;
 		d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 6eb2e961efe503c8ba03227ff58363688d61d27a)
@@ -326,5 +326,5 @@
 		return ENOMEM;
 	}
-	strcpy(namep->name, nm);
+	str_cpy(namep->name, size + 1, nm);
 	namep->parent = parentp;
 	
