1 /* CGIBIN.C (c)Copyright Jan Jaeger, 2002-2010 */
2 /* HTTP cgi-bin routines */
3
4 /* This file contains all cgi routines that may be executed on the */
5 /* server (ie under control of a hercules thread) */
6 /* */
7 /* */
8 /* All cgi-bin routines are identified in the directory at the end */
9 /* of this file */
10 /* */
11 /* */
12 /* The cgi-bin routines may call the following HTTP service routines */
13 /* */
14 /* char *cgi_variable(WEBBLK *webblk, char *name); */
15 /* This call returns a pointer to the cgi variable requested */
16 /* or a NULL pointer if the variable is not found */
17 /* */
18 /* char *cgi_cookie(WEBBLK *webblk, char *name); */
19 /* This call returns a pointer to the cookie requested */
20 /* or a NULL pointer if the cookie is not found */
21 /* */
22 /* char *cgi_username(WEBBLK *webblk); */
23 /* Returns the username for which the user has been authenticated */
24 /* or NULL if not authenticated (refer to auth/noauth parameter */
25 /* on the HTTPPORT configuration statement) */
26 /* */
27 /* char *cgi_baseurl(WEBBLK *webblk); */
28 /* Returns the url as requested by the user */
29 /* */
30 /* */
31 /* void html_header(WEBBLK *webblk); */
32 /* Sets up the standard html header, and includes the */
33 /* html/header.htmlpart file. */
34 /* */
35 /* void html_footer(WEBBLK *webblk); */
36 /* Sets up the standard html footer, and includes the */
37 /* html/footer.htmlpart file. */
38 /* */
39 /* int html_include(WEBBLK *webblk, char *filename); */
40 /* Includes an html file */
41 /* */
42 /* */
43 /* Jan Jaeger - 28/03/2002 */
44
45 #include "hstdinc.h"
46
47 #define _CGIBIN_C_
48 #define _HENGINE_DLL_
49
50 #include "hercules.h"
51 #include "devtype.h"
52 #include "opcode.h"
53 #include "httpmisc.h"
54
55 #if defined(OPTION_HTTP_SERVER)
56
57
cgibin_reg_control(WEBBLK * webblk)58 void cgibin_reg_control(WEBBLK *webblk)
59 {
60 int i;
61
62 REGS *regs;
63
64 regs = sysblk.regs[sysblk.pcpu];
65 if (!regs) regs = &sysblk.dummyregs;
66
67 html_header(webblk);
68
69 hprintf(webblk->sock, "<H2>Control Registers</H2>\n");
70 hprintf(webblk->sock, "<PRE>\n");
71 if(regs->arch_mode != ARCH_900)
72 for (i = 0; i < 16; i++)
73 hprintf(webblk->sock, "CR%2.2d=%8.8X%s", i, regs->CR_L(i),
74 ((i & 0x03) == 0x03) ? "\n" : "\t");
75 else
76 for (i = 0; i < 16; i++)
77 hprintf(webblk->sock, "CR%1.1X=%16.16" I64_FMT "X%s", i,
78 (U64)regs->CR_G(i), ((i & 0x03) == 0x03) ? "\n" : " ");
79
80 hprintf(webblk->sock, "</PRE>\n");
81
82 html_footer(webblk);
83
84 }
85
86
cgibin_reg_general(WEBBLK * webblk)87 void cgibin_reg_general(WEBBLK *webblk)
88 {
89 int i;
90
91 REGS *regs;
92
93 regs = sysblk.regs[sysblk.pcpu];
94 if (!regs) regs = &sysblk.dummyregs;
95
96 html_header(webblk);
97
98 hprintf(webblk->sock, "<H2>General Registers</H2>\n");
99 hprintf(webblk->sock, "<PRE>\n");
100 if(regs->arch_mode != ARCH_900)
101 for (i = 0; i < 16; i++)
102 hprintf(webblk->sock, "GR%2.2d=%8.8X%s", i, regs->GR_L(i),
103 ((i & 0x03) == 0x03) ? "\n" : "\t");
104 else
105 for (i = 0; i < 16; i++)
106 hprintf(webblk->sock, "GR%1.1X=%16.16" I64_FMT "X%s", i,
107 (U64)regs->GR_G(i), ((i & 0x03) == 0x03) ? "\n" : " ");
108
109 hprintf(webblk->sock, "</PRE>\n");
110
111 html_footer(webblk);
112
113 }
114
115
116 // void copy_psw (REGS *regs, BYTE *addr);
117
cgibin_psw(WEBBLK * webblk)118 void cgibin_psw(WEBBLK *webblk)
119 {
120 REGS *regs;
121 QWORD qword; /* quadword work area */
122
123 char *value;
124 int autorefresh=0;
125 int refresh_interval=5;
126
127 regs = sysblk.regs[sysblk.pcpu];
128 if (!regs) regs = &sysblk.dummyregs;
129
130 html_header(webblk);
131
132
133 if (cgi_variable(webblk,"autorefresh"))
134 autorefresh = 1;
135 else if (cgi_variable(webblk,"norefresh"))
136 autorefresh = 0;
137 else if (cgi_variable(webblk,"refresh"))
138 autorefresh = 1;
139
140 if ((value = cgi_variable(webblk,"refresh_interval")))
141 refresh_interval = atoi(value);
142
143 hprintf(webblk->sock, "<H2>Program Status Word</H2>\n");
144
145 hprintf(webblk->sock, "<FORM method=post>\n");
146
147 if (!autorefresh)
148 {
149 hprintf(webblk->sock, "<INPUT type=submit value=\"Auto Refresh\" name=autorefresh>\n");
150 hprintf(webblk->sock, "Refresh Interval: ");
151 hprintf(webblk->sock, "<INPUT type=text size=2 name=\"refresh_interval\" value=%d>\n",
152 refresh_interval);
153 }
154 else
155 {
156 hprintf(webblk->sock, "<INPUT type=submit value=\"Stop Refreshing\" name=norefresh>\n");
157 hprintf(webblk->sock, "Refresh Interval: %d\n", refresh_interval);
158 hprintf(webblk->sock, "<INPUT type=hidden name=\"refresh_interval\" value=%d>\n",refresh_interval);
159 }
160
161 hprintf(webblk->sock, "</FORM>\n");
162
163 hprintf(webblk->sock, "<P>\n");
164
165 if( regs->arch_mode != ARCH_900 )
166 {
167 copy_psw (regs, qword);
168 hprintf(webblk->sock, "PSW=%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n",
169 qword[0], qword[1], qword[2], qword[3],
170 qword[4], qword[5], qword[6], qword[7]);
171 }
172 else
173 {
174 copy_psw (regs, qword);
175 hprintf(webblk->sock, "PSW=%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X "
176 "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X\n",
177 qword[0], qword[1], qword[2], qword[3],
178 qword[4], qword[5], qword[6], qword[7],
179 qword[8], qword[9], qword[10], qword[11],
180 qword[12], qword[13], qword[14], qword[15]);
181 }
182
183 if (autorefresh)
184 {
185 /* JavaScript to cause automatic page refresh */
186 hprintf(webblk->sock, "<script language=\"JavaScript\">\n");
187 hprintf(webblk->sock, "<!--\nsetTimeout('window.location.replace(\"%s?refresh_interval=%d&refresh=1\")', %d)\n",
188 cgi_baseurl(webblk),
189 refresh_interval,
190 refresh_interval*1000);
191 hprintf(webblk->sock, "//-->\n</script>\n");
192 }
193
194 html_footer(webblk);
195
196 }
197
198
cgibin_syslog(WEBBLK * webblk)199 void cgibin_syslog(WEBBLK *webblk)
200 {
201 int num_bytes;
202 int logbuf_idx;
203 char *logbuf_ptr;
204 char *command;
205 char *value;
206 int autorefresh = 0;
207 int refresh_interval = 5;
208 int msgcount = 22;
209
210 if ((command = cgi_variable(webblk,"command")))
211 {
212 panel_command(command);
213 // Wait a bit before proceeding in case
214 // the command issues a lot of messages
215 usleep(50000);
216 }
217
218 if((value = cgi_variable(webblk,"msgcount")))
219 msgcount = atoi(value);
220 else
221 if((value = cgi_cookie(webblk,"msgcount")))
222 msgcount = atoi(value);
223
224 if ((value = cgi_variable(webblk,"refresh_interval")))
225 refresh_interval = atoi(value);
226
227 if (cgi_variable(webblk,"autorefresh"))
228 autorefresh = 1;
229 else if (cgi_variable(webblk,"norefresh"))
230 autorefresh = 0;
231 else if (cgi_variable(webblk,"refresh"))
232 autorefresh = 1;
233
234 html_header(webblk);
235
236 hprintf(webblk->sock,"<script language=\"JavaScript\">\n"
237 "<!--\n"
238 "document.cookie = \"msgcount=%d\";\n"
239 "//-->\n"
240 "</script>\n",
241 msgcount);
242
243 hprintf(webblk->sock, "<H2>Hercules System Log</H2>\n");
244 hprintf(webblk->sock, "<PRE>\n");
245
246 // Get the index to our desired starting message...
247
248 logbuf_idx = msgcount ? log_line( msgcount ) : -1;
249
250 // Now read the logfile starting at that index. The return
251 // value is the total #of bytes of messages data there is.
252
253 if ( (num_bytes = log_read( &logbuf_ptr, &logbuf_idx, LOG_NOBLOCK )) > 0 )
254 {
255 // Copy the message data to a work buffer for processing.
256 // This is to allow for the possibility, however remote,
257 // that the logfile buffer actually wraps around and over-
258 // lays the message data we were going to display (which
259 // could happen if there's a sudden flood of messages)
260
261 int sav_bytes = num_bytes;
262 char *wrk_bufptr = malloc( num_bytes );
263
264 if ( wrk_bufptr ) strncpy( wrk_bufptr, logbuf_ptr, num_bytes );
265 else wrk_bufptr = logbuf_ptr;
266
267 // We need to convert certain characters that might
268 // possibly be erroneously interpretted as HTML code
269
270 #define AMP_LT "<" // (HTML code for '<')
271 #define AMP_GT ">" // (HTML code for '>')
272 #define AMP_AMP "&" // (HTML code for '&')
273
274 while ( num_bytes-- )
275 {
276 switch ( *wrk_bufptr )
277 {
278 case '<':
279 hwrite( webblk->sock, AMP_LT , sizeof(AMP_LT) );
280 break;
281 case '>':
282 hwrite( webblk->sock, AMP_GT , sizeof(AMP_GT) );
283 break;
284 case '&':
285 hwrite( webblk->sock, AMP_AMP , sizeof(AMP_AMP));
286 break;
287 default:
288 hwrite( webblk->sock, wrk_bufptr , 1 );
289 break;
290 }
291
292 wrk_bufptr++;
293 }
294
295 // (free our work buffer if it's really ours)
296
297 if ( ( wrk_bufptr -= sav_bytes ) != logbuf_ptr )
298 free( wrk_bufptr );
299 }
300
301 hprintf(webblk->sock, "</PRE>\n");
302
303 hprintf(webblk->sock, "<FORM method=post>Command:\n");
304 hprintf(webblk->sock, "<INPUT type=text name=command size=80 autofocus>\n");
305 hprintf(webblk->sock, "<INPUT type=submit name=send value=\"Send\">\n");
306 hprintf(webblk->sock, "<INPUT type=hidden name=%srefresh value=1>\n",autorefresh ? "auto" : "no");
307 hprintf(webblk->sock, "<INPUT type=hidden name=refresh_interval value=%d>\n",refresh_interval);
308 hprintf(webblk->sock, "<INPUT type=hidden name=msgcount value=%d>\n",msgcount);
309 hprintf(webblk->sock, "</FORM>\n<BR>\n");
310
311 hprintf(webblk->sock, "<A name=bottom>\n");
312
313 hprintf(webblk->sock, "<FORM method=post>\n");
314 if(!autorefresh)
315 {
316 hprintf(webblk->sock, "<INPUT type=submit value=\"Auto Refresh\" name=autorefresh>\n");
317 hprintf(webblk->sock, "Refresh Interval: ");
318 hprintf(webblk->sock, "<INPUT type=text name=\"refresh_interval\" size=2 value=%d>\n",
319 refresh_interval);
320 }
321 else
322 {
323 hprintf(webblk->sock, "<INPUT type=submit name=norefresh value=\"Stop Refreshing\">\n");
324 hprintf(webblk->sock, "<INPUT type=hidden name=refresh_interval value=%d>\n",refresh_interval);
325 hprintf(webblk->sock, " Refresh Interval: %2d \n", refresh_interval);
326 }
327 hprintf(webblk->sock, "<INPUT type=hidden name=msgcount value=%d>\n",msgcount);
328 hprintf(webblk->sock, "</FORM>\n");
329
330 hprintf(webblk->sock, "<FORM method=post>\n");
331 hprintf(webblk->sock, "Only show last ");
332 hprintf(webblk->sock, "<INPUT type=text name=msgcount size=3 value=%d>",msgcount);
333 hprintf(webblk->sock, " lines (zero for all loglines)\n");
334 hprintf(webblk->sock, "<INPUT type=hidden name=%srefresh value=1>\n",autorefresh ? "auto" : "no");
335 hprintf(webblk->sock, "<INPUT type=hidden name=refresh_interval value=%d>\n",refresh_interval);
336 hprintf(webblk->sock, "</FORM>\n");
337
338 if (autorefresh)
339 {
340 /* JavaScript to cause automatic page refresh */
341 hprintf(webblk->sock, "<script language=\"JavaScript\">\n");
342 hprintf(webblk->sock, "<!--\nsetTimeout('window.location.replace(\"%s"
343 "?refresh_interval=%d"
344 "&refresh=1"
345 "&msgcount=%d"
346 "\")', %d)\n",
347 cgi_baseurl(webblk),
348 refresh_interval,
349 msgcount,
350 refresh_interval*1000);
351 hprintf(webblk->sock, "//-->\n</script>\n");
352 }
353
354 html_footer(webblk);
355
356 }
357
358
cgibin_debug_registers(WEBBLK * webblk)359 void cgibin_debug_registers(WEBBLK *webblk)
360 {
361 int i, cpu = 0;
362 int select_gr, select_cr, select_ar;
363 char *value;
364 REGS *regs;
365
366 if((value = cgi_variable(webblk,"cpu")))
367 cpu = atoi(value);
368
369 if((value = cgi_variable(webblk,"select_gr")) && *value == 'S')
370 select_gr = 1;
371 else
372 select_gr = 0;
373
374 if((value = cgi_variable(webblk,"select_cr")) && *value == 'S')
375 select_cr = 1;
376 else
377 select_cr = 0;
378
379 if((value = cgi_variable(webblk,"select_ar")) && *value == 'S')
380 select_ar = 1;
381 else
382 select_ar = 0;
383
384 /* Validate cpu number */
385 if (cpu < 0 || cpu >= MAX_CPU || !IS_CPU_ONLINE(cpu))
386 for (cpu = 0; cpu < MAX_CPU; cpu++)
387 if(IS_CPU_ONLINE(cpu))
388 break;
389
390 if(cpu < MAX_CPU)
391 regs = sysblk.regs[cpu];
392 else
393 regs = sysblk.regs[sysblk.pcpu];
394
395 if (!regs) regs = &sysblk.dummyregs;
396
397 if((value = cgi_variable(webblk,"alter_gr")) && *value == 'A')
398 {
399 for(i = 0; i < 16; i++)
400 {
401 char regname[16];
402 sprintf(regname,"alter_gr%d",i);
403 if((value = cgi_variable(webblk,regname)))
404 {
405 if(regs->arch_mode != ARCH_900)
406 sscanf(value,"%"I32_FMT"x",&(regs->GR_L(i)));
407 else
408 sscanf(value,"%"I64_FMT"x",&(regs->GR_G(i)));
409 }
410 }
411 }
412
413 if((value = cgi_variable(webblk,"alter_cr")) && *value == 'A')
414 {
415 for(i = 0; i < 16; i++)
416 {
417 char regname[16];
418 sprintf(regname,"alter_cr%d",i);
419 if((value = cgi_variable(webblk,regname)))
420 {
421 if(regs->arch_mode != ARCH_900)
422 sscanf(value,"%"I32_FMT"x",&(regs->CR_L(i)));
423 else
424 sscanf(value,"%"I64_FMT"x",&(regs->CR_G(i)));
425 }
426 }
427 }
428
429 if((value = cgi_variable(webblk,"alter_ar")) && *value == 'A')
430 {
431 for(i = 0; i < 16; i++)
432 {
433 char regname[16];
434 sprintf(regname,"alter_ar%d",i);
435 if((value = cgi_variable(webblk,regname)))
436 sscanf(value,"%x",&(regs->AR(i)));
437 }
438 }
439
440 html_header(webblk);
441
442 hprintf(webblk->sock,"<form method=post>\n"
443 "<select type=submit name=cpu>\n");
444
445 for(i = 0; i < MAX_CPU; i++)
446 if(IS_CPU_ONLINE(i))
447 hprintf(webblk->sock,"<option value=%d%s>CPU%4.4X</option>\n",
448 i,i==cpu?" selected":"",i);
449
450 hprintf(webblk->sock,"</select>\n"
451 "<input type=submit name=selcpu value=\"Select\">\n"
452 "<input type=hidden name=cpu value=%d>\n"
453 "<input type=hidden name=select_gr value=%c>\n"
454 "<input type=hidden name=select_cr value=%c>\n"
455 "<input type=hidden name=select_ar value=%c>\n",
456 cpu, select_gr?'S':'H',select_cr?'S':'H',select_ar?'S':'H');
457 hprintf(webblk->sock,"Mode: %s\n",get_arch_mode_string(regs));
458 hprintf(webblk->sock,"</form>\n");
459
460 if(!select_gr)
461 {
462 hprintf(webblk->sock,"<form method=post>\n"
463 "<input type=submit name=select_gr "
464 "value=\"Select General Registers\">\n"
465 "<input type=hidden name=cpu value=%d>\n"
466 "<input type=hidden name=select_cr value=%c>\n"
467 "<input type=hidden name=select_ar value=%c>\n"
468 "</form>\n",cpu,select_cr?'S':'H',select_ar?'S':'H');
469 }
470 else
471 {
472 hprintf(webblk->sock,"<form method=post>\n"
473 "<input type=submit name=select_gr "
474 "value=\"Hide General Registers\">\n"
475 "<input type=hidden name=cpu value=%d>\n"
476 "<input type=hidden name=select_cr value=%c>\n"
477 "<input type=hidden name=select_ar value=%c>\n"
478 "</form>\n",cpu,select_cr?'S':'H',select_ar?'S':'H');
479
480 hprintf(webblk->sock,"<form method=post>\n"
481 "<table>\n");
482 for(i = 0; i < 16; i++)
483 {
484 if(regs->arch_mode != ARCH_900)
485 hprintf(webblk->sock,"%s<td>GR%d</td><td><input type=text name=alter_gr%d size=8 "
486 "value=%8.8X></td>\n%s",
487 (i&3)==0?"<tr>\n":"",i,i,regs->GR_L(i),((i&3)==3)?"</tr>\n":"");
488 else
489 hprintf(webblk->sock,"%s<td>GR%d</td><td><input type=text name=alter_gr%d size=16 "
490 "value=%16.16" I64_FMT "X></td>\n%s",
491 (i&3)==0?"<tr>\n":"",i,i,(U64)regs->GR_G(i),((i&3)==3)?"</tr>\n":"");
492 }
493 hprintf(webblk->sock,"</table>\n"
494 "<input type=submit name=refresh value=\"Refresh\">\n"
495 "<input type=submit name=alter_gr value=\"Alter\">\n"
496 "<input type=hidden name=cpu value=%d>\n"
497 "<input type=hidden name=select_gr value=S>\n"
498 "<input type=hidden name=select_cr value=%c>\n"
499 "<input type=hidden name=select_ar value=%c>\n"
500 "</form>\n",cpu,select_cr?'S':'H',select_ar?'S':'H');
501 }
502
503
504 if(!select_cr)
505 {
506 hprintf(webblk->sock,"<form method=post>\n"
507 "<input type=submit name=select_cr "
508 "value=\"Select Control Registers\">\n"
509 "<input type=hidden name=cpu value=%d>\n"
510 "<input type=hidden name=select_gr value=%c>\n"
511 "<input type=hidden name=select_ar value=%c>\n"
512 "</form>\n",cpu,select_gr?'S':'H',select_ar?'S':'H');
513 }
514 else
515 {
516 hprintf(webblk->sock,"<form method=post>\n"
517 "<input type=submit name=select_cr "
518 "value=\"Hide Control Registers\">\n"
519 "<input type=hidden name=cpu value=%d>\n"
520 "<input type=hidden name=select_gr value=%c>\n"
521 "<input type=hidden name=select_ar value=%c>\n"
522 "</form>\n",cpu,select_gr?'S':'H',select_ar?'S':'H');
523
524 hprintf(webblk->sock,"<form method=post>\n"
525 "<table>\n");
526 for(i = 0; i < 16; i++)
527 {
528 if(regs->arch_mode != ARCH_900)
529 hprintf(webblk->sock,"%s<td>CR%d</td><td><input type=text name=alter_cr%d size=8 "
530 "value=%8.8X></td>\n%s",
531 (i&3)==0?"<tr>\n":"",i,i,regs->CR_L(i),((i&3)==3)?"</tr>\n":"");
532 else
533 hprintf(webblk->sock,"%s<td>CR%d</td><td><input type=text name=alter_cr%d size=16 "
534 "value=%16.16" I64_FMT "X></td>\n%s",
535 (i&3)==0?"<tr>\n":"",i,i,(U64)regs->CR_G(i),((i&3)==3)?"</tr>\n":"");
536 }
537 hprintf(webblk->sock,"</table>\n"
538 "<input type=submit name=refresh value=\"Refresh\">\n"
539 "<input type=submit name=alter_cr value=\"Alter\">\n"
540 "<input type=hidden name=cpu value=%d>\n"
541 "<input type=hidden name=select_cr value=S>\n"
542 "<input type=hidden name=select_gr value=%c>\n"
543 "<input type=hidden name=select_ar value=%c>\n"
544 "</form>\n",cpu,select_gr?'S':'H',select_ar?'S':'H');
545 }
546
547
548 if(regs->arch_mode != ARCH_370)
549 {
550 if(!select_ar)
551 {
552 hprintf(webblk->sock,"<form method=post>\n"
553 "<input type=submit name=select_ar "
554 "value=\"Select Access Registers\">\n"
555 "<input type=hidden name=cpu value=%d>\n"
556 "<input type=hidden name=select_gr value=%c>\n"
557 "<input type=hidden name=select_cr value=%c>\n"
558 "</form>\n",cpu,select_gr?'S':'H',select_cr?'S':'H');
559 }
560 else
561 {
562 hprintf(webblk->sock,"<form method=post>\n"
563 "<input type=submit name=select_ar "
564 "value=\"Hide Access Registers\">\n"
565 "<input type=hidden name=cpu value=%d>\n"
566 "<input type=hidden name=select_gr value=%c>\n"
567 "<input type=hidden name=select_cr value=%c>\n"
568 "</form>\n",cpu,select_gr?'S':'H',select_cr?'S':'H');
569
570 hprintf(webblk->sock,"<form method=post>\n"
571 "<table>\n");
572 for(i = 0; i < 16; i++)
573 {
574 hprintf(webblk->sock,"%s<td>AR%d</td><td><input type=text name=alter_ar%d size=8 "
575 "value=%8.8X></td>\n%s",
576 (i&3)==0?"<tr>\n":"",i,i,regs->AR(i),((i&3)==3)?"</tr>\n":"");
577 }
578 hprintf(webblk->sock,"</table>\n"
579 "<input type=submit name=refresh value=\"Refresh\">\n"
580 "<input type=submit name=alter_ar value=\"Alter\">\n"
581 "<input type=hidden name=cpu value=%d>\n"
582 "<input type=hidden name=select_gr value=%c>\n"
583 "<input type=hidden name=select_cr value=%c>\n"
584 "<input type=hidden name=select_ar value=S>\n"
585 "</form>\n",cpu,select_gr?'S':'H',select_cr?'S':'H');
586 }
587 }
588
589 html_footer(webblk);
590
591 }
592
593
cgibin_debug_storage(WEBBLK * webblk)594 void cgibin_debug_storage(WEBBLK *webblk)
595 {
596 int i, j;
597 char *value;
598 U32 addr = 0;
599
600 /* INCOMPLETE
601 * no storage alter
602 * no storage type (abs/real/prim virt/sec virt/access reg virt)
603 * no cpu selection for storage other then abs
604 */
605
606 if((value = cgi_variable(webblk,"alter_a0")))
607 sscanf(value,"%x",&addr);
608
609 addr &= ~0x0F;
610
611 html_header(webblk);
612
613
614 hprintf(webblk->sock,"<form method=post>\n"
615 "<table>\n");
616
617 if(addr > sysblk.mainsize || (addr + 128) > sysblk.mainsize)
618 addr = sysblk.mainsize - 128;
619
620 for(i = 0; i < 128;)
621 {
622 if(i == 0)
623 hprintf(webblk->sock,"<tr>\n"
624 "<td><input type=text name=alter_a0 size=8 value=%8.8X>"
625 "<input type=hidden name=alter_a1 value=%8.8X></td>\n"
626 "<td><input type=submit name=refresh value=\"Refresh\"></td>\n",
627 i + addr, i + addr);
628 else
629 hprintf(webblk->sock,"<tr>\n"
630 "<td align=center>%8.8X</td>\n"
631 "<td></td>\n",
632 i + addr);
633
634 for(j = 0; j < 4; i += 4, j++)
635 {
636 U32 m;
637 FETCH_FW(m,sysblk.mainstor + i + addr);
638 hprintf(webblk->sock,"<td><input type=text name=alter_m%d size=8 value=%8.8X></td>\n",i,m);
639 }
640
641 hprintf(webblk->sock,"</tr>\n");
642 }
643
644 hprintf(webblk->sock,"</table>\n"
645 "</form>\n");
646 html_footer(webblk);
647
648 }
649
650
cgibin_ipl(WEBBLK * webblk)651 void cgibin_ipl(WEBBLK *webblk)
652 {
653 int i;
654 char *value;
655 DEVBLK *dev;
656 U16 ipldev;
657 int iplcpu;
658 U32 doipl;
659
660 html_header(webblk);
661
662 hprintf(webblk->sock,"<h1>Perform Initial Program Load</h1>\n");
663
664 if(cgi_variable(webblk,"doipl"))
665 doipl = 1;
666 else
667 doipl = 0;
668
669 if((value = cgi_variable(webblk,"device")))
670 sscanf(value,"%hx",&ipldev);
671 else
672 ipldev = sysblk.ipldev;
673
674 if((value = cgi_variable(webblk,"cpu")))
675 sscanf(value,"%x",&iplcpu);
676 else
677 iplcpu = sysblk.iplcpu;
678
679 if((value = cgi_variable(webblk,"loadparm")))
680 set_loadparm(value);
681
682 /* Validate CPU number */
683 if(iplcpu >= MAX_CPU)
684 doipl = 0;
685
686 if(!doipl)
687 {
688 /* Present IPL parameters */
689 hprintf(webblk->sock,"<form method=post>\n"
690 "<select type=submit name=cpu>\n");
691
692 for(i = 0; i < MAX_CPU; i++)
693 if(IS_CPU_ONLINE(i))
694 hprintf(webblk->sock,"<option value=%4.4X%s>CPU%4.4X</option>\n",
695 i, ((sysblk.regs[i]->cpuad == iplcpu) ? " selected" : ""), i);
696
697 hprintf(webblk->sock,"</select>\n"
698 "<select type=submit name=device>\n");
699
700 for(dev = sysblk.firstdev; dev; dev = dev->nextdev)
701 if(dev->pmcw.flag5 & PMCW5_V)
702 hprintf(webblk->sock,"<option value=%4.4X%s>DEV%4.4X</option>\n",
703 dev->devnum, ((dev->devnum == ipldev) ? " selected" : ""), dev->devnum);
704
705 hprintf(webblk->sock,"</select>\n");
706
707 hprintf(webblk->sock,"Loadparm:<input type=text name=loadparm size=8 value=\"%s\">\n", str_loadparm());
708
709 hprintf(webblk->sock,"<input type=submit name=doipl value=\"IPL\">\n"
710 "</form>\n");
711
712 }
713 else
714 {
715 OBTAIN_INTLOCK(NULL);
716 /* Perform IPL function */
717 if( load_ipl(0, ipldev, iplcpu,0) )
718 {
719 hprintf(webblk->sock,"<h3>IPL failed, see the "
720 "<a href=\"syslog#bottom\">system log</a> "
721 "for details</h3>\n");
722 }
723 else
724 {
725 hprintf(webblk->sock,"<h3>IPL completed</h3>\n");
726 }
727 RELEASE_INTLOCK(NULL);
728 }
729
730 html_footer(webblk);
731
732 }
733
734
cgibin_debug_device_list(WEBBLK * webblk)735 void cgibin_debug_device_list(WEBBLK *webblk)
736 {
737 DEVBLK *dev;
738 char *class;
739
740 html_header(webblk);
741
742 hprintf(webblk->sock,"<h2>Attached Device List</h2>\n"
743 "<table>\n"
744 "<tr><th>Number</th>"
745 "<th>Subchannel</th>"
746 "<th>Class</th>"
747 "<th>Type</th>"
748 "<th>Status</th></tr>\n");
749
750 for(dev = sysblk.firstdev; dev; dev = dev->nextdev)
751 if(dev->pmcw.flag5 & PMCW5_V)
752 {
753 (dev->hnd->query)(dev, &class, 0, NULL);
754
755 hprintf(webblk->sock,"<tr>"
756 "<td>%4.4X</td>"
757 "<td><a href=\"detail?subchan=%4.4X\">%4.4X</a></td>"
758 "<td>%s</td>"
759 "<td>%4.4X</td>"
760 "<td>%s%s%s</td>"
761 "</tr>\n",
762 dev->devnum,
763 dev->subchan,dev->subchan,
764 class,
765 dev->devtype,
766 (dev->fd > 2 ? "open " : ""),
767 (dev->busy ? "busy " : ""),
768 (IOPENDING(dev) ? "pending " : ""));
769 }
770
771 hprintf(webblk->sock,"</table>\n");
772
773 html_footer(webblk);
774
775 }
776
777
cgibin_debug_device_detail(WEBBLK * webblk)778 void cgibin_debug_device_detail(WEBBLK *webblk)
779 {
780 DEVBLK *sel, *dev = NULL;
781 char *value;
782 int subchan;
783
784 html_header(webblk);
785
786 if((value = cgi_variable(webblk,"subchan"))
787 && sscanf(value,"%x",&subchan) == 1)
788 for(dev = sysblk.firstdev; dev; dev = dev->nextdev)
789 if(dev->subchan == subchan)
790 break;
791
792 hprintf(webblk->sock,"<h3>Subchannel Details</h3>\n");
793
794 hprintf(webblk->sock,"<form method=post>\n"
795 "<select type=submit name=subchan>\n");
796
797 for(sel = sysblk.firstdev; sel; sel = sel->nextdev)
798 {
799 hprintf(webblk->sock,"<option value=%4.4X%s>Subchannel %4.4X",
800 sel->subchan, ((sel == dev) ? " selected" : ""), sel->subchan);
801 if(sel->pmcw.flag5 & PMCW5_V)
802 hprintf(webblk->sock," Device %4.4X</option>\n",sel->devnum);
803 else
804 hprintf(webblk->sock,"</option>\n");
805 }
806
807 hprintf(webblk->sock,"</select>\n"
808 "<input type=submit value=\"Select / Refresh\">\n"
809 "</form>\n");
810
811 if(dev)
812 {
813
814 hprintf(webblk->sock,"<table border>\n"
815 "<caption align=left>"
816 "<h3>Path Management Control Word</h3>"
817 "</caption>\n");
818
819 hprintf(webblk->sock,"<tr><th colspan=32>Interruption Parameter</th></tr>\n");
820
821 hprintf(webblk->sock,"<tr><td colspan=32>%2.2X%2.2X%2.2X%2.2X</td></tr>\n",
822 dev->pmcw.intparm[0], dev->pmcw.intparm[1],
823 dev->pmcw.intparm[2], dev->pmcw.intparm[3]);
824
825 hprintf(webblk->sock,"<tr><th>Q</th>"
826 "<th>0</th>"
827 "<th colspan=3>ISC</th>"
828 "<th colspan=2>00</th>"
829 "<th>A</th>"
830 "<th>E</th>"
831 "<th colspan=2>LM</th>"
832 "<th colspan=2>MM</th>"
833 "<th>D</th>"
834 "<th>T</th>"
835 "<th>V</th>"
836 "<th colspan=16>DEVNUM</th></tr>\n");
837
838 hprintf(webblk->sock,"<tr><td>%d</td>"
839 "<td></td>"
840 "<td colspan=3>%d</td>"
841 "<td colspan=2></td>"
842 "<td>%d</td>"
843 "<td>%d</td>"
844 "<td colspan=2>%d%d</td>"
845 "<td colspan=2>%d%d</td>"
846 "<td>%d</td>"
847 "<td>%d</td>"
848 "<td>%d</td>"
849 "<td colspan=16>%2.2X%2.2X</td></tr>\n",
850 ((dev->pmcw.flag4 & PMCW4_Q) >> 7),
851 ((dev->pmcw.flag4 & PMCW4_ISC) >> 3),
852 (dev->pmcw.flag4 & 1),
853 ((dev->pmcw.flag5 >> 7) & 1),
854 ((dev->pmcw.flag5 >> 6) & 1),
855 ((dev->pmcw.flag5 >> 5) & 1),
856 ((dev->pmcw.flag5 >> 4) & 1),
857 ((dev->pmcw.flag5 >> 3) & 1),
858 ((dev->pmcw.flag5 >> 2) & 1),
859 ((dev->pmcw.flag5 >> 1) & 1),
860 (dev->pmcw.flag5 & 1),
861 dev->pmcw.devnum[0],
862 dev->pmcw.devnum[1]);
863
864 hprintf(webblk->sock,"<tr><th colspan=8>LPM</th>"
865 "<th colspan=8>PNOM</th>"
866 "<th colspan=8>LPUM</th>"
867 "<th colspan=8>PIM</th></tr>\n");
868
869 hprintf(webblk->sock,"<tr><td colspan=8>%2.2X</td>"
870 "<td colspan=8>%2.2X</td>"
871 "<td colspan=8>%2.2X</td>"
872 "<td colspan=8>%2.2X</td></tr>\n",
873 dev->pmcw.lpm,
874 dev->pmcw.pnom,
875 dev->pmcw.lpum,
876 dev->pmcw.pim);
877
878 hprintf(webblk->sock,"<tr><th colspan=16>MBI</th>"
879 "<th colspan=8>POM</th>"
880 "<th colspan=8>PAM</th></tr>\n");
881
882 hprintf(webblk->sock,"<tr><td colspan=16>%2.2X%2.2X</td>"
883 "<td colspan=8>%2.2X</td>"
884 "<td colspan=8>%2.2X</td></tr>\n",
885 dev->pmcw.mbi[0],
886 dev->pmcw.mbi[1],
887 dev->pmcw.pom,
888 dev->pmcw.pam);
889
890 hprintf(webblk->sock,"<tr><th colspan=8>CHPID=0</th>"
891 "<th colspan=8>CHPID=1</th>"
892 "<th colspan=8>CHPID=2</th>"
893 "<th colspan=8>CHPID=3</th></tr>\n");
894
895 hprintf(webblk->sock,"<tr><td colspan=8>%2.2X</td>"
896 "<td colspan=8>%2.2X</td>"
897 "<td colspan=8>%2.2X</td>"
898 "<td colspan=8>%2.2X</td></tr>\n",
899 dev->pmcw.chpid[0],
900 dev->pmcw.chpid[1],
901 dev->pmcw.chpid[2],
902 dev->pmcw.chpid[3]);
903
904 hprintf(webblk->sock,"<tr><th colspan=8>CHPID=4</th>"
905 "<th colspan=8>CHPID=5</th>"
906 "<th colspan=8>CHPID=6</th>"
907 "<th colspan=8>CHPID=7</th></tr>\n");
908
909 hprintf(webblk->sock,"<tr><td colspan=8>%2.2X</td>"
910 "<td colspan=8>%2.2X</td>"
911 "<td colspan=8>%2.2X</td>"
912 "<td colspan=8>%2.2X</td></tr>\n",
913 dev->pmcw.chpid[4],
914 dev->pmcw.chpid[5],
915 dev->pmcw.chpid[6],
916 dev->pmcw.chpid[7]);
917
918 hprintf(webblk->sock,"<tr><th colspan=8>ZONE</th>"
919 "<th colspan=5>00000</th>"
920 "<th colspan=3>VISC</th>"
921 "<th colspan=8>00000000</th>"
922 "<th>I</th>"
923 "<th colspan=6>000000</th>"
924 "<th>S</th></tr>\n");
925
926 hprintf(webblk->sock,"<tr><td colspan=8>%2.2X</td>"
927 "<td colspan=5></td>"
928 "<td colspan=3>%d</td>"
929 "<td colspan=8></td>"
930 "<td>%d</td>"
931 "<td colspan=6></td>"
932 "<td>%d</td></tr>\n",
933 dev->pmcw.zone,
934 (dev->pmcw.flag25 & PMCW25_VISC),
935 (dev->pmcw.flag27 & PMCW27_I) >> 7,
936 (dev->pmcw.flag27 & PMCW27_S));
937
938 hprintf(webblk->sock,"</table>\n");
939
940 }
941
942 html_footer(webblk);
943
944 }
945
946
cgibin_debug_misc(WEBBLK * webblk)947 void cgibin_debug_misc(WEBBLK *webblk)
948 {
949 int zone;
950
951 html_header(webblk);
952
953 hprintf(webblk->sock,"<h2>Miscellaneous Registers<h2>\n");
954
955
956 hprintf(webblk->sock,"<table border>\n"
957 "<caption align=left>"
958 "<h3>Zone related Registers</h3>"
959 "</caption>\n");
960
961 hprintf(webblk->sock,"<tr><th>Zone</th>"
962 "<th>CS Origin</th>"
963 "<th>CS Limit</th>"
964 "<th>ES Origin</th>"
965 "<th>ES Limit</th>"
966 "<th>Measurement Block</th>"
967 "<th>Key</th></tr>\n");
968
969 for(zone = 0; zone < FEATURE_SIE_MAXZONES; zone++)
970 {
971 hprintf(webblk->sock,"<tr><td>%2.2X</td>"
972 "<td>%8.8X</td>"
973 "<td>%8.8X</td>"
974 "<td>%8.8X</td>"
975 "<td>%8.8X</td>"
976 "<td>%8.8X</td>"
977 "<td>%2.2X</td></tr>\n",
978 zone,
979 #if defined(_FEATURE_SIE)
980 (U32)sysblk.zpb[zone].mso << 20,
981 ((U32)sysblk.zpb[zone].msl << 20) | 0xFFFFF,
982 (U32)sysblk.zpb[zone].eso << 20,
983 ((U32)sysblk.zpb[zone].esl << 20) | 0xFFFFF,
984 (U32)sysblk.zpb[zone].mbo,
985 sysblk.zpb[zone].mbk
986 #else
987 0, 0, 0, 0, 0, 0
988 #endif
989 );
990 }
991
992 hprintf(webblk->sock,"</table>\n");
993
994
995 hprintf(webblk->sock,"<table border>\n"
996 "<caption align=left>"
997 "<h3>Alternate Measurement</h3>"
998 "</caption>\n");
999
1000 hprintf(webblk->sock,"<tr><th>Measurement Block</th>"
1001 "<th>Key</th></tr>\n");
1002
1003 hprintf(webblk->sock,"<tr><td>%8.8X</td>"
1004 "<td>%2.2X</td></tr>\n",
1005 (U32)sysblk.mbo,
1006 sysblk.mbk);
1007
1008 hprintf(webblk->sock,"</table>\n");
1009
1010
1011 hprintf(webblk->sock,"<table border>\n"
1012 "<caption align=left>"
1013 "<h3>Address Limit Register</h3>"
1014 "</caption>\n");
1015
1016 hprintf(webblk->sock,"<tr><td>%8.8X</td></tr>\n",
1017 (U32)sysblk.addrlimval);
1018
1019 hprintf(webblk->sock,"</table>\n");
1020
1021 html_footer(webblk);
1022
1023 }
1024
1025
cgibin_configure_cpu(WEBBLK * webblk)1026 void cgibin_configure_cpu(WEBBLK *webblk)
1027 {
1028 int i,j;
1029
1030 html_header(webblk);
1031
1032 hprintf(webblk->sock,"<h1>Configure CPU</h1>\n");
1033
1034 for(i = 0; i < MAX_CPU; i++)
1035 {
1036 char cpuname[8], *cpustate;
1037 int cpuonline = -1;
1038
1039 sprintf(cpuname,"cpu%d",i);
1040 if((cpustate = cgi_variable(webblk,cpuname)))
1041 sscanf(cpustate,"%d",&cpuonline);
1042
1043 OBTAIN_INTLOCK(NULL);
1044
1045 switch(cpuonline) {
1046
1047 case 0:
1048 if(IS_CPU_ONLINE(i))
1049 deconfigure_cpu(i);
1050 break;
1051
1052 case 1:
1053 if(!IS_CPU_ONLINE(i))
1054 configure_cpu(i);
1055 break;
1056 }
1057
1058 RELEASE_INTLOCK(NULL);
1059 }
1060
1061 for(i = 0; i < MAX_CPU; i++)
1062 {
1063 hprintf(webblk->sock,"<p>CPU%4.4X\n"
1064 "<form method=post>\n"
1065 "<select type=submit name=cpu%d>\n",i,i);
1066
1067 for(j = 0; j < 2; j++)
1068 hprintf(webblk->sock,"<option value=%d%s>%sline</option>\n",
1069 j, ((j!=0) == (IS_CPU_ONLINE(i)!=0)) ? " selected" : "", (j) ? "On" : "Off");
1070
1071 hprintf(webblk->sock,"</select>\n"
1072 "<input type=submit value=Update>\n"
1073 "</form>\n");
1074 }
1075
1076 html_footer(webblk);
1077
1078 }
1079
1080
cgibin_debug_version_info(WEBBLK * webblk)1081 void cgibin_debug_version_info(WEBBLK *webblk)
1082 {
1083 html_header(webblk);
1084
1085 hprintf(webblk->sock,"<h1>Hercules Version Information</h1>\n"
1086 "<pre>\n");
1087 display_version_2(NULL,"Hercules HTTP Server ", TRUE,webblk->sock);
1088 hprintf(webblk->sock,"</pre>\n");
1089
1090 html_footer(webblk);
1091
1092 }
1093
1094 #if defined(OPTION_MIPS_COUNTING)
1095 /* contributed by Tim Pinkawa [timpinkawa@gmail.com] */
cgibin_xml_rates_info(WEBBLK * webblk)1096 void cgibin_xml_rates_info(WEBBLK *webblk)
1097 {
1098 hprintf(webblk->sock,"Expires: 0\n");
1099 hprintf(webblk->sock,"Content-type: text/xml;\n\n"); /* XML document */
1100
1101 hprintf(webblk->sock,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1102 hprintf(webblk->sock,"<hercules>\n");
1103 hprintf(webblk->sock,"\t<arch>%d</arch>\n", sysblk.arch_mode);
1104 hprintf(webblk->sock,"\t<mips>%.1d.%.2d</mips>\n",
1105 sysblk.mipsrate / 1000000, (sysblk.mipsrate % 1000000) / 10000);
1106 hprintf(webblk->sock,"\t<siosrate>%d</siosrate>\n", sysblk.siosrate);
1107 hprintf(webblk->sock,"</hercules>\n");
1108 }
1109 #endif /*defined(OPTION_MIPS_COUNTING)*/
1110
1111
1112 // cgibin_hwrite: helper function to output HTML
1113
cgibin_hwrite(WEBBLK * webblk,char * msg,int msg_len)1114 void cgibin_hwrite(WEBBLK *webblk, char *msg, int msg_len)
1115 {
1116 char buffer[1024];
1117 char *new_str;
1118
1119 int buf_used = 0;
1120 int new_len;
1121 int i;
1122
1123
1124 if ((msg == NULL) || (msg_len < 1))
1125 return;
1126
1127 // Output message, accounting for http special characters.
1128
1129 // Method: rather than doing an hwrite for every character,
1130 // buffer the message, expanding special characters.
1131 // Output the buffer when full, then reuse it.
1132
1133 // Note that sizeof(X) where X is a #define string literal is 1 greater
1134 // than strlen(X).
1135
1136 for (i = 0; i < msg_len; i++)
1137 {
1138 switch (msg[i])
1139 {
1140 case '<':
1141 new_len = sizeof(AMP_LT) - 1;
1142 new_str = AMP_LT;
1143 break;
1144 case '>':
1145 new_len = sizeof(AMP_GT) - 1;
1146 new_str = AMP_GT;
1147 break;
1148 case '&':
1149 new_len = sizeof(AMP_AMP) - 1;
1150 new_str = AMP_AMP;
1151 break;
1152 default:
1153 new_len = 1;
1154 new_str = &(msg[i]);
1155 break;
1156 }
1157
1158 if ((buf_used + new_len) > (int)sizeof(buffer))
1159 {
1160 // new piece won't fit, write forced
1161 hwrite(webblk->sock, buffer, buf_used);
1162 buf_used = 0;
1163 }
1164
1165 while (new_len > 0)
1166 {
1167 buffer[buf_used++] = *new_str++;
1168 new_len--;
1169 }
1170 }
1171
1172 if (buf_used > 0)
1173 {
1174 // write out final/partial buffer
1175 hwrite(webblk->sock, buffer, buf_used);
1176 }
1177 }
1178
1179
1180 // cgibin_cmd_cmd: issue panel command and return response only
1181 // without the rest of the syslog, and without most of the HTML wrapping
1182
cgibin_cmd_cmd(WEBBLK * webblk,char * command)1183 void cgibin_cmd_cmd(WEBBLK *webblk, char *command)
1184 {
1185 char * response;
1186
1187 while (isspace(*command))
1188 command++;
1189
1190 if (*command == 0)
1191 {
1192 return; /* command is all blank, ignore */
1193 }
1194
1195 response = log_capture(panel_command, command);
1196
1197 if (response == NULL)
1198 {
1199 return; /* command failed to execute */
1200 }
1201
1202 html_header(webblk);
1203 hprintf(webblk->sock, "<PRE>\n");
1204
1205 cgibin_hwrite(webblk, response, strlen (response));
1206
1207 hprintf(webblk->sock, "</PRE>\n");
1208 html_footer(webblk);
1209
1210 // Ensure command and response is visible on Hercules console panel
1211
1212 logmsg ("%s", response);
1213
1214 free (response);
1215 }
1216
1217
1218 // handle http requests of the form:
1219 // http://localhost:8081/cgi-bin/tasks/cmd?cmd=qcpuid
1220
cgibin_cmd(WEBBLK * webblk)1221 void cgibin_cmd(WEBBLK *webblk)
1222 {
1223 char *command;
1224
1225 if ((command = cgi_variable(webblk,"cmd")))
1226 {
1227 /* "cmd" issues a single command */
1228 cgibin_cmd_cmd (webblk, command);
1229 return;
1230 }
1231 }
1232
1233
1234 /* The following table is the cgi-bin directory, which */
1235 /* associates directory filenames with cgibin routines */
1236
1237 CGITAB cgidir[] = {
1238 { "tasks/cmd", &cgibin_cmd },
1239 { "tasks/syslog", &cgibin_syslog },
1240 { "tasks/ipl", &cgibin_ipl },
1241 { "configure/cpu", &cgibin_configure_cpu },
1242 { "debug/registers", &cgibin_debug_registers },
1243 { "debug/storage", &cgibin_debug_storage },
1244 { "debug/misc", &cgibin_debug_misc },
1245 { "debug/version_info", &cgibin_debug_version_info },
1246 { "debug/device/list", &cgibin_debug_device_list },
1247 { "debug/device/detail", &cgibin_debug_device_detail },
1248 { "registers/general", &cgibin_reg_general },
1249 { "registers/control", &cgibin_reg_control },
1250 { "registers/psw", &cgibin_psw },
1251 #if defined(OPTION_MIPS_COUNTING)
1252 { "xml/rates", &cgibin_xml_rates_info },
1253 #endif /*defined(OPTION_MIPS_COUNTING)*/
1254 { NULL, NULL } };
1255
1256 #endif /*defined(OPTION_HTTP_SERVER)*/
1257