PERFORCE change 125439 for review

Fredrik Lindberg fli at FreeBSD.org
Mon Aug 20 10:33:26 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=125439

Change 125439 by fli at fli_nexus on 2007/08/20 17:32:59

	- Add mdns_db_name_{list, freelist}, obtains a list of
	  names assigned to a resource identifier.
	- Add mdns_db_res_{list, freelist}, obatins a list of
	  resources assigned to a resource identifier.

Affected files ...

.. //depot/projects/soc2007/fli-mdns_sd/libmdns/libmdns.c#4 edit
.. //depot/projects/soc2007/fli-mdns_sd/libmdns/mdns.h#4 edit

Differences ...

==== //depot/projects/soc2007/fli-mdns_sd/libmdns/libmdns.c#4 (text+ko) ====

@@ -708,6 +708,400 @@
 }
 
 int
+mdns_db_res_list(struct mdns *m, const char *ident, unsigned int ifidx,
+    struct mdns_res **mr)
+{
+	int i, mid, validres, count, error;
+	size_t ilen, l;
+	char *p;
+	TAILQ_HEAD(, mdns_msg) msgtmp;
+	struct mdns_msg *mm, *mm2;
+	struct mdns_res *mrval;
+	struct mipc_dbi_res_get *mirg;
+	struct mipc_dbi_res_list mirl;
+
+	MDNS_ASSERT(m);
+
+	if (ifidx == 0)
+		return (-1);
+	ilen = strlen(ident);
+	if (ilen == 0)
+		return (-1);
+
+	mirl.mirl_ilen = ilen;
+	mirl.mirl_ifidx = ifidx;
+	mid = docmd(m, MIM_IDENT_RES_LIST, 2, &mirl,
+	    sizeof(struct mipc_dbi_res_list), ident, ilen);
+	if (mid < 0)
+		return (-1);
+
+	count = 0;
+    	validres = 1;
+	TAILQ_INIT(&msgtmp);
+	do {
+		mm = msg_wait(m, mid, NULL);
+		if (mm == NULL)
+			break;
+		if (mm->mm_msgtype == MIM_IDENT_RES) {
+			TAILQ_INSERT_TAIL(&msgtmp, mm, mm_next);
+			count++;
+		}
+		else if ((mm->mm_msgtype == MIM_ACK) ||
+		    ((error = errormsg(mm)) >= 0)) {
+			validres = 0;
+			msg_free(mm);
+		}
+	} while (validres);
+
+	if (count == 0) {
+		*mr = NULL;
+		return (0);
+	}
+
+	mrval = malloc(sizeof(struct mdns_res) * count);
+	if (mrval == NULL)
+		goto out;
+
+	i = 0;
+	TAILQ_FOREACH_SAFE(mm, &msgtmp, mm_next, mm2) {
+		TAILQ_REMOVE(&msgtmp, mm, mm_next);
+		l = mm->mm_buflen;
+		if (l < sizeof(struct mipc_dbi_res_get)) {
+			msg_free(mm);
+			continue;
+		}
+		mirg = (struct mipc_dbi_res_get *)mm->mm_buf;
+		p = mm->mm_buf + sizeof(struct mipc_dbi_res_get);
+		l -= sizeof(struct mipc_dbi_res_get);
+
+		if (l < mirg->mirg_len) {
+			msg_free(mm);
+			continue;
+		}
+
+		mrval[i].mr_res =
+		    malloc((mirg->mirg_len + 1) * sizeof(wchar_t));
+		if (mrval[i].mr_res == NULL) {
+			msg_free(mm);
+			goto out;
+		}
+		memcpy(mrval[i].mr_res, p, mirg->mirg_len * sizeof(wchar_t));
+		mrval[i].mr_res[mirg->mirg_len] = L'\0';
+
+		p += (mirg->mirg_len * sizeof(wchar_t));
+		l -= (mirg->mirg_len * sizeof(wchar_t));
+
+		if (l < mirg->mirg_elen) {
+			free(mrval[i].mr_res);
+			msg_free(mm);
+			continue;
+		}
+
+		mrval[i].mr_data = malloc(mirg->mirg_elen);
+		if (mrval[i].mr_data == NULL) {
+			free(mrval[i].mr_res);
+			msg_free(mm);
+			goto out;
+		}
+		memcpy(mrval[i].mr_data, p, mirg->mirg_elen);
+		p += mirg->mirg_elen;
+		l -= mirg->mirg_elen;
+
+		if (mirg->mirg_ilen > 0) {
+			if (l < mirg->mirg_ilen) {
+				free(mrval[i].mr_res);
+				free(mrval[i].mr_data);
+				msg_free(mm);
+				continue;
+			}
+			mrval[i].mr_ptr = malloc(mirg->mirg_ilen + 1);
+			if (mrval[i].mr_ptr == NULL) {
+				free(mrval[i].mr_res);
+				free(mrval[i].mr_data);
+				msg_free(mm);
+				goto out;
+			}
+			memcpy(mrval[i].mr_ptr, p, mirg->mirg_ilen);
+			mrval[i].mr_ptr[mirg->mirg_ilen] = '\0';
+		}
+		else {
+			mrval[i].mr_ptr = NULL;
+		}
+
+		mrval[i].mr_ttl = mirg->mirg_ttl;
+		mrval[i].mr_class = mirg->mirg_class;
+		mrval[i].mr_type = mirg->mirg_type;
+		mrval[i].mr_len = mirg->mirg_len;
+		mrval[i].mr_ident = strdup(ident);
+		i++;
+		msg_free(mm);
+	}
+
+	*mr = mrval;
+	return (i);
+out:
+	TAILQ_FOREACH_SAFE(mm, &msgtmp, mm_next, mm2) {
+		TAILQ_REMOVE(&msgtmp, mm, mm_next);
+		msg_free(mm);
+	}
+	return (-1);
+}
+
+void
+mdns_db_res_freelist(struct mdns_res *mr, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		free(mr[i].mr_ident);
+		free(mr[i].mr_res);
+		free(mr[i].mr_data);
+		if (mr[i].mr_ptr != NULL)
+			free(mr[i].mr_ptr);
+	}
+	free(mr);
+}
+
+static int
+namelist(struct mdns *m, const char *ident, size_t ilen, unsigned int ifidx,
+    struct mdns_name **mnret)
+{
+	int i, mid, error, validres;
+	size_t count, l;
+	char *p;
+	struct mdns_msg *mm, *mm2;
+	struct mdns_name *mn;
+	struct mipc_dbi_name *miin;
+	TAILQ_HEAD(, mdns_msg) msgtmp;
+	struct mipc_dbi_name_list miinl;
+
+	TAILQ_INIT(&msgtmp);
+
+	miinl.miinl_ifidx = ifidx;
+	miinl.miinl_ilen = ilen;
+	mid = docmd(m, MIM_IDENT_NAME_LIST, 2, &miinl,
+	    sizeof(struct mipc_dbi_name_list), ident, ilen);
+	if (mid < 0)
+		goto out;
+
+	count = 0;
+    	validres = 1;
+	do {
+		mm = msg_wait(m, mid, NULL);
+		if (mm == NULL)
+			break;
+		if (mm->mm_msgtype == MIM_IDENT_NAME) {
+			TAILQ_INSERT_TAIL(&msgtmp, mm, mm_next);
+			count++;
+		}
+		else if ((mm->mm_msgtype == MIM_ACK) ||
+		    ((error = errormsg(mm)) >= 0)) {
+			validres = 0;
+			msg_free(mm);
+		}
+	} while (validres);
+
+	if (count == 0) {
+		*mnret = NULL;
+		return (0);
+	}
+
+	mn = malloc(sizeof(struct mdns_name) * count);
+	if (mn == NULL)
+		goto out;
+
+	i = 0;
+	TAILQ_FOREACH_SAFE(mm, &msgtmp, mm_next, mm2) {
+		TAILQ_REMOVE(&msgtmp, mm, mm_next);
+		l = mm->mm_buflen;
+		if (l < sizeof(struct mipc_dbi_name)) {
+			msg_free(mm);
+			continue;
+		}
+
+		miin = (struct mipc_dbi_name *)mm->mm_buf;
+		p = mm->mm_buf + sizeof(struct mipc_dbi_name);
+		l -= sizeof(struct mipc_dbi_name);
+
+		if (l < miin->miin_ilen) {
+			msg_free(mm);
+			continue;
+		}
+		mn[i].mn_ident = malloc(miin->miin_ilen + 1);
+		if (mn[i].mn_ident == NULL)
+			goto out;
+		memcpy(mn[i].mn_ident, p, miin->miin_ilen);
+		mn[i].mn_ident[miin->miin_ilen] = '\0';
+
+		p += miin->miin_ilen;
+		l -= miin->miin_ilen;
+		if (l < (miin->miin_len * sizeof(wchar_t))) {
+			free(mn[i].mn_ident);
+			msg_free(mm);
+			continue;
+		}
+
+		mn[i].mn_name = malloc((miin->miin_len + 1) * sizeof(wchar_t));
+		if (mn[i].mn_name == NULL)
+			goto out;
+		memcpy(mn[i].mn_name, p, miin->miin_len * sizeof(wchar_t));
+		mn[i].mn_name[miin->miin_len] = L'\0';
+
+		p += (miin->miin_len * sizeof(wchar_t));
+		l -= miin->miin_len;
+	
+		if (miin->miin_elen > 0) {
+			if (l < (miin->miin_elen * sizeof(wchar_t))) {
+				free(mn[i].mn_ident);
+				free(mn[i].mn_name);
+				continue;
+			}
+
+			mn[i].mn_ename =
+			    malloc((miin->miin_elen + 1) * sizeof(wchar_t));
+			if (mn[i].mn_ename == NULL)
+				goto out;
+			memcpy(mn[i].mn_ename, p,
+			    miin->miin_elen * sizeof(wchar_t));
+			mn[i].mn_ename[miin->miin_elen] = L'\0';
+		}
+		else {
+			mn[i].mn_ename = NULL;
+		}
+
+		i++;
+		msg_free(mm);
+	}
+
+	*mnret = mn;
+	return (i);
+out:
+	return (-1);
+}
+
+int
+mdns_db_name_list(struct mdns *m, const char *ident, unsigned int ifidx,
+    struct mdns_name **mn)
+{
+	int mid, validres, error;
+	char *p, *id;
+	size_t l, ilen;
+	ssize_t count, tmp, i, j;
+	struct mipc_dbident *mii;
+	struct mdns_msg *mm, *mm2;
+	struct mdns_name *mn2, *mnret;
+	void *ptr;
+	TAILQ_HEAD(, mdns_msg) msgtmp;
+	struct mipc_dbi_list miil;
+
+	if (ifidx == 0)
+		return (-1);
+
+	if (ident != NULL) {
+		ilen = strlen(ident);
+		count = namelist(m, ident, ilen, ifidx, &mn2);
+		*mn = mn2;
+		return (count);
+	}
+
+	miil.miil_ifidx = ifidx;
+	mid = docmd(m, MIM_IDENT_LIST, 1, &miil, sizeof(struct mipc_dbi_list));
+	if (mid < 0)
+		return (-1);
+
+	validres = 1;
+	TAILQ_INIT(&msgtmp);
+	do {
+		mm = msg_wait(m, mid, NULL);
+		if (mm == NULL)
+			break;
+		if (mm->mm_msgtype == MIM_IDENT) {
+			TAILQ_INSERT_TAIL(&msgtmp, mm, mm_next);
+		}
+		else if ((mm->mm_msgtype == MIM_ACK) ||
+		    ((error = errormsg(mm)) >= 0)) {
+			validres = 0;
+			msg_free(mm);
+		}
+	} while (validres);
+
+	mnret = NULL;
+	count = 0;
+	TAILQ_FOREACH_SAFE(mm, &msgtmp, mm_next, mm2) {
+		TAILQ_REMOVE(&msgtmp, mm, mm_next);
+		l = mm->mm_buflen;
+		if (l < sizeof(struct mipc_dbident)) {
+			msg_free(mm);
+			continue;
+		}
+		mii = (struct mipc_dbident *)mm->mm_buf;
+		p = mm->mm_buf + sizeof(struct mipc_dbident);
+		l -= sizeof(struct mipc_dbident);
+
+		if (l < mii->mii_len) {
+			msg_free(mm);
+			continue;
+		}
+
+		id = malloc(mii->mii_len + 1);
+		if (id == NULL)
+			goto out;
+
+		memcpy(id, p, mii->mii_len);
+		id[mii->mii_len] = '\0';
+		
+		tmp = namelist(m, id, mii->mii_len, ifidx, &mn2);
+		if (tmp > 0 && mn2 != NULL) {
+			i = count;
+			count += tmp;
+			ptr = realloc(mnret, sizeof(struct mdns_name) * count);
+			if (ptr == NULL) {
+				for (j = 0; j < tmp; j++) {
+					free(mn2[j].mn_ident);
+					free(mn2[j].mn_name);
+					if (mn2[j].mn_ename != NULL)
+						free(mn2[j].mn_ename);
+				}
+				goto out;
+			}
+			mnret = ptr;
+			for (j = 0; i < count; i++, j++) {
+				memcpy(&mnret[i], &mn2[j],
+				    sizeof(struct mdns_name));
+			}
+		}
+		
+		msg_free(mm);
+	}
+
+	*mn = mnret;
+	return (count);
+out:
+	TAILQ_FOREACH_SAFE(mm, &msgtmp, mm_next, mm2) {
+		TAILQ_REMOVE(&msgtmp, mm, mm_next);
+		msg_free(mm);
+	}
+	if (mnret == NULL)
+		free(mnret);
+	*mn = NULL;
+	return (-1);
+}
+
+void
+mdns_db_name_freelist(struct mdns_name *mn, size_t len)
+{
+	unsigned int i;
+
+	for (i = 0; i < len; i++) {
+		free(mn[i].mn_ident);
+		free(mn[i].mn_name);
+		if (mn[i].mn_ename != NULL)
+			free(mn[i].mn_ename);
+	}
+	free(mn);
+}
+
+int
 mdns_cache_flush(struct mdns *m, unsigned int ifidx)
 {
 	int mid, error;

==== //depot/projects/soc2007/fli-mdns_sd/libmdns/mdns.h#4 (text+ko) ====

@@ -75,6 +75,20 @@
 /* Remove a record name from a resource set */
 int		mdns_db_name_del(struct mdns *, const char *, unsigned int,
     const wchar_t *);
+
+/* Represents a name assigned to an identifer */
+struct mdns_name {
+	char	*mn_ident;	/* Resource identifier */
+	wchar_t	*mn_name;	/* Unexpanded name */
+	wchar_t	*mn_ename;	/* Expanded name, or NULL */
+};
+
+/* List names assigned to one or all resource sets */
+int		mdns_db_name_list(struct mdns *, const char *, unsigned int,
+    struct mdns_name **);
+/* Free name list */
+void		mdns_db_name_freelist(struct mdns_name *, size_t);
+
 /* Add a resource to a resource set */
 int		mdns_db_res_add(struct mdns *, const char *, unsigned int,
     uint16_t, uint16_t, uint32_t, int, const void *);
@@ -86,6 +100,24 @@
 #define MDNS_RES_DEFAULT (0)	/* Default resource type */
 #define MDNS_RES_POINTER (-1)	/* Resource is a resource set pointer */
 
+/* Resource assigned to an identifier */
+struct mdns_res {
+	char		*mr_ident;	/* Resource identifier */
+	wchar_t		*mr_res;	/* Unexpanded resource */
+	char		*mr_ptr;	/* Pointer resource, or NULL */
+	uint32_t	mr_ttl;		/* TTL (seconds) */
+	uint16_t	mr_class;	/* mDNS class */
+	uint16_t	mr_type;	/* mDNS type */
+	char		*mr_data;
+	size_t		mr_len;
+};
+
+/* List resources assigned to an identifier */
+int		mdns_db_res_list(struct mdns *, const char *, unsigned int,
+    struct mdns_res **);
+/* Free resource list */
+void		mdns_db_res_freelist(struct mdns_res *, size_t);
+
 /* Cache entry */
 struct mdns_cache {
 	uint32_t		mc_ttl_left;


More information about the p4-projects mailing list