Beispiel #1
0
int main(int argc, char **argv)
{
        int rtn,i,pid;
        char cha,name[40];
        rtn = shared_memory_attach();
        mk_daemon(argc,argv);
        pid = getpid();
        T->pid[TEMP08_PID].pids = pid;
        rtn = find_local();
	LOC = rtn;
	if (!Daemon) printf ("Local is %d\n",LOC);
	rtn = open_port(*argv);
	Fd = rtn;
	if (!Daemon) printf("Fd = %d\n",Fd);
	strcpy(name,"oww_temp_1");
	rtn = find_device(name);
	Oww_temp_1_dev = rtn;
	strcpy(name,"oww_temp_2");
	rtn = find_device(name);
	Oww_temp_2_dev = rtn;
	if (!Daemon) printf("Oww_temp_1_dev = %d\n",Oww_temp_1_dev);
	if (Fd > 0)
	{
		initialize();
		read_parse_data();
	}
	
	exit(0);

}
int main(int argc, char **argv)
{
        int rtn,i,pid;
        char cha,str[30];
	//rtn = log_progress("1");
	system("cd /Users/laurenceschenk/mini-src/mySrc/");
        rtn = shared_memory_attach();
        rtn = find_local();
	rtn = mk_daemon(argc,argv);	//must have this to write PID file
        rtn = shared_memory_attach();
        Mask = COLDIPOZZO_SEND | ROCCAMORICE_SEND | STARLIGHT_SEND | WEEHAWKEN_SEND ;
	rtn = find_devices();
	//rtn = log_progress("Main program starting....\n");
	system("cd /Users/laurenceschenk/mini-src/mySrc/coldipozzo");
	rtn = getuid();
	sprintf(str,"uid = %d",rtn);
	//rtn = log_progress(str);
	rtn = geteuid();
	sprintf(str,"euid = %d",rtn);
	//rtn = log_progress(str);
        while (1)
        {
		//rtn = log_progress("5");
                rtn =main_loop();
		//rtn = log_progress("6");
        }
        exit(0);
}
Beispiel #3
0
SCOPE2 int
alfind(int adr, int len, int up)
{
    int canstr;
    int i, found;
    int voc, last_voc;

    canstr = alcanonical(adr, len, up);

#ifdef INCLUDE_LOCALS
    if ((found = find_local(canstr, len, up)) != 0) {
        return found;
    }
#endif
    last_voc = 0;
    for (i = 0; i < NVOCS; i++) {
//        voc = V(CONTEXT) + i;
        voc = V(CONTEXT + i);
        if (voc == 0)
            continue;
        if ( (voc != last_voc) && ((found = search_wid(canstr, len, voc, up)) != 0) )
            return found;
        last_voc = voc;
    }
    return 0;
}
Beispiel #4
0
int main(void)
{
    int     i;

    find_local();
    for (i = 0; i < num_local; i++)
	printf("%s\n", inet_ntoa(addrs[i]));
}
	void	as_environment::set_variable_raw (
	    const tu_string &varname,
	    const as_value &val,
	    const array<with_stack_entry>& with_stack )
	// No path rigamarole.
	{
		// Check the with-stack.
		for ( int i = with_stack.size() - 1; i >= 0; i-- )
		{
			as_object	*obj = with_stack[i].m_object.get_ptr();
			as_value unused;

			if ( obj && obj->get_member ( varname, &unused ) )
			{
				// This object has the member; so set it here.
				obj->set_member ( varname, val );
				return;
			}
		}

		// Check locals.
		int	local_index = find_local ( varname, true );

		if ( local_index >= 0 )
		{
			// Set local var.
			m_local_frames[local_index].m_value = val;
			return;
		}

		if ( m_target != NULL )
		{
			m_target->set_member ( varname, val );
		}

		else
		{
			// assume local var
			// This case happens for example so
			// class myclass
			// {
			//		function myfunc()
			//		{
			//			for (i=0;...)		should be for (var i=0; ...)
			//			{
			//			}
			//		}
			//	}
			add_local ( varname, val );
			IF_VERBOSE_ACTION ( log_error ( "can't set_variable_raw %s=%s, target is NULL, it's assumed as local\n",
			                                varname.c_str(), val.to_string() ) );
			IF_VERBOSE_ACTION ( log_error ( "probably you forgot to declare variable '%s'\n", varname.c_str() ) );
		}
	}
