Greg Stein wrote:

> On Mon, Oct 01, 2001 at 03:51:07PM -0000, [EMAIL PROTECTED] wrote:
> 
>>wrowe       01/10/01 08:51:07
>>
>>  Modified:    modules/generators mod_status.c
>>  Log:
>>    Clean up some warnings by summing bytecounts into apr_off_t holders
>>    instead of ulongs.
>>
> 
> Ah! Good stuff.
> 
> Cheers,
> -g
> 
> 

Hi.
I had a patch which added a '?xml' option
to mod_status.
It's a large (>400 lines) patch, but most of it is puts.
does anyone have any objections to it?




Index: modules/generators/mod_status.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/generators/mod_status.c,v
retrieving revision 1.47
diff -u -u -r1.47 mod_status.c
--- modules/generators/mod_status.c     2001/10/01 15:51:07     1.47
+++ modules/generators/mod_status.c     2001/10/02 04:55:22
@@ -206,10 +206,11 @@

  /* ID values for command table */

-#define STAT_OPT_END           -1
-#define STAT_OPT_REFRESH       0
-#define STAT_OPT_NOTABLE       1
-#define STAT_OPT_AUTO          2
+#define STAT_OPT_END       -1
+#define STAT_OPT_REFRESH    0
+#define STAT_OPT_NOTABLE    1
+#define STAT_OPT_AUTO       2
+#define STAT_OPT_XML        3

  struct stat_opt {
      int id;
@@ -222,6 +223,7 @@
      {STAT_OPT_REFRESH, "refresh", "Refresh"},
      {STAT_OPT_NOTABLE, "notable", NULL},
      {STAT_OPT_AUTO, "auto", NULL},
+    {STAT_OPT_XML, "xml", NULL},
      {STAT_OPT_END, NULL, NULL}
  };

@@ -249,6 +251,8 @@
  #endif
      int short_report = 0;
      int no_table_report = 0;
+    int xml_report = 0;
+    int html_report =0;
      worker_score ws_record;
      process_score ps_record;
      char stat_buffer[HARD_SERVER_LIMIT * HARD_THREAD_LIMIT];
@@ -273,6 +277,7 @@
        return DECLINED;

      r->content_type = "text/html";
+    html_report =1;

      /*
       * Simple table-driven form data set parser that lets you alter the header
@@ -300,7 +305,14 @@
                case STAT_OPT_AUTO:
                    r->content_type = "text/plain";
                    short_report = 1;
+            html_report =0;
                    break;
+ 
        case STAT_OPT_XML:
+ 
            r->content_type = "text/xml";
+ 
            xml_report = 1;
+            html_report =0;
+ 
            break;
+
                }
            }
            i++;
@@ -355,25 +367,37 @@
      /* up_time in seconds */
      up_time = (apr_uint32_t) ((nowtime - ap_restart_time)/APR_USEC_PER_SEC);

-    if (!short_report) {
- 
ap_rputs(DOCTYPE_HTML_3_2
+    if (html_report) {
+        ap_rputs(DOCTYPE_HTML_3_2
                 "<html><head>\n<title>Apache Status</title>\n</head><body>\n",
                 r);
- 
ap_rputs("<h1>Apache Server Status for ", r);
- 
ap_rvputs(r, ap_get_server_name(r), "</h1>\n\n", NULL);
- 
ap_rvputs(r, "<dl><dt>Server Version: ",
- 
   ap_get_server_version(), "</dt>\n", NULL);
- 
ap_rvputs(r, "<dt>Server Built: ",
- 
   ap_get_server_built(), "\n</dt></dl><hr /><dl>\n", NULL);
- 
ap_rvputs(r, "<dt>Current Time: ",
- 
   ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), "</dt>\n", NULL);
- 
ap_rvputs(r, "<dt>Restart Time: ",
- 
   ap_ht_time(r->pool, ap_restart_time, DEFAULT_TIME_FORMAT, 0),
- 
   "</dt>\n", NULL);
- 
ap_rprintf(r, "<dt>Parent Server Generation: %d</dt>\n", (int) ap_my_generation);
- 
ap_rputs("<dt>Server uptime: ", r);
- 
show_time(r, up_time);
- 
ap_rputs("</dt>\n", r);
+        ap_rputs("<h1>Apache Server Status for ", r);
+        ap_rvputs(r, ap_get_server_name(r), "</h1>\n\n", NULL);
+        ap_rvputs(r, "<dl><dt>Server Version: ",
+          ap_get_server_version(), "</dt>\n", NULL);
+        ap_rvputs(r, "<dt>Server Built: ",
+          ap_get_server_built(), "\n</dt></dl><hr /><dl>\n", NULL);
+        ap_rvputs(r, "<dt>Current Time: ",
+          ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), "</dt>\n", NULL);
+        ap_rvputs(r, "<dt>Restart Time: ",
+          ap_ht_time(r->pool, ap_restart_time, DEFAULT_TIME_FORMAT, 0),
+          "</dt>\n", NULL);
+        ap_rprintf(r, "<dt>Parent Server Generation: %d</dt>\n", (int) 
+ap_my_generation);
+        ap_rputs("<dt>Server uptime: ", r);
+        show_time(r, up_time);
+        ap_rputs("</dt>\n", r);
+    }
+    if (xml_report) {
+        ap_rputs("<?xml version='1.0' ?>\n",r);
+        ap_rprintf(r,"<status servername='%s'>\n",ap_get_server_name(r));
+        
+ap_rprintf(r,"<time><built>%s</built><current>%s</current><restart>%s</restart></time>\n",
+            ap_get_server_built(),
+            ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0),
+            ap_ht_time(r->pool, ap_restart_time, DEFAULT_TIME_FORMAT, 0));
+        ap_rprintf(r,"<generation number='%d' />\n",(int)ap_my_generation);
+        ap_rputs("<uptime>",r);
+        show_time(r,up_time);
+        ap_rputs("</uptime>\n",r);
      }

      if (ap_extended_status) {
@@ -401,81 +425,156 @@
                ap_rprintf(r, "BytesPerReq: %g\n",
                    KBYTE * (float) kbcount / (float) count);
        }
