static mStatus RegisterOurServices(void) { mStatus status; status = mStatus_NoError; if (gServiceName[0] != 0) { status = RegisterOneService(gServiceName, gServiceType, gServiceDomain, gServiceText, gServiceTextLen, gPortNumber); } if (status == mStatus_NoError && gServiceFile[0] != 0) { status = RegisterServicesInFile(gServiceFile); } return status; }
/* * rend_callback * * This is borrowed from the OSX rend client */ void rend_callback(void) { REND_MESSAGE msg; int result; int err; mDNSInterfaceID id; DPRINTF(E_DBG,L_REND,"Processing rendezvous message\n"); /* here, we've seen the message, now we have to process it */ if((result=rend_read_message(&msg)) != sizeof(msg)) { err=errno; DPRINTF(E_FATAL,L_REND,"Rendezvous socket closed (daap server crashed?) Aborting.\n"); gStopNow=mDNStrue; return; } switch(msg.cmd) { case REND_MSG_TYPE_REGISTER: id=rend_get_interface_id(msg.iface); DPRINTF(E_DBG,L_REND,"Registering %s.%s (%d)\n",msg.name,msg.type,msg.port); RegisterOneService(msg.name,msg.type,"local.",msg.txt,strlen(msg.txt), msg.port,id); rend_send_response(0); /* success */ break; case REND_MSG_TYPE_UNREGISTER: rend_send_response(1); /* error */ break; case REND_MSG_TYPE_STOP: DPRINTF(E_INF,L_REND,"Stopping mDNS\n"); gStopNow = mDNStrue; rend_send_response(0); break; case REND_MSG_TYPE_STATUS: rend_send_response(1); break; default: break; } }
static mStatus RegisterServicesInFile(const char *filePath) { mStatus status = mStatus_NoError; FILE * fp = fopen(filePath, "r"); int junk; if (fp == NULL) { status = mStatus_UnknownErr; } if (status == mStatus_NoError) { mDNSBool good = mDNStrue; do { int ch; char name[256]; char type[256]; const char *dom = kDefaultServiceDomain; char rawText[1024]; mDNSu8 text[sizeof(RDataBody)]; unsigned int textLen = 0; char port[256]; // Skip over any blank lines. do ch = fgetc(fp); while ( ch == '\n' || ch == '\r' ); if (ch != EOF) good = (ungetc(ch, fp) == ch); // Read three lines, check them for validity, and register the service. good = ReadALine(name, sizeof(name), fp); if (good) { good = ReadALine(type, sizeof(type), fp); } if (good) { char *p = type; while (*p && *p != ' ') p++; if (*p) { *p = 0; dom = p+1; } } if (good) { good = ReadALine(port, sizeof(port), fp); } if (good) { good = CheckThatRichTextNameIsUsable(name, mDNSfalse) && CheckThatServiceTypeIsUsable(type, mDNSfalse) && CheckThatPortNumberIsUsable(atol(port), mDNSfalse); } if (good) { while (1) { int len; if (!ReadALine(rawText, sizeof(rawText), fp)) break; len = strlen(rawText); if (len <= 255) { unsigned int newlen = textLen + 1 + len; if (len == 0 || newlen >= sizeof(text)) break; text[textLen] = len; memcpy(text + textLen + 1, rawText, len); textLen = newlen; } else fprintf(stderr, "%s: TXT attribute too long for name = %s, type = %s, port = %s\n", gProgramName, name, type, port); } } if (good) { status = RegisterOneService(name, type, dom, text, textLen, atol(port)); if (status != mStatus_NoError) { fprintf(stderr, "%s: Failed to register service, name = %s, type = %s, port = %s\n", gProgramName, name, type, port); status = mStatus_NoError; // keep reading } } } while (good && !feof(fp)); if ( ! good ) { fprintf(stderr, "%s: Error reading service file %s\n", gProgramName, filePath); } } if (fp != NULL) { junk = fclose(fp); assert(junk == 0); } return status; }