void SBCFromTXT(CPhidgetSBCHandle sbc, uint16_t txtLen, const char *txtRecord) { char *hversion = NULL, *txtver = NULL; uint8_t valLen = 0; const char *valPtr = NULL; //txt version if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "txtvers", &valLen))) return; if(!(txtver = malloc(valLen+1))) return; ZEROMEM(txtver, valLen+1); memcpy(txtver, valPtr, valLen); sbc->txtver = (short)strtol(txtver, NULL, 10); free(txtver); //Firmware version if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "fversion", &valLen))) return; if(valLen > 12) valLen = 12; memcpy(sbc->fversion, valPtr, valLen); sbc->fversion[valLen] = '\0'; //Hardware version if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "hversion", &valLen))) return; if(!(hversion = malloc(valLen+1))) return; ZEROMEM(hversion, valLen+1); memcpy(hversion, valPtr, valLen); sbc->hversion = (short)strtol(hversion, NULL, 10); free(hversion); // things added in version 2 of the txt if(sbc->txtver >= 2) { //Hostname if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "hostname", &valLen))) return; if(valLen > 128) valLen = 128; memcpy(sbc->hostname, valPtr, valLen); sbc->hostname[valLen] = '\0'; } // things added in version 3 of the txt if(sbc->txtver >= 3) { //Device Name if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "name", &valLen))) return; if(valLen > 128) valLen = 128; memcpy(sbc->deviceName, valPtr, valLen); sbc->deviceName[valLen] = '\0'; } else { sprintf(sbc->deviceName, "PhidgetSBC"); } }
STDMETHODIMP CTXTRecord::GetValueForKey(BSTR key, VARIANT* value) { std::string keyUTF8; const void * rawValue; uint8_t rawValueLen; BOOL ok = TRUE; HRESULT hr = S_OK; VariantClear( value ); if ( m_byteArray.size() > 0 ) { ok = BSTRToUTF8( key, keyUTF8 ); require_action( ok, exit, hr = S_FALSE ); rawValue = TXTRecordGetValuePtr( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str(), &rawValueLen ); if ( rawValue ) { ok = ByteArrayToVariant( rawValue, rawValueLen, value ); require_action( ok, exit, hr = S_FALSE ); } } exit: return hr; }
void resolveCB(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const char *txtRecord, void *context) { player_sd_dev_t* sddev = (player_sd_dev_t*)context; const char* value; uint8_t value_len; char* colon; char buf[PLAYER_SD_TXT_MAXLEN]; // Handle resolution result if(errorCode == kDNSServiceErr_NoError) { // Fill in the address info memset(sddev->hostname,0,sizeof(sddev->hostname)); strncpy(sddev->hostname,hosttarget,sizeof(sddev->hostname)-1); sddev->robot = port; if(!(value = (const char*)TXTRecordGetValuePtr(txtLen, txtRecord, PLAYER_SD_DEVICE_TXTNAME, &value_len))) { PLAYER_ERROR1("Failed to find TXT info for service %s\n", sddev->name); sddev->addr_fail = 1; return; } if(!(colon = strchr(value,':')) || ((colon-value) <= 0) || ((value_len - (colon-value+1)) <= 0)) { PLAYER_ERROR2("Failed to parse TXT info \"%s\" for service %s\n", value, sddev->name); sddev->addr_fail = 1; return; } memset(buf,0,sizeof(buf)); strncpy(buf,value,(colon-value)); sddev->interf = str_to_interf(buf); memset(buf,0,sizeof(buf)); strncpy(buf,colon+1,(value_len-(colon-value+1))); sddev->index = atoi(buf); sddev->addr_valid = 1; } else { // Something went wrong. sddev->addr_fail = 1; } }
OSStatus CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_t inTXTSize, const char * inTXT ) { check( service ); check( q ); // <rdar://problem/3946587> Use TXTRecord APIs declared in dns_sd.h bool qtotalDefined = false; const void * val; char buf[256]; uint8_t len; OSStatus err = kNoErr; // <rdar://problem/3987680> Default to queue "lp" q->name = L"lp"; // <rdar://problem/4003710> Default pdl key to be "application/postscript" q->pdl = L"application/postscript"; if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "rp", &len ) ) != NULL ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; err = UTF8StringToStringObject( buf, q->name ); require_noerr( err, exit ); } if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "pdl", &len ) ) != NULL ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; err = UTF8StringToStringObject( buf, q->pdl ); require_noerr( err, exit ); } if ( ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "usb_mfg", &len ) ) != NULL ) || ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "usb_manufacturer", &len ) ) != NULL ) ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; err = UTF8StringToStringObject( buf, q->usb_MFG ); require_noerr( err, exit ); } if ( ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "usb_mdl", &len ) ) != NULL ) || ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "usb_model", &len ) ) != NULL ) ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; err = UTF8StringToStringObject( buf, q->usb_MDL ); require_noerr( err, exit ); } if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "ty", &len ) ) != NULL ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; err = UTF8StringToStringObject( buf, q->description ); require_noerr( err, exit ); } if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "product", &len ) ) != NULL ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; err = UTF8StringToStringObject( buf, q->product ); require_noerr( err, exit ); } if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "note", &len ) ) != NULL ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; err = UTF8StringToStringObject( buf, q->location ); require_noerr( err, exit ); } if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "qtotal", &len ) ) != NULL ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; service->qtotal = (unsigned short) atoi( buf ); qtotalDefined = true; } if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "priority", &len ) ) != NULL ) { // Stringize val ( doesn't have trailing '\0' yet ) memcpy( buf, val, len ); buf[len] = '\0'; q->priority = atoi( buf ); } // <rdar://problem/4124524> Was this printer discovered via OS X Printer Sharing? if ( TXTRecordContainsKey( inTXTSize, inTXT, "printer-state" ) || TXTRecordContainsKey( inTXTSize, inTXT, "printer-type" ) ) { service->printer->isSharedFromOSX = true; } exit: // The following code is to fix a problem with older HP // printers that don't include "qtotal" in their text // record. We'll check to see if the q->name is "TEXT" // and if so, we're going to modify it to be "lp" so // that we don't use the wrong queue if ( !err && !qtotalDefined && ( q->name == L"TEXT" ) ) { q->name = "lp"; } return err; }
static void resolve_callback( DNSServiceRef sdRef, /* I - Service reference */ DNSServiceFlags flags, /* I - Data flags */ uint32_t interfaceIndex, /* I - Interface */ DNSServiceErrorType errorCode, /* I - Error, if any */ const char *fullName, /* I - Full service name */ const char *hostTarget, /* I - Hostname */ uint16_t port, /* I - Port number (network byte order) */ uint16_t txtLen, /* I - Length of TXT record data */ const unsigned char *txtRecord, /* I - TXT record data */ void *context) /* I - Device */ { char temp[257], /* TXT key value */ uri[1024]; /* Printer URI */ const void *value; /* Value from TXT record */ uint8_t valueLen; /* Length of value */ cups_device_t *device = (cups_device_t *)context; /* Device */ #ifdef DEBUG fprintf(stderr, "\rresolve_callback(sdRef=%p, flags=%x, " "interfaceIndex=%d, errorCode=%d, fullName=\"%s\", " "hostTarget=\"%s\", port=%d, txtLen=%u, txtRecord=%p, " "context=%p)\n", sdRef, flags, interfaceIndex, errorCode, fullName ? fullName : "(null)", hostTarget ? hostTarget : "(null)", ntohs(port), txtLen, txtRecord, context); #endif /* DEBUG */ /* * Only process "add" data... */ if (errorCode != kDNSServiceErr_NoError) return; device->got_resolve = 1; device->host = strdup(hostTarget); device->port = ntohs(port); /* * Extract the "remote printer" key from the TXT record and save the URI... */ if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "rp", &valueLen)) != NULL) { if (((char *)value)[0] == '/') { /* * "rp" value (incorrectly) has a leading slash already... */ memcpy(temp, value, valueLen); temp[valueLen] = '\0'; } else { /* * Convert to resource by concatenating with a leading "/"... */ temp[0] = '/'; memcpy(temp + 1, value, valueLen); temp[valueLen + 1] = '\0'; } } else { /* * Default "rp" value is blank, mapping to a path of "/"... */ temp[0] = '/'; temp[1] = '\0'; } if (!strncmp(temp, "/printers/", 10)) device->cups_shared = -1; httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, hostTarget, ntohs(port), temp); device->uri = strdup(uri); device->rp = strdup(temp); if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "ty", &valueLen)) != NULL) { memcpy(temp, value, valueLen); temp[valueLen] = '\0'; device->ty = strdup(temp); } if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "pdl", &valueLen)) != NULL) { memcpy(temp, value, valueLen); temp[valueLen] = '\0'; device->pdl = strdup(temp); } if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "printer-type", &valueLen)) != NULL) device->cups_shared = 1; if (device->cups_shared) fprintf(stderr, "\rIgnoring CUPS printer %s\n", uri); else fprintf(stderr, "\rFound IPP printer %s\n", uri); progress(); }
LONG ExplorerBarWindow::OnResolve( ResolveInfo * resolve ) { CString url; uint8_t * path; uint8_t pathSize; char * pathPrefix; CString username; CString password; check( resolve ); // Get login info if needed. if( resolve->handler->needsLogin ) { LoginDialog dialog; if( !dialog.GetLogin( username, password ) ) { goto exit; } } // If the HTTP TXT record is a "path=" entry, use it as the resource path. Otherwise, use "/". pathPrefix = ""; if( strcmp( resolve->handler->type, "_http._tcp" ) == 0 ) { uint8_t * txtData; uint16_t txtLen; resolve->txt.GetData( &txtData, &txtLen ); path = (uint8_t*) TXTRecordGetValuePtr(txtLen, txtData, kTXTRecordKeyPath, &pathSize); if (path == NULL) { path = (uint8_t*) ""; pathSize = 1; } } else { path = (uint8_t *) ""; pathSize = 1; } // Build the URL in the following format: // // <urlScheme>[<username>[:<password>]@]<name/ip>[<path>] url.AppendFormat( TEXT( "%S" ), resolve->handler->urlScheme ); // URL Scheme if( username.GetLength() > 0 ) { url.AppendFormat( TEXT( "%s" ), username ); // Username if( password.GetLength() > 0 ) { url.AppendFormat( TEXT( ":%s" ), password ); // Password } url.AppendFormat( TEXT( "@" ) ); } url += resolve->host; // Host url.AppendFormat( TEXT( ":%d" ), resolve->port ); // :Port url.AppendFormat( TEXT( "%S" ), pathPrefix ); // Path Prefix ("/" or empty). url.AppendFormat( TEXT( "%.*S" ), (int) pathSize, (char *) path ); // Path (possibly empty). // Tell Internet Explorer to go to the URL. check( mOwner ); mOwner->GoToURL( url ); exit: delete resolve; return( 0 ); }
void PhidFromTXT(CPhidgetHandle phid, uint16_t txtLen, const char *txtRecord) { int i = 0; short txtver; uint8_t valLen = 0; const char *valPtr = NULL; //txt version if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "txtvers", &valLen))) return; txtver = (short)strtol(valPtr, NULL, 10); //Serial Number if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "serial", &valLen))) return; phid->serialNumber = strtol(valPtr, NULL, 10); phid->specificDevice = PTRUE; //version if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "version", &valLen))) return; phid->deviceVersion = strtol(valPtr, NULL, 10); //label if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "label", &valLen))) return; if(valLen > 10) valLen = 10; memcpy(phid->label, valPtr, valLen); phid->label[valLen] = '\0'; //server_id if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "server_id", &valLen))) return; free(phid->networkInfo->zeroconf_server_id); if(!(phid->networkInfo->zeroconf_server_id = malloc(valLen+1))) return; ZEROMEM(phid->networkInfo->zeroconf_server_id, valLen+1); memcpy(phid->networkInfo->zeroconf_server_id, valPtr, valLen); // things added in version 2 of the txt if(txtver >= 2) { //Device ID if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "id", &valLen))) return; phid->deviceIDSpec = strtol(valPtr, NULL, 10); for(i = 1;i<PHIDGET_DEVICE_COUNT;i++) if(phid->deviceIDSpec == Phid_Device_Def[i].pdd_sdid) break; phid->deviceDef = &Phid_Device_Def[i]; phid->attr = Phid_Device_Def[i].pdd_attr; //Device Class if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "class", &valLen))) return; phid->deviceID = strtol(valPtr, NULL, 10); phid->deviceType = Phid_DeviceName[phid->deviceID]; } //Old version uses string searching, but some devices have the same name with different IDs else { char *name = NULL; char *type = NULL; //name if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "name", &valLen))) return; if(!(name = malloc(valLen+1))) return; ZEROMEM(name, valLen+1); memcpy(name, valPtr, valLen); for(i = 0;i<PHIDGET_DEVICE_COUNT;i++) { if(!strcmp(name, Phid_Device_Def[i].pdd_name)) { phid->deviceIDSpec = Phid_Device_Def[i].pdd_sdid; phid->deviceDef = &Phid_Device_Def[i]; phid->attr = Phid_Device_Def[i].pdd_attr; break; } } free(name); //type if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "type", &valLen))) return; if(!(type = malloc(valLen+1))) return; ZEROMEM(type, valLen+1); memcpy(type, valPtr, valLen); phid->deviceID = phidget_type_to_id(type); phid->deviceType = Phid_DeviceName[phid->deviceID]; free(type); } phid->networkInfo->mdns = PTRUE; }
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { const char *r; TXTRecordRef ref; uint8_t l; const void *p; char k[256]; TXTRecordCreate(&ref, 0, NULL); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "foo", 7, "lennart"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "waldo", 5, "rocks"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "quux", 9, "the_house"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "yeah", 0, NULL); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "waldo", 6, "rocked"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordRemoveValue(&ref, "foo"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordRemoveValue(&ref, "waldo"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "kawumm", 6, "bloerb"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "one", 1, "1"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "two", 1, "2"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); TXTRecordSetValue(&ref, "three", 1, "3"); hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref)); assert(TXTRecordContainsKey(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "two")); assert(!TXTRecordContainsKey(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "four")); r = TXTRecordGetValuePtr(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "kawumm", &l); hexdump(r, l); assert(TXTRecordGetCount(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref)) == 6); TXTRecordGetItemAtIndex(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), 2, sizeof(k), k, &l, &p); fprintf(stderr, "key=<%s>\n", k); hexdump(p, l); assert(TXTRecordGetItemAtIndex(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), 20, sizeof(k), k, &l, &p) == kDNSServiceErr_Invalid); TXTRecordDeallocate(&ref); }
void PhidFromTXT(CPhidgetHandle phid, uint16_t txtLen, const char *txtRecord) { int i = 0; char *type = NULL; char *serial = NULL; char *version = NULL; char *name = NULL; uint8_t valLen = 0; const char *valPtr = NULL; //Serial Number if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "serial", &valLen))) return; if(!(serial = malloc(valLen+1))) return; ZEROMEM(serial, valLen+1); memcpy(serial, valPtr, valLen); phid->serialNumber = strtol(serial, NULL, 10); phid->specificDevice = PTRUE; free(serial); //name if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "name", &valLen))) return; if(!(name = malloc(valLen+1))) return; ZEROMEM(name, valLen+1); memcpy(name, valPtr, valLen); for(i = 0;i<PHIDGET_DEVICE_COUNT;i++) { if(!strcmp(name, Phid_DeviceSpecificName[i])) { phid->deviceIDSpec = i; phid->attr = Phid_Device_Def[i].pdd_attr; break; } } free(name); //type if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "type", &valLen))) return; if(!(type = malloc(valLen+1))) return; ZEROMEM(type, valLen+1); memcpy(type, valPtr, valLen); phid->deviceID = phidget_type_to_id(type); phid->deviceType = Phid_DeviceName[phid->deviceID]; free(type); //version if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "version", &valLen))) return; if(!(version = malloc(valLen+1))) return; ZEROMEM(version, valLen+1); memcpy(version, valPtr, valLen); phid->deviceVersion = strtol(version, NULL, 10); free(version); //label if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "label", &valLen))) return; if(valLen > 10) valLen = 10; memcpy(phid->label, valPtr, valLen); phid->label[valLen] = '\0'; //server_id if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "server_id", &valLen))) return; if(!(phid->networkInfo->zeroconf_server_id = malloc(valLen+1))) return; ZEROMEM(phid->networkInfo->zeroconf_server_id, valLen+1); memcpy(phid->networkInfo->zeroconf_server_id, valPtr, valLen); phid->networkInfo->mdns = PTRUE; }