1 /*
2 cdcd - Command Driven CD player
3 Copyright (C)1998-99 Tony Arcieri
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* modified for Audio::CD by dougm */
20 
21 #include "cdaudio.h"
22 #include "cddb_lookup.h"
23 #include "stdio.h"
24 
25 #define PACKAGE "Audio::CD"
26 
27 static int verbosity = 0;
28 static int timestamp = 0;
29 
30 /* Timestamped discid */
31 static int timestamped_discid = 0;
32 
33 void cddb_verbose(void *h, int flag)
34 {
35     verbosity = flag;
36 }
37 
38 static cddb_inexact_selection_func_t ixs_func = NULL;
39 
40 void cddb_inexact_selection_set(cddb_inexact_selection_func_t func)
41 {
42     ixs_func = func;
43 }
44 
45 static int inexact_selection(void)
46 {
47     if (ixs_func) {
48 	return (*ixs_func)();
49     }
50     else {
51 	char inbuffer[256];
52 	fgets(inbuffer, sizeof(inbuffer), stdin);
53 	return strtol(inbuffer, NULL, 10);
54     }
55 }
56 
57 int cdcd_cd_stat(int cd_desc, struct disc_info *disc)
58 {
59    cd_stat(cd_desc, disc);
60    if(!disc->disc_present) {
61       cd_close(cd_desc);
62       cd_stat(cd_desc, disc);
63       if(!disc->disc_present) {
64 	 if (verbosity) puts("No disc in drive");
65 	 return -1;
66       }
67    }
68 
69    return 0;
70 }
71 
72 void cddb_lookup(int cd_desc, struct disc_data *data)
73 {
74    int index, serverindex, selection, sock = -1;
75    struct disc_info disc;
76    struct cddb_conf conf;
77    struct cddb_serverlist list;
78    struct cddb_server *proxy;
79    struct cddb_entry entry;
80    struct cddb_hello hello;
81    struct cddb_query query;
82    char http_string[512], discid[CDINDEX_ID_SIZE];
83 
84    if(cdcd_cd_stat(cd_desc, &disc) < 0)
85      return;
86 
87    if(0)
88      cddb_read_disc_data(cd_desc, data);
89    else {
90       cddb_stat_disc_data(cd_desc, &entry);
91 
92       if(entry.entry_present) {
93 	 if(entry.entry_timestamp == timestamp && entry.entry_id == timestamped_discid)
94 	   return;
95 
96 	 cddb_read_disc_data(cd_desc, data);
97 	 timestamp = entry.entry_timestamp;
98 	 timestamped_discid = entry.entry_id;
99       } else {
100 	 proxy = (struct cddb_server *)malloc(sizeof(struct cddb_server));
101 	 cddb_read_serverlist(&conf, &list, proxy);
102 	 if(conf.conf_access == CDDB_ACCESS_LOCAL) {
103 	    free(proxy);
104 	    cddb_generate_unknown_entry(cd_desc, data);
105 	    return;
new_caseless_value(const GValue * cvalue)106 	 }
107 	 if(!conf.conf_proxy) {
108 	    free(proxy);
109 	    proxy = NULL;
110 	 } else
111 	    if (verbosity) printf("Using proxy http://%s:%d/\n", proxy->server_name, proxy->server_port);
112 
113 	 strncpy(hello.hello_program, PACKAGE, 256);
114 	 strncpy(hello.hello_version, VERSION, 256);
115 
116 	 serverindex = 0;
117 
118          do {
119 	    switch(list.list_host[serverindex].host_protocol) {
120 	     case CDDB_MODE_CDDBP:
121 	       if (verbosity) printf("Trying CDDB server cddbp://%s:%d/\n", list.list_host[serverindex].host_server.server_name, list.list_host[serverindex].host_server.server_port);
122 	       sock = cddb_connect_server(list.list_host[serverindex++], proxy, hello);
123 	       break;
124 	     case CDDB_MODE_HTTP:
125 	       if (verbosity) printf("Trying CDDB server http://%s:%d/%s\n", list.list_host[serverindex].host_server.server_name, list.list_host[serverindex].host_server.server_port, list.list_host[serverindex].host_addressing);
126 	       sock = cddb_connect_server(list.list_host[serverindex++], proxy, hello, http_string, 512);
127 	       break;
128 	     case CDINDEX_MODE_HTTP:
129 	       if (verbosity) printf("Trying CD Index server http://%s:%d/%s\n", list.list_host[serverindex].host_server.server_name, list.list_host[serverindex].host_server.server_port, list.list_host[serverindex].host_addressing);
130 	       sock = cdindex_connect_server(list.list_host[serverindex++], proxy, http_string, 512);
131 	       break;
132 	     default:
133 	       if (verbosity) puts("Invalid protocol selected!");
to_caseless_string(gchar * string)134 	       return;
135 	    }
136 	    if(sock == -1) fprintf(stderr, "Connection error: %s\n", cddb_message);
137 	 } while(serverindex < list.list_len && sock == -1);
138 
139 	 if(sock == -1) {
140 	    if (verbosity) puts("Could not establish connection with any CDDB servers!");
141 	    if(conf.conf_proxy) free(proxy);
142 	    cddb_generate_unknown_entry(cd_desc, data);
143 	    return;
144 	 }
145 	 serverindex--;
146          if (verbosity) puts("Connection established.");
147 
148 	 switch(list.list_host[serverindex].host_protocol) {
149 	  case CDDB_MODE_CDDBP:
150 	    if (verbosity) printf("Retrieving information on %02lx.\n", cddb_discid(cd_desc));
151             if(cddb_query(cd_desc, sock, CDDB_MODE_CDDBP, &query) < 0) {
152 	       fprintf(stderr, "CDDB query error: %s", cddb_message);
153 	       if(conf.conf_proxy) free(proxy);
_gda_sqlite_provider_meta_init(GdaServerProvider * provider)154 	       cddb_generate_unknown_entry(cd_desc, data);
155 	       return;
156 	    }
157             break;
158 	  case CDDB_MODE_HTTP:
159 	    if (verbosity) printf("Retrieving information on %02lx.\n", cddb_discid(cd_desc));
160 	    if(cddb_query(cd_desc, sock, CDDB_MODE_HTTP, &query, http_string) < 0) {
161 	       fprintf(stderr, "CDDB query error: %s", cddb_message);
162 	       if(conf.conf_proxy) free(proxy);
163 	       cddb_generate_unknown_entry(cd_desc, data);
164 	       return;
165 	    }
166 	    shutdown(sock, 2);
167 	    close(sock);
168 
169 	    if((sock = cddb_connect_server(list.list_host[serverindex], proxy, hello, http_string, 512)) < 0) {
170 	       perror("HTTP server reconnection error");
171 	       if(conf.conf_proxy) free(proxy);
172 	       cddb_generate_unknown_entry(cd_desc, data);
173 	       return;
174 	    }
175 	    break;
176 	  case CDINDEX_MODE_HTTP:
177 	    cdindex_discid(cd_desc, discid, CDINDEX_ID_SIZE);
178 	    if (verbosity) printf("Retrieving information on %s.\n", discid);
179 	    if(cdindex_read(cd_desc, sock, data, http_string) < 0) {
180 	       if (verbosity) printf("No match for %s.\n", discid);
181 	       if(conf.conf_proxy) free(proxy);
182 	       cddb_generate_unknown_entry(cd_desc, data);
183 	       return;
184 	    }
185 	    if (verbosity) printf("Match for %s: %s / %s\nDownloading data...\n", discid, data->data_artist, data->data_title);
186 	    cddb_write_data(cd_desc, data);
187 	    return;
188 	 }
189 
190 	 if(conf.conf_proxy) free(proxy);
191 
192 	 if(list.list_host[serverindex].host_protocol == CDINDEX_MODE_HTTP);
193 
get_statement(InternalStatementItem type,const gchar * schema_name,const gchar * obj_name,GError ** error)194          switch(query.query_match) {
195           case QUERY_EXACT:
196 	    if(strlen(query.query_list[0].list_artist) > 0)
197 	      if (verbosity) printf("Match for %02lx: %s / %s\nDownloading data...\n", cddb_discid(cd_desc), query.query_list[0].list_artist, query.query_list[0].list_title);
198 	    else
199 	      if (verbosity) printf("Match for %02lx: %s\nDownloading data...\n", cddb_discid(cd_desc), query.query_list[0].list_title);
200 	    entry.entry_genre = query.query_list[0].list_genre;
201 	    entry.entry_id = query.query_list[0].list_id;
202 	    switch(list.list_host[serverindex].host_protocol) {
203 	      case CDDB_MODE_CDDBP:
204 		if(cddb_read(cd_desc, sock, CDDB_MODE_CDDBP, entry, data) < 0) {
205 		   perror("CDDB read error");
206 		   cddb_generate_unknown_entry(cd_desc, data);
207 		   return;
208 		}
209 		cddb_quit(sock);
210 		break;
211 	      case CDDB_MODE_HTTP:
212 		if(cddb_read(cd_desc, sock, CDDB_MODE_HTTP, entry, data, http_string) < 0) {
213 		   perror("CDDB read error");
214 		   cddb_generate_unknown_entry(cd_desc, data);
215 		   return;
216 		}
217 
218 		shutdown(sock, 2);
219 		close(sock);
220 		break;
221 	    }
222 	    break;
223           case QUERY_INEXACT:
224 	    if (verbosity) printf("Inexact match for %02lx.\n", cddb_discid(cd_desc));
225 	    if (verbosity) puts("Please choose from the following inexact matches:");
226 	    for(index = 0; index < query.query_matches; index++)
227 	      if(strlen(query.query_list[index].list_artist) < 1)
228 		if (verbosity) printf("%d: %s\n", index + 1, query.query_list[index].list_title);
229 	      else
230 	        if (verbosity) printf("%d: %s / %s\n", index + 1, query.query_list[index].list_artist, query.query_list[index].list_title);
231 	    if (verbosity) printf("%d: None of the above.\n", index + 1);
232 	    if (verbosity) printf("> ");
233 
234 	    selection = inexact_selection();
235 
236 	    if(selection > 0 && selection <= query.query_matches) {
237 	       entry.entry_genre = query.query_list[selection - 1].list_genre;
238 	       entry.entry_id = query.query_list[selection - 1].list_id;
239 	       if (verbosity) puts("Downloading data...");
240 	       switch(list.list_host[serverindex].host_protocol) {
241 	         case CDDB_MODE_CDDBP:
242 		   if(cddb_read(cd_desc, sock, CDDB_MODE_CDDBP, entry, data) < 0) {
243 		      perror("CDDB read error");
244 		      cddb_generate_unknown_entry(cd_desc, data);
245 		      return;
246 		   }
247 		   cddb_quit(sock);
248 		   break;
249 	         case CDDB_MODE_HTTP:
250 		   if(cddb_read(cd_desc, sock, CDDB_MODE_HTTP, entry, data, http_string) < 0) {
251 		      perror("CDDB read error");
252 		      cddb_generate_unknown_entry(cd_desc, data);
253 		      return;
254 		   }
255 		   shutdown(sock, 2);
256 		   close(sock);
257 		   break;
258 	       }
259 	       break;
260 	    }
261           case QUERY_NOMATCH:
262 	    if (verbosity) printf("No match for %02lx.\n", cddb_discid(cd_desc));
263 	    cddb_generate_unknown_entry(cd_desc, data);
264          }
_gda_sqlite_meta__btypes(G_GNUC_UNUSED GdaServerProvider * prov,G_GNUC_UNUSED GdaConnection * cnc,GdaMetaStore * store,GdaMetaContext * context,GError ** error)265          close(sock);
266          cddb_write_data(cd_desc, data);
267       }
268    }
269    return;
270 }
271