00001 // -*- C++ -*- vim:shiftwidth=4 softtabstop=4 tabstop=8 00002 // 00003 // console.cc - This is the main part of the console program, which will attach 00004 // a user on a tty to a long-lived server process providing the access to 00005 // a machine's console. 00006 // 00007 // ***** BEGIN LICENSE BLOCK ***** 00008 // Version: MPL 1.1/GPL 2.0/LGPL 2.1 00009 // 00010 // The contents of this file are subject to the Mozilla Public License 00011 // Version 1.1 (the "License"); you may not use this file except in 00012 // compliance with the License. You may obtain a copy of the License at 00013 // http://www.mozilla.org/MPL/ 00014 // 00015 // Software distributed under the License is distributed on an "AS IS" 00016 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 // the License for the specific language governing rights and limitations 00018 // under the License. 00019 // 00020 // The Original Code is the consmgr network/serial-line monitoring package. 00021 // 00022 // The Initial Developer of the Original Code is Chris P. Ross. 00023 // Portions created by the Initial Developer are Copyright (C) 2000-2008 00024 // the Initial Developer. All Rights Reserved. 00025 // 00026 // Contributor(s): 00027 // 00028 // Alternatively, the contents of this file may be used under the terms of 00029 // either the GNU General Public License Version 2 or later (the "GPL"), or 00030 // the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 00031 // in which case the provisions of the GPL or the LGPL are applicable instead 00032 // of those above. If you wish to allow use of your version of this file only 00033 // under the terms of either the GPL or the LGPL, and not to allow others to 00034 // use your version of this file under the terms of the MPL, indicate your 00035 // decision by deleting the provisions above and replace them with the notice 00036 // and other provisions required by the GPL or the LGPL. If you do not delete 00037 // the provisions above, a recipient may use your version of this file under 00038 // the terms of any one of the MPL, the GPL or the LGPL. 00039 // 00040 // ***** END LICENSE BLOCK ***** 00041 00042 extern "C" { 00043 #include <unistd.h> 00044 #include <sys/types.h> 00045 #include <fcntl.h> 00046 } 00047 00048 #include <fstream> 00049 00050 #include "consmgr.h" 00051 #include "cmconfig.h" 00052 #include "mastercont.h" 00053 00054 // Internal functions... 00055 static void usage(void); 00056 00057 #if 0 00058 // This is declared here, globally, so that exit(3) will cause its destructor 00059 // to run. If it's a stack variable in main(), this does not happen... :-/ 00060 static UserTTYConn tty; 00061 #endif 00062 00063 int 00064 main(int argc, char *argv[]) 00065 { 00066 int ch; 00067 00068 // Shut off clog until we parse options... 00069 std::ofstream *null = new std::ofstream("/dev/null"); 00070 clog.rdbuf(null->rdbuf()); 00071 00072 bool debug = false; 00073 Config *cnf = NULL; 00074 00075 // ConfigFactory::config_object() may throw exceptions 00076 try { 00077 while ((ch = getopt(argc, argv, "c:Dv")) != -1) { 00078 switch (ch) { 00079 case 'c': 00080 if (cnf) 00081 err(6,"Only able to use one configuration" \ 00082 " file [currently]"); 00083 else 00084 cnf = ConfigFactory::config_object(optarg); 00085 break; 00086 case 'D': 00087 debug = true; 00088 break; 00089 case 'v': 00090 std::cout << "console, part of consmgr, built " << __DATE__ 00091 << " " << __TIME__ << endl; 00092 break; 00093 case '?': 00094 usage(); 00095 exit(1); 00096 } 00097 } 00098 00099 if (cnf == NULL) 00100 cnf = ConfigFactory::config_object("/etc/consmgr.conf"); 00101 00102 argc -= optind; 00103 argv += optind; 00104 00105 if (argc != 1) { 00106 usage(); 00107 exit(1); 00108 } 00109 } catch (const string &error) { 00110 cerr << error << endl; 00111 exit(7); 00112 } catch (ConfigException &e) { 00113 cerr << "Config exception: " << e.what() << endl; 00114 exit(7); 00115 } catch (...) { 00116 cerr << "Other random exception thrown while parsing arguments" 00117 << endl; 00118 exit(7); 00119 } 00120 00121 // Set up the debugging stream to go to stderr, and nuke the 00122 // temporary null out we made for it... 00123 if (debug) { 00124 clog.rdbuf(cerr.rdbuf()); 00125 delete null; 00126 } 00127 00128 // Check the config for the specified connection. 00129 try { 00130 cnf->load_entry(argv[0]); 00131 } CATCH_STR_OR_DIE(2) { 00132 cerr << "** Uncaught exception from Config::load_entry(" << argv[0] 00133 << ")!!" << endl; 00134 exit(2); 00135 } 00136 00137 /* Not sure exactly what error are we looking for, here? 00138 if (cnf->??) { 00139 std::cerr << "No available configuration to find '" << argv[0] 00140 << "'. Please check the config file(s)." << std::endl; 00141 exit(3); 00142 } 00143 */ 00144 00145 // OK, we're set. Start up the MasterController, which does all the work. 00146 ConfigP config(cnf); // This is safe because cnf was dyn. allocated 00147 MasterController::run(config); 00148 00149 clog << "MasterControll::run() returned, return()ing from main" << endl; 00150 00151 // Calling exit(3) here will not call the destructors for any objects 00152 // declared in/on main()s stack. :-/ 00153 return(0); 00154 } 00155 00156 static void 00157 usage(void) 00158 { 00159 cerr << "Usage: " << __progname << " [-D] [-c <config-file>]" 00160 << " <connection-name>" << endl; 00161 return; 00162 } 00163