Exemple #1
0
const char *log_getfilename(int whatfor)
{
	const char *p = NULL;
	
	switch(whatfor) {
	case LOG_FILE_DAEMON:
		if( (p = conf_string(cf_log_file_daemon)) == NULL )
			p = DAEMON_LOGFILE;
		break;
	case LOG_FILE_SESSION:
		if( (p = conf_string(cf_log_file)) == NULL )
			p = BFORCE_LOGFILE;
		break;
#ifdef DEBUG
	case LOG_FILE_DEBUG:
		if( (p = conf_string(cf_debug_file)) == NULL )
			p = BFORCE_DEBFILE;
		break;
#endif
	case LOG_FILE_HISTORY:
		break;
	}
	
	return p;
}
Exemple #2
0
void debug_configure() // this function should be called after configuration is settled
{
    char *debugfile = conf_string(cf_debug_file);
    char *debuglevel =  conf_string(cf_debug_level);
    unsigned long n_debuglevel;

    if (debugfile!=NULL) {
	if( strcmp(debug_name, debugfile)!=0 ) {
	
            if( debug_isopened() ) debug_close();
	
	/* Reset ignore flag */
	    if( debug_invalid_name )
		debug_invalid_name = FALSE;
	
	    strncpy(debug_name, debugfile, sizeof(debug_name));
	}
    }

    _debug_parsestring(debuglevel, &n_debuglevel);

    if( n_debuglevel != debug_current_debuglevel ) {
		log("changing debug level from 0x%08x to 0x%08x",
			debug_current_debuglevel, n_debuglevel);
		debug_current_debuglevel = n_debuglevel;
    }
}
Exemple #3
0
void settings_load_fields(void *st, const field *fields, int nfields) {
    for(int i=0;i < nfields;++i) {
        const field *f = &fields[i];
        switch(f->type) {
            case TYPE_INT:
                *fieldint(st, f->offset) = conf_int(f->name);
                break;

            case TYPE_FLOAT:
                *fieldfloat(st, f->offset) = conf_float(f->name);
                break;

            case TYPE_BOOL:
                *fieldbool(st, f->offset) = conf_bool(f->name);
                break;

            case TYPE_STRING:
                {
                    // make a copy of the string
                    char **s = fieldstr(st, f->offset);
                    if(*s) {
                        free(*s);
                    }
                    const char *s2 = conf_string(f->name);
                    *s = malloc(strlen(s2)+1);
                    strcpy(*s, s2);
                }
                break;
        }
    }
}
Exemple #4
0
int fw_perform_return( gchar *action, GHashTable *conf, peer *p, gchar *result, int size) {
    GHashTable *data;
    gchar *cmd;
    FILE * fd;
    int ret=0;

    gchar dummy_result[30];
    if ( !result ) {
        result = dummy_result;
        size = sizeof(dummy_result);
    }
    
    data = g_hash_dup( conf );
    //
    // Than add specifics about this particular client, if any
    if (p != NULL) {
	g_hash_set( data, "IP",    p->ip );
	g_hash_set( data, "MAC",   p->hw );
	g_hash_set( data, "Class", "Public" );
    }

    cmd = conf_string( conf, action );
    cmd = parse_template( cmd, data );
    g_warning("Got command %s from action %s", cmd, action );
    
    // add data to the environment
    g_hash_table_foreach( data, (GHFunc) fw_popen_set_env, NULL );

    fd = popen(cmd, "r");
    if(fd == NULL) { 
        g_warning( "popen %s failed: %m", cmd );
        ret=1;
    }
    else if ( fgets(result, size, fd) == NULL ) {
        g_warning( "fgets %s failed: %m", cmd );
        ret=1;
    }
    if ( fd && pclose(fd) != 0 ) {
        g_warning( "pclose %s failed: %m", cmd );
        ret=1;
    }
    g_hash_free(data);
    g_free(cmd);
    return ret;
}
Exemple #5
0
int bforce_create_dirs(void)
{
	const char *p_dirname = conf_string(cf_status_directory);

	if( p_dirname )
	{
		if( access(p_dirname, F_OK) == -1 || !is_directory(p_dirname) )
		{
			if( directory_create(p_dirname, 0700) == -1 )
			{
				logerr("cannot create spool directory \"%s\"", p_dirname);
				return -1;
			}
		}
	}

	return 0;
}
Exemple #6
0
static char *session_stat_get_stsfile(s_faddr *addr, int linenum)
{
    char  buf[32];
    char *yield = NULL;
    char *p_stsdir = conf_string(cf_status_directory);

    if( p_stsdir && *p_stsdir )
    {
        if( linenum == -1 )
            sprintf(buf, "%u.%u.%u.%u.sts",
                    addr->zone, addr->net,
                    addr->node, addr->point);
        else
            sprintf(buf, "%u.%u.%u.%u-%u.sts",
                    addr->zone, addr->net,
                    addr->node, addr->point, linenum);

        yield = string_concat(p_stsdir, buf, NULL);
    }

    return yield;
}
Exemple #7
0
static int fw_exec( fw_action *act, GHashTable *conf ) {
    GHashTable *data;
    GPtrArray *env;
    gchar *cmd, **arg, **n;

    data = g_hash_dup( conf );
    //
    // Than add specifics about this particular client, if any
    if (act->p != NULL) {
	g_hash_set( data, "IP",    act->p->ip );
	g_hash_set( data, "MAC",   act->p->hw );
	g_hash_set( data, "Class", "Public" );
    }

    cmd = conf_string( conf, act->cmd );
    cmd = parse_template( cmd, data );
    g_message("Got command %s from action %s", cmd, act->cmd );
    arg = g_strsplit( cmd, " ", 0 );

    // prime the environment with our existing environment
    env = g_ptr_array_new();
    for ( n = environ; *n != NULL; n++ )
	g_ptr_array_add( env, *n );

    // Then add everything from the conf file
    g_hash_table_foreach( data, (GHFunc) fw_exec_add_env, env );

    // Add a closing NULL so execve knows where to lay off.
    g_ptr_array_add( env, NULL );

    /* We're not cleaning up memory references because 
     * hopefully the exec won't fail... */
    execve( *arg, arg, (char **)env->pdata );
    g_error( "execve %s failed: %m", cmd ); // Shouldn't happen.
    return -1;
}
Exemple #8
0
/* ------------------------------------------------------------------------- */
int out_scan(s_outbound_callback_data *callback, const s_falist *fa_list)
{
	const s_falist *alst;
	s_faddr addr = { FALSE, 0, 0, 0, 0, "" };
	s_cval_entry *cfptr;
	char *path;
	
	ASSERT(callback);
	ASSERT(callback->callback);
	ASSERT(callback->dest);

	/*
	 * 1st - try out 4D outbound
	 */
	path = conf_string(cf_outbound_directory);
	if( path && *path )
		(void)out_scan_bso(callback, fa_list, path);
	
	/*
	 *  2th - Scan domain outbounds
	 */
	for( cfptr = conf_first(cf_domain); cfptr; cfptr = conf_next(cfptr) )
	{
		memset(&addr, '\0', sizeof(s_faddr));
		for( alst = fa_list; alst; alst = alst->next )
		{
			if( cfptr->d.domain.zone == alst->addr.zone
			 || alst->addr.zone == -1 )
			{
				addr.zone = cfptr->d.domain.zone;
				out_scan_bso_dir(callback, fa_list, &addr,
						cfptr->d.domain.path, 0);
				break;
			}
		}
	}

	/*
	 *  3th - Scan AmigaDOS outbound
	 */
	path = conf_string(cf_amiga_outbound_directory);
	if( path && *path )
		(void)out_scan_aso(callback, fa_list, path);

	/*
	 * 4th - Scan personal fileboxes
	 */
	if( fa_list )
	{
		/* Scan only listed fileboxes */
		for( cfptr = conf_first(cf_filebox); cfptr; cfptr = conf_next(cfptr) )
		{
			for( alst = fa_list; alst; alst = alst->next )
			{
				if( !ftn_addrcomp(alst->addr, cfptr->d.filebox.addr) )
					out_scan_fbox_dir(callback, cfptr->d.filebox.path,
							cfptr->d.filebox.addr, cfptr->d.filebox.flavor);
			}
		}
	}
	else
	{
		/* Scan all fileboxes */
		for( cfptr = conf_first(cf_filebox); cfptr; cfptr = conf_next(cfptr) )
			out_scan_fbox_dir(callback, cfptr->d.filebox.path,
					cfptr->d.filebox.addr, cfptr->d.filebox.flavor);
	}
	
	/*
	 * 5th - Scan "long" fileboxes
	 */
	path = conf_string(cf_filebox_directory);
	if( path && *path )
		(void)out_scan_lbox(callback, fa_list, path);

	return(0);
}
static void conf(struct menu *menu)
{
	struct symbol *sym;
	struct property *prop;
	struct menu *child;

	if (!menu_is_visible(menu))
		return;

	sym = menu->sym;
	prop = menu->prompt;
	if (prop) {
		const char *prompt;

		switch (prop->type) {
		case P_MENU:
			if ((input_mode == silentoldconfig ||
			     input_mode == listnewconfig ||
			     input_mode == oldnoconfig) &&
			    rootEntry != menu) {
				check_conf(menu);
				return;
			}
			/* fall through */
		case P_COMMENT:
			prompt = menu_get_prompt(menu);
			if (prompt)
				printf("%*c\n%*c %s\n%*c\n",
					indent, '*',
					indent, '*', _(prompt),
					indent, '*');
		default:
			;
		}
	}

	if (!sym)
		goto conf_childs;

	if (sym_is_choice(sym)) {
		conf_choice(menu);
		if (sym->curr.tri != mod)
			return;
		goto conf_childs;
	}

	switch (sym->type) {
	case S_INT:
	case S_HEX:
	case S_STRING:
		conf_string(menu);
		break;
	default:
		conf_sym(menu);
		break;
	}

conf_childs:
	if (sym)
		indent += 2;
	for (child = menu->list; child; child = child->next)
		conf(child);
	if (sym)
		indent -= 2;
}
Exemple #10
0
static void conf(struct menu *menu)
{
	struct menu *submenu;
	const char *prompt = menu_get_prompt(menu);
	struct symbol *sym;
	struct menu *active_menu = NULL;
	int res;
	int s_scroll = 0;

	while (1) {
		item_reset();
		current_menu = menu;
		build_conf(menu);
		if (!child_count)
			break;
		if (menu == &rootmenu) {
			item_make("--- ");
			item_set_tag(':');
			item_make(_("    Load an Alternate Configuration File"));
			item_set_tag('L');
			item_make(_("    Save an Alternate Configuration File"));
			item_set_tag('S');
		}
		dialog_clear();
		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
				  _(menu_instructions),
				  active_menu, &s_scroll);
		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
			break;
		if (!item_activate_selected())
			continue;
		if (!item_tag())
			continue;

		submenu = item_data();
		active_menu = item_data();
		if (submenu)
			sym = submenu->sym;
		else
			sym = NULL;

		switch (res) {
		case 0:
			switch (item_tag()) {
			case 'm':
				if (single_menu_mode)
					submenu->data = (void *) (long) !submenu->data;
				else
					conf(submenu);
				break;
			case 't':
				if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
					conf_choice(submenu);
				else if (submenu->prompt->type == P_MENU)
					conf(submenu);
				break;
			case 's':
				conf_string(submenu);
				break;
			case 'L':
				conf_load();
				break;
			case 'S':
				conf_save();
				break;
			}
			break;
		case 2:
			if (sym)
				show_help(submenu);
			else
				show_helptext(_("README"), _(mconf_readme));
			break;
		case 3:
			if (item_is_tag('t')) {
				if (sym_set_tristate_value(sym, yes))
					break;
				if (sym_set_tristate_value(sym, mod))
					show_textbox(NULL, setmod_text, 6, 74);
			}
			break;
		case 4:
			if (item_is_tag('t'))
				sym_set_tristate_value(sym, no);
			break;
		case 5:
			if (item_is_tag('t'))
				sym_set_tristate_value(sym, mod);
			break;
		case 6:
			if (item_is_tag('t'))
				sym_toggle_tristate_value(sym);
			else if (item_is_tag('m'))
				conf(submenu);
			break;
		case 7:
			search_conf();
			break;
		}
	}
}
Exemple #11
0
int daemon_call(s_sysentry *syst)
{
	pid_t chld_pid;
	const char *p_lockdir = NULL;
	char abuf[BF_MAXADDRSTR+1];
	s_modemport *modemport = NULL;
	
	/*
	 * Check number of allowed clients
	 */
	if( (syst->tcpip == TRUE  && max_tcpip && max_tcpip <= tcpip_clients)
	 || (syst->tcpip == FALSE && max_modem && max_modem <= modem_clients) )
	{
		DEB((D_DAEMON, "daemon_call: too many clients!"));
		return 1;
	}
	
	/*
	 * Check whether this node is allready locked
	 */
	if( out_bsy_check(syst->node.addr) )
		return 0;
	
	/*
	 * Set state structure to make expressions works properly now
	 */
	state.caller  = TRUE;
	state.valid   = TRUE;
	state.node    = syst->node;
	state.listed  = syst->node.listed;
	state.inet    = syst->tcpip;
	
	if( syst->tcpip == FALSE )
	{
		if( (p_lockdir = conf_string(cf_uucp_lock_directory)) == NULL )
			p_lockdir = BFORCE_LOCK_DIR;
		
		if( (modemport = daemon_getfree_port(p_lockdir)) == NULL )
		{
			init_state(&state);
			return 1;
		}
	}
	
	log("call %s line %d via %s",
		ftn_addrstr(abuf, syst->node.addr), syst->line,
		syst->tcpip ? "TCP/IP" : modemport->name);
	
	chld_pid = fork();

	if( chld_pid > 0 )
	{
		(void)daemon_branch_add(syst->node.addr, chld_pid, syst->tcpip,
				syst->tcpip ? NULL : modemport->name);
		
		init_state(&state);
		
		if( syst->tcpip )
			++tcpip_clients;
		else
			++modem_clients;
		
		return 0;
	}
	else if( chld_pid < 0 )
	{
		logerr("failed fork() call");
		return 1;
	}
	
	/* Now we are in child process */
	
	exit(daemon_call_branch(syst, p_lockdir, modemport));
}
Exemple #12
0
static void conf(struct menu *menu)
{
	struct dialog_list_item *active_item = NULL;
	struct menu *submenu;
	const char *prompt = menu_get_prompt(menu);
	struct symbol *sym;
	char active_entry[40];
	int stat, type;

	unlink("lxdialog.scrltmp");
	active_entry[0] = 0;
	while (1) {
		indent = 0;
		child_count = 0;
		current_menu = menu;
		cdone(); cinit();
		build_conf(menu);
		if (!child_count)
			break;
		if (menu == &rootmenu) {
			cmake(); cprint_tag(":"); cprint_name("--- ");
			cmake(); cprint_tag("L"); cprint_name("Load an Alternate Configuration File");
			cmake(); cprint_tag("S"); cprint_name("Save Configuration to an Alternate File");
		}
		dialog_clear();
		stat = dialog_menu(prompt ? prompt : "Main Menu",
				menu_instructions, rows, cols, rows - 10,
				active_entry, item_no, items);
		if (stat < 0)
			return;

		if (stat == 1 || stat == 255)
			break;

		active_item = first_sel_item(item_no, items);
		if (!active_item)
			continue;
		active_item->selected = 0;
		strncpy(active_entry, active_item->tag, sizeof(active_entry));
		active_entry[sizeof(active_entry)-1] = 0;
		type = active_entry[0];
		if (!type)
			continue;

		sym = NULL;
		submenu = NULL;
		if (sscanf(active_entry + 1, "%p", &submenu) == 1)
			sym = submenu->sym;

		switch (stat) {
		case 0:
			switch (type) {
			case 'm':
				if (single_menu_mode)
					submenu->data = (void *) (long) !submenu->data;
				else
					conf(submenu);
				break;
			case 't':
				if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
					conf_choice(submenu);
				else if (submenu->prompt->type == P_MENU)
					conf(submenu);
				break;
			case 's':
				conf_string(submenu);
				break;
			case 'L':
				conf_load();
				break;
			case 'S':
				conf_save();
				break;
			}
			break;
		case 2:
			if (sym)
				show_help(submenu);
			else
				show_helptext("README", mconf_readme);
			break;
		case 3:
			if (type == 't') {
				if (sym_set_tristate_value(sym, yes))
					break;
				if (sym_set_tristate_value(sym, mod))
					show_textbox(NULL, setmod_text, 6, 74);
			}
			break;
		case 4:
			if (type == 't')
				sym_set_tristate_value(sym, no);
			break;
		case 5:
			if (type == 't')
				sym_set_tristate_value(sym, mod);
			break;
		case 6:
			if (type == 't')
				sym_toggle_tristate_value(sym);
			else if (type == 'm')
				conf(submenu);
			break;
		case 7:
			search_conf();
			break;
		}
	}
}
static void conf(struct menu *menu)
{
	struct menu *submenu;
	const char *prompt = menu_get_prompt(menu);
	struct symbol *sym;
	char active_entry[40];
	int stat, type, i;

	unlink("lxdialog.scrltmp");
	active_entry[0] = 0;
	while (1) {
		cprint_init();
		cprint("--title");
		cprint("%s", prompt ? prompt : "Main Menu");
		cprint("--menu");
		cprint(menu_instructions);
		cprint("%d", rows);
		cprint("%d", cols);
		cprint("%d", rows - 10);
		cprint("%s", active_entry);
		current_menu = menu;
		build_conf(menu);
		if (!child_count)
			break;
		if (menu == &rootmenu) {
			cprint(":");
			cprint("--- ");
			cprint("L");
			cprint("    Load an Alternate Configuration File");
			cprint("S");
			cprint("    Save Configuration to an Alternate File");
		}
		stat = exec_conf();
		if (stat < 0)
			continue;

		if (stat == 1 || stat == 255)
			break;

		type = input_buf[0];
		if (!type)
			continue;

		for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
			;
		if (i >= sizeof(active_entry))
			i = sizeof(active_entry) - 1;
		input_buf[i] = 0;
		strcpy(active_entry, input_buf);

		sym = NULL;
		submenu = NULL;
		if (sscanf(input_buf + 1, "%p", &submenu) == 1)
			sym = submenu->sym;

		switch (stat) {
		case 0:
			switch (type) {
			case 'm':
				if (single_menu_mode)
					submenu->data = (void *) (long) !submenu->data;
				else
					conf(submenu);
				break;
			case 't':
				if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
					conf_choice(submenu);
				else if (submenu->prompt->type == P_MENU)
					conf(submenu);
				break;
			case 's':
				conf_string(submenu);
				break;
			case 'L':
				conf_load();
				break;
			case 'S':
				conf_save();
				break;
			}
			break;
		case 2:
			if (sym)
				show_help(submenu);
			else
				show_readme();
			break;
		case 3:
			if (type == 't') {
				if (sym_set_tristate_value(sym, yes))
					break;
				if (sym_set_tristate_value(sym, mod))
					show_textbox(NULL, setmod_text, 6, 74);
			}
			break;
		case 4:
			if (type == 't')
				sym_set_tristate_value(sym, no);
			break;
		case 5:
			if (type == 't')
				sym_set_tristate_value(sym, mod);
			break;
		case 6:
			if (type == 't')
				sym_toggle_tristate_value(sym);
			else if (type == 'm')
				conf(submenu);
			break;
		}
	}
}
Exemple #14
0
/* ------------------------------------------------------------------------- */
void emsi_set_sysinfo(s_emsi *emsi, s_emsi *remote_emsi, int hrc,
                      e_protocol protocol)
{
	char buf[64];
	s_cval_entry *addr_ptr;
	s_cval_entry *hide_ptr;
	s_faddr *primary = NULL;
	
	const long options      = conf_options(cf_options);
	const long speed        = conf_number(cf_max_speed);
	const char *p_systname  = conf_string(cf_system_name);
	const char *p_location  = conf_string(cf_location);
	const char *p_sysopname = conf_string(cf_sysop_name);
	const char *p_phone     = conf_string(cf_phone);
	const char *p_flags     = conf_string(cf_flags);
	const char *p_emsioh    = conf_string(cf_emsi_OH_time);
	const char *p_emsifr    = conf_string(cf_emsi_FR_time);

	/* free previously allocated memory */
//	if( emsi->addrs ) free(emsi->addrs);
		
	memset(emsi, '\0', sizeof(s_emsi));
	
	/* ----------------------------------------------------------------- */
	/* Data for {EMSI} field                                             */
	/* ----------------------------------------------------------------- */
	emsi->have_emsi = 1;
	
	/* Set best primary address */
	primary = session_get_bestaka(state.node.addr);
		
	/* Add primary address */
	if( primary )
		session_addrs_add(&state.localaddrs, &state.n_localaddr, *primary);

	/* Add other AKAs */
	for( addr_ptr = conf_first(cf_address); addr_ptr;
	     addr_ptr = conf_next(addr_ptr) )
	{
		for( hide_ptr = conf_first(cf_hide_our_aka); hide_ptr;
		     hide_ptr = conf_next(hide_ptr) )
		{
			if( !ftn_addrcomp(hide_ptr->d.falist.addr, addr_ptr->d.falist.addr) )
				break;
		}
		
		if( !hide_ptr && primary != &addr_ptr->d.falist.addr )
			session_addrs_add(&state.localaddrs, &state.n_localaddr,
					addr_ptr->d.falist.addr);
	}
	
	if( state.localaddrs == 0 )
		log("warning: no addresses will be presented to remote");

	/* session password */
	if( state.caller )
	{
		session_get_password(state.node.addr, emsi->passwd, sizeof(emsi->passwd));
	}
	else if( hrc == HRC_OK )
	{
		/* Satisfy remote with their password */
		const char *p = state.handshake->remote_password(state.handshake);
		if( p )
			strnxcpy(emsi->passwd, p, sizeof(emsi->passwd));
	}
	
	/* link codes */
	if( state.caller ) /* CALLER */
	{
		if( (options & OPTIONS_NO_RH1)   != OPTIONS_NO_RH1
		 && (options & OPTIONS_NO_HYDRA) != OPTIONS_NO_HYDRA)
			{ emsi->linkcodes.RH1 = 1; }
		
		if( (options & OPTIONS_NO_PICKUP) == OPTIONS_NO_PICKUP )
			{ emsi->linkcodes.NPU = 1; }
		else
			{ emsi->linkcodes.PUA = 1; }
			
		if( (options & OPTIONS_MAILONLY) == OPTIONS_MAILONLY )
			{ emsi->linkcodes.HXT = 1; }
		
		if( (options & OPTIONS_NO_EMSI_II) != OPTIONS_NO_EMSI_II )
		{
			/* EMSI-II */
			if( (options & OPTIONS_HOLDREQ) != OPTIONS_HOLDREQ )
				{ emsi->linkcodes.RMA = 1; }
		}
		else
		{
			/* EMSI-I */
			emsi->linkcodes.N81 = 1;
		}
	}
	else if( (remote_emsi->compcodes.EII == 1)
	      && (options & OPTIONS_NO_EMSI_II) != OPTIONS_NO_EMSI_II )
	{
		/* ANSWER/EMSI-II */
		if( remote_emsi->linkcodes.RH1 && protocol == PROT_HYDRA )
			{ emsi->linkcodes.RH1 = 1; }
		
		if( state.reqstat == REQS_ALLOW && remote_emsi->linkcodes.RMA )
			{ emsi->linkcodes.RMA = 1; }
		else if( state.reqstat == REQS_NOTALLOW )
			{ emsi->linkcodes.HRQ = 1; }
		
		if( (options & OPTIONS_MAILONLY) == OPTIONS_MAILONLY )
			{ emsi->linkcodes.HXT = 1; }
	}
	else
	{
		/* ANSWER/EMSI-I */
		if( remote_emsi->linkcodes.RH1 && protocol == PROT_HYDRA )
			{ emsi->linkcodes.RH1 = 1; }
		
		if( state.reqstat == REQS_NOTALLOW )
			{ emsi->linkcodes.HRQ = 1; }
		
		if( (options & OPTIONS_MAILONLY) == OPTIONS_MAILONLY )
			{ emsi->linkcodes.HXT = 1; }
	}
	
	/* compatibility codes */
	if( state.caller )
	{
		if( (options & OPTIONS_NO_EMSI_II) != OPTIONS_NO_EMSI_II )
		{
			/* EMSI-II */
			emsi->compcodes.EII = 1;
		}
		else
		{
			/* EMSI-I */
			emsi->compcodes.ARC = 1;
			emsi->compcodes.XMA = 1;
		}
		if( (options & OPTIONS_NO_ZMODEM) != OPTIONS_NO_ZMODEM )
			{ emsi->compcodes.ZMO = 1; }
		if( (options & OPTIONS_NO_ZEDZAP) != OPTIONS_NO_ZEDZAP )
			{ emsi->compcodes.ZAP = 1; }
		if( (options & OPTIONS_NO_DIRZAP) != OPTIONS_NO_DIRZAP )
			{ emsi->compcodes.DZA = 1; }
		if( (options & OPTIONS_NO_JANUS) != OPTIONS_NO_JANUS )
			{ emsi->compcodes.JAN = 1; }
		if( (options & OPTIONS_NO_HYDRA) != OPTIONS_NO_HYDRA )
			{ emsi->compcodes.HYD = 1; }
	}
	else
	{
		if( (remote_emsi->compcodes.EII == 1)
		 && (options & OPTIONS_NO_EMSI_II) != OPTIONS_NO_EMSI_II )
		{
			/* EMSI-II */
			emsi->compcodes.EII = 1;
		}
		else
		{
			/* EMSI-I */
			emsi->compcodes.ARC = 1;
			emsi->compcodes.XMA = 1;
		}
		
		if( state.reqstat == REQS_DISABLED )
			{ emsi->compcodes.NRQ = 1; }
			
		switch(protocol) {
		case PROT_NOPROT: emsi->compcodes.NCP = 1; break;
		case PROT_ZMODEM: emsi->compcodes.ZMO = 1; break;
		case PROT_ZEDZAP: emsi->compcodes.ZAP = 1; break;
		case PROT_DIRZAP: emsi->compcodes.DZA = 1; break;
		case PROT_JANUS:  emsi->compcodes.JAN = 1; break;
		case PROT_HYDRA:  emsi->compcodes.HYD = 1; break;
		default:          ASSERT(FALSE);           break;
		}
	}
	
	strnxcpy(emsi->m_pid,  BF_EMSI_NUM,  sizeof(emsi->m_pid));
	strnxcpy(emsi->m_name, BF_EMSI_NAME, sizeof(emsi->m_name));
	
	if( hrc != HRC_BAD_PASSWD )
	{
		strnxcpy(emsi->m_ver,  BF_EMSI_VER,  sizeof(emsi->m_ver));
		strnxcpy(emsi->m_reg,  BF_EMSI_REG,  sizeof(emsi->m_reg));
	}
	else
	{
		strnxcpy(emsi->m_ver, "?", sizeof(emsi->m_ver));
		strnxcpy(emsi->m_reg, "?", sizeof(emsi->m_reg));
	}

	/* ----------------------------------------------------------------- */
	/* Data for {IDENT} field                                            */
	/* ----------------------------------------------------------------- */
	emsi->have_ident = 1;
	emsi->speed = (speed > 0) ? speed : 300;
	
	strnxcpy(emsi->sysop, p_sysopname ? p_sysopname : "Unknown", sizeof(emsi->sysop));
	strnxcpy(emsi->phone, p_phone     ? p_phone     : "Unknown", sizeof(emsi->phone));
	
	switch(hrc) {
	case HRC_BAD_PASSWD:
		strnxcpy(emsi->sname,    "Bad password", sizeof(emsi->sname));
		strnxcpy(emsi->location, "Check security table", sizeof(emsi->location));
		strnxcpy(emsi->flags,    "Password Error", sizeof(emsi->flags));
		break;
	case HRC_LOW_SPEED:
		strnxcpy(emsi->sname,    "Connect speed too low", sizeof(emsi->sname));
		strnxcpy(emsi->location, "Buy new modem and call again", sizeof(emsi->location));
		sprintf(buf, "Minimal speed: %ldbps", (long)state.minspeed);
		strnxcpy(emsi->flags,    buf, sizeof(emsi->flags));
		break;
	case HRC_BUSY:
		strnxcpy(emsi->sname,    "All AKAs are busy", sizeof(emsi->sname));
		strnxcpy(emsi->location, "Possible another session is running", sizeof(emsi->location));
		strnxcpy(emsi->flags,    "Please, call later", sizeof(emsi->flags));
		break;
	default:
		strnxcpy(emsi->sname,    p_systname  ? p_systname  : "Unknown", sizeof(emsi->sname));
		strnxcpy(emsi->location, p_location  ? p_location  : "Unknown", sizeof(emsi->location));
		strnxcpy(emsi->flags,    p_flags     ? p_flags     : "MO",      sizeof(emsi->flags));
	}
	
	/* ----------------------------------------------------------------- */
	/* Data for {OHFR} field                                             */
	/* ----------------------------------------------------------------- */
	if( p_emsioh && *p_emsioh && hrc != HRC_BAD_PASSWD )
	{
		emsi->have_ohfr = 1;
		strnxcpy(emsi->oh_time, p_emsioh, sizeof(emsi->oh_time));
		if( p_emsifr && *p_emsifr )
			strnxcpy(emsi->fr_time, p_emsifr, sizeof(emsi->fr_time));
	}
	
	/* ----------------------------------------------------------------- */
	/* Data for {TRX#} field                                             */
	/* ----------------------------------------------------------------- */
	emsi->have_trx = 1;
	emsi->time = localtogmt(time(NULL));
	
	/* ----------------------------------------------------------------- */
	/* Data for {TRAF} and {MOH#} fields                                 */
	/* ----------------------------------------------------------------- */
	if( state.caller == 0 && hrc != HRC_BAD_PASSWD )
	{
		emsi->have_traf = 1;
		emsi->netmail_size = state.traff_send.netmail_size;
		emsi->arcmail_size = state.traff_send.arcmail_size;
		if ( state.traff_send.files_size )
		{
			emsi->have_moh = 1;
			emsi->files_size = state.traff_send.files_size;
		}	
	}
}
/*****************************************************************************
 * Set our local system information 
 *
 * Arguments:
 * 	binkp       structure where to store system information
 * 	remote_addr remote main address (for setting best AKA)
 * 	caller      are we calling system?
 *
 * Return value:
 * 	None
 */
