1 /* CMDTAB.C (c) Copyright Roger Bowler, 1999-2009 */
2 /* (c) Copyright "Fish" (David B. Trout), 2002-2009 */
3 /* (c) Copyright Jan Jaeger, 2003-2009 */
4 /* Route all Hercules configuration statements */
5 /* and panel commands to the appropriate functions */
6
7 #include "hstdinc.h"
8
9 #define _CMDTAB_C_
10 #define _HENGINE_DLL_
11
12 #include "hercules.h"
13 #include "history.h"
14
15
16 // Handle externally defined commands...
17
18 // (for use in CMDTAB COMMAND entry further below)
19 #define EXT_CMD(xxx_cmd) call_ ## xxx_cmd
20
21 // (for defining routing function immediately below)
22 #define CALL_EXT_CMD(xxx_cmd) \
23 int call_ ## xxx_cmd ( int argc, char *argv[], char *cmdline ) { \
24 return xxx_cmd ( argc, argv, cmdline ); }
25
26 // Externally defined commands routing functions...
27
28 CALL_EXT_CMD ( ptt_cmd )
29 CALL_EXT_CMD ( cache_cmd )
30 CALL_EXT_CMD ( shared_cmd )
31
32 /*-------------------------------------------------------------------*/
33 /* Create forward references for all commands in the command table */
34 /*-------------------------------------------------------------------*/
35 #define _FW_REF
36 #define COMMAND(_stmt, _type, _func, _sdesc, _ldesc) \
37 int (_func)(int argc, char *argv[], char *cmdline);
38 #define CMDABBR(_stmt, _abbr, _type, _func, _sdesc, _ldesc) \
39 int (_func)(int argc, char *argv[], char *cmdline);
40 #include "cmdtab.h"
41 #undef COMMAND
42 #undef CMDABBR
43 #undef _FW_REF
44
45
46 typedef int CMDFUNC(int argc, char *argv[], char *cmdline);
47
48 /* Layout of command routing table */
49 typedef struct _CMDTAB
50 {
51 const char *statement; /* statement */
52 const size_t statminlen; /* min abbreviation */
53 int type; /* statement type */
54 #define DISABLED 0x00 /* disabled statement */
55 #define CONFIG 0x01 /* config statement */
56 #define PANEL 0x02 /* command statement */
57 CMDFUNC *function; /* handler function */
58 const char *shortdesc; /* description */
59 const char *longdesc; /* detaled description */
60 } CMDTAB;
61
62 #define COMMAND(_stmt, _type, _func, _sdesc, _ldesc) \
63 { (_stmt), (0), (_type), (_func), (_sdesc), (_ldesc) },
64 #define CMDABBR(_stmt, _abbr, _type, _func, _sdesc, _ldesc) \
65 { (_stmt), (_abbr), (_type), (_func), (_sdesc), (_ldesc) },
66
67 static CMDTAB cmdtab[] =
68 {
69 #include "cmdtab.h"
70 COMMAND ( NULL, 0, NULL, NULL, NULL ) /* End of table */
71 };
72
73
74 /*-------------------------------------------------------------------*/
75 /* $zapcmd - internal debug - may cause havoc - use with caution */
76 /*-------------------------------------------------------------------*/
zapcmd_cmd(int argc,char * argv[],char * cmdline)77 int zapcmd_cmd(int argc, char *argv[], char *cmdline)
78 {
79 CMDTAB* cmdent;
80 int i;
81
82 UNREFERENCED(cmdline);
83
84 if (argc > 1)
85 {
86 for (cmdent = cmdtab; cmdent->statement; cmdent++)
87 {
88 if(!strcasecmp(argv[1], cmdent->statement))
89 {
90 if(argc > 2)
91 for(i = 2; i < argc; i++)
92 {
93 if(!strcasecmp(argv[i],"Cfg"))
94 cmdent->type |= CONFIG;
95 else
96 if(!strcasecmp(argv[i],"NoCfg"))
97 cmdent->type &= ~CONFIG;
98 else
99 if(!strcasecmp(argv[i],"Cmd"))
100 cmdent->type |= PANEL;
101 else
102 if(!strcasecmp(argv[i],"NoCmd"))
103 cmdent->type &= ~PANEL;
104 else
105 {
106 logmsg(_("Invalid arg: %s: %s %s [(No)Cfg|(No)Cmd]\n"),argv[i],argv[0],argv[1]);
107 return -1;
108 }
109 }
110 else
111 logmsg(_("%s: %s(%sCfg,%sCmd)\n"),argv[0],cmdent->statement,
112 (cmdent->type&CONFIG)?"":"No",(cmdent->type&PANEL)?"":"No");
113 return 0;
114 }
115 }
116 logmsg(_("%s: %s not in command table\n"),argv[0],argv[1]);
117 return -1;
118 }
119 else
120 logmsg(_("Usage: %s <command> [(No)Cfg|(No)Cmd]\n"),argv[0]);
121 return -1;
122 }
123
124 CMDT_DLL_IMPORT
ProcessConfigCommand(int argc,char ** argv,char * cmdline)125 int ProcessConfigCommand (int argc, char **argv, char *cmdline)
126 {
127 CMDTAB* cmdent;
128
129 if (argc)
130 for (cmdent = cmdtab; cmdent->statement; cmdent++)
131 if(cmdent->function && (cmdent->type & CONFIG))
132 if(!strcasecmp(argv[0], cmdent->statement))
133 return cmdent->function(argc, argv, cmdline);
134
135 return -1;
136 }
137
138
139 /*-------------------------------------------------------------------*/
140 /* Main panel command processing function */
141 /*-------------------------------------------------------------------*/
142 int OnOffCommand(int argc, char *argv[], char *cmdline);
143 int ShadowFile_cmd(int argc, char *argv[], char *cmdline);
144
145 int cmd_argc;
146 char* cmd_argv[MAX_ARGS];
147
ProcessPanelCommand(char * pszCmdLine)148 int ProcessPanelCommand (char* pszCmdLine)
149 {
150 CMDTAB* pCmdTab = NULL;
151 char* pszSaveCmdLine = NULL;
152 char* cl = NULL;
153 int rc = -1;
154 int cmdl;
155
156 if (!pszCmdLine || !*pszCmdLine)
157 {
158 /* [enter key] by itself: start the CPU
159 (ignore if not instruction stepping) */
160 if (sysblk.inststep)
161 rc = start_cmd(0,NULL,NULL);
162 goto ProcessPanelCommandExit;
163 }
164
165 #if defined(OPTION_CONFIG_SYMBOLS)
166 /* Perform variable substitution */
167 /* First, set some 'dynamic' symbols to their own values */
168 set_symbol("CUU","$(CUU)");
169 set_symbol("cuu","$(cuu)");
170 set_symbol("CCUU","$(CCUU)");
171 set_symbol("ccuu","$(ccuu)");
172 cl=resolve_symbol_string(pszCmdLine);
173 #else
174 cl=pszCmdLine;
175 #endif
176
177 /* Save unmodified copy of the command line in case
178 its format is unusual and needs customized parsing. */
179 pszSaveCmdLine = strdup(cl);
180
181 /* Parse the command line into its individual arguments...
182 Note: original command line now sprinkled with nulls */
183 parse_args (cl, MAX_ARGS, cmd_argv, &cmd_argc);
184
185 /* If no command was entered (i.e. they entered just a comment
186 (e.g. "# comment")) then ignore their input */
187 if ( !cmd_argv[0] )
188 goto ProcessPanelCommandExit;
189
190 #if defined(OPTION_DYNAMIC_LOAD)
191 if(system_command)
192 if((rc = system_command(cmd_argc, (char**)cmd_argv, pszSaveCmdLine)))
193 goto ProcessPanelCommandExit;
194 #endif
195
196 /* Route standard formatted commands from our routing table... */
197 if (cmd_argc)
198 for (pCmdTab = cmdtab; pCmdTab->function; pCmdTab++)
199 {
200 if(pCmdTab->function && (pCmdTab->type & PANEL))
201 {
202 if (!pCmdTab->statminlen)
203 {
204 if(!strcasecmp(cmd_argv[0], pCmdTab->statement))
205 {
206 rc = pCmdTab->function(cmd_argc, (char**)cmd_argv, pszSaveCmdLine);
207 goto ProcessPanelCommandExit;
208 }
209 }
210 else
211 {
212 cmdl=MAX(strlen(cmd_argv[0]),pCmdTab->statminlen);
213 if(!strncasecmp(cmd_argv[0],pCmdTab->statement,cmdl))
214 {
215 rc = pCmdTab->function(cmd_argc, (char**)cmd_argv, pszSaveCmdLine);
216 goto ProcessPanelCommandExit;
217 }
218 }
219 }
220 }
221
222 /* Route non-standard formatted commands... */
223
224 /* sf commands - shadow file add/remove/set/compress/display */
225 if (0
226 || !strncasecmp(pszSaveCmdLine,"sf+",3)
227 || !strncasecmp(pszSaveCmdLine,"sf-",3)
228 || !strncasecmp(pszSaveCmdLine,"sfc",3)
229 || !strncasecmp(pszSaveCmdLine,"sfd",3)
230 || !strncasecmp(pszSaveCmdLine,"sfk",3)
231 )
232 {
233 rc = ShadowFile_cmd(cmd_argc,(char**)cmd_argv,pszSaveCmdLine);
234 goto ProcessPanelCommandExit;
235 }
236
237 /* x+ and x- commands - turn switches on or off */
238 if ('+' == pszSaveCmdLine[1] || '-' == pszSaveCmdLine[1])
239 {
240 rc = OnOffCommand(cmd_argc,(char**)cmd_argv,pszSaveCmdLine);
241 goto ProcessPanelCommandExit;
242 }
243
244 /* Error: unknown/unsupported command... */
245 ASSERT( cmd_argv[0] );
246
247 logmsg( _("HHCPN139E Command \"%s\" not found; enter '?' for list.\n"),
248 cmd_argv[0] );
249
250 ProcessPanelCommandExit:
251
252 /* Free our saved copy */
253 free(pszSaveCmdLine);
254
255 #if defined(OPTION_CONFIG_SYMBOLS)
256 if (cl != pszCmdLine)
257 free(cl);
258 #endif
259
260 return rc;
261 }
262
263
264 /*-------------------------------------------------------------------*/
265 /* help command - display additional help for a given command */
266 /*-------------------------------------------------------------------*/
HelpCommand(int argc,char * argv[],char * cmdline)267 int HelpCommand(int argc, char *argv[], char *cmdline)
268 {
269 CMDTAB* pCmdTab;
270
271 UNREFERENCED(cmdline);
272
273 if (argc < 2)
274 {
275 logmsg( _("HHCPN140I Valid panel commands are...\n\n") );
276 logmsg( " %-9.9s %s \n", "Command", "Description..." );
277 logmsg( " %-9.9s %s \n", "-------", "-----------------------------------------------" );
278
279 /* List standard formatted commands from our routing table... */
280
281 for (pCmdTab = cmdtab; pCmdTab->statement; pCmdTab++)
282 {
283 if ( (pCmdTab->type & PANEL) && (pCmdTab->shortdesc))
284 logmsg( _(" %-9.9s %s \n"), pCmdTab->statement, pCmdTab->shortdesc );
285 }
286
287 }
288 else
289 {
290 for (pCmdTab = cmdtab; pCmdTab->statement; pCmdTab++)
291 {
292 if (!strcasecmp(pCmdTab->statement,argv[1]) && (pCmdTab->type & PANEL) )
293 {
294 logmsg( _("%s: %s\n"),pCmdTab->statement,pCmdTab->shortdesc);
295 if(pCmdTab->longdesc)
296 logmsg( _("%s\n"),pCmdTab->longdesc );
297 return 0;
298 }
299 }
300
301 logmsg( _("HHCPN142I Command %s not found - no help available\n"),argv[1]);
302 return -1;
303 }
304 return 0;
305 }
306
307
308 int scr_recursion_level();
309
310 #if defined(OPTION_DYNAMIC_LOAD)
panel_command_r(void * cmdline)311 DLL_EXPORT void *panel_command_r (void *cmdline)
312 #else
313 void *panel_command (void *cmdline)
314 #endif
315 {
316 #define MAX_CMD_LEN (32768)
317 char cmd[MAX_CMD_LEN]; /* Copy of panel command */
318 char *pCmdLine;
319 unsigned i;
320 int noredisp;
321
322 pCmdLine = cmdline; ASSERT(pCmdLine);
323 /* every command will be stored in history list */
324 /* except null commands and script commands */
325 if (*pCmdLine != 0 && scr_recursion_level() == 0)
326 history_add(cmdline);
327
328 /* Copy panel command to work area, skipping leading blanks */
329
330 /* If the command starts with a -, then strip it and indicate
331 * we do not want command redisplay
332 */
333
334 noredisp=0;
335 while (*pCmdLine && isspace(*pCmdLine)) pCmdLine++;
336 i = 0;
337 while (*pCmdLine && i < (MAX_CMD_LEN-1))
338 {
339 if(i==0 && *pCmdLine=='-')
340 {
341 noredisp=1;
342 /* and remove blanks again.. */
343 while (*pCmdLine && isspace(*pCmdLine)) pCmdLine++;
344 }
345 else
346 {
347 cmd[i] = *pCmdLine;
348 i++;
349 }
350 pCmdLine++;
351 }
352 cmd[i] = 0;
353
354 /* Ignore null commands (just pressing enter)
355 unless instruction stepping is enabled or
356 commands are being sent to the SCP by default. */
357 if (!sysblk.inststep && (sysblk.cmdtgt == 0) && (0 == cmd[0]))
358 return NULL;
359
360 /* Echo the command to the control panel */
361 if(!noredisp)
362 {
363 logmsg( "%s\n", cmd);
364 }
365
366 #ifdef OPTION_CMDTGT
367 /* check for herc, scp or pscp command */
368 /* Please note that cmdtgt is a hercules command! */
369 /* Changing the target to her in scp mode is done by using herc cmdtgt herc */
370 if(!strncasecmp(cmd, "herc ", 5) || !strncasecmp(cmd, "scp ", 4) || !strncasecmp(cmd, "pscp ", 5))
371 {
372 ProcessPanelCommand(cmd);
373 return NULL;
374 }
375
376 /* Send command to the selected command target */
377 switch(sysblk.cmdtgt)
378 {
379 case 0: // cmdtgt herc
380 {
381 /* Stay compatible */
382 #ifdef _FEATURE_SYSTEM_CONSOLE
383 if(cmd[0] == '.' || cmd[0] == '!')
384 {
385 if(!cmd[1])
386 {
387 cmd[1] = ' ';
388 cmd[2] = 0;
389 }
390 scp_command(cmd + 1, cmd[0] == '!');
391 }
392 else
393 #endif /*_FEATURE_SYSTEM_CONSOLE*/
394 ProcessPanelCommand(cmd);
395 break;
396 }
397 case 1: // cmdtgt scp
398 {
399 if(!cmd[0])
400 {
401 cmd[0] = ' ';
402 cmd[1] = 0;
403 }
404 scp_command(cmd, 0);
405 break;
406 }
407 case 2: // cmdtgt pscp
408 {
409 if(!cmd[0])
410 {
411 cmd[0] = ' ';
412 cmd[1] = 0;
413 }
414 scp_command(cmd, 1);
415 break;
416 }
417 }
418 #else // OPTION_CMDTGT
419 #ifdef _FEATURE_SYSTEM_CONSOLE
420 if ('.' == cmd[0] || '!' == cmd[0])
421 {
422 if (!cmd[1]) { cmd[1]=' '; cmd[2]=0; }
423 scp_command (cmd+1, cmd[0] == '!');
424 return NULL;
425 }
426 #endif /*_FEATURE_SYSTEM_CONSOLE*/
427
428 ProcessPanelCommand(cmd);
429 #endif // OPTION_CMDTGT
430
431 return NULL;
432 }
433