* win32/win32.c (make_cmdvector): recognize quote within string.
based on Nobu's patch ([ruby-win32:450]). [ruby-talk:75853] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4087 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
8654ce809b
commit
5b1008a005
@ -1,3 +1,8 @@
|
|||||||
|
Fri Jul 18 14:57:19 2003 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
|
* win32/win32.c (make_cmdvector): recognize quote within string.
|
||||||
|
based on Nobu's patch ([ruby-win32:450]). [ruby-talk:75853]
|
||||||
|
|
||||||
Fri Jul 18 13:04:36 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Fri Jul 18 13:04:36 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* eval.c (rb_f_missing): VCALL is called only for LOCAL_ID. no
|
* eval.c (rb_f_missing): VCALL is called only for LOCAL_ID. no
|
||||||
|
386
win32/win32.c
386
win32/win32.c
@ -89,7 +89,8 @@
|
|||||||
bool NtSyncProcess = TRUE;
|
bool NtSyncProcess = TRUE;
|
||||||
|
|
||||||
static struct ChildRecord *CreateChild(char *, char *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
|
static struct ChildRecord *CreateChild(char *, char *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
|
||||||
static bool NtHasRedirection (char *);
|
static int make_cmdvector(const char *, char ***);
|
||||||
|
static bool has_redirection(const char *);
|
||||||
static int valid_filename(char *s);
|
static int valid_filename(char *s);
|
||||||
static void StartSockets ();
|
static void StartSockets ();
|
||||||
static char *str_grow(struct RString *str, size_t new_size);
|
static char *str_grow(struct RString *str, size_t new_size);
|
||||||
@ -370,7 +371,7 @@ NtInitialize(int *argc, char ***argv)
|
|||||||
//
|
//
|
||||||
// subvert cmd.exe's feeble attempt at command line parsing
|
// subvert cmd.exe's feeble attempt at command line parsing
|
||||||
//
|
//
|
||||||
*argc = NtMakeCmdVector((char *)GetCommandLine(), argv, TRUE);
|
*argc = make_cmdvector(GetCommandLine(), argv);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now set up the correct time stuff
|
// Now set up the correct time stuff
|
||||||
@ -510,28 +511,44 @@ static char *szInternalCmds[] = {
|
|||||||
"type",
|
"type",
|
||||||
"ver",
|
"ver",
|
||||||
"vol",
|
"vol",
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
static int
|
||||||
isInternalCmd(char *cmd)
|
internal_match(const void *key, const void *elem)
|
||||||
{
|
{
|
||||||
int i, fRet=0;
|
return strcmp(key, *(const char *const *)elem);
|
||||||
char **vec;
|
}
|
||||||
int vecc = NtMakeCmdVector(cmd, &vec, FALSE);
|
|
||||||
|
|
||||||
if (vecc == 0)
|
static int
|
||||||
return 0;
|
isInternalCmd(const char *cmd)
|
||||||
for( i = 0; szInternalCmds[i] ; i++){
|
{
|
||||||
if(!strcasecmp(szInternalCmds[i], vec[0])){
|
int i;
|
||||||
fRet = 1;
|
char cmdname[8], *b = cmdname, c;
|
||||||
break;
|
|
||||||
}
|
do {
|
||||||
|
if (!(c = *cmd++)) return 0;
|
||||||
|
} while (isspace(c));
|
||||||
|
while (isalpha(c)) {
|
||||||
|
*b++ = tolower(c);
|
||||||
|
if (b == cmdname + sizeof(cmdname)) return 0;
|
||||||
|
if (!(c = *cmd++)) return 0;
|
||||||
}
|
}
|
||||||
|
if (c == '.') c = *cmd;
|
||||||
SafeFree(vec, vecc);
|
switch (c) {
|
||||||
|
case '<': case '>': case '|':
|
||||||
return fRet;
|
return 1;
|
||||||
|
case '\0': case ' ': case '\t': case '\n':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*b = 0;
|
||||||
|
if (!bsearch(cmdname, szInternalCmds,
|
||||||
|
sizeof(szInternalCmds) / sizeof(*szInternalCmds),
|
||||||
|
sizeof(*szInternalCmds),
|
||||||
|
internal_match))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -860,14 +877,15 @@ CreateChild(char *cmd, char *prog, SECURITY_ATTRIBUTES *psa, HANDLE hInput, HAND
|
|||||||
shell = prog;
|
shell = prog;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((shell = getenv("RUBYSHELL")) && NtHasRedirection(cmd)) {
|
int redir = -1;
|
||||||
|
if ((shell = getenv("RUBYSHELL")) && (redir = has_redirection(cmd))) {
|
||||||
char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) +
|
char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) +
|
||||||
sizeof (" -c "));
|
sizeof (" -c "));
|
||||||
sprintf(tmp, "%s -c %s", shell, cmd);
|
sprintf(tmp, "%s -c %s", shell, cmd);
|
||||||
cmd = tmp;
|
cmd = tmp;
|
||||||
}
|
}
|
||||||
else if ((shell = getenv("COMSPEC")) &&
|
else if ((shell = getenv("COMSPEC")) &&
|
||||||
(NtHasRedirection(cmd) || isInternalCmd(cmd))) {
|
((redir < 0 ? has_redirection(cmd) : redir) || isInternalCmd(cmd))) {
|
||||||
char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) +
|
char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) +
|
||||||
sizeof (" /c "));
|
sizeof (" /c "));
|
||||||
sprintf(tmp, "%s /c %s", shell, cmd);
|
sprintf(tmp, "%s /c %s", shell, cmd);
|
||||||
@ -904,7 +922,7 @@ CreateChild(char *cmd, char *prog, SECURITY_ATTRIBUTES *psa, HANDLE hInput, HAND
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _NtCmdLineElement {
|
typedef struct _NtCmdLineElement {
|
||||||
struct _NtCmdLineElement *next, *prev;
|
struct _NtCmdLineElement *next;
|
||||||
char *str;
|
char *str;
|
||||||
int len;
|
int len;
|
||||||
int flags;
|
int flags;
|
||||||
@ -918,38 +936,11 @@ typedef struct _NtCmdLineElement {
|
|||||||
#define NTMALLOC 0x2 // string in element was malloc'ed
|
#define NTMALLOC 0x2 // string in element was malloc'ed
|
||||||
#define NTSTRING 0x4 // element contains a quoted string
|
#define NTSTRING 0x4 // element contains a quoted string
|
||||||
|
|
||||||
NtCmdLineElement *NtCmdHead = NULL, *NtCmdTail = NULL;
|
|
||||||
|
|
||||||
void
|
|
||||||
NtFreeCmdLine(void)
|
|
||||||
{
|
|
||||||
NtCmdLineElement *ptr;
|
|
||||||
|
|
||||||
while(NtCmdHead) {
|
|
||||||
ptr = NtCmdHead;
|
|
||||||
NtCmdHead = NtCmdHead->next;
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
NtCmdHead = NtCmdTail = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This function expands wild card characters that were spotted
|
|
||||||
// during the parse phase. The idea here is to call FindFirstFile and
|
|
||||||
// FindNextFile with the wildcard pattern specified, and splice in the
|
|
||||||
// resulting list of new names. If the wildcard pattern doesn't match
|
|
||||||
// any existing files, just leave it in the list.
|
|
||||||
//
|
|
||||||
typedef struct {
|
|
||||||
NtCmdLineElement *head;
|
|
||||||
NtCmdLineElement *tail;
|
|
||||||
} ListInfo;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
insert(const char *path, VALUE vinfo)
|
insert(const char *path, VALUE vinfo)
|
||||||
{
|
{
|
||||||
NtCmdLineElement *tmpcurr;
|
NtCmdLineElement *tmpcurr;
|
||||||
ListInfo *listinfo = (ListInfo *)vinfo;
|
NtCmdLineElement ***tail = (NtCmdLineElement ***)vinfo;
|
||||||
|
|
||||||
tmpcurr = ALLOC(NtCmdLineElement);
|
tmpcurr = ALLOC(NtCmdLineElement);
|
||||||
MEMZERO(tmpcurr, NtCmdLineElement, 1);
|
MEMZERO(tmpcurr, NtCmdLineElement, 1);
|
||||||
@ -957,14 +948,8 @@ insert(const char *path, VALUE vinfo)
|
|||||||
tmpcurr->str = ALLOC_N(char, tmpcurr->len + 1);
|
tmpcurr->str = ALLOC_N(char, tmpcurr->len + 1);
|
||||||
tmpcurr->flags |= NTMALLOC;
|
tmpcurr->flags |= NTMALLOC;
|
||||||
strcpy(tmpcurr->str, path);
|
strcpy(tmpcurr->str, path);
|
||||||
if (listinfo->tail) {
|
**tail = tmpcurr;
|
||||||
listinfo->tail->next = tmpcurr;
|
*tail = &tmpcurr->next;
|
||||||
tmpcurr->prev = listinfo->tail;
|
|
||||||
listinfo->tail = tmpcurr;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
listinfo->tail = listinfo->head = tmpcurr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
#ifdef HAVE_SYS_PARAM_H
|
||||||
@ -973,14 +958,13 @@ insert(const char *path, VALUE vinfo)
|
|||||||
# define MAXPATHLEN 512
|
# define MAXPATHLEN 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
|
||||||
NtCmdGlob (NtCmdLineElement *patt)
|
static NtCmdLineElement **
|
||||||
|
cmdglob(NtCmdLineElement *patt, NtCmdLineElement **tail)
|
||||||
{
|
{
|
||||||
ListInfo listinfo;
|
|
||||||
char buffer[MAXPATHLEN], *buf = buffer;
|
char buffer[MAXPATHLEN], *buf = buffer;
|
||||||
char *p;
|
char *p;
|
||||||
|
NtCmdLineElement **last = tail;
|
||||||
listinfo.head = listinfo.tail = 0;
|
|
||||||
|
|
||||||
if (patt->len >= MAXPATHLEN)
|
if (patt->len >= MAXPATHLEN)
|
||||||
buf = ruby_xmalloc(patt->len + 1);
|
buf = ruby_xmalloc(patt->len + 1);
|
||||||
@ -990,21 +974,15 @@ NtCmdGlob (NtCmdLineElement *patt)
|
|||||||
for (p = buf; *p; p = CharNext(p))
|
for (p = buf; *p; p = CharNext(p))
|
||||||
if (*p == '\\')
|
if (*p == '\\')
|
||||||
*p = '/';
|
*p = '/';
|
||||||
rb_globi(buf, insert, (VALUE)&listinfo);
|
rb_globi(buf, insert, (VALUE)&tail);
|
||||||
if (buf != buffer)
|
if (buf != buffer)
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
if (listinfo.head && listinfo.tail) {
|
if (last == tail) return 0;
|
||||||
listinfo.head->prev = patt->prev;
|
|
||||||
listinfo.tail->next = patt->next;
|
|
||||||
if (listinfo.head->prev)
|
|
||||||
listinfo.head->prev->next = listinfo.head;
|
|
||||||
if (listinfo.tail->next)
|
|
||||||
listinfo.tail->next->prev = listinfo.tail;
|
|
||||||
}
|
|
||||||
if (patt->flags & NTMALLOC)
|
if (patt->flags & NTMALLOC)
|
||||||
free(patt->str);
|
free(patt->str);
|
||||||
// free(patt); //TODO: memory leak occures here. we have to fix it.
|
free(patt);
|
||||||
|
return tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1013,80 +991,77 @@ NtCmdGlob (NtCmdLineElement *patt)
|
|||||||
//
|
//
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
NtHasRedirection (char *cmd)
|
has_redirection(const char *cmd)
|
||||||
{
|
{
|
||||||
int inquote = 0;
|
|
||||||
char quote = '\0';
|
char quote = '\0';
|
||||||
char *ptr ;
|
const char *ptr;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Scan the string, looking for redirection (< or >) or pipe
|
// Scan the string, looking for redirection (< or >) or pipe
|
||||||
// characters (|) that are not in a quoted string
|
// characters (|) that are not in a quoted string
|
||||||
//
|
//
|
||||||
|
|
||||||
for (ptr = cmd; *ptr; ptr++) {
|
for (ptr = cmd; *ptr;) {
|
||||||
|
|
||||||
switch (*ptr) {
|
switch (*ptr) {
|
||||||
|
|
||||||
case '\'':
|
case '\'':
|
||||||
case '\"':
|
case '\"':
|
||||||
if (inquote) {
|
if (!quote)
|
||||||
if (quote == *ptr) {
|
|
||||||
inquote = 0;
|
|
||||||
quote = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quote = *ptr;
|
quote = *ptr;
|
||||||
inquote++;
|
else if (quote == *ptr)
|
||||||
}
|
quote = '\0';
|
||||||
|
ptr++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
case '<':
|
case '<':
|
||||||
case '|':
|
case '|':
|
||||||
|
if (!quote)
|
||||||
if (!inquote)
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
ptr++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
ptr++;
|
||||||
|
default:
|
||||||
|
ptr = CharNext(ptr);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
int
|
skipspace(char *ptr)
|
||||||
NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
|
|
||||||
{
|
{
|
||||||
int cmdlen = strlen(cmdline);
|
while (ISSPACE(*ptr))
|
||||||
int done, instring, globbing, quoted, len;
|
ptr++;
|
||||||
int newline, need_free = 0, i;
|
return ptr;
|
||||||
int elements, strsz;
|
}
|
||||||
int slashes = 0;
|
|
||||||
char *ptr, *base, *buffer;
|
static int
|
||||||
|
make_cmdvector(const char *cmd, char ***vec)
|
||||||
|
{
|
||||||
|
int cmdlen, globbing, len, i;
|
||||||
|
int elements, strsz, done;
|
||||||
|
int slashes, escape;
|
||||||
|
char *ptr, *base, *buffer, *cmdline;
|
||||||
char **vptr;
|
char **vptr;
|
||||||
char quote;
|
char quote;
|
||||||
NtCmdLineElement *curr;
|
NtCmdLineElement *curr, **tail;
|
||||||
|
NtCmdLineElement *cmdhead = NULL, **cmdtail = &cmdhead;
|
||||||
|
|
||||||
//
|
//
|
||||||
// just return if we don't have a command line
|
// just return if we don't have a command line
|
||||||
//
|
//
|
||||||
|
|
||||||
if (cmdlen == 0) {
|
while (ISSPACE(*cmd))
|
||||||
|
cmd++;
|
||||||
|
if (!*cmd) {
|
||||||
*vec = NULL;
|
*vec = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdline = strdup(cmdline);
|
ptr = cmdline = strdup(cmd);
|
||||||
|
|
||||||
//
|
|
||||||
// strip trailing white space
|
|
||||||
//
|
|
||||||
|
|
||||||
ptr = cmdline+(cmdlen - 1);
|
|
||||||
while(ptr >= cmdline && ISSPACE(*ptr))
|
|
||||||
--ptr;
|
|
||||||
*++ptr = '\0';
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Ok, parse the command line, building a list of CmdLineElements.
|
// Ok, parse the command line, building a list of CmdLineElements.
|
||||||
@ -1097,19 +1072,10 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
|
|||||||
// The inner loop does one interation for each character in the element.
|
// The inner loop does one interation for each character in the element.
|
||||||
//
|
//
|
||||||
|
|
||||||
for (done = 0, ptr = cmdline; *ptr;) {
|
while (*(ptr = skipspace(ptr))) {
|
||||||
|
|
||||||
//
|
|
||||||
// zap any leading whitespace
|
|
||||||
//
|
|
||||||
|
|
||||||
while(ISSPACE(*ptr))
|
|
||||||
ptr++;
|
|
||||||
base = ptr;
|
base = ptr;
|
||||||
|
quote = slashes = globbing = escape = 0;
|
||||||
for (done = newline = globbing = instring = quoted = 0;
|
for (done = 0; !done && *ptr; ) {
|
||||||
*ptr && !done; ptr++) {
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Switch on the current character. We only care about the
|
// Switch on the current character. We only care about the
|
||||||
// white-space characters, the wild-card characters, and the
|
// white-space characters, the wild-card characters, and the
|
||||||
@ -1118,55 +1084,40 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
|
|||||||
|
|
||||||
switch (*ptr) {
|
switch (*ptr) {
|
||||||
case '\\':
|
case '\\':
|
||||||
if (ptr[1] == '"') ptr++;
|
slashes++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
#if 0
|
case '\n':
|
||||||
case '/': // have to do this for NT/DOS option strings
|
|
||||||
|
|
||||||
//
|
|
||||||
// check to see if we're parsing an option switch
|
|
||||||
//
|
|
||||||
|
|
||||||
if (*ptr == '/' && base == ptr)
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
//
|
//
|
||||||
// if we're not in a string, then we're finished with this
|
// if we're not in a string, then we're finished with this
|
||||||
// element
|
// element
|
||||||
//
|
//
|
||||||
|
|
||||||
if (!instring)
|
if (!quote) {
|
||||||
done++;
|
*ptr = 0;
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
case '?':
|
case '?':
|
||||||
|
case '[':
|
||||||
|
case '{':
|
||||||
//
|
//
|
||||||
// record the fact that this element has a wildcard character
|
// record the fact that this element has a wildcard character
|
||||||
// N.B. Don't glob if inside a single quoted string
|
// N.B. Don't glob if inside a single quoted string
|
||||||
//
|
//
|
||||||
|
|
||||||
if (!(instring && quote == '\''))
|
if (quote != '\'')
|
||||||
globbing++;
|
globbing++;
|
||||||
break;
|
ptr++;
|
||||||
|
slashes = 0;
|
||||||
case '\n':
|
|
||||||
|
|
||||||
//
|
|
||||||
// If this string contains a newline, mark it as such so
|
|
||||||
// we can replace it with the two character sequence "\n"
|
|
||||||
// (cmd.exe doesn't like raw newlines in strings...sigh).
|
|
||||||
//
|
|
||||||
|
|
||||||
newline++;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\'':
|
case '\'':
|
||||||
case '\"':
|
case '\"':
|
||||||
|
|
||||||
//
|
//
|
||||||
// if we're already in a string, see if this is the
|
// if we're already in a string, see if this is the
|
||||||
// terminating close-quote. If it is, we're finished with
|
// terminating close-quote. If it is, we're finished with
|
||||||
@ -1174,90 +1125,99 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
|
|||||||
// If we're not already in a string, start one.
|
// If we're not already in a string, start one.
|
||||||
//
|
//
|
||||||
|
|
||||||
if (instring) {
|
if (!(slashes & 1)) {
|
||||||
if (quote == *ptr) {
|
if (!quote)
|
||||||
instring = 0;
|
quote = *ptr;
|
||||||
|
else if (quote == *ptr)
|
||||||
quote = '\0';
|
quote = '\0';
|
||||||
}
|
escape++;
|
||||||
}
|
|
||||||
else {
|
|
||||||
instring++;
|
|
||||||
quote = *ptr;
|
|
||||||
quoted++;
|
|
||||||
}
|
}
|
||||||
|
slashes = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ptr = CharNext(ptr);
|
||||||
|
slashes = 0;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// need to back up ptr by one due to last increment of for loop
|
|
||||||
// (if we got out by seeing white space)
|
|
||||||
//
|
|
||||||
|
|
||||||
if (*ptr)
|
|
||||||
ptr--;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// when we get here, we've got a pair of pointers to the element,
|
// when we get here, we've got a pair of pointers to the element,
|
||||||
// base and ptr. Base points to the start of the element while ptr
|
// base and ptr. Base points to the start of the element while ptr
|
||||||
// points to the character following the element.
|
// points to the character following the element.
|
||||||
//
|
//
|
||||||
|
|
||||||
curr = ALLOC(NtCmdLineElement);
|
|
||||||
memset (curr, 0, sizeof(*curr));
|
|
||||||
|
|
||||||
len = ptr - base;
|
len = ptr - base;
|
||||||
|
if (quote) escape = 0;
|
||||||
|
else if (done) --len;
|
||||||
|
|
||||||
//
|
//
|
||||||
// if it's an input vector element and it's enclosed by quotes,
|
// if it's an input vector element and it's enclosed by quotes,
|
||||||
// we can remove them.
|
// we can remove them.
|
||||||
//
|
//
|
||||||
|
|
||||||
if (InputCmd && !instring && (base[0] == '\"' && base[len-1] == '\"')) {
|
if (escape) {
|
||||||
char *p;
|
char *p = base;
|
||||||
base++;
|
slashes = quote = 0;
|
||||||
len -= 2;
|
while (p < base + len) {
|
||||||
base[len] = 0;
|
switch (*p) {
|
||||||
for (p = base; p < base + len; p++) {
|
case '\\':
|
||||||
if ((p[0] == '\\' || p[0] == '\"') && p[1] == '"') {
|
p++;
|
||||||
strcpy(p, p + 1);
|
slashes++;
|
||||||
len--;
|
break;
|
||||||
|
|
||||||
|
case '\'':
|
||||||
|
case '"':
|
||||||
|
if (!(slashes & 1)) {
|
||||||
|
if (!quote)
|
||||||
|
quote = *p;
|
||||||
|
else if (quote == *p)
|
||||||
|
quote = '\0';
|
||||||
|
else {
|
||||||
|
p++;
|
||||||
|
slashes = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (base + slashes == p) {
|
||||||
|
base += slashes >> 1;
|
||||||
|
len -= slashes >> 1;
|
||||||
|
slashes &= 1;
|
||||||
|
}
|
||||||
|
if (base == p) {
|
||||||
|
base = ++p;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(p - ((slashes + 1) >> 1), p + (~slashes & 1), base + len - p);
|
||||||
|
slashes >>= 1;
|
||||||
|
p -= slashes;
|
||||||
|
len -= slashes + 1;
|
||||||
|
slashes = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
p = CharNext(p);
|
||||||
|
slashes = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (InputCmd && !instring && (base[0] == '\'' && base[len-1] == '\'')) {
|
|
||||||
base++;
|
|
||||||
len -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
curr = ALLOC(NtCmdLineElement);
|
||||||
|
MEMZERO(curr, NtCmdLineElement, 1);
|
||||||
curr->str = base;
|
curr->str = base;
|
||||||
curr->len = len;
|
curr->len = len;
|
||||||
curr->flags |= (globbing ? NTGLOB : 0);
|
|
||||||
|
|
||||||
//
|
if (globbing && (tail = cmdglob(curr, cmdtail))) {
|
||||||
// Now put it in the list of elements
|
cmdtail = tail;
|
||||||
//
|
|
||||||
if (NtCmdTail) {
|
|
||||||
NtCmdTail->next = curr;
|
|
||||||
curr->prev = NtCmdTail;
|
|
||||||
NtCmdTail = curr;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NtCmdHead = NtCmdTail = curr;
|
*cmdtail = curr;
|
||||||
}
|
cmdtail = &curr->next;
|
||||||
}
|
|
||||||
|
|
||||||
if (InputCmd) {
|
|
||||||
|
|
||||||
//
|
|
||||||
// When we get here we've finished parsing the command line. Now
|
|
||||||
// we need to run the list, expanding any globbing patterns.
|
|
||||||
//
|
|
||||||
|
|
||||||
for(curr = NtCmdHead; curr; curr = curr->next) {
|
|
||||||
if (curr->flags & NTGLOB) {
|
|
||||||
NtCmdGlob(curr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1267,7 +1227,7 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
|
|||||||
// (argv) and a string table for the elements.
|
// (argv) and a string table for the elements.
|
||||||
//
|
//
|
||||||
|
|
||||||
for (elements = 0, strsz = 0, curr = NtCmdHead; curr; curr = curr->next) {
|
for (elements = 0, strsz = 0, curr = cmdhead; curr; curr = curr->next) {
|
||||||
elements++;
|
elements++;
|
||||||
strsz += (curr->len + 1);
|
strsz += (curr->len + 1);
|
||||||
}
|
}
|
||||||
@ -1275,8 +1235,6 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
|
|||||||
len = (elements+1)*sizeof(char *) + strsz;
|
len = (elements+1)*sizeof(char *) + strsz;
|
||||||
buffer = ALLOC_N(char, len);
|
buffer = ALLOC_N(char, len);
|
||||||
|
|
||||||
memset (buffer, 0, len);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// make vptr point to the start of the buffer
|
// make vptr point to the start of the buffer
|
||||||
// and ptr point to the area we'll consider the string table.
|
// and ptr point to the area we'll consider the string table.
|
||||||
@ -1293,13 +1251,17 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
|
|||||||
|
|
||||||
ptr = buffer + (elements+1) * sizeof(char *);
|
ptr = buffer + (elements+1) * sizeof(char *);
|
||||||
|
|
||||||
for (curr = NtCmdHead; curr; curr = curr->next) {
|
while (curr = cmdhead) {
|
||||||
strncpy (ptr, curr->str, curr->len);
|
strncpy (ptr, curr->str, curr->len);
|
||||||
ptr[curr->len] = '\0';
|
ptr[curr->len] = '\0';
|
||||||
*vptr++ = ptr;
|
*vptr++ = ptr;
|
||||||
ptr += curr->len + 1;
|
ptr += curr->len + 1;
|
||||||
|
cmdhead = curr->next;
|
||||||
|
if (curr->flags & NTMALLOC) free(curr->str);
|
||||||
|
free(curr);
|
||||||
}
|
}
|
||||||
NtFreeCmdLine();
|
*vptr = 0;
|
||||||
|
|
||||||
*vec = (char **) buffer;
|
*vec = (char **) buffer;
|
||||||
free(cmdline);
|
free(cmdline);
|
||||||
return elements;
|
return elements;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user