OSDN Git Service

#370,#398,#430,#391
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / src / l7vsadm.cpp
1 /*!
2  *    @file    l7vsadm.cpp
3  *    @brief    l7vsadm command is l7vsd control application
4  *
5  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6  * Copyright (C) 2009  NTT COMWARE Corporation.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  **********************************************************************/
24
25 #include <iostream>
26 #include <sstream>
27 #include <exception>
28 #include <boost/bind.hpp>
29 #include <boost/archive/text_oarchive.hpp>
30 #include <boost/archive/text_iarchive.hpp>
31 #include <boost/format.hpp>
32 #include <boost/algorithm/string.hpp>
33 #include <sys/file.h>
34 #include "l7vsadm.h"
35 #include "logger.h"
36 #include "parameter.h"
37 #include "protocol_module_control.h"
38 #include "schedule_module_control.h"
39 #include "virtualservice_element.h"
40 #include "logger_access_manager.h"
41
42 #define VS_CONTACT_CLASS_SSL (0x00000001)
43
44 // global function prototype
45 static void    sig_exit_handler(int sig);
46 static int    set_sighandler(int sig, void (*handler)(int));
47 static int    set_sighandlers();
48
49 // global variables
50 static bool    signal_flag = false;
51 static int    received_sig = 0;
52
53 //
54 // command functions.
55 //
56 //! list command parsing.
57 //! @param[in]    request command
58 //! @param[in]    argument count
59 //! @param[in]    argument value
60 bool    l7vs::l7vsadm::parse_list_func(    l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char* argv[] ){
61     Logger    logger( LOG_CAT_L7VSADM_COMMON, 1, "l7vsadm::parse_list_func", __FILE__, __LINE__ );
62
63     request.command = cmd;    // set command
64     if( argc < 3 ) return true;    // option is none. this pattern is true
65
66     if( argc > 3 ){
67         std::stringstream buf;
68         buf << "Argument argc is illegal for " << argv[1] << " command.";
69         l7vsadm_err.setter( true, buf.str() );
70         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 117, buf.str(), __FILE__, __LINE__ );
71         return false;
72     }
73
74     for( int pos = 2; pos < argc; ++pos ){     //search option function from argv strings
75         parse_opt_map_type::iterator itr = list_option_dic.find( argv[pos] );
76         if( itr != list_option_dic.end() ){    // option string function find.
77             if( ! itr->second( pos, argc, argv ) ) return false;    // option string function error.
78         }
79         else{    //option string function don't find.
80             // print option not found message.
81             std::stringstream buf;
82             buf << "list option not found:" << argv[pos];
83             l7vsadm_err.setter( true, buf.str() );
84             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 1, buf.str(), __FILE__, __LINE__ );
85             return false;
86         }
87     }
88     return true;
89 }
90 //
91 // option list functions.
92 //
93 //! list numeric flag check.
94 //! @param[in]    argument position
95 //! @param[in]    argument count
96 //! @param[in]    argument value
97 bool    l7vs::l7vsadm::parse_opt_list_numeric_func( int& pos, int argc, char* argv[] ){
98     Logger    logger( LOG_CAT_L7VSADM_COMMON, 2, "l7vsadm::parse_opt_list_numeric_func", __FILE__, __LINE__ );
99
100     numeric_flag = true;    //numeric flag on.
101     return true;
102 }
103
104 //! virtualservice command parsing.
105 //! @param[in]    request command
106 //! @param[in]    argument count
107 //! @param[in]    argument value
108 bool    l7vs::l7vsadm::parse_vs_func( l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char* argv[] ){
109     Logger    logger( LOG_CAT_L7VSADM_COMMON, 3, "l7vsadm::parse_vs_func", __FILE__, __LINE__ );
110
111     request.command = cmd;    // set command
112     if( l7vsadm_request::CMD_FLUSH_VS == cmd ){
113         if( argc != 2 ){
114             std::stringstream buf;
115             buf << "Argument argc is illegal for " << argv[1] << " command.";
116             l7vsadm_err.setter( true, buf.str() );
117             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 118, buf.str(), __FILE__, __LINE__ );
118             return false;
119         }
120     }else{
121         if( argc < 6 ){
122             std::stringstream buf;
123             buf << "Argument argc is illegal for " << argv[1] << " command.";
124             l7vsadm_err.setter( true, buf.str() );
125             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 119, buf.str(), __FILE__, __LINE__ );
126             return false;
127         }
128     }
129
130     std::map< std::string, int > count_map;
131
132     for(parse_opt_map_type::iterator itr = vs_option_dic.begin() ;
133         itr != vs_option_dic.end() ; ++itr ){
134         count_map[ itr->first ] = 0;
135     }
136
137     for( int pos = 2; pos < argc; ++pos ){    // check options.
138         parse_opt_map_type::iterator itr = vs_option_dic.find( argv[pos] );
139         if( itr != vs_option_dic.end() ){    // find option
140             count_map[ itr->first ]++;
141             if( ! itr->second( pos, argc, argv ) ) return false;    // option function execute.
142         }
143         else{    // don't find option function.
144             std::stringstream buf;
145             buf << "virtualservice option not found:" << argv[pos];
146             l7vsadm_err.setter( true, buf.str() );
147             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 2, buf.str(), __FILE__, __LINE__ );
148             return false;
149         }
150     }
151     // check virtualservice on response
152     //
153     if( l7vsadm_request::CMD_FLUSH_VS == cmd ){
154         // flushvs required no option
155         return true;
156     }
157     if( ( l7vsadm_request::CMD_ADD_VS == cmd ) && ( request.vs_element.schedule_module_name.length() == 0 ) ){
158         //scheduler module not specified
159         //scheduler module check.
160         std::string    scheduler_name = L7VSADM_DEFAULT_SCHEDULER;        //default scheduler
161         schedule_module_control&    ctrl = schedule_module_control::getInstance();
162         ctrl.initialize( L7VS_MODULE_PATH );
163         schedule_module_base* module;
164         try{
165             module = ctrl.load_module( scheduler_name );
166         }
167         catch( ... ){
168             std::stringstream buf;
169             buf << "scheduler module load error:" << scheduler_name;
170             l7vsadm_err.setter( true, buf.str() );
171             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 3, buf.str(), __FILE__, __LINE__ );
172             return false;
173         }
174         if( !module ){
175             // don't find schedule module
176             std::stringstream buf;
177             buf << "scheduler module not found:" << scheduler_name;
178             l7vsadm_err.setter( true, buf.str() );
179             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 4, buf.str(), __FILE__, __LINE__ );
180             return false;
181         }
182         ctrl.unload_module( module );
183         request.vs_element.schedule_module_name = scheduler_name;
184     }
185     if( request.vs_element.protocol_module_name.length() == 0 ){
186         //protocol module name error
187         std::string    buf("protocol module not specified.");
188         l7vsadm_err.setter( true, buf );
189         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 5, buf, __FILE__, __LINE__ );
190         return false;
191     }
192     if( request.vs_element.udpmode ){
193         if( request.vs_element.udp_recv_endpoint == boost::asio::ip::udp::endpoint() ){
194             // udp mode,but not acceptor endpoint
195             std::string buf("udp recv endpoint not specified.");
196             l7vsadm_err.setter( true, buf );
197             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 6, buf, __FILE__, __LINE__ );
198             return false;
199         }
200     }
201     else{
202         if( request.vs_element.tcp_accept_endpoint == boost::asio::ip::tcp::endpoint() ){
203             // tcp mode, but not acceptor endpoint
204             std::string buf("tcp accpeptor endpoint not specified.");
205             l7vsadm_err.setter( true, buf );
206             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 7, buf, __FILE__, __LINE__ );
207             return false;
208         }
209     }
210     if( 0 > request.vs_element.sorry_maxconnection ){
211         std::string    buf("invalid sorry_maxconnection value.");
212         l7vsadm_err.setter( true, buf );
213         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 8, buf, __FILE__, __LINE__ );
214         return false;
215     }
216
217     if( ( l7vsadm_request::CMD_ADD_VS == cmd ) &&
218         ( request.vs_element.access_log_flag == 1 ) && ( request.vs_element.access_log_file_name.length() == 0 ) ){
219         std::string    buf("access log file is not specified.");
220         l7vsadm_err.setter( true, buf );
221         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 89, buf, __FILE__, __LINE__ );
222         return false;
223     }
224     if( l7vsadm_request::CMD_EDIT_VS == cmd){
225         // Existence check of the parameter
226         if( count_map["-s"] == 0 &&
227             count_map["--scheduler"] == 0 &&
228             count_map["-u"] == 0 &&
229             count_map["--upper"] == 0 &&
230             count_map["-b"] == 0 &&
231             count_map["--bypass"] == 0 &&
232             count_map["-f"] == 0 &&
233             count_map["--flag"] == 0 &&
234             count_map["-Q"] == 0 &&
235             count_map["--qos-up"] == 0 &&
236             count_map["-q"] == 0 &&
237             count_map["--qos-down"] == 0 &&
238             count_map["-L"] == 0 &&
239             count_map["--access-log"] == 0){
240
241             std::string    buf("All option omitted for edit vs command.");
242             l7vsadm_err.setter( true, buf );
243             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 116, buf, __FILE__, __LINE__ );
244             return false;
245         }
246     }
247
248     //conflict check
249     std::string conflict_option_name;
250     bool is_conflict = false;
251
252     for( std::map< std::string, int >::iterator itr = count_map.begin() ;
253         itr != count_map.end() ; ++itr ){
254         if(itr->second > 1){
255             conflict_option_name = itr->first;
256             is_conflict = true;
257             break;
258         }
259     }
260
261     if(is_conflict == false &&  
262         count_map["-t"] == 1 && count_map ["--tcp-service"] == 1){
263         //-t(--tcp-service)
264         conflict_option_name = "--tcp-service";
265         is_conflict = true;
266     }
267     if(is_conflict == false &&  
268         count_map["-m"] == 1 && count_map ["--proto-module"] == 1){
269         //-m(--proto-module)
270         conflict_option_name = "--proto-module";
271         is_conflict = true;
272     }
273     if(is_conflict == false &&  
274         count_map["-s"] == 1 && count_map ["--scheduler"] == 1){
275         //-s(--scheduler)
276         conflict_option_name = "--scheduler";
277         is_conflict = true;
278     }
279     if(is_conflict == false &&  
280         count_map["-u"] == 1 && count_map ["--upper"] == 1){
281         //-u(--upper)
282         conflict_option_name = "--upper";
283         is_conflict = true;
284     }
285     if(is_conflict == false &&  
286         count_map["-b"] == 1 && count_map ["--bypass"] == 1){
287         //-b(--bypass)
288         conflict_option_name = "--bypass";
289         is_conflict = true;
290     }
291     if(is_conflict == false &&  
292         count_map["-f"] == 1 && count_map ["--flag"] == 1){
293         //-f(--flag)
294         conflict_option_name = "--flag";
295         is_conflict = true;
296     }
297     if(is_conflict == false &&  
298         count_map["-Q"] == 1 && count_map ["--qos-up"] == 1){
299         //-Q(--qos-up)
300         conflict_option_name = "--qos-up";
301         is_conflict = true;
302     }
303     if(is_conflict == false &&  
304         count_map["-q"] == 1 && count_map ["--qos-down"] == 1){
305         //-q(--qos-down)
306         conflict_option_name = "--qos-down";
307         is_conflict = true;
308     }
309     if(is_conflict == false &&  
310         count_map["-p"] == 1 && count_map ["--udp"] == 1){
311         //-p(--udp)
312         conflict_option_name = "--udp";
313         is_conflict = true;
314     }
315     if(is_conflict == false &&  
316         count_map["-z"] == 1 && count_map ["--ssl"] == 1){
317         //-z(--ssl)
318         conflict_option_name = "--ssl";
319         is_conflict = true;
320     }
321     if(is_conflict == false &&  
322         count_map["-O"] == 1 && count_map ["--sockopt"] == 1){
323         //-O(--sockopt)
324         conflict_option_name = "--sockopt";
325         is_conflict = true;
326     }
327     if(is_conflict == false &&  
328         count_map["-L"] == 1 && count_map ["--access-log"] == 1){
329         //-L(--access-log)
330         conflict_option_name = "--access-log";
331         is_conflict = true;
332     }
333     if(is_conflict == false &&  
334         count_map["-a"] == 1 && count_map ["--access-log-name"] == 1){
335         //-a(--access-log-name)
336         conflict_option_name = "--access-log-name";
337         is_conflict = true;
338     }
339
340     if( is_conflict == true ){
341         std::stringstream buf;
342         buf << "Option " << conflict_option_name << " is conflict.";
343         l7vsadm_err.setter( true, buf.str() );
344         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 120, buf.str(), __FILE__, __LINE__ );
345         return false;
346     }
347
348     return true;
349 }
350 //
351 // option virtualservice functions.
352 //
353 //! target option check
354 //! @param[in]    argument position
355 //! @param[in]    argument count
356 //! @param[in]    argument value
357 bool    l7vs::l7vsadm::parse_opt_vs_target_func( int& pos, int argc, char* argv[] ){
358     Logger    logger( LOG_CAT_L7VSADM_COMMON, 4, "l7vsadm::parse_opt_vs_target_func", __FILE__, __LINE__ );
359
360     if( ++pos >= argc ){
361         //don't target recvaddress:port
362         std::string    buf("target endpoint is not specified.");
363         l7vsadm_err.setter( true, buf );
364         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 9, buf, __FILE__, __LINE__ );
365         return false;
366     }
367     // get host endpoint from string
368     std::string    src_str = argv[pos];
369     if( request.vs_element.udpmode ){
370         error_code    err;
371         request.vs_element.udp_recv_endpoint = string_to_endpoint<boost::asio::ip::udp>( src_str, err );
372         if( err ){
373             std::stringstream buf;
374             buf << "target endpoint parse error:" << err.get_message() << src_str;
375             l7vsadm_err.setter( true, buf.str() );
376             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 10, buf.str(), __FILE__, __LINE__ );
377             return false;
378         }
379         check_endpoint<boost::asio::ip::udp>( request.vs_element.udp_recv_endpoint, true, err );
380         if ( err ){
381             std::stringstream buf;
382             buf << "target endpoint parse error:" << err.get_message() << src_str;
383             l7vsadm_err.setter( true, buf.str() );
384             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 11, buf.str(), __FILE__, __LINE__ );
385             return false;
386         }
387     }
388     else{
389         error_code    err;
390         request.vs_element.tcp_accept_endpoint = string_to_endpoint<boost::asio::ip::tcp>( src_str, err );
391         if( err ){
392             std::stringstream buf;
393             buf << "target endpoint parse error:" << err.get_message() << src_str;
394             l7vsadm_err.setter( true, buf.str() );
395             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 12, buf.str(), __FILE__, __LINE__ );
396             return false;
397         }
398         check_endpoint<boost::asio::ip::tcp>( request.vs_element.tcp_accept_endpoint, true, err );
399         if ( err ){
400             std::stringstream buf;
401             buf << "target endpoint parse error:" << err.get_message() << src_str;
402             l7vsadm_err.setter( true, buf.str() );
403             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 13, buf.str(), __FILE__, __LINE__ );
404             return false;
405         }
406     }
407     return true;
408 }
409 //! module option check
410 //! @param[in]    argument position
411 //! @param[in]    argument count
412 //! @param[in]    argument value
413 bool    l7vs::l7vsadm::parse_opt_vs_module_func( int& pos, int argc, char* argv[] ){
414     Logger    logger( LOG_CAT_L7VSADM_COMMON, 5, "l7vsadm::parse_opt_vs_module_func", __FILE__, __LINE__ );
415     if( ++pos >= argc ){
416         //don't target protomod name.
417         std::string    buf("protomod name is not specified.");
418         l7vsadm_err.setter( true, buf );
419         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 14, buf, __FILE__, __LINE__ );
420         return false;
421     }
422     std::string    module_name = argv[pos];
423     if( L7VS_MODNAME_LEN < module_name.length() ){
424         std::string    buf("protomod name is too long.");
425         l7vsadm_err.setter( true, buf );
426         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 15, buf, __FILE__, __LINE__ );
427         return false;
428     }
429     protocol_module_control&    ctrl = protocol_module_control::getInstance();
430     ctrl.initialize( L7VS_MODULE_PATH );
431     protocol_module_base* module;
432     try{
433         module = ctrl.load_module( module_name );
434     }
435     catch( ... ){
436         std::stringstream buf;
437         buf << "protocol module load error:" << module_name;
438         l7vsadm_err.setter( true, buf.str() );
439         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 16, buf.str(), __FILE__, __LINE__ );
440         return false;
441     }
442     if( !module ){
443         //don't find protocol module.
444         std::stringstream buf;
445         buf << "protocol module not found:" << module_name;
446         l7vsadm_err.setter( true, buf.str() );
447         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 17, buf.str(), __FILE__, __LINE__ );
448         return false;
449     }
450     module->init_logger_functions(
451                     boost::bind( &l7vs::Logger::getLogLevel, l7vs::LOG_CAT_PROTOCOL ),
452                     boost::bind( &l7vs::Logger::putLogFatal, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4 ),
453                     boost::bind( &l7vs::Logger::putLogError, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4 ),
454                     boost::bind( &l7vs::Logger::putLogWarn, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4 ),
455                     boost::bind( &l7vs::Logger::putLogInfo, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4 ),
456                     boost::bind( &l7vs::Logger::putLogDebug, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4 ) );
457     // create module args.
458     std::vector< std::string > module_args;
459     while( true ){
460         if( ++pos == argc ) break; //module option end.
461         parse_opt_map_type::iterator vsitr = vs_option_dic.find( argv[pos] );
462         if( vsitr != vs_option_dic.end() ){
463             --pos;    // back for next option
464             break;    // module option end.
465         }
466         parse_opt_map_type::iterator rsitr = rs_option_dic.find( argv[pos] );
467         if( rsitr != rs_option_dic.end() ){
468             --pos;    // back for next option
469             break;    // module option end.
470         }
471         module_args.push_back( argv[pos] );
472     }
473     protocol_module_base::check_message_result module_message = module->check_parameter( module_args );
474
475     if( !module_message.flag ){
476         // args is not supported.
477         std::stringstream    buf;
478         buf << "protocol module argument error: " << module_message.message;
479         l7vsadm_err.setter( true, buf.str() );
480         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 18, buf.str(), __FILE__, __LINE__ );
481         return false;
482     }
483     request.vs_element.protocol_module_name = module_name;
484     BOOST_FOREACH( std::string str,    module_args ){
485         request.vs_element.protocol_args.push_back( str );
486     }
487     ctrl.unload_module( module );
488
489     return true;
490 }
491
492 //! scheduler option check.
493 //! @param[in]    argument position
494 //! @param[in]    argument count
495 //! @param[in]    argument value
496 bool    l7vs::l7vsadm::parse_opt_vs_scheduler_func( int& pos, int argc, char* argv[] ){
497     Logger    logger( LOG_CAT_L7VSADM_COMMON, 6, "l7vsadm::parse_opt_vs_scheduler_func", __FILE__, __LINE__ );
498
499     if( ++pos >= argc ){
500         // don't target scheduler name.
501         std::string    buf("scheduler name is not specified.");
502         l7vsadm_err.setter( true, buf );
503         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 19, buf, __FILE__, __LINE__ );
504         return false;
505     }
506     //schedule module check.
507     std::string    scheduler_name = argv[pos];
508     if( L7VS_MODNAME_LEN < scheduler_name.length() ){
509         std::string    buf("scheduler name is too long.");
510         l7vsadm_err.setter( true, buf );
511         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 20, buf, __FILE__, __LINE__ );
512         return false;
513     }
514     schedule_module_control&    ctrl = schedule_module_control::getInstance();
515     ctrl.initialize( L7VS_MODULE_PATH );
516     schedule_module_base* module;
517     try{
518         module = ctrl.load_module( scheduler_name );
519     }
520     catch( ... ){
521         std::stringstream buf;
522         buf << "scheduler module load error:" << scheduler_name;
523         l7vsadm_err.setter( true, buf.str() );
524         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 21, buf.str(), __FILE__, __LINE__ );
525         return false;
526     }
527     if( !module ){
528         // don't find schedule module
529         std::stringstream buf;
530         buf << "scheduler module not found:" << scheduler_name;
531         l7vsadm_err.setter( true, buf.str() );
532         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 22, buf.str(), __FILE__, __LINE__ );
533         return false;
534     }
535     ctrl.unload_module( module );
536     request.vs_element.schedule_module_name = scheduler_name;
537     return true;
538 }
539 //! upper flag check
540 //! @param[in]    argument position
541 //! @param[in]    argument count
542 //! @param[in]    argument value
543 bool    l7vs::l7vsadm::parse_opt_vs_upper_func( int& pos, int argc, char* argv[] ){
544     Logger    logger( LOG_CAT_L7VSADM_COMMON, 7, "l7vsadm::parse_opt_vs_upper_func", __FILE__, __LINE__ );
545
546     if( ++pos >= argc ){
547         // don't target maxconnection_num
548         std::string    buf("maxconnection value is not specified.");
549         l7vsadm_err.setter( true, buf );
550         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 23, buf, __FILE__, __LINE__ );
551         return false;
552     }
553     try{
554         request.vs_element.sorry_maxconnection = boost::lexical_cast< long long >( argv[pos] );
555         if( ( 0LL > request.vs_element.sorry_maxconnection ) ||
556             ( 100000LL < request.vs_element.sorry_maxconnection ) ){
557             std::string    buf("invalid sorry_maxconnection value.");
558             l7vsadm_err.setter( true, buf );
559             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 24, buf, __FILE__, __LINE__ );
560             return false;
561         }
562         if( 0LL == request.vs_element.sorry_maxconnection )
563             request.vs_element.sorry_maxconnection = LLONG_MAX;        // clear value
564     }
565     catch( boost::bad_lexical_cast& e ){
566         // don't convert argv[pos] is
567         std::string    buf("invalid sorry_maxconnection value.");
568         l7vsadm_err.setter( true, buf );
569         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 25, buf, __FILE__, __LINE__ );
570         return false;
571     }
572     //check connection limit and zero
573     return true;
574 }
575 //! bypass(SorryServer) option check
576 //! @param[in]    argument position
577 //! @param[in]    argument count
578 //! @param[in]    argument value
579 bool    l7vs::l7vsadm::parse_opt_vs_bypass_func( int& pos, int argc, char* argv[] ){
580     Logger    logger( LOG_CAT_L7VSADM_COMMON, 8, "l7vsadm::parse_opt_vs_bypass_func", __FILE__, __LINE__ );
581
582     if( ++pos >= argc ){
583         //don't target sorryserver:port
584         std::string    buf("sorryserver endpoint is not specified.");
585         l7vsadm_err.setter( true, buf );
586         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 26, buf, __FILE__, __LINE__ );
587         return false;
588     }
589     std::string sorry_endpoint = argv[pos];
590     error_code err;
591     request.vs_element.sorry_endpoint = string_to_endpoint< boost::asio::ip::tcp > ( sorry_endpoint, err );
592     if( err ){
593         std::stringstream buf;
594         buf << "sorryserver endpoint parse error:" << err.get_message() << sorry_endpoint;
595         l7vsadm_err.setter( true, buf.str() );
596         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 27, buf.str(), __FILE__, __LINE__ );
597         return false;
598     }
599     // clear endpoint check
600     if( request.vs_element.sorry_endpoint == boost::asio::ip::tcp::endpoint() ){
601         std::string    clear_endpoint = "255.255.255.255:0";        // clear value
602         request.vs_element.sorry_endpoint = string_to_endpoint< boost::asio::ip::tcp > ( clear_endpoint, err );
603         if( err ){
604             std::stringstream buf;
605             buf << "sorryserver endpoint parse error:" << err.get_message() << clear_endpoint;
606             l7vsadm_err.setter( true, buf.str() );
607             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 28, buf.str(), __FILE__, __LINE__ );
608             return false;
609         }
610     }
611     else{
612         check_endpoint<boost::asio::ip::tcp>( request.vs_element.sorry_endpoint, false, err );
613         if( err ){
614             std::stringstream buf;
615             buf << "sorryserver endpoint parse error:" << err.get_message() << sorry_endpoint;
616             l7vsadm_err.setter( true, buf.str() );
617             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 29, buf.str(), __FILE__, __LINE__ );
618             return false;
619         }
620     }
621     return true;    //
622 }
623 //! virtualservice option flag function
624 //! @param[in]    argument position
625 //! @param[in]    argument count
626 //! @param[in]    argument value
627 bool    l7vs::l7vsadm::parse_opt_vs_flag_func( int& pos, int argc, char* argv[] ){
628     Logger    logger( LOG_CAT_L7VSADM_COMMON, 9, "l7vsadm::parse_opt_vs_flag_func", __FILE__, __LINE__ );
629
630     if( ++pos >= argc ){
631         //don't target sorry flag
632         std::string    buf("sorryflag value is not specified.");
633         l7vsadm_err.setter( true, buf );
634         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 30, buf, __FILE__, __LINE__ );
635         return false;
636     }
637     try{
638         int    tmp = boost::lexical_cast< int >( argv[pos] );
639         if( ( 0 != tmp ) && ( 1 != tmp ) ){
640             std::string    buf("invalid sorryflag value.");
641             l7vsadm_err.setter( true, buf );
642             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 31, buf, __FILE__, __LINE__ );
643             return false;
644         }
645         if( 0 == tmp )
646             request.vs_element.sorry_flag = INT_MAX;    // clear value
647         else
648             request.vs_element.sorry_flag = 1;
649     }
650     catch( boost::bad_lexical_cast& e ){
651         // don't convert argv[pos] is
652         std::string    buf("invalid sorryflag value.");
653         l7vsadm_err.setter( true, buf );
654         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 32, buf, __FILE__, __LINE__ );
655         return false;
656     }
657     return true;    //
658 }
659 //! virtualservice option qosupstream function
660 //! @param[in]    argument position
661 //! @param[in]    argument count
662 //! @param[in]    argument value
663 bool    l7vs::l7vsadm::parse_opt_vs_qosup_func( int& pos, int argc, char* argv[] ){
664     Logger    logger( LOG_CAT_L7VSADM_COMMON, 10, "l7vsadm::parse_opt_vs_qosup_func", __FILE__, __LINE__ );
665
666     if( ++pos >= argc ){
667         //don't rarget QoS upstream value.
668         std::string    buf("qos_upstream value is not specified.");
669         l7vsadm_err.setter( true, buf );
670         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 33, buf, __FILE__, __LINE__ );
671         return false;
672     }
673     try{
674         virtualservice_element& elem = request.vs_element;    // request virtualservice element refalence get.
675         std::string    tmp    = argv[pos];
676         std::string::reverse_iterator ritr = tmp.rbegin();
677         if( *ritr == 'G' || *ritr == 'g' ){
678             std::string    strval = tmp.substr(0, tmp.length() - 1);
679             unsigned long long    ullval    = boost::lexical_cast< unsigned long long > ( strval );
680             if( ullval > 999 ){
681                 std::string    buf("qos_upstream value is too big.");
682                 l7vsadm_err.setter( true, buf );
683                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 34, buf, __FILE__, __LINE__ );
684                 return false;
685             }
686             elem.qos_upstream = ullval * 1000 * 1000 * 1000;        // set qos_upstream
687         }
688         else if( *ritr == 'M' || *ritr == 'm' ){
689             std::string    strval = tmp.substr(0, tmp.length() - 1);
690             unsigned long long    ullval    = boost::lexical_cast< unsigned long long > ( strval );
691             if( ullval > 999 ){
692                 std::string    buf("qos_upstream value is too big.");
693                 l7vsadm_err.setter( true, buf );
694                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 35, buf, __FILE__, __LINE__ );
695                 return false;
696             }
697             elem.qos_upstream = ullval * 1000 * 1000;        // set qos_upstream
698         }
699         else if( *ritr == 'K' || *ritr == 'k' ){
700             std::string    strval = tmp.substr(0, tmp.length() - 1);
701             unsigned long long    ullval    = boost::lexical_cast< unsigned long long > ( strval );
702             if( ullval > 999 ){
703                 std::string    buf("qos_upstream value is too big.");
704                 l7vsadm_err.setter( true, buf );
705                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 36, buf, __FILE__, __LINE__ );
706                 return false;
707             }
708             elem.qos_upstream = ullval * 1000;        // set qos_upstream
709         }
710         else{
711             unsigned long long ullval = boost::lexical_cast< unsigned long long > ( argv[pos] );
712             if( ullval > 999 ){
713                 std::string    buf("qos_upstream value is too big.");
714                 l7vsadm_err.setter( true, buf );
715                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 111, buf, __FILE__, __LINE__ );
716                 return false;
717             }
718             elem.qos_upstream = ullval;    // set qos_upstream
719         }
720         if( 0ULL == elem.qos_upstream ) {
721             elem.qos_upstream = ULLONG_MAX;        // clear value
722         } else {
723             elem.qos_upstream /= 8;                //qos convert to bytes per sec to bit per sec
724         }
725
726     }
727     catch( boost::bad_lexical_cast& ex ){    // don't convert string to qos_upsatream
728         // don't conv qos upstream
729         std::string    buf("invalid qos_upstream value.");
730         l7vsadm_err.setter( true, buf );
731         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 37, buf, __FILE__, __LINE__ );
732         return false;
733     }
734     return true;        
735 }
736 //! virtualservice option qosdownstream functipn
737 //! @param[in]    argument position
738 //! @param[in]    argument count
739 //! @param[in]    argument value
740 bool    l7vs::l7vsadm::parse_opt_vs_qosdown_func( int& pos, int argc, char* argv[] ){
741     Logger    logger( LOG_CAT_L7VSADM_COMMON, 11, "l7vsadm::parse_opt_vs_qosdown_func", __FILE__, __LINE__ );
742
743     if( ++pos >= argc ){
744         // don't target QoS downstream value
745         std::string    buf("qos_downstream value is not specified.");
746         l7vsadm_err.setter( true, buf );
747         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 38, buf, __FILE__, __LINE__ );
748         return false;
749     }
750     try{
751         virtualservice_element& elem = request.vs_element;    // request virtualservice element refalence get.
752         std::string    tmp    = argv[pos];
753         std::string::reverse_iterator ritr = tmp.rbegin();
754         if( *ritr == 'G' || *ritr == 'g' ){
755             std::string    strval = tmp.substr(0, tmp.length() - 1);
756             unsigned long long    ullval    = boost::lexical_cast< unsigned long long > ( strval );
757             if( ullval > 999 ){
758                 std::string    buf("qos_downstream value is too big.");
759                 l7vsadm_err.setter( true, buf );
760                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 39, buf, __FILE__, __LINE__ );
761                 return false;
762             }
763             elem.qos_downstream = ullval * 1000 * 1000 * 1000;        // set qos_upstream
764         }
765         else if( *ritr == 'M' || *ritr == 'm' ){
766             std::string    strval = tmp.substr(0, tmp.length() - 1);
767             unsigned long long    ullval    = boost::lexical_cast< unsigned long long > ( strval );
768             if( ullval > 999 ){
769                 std::string    buf("qos_downstream value is too big.");
770                 l7vsadm_err.setter( true, buf );
771                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 40, buf, __FILE__, __LINE__ );
772                 return false;
773             }
774             elem.qos_downstream = ullval * 1000 * 1000;        // set qos_upstream
775         }
776         else if( *ritr == 'K' || *ritr == 'k' ){
777             std::string    strval = tmp.substr(0, tmp.length() - 1);
778             unsigned long long    ullval    = boost::lexical_cast< unsigned long long > ( strval );
779             if( ullval > 999 ){
780                 std::string    buf("qos_downstream value is too big.");
781                 l7vsadm_err.setter( true, buf );
782                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 41, buf, __FILE__, __LINE__ );
783                 return false;
784             }
785             elem.qos_downstream = ullval * 1000;        // set qos_upstream
786         }
787         else{
788             unsigned long long ullval = boost::lexical_cast< unsigned long long > ( argv[pos] );
789             if( ullval > 999 ){
790                 std::string    buf("qos_downstream value is too big.");
791                 l7vsadm_err.setter( true, buf );
792                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 115, buf, __FILE__, __LINE__ );
793                 return false;
794             }
795             elem.qos_downstream = boost::lexical_cast< unsigned long long > ( argv[pos] );    // set qos_downstream
796         }
797         if( 0ULL == elem.qos_downstream ) {
798             elem.qos_downstream = ULLONG_MAX;        // clear value
799         } else {
800             elem.qos_downstream /= 8;                //qos convert to bytes per sec to bit per sec
801         }
802     }
803     catch( boost::bad_lexical_cast& ex ){
804         // don' conv qos downstream
805         std::string    buf("invalid qos_downstream value.");
806         l7vsadm_err.setter( true, buf );
807         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 42, buf, __FILE__, __LINE__ );
808         return false;
809     }
810     return true;
811 }
812 //! virtualservice option udp func.
813 //! @param[in]    argument position
814 //! @param[in]    argument count
815 //! @param[in]    argument value
816 bool    l7vs::l7vsadm::parse_opt_vs_udp_func( int& pos, int argc, char* argv[] ){
817     Logger    logger( LOG_CAT_L7VSADM_COMMON, 12, "l7vsadm::parse_opt_vs_udp_func", __FILE__, __LINE__ );
818
819     virtualservice_element& elem = request.vs_element;    // request virtualservie element reference get.
820     elem.udpmode = true;    // udpmode on.
821     boost::asio::ip::tcp::endpoint    zeropoint;
822     if( zeropoint != elem.tcp_accept_endpoint ){ // adddress tcp_acceptor endpoint
823         std::stringstream    sstream;
824         sstream    << elem.tcp_accept_endpoint;
825         std::string    endpoint    = sstream.str();
826         error_code err;
827         elem.udp_recv_endpoint = string_to_endpoint<boost::asio::ip::udp>( endpoint, err );
828         if( err ){
829             std::stringstream buf;
830             buf << "target endpoint parse error:" << err.get_message() << endpoint;
831             l7vsadm_err.setter( true, buf.str() );
832             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 43, buf.str(), __FILE__, __LINE__ );
833             return false;
834         }
835         elem.tcp_accept_endpoint = zeropoint;
836     }
837     if( elem.realserver_vector.size() != 0 && elem.realserver_vector.front().tcp_endpoint != zeropoint ){
838         std::stringstream     sstream;
839         sstream << elem.realserver_vector.front().tcp_endpoint;
840         std::string    endpoint = sstream.str();
841         error_code err;
842         elem.realserver_vector.front().udp_endpoint = string_to_endpoint< boost::asio::ip::udp > ( endpoint, err );
843         if( err ){
844             std::stringstream buf;
845             buf << "realserver endpoint parse error:" << err.get_message() << endpoint;
846             l7vsadm_err.setter( true, buf.str() );
847             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 44, buf.str(), __FILE__, __LINE__ );
848             return false;
849         }
850         elem.realserver_vector.front().tcp_endpoint = zeropoint;
851     }
852     return true;
853 }
854 //! virtualservice option ssl_file function
855 //! @param[in]    argument position
856 //! @param[in]    argument count
857 //! @param[in]    argument value
858 bool    l7vs::l7vsadm::parse_opt_vs_ssl_file_func( int& pos, int argc, char* argv[] ){
859     Logger    logger( LOG_CAT_L7VSADM_COMMON, 38, "l7vsadm::parse_opt_vs_ssl_file_func", __FILE__, __LINE__ );
860
861     if( ++pos >= argc ){
862         std::string    buf("ssl config filename is not specified.");
863         l7vsadm_err.setter( true, buf );
864         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 90, buf, __FILE__, __LINE__ );
865         return false;
866     }
867     // ssl config file check.
868     std::string conf_file_name = argv[pos];
869     if( L7VS_FILENAME_LEN < conf_file_name.length() ){
870         std::string buf("ssl config filename is too long.");
871         l7vsadm_err.setter( true, buf );
872         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 91, buf, __FILE__, __LINE__ );
873         return false;
874     }
875     FILE  *fp;
876     if ((fp = fopen(conf_file_name.c_str(), "r")) == NULL) {
877         std::string buf("ssl config file cannot open.");
878         l7vsadm_err.setter( true, buf );
879         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 92, buf, __FILE__, __LINE__ );
880         return false;
881     }
882     fclose(fp);
883
884     if( ( strcmp( argv[ 1 ] , "-A" ) == 0 ) 
885     || ( strcmp( argv[ 1 ] , "--add-service" ) == 0 ) ) {
886         protocol_module_control&        ctrl 
887                 = protocol_module_control::getInstance();
888         ctrl.initialize( L7VS_MODULE_PATH );
889         protocol_module_base* module;
890         try{
891             module 
892                 = ctrl.load_module( request.vs_element.protocol_module_name );
893         }
894         catch( ... ){
895             std::stringstream buf;
896             buf << "protocol module load error:" 
897                 << request.vs_element.protocol_module_name;
898             l7vsadm_err.setter( true, buf.str() );
899             Logger::putLogError( 
900                         LOG_CAT_L7VSADM_PARSE, 
901                         108, 
902                         buf.str(), 
903                         __FILE__, 
904                         __LINE__ );
905             return false;
906         }
907         if( !module ){
908             //don't find protocol module.
909             std::stringstream buf;
910             buf << "protocol module not found:" 
911                 << request.vs_element.protocol_module_name;
912             l7vsadm_err.setter( true, buf.str() );
913             Logger::putLogError( 
914                 LOG_CAT_L7VSADM_PARSE, 
915                 109, buf.str(), 
916                 __FILE__, 
917                 __LINE__ );
918             return false;
919         }
920         
921         bool module_used_flag = module->is_exec_OK( VS_CONTACT_CLASS_SSL );
922         if( module_used_flag == false ) {
923             //don't find protocol module.
924             std::stringstream buf;
925             buf << "When \"protocol_module sslid\" was designated," 
926                 << " it isn't possible to designate \"-z\" option.";
927             l7vsadm_err.setter( true, buf.str() );
928             Logger::putLogError( 
929                 LOG_CAT_L7VSADM_PARSE, 
930                 110, 
931                 buf.str(), 
932                 __FILE__, 
933                 __LINE__ );
934             return false;
935         }
936     }
937
938     request.vs_element.ssl_file_name = conf_file_name;
939     return true;
940 }
941
942 //! virtualservice option access log function
943 //! @param[in]    argument position
944 //! @param[in]    argument count
945 //! @param[in]    argument value
946 bool    l7vs::l7vsadm::parse_opt_vs_access_log_func( int& pos, int argc, char* argv[] ){
947     Logger    logger( LOG_CAT_L7VSADM_COMMON, 39, "l7vsadm::parse_opt_vs_access_log_func", __FILE__, __LINE__ );
948
949     if( ++pos >= argc ){
950         //don't target access log flag
951         std::string    buf("access log flag value is not specified.");
952         l7vsadm_err.setter( true, buf );
953         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 93, buf, __FILE__, __LINE__ );
954         return false;
955     }
956     try{
957         int    tmp = boost::lexical_cast< int >( argv[pos] );
958         if( ( 0 != tmp ) && ( 1 != tmp ) ){
959             std::string    buf("invalid access log flag value.");
960             l7vsadm_err.setter( true, buf );
961             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 94, buf, __FILE__, __LINE__ );
962             return false;
963         }
964         if( 0 == tmp )
965             request.vs_element.access_log_flag = INT_MAX;    // clear value
966         else
967             request.vs_element.access_log_flag = 1;
968     }
969     catch( boost::bad_lexical_cast& e ){
970         // don't convert argv[pos] is
971         std::string    buf("invalid access log flag value.");
972         l7vsadm_err.setter( true, buf );
973         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 95, buf, __FILE__, __LINE__ );
974         return false;
975     }
976     return true;    //
977 }
978
979 //! virtualservice option access_log_logrotate function
980 //! @param[in]    argument position
981 //! @param[in]    argument count
982 //! @param[in]    argument value
983 bool    l7vs::l7vsadm::parse_opt_vs_access_log_logrotate_func( int& pos, int argc, char* argv[] ){
984     Logger    logger( LOG_CAT_L7VSADM_COMMON, 40, "l7vsadm::parse_opt_vs_accesslog_logrotate_func", __FILE__, __LINE__ );
985
986     if( ++pos >= argc ){
987         std::string    buf("access log filename is not specified.");
988         l7vsadm_err.setter( true, buf );
989         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 96, buf, __FILE__, __LINE__ );
990         return false;
991     }
992     // access log file check.
993     std::string access_log_file_name = argv[pos];
994     if( L7VS_FILENAME_LEN < access_log_file_name.length() ){
995         std::string buf("access log filename is too long.");
996         l7vsadm_err.setter( true, buf );
997         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 97, buf, __FILE__, __LINE__ );
998         return false;
999     }
1000     if( "/" != access_log_file_name.substr(0, 1) ){
1001         std::string buf("please specify access log filename in fullpath.");
1002         l7vsadm_err.setter( true, buf );
1003         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 98, buf, __FILE__, __LINE__ );
1004         return false;
1005     }
1006     
1007     // create access log  args.
1008     std::vector< std::string > arguments_vector;
1009     virtualservice_element::access_log_rotate_arguments_map_type arguments_map;
1010     while( true ){
1011         if( ++pos == argc ) break; //access log arguments end.
1012         parse_opt_map_type::iterator vsitr = vs_option_dic.find( argv[pos] );
1013         if( vsitr != vs_option_dic.end() ){
1014             --pos;    // back for next option
1015             break;    // module option end.
1016         }
1017         arguments_vector.push_back( argv[pos] );
1018     }
1019     if( 0 < arguments_vector.size() ){
1020         if( 0 == ( arguments_vector.size() % 2 ) ){
1021             for( unsigned int i = 0; i < ( arguments_vector.size() - 1 ); ++i ){
1022                 std::pair< virtualservice_element::access_log_rotate_arguments_map_type::iterator, bool > ret =
1023                 arguments_map.insert(
1024                     virtualservice_element::access_log_rotate_arguments_pair_type(
1025                         arguments_vector[i], arguments_vector[i+1] ) );
1026                 if( !ret.second ){
1027                     std::string buf("access log rotation argument is duplicated.");
1028                     l7vsadm_err.setter( true, buf );
1029                     Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 99, buf, __FILE__, __LINE__ );
1030                     return false;
1031                 }
1032                 ++i;
1033             }
1034         }
1035         else{
1036             std::string buf("access log rotation argument error.");
1037             l7vsadm_err.setter( true, buf );
1038             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 100, buf, __FILE__, __LINE__ );
1039             return false;
1040         }
1041         bool ret = logger_access_manager::getInstance().access_log_logrotate_parameter_check( arguments_map );
1042         if( !ret ){
1043             std::string buf("access log rotation argument error.");
1044             l7vsadm_err.setter( true, buf );
1045             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 101, buf, __FILE__, __LINE__ );
1046             return false;
1047         }
1048     }
1049     
1050     request.vs_element.access_log_file_name = access_log_file_name;
1051     request.vs_element.access_log_rotate_arguments.clear();
1052     request.vs_element.access_log_rotate_key_info = "";
1053     BOOST_FOREACH( virtualservice_element::access_log_rotate_arguments_pair_type pair, arguments_map ){
1054         request.vs_element.access_log_rotate_arguments.insert( pair );
1055         request.vs_element.access_log_rotate_key_info += pair.first + " " + pair.second + " ";
1056     }
1057     boost::algorithm::erase_last( request.vs_element.access_log_rotate_key_info , " " );
1058
1059     return true;
1060 }
1061
1062 //! virtualservice option socket function
1063 //! @param[in]    argument position
1064 //! @param[in]    argument count
1065 //! @param[in]    argument value
1066 bool    l7vs::l7vsadm::parse_opt_vs_socket_func( int& pos, int argc, char* argv[] ){
1067     Logger    logger( LOG_CAT_L7VSADM_COMMON, 41, "l7vsadm::parse_opt_vs_socket_func", __FILE__, __LINE__ );
1068
1069     if( ++pos >= argc ){
1070         std::string    buf("socket_option is not specified.");
1071         l7vsadm_err.setter( true, buf );
1072         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 102, buf, __FILE__, __LINE__ );
1073         return false;
1074     }
1075
1076     bool is_set_defer_accept = false;
1077     bool is_set_nodelay = false;
1078     bool is_set_cork = false;
1079     bool is_set_quickack = false;
1080
1081     request.vs_element.socket_option_tcp_defer_accept = 0;
1082     request.vs_element.socket_option_tcp_nodelay = 0;
1083     request.vs_element.socket_option_tcp_cork = 0;
1084     request.vs_element.socket_option_tcp_quickack = 0;
1085
1086     std::string socket_option_string = argv[pos];
1087     std::vector< std::string > socket_options;
1088     boost::split( socket_options, socket_option_string, boost::algorithm::is_any_of( "," ) );
1089
1090     BOOST_FOREACH( std::string option, socket_options ){
1091         if( option == "deferaccept" ){
1092             if( !is_set_defer_accept ){
1093                 is_set_defer_accept = true;
1094                 request.vs_element.socket_option_tcp_defer_accept = 1;
1095             }
1096             else{
1097                 // defer_accept is duplicated
1098                 std::stringstream buf;
1099                 buf << "socket option deferaccept is duplicated.";
1100                 l7vsadm_err.setter( true, buf.str() );
1101                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 103, buf.str(), __FILE__, __LINE__ );
1102                 return false;
1103             }
1104         }
1105         else if(option == "nodelay" ) {
1106             if( !is_set_nodelay ){
1107                 is_set_nodelay = true;
1108                 request.vs_element.socket_option_tcp_nodelay = 1;
1109             }
1110             else{
1111                 // nodelay is duplicated
1112                 std::stringstream buf;
1113                 buf << "socket option nodelay is duplicated.";
1114                 l7vsadm_err.setter( true, buf.str() );
1115                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 104, buf.str(), __FILE__, __LINE__ );
1116                 return false;
1117             }
1118         }
1119         else if(option == "cork" ) {
1120             if( !is_set_cork ){
1121                 is_set_cork = true;
1122                 request.vs_element.socket_option_tcp_cork = 1;
1123             }
1124             else{
1125                 // cork is duplicated
1126                 std::stringstream buf;
1127                 buf << "socket option cork is duplicated.";
1128                 l7vsadm_err.setter( true, buf.str() );
1129                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 105, buf.str(), __FILE__, __LINE__ );
1130                 return false;
1131             }
1132         }
1133         else if( option == "quickackon" || option == "quickackoff" ) {
1134             if( !is_set_quickack ){
1135                 is_set_quickack = true;
1136                 request.vs_element.socket_option_tcp_quickack = ( ( option == "quickackon" ) ? 1 : 2 );
1137             }
1138             else{
1139                 // quickack is duplicated
1140                 std::stringstream buf;
1141                 buf << "socket option quickack is duplicated.";
1142                 l7vsadm_err.setter( true, buf.str() );
1143                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 106, buf.str(), __FILE__, __LINE__ );
1144                 return false;
1145             }
1146         }
1147         else{
1148             // unknown socket option
1149             std::stringstream buf;
1150             buf << "unknown socket option.";
1151             l7vsadm_err.setter( true, buf.str() );
1152             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 107, buf.str(), __FILE__, __LINE__ );
1153             return false;
1154         }
1155     }
1156
1157     request.vs_element.socket_option_string = socket_option_string;
1158     return true;
1159
1160 }
1161 //! realserver command parsing.
1162 //! @param[in]    request command
1163 //! @param[in]    argument count
1164 //! @param[in]    argument value
1165 bool    l7vs::l7vsadm::parse_rs_func( l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char* argv[] ){
1166     Logger    logger( LOG_CAT_L7VSADM_COMMON, 13, "l7vsadm::parse_rs_func", __FILE__, __LINE__ );
1167
1168     if( argc < 8 ) {
1169         //argument num err
1170         std::stringstream buf;
1171         buf << "Argument argc is illegal for ";
1172         buf << argv[1];
1173         buf << " command.";
1174         
1175         l7vsadm_err.setter( true, buf.str() );
1176         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 121, buf.str(), __FILE__, __LINE__ );
1177         return false;
1178     }
1179
1180     request.command = cmd;
1181
1182     request.vs_element.realserver_vector.push_back( realserver_element() );
1183
1184     std::map< std::string, int > count_map;
1185     for(parse_opt_map_type::iterator itr = rs_option_dic.begin() ;
1186         itr != rs_option_dic.end() ; ++itr ){
1187         count_map[ itr->first ] = 0;
1188     }
1189
1190     for( int pos = 2; pos < argc; ++pos ){
1191         parse_opt_map_type::iterator itr = rs_option_dic.find( argv[pos] );
1192         if( itr != rs_option_dic.end() ){
1193             count_map[ itr->first ]++;
1194             if( ! itr->second( pos, argc, argv ) ) return false;
1195         }
1196         else{
1197             std::stringstream buf;
1198             buf << "realserver option not found:" << argv[pos];
1199             l7vsadm_err.setter( true, buf.str() );
1200             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 45, buf.str(), __FILE__, __LINE__ );
1201             return false;
1202         }
1203     }
1204
1205     if( request.vs_element.protocol_module_name.length() == 0 ){
1206         //protocol module name error
1207         std::string    buf("protocol module not specified.");
1208         l7vsadm_err.setter( true, buf );
1209         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 46, buf, __FILE__, __LINE__ );
1210         return false;
1211     }
1212     if( request.vs_element.udpmode ){
1213         if( request.vs_element.udp_recv_endpoint == boost::asio::ip::udp::endpoint() ){
1214             // udp mode,but not acceptor endpoint
1215             std::string    buf("udp recv endpoint not specified.");
1216             l7vsadm_err.setter( true, buf );
1217             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 47, buf, __FILE__, __LINE__ );
1218             return false;
1219         }
1220         if( request.vs_element.realserver_vector.front().udp_endpoint == boost::asio::ip::udp::endpoint() ){
1221             // udp mode,but not realserver endpoint
1222             std::string    buf("realserver udp endpoint not specified.");
1223             l7vsadm_err.setter( true, buf );
1224             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 48, buf, __FILE__, __LINE__ );
1225             return false;
1226         }
1227     }
1228     else{
1229         if( request.vs_element.tcp_accept_endpoint == boost::asio::ip::tcp::endpoint() ){
1230             // tcp mode, but not acceptor endpoint
1231             std::string    buf("tcp accpeptor endpoint not specified.");
1232             l7vsadm_err.setter( true, buf );
1233             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 49, buf, __FILE__, __LINE__ );
1234             return false;
1235         }
1236         if( request.vs_element.realserver_vector.front().tcp_endpoint == boost::asio::ip::tcp::endpoint() ){
1237             // tcp mode,but not realserver endpoint
1238             std::string    buf("realserver tcp endpoint not specified.");
1239             l7vsadm_err.setter( true, buf );
1240             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 50, buf, __FILE__, __LINE__ );
1241             return false;
1242         }
1243     }
1244
1245     if( l7vsadm_request::CMD_EDIT_RS != cmd ) {
1246         // realserver weight default value = 1
1247         if( -1 == request.vs_element.realserver_vector.front().weight ){
1248             request.vs_element.realserver_vector.front().weight = 1;
1249         }
1250     }
1251
1252     //conflict check
1253     std::string conflict_option_name;
1254     bool is_conflict = false;
1255
1256     for( std::map< std::string, int >::iterator itr = count_map.begin() ;
1257         itr != count_map.end() ; ++itr ){
1258         if(itr->second > 1){
1259             conflict_option_name = itr->first;
1260             is_conflict = true;
1261             break;
1262         }
1263     }
1264
1265     if(is_conflict == false &&  
1266         count_map["-t"] == 1 && count_map ["--tcp-service"] == 1){
1267         //-t(--tcp-service)
1268         conflict_option_name = "--tcp-service";
1269         is_conflict = true;
1270     }
1271     if(is_conflict == false &&  
1272         count_map["-m"] == 1 && count_map ["--proto-module"] == 1){
1273         //-m(--proto-module)
1274         conflict_option_name = "--proto-module";
1275         is_conflict = true;
1276     }
1277     if(is_conflict == false &&  
1278         count_map["-r"] == 1 && count_map ["--real-server"] == 1){
1279         //-r(--real-server)
1280         conflict_option_name = "--real-server";
1281         is_conflict = true;
1282     }
1283     if( (is_conflict == false) &&  
1284         (count_map["-w"] == 1) && (count_map ["--weight"] == 1) && 
1285         (l7vsadm_request::CMD_DEL_RS != cmd) ){
1286         //-w(--weight)
1287         conflict_option_name = "--weight";
1288         is_conflict = true;
1289     }
1290     
1291     if( is_conflict == true ){
1292         std::stringstream buf;
1293         buf << "Option " << conflict_option_name << " is conflict.";
1294         l7vsadm_err.setter( true, buf.str() );
1295         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 122, buf.str(), __FILE__, __LINE__ );
1296         return false;
1297     }
1298
1299     return true;
1300 }
1301 //
1302 // realserver option functions.
1303 //
1304 //! realserver weight set
1305 //! @param[in]    argument position
1306 //! @param[in]    argument count
1307 //! @param[in]    argument value
1308 bool    l7vs::l7vsadm::parse_opt_rs_weight_func( int& pos, int argc, char* argv[] ){
1309     Logger    logger( LOG_CAT_L7VSADM_COMMON, 14, "l7vsadm::parse_opt_rs_weight_func", __FILE__, __LINE__ );
1310
1311     if( ++pos >= argc ){
1312         //don't target weight value
1313         std::string    buf("weight value is not specified.");
1314         l7vsadm_err.setter( true, buf );
1315         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 51, buf, __FILE__, __LINE__ );
1316         return false;
1317     }
1318     try{
1319         request.vs_element.realserver_vector.front().weight = boost::lexical_cast<int>( argv[pos] );
1320         if( ( 0 > request.vs_element.realserver_vector.front().weight ) ||
1321             ( 100 < request.vs_element.realserver_vector.front().weight ) ){
1322             std::string    buf("invalid weight value.");
1323             l7vsadm_err.setter( true, buf );
1324             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 52, buf, __FILE__, __LINE__ );
1325             return false;
1326         }
1327     }
1328     catch( boost::bad_lexical_cast& ex ){
1329         // lexical cast error
1330         std::string    buf("invalid weight value.");
1331         l7vsadm_err.setter( true, buf );
1332         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 53, buf, __FILE__, __LINE__ );
1333         return false;
1334     }
1335     return true;
1336 }
1337 //! realserver target set
1338 //! @param[in]    argument position
1339 //! @param[in]    argument count
1340 //! @param[in]    argument value
1341 bool    l7vs::l7vsadm::parse_opt_rs_realserver_func( int& pos, int argc, char* argv[] ){
1342     Logger    logger( LOG_CAT_L7VSADM_COMMON, 15, "l7vsadm::parse_opt_rs_realserver_func", __FILE__, __LINE__ );
1343
1344     if( ++pos >= argc ){
1345         // don't target realserver address
1346         std::string    buf("realserver address is not specified.");
1347         l7vsadm_err.setter( true, buf );
1348         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 54, buf, __FILE__, __LINE__ );
1349         return false;
1350     }
1351     std::string    src_str = argv[pos];
1352     if( request.vs_element.udpmode ){
1353         error_code err;
1354         request.vs_element.realserver_vector.front().udp_endpoint = string_to_endpoint< boost::asio::ip::udp >( src_str, err );
1355         if ( err ){
1356             // address string error.
1357             std::stringstream buf;
1358             buf << "realserver endpoint parse error:" << err.get_message() << src_str;
1359             l7vsadm_err.setter( true, buf.str() );
1360             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 55, buf.str(), __FILE__, __LINE__ );
1361             return false;
1362         }
1363         check_endpoint<boost::asio::ip::udp>( request.vs_element.realserver_vector.front().udp_endpoint, false, err );
1364         if ( err ){
1365             std::stringstream buf;
1366             buf << "realserver endpoint parse error:" << err.get_message() << src_str;
1367             l7vsadm_err.setter( true, buf.str() );
1368             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 56, buf.str(), __FILE__, __LINE__ );
1369             return false;
1370         }
1371     }
1372     else{
1373         error_code err;
1374         request.vs_element.realserver_vector.front().tcp_endpoint = string_to_endpoint< boost::asio::ip::tcp >( src_str, err );
1375         if ( err ){
1376             // address string error.
1377             std::stringstream buf;
1378             buf << "realserver endpoint parse error:" << err.get_message() << src_str;
1379             l7vsadm_err.setter( true, buf.str() );
1380             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 57, buf.str(), __FILE__, __LINE__ );
1381             return false;
1382         }
1383         check_endpoint<boost::asio::ip::tcp>( request.vs_element.realserver_vector.front().tcp_endpoint, false, err );
1384         if ( err ){
1385             std::stringstream buf;
1386             buf << "realserver endpoint parse error:" << err.get_message() << src_str;
1387             l7vsadm_err.setter( true, buf.str() );
1388             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 58, buf.str(), __FILE__, __LINE__ );
1389             return false;
1390         }
1391     }
1392     return true;
1393 }
1394     
1395 //! replication command parsing.
1396 //! @param[in]    request command
1397 //! @param[in]    argument count
1398 //! @param[in]    argument value
1399 bool    l7vs::l7vsadm::parse_replication_func( l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char* argv[] ){
1400     Logger    logger( LOG_CAT_L7VSADM_COMMON, 16, "l7vsadm::parse_replication_func", __FILE__, __LINE__ );
1401
1402     if( argc < 3 || argc > 4 ) {
1403         //argument num err
1404         std::stringstream buf;
1405         buf << "Argument argc is illegal for ";
1406         buf << argv[1];
1407         buf << " command.";
1408         
1409         l7vsadm_err.setter( true, buf.str() );
1410         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 123, buf.str(), __FILE__, __LINE__ );
1411         return false;
1412     }
1413     
1414     request.command = cmd;
1415
1416     for( int pos = 2; pos < argc; ++pos ){
1417         parse_opt_map_type::iterator itr = replication_option_dic.find( argv[pos] );
1418         if( itr != replication_option_dic.end() ){
1419             if( ! itr->second( pos, argc, argv ) ) return false;
1420         }
1421         else{
1422             std::stringstream buf;
1423             buf << "replication option not found:" << argv[pos];
1424             l7vsadm_err.setter( true, buf.str() );
1425             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 59, buf.str(), __FILE__, __LINE__ );
1426             return false;
1427         }
1428     }
1429     if( l7vsadm_request::REP_NONE == request.replication_command ){
1430         // not specified replication command
1431         std::string    buf("replication command not specified.");
1432         l7vsadm_err.setter( true, buf );
1433         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 60, buf, __FILE__, __LINE__ );
1434         return false;
1435     }
1436
1437     return true;
1438 }
1439
1440 //
1441 //    replication option functions.
1442 //
1443 //! replication switch function
1444 //! @param[in]    argument position
1445 //! @param[in]    argument count
1446 //! @param[in]    argument value
1447 bool    l7vs::l7vsadm::parse_opt_replication_switch_func( int& pos, int argc, char* argv[] ){
1448     Logger    logger( LOG_CAT_L7VSADM_COMMON, 17, "l7vsadm::parse_opt_replication_switch_func", __FILE__, __LINE__ );
1449
1450     if( request.replication_command != l7vsadm_request::REP_NONE ){ 
1451         // double command target.
1452         std::string    buf("replication option is double specified.");
1453         l7vsadm_err.setter( true, buf );
1454         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 61, buf, __FILE__, __LINE__ );
1455         return false;
1456     }
1457     if( ++pos >= argc ){
1458         // don't target replication switch value
1459         std::string    buf("replication switch option is not specified.");
1460         l7vsadm_err.setter( true, buf );
1461         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 62, buf, __FILE__, __LINE__ );
1462         return false;
1463     }
1464     parse_opt_map_type::iterator itr = replication_switch_option_dic.find( argv[pos] );
1465     if( itr != replication_switch_option_dic.end() ){    // option string function find.
1466         if( ! itr->second( pos, argc, argv ) ) return false;    // option string function error.
1467     }
1468     else{    //option string function don't find.
1469         // print option not found message.
1470         std::stringstream buf;
1471         buf << "replication switch option not found:" << argv[pos];
1472         l7vsadm_err.setter( true, buf.str() );
1473         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 63, buf.str(), __FILE__, __LINE__ );
1474         return false;
1475     }
1476     return true;
1477 }
1478 //! replication start function
1479 //! @param[in]    argument position
1480 //! @param[in]    argument count
1481 //! @param[in]    argument value
1482 bool    l7vs::l7vsadm::parse_opt_replication_start_func( int& pos, int argc, char* argv[] ){
1483     Logger    logger( LOG_CAT_L7VSADM_COMMON, 18, "l7vsadm::parse_opt_replication_start_func", __FILE__, __LINE__ );
1484
1485     request.replication_command = l7vsadm_request::REP_START;
1486     return true;
1487 }
1488 //! replication stop function
1489 //! @param[in]    argument position
1490 //! @param[in]    argument count
1491 //! @param[in]    argument value
1492 bool    l7vs::l7vsadm::parse_opt_replication_stop_func( int& pos, int argc, char* argv[] ){
1493     Logger    logger( LOG_CAT_L7VSADM_COMMON, 19, "l7vsadm::parse_opt_replication_stop_func", __FILE__, __LINE__ );
1494
1495     request.replication_command = l7vsadm_request::REP_STOP;
1496     return true;
1497 }
1498 //! replication force function
1499 //! @param[in]    argument position
1500 //! @param[in]    argument count
1501 //! @param[in]    argument value
1502 bool    l7vs::l7vsadm::parse_opt_replication_force_func( int& pos, int argc, char* argv[] ){
1503     Logger    logger( LOG_CAT_L7VSADM_COMMON, 20, "l7vsadm::parse_opt_replication_force_func", __FILE__, __LINE__ );
1504
1505     if( request.replication_command != l7vsadm_request::REP_NONE ){ 
1506         // double command target.
1507         std::string    buf("replication option is double specified.");
1508         l7vsadm_err.setter( true, buf );
1509         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 64, buf, __FILE__, __LINE__ );
1510         return false;
1511     }
1512     request.replication_command = l7vsadm_request::REP_FORCE;
1513     return true;
1514 }
1515 //! replication dump function
1516 //! @param[in]    argument position
1517 //! @param[in]    argument count
1518 //! @param[in]    argument value
1519 bool    l7vs::l7vsadm::parse_opt_replication_dump_func( int& pos, int argc, char* argv[] ){
1520     Logger    logger( LOG_CAT_L7VSADM_COMMON, 21, "l7vsadm::parse_opt_replication_dump_func", __FILE__, __LINE__ );
1521
1522     if( request.replication_command != l7vsadm_request::REP_NONE ){ 
1523         // double command target.
1524         std::string    buf("replication option is double specified.");
1525         l7vsadm_err.setter( true, buf );
1526         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 65, buf, __FILE__, __LINE__ );
1527         return false;
1528     }
1529     request.replication_command = l7vsadm_request::REP_DUMP;
1530     return true;
1531 }
1532
1533 //! log command parsing.
1534 //! @param[in]    request command
1535 //! @param[in]    argument count
1536 //! @param[in]    argument value
1537 bool    l7vs::l7vsadm::parse_log_func( l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char* argv[] ){
1538     Logger    logger( LOG_CAT_L7VSADM_COMMON, 22, "l7vsadm::parse_log_func", __FILE__, __LINE__ );
1539
1540     if( argc != 6 ) {
1541         //argument num err
1542         std::stringstream buf;
1543         buf << "Argument argc is illegal for ";
1544         buf << argv[1];
1545         buf << " command.";
1546         
1547         l7vsadm_err.setter( true, buf.str() );
1548         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 124, buf.str(), __FILE__, __LINE__ );
1549         return false;
1550     }
1551
1552     request.command = cmd;
1553
1554     for( int pos = 2; pos < argc; ++pos ){
1555         parse_opt_map_type::iterator itr = log_option_dic.find( argv[pos] );
1556         if( itr != log_option_dic.end() ){    // option string function find.
1557             if( ! itr->second( pos, argc, argv ) ) return false;    // option string function error.
1558         }
1559         else{    //option string function don't find.
1560             // print option not found message.
1561             std::stringstream buf;
1562             buf << "log option not found:" << argv[pos];
1563             l7vsadm_err.setter( true, buf.str() );
1564             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 66, buf.str(), __FILE__, __LINE__ );
1565             return false;
1566         }
1567     }
1568     if( LOG_CAT_NONE == request.log_category ){
1569         // not specified logcategory
1570         std::string    buf("logcategory not specified.");
1571         l7vsadm_err.setter( true, buf );
1572         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 67, buf, __FILE__, __LINE__ );
1573         return false;
1574     }
1575     if( LOG_LV_NONE == request.log_level ){
1576         // not specified loglevel
1577         std::string    buf("loglevel not specified.");
1578         l7vsadm_err.setter( true, buf );
1579         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 68, buf, __FILE__, __LINE__ );
1580         return false;
1581     }
1582
1583     return true;
1584 }
1585 //
1586 //    log option function
1587 //
1588 //! log category set function
1589 //! @param[in]    argument position
1590 //! @param[in]    argument count
1591 //! @param[in]    argument value
1592 bool    l7vs::l7vsadm::parse_opt_log_category_func( int& pos, int argc, char* argv[] ){
1593     Logger    logger( LOG_CAT_L7VSADM_COMMON, 23, "l7vsadm::parse_opt_log_category_func", __FILE__, __LINE__ );
1594
1595     if( request.log_category != LOG_CAT_NONE ){
1596         // double target commands.
1597         std::stringstream buf;
1598         buf << "Option ";
1599         buf << argv[pos];
1600         buf << " conflict.";
1601
1602         l7vsadm_err.setter( true, buf.str() );
1603         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 69, buf.str(), __FILE__, __LINE__ );
1604         return false;
1605     }
1606     if( ++pos >= argc ){
1607         // don't target logcategory
1608         std::string    buf("logcategory is not specified.");
1609         l7vsadm_err.setter( true, buf );
1610         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 70, buf, __FILE__, __LINE__ );
1611         return false;
1612     }
1613     string_logcategory_map_type::iterator itr = string_logcategory_dic.find( argv[pos] );
1614     if( itr != string_logcategory_dic.end() ){
1615         request.log_category = itr->second;
1616         return true;
1617     }
1618     std::stringstream buf;
1619     buf << "logcategory not found:" << argv[pos];
1620     l7vsadm_err.setter( true, buf.str() );
1621     Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 71, buf.str(), __FILE__, __LINE__ );
1622     return false;
1623 }
1624 //! log level set function
1625 //! @param[in]    argument position
1626 //! @param[in]    argument count
1627 //! @param[in]    argument value
1628 bool    l7vs::l7vsadm::parse_opt_log_level_func( int& pos, int argc, char* argv[] ){
1629     Logger    logger( LOG_CAT_L7VSADM_COMMON, 24, "l7vsadm::parse_opt_log_level_func", __FILE__, __LINE__ );
1630
1631     if( request.log_level != LOG_LV_NONE ){
1632         // double target commands.
1633         std::stringstream buf;
1634         buf << "Option ";
1635         buf << argv[pos];
1636         buf << " conflict.";
1637
1638         l7vsadm_err.setter( true, buf.str() );
1639         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 72, buf.str(), __FILE__, __LINE__ );
1640         return false;
1641     }
1642     if( ++pos >= argc ){
1643         // don't target loglevel
1644         std::string    buf("loglevel is not specified.");
1645         l7vsadm_err.setter( true, buf );
1646         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 73, buf, __FILE__, __LINE__ );
1647         return false;
1648     }
1649     string_loglevel_map_type::iterator itr = string_loglevel_dic.find( argv[pos] );
1650     if( itr != string_loglevel_dic.end() ){
1651         request.log_level = itr->second;
1652         return true;
1653     }
1654     std::stringstream buf;
1655     buf << "loglevel not found:" << argv[pos];
1656     l7vsadm_err.setter( true, buf.str() );
1657     Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 74, buf.str(), __FILE__, __LINE__ );
1658     return false;
1659 }
1660
1661 //! snmp command parsing
1662 //! @param[in]    request command
1663 //! @param[in]    argument count
1664 //! @param[in]    argument value
1665 bool    l7vs::l7vsadm::parse_snmp_func( l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char* argv[] ){
1666     Logger    logger( LOG_CAT_L7VSADM_COMMON, 25, "l7vsadm::parse_snmp_func", __FILE__, __LINE__ );
1667
1668     if( argc != 6 ) {
1669         //argument num err
1670         std::stringstream buf;
1671         buf << "Argument argc is illegal for ";
1672         buf << argv[1];
1673         buf << " command.";
1674         
1675         l7vsadm_err.setter( true, buf.str() );
1676         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 125, buf.str(), __FILE__, __LINE__ );
1677         return false;
1678     }
1679
1680     request.command = cmd;
1681
1682     for( int pos = 2; pos < argc; ++pos ){
1683         parse_opt_map_type::iterator itr = snmp_option_dic.find( argv[pos] );
1684         if( itr != snmp_option_dic.end() ){    // option string function find.
1685             if( ! itr->second( pos, argc, argv ) ) return false;    // option string function error.
1686         }
1687         else{    //option string function don't find.
1688             // print option not found message.
1689             std::stringstream buf;
1690             buf << "snmp log option not found:" << argv[pos];
1691             l7vsadm_err.setter( true, buf.str() );
1692             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 75, buf.str(), __FILE__, __LINE__ );
1693             return false;
1694         }
1695     }
1696     if( LOG_CAT_NONE == request.snmp_log_category ){
1697         // not specified logcategory
1698         std::string    buf("snmp logcategory not specified.");
1699         l7vsadm_err.setter( true, buf );
1700         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 76, buf, __FILE__, __LINE__ );
1701         return false;
1702     }
1703     if( LOG_LV_NONE == request.snmp_log_level ){
1704         // not specified loglevel
1705         std::string    buf("snmp loglevel not specified.");
1706         l7vsadm_err.setter( true, buf );
1707         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 77, buf, __FILE__, __LINE__ );
1708         return false;
1709     }
1710
1711     return true;
1712 }
1713 //! snmp log category set function
1714 //! @param[in]    argument position
1715 //! @param[in]    argument count
1716 //! @param[in]    argument value
1717 bool    l7vs::l7vsadm::parse_opt_snmp_log_category_func( int& pos, int argc, char* argv[] ){
1718     Logger    logger( LOG_CAT_L7VSADM_COMMON, 26, "l7vsadm::parse_opt_snmp_log_category_func", __FILE__, __LINE__ );
1719
1720     if( request.snmp_log_category != LOG_CAT_NONE ){
1721         // double target commands.
1722         std::stringstream buf;
1723         buf << "Option ";
1724         buf << argv[pos];
1725         buf << " conflict.";
1726
1727         l7vsadm_err.setter( true, buf.str() );
1728         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 78, buf.str(), __FILE__, __LINE__ );
1729         return false;
1730     }
1731     if( ++pos >= argc ){
1732         // don't target logcategory
1733         std::string    buf("snmp logcategory is not specified.");
1734         l7vsadm_err.setter( true, buf );
1735         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 79, buf, __FILE__, __LINE__ );
1736         return false;
1737     }
1738     string_logcategory_map_type::iterator itr = string_snmp_logcategory_dic.find( argv[pos] );
1739     if( itr != string_snmp_logcategory_dic.end() ){
1740         request.snmp_log_category = itr->second;
1741         return true;
1742     }
1743     std::stringstream buf;
1744     buf << "snmp logcategory not found:" << argv[pos];
1745     l7vsadm_err.setter( true, buf.str() );
1746     Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 80, buf.str(), __FILE__, __LINE__ );
1747     return false;
1748 }
1749 //! snmp log level set function
1750 //! @param[in]    argument position
1751 //! @param[in]    argument count
1752 //! @param[in]    argument value
1753 bool    l7vs::l7vsadm::parse_opt_snmp_log_level_func( int& pos, int argc, char* argv[] ){
1754     Logger    logger( LOG_CAT_L7VSADM_COMMON, 27, "l7vsadm::parse_opt_snmp_log_level_func", __FILE__, __LINE__ );
1755
1756     if( request.snmp_log_level != LOG_LV_NONE ){
1757         // double target commands.
1758         std::stringstream buf;
1759         buf << "Option ";
1760         buf << argv[pos];
1761         buf << " conflict.";
1762
1763         l7vsadm_err.setter( true, buf.str() );
1764         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 81, buf.str(), __FILE__, __LINE__ );
1765         return false;
1766     }
1767     if( ++pos >= argc ){
1768         // don't rarget logcategory
1769         std::string    buf("snmp loglevel is not specified.");
1770         l7vsadm_err.setter( true, buf );
1771         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 82, buf, __FILE__, __LINE__ );
1772         return false;
1773     }
1774     string_loglevel_map_type::iterator itr = string_loglevel_dic.find( argv[pos] );
1775     if( itr != string_loglevel_dic.end() ){
1776         request.snmp_log_level = itr->second;
1777         return true;
1778     }
1779     std::stringstream buf;
1780     buf << "snmp loglevel not found:" << argv[pos];
1781     l7vsadm_err.setter( true, buf.str() );
1782     Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 83, buf.str(), __FILE__, __LINE__ );
1783     return false;
1784 }
1785
1786 //! parameter command parsing
1787 //! @param[in]    request command
1788 //! @param[in]    argument count
1789 //! @param[in]    argument value
1790 bool    l7vs::l7vsadm::parse_parameter_func( l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char* argv[] ){
1791     Logger    logger( LOG_CAT_L7VSADM_COMMON, 28, "l7vsadm::parse_parameter_func", __FILE__, __LINE__ );
1792
1793     if( argc != 4 ) {
1794         //argument num err
1795         std::stringstream buf;
1796         buf << "Argument argc is illegal for ";
1797         buf << argv[1];
1798         buf << " command.";
1799         
1800         l7vsadm_err.setter( true, buf.str() );
1801         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 126, buf.str(), __FILE__, __LINE__ );
1802         return false;
1803     }
1804     
1805     request.command = cmd;
1806
1807     for( int pos = 2; pos < argc; ++pos ){
1808         parse_opt_map_type::iterator itr = parameter_option_dic.find( argv[pos] );
1809         if( itr != parameter_option_dic.end() ){    // option string function find.
1810             if( ! itr->second( pos, argc, argv ) ) return false;    // option string function error.
1811         }
1812         else{    //option string function don't find.
1813             // print option not found message.
1814             std::stringstream buf;
1815             buf << "parameter option not found:" << argv[pos];
1816             l7vsadm_err.setter( true, buf.str() );
1817             Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 84, buf.str(), __FILE__, __LINE__ );
1818             return false;
1819         }
1820     }
1821
1822     if( PARAM_COMP_NOCAT == request.reload_param ){
1823         // not specified reload_param
1824         std::string    buf("reload component not specified.");
1825         l7vsadm_err.setter( true, buf );
1826         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 85, buf, __FILE__, __LINE__ );
1827         return false;
1828     }
1829
1830     return true;
1831 }
1832 //
1833 //    parameter command 
1834 //
1835 //! parameter reload component parsing
1836 //! @param[in]    argument position
1837 //! @param[in]    argument count
1838 //! @param[in]    argument value
1839 bool    l7vs::l7vsadm::parse_opt_parameter_reload_func( int& pos, int argc, char* argv[] ){
1840     Logger    logger( LOG_CAT_L7VSADM_COMMON, 29, "l7vsadm::parse_opt_parameter_reload_func", __FILE__, __LINE__ );
1841
1842     if( ++pos >= argc ){
1843         // don't target reload component
1844         std::string    buf("reload component is not specified.");
1845         l7vsadm_err.setter( true, buf );
1846         Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 86, buf, __FILE__, __LINE__ );
1847         return false;
1848     }
1849     string_parameter_map_type::iterator itr = string_parameter_dic.find( argv[pos] );
1850     if( itr != string_parameter_dic.end() ){
1851         request.reload_param = itr->second;
1852         return true;
1853     }
1854     std::stringstream buf;
1855     buf << "reload component not found:" << argv[pos];
1856     l7vsadm_err.setter( true, buf.str() );
1857     Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 87, buf.str(), __FILE__, __LINE__ );
1858     return false;
1859 }
1860
1861 //! help command parsing
1862 //! @param[in]    request command
1863 //! @param[in]    argument count
1864 //! @param[in]    argument value
1865 bool    l7vs::l7vsadm::parse_help_func( l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char* argv[] ){
1866     Logger    logger( LOG_CAT_L7VSADM_COMMON, 30, "l7vsadm::parse_help_func", __FILE__, __LINE__ );
1867
1868     request.command = cmd;
1869
1870     std::cout << usage() << std::endl;
1871
1872     std::cout <<
1873     "Commands:\n"
1874     "  --add-service      -A        add virtual service with options\n"
1875     "  --edit-service     -E        edit virtual service with options\n"
1876     "  --delete-service   -D        delete virtual service with options\n"
1877     "  --flush            -C        flush virtual service\n"
1878     "  --add-server       -a        add real server with options\n"
1879     "  --edit-server      -e        edit real server with options\n"
1880     "  --delete-server    -d        delete real server with options\n"
1881     "  --replication      -R        control replication-function\n"
1882     "  --log              -L        control logger-function\n"
1883     "  --snmp             -S        control SNMP Agent-function\n"
1884     "  --parameter        -P        control parameter-function\n"
1885     "  --list             -l        list the table\n"
1886     "  --verbose          -V        list the table in verbose format\n"
1887     "  --key              -K        list the table in key setting format\n"
1888     "  --help             -h        show usage\n"
1889     << std::endl;
1890
1891     std::cout <<
1892     "Options:\n"
1893     "  --tcp-service      -t service-address     service-address is host:port\n"
1894     "  --proto-module     -m proto-module        protocol module name and module argment\n"
1895     "                        [module-args]\n"
1896     "  --scheduler        -s scheduler           one of rr,lc,wrr\n"
1897     "  --upper            -u connection-count    maximum number of connections\n"
1898     "  --bypass           -b sorry-server        sorry server address is host:port\n"
1899     "  --flag             -f sorry-flag          sorry status set to virtual service\n"
1900     "  --qos-up           -Q QoSval-up           QoS Threshold(bps) set to real server direction\n"
1901     "  --qos-down         -q QoSval-down         QoS Threshold(bps) set to client direction\n"
1902     "  --ssl              -z ssl-config-file     SSL configuration file(Use SSL)\n"
1903     "  --sockopt          -O socket-option       deferaccept,nodelay,cork,quickackon or quickackoff set to socket option\n"
1904     "  --access-log       -L access-log-flag     access log flag 0(none) or 1(output)\n"
1905     "  --access-log-name  -L access-log-file     access log file\n"
1906     "                        [logrotate-args]\n"
1907     "  --real-server      -r server-address      server-address is host:port\n"
1908     "  --weight           -w weight              scheduling weight set to real server\n"
1909     "  --switch           -s replication-switch  start or stop replication\n"
1910     "  --force            -f                     force replication start\n"
1911     "  --dump             -d                     dump replication memory\n"
1912     "  --category         -c log-category        set log category for l7vsd or SNMP Agent\n"
1913     "  --level            -l log-level           set log level for l7vsd or SNMP Agent\n"
1914     "  --reload           -r reload-parameter    reload specified config parameter\n"
1915     "  --numeric          -n                     list the table in numeric\n"
1916     << std::endl;
1917
1918     return true;
1919 }
1920
1921 //! usage function.
1922 std::string    l7vs::l7vsadm::usage(){
1923     Logger    logger( LOG_CAT_L7VSADM_COMMON, 31, "l7vsadm::usage", __FILE__, __LINE__ );
1924
1925     std::stringstream    stream;
1926     stream <<
1927     "Usage: \n"
1928     "  l7vsadm -A -t service-address -m proto-module [module-args]\n"
1929     "          [-s scheduler] [-u connection-count] [-b sorry-server]\n"
1930     "          [-f sorry-flag] [-Q QoSval-up] [-q QoSval-down] [-z ssl-config-file]\n"
1931     "          [-O socket-option] [-L access-log-lfag] [-a access-log-file [logrotate-args]]\n"
1932     "  l7vsadm -E -t service-address -m proto-module [module-args]\n"
1933     "          [-s scheduler] [-u connection-count] [-b sorry-server]\n"
1934     "          [-f sorry-flag] [-Q QoSval-up] [-q QoSval-down] [-L access-log-flag]\n"
1935     "  l7vsadm -D -t service-address -m proto-module [module-args]\n"
1936     "  l7vsadm -C\n"
1937     "  l7vsadm -a|e -t service-address -m proto-module [module-args] [-u]\n"
1938     "          -r server-address [-w weight]\n"
1939     "  l7vsadm -d -t service-address -m proto-module [module-args]\n"
1940     "          -r server-address\n"
1941     "  l7vsadm -R -s replication-switch\n"
1942     "  l7vsadm -R -f\n"
1943     "  l7vsadm -R -d\n"
1944     "  l7vsadm -L -c log-category -l log-level\n"
1945     "  l7vsadm -S -c log-category -l log-level\n"
1946     "  l7vsadm -P -r reload-parameter\n"
1947     "  l7vsadm -l [-n]\n"
1948     "  l7vsadm -V [-n]\n"
1949     "  l7vsadm -K [-n]\n"
1950     "  l7vsadm -h\n"
1951     << std::endl;
1952     return stream.str();
1953 }
1954
1955 //!    disp_list function
1956 void    l7vs::l7vsadm::disp_list(){
1957     Logger    logger( LOG_CAT_L7VSADM_COMMON, 32, "l7vsadm::disp_list", __FILE__, __LINE__ );
1958
1959     std::stringstream buf;
1960     buf << boost::format( "Layer-7 Virtual Server version %s\n" ) % VERSION;
1961     buf << "Prot LocalAddress:Port ProtoMod Scheduler\n";
1962     buf << "  -> RemoteAddress:Port           Forward Weight ActiveConn InactConn\n";
1963     BOOST_FOREACH( virtualservice_element vse, response.virtualservice_status_list ){
1964         std::string    vsepstr;
1965         if(vse.udpmode)
1966             vsepstr = endpoint_to_string<boost::asio::ip::udp>( vse.udp_recv_endpoint, numeric_flag );
1967         else
1968             vsepstr = endpoint_to_string<boost::asio::ip::tcp>( vse.tcp_accept_endpoint, numeric_flag );
1969         buf << boost::format( "%s %s %s %s\n" )
1970             % ( vse.udpmode ? "UDP" : "TCP" )
1971             % vsepstr
1972             % vse.protocol_module_name
1973             % vse.schedule_module_name;
1974         BOOST_FOREACH( realserver_element rse, vse.realserver_vector ){
1975             std::string    rsepstr;
1976             if(vse.udpmode)
1977                 rsepstr = endpoint_to_string<boost::asio::ip::udp>( rse.udp_endpoint, numeric_flag );
1978             else
1979                 rsepstr = endpoint_to_string<boost::asio::ip::tcp>( rse.tcp_endpoint, numeric_flag );
1980             buf << boost::format( "  -> %-28s %-7s %-6d %-10d %-10d\n" )
1981                 % rsepstr
1982                 % "Masq"
1983                 % rse.weight
1984                 % rse.get_active()
1985                 % rse.get_inact();
1986         }
1987     }
1988     std::cout << buf.str();
1989 }
1990
1991 //!    disp_list_key function
1992 void    l7vs::l7vsadm::disp_list_key(){
1993     Logger    logger( LOG_CAT_L7VSADM_COMMON, 33, "l7vsadm::disp_list_key", __FILE__, __LINE__ );
1994
1995     std::stringstream buf;
1996     buf << boost::format( "Layer-7 Virtual Server version %s\n" ) % VERSION;
1997     buf << "Prot LocalAddress:Port ProtoMod Scheduler\n";
1998     buf << "     SSL_config_file\n";
1999     buf << "     Socket option\n";
2000     buf << "     Access_log_flag\n";
2001     buf << "     Access_log_file\n";
2002     buf << "     Access_log_rotate option\n";
2003     buf << "  -> RemoteAddress:Port           Forward Weight ActiveConn InactConn\n";
2004     BOOST_FOREACH( virtualservice_element vse, response.virtualservice_status_list ){
2005         std::string    vsepstr;
2006         if(vse.udpmode)
2007             vsepstr = endpoint_to_string<boost::asio::ip::udp>( vse.udp_recv_endpoint, numeric_flag );
2008         else
2009             vsepstr = endpoint_to_string<boost::asio::ip::tcp>( vse.tcp_accept_endpoint, numeric_flag );
2010         buf << boost::format( "%s %s %s %s\n" )
2011             % ( vse.udpmode ? "UDP" : "TCP" )
2012             % vsepstr
2013             % vse.protocol_module_name
2014             % vse.schedule_module_name;
2015         buf << boost::format( "    %s\n" )
2016             % ( ( 0 == vse.ssl_file_name.length() ) ? "none": vse.ssl_file_name );
2017         buf << boost::format( "    %s\n" )
2018             % ( ( 0 == vse.socket_option_string.length() ) ? "none": vse.socket_option_string );
2019         buf << boost::format( "    %d\n" ) % vse.access_log_flag;
2020         buf << boost::format( "    %s\n" )
2021             % ( ( 0 == vse.access_log_file_name.length() ) ? "none": vse.access_log_file_name );
2022         buf << boost::format( "    %s\n" )
2023             % ( ( 0 == vse.access_log_rotate_key_info.length() ) ? "none" :  vse.access_log_rotate_key_info );
2024         
2025         BOOST_FOREACH( realserver_element rse, vse.realserver_vector ){
2026             std::string    rsepstr;
2027             if(vse.udpmode)
2028                 rsepstr = endpoint_to_string<boost::asio::ip::udp>( rse.udp_endpoint, numeric_flag );
2029             else
2030                 rsepstr = endpoint_to_string<boost::asio::ip::tcp>( rse.tcp_endpoint, numeric_flag );
2031             buf << boost::format( "  -> %-28s %-7s %-6d %-10d %-10d\n" )
2032                 % rsepstr
2033                 % "Masq"
2034                 % rse.weight
2035                 % rse.get_active()
2036                 % rse.get_inact();
2037         }
2038     }
2039     std::cout << buf.str();
2040 }
2041
2042 //!    disp_list_verbose function
2043 void    l7vs::l7vsadm::disp_list_verbose(){
2044     Logger    logger( LOG_CAT_L7VSADM_COMMON, 34, "l7vsadm::disp_list_verbose", __FILE__, __LINE__ );
2045
2046     unsigned long long output_qos_upstream_value;
2047     unsigned long long output_qos_downstream_value;
2048
2049     std::stringstream    buf;
2050     buf << boost::format( "Layer-7 Virtual Server version %s\n" ) % VERSION;
2051
2052     //disp loglevel
2053     buf << "L7vsd Log Level:\n";
2054     buf << "Category                       Level\n";
2055     typedef    std::pair< LOG_CATEGORY_TAG, LOG_LEVEL_TAG > logstatus_type;
2056     BOOST_FOREACH( logstatus_type logstatus, response.log_status_list ){
2057         buf << boost::format( "%-30s %s\n" )
2058             % logcategory_string_dic[logstatus.first]
2059             % loglevel_string_dic[logstatus.second];
2060     }
2061     buf << "\n";
2062
2063     //disp replication
2064     buf << "Replication Mode:\n";
2065     buf << boost::format( "%s\n" ) % replication_mode_string_dic[response.replication_mode_status];
2066     buf << "\n";
2067
2068     //disp snmp connection status
2069     buf << "SNMPAgent Connection Status:\n";
2070     if( response.snmp_connection_status )
2071         buf << "connecting\n";
2072     else
2073         buf << "non-connecting\n";
2074     buf << "\n";
2075
2076     //disp snmp loglevel
2077     buf << "SNMPAgent Log Level:\n";
2078     buf << "Category                       Level\n";
2079     BOOST_FOREACH( logstatus_type snmplogstatus, response.snmp_log_status_list ){
2080         buf << boost::format( "%-30s %s\n" )
2081             % snmp_logcategory_string_dic[snmplogstatus.first]
2082             % loglevel_string_dic[snmplogstatus.second];
2083     }
2084     buf << "\n";
2085
2086     // disp vs    
2087     buf << "Prot LocalAddress:Port ProtoMod Scheduler Protomod_opt_string\n";
2088     buf << "     SorryAddress:Port Sorry_cc Sorry_flag\n";
2089     buf << "     QoS-up   Throughput-up\n";
2090     buf << "     QoS-down Throughput-down\n";
2091     buf << "     SSL_config_file\n";
2092     buf << "     Socket option\n";
2093     buf << "     Access_log_flag\n";
2094     buf << "     Access_log_file\n";
2095     buf << "     Access_log_rotate option\n";
2096     buf << "  -> RemoteAddress:Port           Forward Weight ActiveConn InactConn\n";
2097     BOOST_FOREACH( virtualservice_element vse, response.virtualservice_status_list ){
2098         std::string    vsepstr;
2099         if( vse.udpmode )
2100             vsepstr = endpoint_to_string<boost::asio::ip::udp>( vse.udp_recv_endpoint, numeric_flag );
2101         else
2102             vsepstr = endpoint_to_string<boost::asio::ip::tcp>( vse.tcp_accept_endpoint, numeric_flag );
2103
2104
2105         if( vse.qos_upstream == ULLONG_MAX ) {
2106             output_qos_upstream_value = 0;
2107         } else {
2108             output_qos_upstream_value = vse.qos_upstream * 8;
2109         }
2110
2111         if( vse.qos_downstream == ULLONG_MAX ) {
2112             output_qos_downstream_value = 0;
2113         } else {
2114             output_qos_downstream_value = vse.qos_downstream * 8;
2115         }
2116
2117
2118         buf << boost::format( "%s %s %s %s %s\n" )
2119             % ( vse.udpmode ? "UDP" : "TCP" )
2120             % vsepstr
2121             % vse.protocol_module_name
2122             % vse.schedule_module_name
2123             % vse.protocol_module_for_indication_options;
2124         if( !vse.udpmode ){
2125             std::string    sorryepstr;
2126             boost::asio::ip::tcp::endpoint    zeropoint;
2127             if( zeropoint == vse.sorry_endpoint ){
2128                 sorryepstr = "none";
2129             }
2130             else{
2131                 sorryepstr = endpoint_to_string<boost::asio::ip::tcp>( vse.sorry_endpoint, numeric_flag );
2132             }
2133             buf << boost::format( "    %s %d %d\n" )
2134                 % sorryepstr
2135                 % vse.sorry_maxconnection
2136                 % vse.sorry_flag;
2137         }
2138         // QoS value and throughput convert from byte/s to bps.
2139         buf << boost::format( "    %lld %lld\n" )
2140             % (output_qos_upstream_value)
2141             % (vse.throughput_upstream * 8);
2142         buf << boost::format( "    %lld %lld\n" )
2143             % (output_qos_downstream_value)
2144             % (vse.throughput_downstream * 8);
2145         buf << boost::format( "    %s\n" )
2146             % ( ( 0 == vse.ssl_file_name.length() ) ? "none": vse.ssl_file_name );
2147         buf << boost::format( "    %s\n" )
2148             % ( ( 0 == vse.socket_option_string.length() ) ? "none": vse.socket_option_string );
2149         buf << boost::format( "    %d\n" ) % vse.access_log_flag;
2150         buf << boost::format( "    %s\n" )
2151             % ( ( 0 == vse.access_log_file_name.length() ) ? "none": vse.access_log_file_name );
2152         buf << boost::format( "    %s\n" )
2153             % ( ( 0 == vse.access_log_rotate_verbose_info.length() ) ? "none" :  vse.access_log_rotate_verbose_info );
2154
2155         BOOST_FOREACH( realserver_element rse, vse.realserver_vector ){
2156             std::string    rsepstr;
2157             if( vse.udpmode )
2158                 rsepstr = endpoint_to_string<boost::asio::ip::udp>( rse.udp_endpoint, numeric_flag );
2159             else
2160                 rsepstr = endpoint_to_string<boost::asio::ip::tcp>( rse.tcp_endpoint, numeric_flag );
2161             buf << boost::format( "  -> %-28s %-7s %-6d %-10d %-10d\n" )
2162                 % rsepstr
2163                 % "Masq"
2164                 % rse.weight
2165                 % rse.get_active()
2166                 % rse.get_inact();
2167         }
2168     }
2169     std::cout << buf.str();
2170 }
2171 //! l7vsadm constractor.
2172 //! create including all dictionary.
2173 l7vs::l7vsadm::l7vsadm()
2174                 :   numeric_flag(false),
2175                     command_wait_interval( L7VSADM_DEFAULT_WAIT_INTERVAL ),
2176                     command_wait_count( L7VSADM_DEFAULT_WAIT_COUNT ),
2177                     connect_wait_interval( L7VSADM_DEFAULT_WAIT_INTERVAL ),
2178                     connect_wait_count( L7VSADM_DEFAULT_WAIT_COUNT ){
2179     Logger    logger( LOG_CAT_L7VSADM_COMMON, 35, "l7vsadm::l7vsadm(constructor)", __FILE__, __LINE__ );
2180
2181     // create command dictionary.
2182     command_dic["-l"]               = boost::bind( &l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST, _1, _2 );
2183     command_dic["--list"]           = boost::bind( &l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST, _1, _2 );
2184     command_dic["-V"]               = boost::bind( &l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_VERBOSE, _1, _2 );
2185     command_dic["--verbose"]        = boost::bind( &l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_VERBOSE, _1, _2 );
2186     command_dic["-K"]               = boost::bind( &l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_KEY, _1, _2 );
2187     command_dic["--key"]            = boost::bind( &l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_KEY, _1, _2 );
2188     command_dic["-A"]               = boost::bind( &l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_ADD_VS, _1, _2 );
2189     command_dic["--add-service"]    = boost::bind( &l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_ADD_VS, _1, _2 );
2190     command_dic["-D"]               = boost::bind( &l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_DEL_VS, _1, _2 );
2191     command_dic["--delete-service"] = boost::bind( &l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_DEL_VS, _1, _2 );
2192     command_dic["-E"]               = boost::bind( &l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_EDIT_VS, _1, _2 );
2193     command_dic["--edit-service"]   = boost::bind( &l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_EDIT_VS, _1, _2 );
2194     command_dic["-C"]               = boost::bind( &l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_FLUSH_VS, _1, _2 );
2195     command_dic["--flush"]          = boost::bind( &l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_FLUSH_VS, _1, _2 );
2196     command_dic["-a"]               = boost::bind( &l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_ADD_RS, _1, _2 );
2197     command_dic["--add-server"]     = boost::bind( &l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_ADD_RS, _1, _2 );
2198     command_dic["-d"]               = boost::bind( &l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_DEL_RS, _1, _2 );
2199     command_dic["--delete-server"]  = boost::bind( &l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_DEL_RS, _1, _2 );
2200     command_dic["-e"]               = boost::bind( &l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_EDIT_RS, _1, _2 );
2201     command_dic["--edit-server"]    = boost::bind( &l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_EDIT_RS, _1, _2 );
2202     command_dic["-R"]               = boost::bind( &l7vsadm::parse_replication_func, this, l7vsadm_request::CMD_REPLICATION, _1, _2 );
2203     command_dic["--replication"]    = boost::bind( &l7vsadm::parse_replication_func, this, l7vsadm_request::CMD_REPLICATION, _1, _2 );
2204     command_dic["-L"]               = boost::bind( &l7vsadm::parse_log_func, this, l7vsadm_request::CMD_LOG, _1, _2 );
2205     command_dic["--log"]            = boost::bind( &l7vsadm::parse_log_func, this, l7vsadm_request::CMD_LOG, _1, _2 );
2206     command_dic["-S"]               = boost::bind( &l7vsadm::parse_snmp_func, this, l7vsadm_request::CMD_SNMP, _1, _2 );
2207     command_dic["--snmp"]           = boost::bind( &l7vsadm::parse_snmp_func, this, l7vsadm_request::CMD_SNMP, _1, _2 );
2208     command_dic["-P"]               = boost::bind( &l7vsadm::parse_parameter_func, this, l7vsadm_request::CMD_PARAMETER, _1, _2 );
2209     command_dic["--parameter"]      = boost::bind( &l7vsadm::parse_parameter_func, this, l7vsadm_request::CMD_PARAMETER, _1, _2 );
2210     command_dic["-h"]               = boost::bind( &l7vsadm::parse_help_func, this, l7vsadm_request::CMD_HELP, _1, _2 );
2211     command_dic["--help"]           = boost::bind( &l7vsadm::parse_help_func, this, l7vsadm_request::CMD_HELP, _1, _2 );
2212
2213     // create list option dictionary.
2214     list_option_dic["-n"]           = boost::bind( &l7vsadm::parse_opt_list_numeric_func, this, _1, _2, _3 );
2215     list_option_dic["--numeric"]    = boost::bind( &l7vsadm::parse_opt_list_numeric_func, this, _1, _2, _3 );
2216     // create virtualservice option dictionary
2217     vs_option_dic["-t"]             = boost::bind( &l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3 );
2218     vs_option_dic["--tcp-service"]       = boost::bind( &l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3 );
2219     vs_option_dic["-m"]             = boost::bind( &l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3 );
2220     vs_option_dic["--proto-module"]       = boost::bind( &l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3 );
2221     vs_option_dic["-s"]             = boost::bind( &l7vsadm::parse_opt_vs_scheduler_func, this, _1, _2, _3 );
2222     vs_option_dic["--scheduler"]    = boost::bind( &l7vsadm::parse_opt_vs_scheduler_func, this, _1, _2, _3 );
2223     vs_option_dic["-u"]             = boost::bind( &l7vsadm::parse_opt_vs_upper_func, this, _1, _2, _3 );
2224     vs_option_dic["--upper"]        = boost::bind( &l7vsadm::parse_opt_vs_upper_func, this, _1, _2, _3 );
2225     vs_option_dic["-b"]             = boost::bind( &l7vsadm::parse_opt_vs_bypass_func, this, _1, _2, _3 );
2226     vs_option_dic["--bypass"]       = boost::bind( &l7vsadm::parse_opt_vs_bypass_func, this, _1, _2, _3 );
2227     vs_option_dic["-f"]             = boost::bind( &l7vsadm::parse_opt_vs_flag_func, this, _1, _2, _3 );
2228     vs_option_dic["--flag"]         = boost::bind( &l7vsadm::parse_opt_vs_flag_func, this, _1, _2, _3 );
2229     vs_option_dic["-Q"]             = boost::bind( &l7vsadm::parse_opt_vs_qosup_func, this, _1, _2, _3 );
2230     vs_option_dic["--qos-up"]       = boost::bind( &l7vsadm::parse_opt_vs_qosup_func, this, _1, _2, _3 );
2231     vs_option_dic["-q"]             = boost::bind( &l7vsadm::parse_opt_vs_qosdown_func, this, _1, _2, _3 );
2232     vs_option_dic["--qos-down"]     = boost::bind( &l7vsadm::parse_opt_vs_qosdown_func, this, _1, _2, _3 );
2233     vs_option_dic["-p"]             = boost::bind( &l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3 );
2234     vs_option_dic["--udp"]          = boost::bind( &l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3 );
2235     vs_option_dic["-z"]             = boost::bind( &l7vsadm::parse_opt_vs_ssl_file_func, this, _1, _2, _3 );
2236     vs_option_dic["--ssl"]          = boost::bind( &l7vsadm::parse_opt_vs_ssl_file_func, this, _1, _2, _3 );
2237     vs_option_dic["-O"]             = boost::bind( &l7vsadm::parse_opt_vs_socket_func, this, _1, _2, _3 );
2238     vs_option_dic["--sockopt"]      = boost::bind( &l7vsadm::parse_opt_vs_socket_func, this, _1, _2, _3 );
2239     vs_option_dic["-L"]             = boost::bind( &l7vsadm::parse_opt_vs_access_log_func, this, _1, _2, _3 );
2240     vs_option_dic["--access-log"]   = boost::bind( &l7vsadm::parse_opt_vs_access_log_func, this, _1, _2, _3 );
2241     vs_option_dic["-a"]             = boost::bind( &l7vsadm::parse_opt_vs_access_log_logrotate_func, this, _1, _2, _3 );
2242     vs_option_dic["--access-log-name"]
2243                                     = boost::bind( &l7vsadm::parse_opt_vs_access_log_logrotate_func, this, _1, _2, _3 );
2244     // create realserver option dictionary
2245     rs_option_dic["-t"]             = boost::bind( &l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3 );
2246     rs_option_dic["--tcp-service"]       = boost::bind( &l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3 );
2247     rs_option_dic["-w"]             = boost::bind( &l7vsadm::parse_opt_rs_weight_func, this, _1, _2, _3 );
2248     rs_option_dic["--weight"]       = boost::bind( &l7vsadm::parse_opt_rs_weight_func, this, _1, _2, _3 );
2249     rs_option_dic["-m"]             = boost::bind( &l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3 );
2250     rs_option_dic["--proto-module"]       = boost::bind( &l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3 );
2251     rs_option_dic["-p"]             = boost::bind( &l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3 );
2252     rs_option_dic["--udp"]          = boost::bind( &l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3 );
2253     rs_option_dic["-r"]             = boost::bind( &l7vsadm::parse_opt_rs_realserver_func, this, _1, _2, _3 );
2254     rs_option_dic["--real-server"]  = boost::bind( &l7vsadm::parse_opt_rs_realserver_func, this, _1, _2, _3 );
2255     // create replication option dictionary
2256     replication_option_dic["-s"]    = boost::bind( &l7vsadm::parse_opt_replication_switch_func, this, _1, _2, _3 );
2257     replication_option_dic["--switch"]
2258                                     = boost::bind( &l7vsadm::parse_opt_replication_switch_func, this, _1, _2, _3 );
2259     replication_switch_option_dic["start"]
2260                                     = boost::bind( &l7vsadm::parse_opt_replication_start_func, this, _1, _2, _3 );
2261     replication_switch_option_dic["stop"]
2262                                     = boost::bind( &l7vsadm::parse_opt_replication_stop_func, this, _1, _2, _3 );
2263     replication_option_dic["-f"]    = boost::bind( &l7vsadm::parse_opt_replication_force_func, this, _1, _2, _3 );
2264     replication_option_dic["--force"]
2265                                     = boost::bind( &l7vsadm::parse_opt_replication_force_func, this, _1, _2, _3 );
2266     replication_option_dic["-d"]    = boost::bind( &l7vsadm::parse_opt_replication_dump_func, this, _1, _2, _3 );
2267     replication_option_dic["--dump"]
2268                                     = boost::bind( &l7vsadm::parse_opt_replication_dump_func, this, _1, _2, _3 );
2269     // create log option function dictionary create
2270     log_option_dic["-c"]            = boost::bind( &l7vsadm::parse_opt_log_category_func, this, _1, _2, _3 );
2271     log_option_dic["--category"]    = boost::bind( &l7vsadm::parse_opt_log_category_func, this, _1, _2, _3 );
2272     log_option_dic["-l"]            = boost::bind( &l7vsadm::parse_opt_log_level_func, this, _1, _2, _3 );
2273     log_option_dic["--level"]       = boost::bind( &l7vsadm::parse_opt_log_level_func, this, _1, _2, _3 );
2274     // snmp agent option function dictionary create
2275     snmp_option_dic["-c"]           = boost::bind( &l7vsadm::parse_opt_snmp_log_category_func, this, _1, _2, _3 );
2276     snmp_option_dic["--category"]   = boost::bind( &l7vsadm::parse_opt_snmp_log_category_func, this, _1, _2, _3 );
2277     snmp_option_dic["-l"]           = boost::bind( &l7vsadm::parse_opt_snmp_log_level_func, this, _1, _2, _3 );
2278     snmp_option_dic["--level"]      = boost::bind( &l7vsadm::parse_opt_snmp_log_level_func, this, _1, _2, _3 );
2279     // parameter option function dictionary create
2280     parameter_option_dic["-r"]      = boost::bind( &l7vsadm::parse_opt_parameter_reload_func, this, _1, _2, _3 );
2281     parameter_option_dic["--reload"]
2282                                     = boost::bind( &l7vsadm::parse_opt_parameter_reload_func, this, _1, _2, _3 );
2283
2284     // string logcategory dictionary create
2285     string_logcategory_dic["l7vsd_network"]                 = LOG_CAT_L7VSD_NETWORK;
2286     string_logcategory_dic["nw"]                            = LOG_CAT_L7VSD_NETWORK;
2287     logcategory_string_dic[LOG_CAT_L7VSD_NETWORK]           = "l7vsd_network";
2288     string_logcategory_dic["l7vsd_network_qos"]             = LOG_CAT_L7VSD_NETWORK_QOS;
2289     string_logcategory_dic["nw_qos"]                        = LOG_CAT_L7VSD_NETWORK_QOS;
2290     logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_QOS]       = "l7vsd_network_qos";
2291     string_logcategory_dic["l7vsd_network_bandwidth"]       = LOG_CAT_L7VSD_NETWORK_BANDWIDTH;
2292     string_logcategory_dic["nw_bw"]                         = LOG_CAT_L7VSD_NETWORK_BANDWIDTH;
2293     logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_BANDWIDTH] = "l7vsd_network_bandwidth";
2294     string_logcategory_dic["l7vsd_network_num_connection"]  = LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION;
2295     string_logcategory_dic["nw_conn"]                       = LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION;
2296     logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION]
2297                                                             = "l7vsd_network_num_connection";
2298     string_logcategory_dic["l7vsd_network_access"]          = LOG_CAT_L7VSD_NETWORK_ACCESS;
2299     string_logcategory_dic["nw_acc"]                        = LOG_CAT_L7VSD_NETWORK_ACCESS;
2300     logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_ACCESS]    = "l7vsd_network_access";
2301     string_logcategory_dic["l7vsd_mainthread"]              = LOG_CAT_L7VSD_MAINTHREAD;
2302     string_logcategory_dic["mth"]                           = LOG_CAT_L7VSD_MAINTHREAD;
2303     logcategory_string_dic[LOG_CAT_L7VSD_MAINTHREAD]        = "l7vsd_mainthread";
2304     string_logcategory_dic["l7vsd_virtualservice"]          = LOG_CAT_L7VSD_VIRTUALSERVICE;
2305     string_logcategory_dic["vs"]                            = LOG_CAT_L7VSD_VIRTUALSERVICE;
2306     logcategory_string_dic[LOG_CAT_L7VSD_VIRTUALSERVICE]    = "l7vsd_virtualservice";
2307     string_logcategory_dic["l7vsd_virtualservice_thread"]   = LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD;
2308     string_logcategory_dic["vs_th"]                         = LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD;
2309     logcategory_string_dic[LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD]
2310                                                             = "l7vsd_virtualservice_thread";
2311     string_logcategory_dic["l7vsd_session"]                 = LOG_CAT_L7VSD_SESSION;
2312     string_logcategory_dic["ss"]                            = LOG_CAT_L7VSD_SESSION;
2313     logcategory_string_dic[LOG_CAT_L7VSD_SESSION]           = "l7vsd_session";
2314     string_logcategory_dic["l7vsd_session_thread"]          = LOG_CAT_L7VSD_SESSION_THREAD;
2315     string_logcategory_dic["ss_th"]                         = LOG_CAT_L7VSD_SESSION_THREAD;
2316     logcategory_string_dic[LOG_CAT_L7VSD_SESSION_THREAD]    = "l7vsd_session_thread";
2317     string_logcategory_dic["l7vsd_realserver"]              = LOG_CAT_L7VSD_REALSERVER;
2318     string_logcategory_dic["rs"]                            = LOG_CAT_L7VSD_REALSERVER;
2319     logcategory_string_dic[LOG_CAT_L7VSD_REALSERVER]        = "l7vsd_realserver";
2320     string_logcategory_dic["l7vsd_sorryserver"]             = LOG_CAT_L7VSD_SORRYSERVER;
2321     string_logcategory_dic["sorry"]                         = LOG_CAT_L7VSD_SORRYSERVER;
2322     logcategory_string_dic[LOG_CAT_L7VSD_SORRYSERVER]       = "l7vsd_sorryserver";
2323     string_logcategory_dic["l7vsd_module"]                  = LOG_CAT_L7VSD_MODULE;
2324     string_logcategory_dic["mod"]                           = LOG_CAT_L7VSD_MODULE;
2325     logcategory_string_dic[LOG_CAT_L7VSD_MODULE]            = "l7vsd_module";
2326     string_logcategory_dic["l7vsd_replication"]             = LOG_CAT_L7VSD_REPLICATION;
2327     string_logcategory_dic["rep"]                           = LOG_CAT_L7VSD_REPLICATION;
2328     logcategory_string_dic[LOG_CAT_L7VSD_REPLICATION]       = "l7vsd_replication";
2329     string_logcategory_dic["l7vsd_replication_sendthread"]  = LOG_CAT_L7VSD_REPLICATION_SENDTHREAD;
2330     string_logcategory_dic["rep_sth"]                       = LOG_CAT_L7VSD_REPLICATION_SENDTHREAD;
2331     logcategory_string_dic[LOG_CAT_L7VSD_REPLICATION_SENDTHREAD]
2332                                                             = "l7vsd_replication_sendthread";
2333     string_logcategory_dic["l7vsd_parameter"]               = LOG_CAT_L7VSD_PARAMETER;
2334     string_logcategory_dic["para"]                          = LOG_CAT_L7VSD_PARAMETER;
2335     logcategory_string_dic[LOG_CAT_L7VSD_PARAMETER]         = "l7vsd_parameter";
2336     string_logcategory_dic["l7vsd_logger"]                  = LOG_CAT_L7VSD_LOGGER;
2337     string_logcategory_dic["logger"]                        = LOG_CAT_L7VSD_LOGGER;
2338     logcategory_string_dic[LOG_CAT_L7VSD_LOGGER]            = "l7vsd_logger";
2339     string_logcategory_dic["l7vsd_command"]                 = LOG_CAT_L7VSD_COMMAND;
2340     string_logcategory_dic["cmd"]                           = LOG_CAT_L7VSD_COMMAND;
2341     logcategory_string_dic[LOG_CAT_L7VSD_COMMAND]           = "l7vsd_command";
2342     string_logcategory_dic["l7vsd_start_stop"]              = LOG_CAT_L7VSD_START_STOP;
2343     string_logcategory_dic["stastp"]                        = LOG_CAT_L7VSD_START_STOP;
2344     logcategory_string_dic[LOG_CAT_L7VSD_START_STOP]        = "l7vsd_start_stop";
2345     string_logcategory_dic["l7vsd_system"]                  = LOG_CAT_L7VSD_SYSTEM;
2346     string_logcategory_dic["sys"]                           = LOG_CAT_L7VSD_SYSTEM;
2347     logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM]            = "l7vsd_system";
2348     string_logcategory_dic["l7vsd_system_memory"]           = LOG_CAT_L7VSD_SYSTEM_MEMORY;
2349     string_logcategory_dic["sys_mem"]                       = LOG_CAT_L7VSD_SYSTEM_MEMORY;
2350     logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_MEMORY]     = "l7vsd_system_memory";
2351     string_logcategory_dic["l7vsd_system_endpoint"]         = LOG_CAT_L7VSD_SYSTEM_ENDPOINT;
2352     string_logcategory_dic["sys_ep"]                        = LOG_CAT_L7VSD_SYSTEM_ENDPOINT;
2353     logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_ENDPOINT]   = "l7vsd_system_endpoint";
2354     string_logcategory_dic["l7vsd_system_signal"]           = LOG_CAT_L7VSD_SYSTEM_SIGNAL;
2355     string_logcategory_dic["sys_sig"]                       = LOG_CAT_L7VSD_SYSTEM_SIGNAL;
2356     logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_SIGNAL]     = "l7vsd_system_signal";
2357     string_logcategory_dic["l7vsd_system_environment"]      = LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT;
2358     string_logcategory_dic["sys_env"]                       = LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT;
2359     logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT]
2360                                                             = "l7vsd_system_environment";
2361     string_logcategory_dic["l7vsd_snmpbridge"]              = LOG_CAT_L7VSD_SNMPBRIDGE;
2362     string_logcategory_dic["bridge"]                        = LOG_CAT_L7VSD_SNMPBRIDGE;
2363     logcategory_string_dic[LOG_CAT_L7VSD_SNMPBRIDGE]
2364                                                             = "l7vsd_snmpbridge";
2365     string_logcategory_dic["l7vsd_protocol"]                = LOG_CAT_PROTOCOL;
2366     string_logcategory_dic["prot"]                          = LOG_CAT_PROTOCOL;
2367     logcategory_string_dic[LOG_CAT_PROTOCOL]                = "l7vsd_protocol";
2368     string_logcategory_dic["l7vsd_schedule"]                = LOG_CAT_SCHEDULE;
2369     string_logcategory_dic["sched"]                         = LOG_CAT_SCHEDULE;
2370     logcategory_string_dic[LOG_CAT_SCHEDULE]                = "l7vsd_schedule";
2371     string_logcategory_dic["all"]                           = LOG_CAT_END;
2372
2373     // string snmp logcategory dictionary create 
2374     string_snmp_logcategory_dic["snmpagent_start_stop"]         = LOG_CAT_SNMPAGENT_START_STOP;
2375     string_snmp_logcategory_dic["snmp_stastp"]                  = LOG_CAT_SNMPAGENT_START_STOP;
2376     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_START_STOP]   = "snmpagent_start_stop";
2377     string_snmp_logcategory_dic["snmpagent_manager_receive"]    = LOG_CAT_SNMPAGENT_MANAGER_RECEIVE;
2378     string_snmp_logcategory_dic["snmp_mngrcv"]                  = LOG_CAT_SNMPAGENT_MANAGER_RECEIVE;
2379     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_MANAGER_RECEIVE]
2380                                                                 = "snmpagent_manager_receive";
2381     string_snmp_logcategory_dic["snmpagent_manager_send"]       = LOG_CAT_SNMPAGENT_MANAGER_SEND;
2382     string_snmp_logcategory_dic["snmp_mngsnd"]                  = LOG_CAT_SNMPAGENT_MANAGER_SEND;
2383     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_MANAGER_SEND] = "snmpagent_manager_send";
2384     string_snmp_logcategory_dic["snmpagent_l7vsd_receive"]      = LOG_CAT_SNMPAGENT_L7VSD_RECEIVE;
2385     string_snmp_logcategory_dic["snmp_vsdrcv"]                  = LOG_CAT_SNMPAGENT_L7VSD_RECEIVE;
2386     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_L7VSD_RECEIVE]
2387                                                                 = "snmpagent_l7vsd_receive";
2388     string_snmp_logcategory_dic["snmpagent_l7vsd_send"]         = LOG_CAT_SNMPAGENT_L7VSD_SEND;
2389     string_snmp_logcategory_dic["snmp_vsdsnd"]                  = LOG_CAT_SNMPAGENT_L7VSD_SEND;
2390     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_L7VSD_SEND]   = "snmpagent_l7vsd_send";
2391     string_snmp_logcategory_dic["snmpagent_logger"]             = LOG_CAT_SNMPAGENT_LOGGER;
2392     string_snmp_logcategory_dic["snmp_logger"]                  = LOG_CAT_SNMPAGENT_LOGGER;
2393     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_LOGGER]       = "snmpagent_logger";
2394     string_snmp_logcategory_dic["snmpagent_parameter"]          = LOG_CAT_SNMPAGENT_PARAMETER;
2395     string_snmp_logcategory_dic["snmp_para"]                    = LOG_CAT_SNMPAGENT_PARAMETER;
2396     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_PARAMETER]    = "snmpagent_parameter";
2397     string_snmp_logcategory_dic["snmpagent_system"]             = LOG_CAT_SNMPAGENT_SYSTEM;
2398     string_snmp_logcategory_dic["snmp_sys"]                     = LOG_CAT_SNMPAGENT_SYSTEM;
2399     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM]       = "snmpagent_system";
2400     string_snmp_logcategory_dic["snmpagent_system_memory"]      = LOG_CAT_SNMPAGENT_SYSTEM_MEMORY;
2401     string_snmp_logcategory_dic["snmp_sys_mem"]                 = LOG_CAT_SNMPAGENT_SYSTEM_MEMORY;
2402     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM_MEMORY]
2403                                                                 = "snmpagent_system_memory";
2404     string_snmp_logcategory_dic["snmpagent_system_endpoint"]    = LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT;
2405     string_snmp_logcategory_dic["snmp_sys_ep"]                  = LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT;
2406     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT]
2407                                                                 = "snmpagent_system_endpoint";
2408     string_snmp_logcategory_dic["snmpagent_system_signal"]      = LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL;
2409     string_snmp_logcategory_dic["snmp_sys_sig"]                 = LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL;
2410     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL]
2411                                                                 = "snmpagent_system_signal";
2412     string_snmp_logcategory_dic["snmpagent_system_environment"] = LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT;
2413     string_snmp_logcategory_dic["snmp_sys_env"]                 = LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT;
2414     snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT]
2415                                                                 = "snmpagent_system_environment";
2416     string_snmp_logcategory_dic["all"]                          = LOG_CAT_END;
2417
2418     // string log level dictionary create.
2419     string_loglevel_dic["debug"]        = LOG_LV_DEBUG;
2420     loglevel_string_dic[LOG_LV_DEBUG]   = "debug";
2421     string_loglevel_dic["info"]         = LOG_LV_INFO;
2422     loglevel_string_dic[LOG_LV_INFO]    = "info";
2423     string_loglevel_dic["warn"]         = LOG_LV_WARN;
2424     loglevel_string_dic[LOG_LV_WARN]    = "warn";
2425     string_loglevel_dic["error"]        = LOG_LV_ERROR;
2426     loglevel_string_dic[LOG_LV_ERROR]   = "error";
2427     string_loglevel_dic["fatal"]        = LOG_LV_FATAL;
2428     loglevel_string_dic[LOG_LV_FATAL]   = "fatal";
2429
2430     // parameter category dictionary create
2431     string_parameter_dic["all"]             = PARAM_COMP_ALL;
2432     string_parameter_dic["l7vsd"]           = PARAM_COMP_L7VSD;
2433     string_parameter_dic["command"]         = PARAM_COMP_COMMAND;
2434     string_parameter_dic["session"]         = PARAM_COMP_SESSION;
2435     string_parameter_dic["virtualservice"]  = PARAM_COMP_VIRTUALSERVICE;
2436     string_parameter_dic["module"]          = PARAM_COMP_MODULE;
2437     string_parameter_dic["replication"]     = PARAM_COMP_REPLICATION;
2438     string_parameter_dic["logger"]          = PARAM_COMP_LOGGER;
2439     string_parameter_dic["l7vsadm"]         = PARAM_COMP_L7VSADM;
2440     string_parameter_dic["snmpagent"]       = PARAM_COMP_SNMPAGENT;
2441     string_parameter_dic["ssl"]             = PARAM_COMP_SSL;
2442
2443     // create disp_result dictionary.
2444     disp_result_dic[l7vsadm_request::CMD_LIST]            = boost::bind( &l7vsadm::disp_list, this );
2445     disp_result_dic[l7vsadm_request::CMD_LIST_KEY]        = boost::bind( &l7vsadm::disp_list_key, this );
2446     disp_result_dic[l7vsadm_request::CMD_LIST_VERBOSE]    = boost::bind( &l7vsadm::disp_list_verbose, this );
2447
2448     // response_message_dic create
2449     response_error_message_dic[l7vsd_response::RESPONSE_ERROR]                  = "command error : ";
2450     response_error_message_dic[l7vsd_response::RESPONSE_LIST_ERROR]             = "list command error : ";
2451     response_error_message_dic[l7vsd_response::RESPONSE_LIST_VERBOSE_ERROR]     = "list verbose error : ";
2452     response_error_message_dic[l7vsd_response::RESPONSE_LIST_KEY_ERROR]         = "list key error : ";
2453     response_error_message_dic[l7vsd_response::RESPONSE_ADD_VS_ERROR]           = "add vs error : ";
2454     response_error_message_dic[l7vsd_response::RESPONSE_DEL_VS_ERROR]           = "del vs error : ";
2455     response_error_message_dic[l7vsd_response::RESPONSE_EDIT_VS_ERROR]          = "edit vs error : ";
2456     response_error_message_dic[l7vsd_response::RESPONSE_FLUSH_VS_ERROR]         = "flush vs error : ";
2457     response_error_message_dic[l7vsd_response::RESPONSE_ADD_RS_ERROR]           = "add rs error : ";
2458     response_error_message_dic[l7vsd_response::RESPONSE_DEL_RS_ERROR]           = "del rs error : ";
2459     response_error_message_dic[l7vsd_response::RESPONSE_EDIT_RS_ERROR]          = "edit rs error : ";
2460     response_error_message_dic[l7vsd_response::RESPONSE_REPLICATION_ERROR]      = "replication command error : ";
2461     response_error_message_dic[l7vsd_response::RESPONSE_LOG_ERROR]              = "log command error : ";
2462     response_error_message_dic[l7vsd_response::RESPONSE_SNMP_ERROR]             = "snmp command error : ";
2463     response_error_message_dic[l7vsd_response::RESPONSE_PARAMETER_ERROR]        = "parameter error : ";
2464
2465     replication_mode_string_dic[replication::REPLICATION_OUT]               = "OUT";
2466     replication_mode_string_dic[replication::REPLICATION_SINGLE]            = "SINGLE";
2467     replication_mode_string_dic[replication::REPLICATION_MASTER]            = "MASTER";
2468     replication_mode_string_dic[replication::REPLICATION_SLAVE]             = "SLAVE";
2469     replication_mode_string_dic[replication::REPLICATION_MASTER_STOP]       = "MASTER_STOP";
2470     replication_mode_string_dic[replication::REPLICATION_SLAVE_STOP]        = "SLAVE_STOP";
2471
2472 }
2473
2474 //! Get l7vsadm parameter data
2475 void    l7vs::l7vsadm::set_parameter(){
2476     Logger    logger( LOG_CAT_L7VSADM_COMMON, 36, "l7vsadm::set_parameter", __FILE__, __LINE__ );
2477
2478     // Get and Set l7vsadm all parameter value.
2479     Parameter    param;
2480     error_code    err;
2481
2482     // command_wait_interval
2483     command_wait_interval = param.get_int(PARAM_COMP_L7VSADM, "cmd_interval", err);
2484     if( !err ){
2485         if(    command_wait_interval < 0 ||
2486             command_wait_interval > L7VSADM_MAX_WAIT ){
2487             // When illegal parameter value, use default parameter value.
2488             command_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2489             std::string    msg("Illegal cmd_interval parameter value. Use default value.");
2490             Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 1, msg, __FILE__, __LINE__);
2491         }
2492     }
2493     else{
2494         std::string    msg("Get cmd_interval parameter error. Use default value.");
2495         Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 2, msg, __FILE__, __LINE__);
2496     }
2497
2498     //command_wait_count 
2499     command_wait_count = param.get_int(PARAM_COMP_L7VSADM, "cmd_count", err);
2500     if( !err ){
2501         if(    command_wait_count < 0 ||
2502             command_wait_count > L7VSADM_MAX_WAIT ){
2503             // When illegal parameter value, use default parameter value.
2504             command_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2505             std::string    msg("Illegal cmd_count parameter value. Use default value.");
2506             Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 3, msg, __FILE__, __LINE__);
2507         }
2508     }
2509     else{
2510         std::string    msg("Get cmd_count parameter error. Use default value.");
2511         Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 4, msg, __FILE__, __LINE__);
2512     }
2513
2514     if ((command_wait_interval * command_wait_count) > L7VSADM_MAX_WAIT) {
2515         // When wait value too long, use default parameter value.
2516         command_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2517         command_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2518         std::string    msg("Command wait value too long. Use default value.");
2519         Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 9, msg, __FILE__, __LINE__);
2520
2521     }
2522     if ((connect_wait_interval * connect_wait_count) > L7VSADM_MAX_WAIT) {
2523         // When wait value too long, use default parameter value.
2524         connect_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2525         connect_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2526         std::string    msg("Connect wait value too long. Use default value.");
2527         Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 10, msg, __FILE__, __LINE__);
2528     }
2529 }
2530
2531 //! l7vsadm command execute
2532 bool    l7vs::l7vsadm::execute( int argc, char* argv[] ){
2533     Logger    logger( LOG_CAT_L7VSADM_COMMON, 37, "l7vsadm::execute", __FILE__, __LINE__ );
2534
2535     /*-------- DEBUG LOG --------*/
2536     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSADM_COMMON ) ){
2537         std::stringstream    debugstr;
2538         debugstr << boost::format( "l7vsadm::execute arguments:%s" ) % argument_debug_dump( argc, argv );
2539         Logger::putLogDebug( LOG_CAT_L7VSADM_COMMON, 38, debugstr.str(), __FILE__, __LINE__ );
2540     }
2541     /*------ DEBUG LOG END ------*/
2542
2543     // set sighanlder
2544     if ( 0 > set_sighandlers() ) {
2545         std::string    buf("set_sighandlers failed.");
2546         std::cerr << "COMMON ERROR : " << buf << std::endl;
2547         Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 1, buf, __FILE__, __LINE__ );
2548         return false;
2549     }
2550
2551     // readparam
2552     set_parameter();
2553
2554     // Get l7vsadm execute file path from /proc/(pid)/exe (symbolic link)
2555     char l7vsadm_file_path[256];
2556     memset(l7vsadm_file_path, 0, sizeof(l7vsadm_file_path));
2557     readlink("/proc/self/exe", l7vsadm_file_path, sizeof(l7vsadm_file_path));
2558
2559     // L7vsadm command conflict check. (Try l7vsadm execute file lock)
2560     file_lock    lock( l7vsadm_file_path, l7vsadm_err );
2561     if( l7vsadm_err ){
2562         std::cerr << "COMMON ERROR : " << l7vsadm_err.get_message() << std::endl;
2563         Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 2, l7vsadm_err.get_message(), __FILE__, __LINE__ );
2564         return false;
2565     }
2566
2567     try{
2568         // l7vsadm file lock wait
2569         int command_retry_count = 0;
2570         while( true ){
2571             // Check signal.
2572             if( signal_flag ){
2573                 std::stringstream buf;
2574                 buf << boost::format( "Signal (%d) Received." ) % received_sig;
2575                 l7vsadm_err.setter( true, buf.str() );
2576                 Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 3, buf.str(), __FILE__, __LINE__ );
2577                 break;
2578             }
2579    
2580             // Try lock l7vsadm file.    
2581             if( lock.try_lock() ){
2582                  break;
2583             }
2584
2585             ++command_retry_count;
2586             if (command_retry_count > command_wait_count) {
2587                 // L7vsadm file lock error. (l7vsadm is executing)
2588                 std::string    buf( "L7vsadm file lock timeout. (l7vsadm is already executing)" );
2589                 l7vsadm_err.setter( true, buf );
2590                 Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 4, buf, __FILE__, __LINE__ );
2591                 break;
2592             }
2593
2594             std::stringstream buf;
2595             buf << boost::format( "L7vsadm file lock error. (l7vsadm is already executing) (retry %d)" ) % command_retry_count;
2596             Logger::putLogWarn( LOG_CAT_L7VSADM_COMMON, 11, buf.str(), __FILE__, __LINE__ );
2597
2598             // Lock retrying.
2599             boost::xtime xt;
2600             xtime_get(&xt, boost::TIME_UTC);
2601             xt.sec += command_wait_interval;
2602             boost::thread::sleep(xt);
2603         }
2604
2605         // display err
2606         if( l7vsadm_err ){
2607             std::cerr << "COMMON ERROR : " << l7vsadm_err.get_message() << std::endl;
2608             return false;
2609         }
2610
2611         // no argument, assume list command
2612         if( 1 == argc ){
2613             request.command = l7vsadm_request::CMD_LIST;
2614         }
2615         else {
2616             // parse command line
2617             int pos = 1;
2618             parse_cmd_map_type::iterator itr = command_dic.find( argv[pos] );
2619             if( itr != command_dic.end() ){
2620                 itr->second( argc, argv );
2621             }
2622             else{
2623                 std::string    buf("command not found.");
2624                 l7vsadm_err.setter( true, buf );
2625                 Logger::putLogError( LOG_CAT_L7VSADM_PARSE, 88, buf, __FILE__, __LINE__ );
2626             }
2627         }
2628     
2629         // display command parse result
2630         if( l7vsadm_err ){
2631             std::cerr << "PARSE ERROR : " << l7vsadm_err.get_message() << std::endl;
2632             std::cerr << usage() << std::endl;
2633             return false;
2634         }
2635     
2636         if( l7vsadm_request::CMD_HELP != request.command ){
2637             // communicate to l7vsd
2638             using boost::asio::local::stream_protocol;
2639             boost::array< char, COMMAND_BUFFER_SIZE >    response_buffer;
2640             response_buffer.assign( 0x00 );
2641
2642             // connect
2643             boost::asio::io_service    io;
2644             stream_protocol::socket    s( io );
2645
2646             int    connect_retry_count = 0;
2647             while( true ){
2648                 // Check signal.
2649                 if( signal_flag ){
2650                     std::stringstream buf;
2651                     buf << boost::format( "Signal (%d) Received." ) % received_sig;
2652                     l7vsadm_err.setter( true, buf.str() );
2653                     Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 5, buf.str(), __FILE__, __LINE__ );
2654                     break;
2655                 }
2656         
2657                 // Try connect to config socket.
2658                 boost::system::error_code err;
2659                 s.connect(stream_protocol::endpoint( L7VS_CONFIG_SOCKNAME ), err );
2660                 if( !err ){
2661                     break;
2662                 }else{
2663                     //connect_retry_count was to be unused.
2664                     //must be delete below "waiting" code!
2665                     std::stringstream   buf;
2666                     buf << boost::format( "connect() failed: %s.") % err.message();
2667                     l7vsadm_err.setter( true, buf.str() );
2668                     Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 9, buf.str(), __FILE__, __LINE__ );
2669                     break;
2670                 }
2671
2672                 connect_retry_count++;
2673                 if (connect_retry_count > connect_wait_count) {
2674                     std::stringstream    buf;
2675                     buf << boost::format( "connect() to daemon timeout: %s." ) % err.message();
2676                     l7vsadm_err.setter( true, buf.str() );
2677                     Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 6, buf.str(), __FILE__, __LINE__ );
2678                     break;
2679                 }
2680                 // Connect retrying.
2681                 boost::xtime xt;
2682                 xtime_get(&xt, boost::TIME_UTC);
2683                 xt.sec += connect_wait_interval;
2684                 boost::thread::sleep(xt);
2685             }
2686
2687             // display err
2688             if( l7vsadm_err ){
2689                 std::cerr << "COMMON ERROR : " << l7vsadm_err.get_message() << std::endl;
2690                 return false;
2691             }
2692
2693             /*-------- DEBUG LOG --------*/
2694             if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSADM_COMMON ) ){
2695                 std::stringstream    debugstr;
2696                 debugstr << boost::format( "l7vsadm_send_request:%s" ) % request;
2697                 Logger::putLogDebug( LOG_CAT_L7VSADM_COMMON, 39, debugstr.str(), __FILE__, __LINE__ );
2698             }
2699             /*------ DEBUG LOG END ------*/
2700
2701             // write sockfile
2702             std::stringstream    send_stream;
2703             boost::archive::text_oarchive    oa( send_stream );
2704             oa << (const l7vs::l7vsadm_request&) request;
2705             boost::asio::write( s, boost::asio::buffer( send_stream.str() ) );
2706
2707             // read sockfile
2708             s.read_some( boost::asio::buffer( response_buffer ) );
2709             
2710             std::stringstream    recv_stream;
2711             recv_stream << &(response_buffer[0]);
2712             boost::archive::text_iarchive    ia( recv_stream );
2713             ia >> response;
2714
2715             /*-------- DEBUG LOG --------*/
2716             if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSADM_COMMON ) ){
2717                 std::stringstream    debugstr;
2718                 debugstr << boost::format( "l7vsadm_recv_response:%s" ) % response;
2719                 Logger::putLogDebug( LOG_CAT_L7VSADM_COMMON, 40, debugstr.str(), __FILE__, __LINE__ );
2720             }
2721             /*------ DEBUG LOG END ------*/
2722     
2723             // close socket
2724             s.close();
2725         
2726             // display result
2727             if( l7vsd_response::RESPONSE_OK == response.status ){
2728                 disp_result_map_type::iterator    itr = disp_result_dic.find( request.command );
2729                 if( itr != disp_result_dic.end() )
2730                     itr->second();
2731             }
2732             else{
2733                 std::stringstream    buf;
2734                 response_error_message_map_type::iterator    itr = response_error_message_dic.find( response.status );
2735                 if( itr != response_error_message_dic.end() )
2736                     buf << itr->second << response.message;
2737                 else
2738                     buf << "COMMAND ERROR : " << response.message;
2739                 std::cerr << buf.str() << std::endl;
2740                 Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 7, buf.str(), __FILE__, __LINE__ );
2741                 return false;
2742             }
2743         }    //if help_mode
2744     }    //try
2745     catch( std::exception& e ){
2746         std::stringstream    buf;
2747         buf << "COMMON ERROR : " << e.what();
2748         std::cerr << buf.str() << std::endl;
2749         Logger::putLogError( LOG_CAT_L7VSADM_COMMON, 8, buf.str(), __FILE__, __LINE__ );
2750         return false;
2751     }
2752     return true;
2753 }
2754
2755 //! argument dump for debug
2756 //! @param[in]    argument count
2757 //! @param[in]    argument value
2758 std::string    l7vs::l7vsadm::argument_debug_dump( int argc, char* argv[] ){
2759     std::stringstream buf;
2760     if( !argv ){
2761         buf << "argument=(null)";
2762     }
2763     else{
2764         buf << boost::format( "argument={argc=%d: " ) % argc;
2765         for( int i = 0; i < argc; ++i){
2766             buf << boost::format( "argv[%d]=%s: " ) % i % argv[i];
2767         }
2768         buf << "}";
2769     }
2770     return buf.str();
2771 }
2772
2773 //! signal handler function
2774 //! @param[in]    signal
2775 static void sig_exit_handler( int sig ){
2776     received_sig = sig;
2777     signal_flag = true;
2778 }
2779
2780 //! set singal handler function
2781 //! @param[in]    signal
2782 //! @param[in]    handler function pointer
2783 //! @return        0/success, -1/fail
2784 static int set_sighandler( int sig, void ( *handler )( int ) ){
2785     struct    sigaction act;
2786     int        ret;
2787
2788     ret = sigaction( sig, NULL, &act );
2789     if( 0 > ret )    return ret;
2790
2791     act.sa_flags &= ~SA_RESETHAND;
2792     act.sa_handler = handler;
2793
2794     ret = sigaction( sig, &act, NULL );
2795     if( 0 > ret )    return ret;
2796
2797     return 0;
2798 }
2799
2800 //! set all singal handler function
2801 //! @return        0/success, -1/fail
2802 static int set_sighandlers() {
2803     int ret;
2804
2805 #define SET_SIGHANDLER(sig, handler)                \
2806     do {                                            \
2807         ret = set_sighandler((sig), (handler));        \
2808         if (ret < 0) {                                \
2809             return ret;                                \
2810         }                                            \
2811     } while (0)
2812
2813     SET_SIGHANDLER( SIGHUP,        sig_exit_handler );
2814     SET_SIGHANDLER( SIGINT,        sig_exit_handler );
2815     SET_SIGHANDLER( SIGQUIT,    sig_exit_handler );
2816     SET_SIGHANDLER( SIGPIPE,    sig_exit_handler );
2817     SET_SIGHANDLER( SIGTERM,    sig_exit_handler );
2818     SET_SIGHANDLER( SIGUSR1,    sig_exit_handler );
2819     SET_SIGHANDLER( SIGUSR2,    sig_exit_handler );
2820
2821 #undef SET_SIGHANDLER
2822
2823     return 0;
2824 }
2825
2826 #ifndef    UNIT_TEST
2827 int main( int argc, char* argv[] ){
2828
2829     try {
2830         l7vs::Logger        logger;
2831         l7vs::Parameter        param;
2832         logger.loadConf();
2833     } catch(...) {
2834     }
2835
2836
2837     l7vs::l7vsadm    adm;
2838     if( !adm.execute( argc, argv ) ){
2839         return -1;
2840     }
2841     return 0;
2842 }
2843 #endif    //UNIT_TEST
2844