- 
else {                  /* !short_report */
- 
     ap_rprintf(r, "<dt>Total accesses: %lu - Total Traffic: ", count);
- 
     format_kbyte_out(r, kbcount);
- 
     ap_rputs("</dt>\n", r);
+    else {
+        if (html_report) {                     /* !short_report */
+           ap_rprintf(r, "<dt>Total accesses: %lu - Total Traffic: ", count);
+ 
         format_kbyte_out(r, kbcount);
+ 
         ap_rputs("</dt>\n", r);

  #ifdef HAVE_TIMES
- 
     /* Allow for OS/2 not having CPU stats */
- 
     ap_rprintf(r, "<dt>CPU Usage: u%g s%g cu%g cs%g",
- 
            tu / tick, ts / tick, tcu / tick, tcs / tick);
+ 
         /* Allow for OS/2 not having CPU stats */
+ 
         ap_rprintf(r, "<dt>CPU Usage: u%g s%g cu%g cs%g",
+ 
                tu / tick, ts / tick, tcu / tick, tcs / tick);

- 
     if (ts || tu || tcu || tcs)
- 
        ap_rprintf(r, " - %.3g%% CPU load</dt>\n",
+ 
         if (ts || tu || tcu || tcs)
+ 
            ap_rprintf(r, " - %.3g%% CPU load</dt>\n",
                    (tu + ts + tcu + tcs) / tick / up_time * 100.);
  #endif

- 
     if (up_time > 0)
- 
        ap_rprintf(r, "<dt>%.3g requests/sec - ",
- 
                (float) count / (float) up_time);
+            if (up_time > 0) {
+                   ap_rprintf(r, "<dt>%.3g requests/sec - ",
+ 
                    (float) count / (float) up_time);
+
+ 
                format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount
+                                                             / (float) up_time));
+ 
                ap_rputs("/second - ", r);
+ 
         }

- 
     if (up_time > 0) {
- 
        format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount
-                                                         / (float) up_time));
- 
        ap_rputs("/second - ", r);
- 
     }
+ 
         if (count > 0) {
+ 
             format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount
+                                                             / (float) count));
+ 
                ap_rputs("/request", r);
+ 
         }

- 
     if (count > 0) {
- 
        format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount
-                                                         / (float) count));
- 
        ap_rputs("/request", r);
- 
     }
+ 
         ap_rputs("</dt>\n", r);
+ 
     }                          /* html_report */
+        else {
+            ap_rprintf(r, "<total accesses ='%lu' kb='%lu' />\n", count,kbcount);
+#ifdef HAVE_TIMES
+            ap_rprintf(r, "<cpu usr='%g' sys='%g' cuser='%g' csys='%g'",
+                    tu / tick, ts / tick, tcu / tick, tcs / tick );
+            if (ts || tu || tcu || tcs) {
+ 
                ap_rprintf(r, " load='%.3g%%",
+                    (tu + ts + tcu + tcs) / tick / up_time * 100.);
+            }
+            ap_rputs("/>\n",r);
+#endif
+            if (up_time >0 ) {
+                ap_rprintf(r,
+                   "<reqspersec>%.3g</reqspersec>"
+                   "<bytespersec>%ld</bytespersec>",
+                   (float) count / (float) up_time,
+                   (unsigned long)(KBYTE * (float) kbcount / (float) up_time));
+            }
+
+        } /* xml_report */
+    } /* short_report */
+
+    }  /* ap_extended_status */
+
+    if (html_report) {
+ 
     ap_rprintf(r, "<dt>%d requests currently being processed,",busy);
+        ap_rprintf(r," %d idle workers</dt>\n",ready);
+    }
+    else {
+        if (xml_report ) {
+            ap_rprintf(r,"<workers busy='%d' idle='%d' />\n",busy,ready);

- 
     ap_rputs("</dt>\n", r);
- 
} 
                        /* short_report */
-    }                                  /* ap_extended_status */
-
-    if (!short_report)
- 
ap_rprintf(r, "<dt>%d requests currently being processed, %d idle workers</dt>\n"
- 
        ,busy, ready);
-    else
- 
ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready);
+        }
+        else { /* short_report */
+ 
         ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready);
+        }
+    }

      /* send the scoreboard 'table' out */

-    if (!short_report)
- 
ap_rputs("</dl><pre>", r);
-    else
- 
ap_rputs("Scoreboard: ", r);
+    if (html_report) {
+ 
     ap_rputs("</dl><pre>", r);
+    }
+    else {
+        if (xml_report) {
+            ap_rputs("<scoreboard>\n", r);
+        }
+        else {
+            ap_rputs("Scoreboard: ", r);
+        }
+    }
+ 


      for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