Beispiel #6
0
/*
 *   Get the value of a local by name 
 */
int CVmObjFrameDesc::get_local_val(VMG_ vm_val_t *result, const vm_val_t *name)
{
    /* look up the symbol by name */
    CVmDbgFrameSymPtr sym;
    if (!find_local(vmg_ name, &sym))
        return FALSE;

    /* retrieve the value based on the descriptor */
    get_frame_ref(vmg0_)->get_local_val(vmg_ result, &sym);

    /* found it */
    return TRUE;
}
Beispiel #7
0
 main(int argc, char **argv)
{
        int rtn,i,pid,err;
        char cha,pid_query[40],tmp[10];
        rtn = shared_memory_attach();
        pid = getpid();
        rtn = find_local();
        rtn = mk_daemon(argc,argv);
        rtn = shared_memory_attach();
        printf("Program_name: %s\n",Program_name);
	Occupy_dev = find_device("Occupy");
	Lib_thermo_sp_dev = find_device("Lib_thermo_sp");
	Kit_thermo_sp_dev = find_device("Kit_thermo_sp");
	thermo_failure_dev = find_device("thermo_failure");
	thermo_failure_notify = 0;
	
	read_file();
	if (!Daemon) printf ("Finished reading data file...\n");

	//start two threads, one listening for requests/commands the other running the thermostat
	//connect_with_web_server and run_thermostat

	err = pthread_create(&(tid[0]), NULL, &connect_with_web_server, NULL);
        if (err != 0)
            printf("\ncan't create thread :[%s]", strerror(err));
        else
            printf("\n Thread connect_with_web_server created successfully\n");
	err = pthread_create(&(tid[1]), NULL, &run_thermostat, NULL);
        if (err != 0)
            printf("\ncan't create thread :[%s]", strerror(err));
        else
            printf("\n Thread run_thermostat created successfully\n");
	Pid = getpid();
	strcpy(pid_query,"ls /proc/");
	sprintf(tmp,"%d",Pid);
	strcat(pid_query,tmp);
	strcat(pid_query,"/task");
	if (!Daemon) printf("pid_query = %s\n",pid_query);
	//if (!Daemon) printf("main: base pid = %d\n",Pid);
	while (1)
	{
		sleep(60);
		if (!Daemon)
		{
			printf("\n\nChecking threads....\n");
			system(pid_query);
			printf ("\n\n\n\n");
		}
		
	}
}
Beispiel #8
0
/*
 *   find a local variable in our frame by name, given a VM string value 
 */
int CVmObjFrameDesc::find_local(VMG_ const vm_val_t *nval,
                               CVmDbgFrameSymPtr *symp)
{
    /* make sure the name is a string */
    const char *name = nval->get_as_string(vmg0_);
    if (name == 0)
        err_throw(VMERR_BAD_TYPE_BIF);

    /* parse the length */
    size_t namelen = vmb_get_len(name);
    name += VMB_LEN;

    /* look up the symbol */
    return find_local(vmg_ name, namelen, symp);
}
	void	as_environment::declare_local ( const tu_string &varname )
	// Create the specified local var if it doesn't exist already.
	{
		// Is it in the current frame already?
		int	index = find_local ( varname, false );

		if ( index < 0 )
		{
			// Not in frame; create a new local var.
			add_local ( varname, as_value() );
		}

		else
		{
			// In frame already; don't mess with it.
		}
	}
Beispiel #10
0
 main(int argc, char **argv)
{
        int rtn,i,pid;
        char cha;
        rtn = shared_memory_attach();
        pid = getpid();
        //T->pid[LOOK_PID].pids = pid;
        rtn = find_local();
        rtn = mk_daemon(argc,argv);
        rtn = shared_memory_attach();
        printf("Program_name: %s\n",Program_name);
        initscr();
        while (1)
        {
                main_menu();
        }
}
	void	as_environment::set_local ( const tu_string &varname, const as_value &val )
	// Set/initialize the value of the local variable.
	{
		// Is it in the current frame already?
		int	index = find_local ( varname, false );

		if ( index < 0 )
		{
			// Not in frame; create a new local var.
			add_local ( varname, val );
		}

		else
		{
			// In frame already; modify existing var.
			m_local_frames[index].m_value = val;
		}
	}
