1 /*
2  * PROJECT:    ReactOS NetSh
3  * LICENSE:    GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:    Network Shell main file
5  * COPYRIGHT:  Copyright 2023 Eric Kohl <eric.kohl@reactos.org>
6  */
7 
8 /* INCLUDES *******************************************************************/
9 
10 #include "precomp.h"
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS ******************************************************************/
16 
17 BOOL
18 RunScript(
19     _In_ LPCWSTR filename)
20 {
21     FILE *script;
22     WCHAR tmp_string[MAX_STRING_SIZE];
23 
24     /* Open the file for processing */
25     script = _wfopen(filename, L"r");
26     if (script == NULL)
27     {
28         ConResPrintf(StdErr, IDS_OPEN_FAILED, filename);
29         return FALSE;
30     }
31 
32     /* Read and process the script */
33     while (fgetws(tmp_string, MAX_STRING_SIZE, script) != NULL)
34     {
35         if (InterpretScript(tmp_string) == FALSE)
36         {
37             fclose(script);
38             return FALSE;
39         }
40     }
41 
42     /* Close the file */
43     fclose(script);
44 
45     return TRUE;
46 }
47 
48 /*
49  * wmain():
50  * Main entry point of the application.
51  */
52 int
53 wmain(
54     _In_ int argc,
55     _In_ const LPWSTR argv[])
56 {
57     LPCWSTR tmpBuffer = NULL;
58     LPCWSTR pszFileName = NULL;
59     int index;
60     int result = EXIT_SUCCESS;
61 
62     DPRINT("main()\n");
63 
64     /* Initialize the Console Standard Streams */
65     ConInitStdStreams();
66 
67     /* FIXME: Init code goes here */
68     CreateRootContext();
69     LoadHelpers();
70 
71     if (argc < 2)
72     {
73         /* If there are no command arguments, then go straight to the interpreter */
74         InterpretInteractive();
75     }
76     else
77     {
78         /* If there are command arguments, then process them */
79         for (index = 1; index < argc; index++)
80         {
81             if ((argv[index][0] == '/')||
82                 (argv[index][0] == '-'))
83             {
84                 tmpBuffer = argv[index] + 1;
85             }
86             else
87             {
88                 if (pszFileName != NULL)
89                 {
90                     ConResPuts(StdOut, IDS_APP_USAGE);
91                     result = EXIT_FAILURE;
92                     goto done;
93                 }
94 
95                 /* Run a command from the command line */
96                 if (InterpretCommand((LPWSTR*)&argv[index], argc - index) == FALSE)
97                     result = EXIT_FAILURE;
98                 goto done;
99             }
100 
101             if (_wcsicmp(tmpBuffer, L"?") == 0)
102             {
103                 /* Help option */
104                 ConResPuts(StdOut, IDS_APP_USAGE);
105                 result = EXIT_SUCCESS;
106                 goto done;
107             }
108             else if (_wcsicmp(tmpBuffer, L"a") == 0)
109             {
110                 /* Aliasfile option */
111                 if ((index + 1) < argc)
112                 {
113                     index++;
114                     ConPuts(StdOut, L"\nThe -a option is not implemented yet\n");
115 //                    aliasfile = argv[index];
116                 }
117                 else
118                 {
119                     ConResPuts(StdOut, IDS_APP_USAGE);
120                     result = EXIT_FAILURE;
121                 }
122             }
123             else if (_wcsicmp(tmpBuffer, L"c") == 0)
124             {
125                 /* Context option */
126                 if ((index + 1) < argc)
127                 {
128                     index++;
129                     ConPuts(StdOut, L"\nThe -c option is not implemented yet\n");
130 //                    context = argv[index];
131                 }
132                 else
133                 {
134                     ConResPuts(StdOut, IDS_APP_USAGE);
135                     result = EXIT_FAILURE;
136                 }
137             }
138             else if (_wcsicmp(tmpBuffer, L"f") == 0)
139             {
140                 /* File option */
141                 if ((index + 1) < argc)
142                 {
143                     index++;
144                     pszFileName = argv[index];
145                 }
146                 else
147                 {
148                     ConResPuts(StdOut, IDS_APP_USAGE);
149                     result = EXIT_FAILURE;
150                 }
151             }
152             else if (_wcsicmp(tmpBuffer, L"r") == 0)
153             {
154                 /* Remote option */
155                 if ((index + 1) < argc)
156                 {
157                     index++;
158                     ConPuts(StdOut, L"\nThe -r option is not implemented yet\n");
159 //                    remote = argv[index];
160                 }
161                 else
162                 {
163                     ConResPuts(StdOut, IDS_APP_USAGE);
164                     result = EXIT_FAILURE;
165                 }
166             }
167             else
168             {
169                 /* Invalid command */
170                 ConResPrintf(StdOut, IDS_INVALID_COMMAND, argv[index]);
171                 result = EXIT_FAILURE;
172                 goto done;
173             }
174         }
175 
176         /* Now we process the filename if it exists */
177         if (pszFileName != NULL)
178         {
179             if (RunScript(pszFileName) == FALSE)
180             {
181                 result = EXIT_FAILURE;
182                 goto done;
183             }
184         }
185     }
186 
187 done:
188     /* FIXME: Cleanup code goes here */
189     UnloadHelpers();
190 
191     return result;
192 }
193 
194 
195 DWORD
196 WINAPI
197 MatchEnumTag(
198     _In_ HANDLE hModule,
199     _In_ LPCWSTR pwcArg,
200     _In_ DWORD dwNumArg,
201     _In_ const TOKEN_VALUE *pEnumTable,
202     _Out_ PDWORD pdwValue)
203 {
204     DPRINT1("MatchEnumTag()\n");
205     return 0;
206 }
207 
208 BOOL
209 WINAPI
210 MatchToken(
211     _In_ LPCWSTR pwszUserToken,
212     _In_ LPCWSTR pwszCmdToken)
213 {
214     DPRINT1("MatchToken %S %S\n", pwszUserToken, pwszCmdToken);
215     return (wcsicmp(pwszUserToken, pwszCmdToken) == 0) ? TRUE : FALSE;
216 }
217 
218 DWORD
219 CDECL
220 PrintError(
221     _In_opt_ HANDLE hModule,
222     _In_ DWORD dwErrId,
223     ...)
224 {
225     DPRINT1("PrintError()\n");
226     return 1;
227 }
228 
229 DWORD
230 CDECL
231 PrintMessageFromModule(
232     _In_ HANDLE hModule,
233     _In_ DWORD  dwMsgId,
234     ...)
235 {
236     DPRINT1("PrintMessageFromModule()\n");
237     return 1;
238 }
239 
240 DWORD
241 CDECL
242 PrintMessage(
243     _In_ LPCWSTR pwszFormat,
244     ...)
245 {
246     INT Length;
247     va_list ap;
248 
249     va_start(ap, pwszFormat);
250     Length = ConPrintf(StdOut, pwszFormat);
251     va_end(ap);
252 
253     return Length;
254 }
255