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_HOWL
32 
33 #include "libwzd_howl.h"
34 
35 sw_discovery discovery = NULL;
36 
publish_reply(sw_discovery discovery,sw_discovery_oid oid,sw_discovery_publish_status status,sw_opaque extra)37 static sw_result HOWL_API publish_reply(sw_discovery discovery,
38                                         sw_discovery_oid oid,
39                                         sw_discovery_publish_status status,
40                                         sw_opaque extra) {
41   static sw_string
42     status_text[] =
43     {
44       "Started",
45       "Stopped",
46       "Name Collision",
47       "Invalid"
48     };
49 
50   out_log(LEVEL_INFO, "publish reply: %s\n", status_text[status]);
51   return SW_OKAY;
52 }
53 
ho_zeroconf_setup(unsigned long port,const char * name,const char * username,const char * password,const char * path)54 void* ho_zeroconf_setup(unsigned long port,
55                         const char *name,
56                         const char *username,
57                         const char *password,
58                         const char *path) {
59   sw_result result;
60   sw_discovery_publish_id id;
61   sw_text_record text_record;
62   int txt_rec_len = 0;
63   char service[256] = "WZDFTP Server on ";
64 
65   if (sw_discovery_init (&discovery) != SW_OKAY) {
66     out_log(LEVEL_CRITICAL,
67            "WZDFTPD could not be started. \nTry running mDNSResponder.");
68     return;
69   }
70 
71   /* Prepare service name */
72   if (!name) {
73     out_log(LEVEL_INFO, "Assigning default service name.\n");
74     gethostname(service+17, sizeof(service)-18);
75     service[sizeof(service)-1] = 0;
76 
77     name = strdup(service);
78   }
79 
80   if (!name) return;
81 
82   /* prepare text records */
83   if (sw_text_record_init(&text_record) != SW_OKAY) {
84     out_log(LEVEL_CRITICAL, "Initializing TXT data structure failed\n");
85   }
86 
87   /* assign TXT keys if any */
88   if (username) {
89     if (sw_text_record_add_key_and_string_value(text_record,
90                                                 "u",
91                                                 username) != SW_OKAY) {
92       out_log(LEVEL_CRITICAL, "Adding TXT record %s=%s failed\n", "u", username);
93 
94       ho_zeroconf_unregister();
95       sw_text_record_fina(text_record);
96     }
97   }
98   if (password) {
99     if (sw_text_record_add_key_and_string_value(text_record,
100                                                 "p",
101                                                 password) != SW_OKAY) {
102       out_log(LEVEL_CRITICAL, "Adding TXT record %s=%s failed\n", "p", password);
103 
104       ho_zeroconf_unregister();
105       sw_text_record_fina(text_record);
106     }
107   }
108   if (path) {
109     if (sw_text_record_add_key_and_string_value(text_record,
110                                                 "path",
111                                                 path) != SW_OKAY) {
112       out_log(LEVEL_CRITICAL, "Adding TXT record %s=%s failed\n", "path", path);
113 
114       ho_zeroconf_unregister();
115       sw_text_record_fina(text_record);
116     }
117   }
118 
119   if (!(result = sw_discovery_publish (discovery,
120                                        0,
121                                        name,
122                                        FTP_DNS_SERVICE_TYPE,
123                                        NULL,
124                                        NULL,
125                                        port,
126                                        sw_text_record_bytes(text_record),
127                                        sw_text_record_len(text_record),
128                                        publish_reply,
129                                        NULL,
130                                        &id)) != SW_OKAY) {
131     out_log(LEVEL_INFO, "Adding service '%s'\n", name);
132   } else {
133     out_log(LEVEL_CRITICAL, "Adding service '%s' failed\n", name);
134     ho_zeroconf_unregister();
135   }
136 
137   sw_text_record_fina(text_record);
138 }
139 
ho_zeroconf_run(void)140 void* ho_zeroconf_run(void) {
141   out_log(LEVEL_INFO, "Starting discovery (Yields control of the CPU to Howl)...\n");
142   sw_discovery_run(discovery);
143   out_log(LEVEL_INFO, "Discovery started.");
144 }
145 
ho_zeroconf_unregister(void)146 void* ho_zeroconf_unregister(void) {
147   out_log(LEVEL_INFO, "Trying to stop discovery and to de-allocated resources...\n");
148   sw_discovery_stop_run(discovery);
149   out_log(LEVEL_INFO, "Discovery stopped.");
150 
151 }
152 
153 #endif /* USE_HOWL */
154