libmp3splt
src/freedb.c
Go to the documentation of this file.
00001 /**********************************************************
00002  * libmp3splt -- library based on mp3splt,
00003  *               for mp3/ogg splitting without decoding
00004  *
00005  * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net>
00006  * Copyright (c) 2005-2011 Alexandru Munteanu - io_fx@yahoo.fr
00007  *
00008  *********************************************************/
00009 
00010 /**********************************************************
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00024  * 02111-1307, USA.
00025  *********************************************************/
00026 
00035 #include <string.h>
00036 #include <unistd.h>
00037 
00038 #ifdef __WIN32__
00039 #include <conio.h>
00040 #include <winsock.h>
00041 #else
00042 #include <netdb.h>
00043 #include <sys/socket.h>
00044 #include <netinet/in.h>
00045 #endif
00046 
00047 #include "splt.h"
00048 
00049 #include "freedb.h"
00050 
00051 #if defined(__BEOS__) && !defined (HAS_GETPASS)
00052 //used for proxy (proxy not implemented)
00053 //#warning Faking getpass() !!!
00054 //char *getpass(char *p)
00055 //{
00056 //      char *ret;
00057 //      ret = malloc(30);
00058 //      if (!ret)
00059 //              return NULL;
00060 //      puts(p);
00061 //      fgets(ret,30,stdin);
00062 //      return ret;
00063 //}
00064 #endif
00065 #if defined(__BEOS__) && (IPPROTO_UDP==1)
00066 // net_server has a weird order for IPPROTO_
00067 #else
00068 #define closesocket close
00069 #endif
00070 
00071 // The alphabet fpr the base64 algorithm - for proxy (proxy not implemented)
00072 //
00073 // Base64 Algorithm: Base64.java v. 1.3.6 by Robert Harder
00074 // Ported and optimized for C by Matteo Trotta
00075 //
00076 //const char alphabet [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00077 //char *encode3to4 (unsigned char *source, int srcoffset, int num, char *destination, int destoffset)
00078 //{
00079 //
00080 //    int inbuff=(num>0?(source[srcoffset]<<16):0)|(num>1?(source[srcoffset+1]<<8):0)|(num>2?(source[srcoffset+2]):0);
00081 //    switch(num)
00082 //    {
00083 //      case 3:
00084 //          destination[destoffset] = alphabet[(inbuff>>18)];
00085 //          destination[destoffset+1] = alphabet[(inbuff>>12)&0x3f];
00086 //          destination[destoffset+2] = alphabet[(inbuff>>6)&0x3f];
00087 //          destination[destoffset+3] = alphabet[(inbuff)&0x3f];
00088 //          return destination;
00089 //
00090 //      case 2:
00091 //          destination[destoffset] = alphabet[(inbuff>>18)];
00092 //          destination[destoffset+1] = alphabet[(inbuff>>12)&0x3f];
00093 //          destination[destoffset+2] = alphabet[(inbuff>>6)&0x3f];
00094 //          destination[destoffset+3] = '=';
00095 //          return destination;
00096 //
00097 //      case 1:
00098 //          destination[destoffset] = alphabet[(inbuff>>18)];
00099 //          destination[destoffset+1] = alphabet[(inbuff>>12)&0x3f];
00100 //          destination[destoffset+2] = '=';
00101 //          destination[destoffset+3] = '=';
00102 //          return destination;
00103 //      default:
00104 //          return destination;
00105 //    }
00106 //}
00107 
00108 //used for proxy (proxy not implemented)
00109 //char *b64 (unsigned char *source, int len)
00110 //{
00111 //      char *out;
00112 //      int d, e=0;
00113 //      d = ((len*4/3)+((len%3)>0?4:0));
00114 //      
00115 //      out = malloc(d+1);
00116 //      
00117 //      memset(out, 0x00, d+1);
00118 //      for(d=0;d<(len-2);d+=3,e+=4)
00119 //              out = encode3to4(source, d, 3, out, e);
00120 //      if(d<len)
00121 //              out = encode3to4(source, d, len-d, out, e);
00122 //
00123 //      return out;
00124 //}
00125 // End of Base64 Algorithm
00126 
00128 static int splt_freedb2_analyse_cd_buffer (char *buf, int size,
00129     splt_state *state, int *error)
00130 {
00131   //temporary pointer
00132   char *temp = buf, *temp2 = NULL;
00133 
00134   //we replace the \r with \n
00135   while ((temp = strchr(temp,'\r')) != NULL)
00136   {
00137     *temp = '\n';
00138   }
00139 
00140   temp = NULL;
00141   do
00142   {
00143     //genre
00144     buf = strchr(buf, '\n');
00145 
00146     if (buf != NULL)
00147     {
00148       buf += 1;
00149       buf++;
00150 
00151       //disc id
00152       temp = strchr(buf, ' ');
00153       if (temp != NULL)
00154       {
00155         temp++;
00156 
00157         //artist / album
00158         //temp2 is the end of the line
00159         temp2 = strchr(temp+8,'\n');
00160         if (temp2 != NULL)
00161         {
00162           temp2++;
00163 
00164           splt_fu_freedb_set_disc(state, splt_fu_freedb_get_found_cds(state), 
00165               temp, buf, temp-buf);
00166 
00167           char *full_artist_album = malloc(temp2-(temp+8)-1);
00168           if (full_artist_album)
00169           {
00170             int max_chars = temp2-(temp+8)-1;
00171             snprintf(full_artist_album,max_chars,"%s",temp+9);
00172             //snprintf seems buggy
00173 #ifdef __WIN32__                                        
00174             full_artist_album[max_chars-1] = '\0';
00175 #endif
00176             splt_d_print_debug(state,"Setting the full artist album name _%s_\n", full_artist_album);
00177 
00178             //i!=-1 means that it's not a revision
00179             int i=0;
00180             int err = SPLT_OK;
00181             //here we have in album_name the name of the current album
00182             err = splt_fu_freedb_append_result(state, full_artist_album, i);
00183             if (err < 0)
00184             {
00185               if (full_artist_album)
00186               {
00187                 free(full_artist_album);
00188                 full_artist_album = NULL;
00189               }
00190               *error = err;
00191               return -2;
00192             }
00193 
00194             //free memory
00195             free(full_artist_album);
00196             full_artist_album = NULL;
00197           }
00198           else
00199           {
00200             *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00201             return -2;
00202           }
00203 
00204           //next cd
00205           splt_fu_freedb_found_cds_next(state);
00206         }
00207         else
00208         {
00209           return -1;
00210         }
00211       }
00212     }
00213     else
00214     {
00215       return 0;
00216     }
00217 
00218   } while (((strstr(buf,"/"))!= NULL) &&
00219       ((strchr(buf,'\n'))!= NULL) &&
00220       (splt_fu_freedb_get_found_cds(state) < SPLT_MAXCD));
00221 
00222   return splt_fu_freedb_get_found_cds(state);
00223 }
00224 
00225 //char *login (char *s)
00226 //{
00227 //      char *pass, junk[130];
00228 //      fprintf (stdout, "Username: ");
00229 //      fgets(junk, 128, stdin);
00230 //      junk[strlen(junk)-1]='\0';
00231 //      pass = getpass("Password: ");
00232 //      sprintf (s, "%s:%s", junk, pass);
00233 //      memset (pass, 0x00, strlen(pass));
00234 //      free(pass);
00235 //      return s;
00236 //}
00237 
00238 static splt_addr splt_freedb_useproxy(splt_proxy *proxy, splt_addr dest,
00239     const char search_server[256], int port)
00240 {
00241   dest.proxy=0;
00242   memset(dest.hostname, 0, 256);
00243   //memset(line, 0, 270);
00244 
00245   //if (proxy->use_proxy)
00246   if (proxy)
00247   {
00248     /*
00249     //TODO
00250     strncpy(dest.hostname, proxy->hostname, 255);
00251     dest.port = proxy->port;
00252     dest.proxy = proxy->use_proxy;
00253 
00254     fprintf(stderr, "Using Proxy: %s on Port %d\n", dest.hostname, dest.port);
00255 
00256     dest.auth = malloc(strlen(line)+1);
00257     if (dest.auth==NULL)
00258     {
00259       perror("malloc");
00260       exit(1);
00261     }
00262     memset(dest.auth, 0x0, strlen(line)+1);
00263     strncpy(dest.auth, line, strlen(line));
00264     //dest.auth = b64(line, strlen(line));*/
00265   }
00266 
00267   if (!dest.proxy) 
00268   {
00269     //we put the hostname
00270     if (strlen(search_server) == 0)
00271     {
00272       //by default we use freedb2.org
00273       strncpy(dest.hostname, SPLT_FREEDB2_SITE, 255);
00274     }
00275     else
00276     {
00277       strncpy(dest.hostname, search_server, 255);
00278     }
00279 
00280     //we put the port
00281     if (port == -1)
00282     {
00283       //by default we put the port 80
00284       //to use it with cddb.cgi
00285       dest.port = SPLT_FREEDB_CDDB_CGI_PORT;
00286     }
00287     else
00288     {
00289       dest.port = port;
00290     }      
00291   }
00292 
00293   return dest;
00294 }
00295 
00308 int splt_freedb_process_search(splt_state *state, char *search,
00309                                int search_type, const char search_server[256],
00310                                int port)
00311 {
00312   //we take the cgi path of the search_server
00313   //if we have one
00314   char cgi_path[256] = { '\0' };
00315   if (search_type == SPLT_FREEDB_SEARCH_TYPE_CDDB_CGI)
00316   {
00317     char *temp = strchr(search_server,'/');
00318     if (temp != NULL)
00319     {
00320       snprintf(cgi_path,255,"%s",temp);
00321       *temp = '\0';
00322     }
00323   }
00324   //default cgi path
00325   if (strlen(search_server) == 0)
00326   {
00327     snprintf(cgi_path,255,"%s","/~cddb/cddb.cgi");
00328   }
00329 
00330   //possible error that we will return
00331   int error = SPLT_FREEDB_OK;
00332   //socket and internet structures
00333   struct sockaddr_in host;
00334   struct hostent *h = NULL;
00335   splt_addr dest;
00336   //e is used for the end of the buffer
00337   //c is used for the buffer read
00338   char *c = NULL, *e=NULL;
00339   int i = 0, tot=0;
00340   //the message delivered to the server
00341   char *message = NULL;
00342   //the buffer that we are using to read incoming transmission
00343   char buffer[SPLT_FREEDB_BUFFERSIZE] = { '\0' };
00344 
00345   //fd = socket identifier
00346 #ifdef __WIN32__
00347   long winsockinit;
00348   WSADATA winsock;
00349   SOCKET fd;
00350   winsockinit = WSAStartup(0x0101,&winsock);
00351   if (winsockinit != 0)
00352   {
00353     splt_e_clean_strerror_msg(state);
00354     error = SPLT_FREEDB_ERROR_INITIALISE_SOCKET;
00355     return error;
00356   }
00357 #else
00358   int fd;
00359 #endif
00360 
00361   //transform ' ' to '+'
00362   int string_length = strlen(search);
00363   for (i = 0; i < string_length; i++)
00364   {
00365     if (search[i] == ' ')
00366     {
00367       search[i] = '+';
00368     }
00369   }
00370 
00371   //dest = splt_freedb_useproxy(&state->proxy, dest, search_server, port);
00372   dest = splt_freedb_useproxy(NULL, dest, search_server, port);
00373 
00374   //we get the hostname of freedb
00375   if((h=gethostbyname(dest.hostname))==NULL)
00376   {
00377     splt_e_set_strherror_msg(state);
00378     error = SPLT_FREEDB_ERROR_CANNOT_GET_HOST;
00379     splt_e_set_error_data(state,dest.hostname);
00380 #ifdef __WIN32__
00381     WSACleanup();
00382 #endif
00383     return error;
00384   }
00385   else
00386   {
00387     splt_e_set_error_data(state,dest.hostname);
00388 
00389     //we prepare socket
00390     memset(&host, 0x0, sizeof(host));
00391     host.sin_family=AF_INET;
00392     host.sin_addr.s_addr=((struct in_addr *) (h->h_addr)) ->s_addr;
00393     host.sin_port=htons(dest.port);
00394 
00395     //initialize socket
00396     if((fd = socket(AF_INET, SOCK_STREAM, 0))==-1)
00397     {
00398       splt_e_set_strerror_msg(state);
00399       error = SPLT_FREEDB_ERROR_INITIALISE_SOCKET;
00400 #ifdef __WIN32__
00401       WSACleanup();
00402 #endif
00403       return error;
00404     }
00405     else
00406     {
00407       //make connection
00408       if ((connect(fd, (void *)&host, sizeof(host))) < 0)
00409       {
00410         splt_e_set_strerror_msg(state);
00411         error = SPLT_FREEDB_ERROR_CANNOT_CONNECT;
00412         closesocket(fd);
00413 #ifdef __WIN32__
00414         WSACleanup();
00415 #endif
00416         return error;
00417       }
00418       else
00419       {
00420         //prepare message to send
00421         //proxy not supported for now
00422         //if (dest.proxy) {
00423         //                sprintf(message,
00424         //                "GET http://www.freedb.org"SPLT_SEARCH" "PROXYDLG, search);
00425         //                if (dest.auth!=NULL)
00426         //                sprintf (message, "%s"AUTH"%s\n", message, dest.auth);
00427         //                strncat(message, "\n", 1);
00428         //                }
00429         //                else 
00430         int malloc_number = 0;
00431         //freedb2 search
00432         if (search_type == SPLT_FREEDB_SEARCH_TYPE_CDDB_CGI)
00433         {
00434           malloc_number = strlen(search)+
00435             strlen(SPLT_FREEDB2_SEARCH)+strlen(cgi_path)+strlen(dest.hostname)+3;
00436 
00437           //we allocate the memory for the query string
00438           if ((message = malloc(malloc_number)) == NULL)
00439           {
00440             error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00441           }
00442           else
00443           {
00444             //we write the search query
00445             snprintf(message, malloc_number,
00446                 SPLT_FREEDB2_SEARCH,cgi_path,search, dest.hostname);
00447 
00448             //fprintf(stdout,"message = _%s_\n",message);
00449             //fflush(stdout);
00450 
00451             //message sent
00452             if((send(fd, message, strlen(message), 0))==-1)
00453             {
00454               splt_e_set_strerror_msg(state);
00455               error = SPLT_FREEDB_ERROR_CANNOT_SEND_MESSAGE;
00456             }
00457             else
00458             {
00459               memset(buffer, 0x00, SPLT_FREEDB_BUFFERSIZE);
00460 
00461               splt_fu_freedb_free_search(state);
00462 
00463               int init_err = splt_fu_freedb_init_search(state);
00464               if (init_err == SPLT_OK)
00465               {
00466                 int content_start = SPLT_FALSE;
00467 
00468                 //we read what we receive from the server
00469                 do {
00470                   tot=0;
00471                   c = buffer;
00472 
00473                   do {
00474                     i = recv(fd, c, SPLT_FREEDB_BUFFERSIZE-(c-buffer)-1, 0);
00475                     if (i == -1) 
00476                     {
00477                       splt_e_set_strerror_msg(state);
00478                       error = SPLT_FREEDB_ERROR_CANNOT_RECV_MESSAGE;
00479                       goto function_end1;
00480                     }
00481 
00482                     tot += i;
00483                     buffer[tot]='\0';
00484                     c += i;
00485                   } while ((i>0)&&(tot<SPLT_FREEDB_BUFFERSIZE-1)
00486                       &&((e=strstr(buffer, "\n."))==NULL));
00487 
00488                   //fprintf(stdout,"buffer = %s\n",buffer);
00489                   //fflush(stdout);
00490 
00491                   char *buf_start = buffer;
00492                   if (!content_start)
00493                   {
00494                     char *start = strstr(buffer, "\r\n\r\n");
00495                     if (start)
00496                     {
00497                       buf_start = strstr(start+4, "\r\n");
00498                       if (!buf_start)
00499                       {
00500                         buf_start = buffer;
00501                       }
00502                       content_start = SPLT_TRUE;
00503                     }
00504                   }
00505 
00506                   //we analyse the buffer
00507                   tot = splt_freedb2_analyse_cd_buffer(buf_start, tot, state,&error);
00508                   if (error < 0)
00509                   {
00510                     goto function_end1;
00511                   }
00512 
00513                   if (tot == -1) continue;
00514                   if (tot == -2) break;
00515 
00516                 } while ((i>0)&&(e==NULL)&&
00517                     (splt_fu_freedb_get_found_cds(state)<SPLT_MAXCD));
00518 
00519                 //no cd found
00520                 if (splt_fu_freedb_get_found_cds(state)==0) 
00521                 {
00522                   error = SPLT_FREEDB_NO_CD_FOUND;
00523                   goto function_end1;
00524                 }
00525                 //erroror occured while getting freedb infos
00526                 if (splt_fu_freedb_get_found_cds(state)==-1) 
00527                 {
00528                   error = SPLT_FREEDB_ERROR_GETTING_INFOS;
00529                   goto function_end1;
00530                 }
00531                 //max cd number reached
00532                 if (splt_fu_freedb_get_found_cds(state)==SPLT_MAXCD) 
00533                 {
00534                   error = SPLT_FREEDB_MAX_CD_REACHED;
00535                   goto function_end1;
00536                 }
00537               }
00538               else
00539               {
00540                 error = init_err;
00541                 goto function_end1;
00542               }
00543             }
00544 
00545 function_end1:
00546             //free memory
00547             free(message);
00548             message = NULL;
00549 #ifdef __WIN32__
00550             WSACleanup();
00551 #endif
00552           }
00553         }
00554         //we will put the new web html freedb search
00555         /* TODO when freedb.org releases the web search */
00556         else 
00557         {
00558           error = SPLT_FREEDB_ERROR_GETTING_INFOS;
00559 #ifdef __WIN32__
00560           WSACleanup();
00561 #endif
00562           closesocket(fd);
00563           return error;
00564           /*if (search_type == SPLT_FREEDB_SEARCH_TYPE_CDDB)
00565             {
00566             }*/
00567         }
00568       }
00569       closesocket(fd);
00570     }
00571   }
00572 
00573   return error;
00574 }
00575 
00593 char *splt_freedb_get_file(splt_state *state, int i, int *error,
00594     int get_type, const char cddb_get_server[256], int port)
00595 {
00596   //we take the cgi path of the search_server
00597   //if we have one
00598   char cgi_path[256] = { '\0' };
00599   if (get_type == SPLT_FREEDB_GET_FILE_TYPE_CDDB_CGI)
00600   {
00601     char *temp = strchr(cddb_get_server,'/');
00602     if (temp != NULL)
00603     {
00604       snprintf(cgi_path,256,"%s",temp);
00605       *temp = '\0';
00606     }
00607   }
00608   //default cgi path
00609   if (strlen(cddb_get_server) == 0)
00610   {
00611     snprintf(cgi_path,255,"%s","/~cddb/cddb.cgi");
00612   }
00613 
00614   //possible error that we will return
00615   *error = SPLT_FREEDB_FILE_OK;
00616   //the freedb file that we will return
00617   char *output = NULL;
00618 
00619   //socket and internet structures
00620   struct sockaddr_in host;
00621   struct hostent *h;
00622   splt_addr dest;
00623   char *message = NULL;
00624   int tot=0;
00625   //the buffer that we are using to read incoming transmission
00626   char buffer[SPLT_FREEDB_BUFFERSIZE] = { '\0' };
00627   char *buf_start = buffer;
00628   //e is used for the end of the buffer
00629   //c is used for the buffer read
00630   char *c = NULL, *e=NULL;
00631 
00632   //fd = socket identifier
00633 #ifdef __WIN32__
00634   long winsockinit;
00635   WSADATA winsock;
00636   SOCKET fd;
00637   winsockinit = WSAStartup(0x0101,&winsock);
00638   if (winsockinit != 0)
00639   {
00640     splt_e_clean_strerror_msg(state);
00641     *error = SPLT_FREEDB_ERROR_INITIALISE_SOCKET;
00642     return output;
00643   }
00644 #else
00645   int fd = 0;
00646 #endif
00647 
00648   //dest = splt_freedb_useproxy(&state->proxy, dest, cddb_get_server, port);
00649   dest = splt_freedb_useproxy(NULL, dest, cddb_get_server, port);
00650 
00651   //we get the hostname of freedb
00652   if((h=gethostbyname(dest.hostname))==NULL)
00653   {
00654     splt_e_set_strherror_msg(state);
00655     *error = SPLT_FREEDB_ERROR_CANNOT_GET_HOST;
00656     splt_e_set_error_data(state,dest.hostname);
00657 #ifdef __WIN32__
00658     WSACleanup();
00659 #endif
00660     return NULL;
00661   }
00662   else
00663   {
00664     splt_e_set_error_data(state,dest.hostname);
00665 
00666     //we prepare socket
00667     memset(&host, 0x0, sizeof(host));
00668     host.sin_family=AF_INET;
00669     host.sin_addr.s_addr=((struct in_addr *) (h->h_addr)) ->s_addr;
00670     host.sin_port=htons(dest.port);
00671 
00672     //prepare message to send
00673     //proxy not yet supported
00674     //      if (dest.proxy) {
00675     //        sprintf(message, "GET "FREEDBHTTP"cmd=cddb+read+%s+%s&hello=nouser+mp3splt.net+"PACKAGE_NAME"+"PACKAGE_VERSION"&proto=5 "PROXYDLG, 
00676     //        cdstate->discs[i].category, cdstate->discs[i].discid);
00677     //        if (dest.auth!=NULL) {
00678     //        sprintf (message, "%s"AUTH"%s\n", message, dest.auth);
00679     //        memset(dest.auth, 0x00, strlen(dest.auth));
00680     //        free(dest.auth);
00681     //        }
00682     //        strncat(message, "\n", 1);
00683     //        }
00684     //        else 
00685     const char *cd_category = splt_fu_freedb_get_disc_category(state, i);
00686     const char *cd_id = splt_fu_freedb_get_disc_id(state, i);
00687 
00688     int malloc_number = 0;
00689     if (get_type == SPLT_FREEDB_GET_FILE_TYPE_CDDB)
00690     {
00691       malloc_number = strlen(cd_category)+strlen(cd_id)+
00692         strlen(SPLT_FREEDB_GET_FILE);
00693     }
00694     else
00695     {
00696       //if (get_type == SPLT_FREEDB_GET_FILE_TYPE_CDDB_CGI)
00697       malloc_number = strlen(cd_category) + strlen(cd_id) +
00698         strlen(SPLT_FREEDB_CDDB_CGI_GET_FILE) + strlen(cgi_path) + strlen(dest.hostname);
00699     }
00700     message = malloc(malloc_number);
00701     if (message != NULL)
00702     {
00703       //CDDB protocol (usually port 8880)
00704       if (get_type == SPLT_FREEDB_GET_FILE_TYPE_CDDB)
00705       {
00706         snprintf(message, malloc_number, SPLT_FREEDB_GET_FILE, cd_category, cd_id);
00707 
00708         //open socket
00709         if((fd=socket(AF_INET, SOCK_STREAM, 0))==-1)
00710         {
00711           splt_e_set_strerror_msg(state);
00712           *error = SPLT_FREEDB_ERROR_CANNOT_OPEN_SOCKET;
00713           free(message);
00714           goto end_function;
00715         }
00716         else
00717         {
00718           //connect to host
00719           if ((connect(fd, (void *)&host, sizeof(host)))==-1)
00720           {
00721             splt_e_set_strerror_msg(state);
00722             *error = SPLT_FREEDB_ERROR_CANNOT_CONNECT;
00723             goto bloc_end;
00724           }
00725           else
00726           {
00727             //possible errors + proxy
00728             if (!dest.proxy) 
00729             {
00730               i=recv(fd, buffer, SPLT_FREEDB_BUFFERSIZE-1, 0);
00731               if (i == -1)
00732               {
00733                 splt_e_set_strerror_msg(state);
00734                 *error = SPLT_FREEDB_ERROR_CANNOT_RECV_MESSAGE;
00735                 goto bloc_end;
00736               }
00737               buffer[i]='\0';
00738 
00739               if (strncmp(buffer,"201",3)!=0)  
00740               {
00741                 *error = SPLT_FREEDB_ERROR_SITE_201;
00742                 goto bloc_end;
00743               }
00744 
00745               //send hello message
00746               if((send(fd, SPLT_FREEDB_HELLO, strlen(SPLT_FREEDB_HELLO), 0))==-1)
00747               {
00748                 splt_e_set_strerror_msg(state);
00749                 *error = SPLT_FREEDB_ERROR_CANNOT_SEND_MESSAGE;
00750                 goto bloc_end;
00751               }
00752               i=recv(fd, buffer, SPLT_FREEDB_BUFFERSIZE-1, 0);
00753 
00754               if (i == -1)
00755               {
00756                 splt_e_set_strerror_msg(state);
00757                 *error = SPLT_FREEDB_ERROR_CANNOT_RECV_MESSAGE;
00758                 goto bloc_end;
00759               }
00760               buffer[i]='\0';
00761 
00762               if (strncmp(buffer,"200",3)!=0)  
00763               {
00764                 *error = SPLT_FREEDB_ERROR_SITE_200;
00765                 goto bloc_end;
00766               }
00767             }
00768 
00769             //we send the message
00770             if((send(fd, message, strlen(message), 0))==-1)
00771             {
00772               splt_e_set_strerror_msg(state);
00773               *error = SPLT_FREEDB_ERROR_CANNOT_SEND_MESSAGE;
00774               goto bloc_end;
00775             }
00776             else
00777             {
00778               memset(buffer, 0x00, SPLT_FREEDB_BUFFERSIZE);
00779               c = buffer;
00780               tot=0;
00781 
00782               //we read 
00783               do {
00784                 i = recv(fd, c, SPLT_FREEDB_BUFFERSIZE-(c-buffer)-1, 0);
00785                 if (i == -1)
00786                 {
00787                   splt_e_set_strerror_msg(state);
00788                   *error = SPLT_FREEDB_ERROR_CANNOT_RECV_MESSAGE;
00789                   goto bloc_end;
00790                 }
00791 
00792                 //if errors
00793                 if (tot == 0)
00794                 {
00795                   if ((strncmp(buffer,"50",2) == 0)
00796                       || (strncmp(buffer,"40",2) == 0))
00797                   {
00798                     //if "No such CD entry in database"
00799                     if (strncmp(buffer,"401",3) == 0)
00800                     {
00801                       *error = SPLT_FREEDB_NO_SUCH_CD_IN_DATABASE;
00802                     }
00803                     else
00804                     {
00805                       *error = SPLT_FREEDB_ERROR_SITE;
00806                     }
00807                     goto bloc_end;
00808                   }
00809                 }
00810 
00811                 tot += i;
00812                 buffer[tot]='\0';
00813                 c += i;
00814               } while ((i>0)&&(tot<SPLT_FREEDB_BUFFERSIZE-1)&&
00815                   ((e=strstr(buffer, "\n."))==NULL));
00816 
00817               //we quit
00818               if (!dest.proxy)
00819               {
00820                 if((send(fd, "quit\n", 5, 0))==-1)
00821                 {
00822                   splt_e_set_strerror_msg(state);
00823                   *error = SPLT_FREEDB_ERROR_CANNOT_SEND_MESSAGE;
00824                   goto bloc_end;
00825                 }
00826               }
00827             }
00828           }
00829 
00830 bloc_end:
00831           free(message);
00832           message = NULL;
00833           closesocket(fd);
00834         }
00835 
00836         //if we don't have an error
00837         if (*error >= 0)
00838         {
00839           if (tot==0) 
00840           {
00841             *error = SPLT_FREEDB_ERROR_BAD_COMMUNICATION;
00842             goto end_function;
00843           }
00844 
00845           if (e!=NULL)
00846           {
00847             buffer[e-buffer+1]='\0';
00848           }
00849 
00850           //if invalid server answer
00851           if ((strstr(buffer, "database entry follows"))==NULL)
00852           {
00853             if ((c = strchr(buffer, '\n'))!=NULL)
00854             {
00855               buffer[c-buffer]='\0';
00856             }
00857             *error = SPLT_FREEDB_ERROR_INVALID_SERVER_ANSWER;
00858             goto end_function;
00859           }
00860           else
00861           {
00862             if ((c = strchr(buffer, '#'))==NULL)
00863             {
00864               output = NULL;
00865               *error = SPLT_FREEDB_ERROR_BAD_COMMUNICATION;
00866               goto end_function;
00867             }
00868             else
00869             {
00870               output = malloc(strlen(c)+1);
00871               if (output != NULL)
00872               {
00873                 sprintf(output,c);
00874 #ifdef __WIN32__
00875                 WSACleanup();
00876 #endif
00877                 return output;
00878               }
00879               else
00880               {
00881                 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00882                 goto end_function;
00883               }
00884             }
00885           }
00886         }
00887         else
00888         {
00889           goto end_function;
00890         }
00891       }
00892       //cddb.cgi script (usually port 80)
00893       else
00894       {
00895         if (get_type == SPLT_FREEDB_GET_FILE_TYPE_CDDB_CGI)
00896         {
00897           snprintf(message, malloc_number, SPLT_FREEDB_CDDB_CGI_GET_FILE, 
00898               cgi_path, cd_category, cd_id, dest.hostname);
00899 
00900           //open socket
00901           if((fd=socket(AF_INET, SOCK_STREAM, 0))==-1)
00902           {
00903             splt_e_set_strerror_msg(state);
00904             *error = SPLT_FREEDB_ERROR_CANNOT_OPEN_SOCKET;
00905             free(message);
00906             goto end_function;
00907           }
00908           else
00909           {
00910             //connect to host
00911             if ((connect(fd, (void *)&host, sizeof(host)))==-1)
00912             {
00913               splt_e_set_strerror_msg(state);
00914               *error = SPLT_FREEDB_ERROR_CANNOT_CONNECT;
00915               goto bloc_end2;
00916             }
00917             else
00918             {
00919               //we send the message
00920               if((send(fd, message, strlen(message), 0))==-1)
00921               {
00922                 splt_e_set_strerror_msg(state);
00923                 *error = SPLT_FREEDB_ERROR_CANNOT_SEND_MESSAGE;
00924                 goto bloc_end2;
00925               }
00926               else
00927               {
00928                 memset(buffer, 0x00, SPLT_FREEDB_BUFFERSIZE);
00929                 c = buffer;
00930                 tot=0;
00931 
00932                 int content_start = SPLT_FALSE;
00933 
00934                 //we read 
00935                 //we read what we receive from the server
00936                 do {
00937                   tot=0;
00938                   c = buffer;
00939 
00940                   do {
00941                     i = recv(fd, c, SPLT_FREEDB_BUFFERSIZE-(c-buffer)-1, 0);
00942                     if (i == -1) 
00943                     {
00944                       splt_e_set_strerror_msg(state);
00945                       *error = SPLT_FREEDB_ERROR_CANNOT_RECV_MESSAGE;
00946                       goto bloc_end2;
00947                     }
00948 
00949                     buf_start = buffer;
00950                     if (!content_start)
00951                     {
00952                       char *start = strstr(buffer, "\r\n\r\n");
00953                       if (start)
00954                       {
00955                         buf_start = strstr(start+4, "\r\n");
00956                         if (!buf_start)
00957                         {
00958                           buf_start = buffer;
00959                         }
00960                         content_start = SPLT_TRUE;
00961                       }
00962                     }
00963 
00964                     //if errors
00965                     if (tot == 0)
00966                     {
00967                       if ((strncmp(buf_start,"50",2) == 0)
00968                           || (strncmp(buf_start,"40",2) == 0))
00969                       {
00970                         //if "No such CD entry in database"
00971                         if (strncmp(buf_start,"401",3) == 0)
00972                         {
00973                           *error = SPLT_FREEDB_NO_SUCH_CD_IN_DATABASE;
00974                         }
00975                         else
00976                         {
00977                           *error = SPLT_FREEDB_ERROR_SITE;
00978                         }
00979                         goto bloc_end2;
00980                       }
00981                     }
00982 
00983                     tot += i;
00984                     buffer[tot]='\0';
00985                     c += i;
00986                   } while ((i>0)&&(tot<SPLT_FREEDB_BUFFERSIZE-1)
00987                       &&((e=strstr(buffer, "\n."))==NULL));
00988 
00989                   if (error < 0)
00990                   {
00991                     goto bloc_end2;
00992                   }
00993 
00994                 } while ((i>0)&&(e==NULL));
00995               }
00996             }
00997 
00998 bloc_end2:
00999             free(message);
01000             message = NULL;
01001             closesocket(fd);
01002 
01003             //if we don't have an error
01004             if (*error >= 0)
01005             {
01006               if (tot==0) 
01007               {
01008                 *error = SPLT_FREEDB_ERROR_BAD_COMMUNICATION;
01009                 goto end_function;
01010               }
01011 
01012               if ((c = strchr (buf_start, '#'))==NULL)
01013               {
01014                 output = NULL;
01015                 *error = SPLT_FREEDB_ERROR_BAD_COMMUNICATION;
01016                 goto end_function;
01017               }
01018               else
01019               {
01020                 output = malloc(strlen(c)+1);
01021                 if (output != NULL)
01022                 {
01023                   //we write the output
01024                   sprintf(output,c);
01025 #ifdef __WIN32__
01026                   WSACleanup();
01027 #endif
01028                   return output;
01029                 }
01030                 else
01031                 {
01032                   *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
01033                   goto end_function;
01034                 }
01035               }
01036             }
01037             else
01038             {
01039               goto end_function;
01040             }
01041           }
01042         }
01043         else
01044         {
01045           //invalid get file type
01046           *error = SPLT_FREEDB_ERROR_GETTING_INFOS;
01047           goto end_function;
01048         }
01049       }
01050     }
01051     else
01052     {
01053       *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
01054       goto end_function;
01055     }
01056 
01057 end_function:
01058     ;
01059 #ifdef __WIN32__
01060     WSACleanup();
01061 #endif
01062     return NULL;
01063   }
01064 }
01065 
01066   //deprecated, and not in use
01067   //but may useful for the implementation of the proxy
01068   /*int search_freedb (splt_state *state)
01069     {
01070     char *c, *e=NULL;
01071     FILE *output = NULL;
01072     struct sockaddr_in host;
01073     struct hostent *h;
01074     struct splt_addr dest;
01075 
01076     if ((c=getenv("HOME"))!=NULL) sprintf(message, "%s/"PROXYCONFIG, c);
01077     else strncpy(message, PROXYCONFIG, strlen(PROXYCONFIG));
01078 
01079     if (!(output=splt_io_fopen(message, "r"))) {
01080     if (!(output=splt_io_fopen(message, "w+"))) {
01081     fprintf(stderr, "\nWARNING Can't open config file ");
01082     perror(message);
01083     }
01084     else {
01085     fprintf (stderr, "Will you use a proxy? (y/n): ");
01086     fgets(junk, 200, stdin);
01087     if (junk[0]=='y') {
01088     fprintf (stderr, "Proxy Address: ");
01089     fgets(junk, 200, stdin);
01090     fprintf (output, "PROXYADDR=%s", junk);
01091     fprintf (stderr, "Proxy Port: ");
01092     fgets(junk, 200, stdin);
01093     fprintf (output, "PROXYPORT=%s", junk);
01094     fprintf (stderr, "Need authentication? (y/n): ");
01095     fgets(junk, 200, stdin);
01096     if (junk[0]=='y') {
01097     fprintf (output, "PROXYAUTH=1\n");
01098     fprintf (stderr, "Would you like to save password (insecure)? (y/n): ");
01099     fgets(junk, 200, stdin);
01100     if (junk[0]=='y') {
01101     login (message);
01102     e = b64(message, strlen(message));
01103     fprintf (output, "%s\n", e);
01104     memset(message, 0x00, strlen(message));
01105     memset(e, 0x00, strlen(e));
01106     free(e);
01107     }
01108     }
01109     }
01110     }
01111     }
01112         
01113     if (splt_fu_freedb_get_found_cds(state)<=0) {
01114     if (dest.proxy) {
01115     if (strstr(buffer, "HTTP/1.0")!=NULL) {
01116     if ((c = strchr (buffer, '\n'))!=NULL)
01117     buffer[c-buffer]='\0';
01118     fprintf (stderr, "Proxy Reply: %s\n", buffer);
01119     }
01120     }
01121     }
01122     return 0;
01123     }*/