xref: /reactos/base/shell/cmd/alias.c (revision 50cf16b3)
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     {
68         WARN("Cannot allocate memory for ptr!\n");
69         return;
70     }
71 
72     Aliases = ptr;
73 
74     ZeroMemory(Aliases, len + sizeof(TCHAR));
75 
76     if (GetConsoleAliases(Aliases, len, _T("cmd.exe")) != 0)
77     {
78         while (*Aliases != '\0')
79         {
80             ConOutPrintf(_T("%s\n"), Aliases);
81             Aliases = Aliases + lstrlen(Aliases);
82             Aliases++;
83         }
84     }
85     cmd_free(ptr);
86 }
87 
88 /* specified routines */
89 VOID ExpandAlias (LPTSTR cmd, INT maxlen)
90 {
91     LPTSTR buffer;
92     TCHAR *position, *in, *out;
93     LPTSTR Token;
94     LPTSTR tmp;
95 
96     tmp = cmd_dup(cmd);
97     if (!tmp)
98         return;
99 
100     /* first part is the macro name */
101     position = tmp + _tcscspn(tmp, _T(" \n"));
102     if (position == tmp)
103     {
104         cmd_free(tmp);
105         return;
106     }
107     *position++ = _T('\0');
108     position += _tcsspn(position, _T(" "));
109 
110     buffer = cmd_alloc(maxlen);
111     if (!buffer)
112     {
113         WARN("Cannot allocate memory for alias buffer!\n");
114         cmd_free(tmp);
115         return;
116     }
117 
118     if (GetConsoleAlias(tmp, buffer, maxlen, _T("cmd.exe")) == 0)
119     {
120         cmd_free(tmp);
121         cmd_free(buffer);
122         return;
123     }
124 
125     in = buffer;
126     out = cmd;
127     while (*in)
128     {
129         if (*in == _T('$'))
130         {
131             Token = position;
132             if (in[1] >= _T('1') && in[1] <= _T('9'))
133             {
134                 /* Copy a single space-delimited token from the input line */
135                 INT num;
136                 for (num = in[1] - _T('1'); num > 0; num--)
137                 {
138                     Token += _tcscspn(Token, _T(" \n"));
139                     Token += _tcsspn(Token, _T(" "));
140                 }
141                 while (!_tcschr(_T(" \n"), *Token))
142                 {
143                     if (out >= &cmd[maxlen - 1])
144                         break;
145                     *out++ = *Token++;
146                 }
147                 in += 2;
148                 continue;
149             }
150             else if (in[1] == _T('*'))
151             {
152                 /* Copy the entire remainder of the line */
153                 while (*Token && *Token != _T('\n'))
154                 {
155                     if (out >= &cmd[maxlen - 1])
156                         break;
157                     *out++ = *Token++;
158                 }
159                 in += 2;
160                 continue;
161             }
162         }
163         if (out >= &cmd[maxlen - 1])
164             break;
165         *out++ = *in++;
166     }
167     *out++ = _T('\n');
168     *out = _T('\0');
169 
170     cmd_free(buffer);
171     cmd_free(tmp);
172 }
173 
174 INT CommandAlias (LPTSTR param)
175 {
176     LPTSTR ptr;
177 
178     if (!_tcsncmp (param, _T("/?"), 2))
179     {
180         ConOutResPaging(TRUE,STRING_ALIAS_HELP);
181         return 0;
182     }
183 
184     nErrorLevel = 0;
185 
186     if (param[0] == _T('\0'))
187     {
188         PrintAlias ();
189         return 0;
190     }
191 
192     nErrorLevel = 0;
193 
194     /* error if no '=' found */
195     if ((ptr = _tcschr (param, _T('='))) == 0)
196     {
197         nErrorLevel = 1;
198         return 1;
199     }
200 
201     /* Split rest into name and substitute */
202     *ptr++ = _T('\0');
203 
204     partstrlwr (param);
205 
206     if (ptr[0] == _T('\0'))
207         AddConsoleAlias(param, NULL, _T("cmd.exe"));
208     else
209         AddConsoleAlias(param, ptr, _T("cmd.exe"));
210 
211     return 0;
212 }
213 #endif
214