00001 // 00002 // plumbing - C++ wrapper facades for Berkeley sockets 00003 // Copyright (C) 2009, 2010 Peter Miller 00004 // 00005 // This program is free software; you can redistribute it and/or modify it 00006 // under the terms of the GNU General Public License, version 3, as published 00007 // by the Free Software Foundation. 00008 // 00009 // This program is distributed in the hope that it will be useful, but WITHOUT 00010 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00012 // more details. 00013 // 00014 // You should have received a copy of the GNU General Public License along with 00015 // this program. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 #include <libplumbing/config.h> 00019 #include <cstdio> 00020 #include <cstdlib> 00021 #include <unistd.h> 00022 #include <libexplain/fork.h> 00023 00024 #include <libplumbing/reactor.h> 00025 #include <libplumbing/endpoint/listener/daytime.h> 00026 #include <libplumbing/logging/syslog.h> 00027 #include <libplumbing/progname.h> 00028 #include <libplumbing/version_print.h> 00029 00030 00031 static void 00032 usage() 00033 { 00034 std::string prog = plumbing::progname_get(); 00035 fprintf(stderr, "Usage: %s [ <option>... ]\n", prog.c_str()); 00036 fprintf(stderr, " %s -V\n", prog.c_str()); 00037 exit(1); 00038 } 00039 00040 00041 int 00042 main(int argc, char **argv) 00043 { 00044 std::string port_num; 00045 plumbing::progname_set(argv[0]); 00046 bool debug = false; 00047 int repeat_count = -1; 00048 for (;;) 00049 { 00050 int c = getopt(argc, argv, "adp:V"); 00051 if (c == EOF) 00052 break; 00053 switch (c) 00054 { 00055 case 'a': 00056 repeat_count = 1; 00057 break; 00058 00059 case 'd': 00060 debug = true; 00061 break; 00062 00063 case 'p': 00064 port_num = optarg; 00065 break; 00066 00067 case 'V': 00068 plumbing::version_print(); 00069 return 0; 00070 00071 default: 00072 usage(); 00073 } 00074 } 00075 if (optind != argc) 00076 usage(); 00077 00078 // 00079 // The debug command line option says to stay in the foreground, and 00080 // send errors to stderr. Otherwise, we redirect logging to syslog. 00081 // 00082 if (!debug) 00083 { 00084 if (explain_fork_or_die()) 00085 return 0; 00086 plumbing::logging::register_stream(new plumbing::logging_syslog()); 00087 } 00088 00089 // 00090 // 00091 // This is the simplest reactor main loop that can be achieved with 00092 // the Plumbing library. 00093 // 00094 // The reactor is instantiated, the endpoint is created, and the 00095 // reactor is told to manage the endpoint. The endpoint we create 00096 // is a listener, and when it accepts a connection it creates a new 00097 // server endpoint. Now the reactor manages both of them, or as many 00098 // as are simultaneously connected. When a server is done, the 00099 // reactor will destroy it. 00100 // 00101 // The reactor then runs until there are no more endpoints to be 00102 // managed. Because there will always be a listener, it never returns. 00103 // 00104 plumbing::reactor fat_controller; 00105 plumbing::endpoint_listener::pointer thomas = 00106 plumbing::endpoint_listener_daytime::create 00107 ( 00108 fat_controller, 00109 port_num, 00110 repeat_count 00111 ); 00112 fat_controller.add_endpoint(thomas); 00113 fat_controller.run(); 00114 return 0; 00115 } 00116 00117 00118 // vim: set tw=8 sw=4 et