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