+        if (xml_report) {
+            ap_rprintf(r,"<server number='%d' pid='%"APR_OS_PROC_T_FMT "'>\n",
+                i,pid_buffer[i]);
+        }
          for (j = 0; j < HARD_THREAD_LIMIT; ++j) {
              int indx = (i * HARD_THREAD_LIMIT) + j;
- 
     ap_rputc(stat_buffer[indx], r);
- 
     if ((indx % STATUS_MAXLINE == (STATUS_MAXLINE - 1)) && !short_report)
- 
         ap_rputs("\n", r);
+            if (html_report) {
+                ap_rputc(stat_buffer[indx], r);
+                if ((indx % STATUS_MAXLINE ) == (STATUS_MAXLINE - 1))
+                    ap_rputs("\n",r);
+            }
+            else {
+                if (xml_report) {
+                    if (stat_buffer[indx] != '.' )
+                        ap_rprintf(r,"<thread number='%d' status='%c' 
+/>",j,stat_buffer[indx]);
+                }
+                else {
+                    ap_rputc(stat_buffer[indx], r);
+                }
+            }
+        } /* thread loop */
+        if (xml_report )
+            ap_rputs("</server>\n",r);
+    } /* server loop */
+
+    if (html_report) {
+        ap_rputs("</pre>\n", r);
+        ap_rputs("<p>Scoreboard Key:<br />\n", r);
+        ap_rputs("\"<b><code>_</code></b>\" Waiting for Connection, \n", r);
+        ap_rputs("\"<b><code>S</code></b>\" Starting up, \n", r);
+        ap_rputs("\"<b><code>R</code></b>\" Reading Request,<br />\n", r);
+        ap_rputs("\"<b><code>W</code></b>\" Sending Reply, \n", r);
+        ap_rputs("\"<b><code>K</code></b>\" Keepalive (read), \n", r);
+        ap_rputs("\"<b><code>D</code></b>\" DNS Lookup,<br />\n", r);
+        ap_rputs("\"<b><code>C</code></b>\" Closing connection, \n", r);
+        ap_rputs("\"<b><code>L</code></b>\" Logging, \n", r);
+        ap_rputs("\"<b><code>G</code></b>\" Gracefully finishing,<br /> \n", r);
+        ap_rputs("\"<b><code>I</code></b>\" Idle cleanup of worker, \n", r);
+        ap_rputs("\"<b><code>.</code></b>\" Open slot with no current process</p>\n", 
+r);
+        ap_rputs("<p />\n", r);
+    }
+    else {
+        if (xml_report) {
+            ap_rputs("<statuslegend>\n", r);
+            ap_rputs("<status key='_' description='Waiting for Connection' />\n", r);
+            ap_rputs("<status key='S' description='Starting up' />\n", r);
+            ap_rputs("<status key='R' description='Reading Request' />\n", r);
+            ap_rputs("<status key='W' description='Sending Reply' />\n", r);
+            ap_rputs("<status key='K' description='Keepalive (read)' />\n", r);
+            ap_rputs("<status key='D' description='DNS Lookup' />\n", r);
+            ap_rputs("<status key='C' description='Closing connection' />\n", r);
+            ap_rputs("<status key='L' description='Logging' />\n", r);
+            ap_rputs("<status key='G' description='Gracefully finishing' />\n", r);
+            ap_rputs("<status key='I' description='Idle cleanup of worker' />\n", r);
+            ap_rputs("<status key='.' description='Open slot with no current process' 
+/>\n", r); 

+            ap_rputs("</statuslegend></scoreboard>\n", r);
+        }
+        else {
+            ap_rputs("\n", r);
          }
      }

-    if (short_report)
- 
ap_rputs("\n", r);
-    else {
- 
ap_rputs("</pre>\n", r);
- 
ap_rputs("<p>Scoreboard Key:<br />\n", r);
- 
ap_rputs("\"<b><code>_</code></b>\" Waiting for Connection, \n", r);
- 
ap_rputs("\"<b><code>S</code></b>\" Starting up, \n", r);
- 
ap_rputs("\"<b><code>R</code></b>\" Reading Request,<br />\n", r);
- 
ap_rputs("\"<b><code>W</code></b>\" Sending Reply, \n", r);
- 
ap_rputs("\"<b><code>K</code></b>\" Keepalive (read), \n", r);
- 
ap_rputs("\"<b><code>D</code></b>\" DNS Lookup,<br />\n", r);
- 
ap_rputs("\"<b><code>C</code></b>\" Closing connection, \n", r);
- 
ap_rputs("\"<b><code>L</code></b>\" Logging, \n", r);
- 
ap_rputs("\"<b><code>G</code></b>\" Gracefully finishing,<br /> \n", r);
-        ap_rputs("\"<b><code>I</code></b>\" Idle cleanup of worker, \n", r);
- 
ap_rputs("\"<b><code>.</code></b>\" Open slot with no current process</p>\n", r);
- 
ap_rputs("<p />\n", r);
- 
if (!ap_extended_status) {
+ 
if (!ap_extended_status && html_report) {
            int j;
              int k = 0;
            ap_rputs("PID Key: <br />\n", r);
@@ -499,20 +598,24 @@
            ap_rputs("\n", r);
            ap_rputs("</pre>\n", r);
        }
-    }

      if (ap_extended_status) {
- 
if (!short_report) {
+ 
if (html_report) {
            if (no_table_report)
                ap_rputs("<hr /><h2>Server Details</h2>\n\n", r);
            else
  #ifndef HAVE_TIMES
                /* Allow for OS/2 not having CPU stats */
- 
        ap_rputs("\n\n<table 
border=\"0\"><tr><th>Srv</th><th>PID</th><th>Acc</th><th>M\n</th><th>SS</th><th>Req</th><th>Conn</th><th>Child</th><th>Slot</th><th>Client</th><th>VHost</th><th>Request</th></tr>\n\n",
 
r);
+ 
        ap_rputs("\n\n<table 
border=\"0\"><tr><th>Srv</th><th>PID</th><th>Acc</th><th>M\n</th><th>SS</th><th>Req</th><th>Conn</th><th>Child</th><th>Slot</th><th>Client</th><th>VHost</th><th>Request</th></tr>\n\n",
 
r);
  #else
                ap_rputs("\n\n<table 
border=\"0\"><tr><th>Srv</th><th>PID</th><th>Acc</th><th>M</th><th>CPU\n</th><th>SS</th><th>Req</th><th>Conn</th><th>Child</th><th>Slot</th><th>Client</th><th>VHost</th><th>Request</th></tr>\n\n",
 
r);
  #endif
        }
+    else {
+        if (xml_report) {
+            ap_rputs("<extended><slots>\n",r);
+        }
+    }

        for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
        for (j = 0; j < HARD_THREAD_LIMIT; ++j) {
@@ -554,7 +657,7 @@
            conn_bytes = ws_record.conn_bytes;
            if (lres != 0 || (ws_record.status != SERVER_READY
         
              && ws_record.status != SERVER_DEAD)) {
- 
        if (!short_report) {
+ 
        if (html_report) {
                    if (no_table_report) {
         
        if (ws_record.status == SERVER_DEAD)
         
            ap_rprintf(r,
@@ -710,12 +813,62 @@
         
                vhost->server_hostname) : "(unavailable)",
         
             ap_escape_html(r->pool, ws_record.request));
                    }           /* no_table_report */
- 
        }                       /* !short_report */
+ 
        }                       /* !html_report */
+        else {
+            if (xml_report) {
+                ap_rprintf(r,"<slot id='%d' generation='%d' "
+                                "connection_count='%d' "
+                                "my_access_count='%lu' "
+                                "access_count='%lu' ",
+                                i, (int)ps_record.generation,
+                                (int)conn_lres,my_lres,lres);
+                if (ws_record.status != SERVER_DEAD)
+                    ap_rprintf(r," pid='%"APR_OS_PROC_T_FMT "' ", ps_record.pid);
+
+                ap_rprintf(r,
+                    " status='%d' seconds_since_begining_recent_req='%ld' "
+                    "milliseconds_required_most_recent_req='%ld' ",
+                    ws_record.status,
+                    (long)((nowtime - ws_record.last_used) / APR_USEC_PER_SEC),
+                    (long) req_time);
+#ifdef HAVE_TIMES
+ 
                    ap_rprintf(r, "usr='%g' sys='%g' cusr='%g' csys='%g' ",
+ 
                        ws_record.times.tms_utime / tick,
+ 
                        ws_record.times.tms_stime / tick,
+ 
                        ws_record.times.tms_cutime / tick,
+ 
                        ws_record.times.tms_cstime / tick);
+#endif
+                ap_rputs(">\n",r);
+                ap_rprintf(r,"<bytes conn='%ld' child='%ld' slot='%ld' />",
+                    conn_bytes,my_bytes, bytes);
+                ap_rprintf(r,"<client host='%s' vhost='%s' uri='%s' />",
+ 
                        ap_escape_html(r->pool, ws_record.client),
+                    vhost ? ap_escape_html(r->pool,
+                                   vhost->server_hostname) : "(unavailable)",
+                    ap_escape_html(r->pool, ws_record.request));
+                ap_rputs("</slot>\n",r);
+            }
+        }
            }                   /* if (<active child>) */
        } 
                        /* for () */
        }
+    if (xml_report) {
+        ap_rputs("</slots><statuslegend>\n",r);
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_READY,"Ready");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_STARTING,"Starting");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_BUSY_READ,"Read");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_BUSY_WRITE,"Write");
+        ap_rprintf(r,"<status key='%d' desc='%s' 
+/>\n",SERVER_BUSY_KEEPALIVE,"Keepalive");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_BUSY_LOG,"Logging");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_BUSY_DNS,"DNS Lookup");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_CLOSING,"Closing");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_DEAD,"Dead");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_GRACEFUL,"Graceful");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_IDLE_KILL,"Dying");

- 
if (!(short_report || no_table_report)) {
+        ap_rputs("</statuslegend></extended>\n",r);
+    }
+ 
if (html_report && !no_table_report) {
  #ifndef HAVE_TIMES
            ap_rputs("</table>\n \
  <hr /> \
@@ -750,18 +903,22 @@

      } else {

- 
if (!short_report) {
+ 
if (html_report) {
            ap_rputs("<hr />To obtain a full report with current status information ", 
r);
            ap_rputs("you need to use the <code>ExtendedStatus On</code> directive. 
\n", r);
        }

      }

-    if (!short_report) {
+    if (html_report) {
        ap_rputs(ap_psignature("<hr />\n",r), r);
        ap_rputs("</body></html>\n", r);
      }

+    if (xml_report)
+    {
+        ap_rputs("</status>\n", r);
+    }
      return 0;
  }


Index: modules/generators/mod_status.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/generators/mod_status.c,v
retrieving revision 1.47
diff -u -u -r1.47 mod_status.c
--- modules/generators/mod_status.c     2001/10/01 15:51:07     1.47
+++ modules/generators/mod_status.c     2001/10/02 04:55:22
@@ -206,10 +206,11 @@
 
 /* ID values for command table */
 
-#define STAT_OPT_END           -1
-#define STAT_OPT_REFRESH       0
-#define STAT_OPT_NOTABLE       1
-#define STAT_OPT_AUTO          2
+#define STAT_OPT_END       -1
+#define STAT_OPT_REFRESH    0
+#define STAT_OPT_NOTABLE    1
+#define STAT_OPT_AUTO       2
+#define STAT_OPT_XML        3
 
 struct stat_opt {
     int id;
@@ -222,6 +223,7 @@
     {STAT_OPT_REFRESH, "refresh", "Refresh"},
     {STAT_OPT_NOTABLE, "notable", NULL},
     {STAT_OPT_AUTO, "auto", NULL},
+    {STAT_OPT_XML, "xml", NULL},
     {STAT_OPT_END, NULL, NULL}
 };
 
@@ -249,6 +251,8 @@
 #endif
     int short_report = 0;
     int no_table_report = 0;
+    int xml_report = 0;
+    int html_report =0;
     worker_score ws_record;
     process_score ps_record;
     char stat_buffer[HARD_SERVER_LIMIT * HARD_THREAD_LIMIT];
@@ -273,6 +277,7 @@
        return DECLINED;
 
     r->content_type = "text/html";
+    html_report =1;
 
     /*
      * Simple table-driven form data set parser that lets you alter the header
@@ -300,7 +305,14 @@
                case STAT_OPT_AUTO:
                    r->content_type = "text/plain";
                    short_report = 1;
+            html_report =0;
                    break;
+               case STAT_OPT_XML:
+                   r->content_type = "text/xml";
+                   xml_report = 1;
+            html_report =0;
+                   break;
+
                }
            }
            i++;
@@ -355,25 +367,37 @@
     /* up_time in seconds */
     up_time = (apr_uint32_t) ((nowtime - ap_restart_time)/APR_USEC_PER_SEC);
 
-    if (!short_report) {
-       ap_rputs(DOCTYPE_HTML_3_2
+    if (html_report) {
+        ap_rputs(DOCTYPE_HTML_3_2
                 "<html><head>\n<title>Apache Status</title>\n</head><body>\n",
                 r);
-       ap_rputs("<h1>Apache Server Status for ", r);
-       ap_rvputs(r, ap_get_server_name(r), "</h1>\n\n", NULL);
-       ap_rvputs(r, "<dl><dt>Server Version: ",
-         ap_get_server_version(), "</dt>\n", NULL);
-       ap_rvputs(r, "<dt>Server Built: ",
-         ap_get_server_built(), "\n</dt></dl><hr /><dl>\n", NULL);
-       ap_rvputs(r, "<dt>Current Time: ",
-         ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), "</dt>\n", NULL);
-       ap_rvputs(r, "<dt>Restart Time: ",
-         ap_ht_time(r->pool, ap_restart_time, DEFAULT_TIME_FORMAT, 0), 
-         "</dt>\n", NULL);
-       ap_rprintf(r, "<dt>Parent Server Generation: %d</dt>\n", (int) 
ap_my_generation);
-       ap_rputs("<dt>Server uptime: ", r);
-       show_time(r, up_time);
-       ap_rputs("</dt>\n", r);
+        ap_rputs("<h1>Apache Server Status for ", r);
+        ap_rvputs(r, ap_get_server_name(r), "</h1>\n\n", NULL);
+        ap_rvputs(r, "<dl><dt>Server Version: ",
+          ap_get_server_version(), "</dt>\n", NULL);
+        ap_rvputs(r, "<dt>Server Built: ",
+          ap_get_server_built(), "\n</dt></dl><hr /><dl>\n", NULL);
+        ap_rvputs(r, "<dt>Current Time: ",
+          ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), "</dt>\n", NULL);
+        ap_rvputs(r, "<dt>Restart Time: ",
+          ap_ht_time(r->pool, ap_restart_time, DEFAULT_TIME_FORMAT, 0), 
+          "</dt>\n", NULL);
+        ap_rprintf(r, "<dt>Parent Server Generation: %d</dt>\n", (int) 
+ap_my_generation);
+        ap_rputs("<dt>Server uptime: ", r);
+        show_time(r, up_time);
+        ap_rputs("</dt>\n", r);
+    }
+    if (xml_report) {
+        ap_rputs("<?xml version='1.0' ?>\n",r);
+        ap_rprintf(r,"<status servername='%s'>\n",ap_get_server_name(r));
+        
+ap_rprintf(r,"<time><built>%s</built><current>%s</current><restart>%s</restart></time>\n",
+            ap_get_server_built(),
+            ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0),
+            ap_ht_time(r->pool, ap_restart_time, DEFAULT_TIME_FORMAT, 0));
+        ap_rprintf(r,"<generation number='%d' />\n",(int)ap_my_generation);
+        ap_rputs("<uptime>",r);
+        show_time(r,up_time);
+        ap_rputs("</uptime>\n",r);
     }
 
     if (ap_extended_status) {
@@ -401,81 +425,156 @@
                ap_rprintf(r, "BytesPerReq: %g\n",
                    KBYTE * (float) kbcount / (float) count);
        }
-       else {                  /* !short_report */
-           ap_rprintf(r, "<dt>Total accesses: %lu - Total Traffic: ", count);
-           format_kbyte_out(r, kbcount);
-           ap_rputs("</dt>\n", r);
+    else {
+        if (html_report) {                     /* !short_report */
+           ap_rprintf(r, "<dt>Total accesses: %lu - Total Traffic: ", count);
+               format_kbyte_out(r, kbcount);
+               ap_rputs("</dt>\n", r);
 
 #ifdef HAVE_TIMES
-           /* Allow for OS/2 not having CPU stats */
-           ap_rprintf(r, "<dt>CPU Usage: u%g s%g cu%g cs%g",
-                   tu / tick, ts / tick, tcu / tick, tcs / tick);
+               /* Allow for OS/2 not having CPU stats */
+               ap_rprintf(r, "<dt>CPU Usage: u%g s%g cu%g cs%g",
+                       tu / tick, ts / tick, tcu / tick, tcs / tick);
 
-           if (ts || tu || tcu || tcs)
-               ap_rprintf(r, " - %.3g%% CPU load</dt>\n",
+               if (ts || tu || tcu || tcs)
+                   ap_rprintf(r, " - %.3g%% CPU load</dt>\n",
                    (tu + ts + tcu + tcs) / tick / up_time * 100.);
 #endif
 
-           if (up_time > 0)
-               ap_rprintf(r, "<dt>%.3g requests/sec - ",
-                       (float) count / (float) up_time);
+            if (up_time > 0) {
+                   ap_rprintf(r, "<dt>%.3g requests/sec - ",
+                           (float) count / (float) up_time);
+
+                       format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount 
+                                                             / (float) up_time));
+                       ap_rputs("/second - ", r);
+               }
 
-           if (up_time > 0) {
-               format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount 
-                                                         / (float) up_time));
-               ap_rputs("/second - ", r);
-           }
+               if (count > 0) {
+                    format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount 
+                                                             / (float) count));
+                       ap_rputs("/request", r);
+               }
 
-           if (count > 0) {
-               format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount 
-                                                         / (float) count));
-               ap_rputs("/request", r);
-           }
+               ap_rputs("</dt>\n", r);        
+           }                           /* html_report */
+        else {
+            ap_rprintf(r, "<total accesses ='%lu' kb='%lu' />\n", count,kbcount);
+#ifdef HAVE_TIMES
+            ap_rprintf(r, "<cpu usr='%g' sys='%g' cuser='%g' csys='%g'", 
+                    tu / tick, ts / tick, tcu / tick, tcs / tick );
+            if (ts || tu || tcu || tcs) {
+                       ap_rprintf(r, " load='%.3g%%",
+                    (tu + ts + tcu + tcs) / tick / up_time * 100.);
+            }
+            ap_rputs("/>\n",r);
+#endif
+            if (up_time >0 ) {
+                ap_rprintf(r,
+                   "<reqspersec>%.3g</reqspersec>"
+                   "<bytespersec>%ld</bytespersec>",
+                   (float) count / (float) up_time,
+                   (unsigned long)(KBYTE * (float) kbcount / (float) up_time));
+            }
+
+        } /* xml_report */
+    } /* short_report */
+
+    }  /* ap_extended_status */
+
+    if (html_report) {
+           ap_rprintf(r, "<dt>%d requests currently being processed,",busy);
+        ap_rprintf(r," %d idle workers</dt>\n",ready);
+    }
+    else {
+        if (xml_report ) {
+            ap_rprintf(r,"<workers busy='%d' idle='%d' />\n",busy,ready);
 
-           ap_rputs("</dt>\n", r);
-       }                               /* short_report */
-    }                                  /* ap_extended_status */
-
-    if (!short_report)
-       ap_rprintf(r, "<dt>%d requests currently being processed, %d idle 
workers</dt>\n"
-               ,busy, ready);
-    else
-       ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready);
+        }
+        else { /* short_report */
+               ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready);
+        }
+    }
 
     /* send the scoreboard 'table' out */
 
