[PATCH] cmd: Implement builtin mklink command
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Wed Sep 27 23:30:11 CDT 2017
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
programs/cmd/builtins.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
programs/cmd/cmd.rc | 11 ++++++++++-
programs/cmd/wcmd.h | 4 +++-
programs/cmd/wcmdmain.c | 3 +++
4 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 7301f54..33c38c6 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] = {
@@ -4874,3 +4875,50 @@ 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;
+ 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 && !CreateHardLinkW(file1, file2, NULL))
+ WCMD_output_stderr(WCMD_LoadMessage(WCMD_READFAIL), file1);
+ else if(!junction && !CreateSymbolicLinkW(file1, file2, isdir))
+ WCMD_output_stderr(WCMD_LoadMessage(WCMD_READFAIL), file1);
+ else if(junction)
+ WINE_TRACE("Juction links currently not supported.\n");
+}
diff --git a/programs/cmd/cmd.rc b/programs/cmd/cmd.rc
index 03388de..3ebae5a 100644
--- a/programs/cmd/cmd.rc
+++ b/programs/cmd/cmd.rc
@@ -310,6 +310,15 @@ 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 [[/D] | [/H] | [/J]] Link Target\n\
+/D Creates a directory symbolic link. Default is a file symbolic link.\n\
+/H Creates a hard link instead of a symbolic link.\n\
+/J Creates a Directory Junction.\n\
+Link specifies the new symbolic link name.\n\
+Target specifies the path (relative or absolute) that the new link refers to.\n"
+
WCMD_ALLHELP,
"CMD built-in commands are:\n\
ASSOC\t\tShow or modify file extension associations\n\
@@ -328,6 +337,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 +358,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 c135621..c299f3a 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 1aa3c1c..2a6bb1c 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