[v3 PATCH] cmd: Implement builtin mklink command
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Tue Nov 7 17:26:42 CST 2017
v3. Fixed help message.
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
programs/cmd/builtins.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
programs/cmd/cmd.rc | 12 +++++++++++-
programs/cmd/wcmd.h | 4 +++-
programs/cmd/wcmdmain.c | 3 +++
4 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 1da1f67..6f7a2c9 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -94,6 +94,7 @@ const WCHAR inbuilt[][10] = {
{'F','T','Y','P','E','\0'},
{'M','O','R','E','\0'},
{'C','H','O','I','C','E','\0'},
+ {'M','K','L','I','N','K','\0'},
{'E','X','I','T','\0'}
};
static const WCHAR externals[][10] = {
@@ -4959,3 +4960,54 @@ void WCMD_color (void) {
SetConsoleTextAttribute(hStdOut, color);
}
}
+
+void WCMD_mklink(WCHAR *args)
+{
+ int argno = 0;
+ WCHAR *argN = args;
+ BOOL isdir = FALSE;
+ BOOL junction = FALSE;
+ BOOL hard = FALSE;
+ BOOL ret = FALSE;
+ WCHAR file1[MAX_PATH] = {0};
+ WCHAR file2[MAX_PATH];
+ static const WCHAR optD[] = {'/', 'D', '\0'};
+ static const WCHAR optH[] = {'/', 'H', '\0'};
+ static const WCHAR optJ[] = {'/', 'J', '\0'};
+
+ if (param1[0] == 0x00 || param2[0] == 0x00) {
+ WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOARG));
+ return;
+ }
+
+ while (argN) {
+ WCHAR *thisArg = WCMD_parameter (args, argno++, &argN, FALSE, FALSE);
+
+ if (!argN) break;
+
+ WINE_TRACE("mklink: Processing arg '%s'\n", wine_dbgstr_w(thisArg));
+
+ if(lstrcmpiW(thisArg, optD) == 0)
+ isdir = TRUE;
+ else if(lstrcmpiW(thisArg, optH) == 0)
+ hard = TRUE;
+ else if(lstrcmpiW(thisArg, optJ) == 0)
+ junction = TRUE;
+ else {
+ if(!file1[0])
+ lstrcpyW(file1, thisArg);
+ else
+ lstrcpyW(file2, thisArg);
+ }
+ }
+
+ if(hard)
+ ret = CreateHardLinkW(file1, file2, NULL);
+ else if(!junction)
+ ret = CreateSymbolicLinkW(file1, file2, isdir);
+ else if(junction)
+ WINE_TRACE("Juction links currently not supported.\n");
+
+ if(!ret)
+ WCMD_output_stderr(WCMD_LoadMessage(WCMD_READFAIL), file1);
+}
diff --git a/programs/cmd/cmd.rc b/programs/cmd/cmd.rc
index 03388de..3f74791 100644
--- a/programs/cmd/cmd.rc
+++ b/programs/cmd/cmd.rc
@@ -310,6 +310,16 @@ CHOICE is mainly used to build a menu selection in a batch file.\n"
"EXIT terminates the current command session and returns to the operating\n\
system or shell from which you invoked cmd.\n"
+ WCMD_MKLINK,
+"Creates a symbolic link.\n\
+MKLINK [options] link_name target\n\
+Options:\n\
+/d Creates a symbolic link. (Default)\n\
+/h Creates a hard link.\n\
+/j Creates a Directory Junction.\n\
+link_name specifies the new symbolic link name.\n\
+target specifies the path that the link_name points to.\n"
+
WCMD_ALLHELP,
"CMD built-in commands are:\n\
ASSOC\t\tShow or modify file extension associations\n\
@@ -328,6 +338,7 @@ ENDLOCAL\tEnd localization of environment changes in a batch file\n\
FTYPE\t\tShow or modify open commands associated with file types\n\
HELP\t\tShow brief help details on a topic\n\
MD (MKDIR)\tCreate a subdirectory\n\
+MKLINK\tCreates Symbolic Links and Hard Links\n\
MORE\t\tDisplay output in pages\n\
MOVE\t\tMove a file, set of files or directory tree\n\
PATH\t\tSet or show the search path\n\
@@ -348,7 +359,6 @@ VOL\t\tShow the volume label of a disk device\n\
XCOPY\t\tCopy source files or directory trees to a destination\n\
EXIT\t\tClose down CMD\n\n\
Enter HELP <command> for further information on any of the above commands.\n"
-
WCMD_CONFIRM, "Are you sure?"
WCMD_YES, "#msgctxt#Yes key#Y"
WCMD_NO, "#msgctxt#No key#N"
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h
index 557be14..d4d97a0 100644
--- a/programs/cmd/wcmd.h
+++ b/programs/cmd/wcmd.h
@@ -101,6 +101,7 @@ void WCMD_type (WCHAR *);
void WCMD_verify (const WCHAR *args);
void WCMD_version (void);
int WCMD_volume (BOOL set_label, const WCHAR *args);
+void WCMD_mklink(WCHAR *args);
static inline BOOL WCMD_is_console_handle(HANDLE h)
{
@@ -266,9 +267,10 @@ extern BOOL delayedsubst;
#define WCMD_FTYPE 42
#define WCMD_MORE 43
#define WCMD_CHOICE 44
+#define WCMD_MKLINK 45
/* Must be last in list */
-#define WCMD_EXIT 45
+#define WCMD_EXIT 46
/* Some standard messages */
extern const WCHAR newlineW[];
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index cec6df0..827ddd2 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -1597,6 +1597,9 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
case WCMD_CHOICE:
WCMD_choice(p);
break;
+ case WCMD_MKLINK:
+ WCMD_mklink(p);
+ break;
case WCMD_EXIT:
WCMD_exit (cmdList);
break;
--
1.9.1
More information about the wine-patches
mailing list