[CMD]
[reactos.git] / reactos / base / shell / cmd / alias.c
1 /*
2 * ALIAS.C - alias administration module.
3 *
4 *
5 * History:
6 *
7 * 02/02/1996 (Oliver Mueller)
8 * started.
9 *
10 * 02/03/1996 (Oliver Mueller)
11 * Added sorting algorithm and case sensitive substitution by using
12 * partstrupr().
13 *
14 * 27 Jul 1998 John P. Price
15 * added config.h include
16 * added ifdef's to disable aliases
17 *
18 * 09-Dec-1998 Eric Kohl
19 * Fixed crash when removing an alias in DeleteAlias().
20 * Added help text ("/?").
21 *
22 * 14-Jan-1998 Eric Kohl
23 * Clean up and Unicode safe!
24 *
25 * 24-Jan-1998 Eric Kohl
26 * Redirection safe!
27 *
28 * 02-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
29 * Remove all hardcoded strings in En.rc
30 *
31 * 02-Feb-2008 (Christoph von Wittich <christoph_vw@reactos.org>)
32 * rewrote alias handling for doskey compat
33 */
34
35
36 #include "precomp.h"
37
38 #ifdef FEATURE_ALIASES
39
40 /* module internal functions */
41 /* strlwr only for first word in string */
42 static VOID
43 partstrlwr (LPTSTR str)
44 {
45 LPTSTR c = str;
46 while (*c && !_istspace (*c) && *c != _T('='))
47 {
48 *c = _totlower (*c);
49 c++;
50 }
51 }
52
53 static VOID
54 PrintAlias (VOID)
55 {
56 LPTSTR Aliases;
57 LPTSTR ptr;
58 DWORD len;
59
60 len = GetConsoleAliasesLength(_T("cmd.exe"));
61 if (len == 0)
62 return;
63
64 /* allocate memory for an extra \0 char to make parsing easier */
65 ptr = cmd_alloc(len + sizeof(TCHAR));
66 if (!ptr)
67 return;
68
69 Aliases = ptr;
70
71 ZeroMemory(Aliases, len + sizeof(TCHAR));
72
73 if (GetConsoleAliases(Aliases, len, _T("cmd.exe")) != 0)
74 {
75 while (*Aliases != '\0')
76 {
77 ConOutPrintf(_T("%s\n"), Aliases);
78 Aliases = Aliases + lstrlen(Aliases);
79 Aliases++;
80 }
81 }
82 cmd_free(ptr);
83 }
84
85 /* specified routines */
86 VOID ExpandAlias (LPTSTR cmd, INT maxlen)
87 {
88 LPTSTR buffer;
89 TCHAR *position, *in, *out;
90 LPTSTR Token;
91 LPTSTR tmp;
92
93 tmp = cmd_dup(cmd);
94 if (!tmp)
95 return;
96
97 /* first part is the macro name */
98 position = tmp + _tcscspn(tmp, _T(" \n"));
99 if (position == tmp)
100 {
101 cmd_free(tmp);
102 return;
103 }
104 *position++ = _T('\0');
105 position += _tcsspn(position, _T(" "));
106
107 buffer = cmd_alloc(maxlen);
108 if (!buffer)
109 {
110 cmd_free(tmp);
111 return;
112 }
113
114 if (GetConsoleAlias(tmp, buffer, maxlen, _T("cmd.exe")) == 0)
115 {
116 cmd_free(tmp);
117 cmd_free(buffer);
118 return;
119 }
120
121 in = buffer;
122 out = cmd;
123 while (*in)
124 {
125 if (*in == _T('$'))
126 {
127 Token = position;
128 if (in[1] >= _T('1') && in[1] <= _T('9'))
129 {
130 /* Copy a single space-delimited token from the input line */
131 INT num;
132 for (num = in[1] - _T('1'); num > 0; num--)
133 {
134 Token += _tcscspn(Token, _T(" \n"));
135 Token += _tcsspn(Token, _T(" "));
136 }
137 while (!_tcschr(_T(" \n"), *Token))
138 {
139 if (out >= &cmd[maxlen - 1])
140 break;
141 *out++ = *Token++;
142 }
143 in += 2;
144 continue;
145 }
146 else if (in[1] == _T('*'))
147 {
148 /* Copy the entire remainder of the line */
149 while (*Token && *Token != _T('\n'))
150 {
151 if (out >= &cmd[maxlen - 1])
152 break;
153 *out++ = *Token++;
154 }
155 in += 2;
156 continue;
157 }
158 }
159 if (out >= &cmd[maxlen - 1])
160 break;
161 *out++ = *in++;
162 }
163 *out++ = _T('\n');
164 *out = _T('\0');
165
166 cmd_free(buffer);
167 cmd_free(tmp);
168 }
169
170 INT CommandAlias (LPTSTR param)
171 {
172 LPTSTR ptr;
173
174 if (!_tcsncmp (param, _T("/?"), 2))
175 {
176 ConOutResPaging(TRUE,STRING_ALIAS_HELP);
177 return 0;
178 }
179
180 nErrorLevel = 0;
181
182 if (param[0] == _T('\0'))
183 {
184 PrintAlias ();
185 return 0;
186 }
187
188 nErrorLevel = 0;
189
190 /* error if no '=' found */
191 if ((ptr = _tcschr (param, _T('='))) == 0)
192 {
193 nErrorLevel = 1;
194 return 1;
195 }
196
197 /* Split rest into name and substitute */
198 *ptr++ = _T('\0');
199
200 partstrlwr (param);
201
202 if (ptr[0] == _T('\0'))
203 AddConsoleAlias(param, NULL, _T("cmd.exe"));
204 else
205 AddConsoleAlias(param, ptr, _T("cmd.exe"));
206
207 return 0;
208 }
209 #endif