1 /* vi:ai:et:ts=8 sw=2
2 */
3 /*
4 * wzdftpd - a modular and cool ftp server
5 * Copyright (C) 2002-2006 Pierre Chifflier
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * As a special exemption, Pierre Chifflier
22 * and other respective copyright holders give permission to link this program
23 * with OpenSSL, and distribute the resulting executable, without including
24 * the source code for OpenSSL in the source distribution.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #ifdef USE_BONJOUR
32
33 #include "libwzd_bonjour.h"
34
35 DNSServiceRef publish_session = NULL;
36
37 #ifdef WIN32
38 static void DNSSD_API
39 #else
40 static void
41 #endif
publish_reply(DNSServiceRef sdRef,const DNSServiceFlags flags,DNSServiceErrorType errorCode,const char * name,const char * regtype,const char * domain,void * context)42 publish_reply (DNSServiceRef sdRef,
43 const DNSServiceFlags flags,
44 DNSServiceErrorType errorCode,
45 const char *name,
46 const char *regtype,
47 const char *domain,
48 void *context)
49 {
50 }
51
bo_zeroconf_setup(unsigned long port,const char * name,const char * username,const char * password,const char * path)52 void* bo_zeroconf_setup(unsigned long port,
53 const char *name,
54 const char *username,
55 const char *password,
56 const char *path) {
57 DNSServiceErrorType err;
58 #ifdef HAVE_OSX_TIGER
59 TXTRecordRef txtRecord;
60 #endif
61 char service[256] = "WZDFTP Server on ";
62
63 /* Prepare service name */
64 if (!name) {
65 out_log(LEVEL_INFO, "Assigning default service name.\n");
66 gethostname(service+17, sizeof(service)-18);
67 service[sizeof(service)-1] = 0;
68
69 name = strdup(service);
70 }
71
72 if (!name) return NULL;
73 if (!port) return NULL;
74
75 #ifdef HAVE_OSX_TIGER
76 /* prepare text records */
77 TXTRecordCreate(&txtRecord, 0, 0);
78
79 /* assign TXT keys if any */
80 if (username) {
81 if (TXTRecordSetValue(&text_record,
82 "u",
83 8,
84 username) != kDNSServiceErr_NoError) {
85 out_log(LEVEL_CRITICAL, "Adding TXT record %s=%s failed\n", "u", username);
86
87 TXTRecordDeallocate(&txt_record);
88 bo_zeroconf_unregister();
89 }
90 else {
91 txt_rec_len++;
92 }
93 }
94 if (password) {
95 if (TXTRecordSetValue(&text_record,
96 "p",
97 8,
98 password) != kDNSServiceErr_NoError) {
99 out_log(LEVEL_CRITICAL, "Adding TXT record %s=%s failed\n", "p", password);
100
101 TXTRecordDeallocate(&txt_record);
102 bo_zeroconf_unregister();
103 }
104 else {
105 txt_rec_len++;
106 }
107 }
108 if (path) {
109 if (TXTRecordSetValue(&text_record
110 "path",
111 4,
112 path) != kDNSServiceErr_NoError) {
113 out_log(LEVEL_CRITICAL, "Adding TXT record %s=%s failed\n", "path", path);
114
115 TXTRecordDeallocate(&txt_record);
116 bo_zeroconf_unregister();
117 }
118 else {
119 txt_rec_len++;
120 }
121 }
122 #else
123 out_log(LEVEL_INFO,
124 "You did provide certain TXT keys.\n"
125 "Unfortunatly this particular OSX version is not able to publish TXT keys.\n");
126 #endif
127
128 err = DNSServiceRegister (&publish_session,
129 0, /* flags */
130 0, /* interface; 0 for all */
131 name, /* name */
132 FTP_DNS_SERVICE_TYPE, /* type */
133 NULL, /* domain */
134 NULL, /* hostname */
135 htons (port), /* port in network byte order */
136 #ifdef HAVE_OSX_TIGER
137 TXTRecordGetLength(&txt), /* text record length */
138 TXTRecordGetBytesPtr(&txt), /* text record */
139 #else
140 0,
141 NULL,
142 #endif
143 publish_reply, /* callback */
144 NULL); /* context */
145
146 #ifdef HAVE_OSX_TIGER
147 TXTRecordDeallocate(&txt_record);
148 #endif
149
150 if (err == kDNSServiceErr_NoError) {
151 out_log(LEVEL_INFO, "Adding service '%s'\n", name);
152 } else {
153 out_log(LEVEL_CRITICAL, "Adding service '%s' failed\n", name);
154 bo_zeroconf_unregister();
155 }
156 }
157
bo_zeroconf_run(void)158 int bo_zeroconf_run(void) {
159 fd_set set;
160 int fd;
161 struct timeval timeout;
162
163 /* Initialize the file descriptor set. */
164 FD_ZERO (&set);
165 FD_SET (fd, &set);
166
167 /* Initialize the timeout data structure. */
168 /* TODO: Should the value for sec be configurable? */
169 timeout.tv_sec = 10;
170 timeout.tv_usec = 0;
171
172 if (publish_session != NULL) {
173 fd = DNSServiceRefSockFD(publish_session);
174
175 if (select(FD_SETSIZE,
176 &set, NULL, NULL,
177 &timeout) > 0) {
178 DNSServiceProcessResult(publish_session);
179 }
180 }
181
182 return 0;
183 }
184
bo_zeroconf_unregister(void)185 int bo_zeroconf_unregister(void) {
186 if (publish_session != NULL) {
187 DNSServiceRefDeallocate(publish_session);
188 publish_session = NULL;
189 }
190
191 return 0;
192 }
193
194 #endif /* USE_BONJOUR */
195