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