Beispiel #12
0
/**
 * from_local - determine whether request comes from the local system
 * @sap: pointer to socket address to check
 *
 * With virtual hosting, each hardware network interface can have
 * multiple network addresses. On such machines the number of machine
 * addresses can be surprisingly large.
 *
 * Returns TRUE if the sockaddr contains an address of one of the local
 * network interfaces.  Otherwise FALSE is returned.
 */
int
from_local(const struct sockaddr *sap)
{
    const struct sockaddr_in *addr = (const struct sockaddr_in *)sap;
    int     i;

    if (sap->sa_family != AF_INET)
	return (FALSE);

    if (addrs == 0 && find_local() == 0)
	xlog(L_ERROR, "Cannot find any active local network interfaces");

    for (i = 0; i < num_local; i++) {
	if (memcmp((char *) &(addr->sin_addr), (char *) &(addrs[i]),
		   sizeof(struct in_addr)) == 0)
	    return (TRUE);
    }
    return (FALSE);
}
Beispiel #13
0
cvar_node* cvar_collect::find( const char* str ) const
{
	// Read out the next subnode name
	char name[64];
	const char* next = cvar_parse_name( str, name );

	// Find the local cvar node referred to
	cvar_node* it = find_local( name );

	if ( next && it )
	{
		// We need to go deeper, so this must be a subtree
		if ( it->type()!=CVAR_SUBTREE )
			return nullptr;

		// Continue looking
		it = static_cast<cvar_tree*>( it )->find( next );
	}

	return it;
}
Beispiel #14
0
bool cvar_collect::names( const char* partial, cvar_completion_t& list, cvar_string_t& prefix ) const
{
	// Read the next name out of partial
	char name[200];
	if ( const char* next = cvar_parse_name( partial, name ) )
	{
		// Find the node referring to
		const cvar_node* it = find_local( name );
		if ( !it || it->type()!=CVAR_SUBTREE )
			return false;

		// We have to go deeper, append the prefix and recurse.
		prefix.append( partial, next );
		return static_cast<const cvar_tree*>(it)->names( next, list, prefix );
	}

	// We want all the cvars starting with partial.
	for ( const cvar_node* it = _list; it; it = it->next() )
	{
		cvar_partial( it->name(), partial, list );
	}
	return true;
}
	as_value	as_environment::get_variable_raw (
	    const tu_string &varname,
	    const array<with_stack_entry>& with_stack ) const
	// varname must be a plain variable name; no path parsing.
	{
		as_value	val;

		// First check the with-stack.
		for ( int i = with_stack.size() - 1; i >= 0; i-- )
		{
			as_object	*obj = with_stack[i].m_object.get_ptr();

			if ( obj && obj->get_member ( varname, &val ) )
			{
				// Found the var in this context.
				return val;
			}
		}

		// Then check locals.
		int	local_index = find_local ( varname, true );

		if ( local_index >= 0 )
		{
			return m_local_frames[local_index].m_value;
		}

		// Check movie members.
		if ( m_target != NULL && m_target->get_member ( varname, &val ) )
		{
			return val;
		}

		// Check this, _global, _root
		as_standard_member	varname_id = get_standard_member ( varname );

		switch ( varname_id )
		{
			default:
				break;

			case M_GLOBAL:
				val.set_as_object ( get_player()->get_global() );
				return val;

			case MTHIS:
				val.set_as_object ( get_target() );
				return val;

			case M_ROOT:
			case M_LEVEL0:
				val.set_as_object ( get_root()->get_root_movie() );
				return val;
		}

		// check _global.member
		if ( get_player()->get_global()->get_member ( varname, &val ) )
		{
			return val;
		}

		// Fallback.
		IF_VERBOSE_ACTION ( log_msg ( "get_variable_raw(\"%s\") failed, returning UNDEFINED.\n", varname.c_str() ) );
		return val;
	}
