From owner-p4-projects@FreeBSD.ORG Mon Aug 20 17:33:26 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 070B416A41A; Mon, 20 Aug 2007 17:33:26 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AF2BD16A418 for ; Mon, 20 Aug 2007 17:33:25 +0000 (UTC) (envelope-from fli@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 9DE4E13C4A6 for ; Mon, 20 Aug 2007 17:33:25 +0000 (UTC) (envelope-from fli@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l7KHXPB5058418 for ; Mon, 20 Aug 2007 17:33:25 GMT (envelope-from fli@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l7KHXPjQ058409 for perforce@freebsd.org; Mon, 20 Aug 2007 17:33:25 GMT (envelope-from fli@FreeBSD.org) Date: Mon, 20 Aug 2007 17:33:25 GMT Message-Id: <200708201733.l7KHXPjQ058409@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to fli@FreeBSD.org using -f From: Fredrik Lindberg To: Perforce Change Reviews Cc: Subject: PERFORCE change 125439 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Aug 2007 17:33:26 -0000 http://perforce.freebsd.org/chv.cgi?CH=125439 Change 125439 by fli@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;