enum funcargs_cmp funcargs_cmp(funcargs *args_to, funcargs *args_from)
{
	int count_to;
	int count_from;

	if(args_to == args_from)
		return FUNCARGS_EXACT_EQUAL;

	if(FUNCARGS_EMPTY_NOVOID(args_to)
	|| FUNCARGS_EMPTY_NOVOID(args_from))
	{
		/* a() or b() */
		return FUNCARGS_IMPLICIT_CONV;
	}

	count_to = dynarray_count(args_to->arglist);
	count_from = dynarray_count(args_from->arglist);

	/* still do prototype checks for old_proto functions */
	/*if(args_to->args_old_proto || args_from->args_old_proto)
		return FUNCARGS_IMPLICIT_CONV;*/

	if(!(args_to->variadic ? count_to <= count_from : count_to == count_from))
		return FUNCARGS_MISMATCH_COUNT;

	if(count_to){
		unsigned i;

		for(i = 0; args_to->arglist[i]; i++){
			switch(type_cmp(args_to->arglist[i]->ref, args_from->arglist[i]->ref, 0)){
				case TYPE_EQUAL:
				case TYPE_QUAL_ADD: /* f(const int) and f(int) */
				case TYPE_QUAL_SUB: /* f(int) and f(const int) */
				case TYPE_EQUAL_TYPEDEF:
					break;

				case TYPE_QUAL_POINTED_ADD:
				case TYPE_QUAL_POINTED_SUB:
				case TYPE_QUAL_NESTED_CHANGE:
				case TYPE_CONVERTIBLE_EXPLICIT:
				case TYPE_CONVERTIBLE_IMPLICIT:
				case TYPE_NOT_EQUAL:
					return FUNCARGS_MISMATCH_TYPES;
			}
		}
	}

	return FUNCARGS_EXACT_EQUAL;
}
Exemple #2
0
static char *find_arg(macro *m, char *word, char **args, int *alloced)
{
	*alloced = 0;
	if(!strcmp(word, VA_ARGS_STR)){
		if(args){
			size_t i = dynarray_count(m->args);
			/* if count(args) < i then args[i] is NULL,
			 * which str_join handles
			 */
			*alloced = 1;
			return str_join(args + i, ", ");
		}else{
			return "";
		}
	}

	if(m->args){
		char *w;
		size_t i;

		for(i = 0; (w = m->args[i]); i++)
			if(!strcmp(w, word))
				return args[i]; /* don't expand */
	}

	/* word not found, we use the given identifier */
	return word;
}
Exemple #3
0
/* 
 * Function: DHCPLeaseListWrite
 *
 * Purpose:
 *   Write the last DHCP lease in the list for the given interface/client_id.
 *   We only save the last (current) lease.  See the comments for 
 *   DHCPLeaseListRead above for more information.
 */
void
DHCPLeaseListWrite(DHCPLeaseListRef list_p,
		   const char * ifname,
		   uint8_t cid_type, const void * cid, int cid_length)
{
    int			count;
    char		filename[PATH_MAX];
    CFDictionaryRef	lease_dict;
    DHCPLeaseRef	lease_p;
    
    if (DHCPLeaseListGetPath(ifname, cid_type, cid, cid_length,
			     filename, sizeof(filename)) == FALSE) {
	return;
    }
    DHCPLeaseListRemoveStaleLeases(list_p);
    count = dynarray_count(list_p);
    if (count == 0) {
	unlink(filename);
	return;
    }
    lease_p = dynarray_element(list_p, count - 1);
    lease_dict = DHCPLeaseCopyDictionary(lease_p);
    if (my_CFPropertyListWriteFile(lease_dict, filename, 0644) < 0) {
	/*
	 * An ENOENT error is expected on a read-only filesystem.  All 
	 * other errors should be reported.
	 */
	if (errno != ENOENT) {
	    my_log(LOG_ERR, "my_CFPropertyListWriteFile(%s) failed, %s", 
		   filename, strerror(errno));
	}
    }
    my_CFRelease(&lease_dict);
    return;
}
Exemple #4
0
char *func_mangle(const char *name, type *fnty)
{
	char *pre, suff[8];

	pre = fopt_mode & FOPT_LEADING_UNDERSCORE ? "_" : "";
	*suff = '\0';

	if(fnty){
		funcargs *fa = type_funcargs(fnty);

		switch(fa->conv){
			case conv_fastcall:
				pre = "@";

			case conv_stdcall:
				snprintf(suff, sizeof suff,
						"@%d",
						dynarray_count(fa->arglist) * platform_word_size());

			case conv_x64_sysv:
			case conv_x64_ms:
			case conv_cdecl:
				break;
		}
	}

	if(*pre || *suff){
		return ustrprintf("%s%s%s", pre, name, suff);
	}

	return (char *)name;
}
Exemple #5
0
/*
 * Function: DHCPLeaseListRemoveStaleLeases
 * Purpose:
 *   Scans the list of leases removing any that are no longer valid.
 */