void binkp_set_sysinfo(s_binkp_sysinfo *binkp, s_faddr *remote_addr, bool caller)
{
	s_cval_entry *addr_ptr;
	s_cval_entry *hide_ptr;
	s_faddr *primary = NULL;
	
	const char *p_systname  = conf_string(cf_system_name);
	const char *p_location  = conf_string(cf_location);
	const char *p_sysop     = conf_string(cf_sysop_name);
	const char *p_phone     = conf_string(cf_phone);
	const char *p_flags     = conf_string(cf_flags);
	
	/* free previously allocated memory */
//	if( binkp->addrs )
//		free(binkp->addrs);

	memset(binkp, '\0', sizeof(s_binkp_sysinfo));
	
	/* Set best primary address */
	if(remote_addr) {
		primary = session_get_bestaka(*remote_addr);
		
		/* Add primary address */
		if (primary) session_addrs_add(&state.localaddrs, &state.n_localaddr, *primary);
	}

	/* Add other AKAs */
	for( addr_ptr = conf_first(cf_address); addr_ptr; addr_ptr = conf_next(addr_ptr) ) {
		for( hide_ptr = conf_first(cf_hide_our_aka); hide_ptr;
		     hide_ptr = conf_next(hide_ptr) )
		{
			if( !ftn_addrcomp(hide_ptr->d.falist.addr, addr_ptr->d.falist.addr) )
				break;
		}
		
		if( !hide_ptr && primary != &addr_ptr->d.falist.addr )
			session_addrs_add(&state.localaddrs, &state.n_localaddr,
					addr_ptr->d.falist.addr);
	}
	
	if (state.n_localaddr == 0) log("warning: no addresses will be presented to remote");

	/* session password */
	if( caller )
		session_get_password(state.node.addr, binkp->passwd, sizeof(binkp->passwd));
	
	binkp->majorver = BINKP_MAJOR;
	binkp->minorver = BINKP_MINOR;
	
	strnxcpy(binkp->progname, BF_NAME"/"BF_VERSION"/"BF_OS, sizeof(binkp->progname));
	strnxcpy(binkp->protname, BINKP_NAME, sizeof(binkp->protname));
	
	strnxcpy(binkp->sysop,    p_sysop    ? p_sysop    : "Unknown", sizeof(binkp->sysop));
	strnxcpy(binkp->systname, p_systname ? p_systname : "Unknown", sizeof(binkp->systname));
	strnxcpy(binkp->location, p_location ? p_location : "Unknown", sizeof(binkp->location));
	strnxcpy(binkp->phone,    p_phone    ? p_phone    : "Unknown", sizeof(binkp->phone));
	strnxcpy(binkp->flags,    p_flags    ? p_flags    : "BINKP",   sizeof(binkp->flags));

	time_string_format(binkp->timestr, sizeof(binkp->timestr), "%Y/%m/%d %H:%M:%S", 0);
	
	/* Set session challenge string */
	if( !caller )
	{
		long rnd = (long)random();
		int  pid = ((int)getpid()) ^ ((int)random());
		long utm = (long)time(0);

		binkp->options |= BINKP_OPT_MD5;
		binkp->challenge[0] = (unsigned char)(rnd      );
		binkp->challenge[1] = (unsigned char)(rnd >> 8 );
		binkp->challenge[2] = (unsigned char)(rnd >> 16);
		binkp->challenge[3] = (unsigned char)(rnd >> 24);
		binkp->challenge[4] = (unsigned char)(pid      );
		binkp->challenge[5] = (unsigned char)(pid >> 8 );
		binkp->challenge[6] = (unsigned char)(utm      );
		binkp->challenge[7] = (unsigned char)(utm >> 8 );
		binkp->challenge[8] = (unsigned char)(utm >> 16);
		binkp->challenge[9] = (unsigned char)(utm >> 24);

		binkp->challenge_length = 10;
	}