#include "globus_common.h" #include "globus_options.h" #include "globus_i_gfork.h" #include "version.h" static globus_list_t * gfork_l_list_to_list( const char * in_str, globus_list_t * old_list); globus_result_t globus_i_opts_to_handle( gfork_i_options_t * opts, gfork_i_handle_t * handle) { char * driver_name; char * driver_opts; globus_xio_attr_t attr; globus_result_t result; int i; globus_list_t * list; globus_xio_driver_t driver; GForkFuncName(globus_i_opts_to_handle); memset(handle, '\0', sizeof(gfork_i_handle_t)); globus_xio_stack_init(&handle->stack, NULL); globus_xio_attr_init(&attr); handle->opts = opts; if(opts->server != NULL) { handle->server_argv = (char **) globus_calloc( globus_list_size(opts->server_arg_list) + 2, sizeof(char *)); handle->server_argv[0] = opts->server; i = 1; for(list = opts->server_arg_list; !globus_list_empty(list); list = globus_list_rest(list)) { handle->server_argv[i] = (char *) globus_list_first(list); i++; } } else { /* XXX create error object */ result = GForkErrorStr("no program specified before server arguments"); goto error_no_server; } if(opts->master != NULL) { gfork_i_master_program_ent_t * m_ent; /* add the last one to the list */ m_ent = (gfork_i_master_program_ent_t *) globus_calloc( 1, sizeof(gfork_i_master_program_ent_t)); m_ent->master = opts->master; m_ent->master_arg_list = opts->master_arg_list; m_ent->master_uid = opts->master_user; m_ent->master_nice = opts->master_nice; m_ent->master_env = opts->env_list; globus_list_insert(&opts->master_list, m_ent); } handle->master_list = opts->master_list; if(globus_list_empty(opts->protocol_list)) { globus_list_insert(&opts->protocol_list, "tcp"); } for(list = opts->protocol_list; !globus_list_empty(list); list = globus_list_rest(list)) { driver_name = (char *) globus_list_first(list); driver_opts = strchr(driver_name, ':'); if(driver_opts != NULL) { *driver_opts = '\0'; driver_opts++; } result = globus_xio_driver_load(driver_name, &driver); if(result != GLOBUS_SUCCESS) { goto error_drivers; } globus_list_insert(&handle->loaded_drivers, driver); if(driver_opts != NULL) { result = globus_xio_attr_cntl( attr, driver, GLOBUS_XIO_SET_STRING_OPTIONS, driver_opts); if(result != GLOBUS_SUCCESS) { goto error_drivers; } } globus_xio_stack_push_driver(handle->stack, driver); if(strcmp(driver_name, "tcp") == 0) { handle->tcp_driver = driver; result = globus_xio_attr_cntl( attr, driver, GLOBUS_XIO_TCP_SET_REUSEADDR, GLOBUS_TRUE); if(result != GLOBUS_SUCCESS) { } } } if(opts->crowded_msg == NULL) { opts->crowded_msg = GFORK_CROWDED_MESSAGE; opts->crowded_msg_len = strlen(opts->crowded_msg); } if(opts->instances <= 0) { opts->instances = 100; } if(handle->tcp_driver != NULL) { if(opts->port != 0) { globus_xio_attr_cntl( attr, handle->tcp_driver, GLOBUS_XIO_TCP_SET_PORT, opts->port); } /* int backlog = -1; if(opts->instances > 1) { backlog = opts->instances / 2; backlog = 2; } globus_xio_attr_cntl( attr, handle->tcp_driver, GLOBUS_XIO_TCP_SET_BACKLOG, backlog); */ } result = globus_xio_server_create( &handle->server_xio, attr, handle->stack); if(result != GLOBUS_SUCCESS) { goto error_server; } globus_xio_attr_destroy(attr); return GLOBUS_SUCCESS; error_server: error_drivers: if(handle->master_argv) { globus_free(handle->master_argv); } globus_free(handle->server_argv); globus_list_free(handle->loaded_drivers); error_no_server: globus_xio_attr_destroy(attr); return result; } static globus_result_t gfork_l_opts_help( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { globus_options_help(opts_handle); exit(0); } static globus_result_t gfork_l_opts_master_uid( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { int sc; int mu; gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; sc = sscanf(opt[0], "%d", &mu); if(sc != 1) { goto error_format; } gfork_h->master_user = mu; *out_parms_used = 1; return GLOBUS_SUCCESS; error_format: *out_parms_used = 0; return 0x1; } static globus_result_t gfork_l_opts_master( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_master_program_ent_t * m_ent; gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; if(gfork_h->master != NULL) { m_ent = (gfork_i_master_program_ent_t *) globus_calloc( 1, sizeof(gfork_i_master_program_ent_t)); m_ent->master = gfork_h->master; m_ent->master_arg_list = gfork_h->master_arg_list; m_ent->master_uid = gfork_h->master_user; m_ent->master_env = gfork_h->env_list; m_ent->master_nice = gfork_h->master_nice; gfork_h->env_list = NULL; gfork_h->master = NULL; gfork_h->master_arg_list = NULL; gfork_h->master_user = 0; gfork_h->master_nice = 0; globus_list_insert(&gfork_h->master_list, m_ent); } gfork_h->master = strdup(opt[0]); *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_master_args( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { globus_list_t * list; gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; list = gfork_l_list_to_list(opt[0], gfork_h->master_arg_list); gfork_h->master_arg_list = list; *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_version( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { /* print the version and exit */ globus_version_print( "gfork", &local_version, stderr, GLOBUS_TRUE); globus_module_print_activated_versions(stderr, GLOBUS_TRUE); *out_parms_used = 0; exit(0); } static globus_list_t * gfork_l_list_to_list( const char * in_str, globus_list_t * old_list) { void * tmp_ent; globus_list_t * out_list; globus_list_t * list; globus_list_t * rev_list = NULL; list = globus_list_from_string(in_str, ' ', NULL); /* gotta reverse this */ while(!globus_list_empty(list)) { tmp_ent = globus_list_remove(&list, list); globus_list_insert(&rev_list, tmp_ent); } out_list = globus_list_concat(old_list, rev_list); globus_list_free(rev_list); globus_list_free(old_list); return out_list; } static globus_result_t gfork_l_opts_id( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; gfork_h->id = strdup(opt[0]); *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_protocol( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; globus_list_t * list; gfork_h = (gfork_i_options_t *) arg; list = gfork_l_list_to_list(opt[0], gfork_h->protocol_list); gfork_h->protocol_list = list; *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_server( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; gfork_h->server = strdup(opt[0]); *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_server_args( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { globus_list_t * list; gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; list = gfork_l_list_to_list(opt[0], gfork_h->server_arg_list); gfork_h->server_arg_list = list; *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_port( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { int sc; int port; gfork_i_options_t * gfork_h; globus_result_t result; GForkFuncName(gfork_l_opts_port); gfork_h = (gfork_i_options_t *) arg; sc = sscanf(opt[0], "%d", &port); if(sc != 1) { result = GForkErrorStr("Port must be an integer"); goto error_format; } gfork_h->port = port; *out_parms_used = 1; return GLOBUS_SUCCESS; error_format: *out_parms_used = 0; return result; } static globus_result_t gfork_l_opts_instances( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; int instances; int sc; globus_result_t result; GForkFuncName(gfork_l_opts_instances); gfork_h = (gfork_i_options_t *) arg; sc = sscanf(opt[0], "%d", &instances); if(sc != 1) { result = GForkErrorStr("Instance must be an integer"); goto error_format; } gfork_h->instances = instances; *out_parms_used = 1; return GLOBUS_SUCCESS; error_format: *out_parms_used = 0; return result; } static globus_result_t gfork_l_opts_nice( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; int sc; int nice; globus_result_t result; GForkFuncName(gfork_l_opts_nice); gfork_h = (gfork_i_options_t *) arg; sc = sscanf(opt[0], "%d", &nice); if(sc != 1) { result = GForkErrorStr("Nice must be an integer"); goto error_format; } gfork_h->nice = nice; *out_parms_used = 1; return GLOBUS_SUCCESS; error_format: *out_parms_used = 0; return result; } static globus_result_t gfork_l_opts_bind( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; gfork_h->interfajce = strdup(opt[0]); *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_conf_file( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; gfork_h->conf_file = strdup(opt[0]); *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_env( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; globus_list_t * list; gfork_h = (gfork_i_options_t *) arg; list = gfork_l_list_to_list(opt[0], gfork_h->env_list); gfork_h->env_list = list; *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_log_level( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; int level; int sc; globus_result_t result; GForkFuncName(gfork_l_opts_log_level); gfork_h = (gfork_i_options_t *) arg; sc = sscanf(opt[0], "%d", &level); if(sc != 1) { result = GForkErrorStr("Log level must be an integer"); goto error_format; } gfork_h->log_level = level; *out_parms_used = 1; return GLOBUS_SUCCESS; error_format: *out_parms_used = 0; return result; } static globus_result_t gfork_l_opts_log_file( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; globus_result_t result; FILE * fptr; GForkFuncName(gfork_l_opts_log_file); gfork_h = (gfork_i_options_t *) arg; if(strcmp(opt[0], "-") == 0) { gfork_h->log_fptr = stdout; } else { fptr = fopen(opt[0], "w"); if(fptr == NULL) { result = GForkErrorStr("Could not open log file"); goto error; } gfork_h->log_fptr = fptr; } *out_parms_used = 1; return GLOBUS_SUCCESS; error: return result; } static globus_result_t gfork_l_opts_quiet( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; if(strcasecmp("true", opt[0]) == 0 || strcasecmp("yes", opt[0]) == 0 || strcasecmp("t", opt[0]) == 0 || strcasecmp("y", opt[0]) == 0) { gfork_h->quiet = GLOBUS_TRUE; } else { gfork_h->quiet = GLOBUS_FALSE; } *out_parms_used = 1; return GLOBUS_SUCCESS; } static globus_result_t gfork_l_opts_crowded( globus_options_handle_t opts_handle, char * cmd, char ** opt, void * arg, int * out_parms_used) { gfork_i_options_t * gfork_h; gfork_h = (gfork_i_options_t *) arg; gfork_h->crowded_msg = strdup(opt[0]); gfork_h->crowded_msg_len = strlen(gfork_h->crowded_msg); *out_parms_used = 1; return GLOBUS_SUCCESS; } /* * for xinetd, ignoting type, flags, disable, socket_type, user, group */ globus_options_entry_t gfork_l_opts_table[] = { {"id", "I", NULL, "", "This attribute is used to uniquely identify a service.", 1, gfork_l_opts_id}, {"protocol", "S", NULL, "", "A list of xio drivers bottom to top", 1, gfork_l_opts_protocol}, {"server", "s", NULL, "", "Determines the program to execute for this service.", 1, gfork_l_opts_server}, {"server_args", "sa", NULL, "", "List of arguments. Comma separated (or += if xinetd style)", 1, gfork_l_opts_server_args}, {"port", "p", NULL, "", "The port number for the TCP listener", 1, gfork_l_opts_port}, {"instances", "inst", NULL, "", "The number of servers that can be simultaneously active.", 1, gfork_l_opts_instances}, {"nice", "n", NULL, "", "Sets the server priority.", 1, gfork_l_opts_nice}, {"interface", "b", NULL, "", "Sets the listening interface.", 1, gfork_l_opts_bind}, {"bind", "b", NULL, "", "Sets the listening interface.", 1, gfork_l_opts_bind}, {"env", "e", NULL, "", "Sets the services environment", 1, gfork_l_opts_env}, {"master-uid", "M", NULL, "", "The uid under which the master program will be run", 1, gfork_l_opts_master_uid}, {"master", "m", NULL, "", "The name of the master program", 1, gfork_l_opts_master}, {"master_args", "ma", NULL, "", "List of arguments. Comma separated (or += if xinetd style)", 1, gfork_l_opts_master_args}, {"config_file", "c", NULL, NULL, "Print version information.", 1, gfork_l_opts_conf_file}, {"version", "v", NULL, NULL, "Print version information.", 0, gfork_l_opts_version}, {"help", "h", NULL, NULL, "print the help message", 0, gfork_l_opts_help}, {"log_level", "L", NULL, "", "Set the logging level 0 - 9", 1, gfork_l_opts_log_level}, {"log_file", "f", NULL, "", "Set the log file", 1, gfork_l_opts_log_file}, {"quiet", "q", NULL, "", "Turn off all output", 1, gfork_l_opts_quiet}, {"crowded", "C", NULL, "", "Turn off all output", 1, gfork_l_opts_crowded}, {NULL, NULL, NULL, NULL, NULL, 0, NULL} };