1 /*
2 * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
3 *
4 * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 #include <libgupnp/gupnp.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include "control_point.h"
29 #include "item-creation.h"
30 #include "transfer.h"
31 #include "container-search.h"
32 #include "main.h"
33
34 static GMainLoop *main_loop;
35 static GUPnPContext *upnp_context;
36 static GUPnPServiceProxy *cds_proxy;
37
38 static GList *files = NULL;
39 static char *udn = NULL;
40 static char *interface = NULL;
41
42 static const char *title = NULL;
43 static char *dest_container = NULL;
44 static guint search_timeout = 0;
45
46 static GOptionEntry entries[] =
47 {
48 { "search-timeout", 't', 0,
49 G_OPTION_ARG_INT, &search_timeout,
50 "Search Timeout", "seconds" },
51 { "container-id", 'c', 0,
52 G_OPTION_ARG_STRING, &dest_container,
53 "Destination Container ID", "CONTAINER_ID" },
54 { "title", 'i', 0,
55 G_OPTION_ARG_STRING, &title,
56 "Title for item", "TITLE" },
57 { "interface", 'e', 0,
58 G_OPTION_ARG_STRING, &interface,
59 "Network interface to search MediaServer on", "INTERFACE" },
60 { "udn", 'u', 0,
61 G_OPTION_ARG_STRING, &udn,
62 "UDN of the device to upload to", "UDN" },
63 { NULL }
64 };
65
66 static void
goto_next_file(void)67 goto_next_file (void)
68 {
69 files = g_list_next (files);
70
71 if (files != NULL) {
72 create_item ((char *) files->data,
73 title,
74 cds_proxy,
75 dest_container);
76 } else {
77 /* Exit if there are no more files to upload */
78 application_exit ();
79 }
80 }
81
82 void
transfer_completed(void)83 transfer_completed (void)
84 {
85 goto_next_file ();
86 }
87
88 void
container_found(const char * container_id)89 container_found (const char *container_id)
90 {
91 dest_container = g_strdup (container_id);
92
93 /* Now create the item container */
94 create_item ((char *) files->data,
95 title,
96 cds_proxy,
97 dest_container);
98 }
99
100 void
item_created(const char * import_uri)101 item_created (const char *import_uri) {
102 if (import_uri == NULL) {
103 /* Item creation failed, lets try next file */
104 goto_next_file ();
105 } else {
106 start_transfer ((char *) files->data,
107 import_uri,
108 cds_proxy,
109 upnp_context);
110 }
111 }
112
113 void
target_cds_found(GUPnPServiceProxy * target_cds_proxy)114 target_cds_found (GUPnPServiceProxy *target_cds_proxy)
115 {
116 cds_proxy = target_cds_proxy;
117
118 if (dest_container != NULL) {
119 container_found (dest_container);
120 } else {
121 /* Find a suitable container */
122 search_container (target_cds_proxy);
123 }
124 }
125
126 void
application_exit(void)127 application_exit (void)
128 {
129 if (main_loop != NULL)
130 g_main_loop_quit (main_loop);
131 }
132
133 gint
main(gint argc,gchar * argv[])134 main (gint argc,
135 gchar *argv[])
136 {
137 GError *error = NULL;
138 gint i;
139 GOptionContext *context;
140
141 #if !GLIB_CHECK_VERSION(2, 35, 0)
142 g_type_init ();
143 #endif
144
145 context = g_option_context_new ("- Upload files to UPnP MediaServer");
146 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
147 if (!g_option_context_parse (context, &argc, &argv, &error))
148 {
149 g_print ("option parsing failed: %s\n", error->message);
150 return -1;
151 }
152
153 if (argc < 2) {
154 char *help = NULL;
155
156 help = g_option_context_get_help (context, TRUE, NULL);
157 g_print ("%s\n", help);
158 g_free (help);
159
160 return -4;
161 }
162
163 if (udn == NULL) {
164 g_print ("Error: Please provide UDN for the target server\n");
165 return -4;
166 }
167
168 /* Get the list of files to upload */
169 for (i = 1; i < argc; i++) {
170 if (!g_file_test (argv[i],
171 G_FILE_TEST_EXISTS |
172 G_FILE_TEST_IS_REGULAR)) {
173 g_printerr ("File %s does not exist\n", argv[i]);
174 } else {
175 files = g_list_append (files, argv[i]);
176 }
177 }
178
179 if (files == NULL) {
180 return -5;
181 }
182
183 error = NULL;
184 upnp_context = gupnp_context_new (interface, 0, &error);
185 if (error) {
186 g_printerr ("Error creating the GUPnP context: %s\n",
187 error->message);
188 g_error_free (error);
189
190 return -6;
191 }
192
193 g_print ("UPnP context created for interface %s (%s)\n",
194 gssdp_client_get_interface (GSSDP_CLIENT (upnp_context)),
195 gssdp_client_get_host_ip (GSSDP_CLIENT (upnp_context)));
196
197 if (!init_control_point (upnp_context, udn, search_timeout)) {
198 return -3;
199 }
200
201 main_loop = g_main_loop_new (NULL, FALSE);
202
203 g_main_loop_run (main_loop);
204
205 /* Clean-up */
206 g_clear_pointer (&main_loop, g_main_loop_unref);
207 deinit_control_point ();
208 g_object_unref (upnp_context);
209 g_option_context_free (context);
210 g_free (dest_container);
211 g_free (interface);
212
213 return 0;
214 }
215
216