DNSServiceErrorType DNSSD_API DNSServiceConstructFullName ( char *const fullName, const char *const service, // May be NULL const char *const regtype, const char *const domain ) { const int len = !regtype ? 0 : mDNSPlatformStrLen(regtype) - DomainEndsInDot(regtype); char *fn = fullName; char *const lim = fullName + 1005; const char *s = service; const char *r = regtype; const char *d = domain; // regtype must be at least "x._udp" or "x._tcp" if (len < 6 || !domain || !domain[0]) return kDNSServiceErr_BadParam; if (!strCaseEqual((regtype + len - 4), "_tcp", 4) && !strCaseEqual((regtype + len - 4), "_udp", 4)) return kDNSServiceErr_BadParam; if (service && *service) { while (*s) { unsigned char c = *s++; // Needs to be unsigned, or values like 0xFF will be interpreted as < 32 if (c <= ' ') // Escape non-printable characters { if (fn+4 >= lim) goto fail; *fn++ = '\\'; *fn++ = '0' + (c / 100); *fn++ = '0' + (c / 10) % 10; c = '0' + (c ) % 10; } else if (c == '.' || (c == '\\')) // Escape dot and backslash literals { if (fn+2 >= lim) goto fail; *fn++ = '\\'; } else if (fn+1 >= lim) goto fail; *fn++ = (char)c; } *fn++ = '.'; } while (*r) if (fn+1 >= lim) goto fail; else *fn++ = *r++; if (!DomainEndsInDot(regtype)) { if (fn+1 >= lim) goto fail; else *fn++ = '.'; } while (*d) if (fn+1 >= lim) goto fail; else *fn++ = *d++; if (!DomainEndsInDot(domain)) { if (fn+1 >= lim) goto fail; else *fn++ = '.'; } *fn = '\0'; return kDNSServiceErr_NoError; fail: *fn = '\0'; return kDNSServiceErr_BadParam; }
int DNSSD_API DNSServiceConstructFullName ( char *fullName, const char *service, /* may be NULL */ const char *regtype, const char *domain ) { unsigned long len; unsigned char c; char *fn = fullName; const char *s = service; const char *r = regtype; const char *d = domain; if (service) { while(*s) { c = (unsigned char)*s++; if (c == '.' || (c == '\\')) *fn++ = '\\'; // escape dot and backslash literals else if (c <= ' ') // escape non-printable characters { *fn++ = '\\'; *fn++ = (char) ('0' + (c / 100)); *fn++ = (char) ('0' + (c / 10) % 10); c = (unsigned char)('0' + (c % 10)); } *fn++ = (char)c; } *fn++ = '.'; } if (!regtype) return -1; len = (unsigned long) strlen(regtype); if (DomainEndsInDot(regtype)) len--; if (len < 6) return -1; // regtype must be at least "x._udp" or "x._tcp" if (strncmp((regtype + len - 4), "_tcp", 4) && strncmp((regtype + len - 4), "_udp", 4)) return -1; while(*r) *fn++ = *r++; if (!DomainEndsInDot(regtype)) *fn++ = '.'; if (!domain || !domain[0]) return -1; while(*d) *fn++ = *d++; if (!DomainEndsInDot(domain)) *fn++ = '.'; *fn = '\0'; return 0; }