void my_cleanup(void) { if (item1) release_thing(item1); if (item2) release_thing(item2); if (stuff_ok) unregister_stuff(); return; }
/* * Tries to shutdown this loop impl. * Call this function from inside this thread. */ int md_zeroconf_unregister() { unregister_stuff(); return 0; }
/* * This function tries to register the AFP DNS * SRV service type. */ static void register_stuff(const AFPObj *obj) { uint port; const struct vol *volume; char name[MAXINSTANCENAMELEN+1]; DNSServiceErrorType error; TXTRecordRef txt_adisk; TXTRecordRef txt_devinfo; char tmpname[256]; // If we had already registered, then we will unregister and re-register if(svc_refs) unregister_stuff(); /* Register our service, prepare the TXT record */ TXTRecordCreate(&txt_adisk, 0, NULL); if( 0 > TXTRecordPrintf(&txt_adisk, "sys", "waMa=0,adVF=0x100") ) { LOG ( log_error, logtype_afpd, "Could not create Zeroconf TXTRecord for sys"); goto fail; } /* Build AFP volumes list */ int i = 0; for (volume = getvolumes(); volume; volume = volume->v_next) { if (convert_string(CH_UCS2, CH_UTF8_MAC, volume->v_u8mname, -1, tmpname, 255) <= 0) { LOG ( log_error, logtype_afpd, "Could not set Zeroconf volume name for TimeMachine"); goto fail; } if (volume->v_flags & AFPVOL_TM) { if (volume->v_uuid) { LOG(log_info, logtype_afpd, "Registering volume '%s' with UUID: '%s' for TimeMachine", volume->v_localname, volume->v_uuid); if( 0 > TXTRecordKeyPrintf(&txt_adisk, "dk%u", i++, "adVN=%s,adVF=0xa1,adVU=%s", tmpname, volume->v_uuid) ) { LOG ( log_error, logtype_afpd, "Could not set Zeroconf TXTRecord for dk%u", i); goto fail; } } else { LOG(log_warning, logtype_afpd, "Registering volume '%s' for TimeMachine. But UUID is invalid.", volume->v_localname); if( 0 > TXTRecordKeyPrintf(&txt_adisk, "dk%u", i++, "adVN=%s,adVF=0xa1", tmpname) ) { LOG ( log_error, logtype_afpd, "Could not set Zeroconf TXTRecord for dk%u", i); goto fail; } } } } /* AFP_DNS_SERVICE_TYPE */ svc_ref_count = 1; if (i) { /* ADISK_SERVICE_TYPE */ svc_ref_count++; } if (obj->options.mimicmodel) { /* DEV_INFO_SERVICE_TYPE */ svc_ref_count++; } // Allocate the memory to store our service refs svc_refs = calloc(svc_ref_count, sizeof(DNSServiceRef)); assert(svc_refs); svc_ref_count = 0; port = atoi(obj->options.port); if (convert_string(obj->options.unixcharset, CH_UTF8, obj->options.hostname, -1, name, MAXINSTANCENAMELEN) <= 0) { LOG(log_error, logtype_afpd, "Could not set Zeroconf instance name"); goto fail; } error = DNSServiceRegister(&svc_refs[svc_ref_count++], 0, // no flags 0, // all network interfaces name, AFP_DNS_SERVICE_TYPE, "", // default domains NULL, // default host name htons(port), 0, // length of TXT NULL, // no TXT RegisterReply, // callback NULL); // no context if (error != kDNSServiceErr_NoError) { LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d", AFP_DNS_SERVICE_TYPE, error); goto fail; } if (i) { error = DNSServiceRegister(&svc_refs[svc_ref_count++], 0, // no flags 0, // all network interfaces name, ADISK_SERVICE_TYPE, "", // default domains NULL, // default host name htons(port), TXTRecordGetLength(&txt_adisk), TXTRecordGetBytesPtr(&txt_adisk), RegisterReply, // callback NULL); // no context if (error != kDNSServiceErr_NoError) { LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d", ADISK_SERVICE_TYPE, error); goto fail; } } if (obj->options.mimicmodel) { LOG(log_info, logtype_afpd, "Registering server as model '%s'", obj->options.mimicmodel); TXTRecordCreate(&txt_devinfo, 0, NULL); if ( 0 > TXTRecordPrintf(&txt_devinfo, "model", obj->options.mimicmodel) ) { LOG ( log_error, logtype_afpd, "Could not create Zeroconf TXTRecord for model"); goto fail; } error = DNSServiceRegister(&svc_refs[svc_ref_count++], 0, // no flags 0, // all network interfaces name, DEV_INFO_SERVICE_TYPE, "", // default domains NULL, // default host name /* * We would probably use port 0 zero, but we can't, from man DNSServiceRegister: * "A value of 0 for a port is passed to register placeholder services. * Place holder services are not found when browsing, but other * clients cannot register with the same name as the placeholder service." * We therefor use port 9 which is used by the adisk service type. */ htons(9), TXTRecordGetLength(&txt_devinfo), TXTRecordGetBytesPtr(&txt_devinfo), RegisterReply, // callback NULL); // no context TXTRecordDeallocate(&txt_devinfo); if (error != kDNSServiceErr_NoError) { LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d", DEV_INFO_SERVICE_TYPE, error); goto fail; } } /* if (config->obj.options.mimicmodel) */ /* * Now we can create the thread that will poll for the results * and handle the calling of the callbacks */ if(pthread_create(&poller, NULL, polling_thread, NULL) != 0) { LOG(log_error, logtype_afpd, "Unable to start mDNS polling thread"); goto fail; } fail: TXTRecordDeallocate(&txt_adisk); return; }