[TFTPD] Fix compilation, and use the #define MAX_SERVERS where needed instead of...
[reactos.git] / base / shell / cmd / if.c
1 /*
2 * IF.C - if internal batch command.
3 *
4 *
5 * History:
6 *
7 * 16 Jul 1998 (Hans B Pufal)
8 * started.
9 *
10 * 16 Jul 1998 (John P Price)
11 * Separated commands into individual files.
12 *
13 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
14 * added config.h include
15 *
16 * 07-Jan-1999 (Eric Kohl)
17 * Added help text ("if /?") and cleaned up.
18 *
19 * 21-Jan-1999 (Eric Kohl)
20 * Unicode and redirection ready!
21 *
22 * 01-Sep-1999 (Eric Kohl)
23 * Fixed help text.
24 *
25 * 17-Feb-2001 (ea)
26 * IF DEFINED variable command
27 *
28 * 28-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>
29 * Remove all hardcoded strings in En.rc
30 *
31 */
32
33 #include "precomp.h"
34
35 static INT GenericCmp(INT (*StringCmp)(LPCTSTR, LPCTSTR),
36 LPCTSTR Left, LPCTSTR Right)
37 {
38 TCHAR *end;
39 INT nLeft = _tcstol(Left, &end, 0);
40 if (*end == _T('\0'))
41 {
42 INT nRight = _tcstol(Right, &end, 0);
43 if (*end == _T('\0'))
44 {
45 /* both arguments are numeric */
46 return (nLeft < nRight) ? -1 : (nLeft > nRight);
47 }
48 }
49 return StringCmp(Left, Right);
50 }
51
52 INT cmd_if (LPTSTR param)
53 {
54 TRACE ("cmd_if: (\'%s\')\n", debugstr_aw(param));
55
56 if (!_tcsncmp (param, _T("/?"), 2))
57 {
58 ConOutResPaging(TRUE,STRING_IF_HELP1);
59 return 0;
60 }
61
62 error_syntax(param);
63 return 1;
64 }
65
66 INT ExecuteIf(PARSED_COMMAND *Cmd)
67 {
68 INT result = FALSE; /* when set cause 'then' clause to be executed */
69 LPTSTR param;
70 LPTSTR Left = NULL, Right;
71
72 if (Cmd->If.LeftArg)
73 {
74 Left = DoDelayedExpansion(Cmd->If.LeftArg);
75 if (!Left)
76 return 1;
77 }
78 Right = DoDelayedExpansion(Cmd->If.RightArg);
79 if (!Right)
80 {
81 cmd_free(Left);
82 return 1;
83 }
84
85 if (Cmd->If.Operator == IF_CMDEXTVERSION)
86 {
87 /* IF CMDEXTVERSION n: check if Command Extensions version
88 * is greater or equal to n */
89 DWORD n = _tcstoul(Right, &param, 10);
90 if (*param != _T('\0'))
91 {
92 error_syntax(Right);
93 cmd_free(Right);
94 return 1;
95 }
96 result = (2 >= n);
97 }
98 else if (Cmd->If.Operator == IF_DEFINED)
99 {
100 /* IF DEFINED var: check if environment variable exists */
101 result = (GetEnvVarOrSpecial(Right) != NULL);
102 }
103 else if (Cmd->If.Operator == IF_ERRORLEVEL)
104 {
105 /* IF ERRORLEVEL n: check if last exit code is greater or equal to n */
106 INT n = _tcstol(Right, &param, 10);
107 if (*param != _T('\0'))
108 {
109 error_syntax(Right);
110 cmd_free(Right);
111 return 1;
112 }
113 result = (nErrorLevel >= n);
114 }
115 else if (Cmd->If.Operator == IF_EXIST)
116 {
117 BOOL IsDir;
118 INT Size;
119 WIN32_FIND_DATA f;
120 HANDLE hFind;
121
122 /* IF EXIST filename: check if file exists (wildcards allowed) */
123 StripQuotes(Right);
124
125 Size = _tcslen(Right);
126 IsDir = (Right[Size - 1] == '\\');
127 if (IsDir)
128 Right[Size - 1] = 0;
129
130
131 hFind = FindFirstFile(Right, &f);
132 if (hFind != INVALID_HANDLE_VALUE)
133 {
134 if (IsDir)
135 {
136 result = ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
137 }
138 else
139 {
140 result = TRUE;
141 }
142 FindClose(hFind);
143 }
144
145 if (IsDir)
146 Right[Size - 1] = '\\';
147 }
148 else
149 {
150 /* Do case-insensitive string comparisons if /I specified */
151 INT (*StringCmp)(LPCTSTR, LPCTSTR) =
152 (Cmd->If.Flags & IFFLAG_IGNORECASE) ? _tcsicmp : _tcscmp;
153
154 if (Cmd->If.Operator == IF_STRINGEQ)
155 {
156 /* IF str1 == str2 */
157 result = StringCmp(Left, Right) == 0;
158 }
159 else
160 {
161 result = GenericCmp(StringCmp, Left, Right);
162 switch (Cmd->If.Operator)
163 {
164 case IF_EQU: result = (result == 0); break;
165 case IF_NEQ: result = (result != 0); break;
166 case IF_LSS: result = (result < 0); break;
167 case IF_LEQ: result = (result <= 0); break;
168 case IF_GTR: result = (result > 0); break;
169 case IF_GEQ: result = (result >= 0); break;
170 }
171 }
172 }
173
174 cmd_free(Left);
175 cmd_free(Right);
176
177 if (result ^ ((Cmd->If.Flags & IFFLAG_NEGATE) != 0))
178 {
179 /* full condition was true, do the command */
180 return ExecuteCommand(Cmd->Subcommands);
181 }
182 else
183 {
184 /* full condition was false, do the "else" command if there is one */
185 if (Cmd->Subcommands->Next)
186 return ExecuteCommand(Cmd->Subcommands->Next);
187 return 0;
188 }
189 }
190
191 /* EOF */