Beispiel #16
0
int main(int argc, char **argv)
{
        int rtn,i,pid,state;
	int last;
	int hr,min,sec;
	time_t tt, tloc;
        char cha;
        rtn = shared_memory_attach();
        pid = getpid();
	rtn = mk_daemon(argc,argv);
        rtn = shared_memory_attach();
        rtn = find_local();
	if (LOC != COLDIPOZZO)
	{
		printf("Incorrect LOC: this only maked sense in Coldipozzo. Exiting.\n");
		exit(2);
	}
	T->pid[GATE_PID].pids = getpid();
	//Loops = 0;
	Dly_ms = 500000;	//this is the max....change sec if greater delay wanted
	Dly_s = 0;
	Gate_pulsed_dev = find_device("gate_pulsed");
	if (Gate_ind_dev == -1)
	{
		printf("Unable to find gate_ind....exiting\n");
		exit(1);
	}
	Gate_ind_dev = find_device("gate_ind");
	if (Gate_ind_dev == -1)
	{
		printf("Unable to find gate_ind....exiting\n");
		exit(1);
	}
	Gate_flag_dev = find_device("gate_flag");
	if (Gate_flag_dev == -1)
	{
		printf("Unable to find gate_flag....exiting\n");
		exit(1);
	}
	Entrance_light_dev = find_device("Entrance_light");
	Garage_light_dev = find_device("garage_light");
	Gate_light_dev = find_device("gate_light");
	tt = time(&tloc);
	T->device[Gate_ind_dev].change_time = tt;
        Last_pulsed_state = T->device[Gate_pulsed_dev].state;
        //loop: check for any requests in gate_flag_dev, then check gate_ind to see if anything is happening	
	while (1)
	{
		tt = time(&tloc);
		rtn = set_delay();	//initially set a .5 sec
		//now calculate the time between on/off states
		//if (!Daemon) printf("Return from set_delay = %d\n",rtn);
		//Loops++;	//this is out timer/counter as we need time more accurately than 1 second
		if (Lights_turned_on) turn_off_lights();
		if ((T->device[Gate_ind_dev].state & ON) == ON)
		{
			state = 1;
		}
		if ((T->device[Gate_ind_dev].state & OFF) == OFF)
		{
			state = 0;
		}
		if (state != Last_state)	//there is a change in state...go fast to see if we are opening or closing
		{
			tt = time(&tloc);
                        No_change = 0;
			T->device[Gate_ind_dev].change_time = tt;
			Last_state = state;
			Change_time = (Loops * Dly_s) + (Loops * Dly_ms / 100000);
			if (Change_time < 7)
			{
				if (!Daemon) printf("Change_time < 7 so gate is actively closing\n");
				Gate_state = GATE_CLOSING;
                                T->device[Gate_flag_dev].state = 0;
                                T->device[Gate_flag_dev].state = GATE_CLOSING;
			}
			if (Change_time > 9)
			{
				if (!Daemon) printf("gate is actively opening as Change_time > 9\n");
				Gate_state = GATE_OPENING;
                                T->device[Gate_flag_dev].state = 0;
                                T->device[Gate_flag_dev].state = GATE_OPENING;
				check_lights();
			}
			if (!Daemon) printf("Change of state state = %d Change_time = %d\n",state,Change_time);
			Dly_ms = 50000;	//10 x / second
			Dly_s = 0;
			Loops = 0;
		} else {	//no change in state
			Loops++;
			if (Loops > 50)	//5 seconds
			{
				if (!Daemon) printf ("no change in 5 seconds...dropping back to 1/sec polling\n");
				Dly_ms = 0;
				Dly_s = 1;
				Loops=0;
                                No_change = 1;
			}
		}
		
		//this is the status
                if (No_change > 0)
                {
		        T->device[Gate_ind_dev].change_time = tt ;	//this will not work since the finnest time slice is one second
			if (!Daemon) printf("Final state: Gate is  ");
			if ((T->device[Gate_ind_dev].state & ON ) != 0)
			{
				if (!Daemon) printf("OPEN\t");
                                T->device[Gate_flag_dev].state = 0;
                                T->device[Gate_flag_dev].state = GATE_OPENED;
			}
			if ((T->device[Gate_ind_dev].state & OFF ) != 0)
			{
				if (!Daemon) printf("CLOSED\t");
                                T->device[Gate_flag_dev].state = 0;
                                T->device[Gate_flag_dev].state = GATE_CLOSED;
			}
			if ((T->device[Gate_ind_dev].state ) == 0)
			{
				if (!Daemon) printf("Undefined...\t");
                                T->device[Gate_flag_dev].state = 0;
			}
			if (!Daemon) printf("Gate_state = 0x%x\t",Gate_state);
			if (!Daemon) 
                        {
			        hr = last / 60 /60;
			        min = (last / 60) % 60 ;
			        sec = last % 60;
                                printf("%s changed %d:%d:%d ago\tLoops=%d\n",T->device[Gate_ind_dev].name,hr,min,sec,Loops);
                        }
		}
	}
}
Beispiel #17
0
main(int argc, char **argv)
{
        int rtn,i,pid,rest_of_day,min_of_day,cpid,ppid,loop,place;
	int min,hr,total_min,total_time,hour;
       	time_t tt,tloc;
	char name[20],splace[50], *loc,line[20];
	FILE *in;
	rtn = shared_memory_attach();
	rtn = mk_daemon(argc,argv);
	find_local();
	system("cd /Users/laurenceschenk/mini-src/mySrc/coldipozzo");
	if (T->Loc == STARLIGHT)
	{
		if (!Daemon) printf("Looking up sun_times for Binghamton\n"); 
		in = popen ("./sun_rise_set_Starlight.py","r");
		if (in != NULL)
		{
			fgets( line, sizeof line, in);
			hour = ((line[0] - '0') * 10) + (line[1] - '0');
			min = ((line[2] - '0') * 10) + (line[3] - '0');
			total_time = (60 * hour) + min;
			T->light.dawn = total_time;
			fgets( line, sizeof line, in);
			hour = ((line[0] - '0') * 10) + (line[1] - '0');
			min = ((line[2] - '0') * 10) + (line[3] - '0');
			total_time = (60 * hour) + min;
			T->light.dusk = total_time;
			if (!Daemon) printf ("Updated dusk and dawn are T->light.dawn= %d (%d:%d) and T->light.dusk= %d (%d:%d) \n",T->light.dawn,T->light.dawn/60,T->light.dawn%60,T->light.dusk,T->light.dusk/60,T->light.dusk%60);	
			pclose(in);
		} else {
			T->light.dawn = 60 * 6;		//6 AM
			T->light.dusk = 60 * 18;	//6 PM
		}
	}
	if (T->Loc  == COLDIPOZZO)
	{
		if (!Daemon) printf("Looking up sun_times for Coldipozzo\n");
		in = popen("./sun_rise_set_Coldipozzo.py","r");
		if (in != NULL)
		{
			fgets( line, sizeof line, in);
			hour = ((line[0] - '0') * 10) + (line[1] - '0');
			min = ((line[2] - '0') * 10) + (line[3] - '0');
			total_time = (60 * hour) + min;
			T->light.dawn = total_time;
			fgets( line, sizeof line, in);
			hour = ((line[0] - '0') * 10) + (line[1] - '0');
			min = ((line[2] - '0') * 10) + (line[3] - '0');
			total_time = (60 * hour) + min;
			T->light.dusk = total_time;

			if (!Daemon) printf ("Updated dusk and dawn are T->light.dawn= %d (%d:%d) and T->light.dusk= %d (%d:%d) \n",T->light.dawn,T->light.dawn/60,T->light.dawn%60,T->light.dusk,T->light.dusk/60,T->light.dusk%60);	
			pclose(in);
		} else {
			T->light.dawn = 60 * 6;
			T->light.dusk = 60 * 18;
		}
	}
	if (T->Loc  == WEEHAWKEN)
	{
		if (!Daemon) printf("Looking up sun_times for Weehawken\n");
		in = popen ("./sun_rise_set_Weehawken.py","r");
		if (in != NULL)
		{
			//format receiver is 0610lf2010lf
			//this must be split by hour and minute then total minutes calculated
			fgets( line, sizeof line, in);
			hour = ((line[0] - '0') * 10) + (line[1] - '0');
			min = ((line[2] - '0') * 10) + (line[3] - '0');
			total_time = (60 * hour) + min;
			T->light.dawn = total_time;
			fgets( line, sizeof line, in);
			hour = ((line[0] - '0') * 10) + (line[1] - '0');
			min = ((line[2] - '0') * 10) + (line[3] - '0');
			total_time = (60 * hour) + min;
			T->light.dusk = total_time;
			
			if (!Daemon) printf ("Updated dusk and dawn are T->light.dawn= %d (%d:%d) and T->light.dusk= %d (%d:%d) \n",T->light.dawn,T->light.dawn/60,T->light.dawn%60,T->light.dusk,T->light.dusk/60,T->light.dusk%60);	
			fclose(in);
		} else {
			T->light.dawn = 60 * 6;
			T->light.dusk = 60 * 18;
		}
	}
	//calculate_type_4_times();
	if (T->Loc  == ROCCAMORICE)
	{
		if (!Daemon) printf("Looking up sun_times for Roccamorice\n");
		in = popen ("./sun_rise_set_Rocamorice.py","r");
		if (in != NULL)
		{
			//format receiver is 0610lf2010lf
			//this must be split by hour and minute then total minutes calculated
			fgets( line, sizeof line, in);
			hour = ((line[0] - '0') * 10) + (line[1] - '0');
			min = ((line[2] - '0') * 10) + (line[3] - '0');
			total_time = (60 * hour) + min;
			T->light.dawn = total_time;
			fgets( line, sizeof line, in);
			hour = ((line[0] - '0') * 10) + (line[1] - '0');
			min = ((line[2] - '0') * 10) + (line[3] - '0');
			total_time = (60 * hour) + min;
			T->light.dusk = total_time;
			
			if (!Daemon) printf ("Updated dusk and dawn are T->light.dawn= %d (%d:%d) and T->light.dusk= %d (%d:%d) \n",T->light.dawn,T->light.dawn/60,T->light.dawn%60,T->light.dusk,T->light.dusk/60,T->light.dusk%60);	
			fclose(in);
		} else {
			T->light.dawn = 60 * 6;
			T->light.dusk = 60 * 18;
		}
	}
	//calculate_type_4_times();
	exit(0);
}
Beispiel #18
0
const char *mail_addr_find_opt(MAPS *path, const char *address, char **extp,
			               int in_form, int query_form,
			               int out_form, int strategy)
{
    const char *myname = "mail_addr_find";
    VSTRING *ext_addr_buf = 0;
    VSTRING *int_addr_buf = 0;
    const char *int_addr;
    static VSTRING *int_result = 0;
    const char *result;
    char   *ratsign = 0;
    char   *int_full_key;
    char   *int_bare_key;
    char   *saved_ext;
    int     rc = 0;

    /*
     * Optionally convert the address from external form.
     */
    if (in_form == MA_FORM_EXTERNAL) {
	int_addr_buf = vstring_alloc(100);
	unquote_822_local(int_addr_buf, address);
	int_addr = STR(int_addr_buf);
    } else {
	int_addr = address;
    }
    if (query_form == MA_FORM_EXTERNAL_FIRST
	|| query_form == MA_FORM_EXTERNAL)
	ext_addr_buf = vstring_alloc(100);

    /*
     * Initialize.
     */
    int_full_key = mystrdup(int_addr);
    if (*var_rcpt_delim == 0 || (strategy & MA_FIND_NOEXT) == 0) {
	int_bare_key = saved_ext = 0;
    } else {
	/* XXX This could be done after user+foo@domain fails. */
	int_bare_key =
	    strip_addr_internal(int_full_key, &saved_ext, var_rcpt_delim);
    }

    /*
     * Try user+foo@domain and user@domain.
     */
    if ((strategy & MA_FIND_FULL) != 0) {
	result = find_addr(path, int_full_key, FULL, WITH_DOMAIN,
			   query_form, ext_addr_buf);
    } else {
	result = 0;
	path->error = 0;
    }

    if (result == 0 && path->error == 0 && int_bare_key != 0
	&& (result = find_addr(path, int_bare_key, PARTIAL, WITH_DOMAIN,
			       query_form, ext_addr_buf)) != 0
	&& extp != 0) {
	*extp = saved_ext;
	saved_ext = 0;
    }

    /*
     * Try user+foo if the domain matches user+foo@$myorigin,
     * user+foo@$mydestination or user+foo@[${proxy,inet}_interfaces]. Then
     * try with +foo stripped off.
     */
    if (result == 0 && path->error == 0
	&& (ratsign = strrchr(int_full_key, '@')) != 0
	&& (strategy & (MA_FIND_LOCALPART_IF_LOCAL
			| MA_FIND_LOCALPART_AT_IF_LOCAL)) != 0) {
	if (strcasecmp_utf8(ratsign + 1, var_myorigin) == 0
	    || (rc = resolve_local(ratsign + 1)) > 0) {
	    if ((strategy & MA_FIND_LOCALPART_IF_LOCAL) != 0)
		result = find_local(path, ratsign, 0, int_full_key,
				 int_bare_key, query_form, extp, &saved_ext,
				    ext_addr_buf);
	    if (result == 0 && path->error == 0
		&& (strategy & MA_FIND_LOCALPART_AT_IF_LOCAL) != 0)
		result = find_local(path, ratsign, 1, int_full_key,
				 int_bare_key, query_form, extp, &saved_ext,
				    ext_addr_buf);
	} else if (rc < 0)
	    path->error = rc;
    }

    /*
     * Try @domain.
     */
    if (result == 0 && path->error == 0 && ratsign != 0
	&& (strategy & MA_FIND_AT_DOMAIN) != 0)
	result = maps_find(path, ratsign, PARTIAL);

    /*
     * Try domain (optionally, subdomains).
     */
    if (result == 0 && path->error == 0 && ratsign != 0
	&& (strategy & MA_FIND_DOMAIN) != 0) {
	const char *name;
	const char *next;

	if ((strategy & MA_FIND_PDMS) && (strategy & MA_FIND_PDDMDS))
	    msg_warn("mail_addr_find_opt: do not specify both "
		     "MA_FIND_PDMS and MA_FIND_PDDMDS");
	for (name = ratsign + 1; *name != 0; name = next) {
	    if ((result = maps_find(path, name, PARTIAL)) != 0
		|| path->error != 0
		|| (strategy & (MA_FIND_PDMS | MA_FIND_PDDMDS)) == 0
		|| (next = strchr(name + 1, '.')) == 0)
		break;
	    if ((strategy & MA_FIND_PDDMDS) == 0)
		next++;
	}
    }

    /*
     * Try localpart@ even if the domain is not local.
     */
    if ((strategy & MA_FIND_LOCALPART_AT) != 0 \
	&&result == 0 && path->error == 0)
	result = find_local(path, ratsign, 1, int_full_key,
			    int_bare_key, query_form, extp, &saved_ext,
			    ext_addr_buf);

    /*
     * Optionally convert the result to internal form. The lookup result is
     * supposed to be one external-form email address.
     */
    if (result != 0 && out_form == MA_FORM_INTERNAL) {
	if (int_result == 0)
	    int_result = vstring_alloc(100);
	unquote_822_local(int_result, result);
	result = STR(int_result);
    }

    /*
     * Clean up.
     */
    if (msg_verbose)
	msg_info("%s: %s -> %s", myname, address,
		 result ? result :
		 path->error ? "(try again)" :
		 "(not found)");
    myfree(int_full_key);
    if (int_bare_key)
	myfree(int_bare_key);
    if (saved_ext)
	myfree(saved_ext);
    if (int_addr_buf)
	vstring_free(int_addr_buf);
    if (ext_addr_buf)
	vstring_free(ext_addr_buf);
    return (result);
}