static void
DHCPLeaseListRemoveStaleLeases(DHCPLeaseListRef list_p)
{
    int				count;
    absolute_time_t 		current_time;
    int				i;

    count = dynarray_count(list_p);
    if (count == 0) {
	return;
    }
    current_time = timer_current_secs();
    i = 0;
    while (i < count) {
	DHCPLeaseRef	lease_p = dynarray_element(list_p, i);

	/* check the lease expiration */
	if (lease_p->lease_length != DHCP_INFINITE_LEASE
	    && current_time >= (lease_p->lease_start + lease_p->lease_length)) {
	    /* lease is expired */
	    if (G_IPConfiguration_verbose) {
		my_log(LOG_DEBUG, "Removing Stale Lease "
		       IP_FORMAT " Router " IP_FORMAT,
		       IP_LIST(&lease_p->our_ip),
		       IP_LIST(&lease_p->router_ip));
	    }
	    dynarray_free_element(list_p, i);
	    count--;
	}
	else {
	    i++;
	}
    }
    return;
}
Exemple #6
0
/* checks case duplicates, not default */
static void fold_switch_dups(stmt *sw)
{
	typedef int (*qsort_f)(const void *, const void *);

	struct
	{
		numeric start, end;
		stmt *cse;
	} *vals;
	size_t n = dynarray_count(sw->bits.switch_.cases);
	size_t i = 0;
	stmt **titer;

	if(n == 0)
		return;

	vals = malloc(n * sizeof *vals);

	/* gather all switch values */
	ITER_SWITCH(sw, titer){
		stmt *cse = *titer;

		vals[i].cse = cse;

		const_fold_integral(cse->expr, &vals[i].start);

		if(stmt_kind(cse, case_range))
			const_fold_integral(cse->expr2, &vals[i].end);
		else
			memcpy(&vals[i].end, &vals[i].start, sizeof vals[i].end);

		i++;
	}
static int check_arg_counts(
		funcargs *args_from_decl,
		unsigned count_decl,
		expr **exprargs,
		expr *fnexpr, char *sp)
{
	where *const loc = &fnexpr->where;

	/* this block is purely count checking */
	if(!FUNCARGS_EMPTY_NOVOID(args_from_decl)){
		const unsigned count_arg  = dynarray_count(exprargs);

		if(count_decl != count_arg
		&& (args_from_decl->variadic ? count_arg < count_decl : 1))
		{
			decl *call_decl;
			/* may be args_old_proto but also args_void if copied from
			 * another prototype elsewhere */
			int warn = args_from_decl->args_old_proto
				&& !args_from_decl->args_void;
			int warning_emitted = 1;

#define common_warning                                         \
					"too %s arguments to function %s%s(got %d, need %d)",\
					count_arg > count_decl ? "many" : "few",             \
					sp ? sp : "",                                        \
					sp ? " " : "",                                       \
					count_arg, count_decl

			if(warn){
				warning_emitted = cc1_warn_at(loc, funcall_argcount, common_warning);
			}else{
				warn_at_print_error(loc, common_warning);
			}

#undef common_warning

			if(warning_emitted
			&& (call_decl = expr_to_declref(fnexpr->expr, NULL)))
			{
				note_at(&call_decl->where, "'%s' declared here", call_decl->spel);
			}

			if(!warn){
				fold_had_error = 1;
				return 1;
			}
		}
	}else if(args_from_decl->args_void_implicit && exprargs){
		cc1_warn_at(loc, funcall_argcount,
				"too many arguments to implicitly (void)-function");
	}
	return 0;
}
/*
 * Function: ifl_first_broadcast_inet
 *
 * Purpose:
 *   Return the first non-loopback, broadcast capable interface.
 */
interface_t *
ifl_first_broadcast_inet(interface_list_t * list_p)
{
    int i;
    for (i = 0; i < list_p->count; i++) {
	interface_t * if_p = list_p->list + i;

	if (dynarray_count(&if_p->inet) > 0
	    && !(if_p->flags & IFF_LOOPBACK)
	    && (if_p->flags & IFF_BROADCAST))
	    return (list_p->list + i);
    }
    return (NULL);
}
static void sentinel_check(where *w, expr *e, expr **args,
		const int variadic, const int nstdargs, symtable *stab)
{
#define ATTR_WARN_RET(w, ...) \
	do{ cc1_warn_at(w, attr_sentinel, __VA_ARGS__); return; }while(0)

	attribute *attr = func_or_builtin_attr_present(e, attr_sentinel);
	int i, nvs;
	expr *sentinel;

	if(!attr)
		return;

	if(!variadic)
		return; /* warning emitted elsewhere, on the decl */

	if(attr->bits.sentinel){
		consty k;

		FOLD_EXPR(attr->bits.sentinel, stab);
		const_fold(attr->bits.sentinel, &k);

		if(k.type != CONST_NUM || !K_INTEGRAL(k.bits.num))
			die_at(&attr->where, "sentinel attribute not reducible to integer constant");

		i = k.bits.num.val.i;
	}else{
		i = 0;
	}

	nvs = dynarray_count(args) - nstdargs;

	if(nvs == 0)
		ATTR_WARN_RET(w, "not enough variadic arguments for a sentinel");

	UCC_ASSERT(nvs >= 0, "too few args");

	if(i >= nvs)
		ATTR_WARN_RET(w, "sentinel index is not a variadic argument");

	sentinel = args[(nstdargs + nvs - 1) - i];

	/* must be of a pointer type, printf("%p\n", 0) is undefined */
	if(!expr_is_null_ptr(sentinel, NULL_STRICT_ANY_PTR))
		ATTR_WARN_RET(&sentinel->where, "sentinel argument expected (got %s)",
				type_to_str(sentinel->tree_type));

#undef ATTR_WARN_RET
}
static void gen_inits_terms1(
		decl **ar,
		void (*declare)(decl *),
		int (*cmp)(const void *, const void *))
{
	size_t n = dynarray_count(ar);
	decl **i;

	if(!n)
		return;

	qsort(ar, n, sizeof *ar, cmp);

	for(i = ar; *i; i++)
		declare(*i);
}
Exemple #11
0
STATIC RTADVSocketRef
RTADVSocketFind(int if_index)
{
    int 			i;

    for (i = 0; i < dynarray_count(&S_globals->sockets); i++) {
	interface_t *		if_p;
	RTADVSocketRef		sock;

	sock = dynarray_element(&S_globals->sockets, i);
	if_p = RTADVSocketGetInterface(sock);
	if (if_index == if_link_index(if_p)) {
	    return (sock);
	}
    }
    return (NULL);
}
Exemple #12
0
/*
 * Function: DHCPLeaseListFindLease
 * Purpose:
 *   Find a lease corresponding to the supplied information.
 */
int
DHCPLeaseListFindLease(DHCPLeaseListRef list_p, struct in_addr our_ip,
		       struct in_addr router_ip,
		       const uint8_t * router_hwaddr, int router_hwaddr_length)
{
    int			count;
    int			i;
    bool		private_ip = ip_is_private(our_ip);

    count = dynarray_count(list_p);
    for (i = 0; i < count; i++) {
	DHCPLeaseRef	lease_p = dynarray_element(list_p, i);

	if (lease_p->our_ip.s_addr != our_ip.s_addr) {
	    /* IP doesn't match */
	    continue;
	}
	if (private_ip == FALSE) {
	    /* lease for public IP is unique */
	    return (i);
	}
	if (lease_p->router_ip.s_addr != router_ip.s_addr) {
	    /* router IP doesn't match (or one is set the other isn't)*/
	    continue;
	}
	if (router_ip.s_addr == 0) {
	    /* found lease with no router information */
	    return (i);
	}
	if (lease_p->router_hwaddr_length != router_hwaddr_length) {
	    /* one has router hwaddr, other doesn't */
	    continue;
	}
	if (router_hwaddr == NULL || router_hwaddr_length == 0) {
	    /* found lease with router IP but no router hwaddr */
	    return (i);
	}
	if (bcmp(lease_p->router_hwaddr, router_hwaddr, router_hwaddr_length)
	    == 0) {
	    /* exact match on IP, router IP, router hwaddr */
	    return (i);
	}
    }
    return (-1);
}
static void
DHCPv6SocketDemux(int if_index, const DHCPv6PacketRef pkt, int pkt_len)
{
    DHCPv6SocketReceiveData	data;
    DHCPv6OptionErrorString 	err;
    int 			i;

    if (pkt_len < DHCPV6_PACKET_HEADER_LENGTH) {
	return;
    }
    data.pkt = pkt;
    data.pkt_len = pkt_len;
    data.options = DHCPv6OptionListCreateWithPacket(pkt, pkt_len, &err);
    if (data.options == NULL) {
	my_log(LOG_NOTICE, "DHCPv6Socket: options parse failed, %s",
	       err.str);
	return;
    }
    for (i = 0; i < dynarray_count(&S_globals->sockets); i++) {
	DHCPv6SocketRef	client;

	client = dynarray_element(&S_globals->sockets, i);
	if (if_index != if_link_index(DHCPv6SocketGetInterface(client))) {
	    continue;
	}
	if (S_verbose) {
	    CFMutableStringRef	str;
	    
	    str = CFStringCreateMutable(NULL, 0);
	    DHCPv6PacketPrintToString(str, pkt, pkt_len);
	    if (data.options != NULL) {
		DHCPv6OptionListPrintToString(str, data.options);
	    }
	    my_log(-LOG_DEBUG, "[%s] Receive %@", 
		   if_name(DHCPv6SocketGetInterface(client)), str);
	    CFRelease(str);
	}
	if (client->receive_func != NULL) {
	    (*client->receive_func)(client->receive_arg1, client->receive_arg2,
				    &data);
	}
    }
    DHCPv6OptionListRelease(&data.options);
    return;
}
Exemple #14
0
static void
DHCPLeaseListLog(DHCPLeaseListRef list_p)
{
    int			count;
    int			i;
    CFMutableStringRef	str;
	
    str = CFStringCreateMutable(NULL, 0);
    count = dynarray_count(list_p);
    for (i = 0; i < count; i++) {
	DHCPLeaseRef	lease_p = dynarray_element(list_p, i);

	STRING_APPEND(str, "\n%d. ", i + 1);
	DHCPLeasePrintToString(str, lease_p);
    }
    my_log(~LOG_DEBUG, "DHCPLeaseList has %d element(s)%@", count, str);
    CFRelease(str);
    return;
}
interface_t *
ifl_find_ip(interface_list_t * list_p, struct in_addr iaddr)
{
    int 	i;

    for (i = 0; i < list_p->count; i++) {
	interface_t * if_p = list_p->list + i;
	int j;

	for (j = 0; j < dynarray_count(&if_p->inet); j++) {
	    inet_addrinfo_t *	info;

	    info = dynarray_element(&if_p->inet, j);
	    if (info->addr.s_addr == iaddr.s_addr)
		return (if_p);
	}
    }
    return (NULL);
}
const out_val *gen_expr_stmt(const expr *e, out_ctx *octx)
{
	size_t n;
	const out_val *ret;
	struct out_dbg_lbl *pushed_lbls[2];

	gen_stmt_code_m1(e->code, 1, pushed_lbls, octx);

	n = dynarray_count(e->code->bits.code.stmts);

	if(n > 0 && stmt_kind(e->code->bits.code.stmts[n-1], expr))
		ret = gen_expr(e->code->bits.code.stmts[n - 1]->expr, octx);
	else
		ret = out_new_noop(octx);

	/* this is skipped by gen_stmt_code_m1( ... 1, ... ) */
	gen_stmt_code_m1_finish(e->code, pushed_lbls, octx);

	return ret;
}
interface_t *
ifl_find_subnet(interface_list_t * list_p, struct in_addr iaddr)
{
    int 	i;
    u_long	addr_hl = iptohl(iaddr);

    for (i = 0; i < list_p->count; i++) {
	interface_t * if_p = list_p->list + i;
	int j;

	for (j = 0; j < dynarray_count(&if_p->inet); j++) {
	    inet_addrinfo_t *	info = dynarray_element(&if_p->inet, j);
	    u_long 		ifnetaddr_hl = iptohl(info->netaddr);
	    u_long 		ifmask_hl = iptohl(info->mask);

	    if ((addr_hl & ifmask_hl) == ifnetaddr_hl)
		return (if_p);
	}
    }
    return (NULL);
}
void fold_expr_stmt(expr *e, symtable *stab)
{
	stmt *last_stmt;
	int last;

	(void)stab;

	last = dynarray_count(e->code->bits.code.stmts);
	if(last){
		last_stmt = e->code->bits.code.stmts[last - 1];
		last_stmt->freestanding = 1; /* allow the final to be freestanding */
		last_stmt->expr_no_pop = 1;
	}

	fold_stmt(e->code); /* symtab should've been set by parse */

	if(last && stmt_kind(last_stmt, expr)){
		expr *last_expr = last_stmt->expr;

		e->tree_type = last_expr->tree_type;
		if(fold_check_expr(e,
				FOLD_CHK_ALLOW_VOID,
				"({ ... }) statement"))
		{
			return;
		}

		switch(expr_is_lval(last_expr)){
			case LVALUE_NO:
				break;
			case LVALUE_STRUCT:
			case LVALUE_USER_ASSIGNABLE:
				e->f_islval = expr_is_lval_struct;
		}
	}else{
		e->tree_type = type_nav_btype(cc1_type_nav, type_void);
	}

	e->freestanding = 1; /* ({ ... }) on its own is freestanding */
}
Exemple #19
0
/* 
 * Function: DHCPLeaseListUpdateLease
 *
 * Purpose:
 *   Update the lease entry for the given lease in the in-memory lease database.
 */
void
DHCPLeaseListUpdateLease(DHCPLeaseListRef list_p, struct in_addr our_ip,
			 struct in_addr router_ip,
			 const uint8_t * router_hwaddr,
			 int router_hwaddr_length,
			 absolute_time_t lease_start,
			 dhcp_lease_time_t lease_length,
			 const uint8_t * pkt, int pkt_size,
			 CFStringRef ssid)
{
    int			count;
    int			i;
    DHCPLeaseRef	lease_p;
    boolean_t		private_ip = ip_is_private(our_ip);

    lease_p = DHCPLeaseCreate(our_ip, router_ip,
			      router_hwaddr, router_hwaddr_length,
			      lease_start, lease_length, pkt, pkt_size,
			      ssid);
    /* scan lease list to eliminate NAK'd, incomplete, and duplicate leases */
    count = dynarray_count(list_p);
    for (i = 0; i < count; i++) {
	DHCPLeaseRef	scan_p = dynarray_element(list_p, i);

	if (DHCPLeaseShouldBeRemoved(scan_p, lease_p, private_ip)) {
	    dynarray_free_element(list_p, i);
	    i--;
	    count--;
	}
    }
    dynarray_add(list_p, lease_p);
    if (G_IPConfiguration_verbose) {
	my_log(LOG_DEBUG, "Saved lease for " IP_FORMAT,
	       IP_LIST(&lease_p->our_ip));
	if (G_IPConfiguration_verbose) {
	    DHCPLeaseListLog(list_p);
	}
    }
    return;
}
static void check_standard_funcs(const char *name, expr **args)
{
	const size_t nargs = dynarray_count(args);

	if(!strcmp(name, "free") && nargs == 1){
		c_func_check_free(args[0]);
	}else{
		static const struct {
			const char *name;
			unsigned nargs;
			int szarg;
			int ptrargs[2];
		} memfuncs[] = {
			{ "memcpy", 3, 2, { 0, 1 } },
			{ "memset", 3, 2, { 0, -1 } },
			{ "memmove", 3, 2, { 0, 1 } },
			{ "memcmp", 3, 2, { 0, 1 } },

			{ 0 }
		};

		for(int i = 0; memfuncs[i].name; i++){
			if(nargs == memfuncs[i].nargs && !strcmp(name, memfuncs[i].name)){
				expr *ptrargs[countof(memfuncs[0].ptrargs) + 1] = { 0 };
				unsigned arg;

				for(arg = 0; arg < countof(memfuncs[0].ptrargs); arg++){
					if(memfuncs[i].ptrargs[arg] == -1)
						break;

					ptrargs[arg] = args[memfuncs[i].ptrargs[arg]];
				}

				c_func_check_mem(ptrargs, args[memfuncs[i].szarg], memfuncs[i].name);
				break;
			}
		}
	}
}
Exemple #21
0
PRIVATE_EXTERN void
RTADVSocketRelease(RTADVSocketRef * sock_p)
{
    RTADVSocketRef 	sock = *sock_p;
    int 		i;

    if (sock == NULL) {
	return;
    }
    i = dynarray_index(&S_globals->sockets, sock);
    if (i != -1) {
	dynarray_remove(&S_globals->sockets, i, NULL);
    }
    else {
	my_log(LOG_NOTICE, "RTADVSocketRelease: %s not in list?",
	       if_name(sock->if_p));
    }
    RTADVSocketFreeElement(sock);
    *sock_p = NULL;
    if (dynarray_count(&S_globals->sockets) == 0) {
	RTADVSocketReleaseGlobals(&S_globals);
    }
    return;
}
void
DHCPv6SocketRelease(DHCPv6SocketRef * sock_p)
{
    DHCPv6SocketRef 	sock = *sock_p;
    int 		i;

    if (sock == NULL) {
	return;
    }
    i = dynarray_index(&S_globals->sockets, sock);
    if (i != -1) {
	dynarray_remove(&S_globals->sockets, i, NULL);
    }
    else {
	my_log(LOG_ERR, "DHCPv6SocketRelease: %s not in list?",
	       if_name(sock->if_p));
    }
    DHCPv6SocketFreeElement(sock);
    *sock_p = NULL;
    if (dynarray_count(&S_globals->sockets) == 0) {
	DHCPv6SocketReleaseGlobals(&S_globals);
    }
    return;
}
Exemple #23
0
static void runner(int local, char *path, char **args)
{
	pid_t pid;

	if(show){
		int i;

		if(wrapper)
			fprintf(stderr, "WRAPPER='%s' ", wrapper);

		fprintf(stderr, "%s ", path);
		for(i = 0; args[i]; i++)
			fprintf(stderr, "%s ", args[i]);
		fputc('\n', stderr);
	}

	if(noop)
		return;


	/* if this were to be vfork, all the code in case-0 would need to be done in the parent */
	pid = fork();

	switch(pid){
		case -1:
			die("fork():");

		case 0:
		{
			int nargs = dynarray_count(args);
			int i_in = 0, i_out = 0;
			char **argv;

			/* -wrapper gdb,--args */
			if(wrapper){
				char *p;
				nargs++;
				for(p = wrapper; *p; p++)
					nargs += *p == ',';
			}

			/*
			 * path,
			 * { args }
			 * NULL-term
			 */
			argv = umalloc((2 + nargs) * sizeof *argv);

			/* wrapper */
			if(wrapper){
				char *p, *last;
				for(p = last = wrapper; *p; p++)
					if(*p == ','){
						*p = '\0';
						argv[i_out++] = last;
						last = p + 1;
					}

				if(last != p)
					argv[i_out++] = last;
			}

			argv[i_out++] = local ? actual_path("../", path) : path;

			while(args[i_in])
				argv[i_out++] = args[i_in++];

			argv[i_out++] = NULL;

#ifdef DEBUG
			fprintf(stderr, "%s:\n", *argv);
			for(int i = 0; argv[i]; i++)
				fprintf(stderr, "  [%d] = \"%s\",\n", i, argv[i]);
#endif

			if(wrapper)
				local = 0;

			(local ? execv : execvp)(argv[0], argv);
			die("execv(\"%s\"):", argv[0]);
		}

		default:
		{
			int status, i;
			if(wait(&status) == -1)
				die("wait()");

			if(WIFEXITED(status) && (i = WEXITSTATUS(status)) != 0){
				die("%s returned %d", path, i);
			}else if(WIFSIGNALED(status)){
				int sig = WTERMSIG(status);

				fprintf(stderr, "%s caught signal %d\n", path, sig);

				/* exit with propagating status */
				exit(128 + sig);
			}
		}
	}
}
boolean_t
if_inet_valid(interface_t * if_p)
{
    return (dynarray_count(&if_p->inet) > 0);
}
int
if_inet_count(interface_t * if_p)
{
    return (dynarray_count(&if_p->inet));
}
Exemple #26
0
/*
 * Function: DHCPLeaseListCopyARPAddressInfo
 * Purpose:
 *   Returns a list of arp_address_info_t's corresponding to each
 *   discoverable lease.
 */
arp_address_info_t *
DHCPLeaseListCopyARPAddressInfo(DHCPLeaseListRef list_p,
				CFStringRef ssid,
				absolute_time_t * start_time_threshold_p,
				bool tentative_ok,
				int * ret_count)
{
    int				arp_info_count;
    arp_address_info_t *	arp_info_p;
    int				count;
    int				i;
    arp_address_info_t *	info_p;

    DHCPLeaseListRemoveStaleLeases(list_p);
    count = dynarray_count(list_p);
    if (count == 0) {
	*ret_count = 0;
	return (NULL);
    }
    arp_info_p = (arp_address_info_t *)malloc(sizeof(*arp_info_p) * count);
    arp_info_count = 0;
    info_p = arp_info_p;
    for (i = 0; i < count; i++) {
	DHCPLeaseRef	lease_p = dynarray_element(list_p, i);

	if (ssid != NULL) {
	    if (lease_p->ssid == NULL || !CFEqual(lease_p->ssid, ssid)) {
		if (G_IPConfiguration_verbose) {
		    my_log(LOG_DEBUG,
			   "ignoring lease with SSID %@",
			   lease_p->ssid);
		    continue;
		}
	    }
	    
	}
	if (lease_p->router_ip.s_addr == 0
	    || lease_p->router_hwaddr_length == 0) {
	    /* can't use this with ARP discovery */
	    if (G_IPConfiguration_verbose) {
		my_log(LOG_DEBUG, "ignoring lease for " IP_FORMAT,
		       IP_LIST(&lease_p->our_ip));
	    }
	    continue;
	}
	if (lease_p->tentative && tentative_ok == FALSE) {
	    /* ignore tentative lease */
	    continue;
	}
	if (start_time_threshold_p != NULL
	    && lease_p->lease_start < *start_time_threshold_p) {
	    if (G_IPConfiguration_verbose) {
		my_log(LOG_DEBUG, 
		       "start time on lease " IP_FORMAT " too old (%ld < %ld)",
		       IP_LIST(&lease_p->our_ip),
		       lease_p->lease_start, *start_time_threshold_p);
	    }
	    continue;
	}
	info_p->sender_ip = lease_p->our_ip;
	info_p->target_ip = lease_p->router_ip;
	bcopy(lease_p->router_hwaddr, info_p->target_hardware,
	      lease_p->router_hwaddr_length);
	arp_info_count++;
	info_p++;
    }
    if (arp_info_count == 0) {
	free(arp_info_p);
	arp_info_p = NULL;
    }
    *ret_count = arp_info_count;
    return (arp_info_p);
}
void fold_expr_funcall(expr *e, symtable *stab)
{
	type *func_ty;
	funcargs *args_from_decl;
	char *sp = NULL;
	unsigned count_decl;

	check_implicit_funcall(e, stab, &sp);

	FOLD_EXPR(e->expr, stab);
	func_ty = e->expr->tree_type;

	if(!type_is_callable(func_ty)){
		warn_at_print_error(&e->expr->where,
				"%s-expression (type '%s') not callable",
				expr_str_friendly(e->expr, 0),
				type_to_str(func_ty));

		fold_had_error = 1;

		e->tree_type = type_nav_btype(cc1_type_nav, type_int);
		return;
	}

	e->tree_type = type_func_call(func_ty, &args_from_decl);

	/* func count comparison, only if the func has arg-decls, or the func is f(void) */
	UCC_ASSERT(args_from_decl, "no funcargs for decl %s", sp);

	count_decl = dynarray_count(args_from_decl->arglist);

	if(check_arg_counts(args_from_decl, count_decl, e->funcargs, e, sp))
		return;

	if(e->funcargs){
		check_arg_voidness_and_nonnulls(
				e, stab,
				args_from_decl, count_decl,
				e->funcargs, sp);
	}

	if(!FUNCARGS_EMPTY_NOVOID(args_from_decl))
		check_arg_types(args_from_decl, e->funcargs, stab, sp, &e->where);

	if(e->funcargs)
		default_promote_args(e->funcargs, count_decl, stab);

	if(type_is_s_or_u(e->tree_type)){
		/* handled transparently by the backend */
		e->f_islval = expr_is_lval_struct;

		cc1_warn_at(&e->expr->where,
				aggregate_return,
				"called function returns aggregate (%s)",
				type_to_str(e->tree_type));
	}

	/* attr */
	{
		type *fnty = e->expr->tree_type;

		/* look through decays */
		if(expr_kind(e->expr, cast) && expr_cast_is_lval2rval(e->expr))
			fnty = expr_cast_child(e->expr)->tree_type;

		format_check_call(fnty, e->funcargs, args_from_decl->variadic);

		sentinel_check(
				&e->where, e,
				e->funcargs, args_from_decl->variadic,
				count_decl, stab);
	}

	/* check the subexp tree type to get the funcall attributes */
	if(func_or_builtin_attr_present(e, attr_warn_unused))
		e->freestanding = 0; /* needs use */

	if(sp && !cc1_fopt.freestanding)
		check_standard_funcs(sp, e->funcargs);
}
Exemple #28
0
static void asm_declare_init(enum section_type sec, decl_init *init, type *tfor)
{
	type *r;

	if(init == DYNARRAY_NULL)
		init = NULL;

	if(!init){
		/* don't initialise flex-arrays */
		if(!type_is_incomplete_array(tfor)){
			asm_declare_pad(sec, type_size(tfor, NULL),
					"null init"/*, type_to_str(tfor)*/);
		}else{
			asm_out_section(sec, ASM_COMMENT " flex array init skipped\n");
		}

	}else if((r = type_is_primitive(tfor, type_struct))){
		/* array of stmts for each member
		 * assumes the ->bits.inits order is member order
		 */
		struct_union_enum_st *const sue = r->bits.type->sue;
		sue_member **mem;
		decl_init **i;
		unsigned end_of_last = 0;
		struct bitfield_val *bitfields = NULL;
		unsigned nbitfields = 0;
		decl *first_bf = NULL;
		expr *copy_from_exp;

		UCC_ASSERT(init->type == decl_init_brace, "unbraced struct");

#define DEBUG(s, ...) /*fprintf(f, "\033[35m" s "\033[m\n", __VA_ARGS__)*/

		i = init->bits.ar.inits;

		/* check for compound-literal copy-init */
		if((copy_from_exp = decl_init_is_struct_copy(init, sue))){
			decl_init *copy_from_init;

			copy_from_exp = expr_skip_lval2rval(copy_from_exp);

			/* the only struct-expression that's possible
			 * in static context is a compound literal */
			assert(expr_kind(copy_from_exp, compound_lit)
					&& "unhandled expression init");

			copy_from_init = copy_from_exp->bits.complit.decl->bits.var.init.dinit;
			assert(copy_from_init->type == decl_init_brace);

			i = copy_from_init->bits.ar.inits;
		}

		/* iterate using members, not inits */
		for(mem = sue->members;
				mem && *mem;
				mem++)
		{
			decl *d_mem = (*mem)->struct_member;
			decl_init *di_to_use = NULL;

			if(i){
				int inc = 1;

				if(*i == NULL)
					inc = 0;
				else if(*i != DYNARRAY_NULL)
					di_to_use = *i;

				if(inc){
					i++;
					if(!*i)
						i = NULL; /* reached end */
				}
			}

			DEBUG("init for %ld/%s, %s",
					mem - sue->members, d_mem->spel,
					di_to_use ? di_to_use->bits.expr->f_str() : NULL);

			/* only pad if we're not on a bitfield or we're on the first bitfield */
			if(!d_mem->bits.var.field_width || !first_bf){
				DEBUG("prev padding, offset=%d, end_of_last=%d",
						d_mem->struct_offset, end_of_last);

				UCC_ASSERT(
						d_mem->bits.var.struct_offset >= end_of_last,
						"negative struct pad, sue %s, member %s "
						"offset %u, end_of_last %u",
						sue->spel, decl_to_str(d_mem),
						d_mem->bits.var.struct_offset, end_of_last);

				asm_declare_pad(sec,
						d_mem->bits.var.struct_offset - end_of_last,
						"prev struct padding");
			}

			if(d_mem->bits.var.field_width){
				if(!first_bf || d_mem->bits.var.first_bitfield){
					if(first_bf){
						DEBUG("new bitfield group (%s is new boundary), old:",
								d_mem->spel);
						/* next bitfield group - store the current */
						bitfields_out(sec, bitfields, &nbitfields, first_bf->ref);
					}
					first_bf = d_mem;
				}

				bitfields = bitfields_add(
						bitfields, &nbitfields,
						d_mem, di_to_use);

			}else{
				if(nbitfields){
					DEBUG("at non-bitfield, prev-bitfield out:", 0);
					bitfields_out(sec, bitfields, &nbitfields, first_bf->ref);
					first_bf = NULL;
				}

				DEBUG("normal init for %s:", d_mem->spel);
				asm_declare_init(sec, di_to_use, d_mem->ref);
			}

			if(type_is_incomplete_array(d_mem->ref)){
				UCC_ASSERT(!mem[1], "flex-arr not at end");
			}else if(!d_mem->bits.var.field_width || d_mem->bits.var.first_bitfield){
				unsigned last_sz = type_size(d_mem->ref, NULL);

				end_of_last = d_mem->bits.var.struct_offset + last_sz;
				DEBUG("done with member \"%s\", end_of_last = %d",
						d_mem->spel, end_of_last);
			}
		}

		if(nbitfields)
			bitfields_out(sec, bitfields, &nbitfields, first_bf->ref);
		free(bitfields);

		/* need to pad to struct size */
		asm_declare_pad(sec,
				sue_size(sue, NULL) - end_of_last,
				"struct tail");

	}else if((r = type_is(tfor, type_array))){
		size_t i, len;
		decl_init **p;
		type *next = type_next(tfor);

		UCC_ASSERT(init->type == decl_init_brace, "unbraced struct");

		if(type_is_incomplete_array(tfor)){
			len = dynarray_count(init->bits.ar.inits);
		}else{
			UCC_ASSERT(type_is_complete(tfor), "incomplete array/type init");
			len = type_array_len(tfor);
		}

		for(i = len, p = init->bits.ar.inits;
				i > 0;
				i--)
		{
			decl_init *this = NULL;
			if(*p){
				this = *p++;

				if(this != DYNARRAY_NULL && this->type == decl_init_copy){
					/*fprintf(f, "# copy from %lu\n", DECL_INIT_COPY_IDX(this, init));*/
					struct init_cpy *icpy = *this->bits.range_copy;
					/* resolve the copy */
					this = icpy->range_init;
				}
			}

			asm_declare_init(sec, this, next);
		}

	}else if((r = type_is_primitive(tfor, type_union))){
		/* union inits are decl_init_brace with spaces up to the first union init,
		 * then NULL/end of the init-array */
		struct_union_enum_st *sue = type_is_s_or_u(r);
		unsigned i, sub = 0;
		decl_init *u_init;

		UCC_ASSERT(init->type == decl_init_brace, "brace init expected");

		/* skip the empties until we get to one */
		for(i = 0; init->bits.ar.inits[i] == DYNARRAY_NULL; i++);

		if((u_init = init->bits.ar.inits[i])){
			decl *mem = sue->members[i]->struct_member;
			type *mem_r = mem->ref;

			/* union init, member at index `i' */
			if(mem->bits.var.field_width){
				/* we know it's integral */
				struct bitfield_val bfv;

				ASSERT_SCALAR(u_init);

				bitfield_val_set(&bfv, u_init->bits.expr, mem->bits.var.field_width);

				asm_declare_init_bitfields(sec, &bfv, 1, mem_r);
			}else{
				asm_declare_init(sec, u_init, mem_r);
			}

			sub = type_size(mem_r, NULL);
		} /* else null union init */

		asm_declare_pad(sec,
				type_size(r, NULL) - sub,
				"union extra");

	}else{
		/* scalar */
		expr *exp = init->bits.expr;

		UCC_ASSERT(init->type == decl_init_scalar, "scalar init expected");

		/* exp->tree_type should match tfor */
		{
			char buf[TYPE_STATIC_BUFSIZ];

			UCC_ASSERT(
					type_cmp(exp->tree_type, tfor, TYPE_CMP_ALLOW_TENATIVE_ARRAY) != TYPE_NOT_EQUAL,
					"mismatching init types: %s and %s",
					type_to_str_r(buf, exp->tree_type),
					type_to_str(tfor));
		}

		/* use tfor, since "abc" has type (char[]){(int)'a', (int)'b', ...} */
		DEBUG("  scalar init for %s:", type_to_str(tfor));
		static_val(sec, tfor, exp);
	}
}