WEB4TEST.C
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:5k
源码类别:

操作系统开发

开发平台:

DOS

  1. /* This example keeps a log of HTTP requests over time, and
  2.  * shows a graph of httpd usage per 5 second period
  3.  *
  4.  * Critical sections are used so that the datacollector
  5.  * and the datareporter do not step on each other.
  6.  *
  7.  * Includes FTP server.
  8.  * Includes SMTP server feature: change main title by mailing new subject
  9.  * line as mail subject, to update@thismachine
  10.  */
  11. #include <rtos.h>
  12. #include <net.h>
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16. #include <time.h>
  17. #include <graph.h>
  18. #include <ftpd.h>
  19. #include <httpd.h>
  20. #include <smtpd.h>
  21. #define GRWIDTH 200
  22. #define GRHEIGHT 50
  23. /*
  24.  * Sample Data Collector
  25.  *
  26.  * This code is mostly in charge of aging the data history
  27.  * every 5 seconds.
  28.  *
  29.  * It is placed in a separate thread so it is easy to read
  30.  */
  31. #define POINTS 20
  32. int last_n_points[ POINTS ];    /* this is the series over time */
  33. int curhits;                    /* this is the value in this period */
  34. crit_x *collector_cs;
  35. void collector( DWORD param )
  36. {
  37.     int i;
  38.     /* clear history */
  39.     memset( last_n_points, 0, sizeof( last_n_points ));
  40.     /* clear counter */
  41.     curhits = 0;
  42.     /* we will use a critical section so that collector and
  43.      * reporter are not interrupting each other
  44.      */
  45.     collector_cs = cs_alloc();
  46.     do {
  47.         rt_sleep( 5000 );    /* collect data for 5 seconds */
  48.         /* react to that collected data
  49.          * start by locking it
  50.          */
  51.         cs_enter( collector_cs );
  52.         /* remove the last one from history */
  53.         for ( i = 0 ; i < POINTS - 2 ; ++i )
  54.             last_n_points[ i ] = last_n_points[ i + 1 ];
  55.         /* and include the most recent */
  56.         last_n_points[ POINTS - 2 ] = curhits;
  57.         /* and reset the input to 0 for next round */
  58.         curhits = 0;
  59.         cs_exit( collector_cs );
  60.     } while ( 1 );
  61. }
  62. char newmsg[ 80 ] = "";
  63. void web_help( tcp_Socket *s )
  64. {
  65.     sock_puts( s, "rn<html><head><title>");
  66.     sock_puts( s, (*newmsg) ? newmsg : "Welcome" );  /* change with SMTP */
  67.     sock_puts( s, "</title></head>");
  68.     sock_puts(s, "<a href="time">Show Time</a><br>");
  69.     sock_puts(s, "<a href="mem">Show Free Memory</a><br>");
  70.     sock_puts(s, "<p>The graph below is a real time graph of "
  71.                  "server usage in 5 second increments.</p>");
  72.     sock_puts(s, "<img src="graph.gif" WIDTH=400 HEIGHT=100 >");
  73.     html_tail( s );
  74. }
  75. void web_time( tcp_Socket *s )
  76. {
  77.     time_t t;
  78.     time( &t );
  79.     html_hdr( s, "current time");
  80.     sock_puts( s,"The current time is ");
  81.     sock_puts( s, ctime( &t ));
  82.     html_tail( s );
  83. }
  84. void web_mem( tcp_Socket *s )
  85. {
  86.     char buffer[ 128 ];
  87.     html_hdr( s, "free memory");
  88.     sprintf( buffer, "There are %lu free bytes.",
  89.         kcorefree());
  90.     sock_puts( s, buffer );
  91.     html_tail( s );
  92. }
  93. /* graph code */
  94. crit_x *graph_cs = NULL;
  95. void web_graph( tcp_Socket *s )
  96. {
  97.     graph_x *g;
  98.     kblock();
  99.     if ( graph_cs == NULL )
  100.         graph_cs = cs_alloc();
  101.     kunblock();
  102.     sock_puts( s, "");
  103.     cs_enter( graph_cs );
  104.     g = gr_alloc( GRWIDTH, GRHEIGHT);
  105.     if ( g != NULL ) {
  106.         gr_background( g, 7 );
  107.         /* put a title on the graph */
  108.         gr_text_at( g , "Web Hits", GRWIDTH/2 - 15, GRHEIGHT - 10, 0 );
  109.         /* we need to lock the data for this time */
  110.         cs_enter( collector_cs );
  111.         last_n_points[ POINTS - 1 ] = curhits;
  112.         gr_linegraph( g, POINTS, last_n_points, NULL, "now", 0, 1 );
  113.         /* we don't need the lock on the data anymore */
  114.         cs_exit( collector_cs );
  115.         sock_mode( s, TCP_MODE_BINARY );
  116.         gr_gif( s, g );     /* write the graph out as a GIF file */
  117.         gr_free( g );
  118.     }
  119.     cs_exit( graph_cs );
  120. }
  121. /*
  122.  * - the web server calls this proc for each web request
  123.  * - it is called in the context of *one* of the HTTPD threads,
  124.  *   though which is not known or important
  125.  * - multiple threads may be in the same proc at the same time
  126.  */
  127. void user_proc( tcp_Socket *s, char *cmd, char *file, char *ext )
  128. {
  129.     /* increment the data points */
  130.     curhits++;
  131.     /* prepare output */
  132.     if ( !stricmp( ext, "gif"))  {
  133.         if ( !stricmp( file, "/graph"))
  134.             web_graph( s );
  135.     } else {
  136.         /* non gif stuff */
  137.         if ( !stricmp( file, "/" )) web_help( s );
  138.         else if ( !stricmp( file, "/time" )) web_time( s );
  139.         else if ( !stricmp( file, "/mem" )) web_mem( s );
  140.         else web_help( s );
  141.     }
  142. }
  143. void mailproc( char *from, char *to, char *subject )
  144. {
  145.     char *p;
  146.     if ( ( p = strchr( to, '@')) != NULL ) *p = 0;
  147.     if ( !stricmp( to, "update") && *subject )
  148.         strcpy( newmsg, subject );
  149. }
  150. main()
  151. {
  152.     int i;
  153.     kdebug = 1;
  154.     rt_init(100);
  155.     kpreemptive = 1;        /* enable pre-emptive multithreading */
  156.     sock_init();            /* initialize network */
  157.     cputs("starting...rn");
  158.     rt_newthread( collector, 1,2048, 0, "collector" );
  159.     rt_newthread( ftpdthread, 1,2048, 0, "ftpd" );
  160.     rt_newthread( smtpdthread, (DWORD)&mailproc, 2048, 0, "smtpd");
  161. #define MAXHTTPD 5
  162.     for ( i = 0 ; i < MAXHTTPD; ++i )
  163.         rt_newthread( httpdthread, (DWORD)&user_proc, 4096, 0, "httpd worker" );
  164.     do {
  165.         /* nothing */
  166.         rt_sleep( 1000 );
  167.     } while ( 1 );
  168. }