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