xref: /reactos/base/shell/cmd/alias.c (revision 4f0b8d3d)
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 hardcode string to 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
210