-    if (!short_report)
-       ap_rputs("</dl><pre>", r);
-    else
-       ap_rputs("Scoreboard: ", r);
+    if (html_report) {
+           ap_rputs("</dl><pre>", r);
+    }
+    else {
+        if (xml_report) {
+            ap_rputs("<scoreboard>\n", r);
+        } 
+        else {
+            ap_rputs("Scoreboard: ", r);
+        }
+    }
+           
 
     for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
+        if (xml_report) {
+            ap_rprintf(r,"<server number='%d' pid='%"APR_OS_PROC_T_FMT "'>\n",
+                i,pid_buffer[i]);
+        }
         for (j = 0; j < HARD_THREAD_LIMIT; ++j) {
             int indx = (i * HARD_THREAD_LIMIT) + j;
-           ap_rputc(stat_buffer[indx], r);
-           if ((indx % STATUS_MAXLINE == (STATUS_MAXLINE - 1)) && !short_report)
-               ap_rputs("\n", r);
+            if (html_report) {
+                ap_rputc(stat_buffer[indx], r);
+                if ((indx % STATUS_MAXLINE ) == (STATUS_MAXLINE - 1))
+                    ap_rputs("\n",r);
+            }
+            else {
+                if (xml_report) {
+                    if (stat_buffer[indx] != '.' )
+                        ap_rprintf(r,"<thread number='%d' status='%c' 
+/>",j,stat_buffer[indx]);
+                } 
+                else {
+                    ap_rputc(stat_buffer[indx], r);
+                }
+            }
+        } /* thread loop */
+        if (xml_report )
+            ap_rputs("</server>\n",r);
+    } /* server loop */
+
+    if (html_report) {
+        ap_rputs("</pre>\n", r);
+        ap_rputs("<p>Scoreboard Key:<br />\n", r);
+        ap_rputs("\"<b><code>_</code></b>\" Waiting for Connection, \n", r);
+        ap_rputs("\"<b><code>S</code></b>\" Starting up, \n", r);
+        ap_rputs("\"<b><code>R</code></b>\" Reading Request,<br />\n", r);
+        ap_rputs("\"<b><code>W</code></b>\" Sending Reply, \n", r);
+        ap_rputs("\"<b><code>K</code></b>\" Keepalive (read), \n", r);
+        ap_rputs("\"<b><code>D</code></b>\" DNS Lookup,<br />\n", r);
+        ap_rputs("\"<b><code>C</code></b>\" Closing connection, \n", r);
+        ap_rputs("\"<b><code>L</code></b>\" Logging, \n", r);
+        ap_rputs("\"<b><code>G</code></b>\" Gracefully finishing,<br /> \n", r);
+        ap_rputs("\"<b><code>I</code></b>\" Idle cleanup of worker, \n", r);
+        ap_rputs("\"<b><code>.</code></b>\" Open slot with no current process</p>\n", 
+r);
+        ap_rputs("<p />\n", r);
+    }
+    else {
+        if (xml_report) {
+            ap_rputs("<statuslegend>\n", r);
+            ap_rputs("<status key='_' description='Waiting for Connection' />\n", r);
+            ap_rputs("<status key='S' description='Starting up' />\n", r);
+            ap_rputs("<status key='R' description='Reading Request' />\n", r);
+            ap_rputs("<status key='W' description='Sending Reply' />\n", r);
+            ap_rputs("<status key='K' description='Keepalive (read)' />\n", r);
+            ap_rputs("<status key='D' description='DNS Lookup' />\n", r);
+            ap_rputs("<status key='C' description='Closing connection' />\n", r);
+            ap_rputs("<status key='L' description='Logging' />\n", r);            
+            ap_rputs("<status key='G' description='Gracefully finishing' />\n", r);   
+         
+            ap_rputs("<status key='I' description='Idle cleanup of worker' />\n", r); 
+           
+            ap_rputs("<status key='.' description='Open slot with no current process' 
+/>\n", r);            
+            ap_rputs("</statuslegend></scoreboard>\n", r);
+        }
+        else {
+            ap_rputs("\n", r);
         }
     }
 
-    if (short_report)
-       ap_rputs("\n", r);
-    else {
-       ap_rputs("</pre>\n", r);
-       ap_rputs("<p>Scoreboard Key:<br />\n", r);
-       ap_rputs("\"<b><code>_</code></b>\" Waiting for Connection, \n", r);
-       ap_rputs("\"<b><code>S</code></b>\" Starting up, \n", r);
-       ap_rputs("\"<b><code>R</code></b>\" Reading Request,<br />\n", r);
-       ap_rputs("\"<b><code>W</code></b>\" Sending Reply, \n", r);
-       ap_rputs("\"<b><code>K</code></b>\" Keepalive (read), \n", r);
-       ap_rputs("\"<b><code>D</code></b>\" DNS Lookup,<br />\n", r);
-       ap_rputs("\"<b><code>C</code></b>\" Closing connection, \n", r);
-       ap_rputs("\"<b><code>L</code></b>\" Logging, \n", r);
-       ap_rputs("\"<b><code>G</code></b>\" Gracefully finishing,<br /> \n", r);
-        ap_rputs("\"<b><code>I</code></b>\" Idle cleanup of worker, \n", r);
-       ap_rputs("\"<b><code>.</code></b>\" Open slot with no current process</p>\n", 
r);
-       ap_rputs("<p />\n", r);
-       if (!ap_extended_status) {
+       if (!ap_extended_status && html_report) {
            int j;
             int k = 0;
            ap_rputs("PID Key: <br />\n", r);
@@ -499,20 +598,24 @@
            ap_rputs("\n", r);
            ap_rputs("</pre>\n", r);
        }
-    }
 
     if (ap_extended_status) {
-       if (!short_report) {
+       if (html_report) {
            if (no_table_report)
                ap_rputs("<hr /><h2>Server Details</h2>\n\n", r);
            else
 #ifndef HAVE_TIMES
                /* Allow for OS/2 not having CPU stats */
-               ap_rputs("\n\n<table 
border=\"0\"><tr><th>Srv</th><th>PID</th><th>Acc</th><th>M\n</th><th>SS</th><th>Req</th><th>Conn</th><th>Child</th><th>Slot</th><th>Client</th><th>VHost</th><th>Request</th></tr>\n\n",
 r);
+               ap_rputs("\n\n<table 
+border=\"0\"><tr><th>Srv</th><th>PID</th><th>Acc</th><th>M\n</th><th>SS</th><th>Req</th><th>Conn</th><th>Child</th><th>Slot</th><th>Client</th><th>VHost</th><th>Request</th></tr>\n\n",
+ r);
 #else
                ap_rputs("\n\n<table 
border=\"0\"><tr><th>Srv</th><th>PID</th><th>Acc</th><th>M</th><th>CPU\n</th><th>SS</th><th>Req</th><th>Conn</th><th>Child</th><th>Slot</th><th>Client</th><th>VHost</th><th>Request</th></tr>\n\n",
 r);
 #endif
        }
+    else {
+        if (xml_report) {
+            ap_rputs("<extended><slots>\n",r);
+        }
+    }
 
        for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
        for (j = 0; j < HARD_THREAD_LIMIT; ++j) {
@@ -554,7 +657,7 @@
            conn_bytes = ws_record.conn_bytes;
            if (lres != 0 || (ws_record.status != SERVER_READY
                              && ws_record.status != SERVER_DEAD)) {
-               if (!short_report) {
+               if (html_report) {
                    if (no_table_report) {
                        if (ws_record.status == SERVER_DEAD)
                            ap_rprintf(r,
@@ -710,12 +813,62 @@
                                vhost->server_hostname) : "(unavailable)",
                             ap_escape_html(r->pool, ws_record.request));
                    }           /* no_table_report */
-               }                       /* !short_report */
+               }                       /* !html_report */
+        else {
+            if (xml_report) {
+                ap_rprintf(r,"<slot id='%d' generation='%d' "
+                                "connection_count='%d' "
+                                "my_access_count='%lu' "
+                                "access_count='%lu' ",
+                                i, (int)ps_record.generation,
+                                (int)conn_lres,my_lres,lres);
+                if (ws_record.status != SERVER_DEAD)
+                    ap_rprintf(r," pid='%"APR_OS_PROC_T_FMT "' ", ps_record.pid);
+
+                ap_rprintf(r,
+                    " status='%d' seconds_since_begining_recent_req='%ld' "
+                    "milliseconds_required_most_recent_req='%ld' ",
+                    ws_record.status,
+                    (long)((nowtime - ws_record.last_used) / APR_USEC_PER_SEC),
+                    (long) req_time);
+#ifdef HAVE_TIMES
+                           ap_rprintf(r, "usr='%g' sys='%g' cusr='%g' csys='%g' ",
+                               ws_record.times.tms_utime / tick,
+                               ws_record.times.tms_stime / tick,
+                               ws_record.times.tms_cutime / tick,
+                               ws_record.times.tms_cstime / tick);
+#endif
+                ap_rputs(">\n",r);
+                ap_rprintf(r,"<bytes conn='%ld' child='%ld' slot='%ld' />",
+                    conn_bytes,my_bytes, bytes);
+                ap_rprintf(r,"<client host='%s' vhost='%s' uri='%s' />",
+                               ap_escape_html(r->pool, ws_record.client),
+                    vhost ? ap_escape_html(r->pool, 
+                                   vhost->server_hostname) : "(unavailable)",
+                    ap_escape_html(r->pool, ws_record.request));
+                ap_rputs("</slot>\n",r);
+            }
+        }
            }                   /* if (<active child>) */
        }                               /* for () */
        }
+    if (xml_report) {
+        ap_rputs("</slots><statuslegend>\n",r);
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_READY,"Ready");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_STARTING,"Starting");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_BUSY_READ,"Read");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_BUSY_WRITE,"Write");
+        ap_rprintf(r,"<status key='%d' desc='%s' 
+/>\n",SERVER_BUSY_KEEPALIVE,"Keepalive");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_BUSY_LOG,"Logging");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_BUSY_DNS,"DNS Lookup");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_CLOSING,"Closing");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_DEAD,"Dead");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_GRACEFUL,"Graceful");
+        ap_rprintf(r,"<status key='%d' desc='%s' />\n",SERVER_IDLE_KILL,"Dying");
 
-       if (!(short_report || no_table_report)) {
+        ap_rputs("</statuslegend></extended>\n",r);
+    }
+       if (html_report && !no_table_report) {
 #ifndef HAVE_TIMES
            ap_rputs("</table>\n \
 <hr /> \
@@ -750,18 +903,22 @@
 
     } else {
 
-       if (!short_report) {
+       if (html_report) {
            ap_rputs("<hr />To obtain a full report with current status information ", 
r);
            ap_rputs("you need to use the <code>ExtendedStatus On</code> directive. 
\n", r);
        }
 
     }
 
-    if (!short_report) {
+    if (html_report) {
        ap_rputs(ap_psignature("<hr />\n",r), r);
        ap_rputs("</body></html>\n", r);
     }
 
+    if (xml_report)
+    {
+        ap_rputs("</status>\n", r);
+    }
     return 0;
 }
 

Reply via email to