int get_server_ip(char *server_ip, char *server_port) { const char *gs_server = getenv("GPUSOCK_SERVER"), *gs_port = getenv("GPUSOCK_PORT"); if (gs_server == NULL) { gs_server = DEFAULT_SERVER_IP; gdprintf("GPUSOCK_SERVER not defined, using default server ip: %s\n", gs_server); } if (gs_port == NULL) { gs_port = DEFAULT_SERVER_PORT; gdprintf("GPUSOCK_PORT not defined, using default server port: %s\n", gs_port); } sprintf(server_ip, "%s", gs_server); sprintf(server_port, "%s", gs_port); if (server_ip[0] != '\0' && server_port[0] != '\0') return 0; else if (server_port[0] != '\0') return 1; else if (server_ip[0] != '\0') return 2; else return 3; }
s32 GetHTTPFile(const char *host,const char *file,u8*& Data, int* external_socket_to_use) { //URL_REQUEST if(Data) { mem_free(Data); } if(host == NULL || file == NULL) { //blaarg, we didn't get host or file. fail! return -4; } if(HTTP_Reply[0] != 0) { //reset last reply memset(HTTP_Reply,0,4); } char buffer[1024]; s32 bytes_read = 0; s32 bytes_send = 0; s32 file_size = 0; int socket = 0; s32 ret = 0; char URL_Request[512]; //example : "GET /daco/version.dat HTTP/1.0\r\nHost: www.dacotaco.com\r\nUser-Agent: DacoTacoIsGod/version\r\n\r\n\0" sprintf( URL_Request, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Priiloader/%s(Nintendo Wii) DacoTacoIsGod/1.0 \r\n\r\n", file,host,SVN_REV_STR ); if(external_socket_to_use == 0 || *external_socket_to_use == 0) { socket = ConnectSocket(host,80); if(socket < 0) return socket; } else { socket = *external_socket_to_use; } bytes_send = net_send(socket, URL_Request, strlen(URL_Request), 0); if ( bytes_send > 0) { //receive the header. it starts with something like "HTTP/1.1 [reply number like '200'] [name of code. 200 = 'OK']" { 48 54 54 50 2F 31 2E 31 20 xx xx xx 20 yy yy} for( ;; ) { bytes_read = 0; memset( buffer, '\0', 1024 ); int i, n; for( i = 0;i < 265;) { n = net_recv(socket,(char*)&buffer[i],1, 0); if( n <= 0 ) { //it is possible we get here cause there is no content_lenght mentioned. which fails //that can be fixed by reading anyway and reallocating as we go. not gonna implement that atm ret = -6; goto return_ret; } i += n; if( i > 1 ) { if( buffer[i-1] == 0x0A && buffer[i-2] == 0x0D ) break; } } if(HTTP_Reply[0] == 0) { strncpy(HTTP_Reply,&buffer[9],3); HTTP_Reply[3] = '\0'; char location[256]; char* phost = NULL; char host_new[256]; char file_new[256]; //process the HTTP reply. full list @ http://en.wikipedia.org/wiki/List_of_HTTP_status_codes switch(atoi(HTTP_Reply)) { case 200: // 200 - OK . everything is fine. lets proceed if(redirects > 0) { redirects--; ret = 1; goto return_ret; } break; case 302: case 301: //moved. to lazy to implement that :P { //first lets get the new link. //HTTP/1.1 301 Moved Permanently..Location: http://www.google.com/..Content-Type: memset( buffer, '\0', 1024 ); for( i = 0;i < 265;) { n = net_recv(socket,(char*)&buffer[i],1, 0); if( n <= 0 ) { ret = -6; goto return_ret; } i += n; if( i > 1 ) { if( buffer[i-1] == 0x0A && buffer[i-2] == 0x0D ) break; } } if( !memcmp( buffer, "Location: ", 10 ) ) { sscanf( buffer , "Location: %s\x0D\x0A", location ); } else { //the location wasn't there, or the server wasn't following protocol. so lets bail out net_close(socket); ret = -88; goto return_ret; break; } //we got the url. close everything and start all over net_close(socket); memset( buffer, '\0', 1024 ); bytes_send = 0; bytes_read = 0; memset(host_new,0,256); memset(file_new,0,256); //extract host & file from url if( !memcmp( location, "http://", 7 ) ) { sscanf( location , "http://%s", buffer ); } else { //no http:// found so its prob not a valid link. bail out. ret = -99; goto return_ret; } phost = strchr(buffer,'/'); //note : use snprintf instead of strncpy when im done and make the host/file none-const and make the code more permanent if(phost != NULL) { strncpy(host_new,buffer,phost-buffer); strncpy(file_new,&buffer[phost-buffer],strlen(&buffer[phost-buffer])); } else { strncpy(file_new,"/\0",2); strncpy(host_new,buffer,strlen(buffer)); } gprintf("new host & file : %s & %s\n",host_new,file_new); redirects++; GetHTTPFile(host_new,file_new,Data,&socket); if(redirects > 0) { //we were called from some redirect loop, so lets bail out return 1; } else { //we are no longer in a redirect loop. so we proceed like planned :) break; } } break; case 404: //File Not Found. nothing special we can do :) default: //o ow, a reply we dont understand yet D: close connection and bail out net_close(socket); ret = -7; goto return_ret; break; } } if( !memcmp( buffer, "Content-Length: ", 16 ) ) { sscanf( buffer , "Content-Length: %d", &file_size ); } else if( !memcmp( buffer, "\x0D\x0A", 2 ) ) break; } if(file_size == 0) { if(!external_socket_to_use) net_close(socket); ret = -8; goto return_ret; } Data = (u8*)mem_malloc( file_size ); if (Data == NULL) { ret = -9; goto return_ret; } memset(Data,0,sizeof(u8)); s32 total = 0; gdprintf( "Download: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\r", 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176 ); while (total != file_size) { bytes_read = 0; bytes_read = net_recv(socket,buffer,1024, 0); if(!bytes_read) { if(!external_socket_to_use) net_close(socket); free(Data); Data = NULL; ret = -10; goto return_ret; } memcpy( &Data[total], buffer, bytes_read ); total += bytes_read; int Ddone = (total *20 )/ file_size; gdprintf("Download: "); while( Ddone ) { gdprintf( "%c", 178 ); Ddone--; } gdprintf( "\r" ); } gdprintf("\r\n"); } else { net_close(socket); free(Data); Data = NULL; ret = -5; goto return_ret; } net_close(socket); return file_size; return_ret: if(ret < 0) { net_close(socket); redirects = 0; } if(external_socket_to_use != 0) { memset(external_socket_to_use,socket,sizeof(int)); } return ret; }
s8 GetTitleName(u64 id, u32 app, char* name,u8* _dst_uncode_name) { s32 r; int lang = 1; //CONF_GetLanguage(); /* languages: enum { CONF_LANG_JAPANESE = 0, CONF_LANG_ENGLISH, CONF_LANG_GERMAN, CONF_LANG_FRENCH, CONF_LANG_SPANISH, CONF_LANG_ITALIAN, CONF_LANG_DUTCH, CONF_LANG_SIMP_CHINESE, CONF_LANG_TRAD_CHINESE, CONF_LANG_KOREAN }; cause we dont support unicode stuff in font.cpp we will force to use english then(1) */ u8 return_unicode_name = 0; if(_dst_uncode_name == NULL) { return_unicode_name = 0; } else { return_unicode_name = 1; } char file[256] ATTRIBUTE_ALIGN(32); memset(file,0,256); sprintf(file, "/title/%08x/%08x/content/%08x.app", (u32)(id >> 32), (u32)(id & 0xFFFFFFFF), app); gdprintf("GetTitleName : %s\n",file); u32 cnt ATTRIBUTE_ALIGN(32); cnt = 0; IMET *data = (IMET *)mem_align(32, ALIGN32( sizeof(IMET) ) ); if(data == NULL) { gprintf("GetTitleName : IMET header align failure\n"); return -1; } memset(data,0,sizeof(IMET) ); r = ES_GetNumTicketViews(id, &cnt); if(r < 0) { gprintf("GetTitleName : GetNumTicketViews error %d!\n",r); mem_free(data); return -1; } tikview *views = (tikview *)mem_align( 32, sizeof(tikview)*cnt ); if(views == NULL) { mem_free(data); return -2; } r = ES_GetTicketViews(id, views, cnt); if (r < 0) { gprintf("GetTitleName : GetTicketViews error %d \n",r); mem_free(data); mem_free(views); return -3; } //lets get this party started with the right way to call ES_OpenTitleContent. and not like how libogc < 1.8.3 does it. patch was passed on , and is done correctly in 1.8.3 //the right way is ES_OpenTitleContent(u64 TitleID,tikview* views,u16 Index); note the views >_> s32 fh = ES_OpenTitleContent(id, views, 0); if (fh == -106) { CheckTitleOnSD(id); mem_free(data); mem_free(views); return -106; } else if(fh < 0) { //ES method failed. remove tikviews from memory and fall back on ISFS method gprintf("GetTitleName : ES_OpenTitleContent error %d\n",fh); mem_free(views); fh = ISFS_Open(file, ISFS_OPEN_READ); // f**k failed. lets check SD & GTFO if (fh == -106) { CheckTitleOnSD(id); return -106; } else if (fh < 0) { mem_free(data); gprintf("open %s error %d\n",file,fh); return -5; } // read the completed IMET header r = ISFS_Read(fh, data, sizeof(IMET)); if (r < 0) { gprintf("IMET read error %d\n",r); ISFS_Close(fh); mem_free(data); return -6; } ISFS_Close(fh); } else { //ES method r = ES_ReadContent(fh,(u8*)data,sizeof(IMET)); if (r < 0) { gprintf("GetTitleName : ES_ReadContent error %d\n",r); ES_CloseContent(fh); mem_free(data); mem_free(views); return -8; } //free data and let it point to IMET_data so everything else can work just fine ES_CloseContent(fh); mem_free(views); } char str[10][84]; char str_unprocessed[10][84]; //clear any memory that is in the place of the array cause we dont want any confusion here memset(str,0,10*84); if(return_unicode_name) memset(str_unprocessed,0,10*84); if(data->imet == 0x494d4554) // check if its a valid imet header { for(u8 y =0;y <= 9;y++) { u8 p = 0; u8 up = 0; for(u8 j=0;j<83;j++) { if(data->names[y][j] < 0x20) if(return_unicode_name && data->names[y][j] == 0x00) str_unprocessed[y][up++] = data->names[y][j]; else continue; else if(data->names[y][j] > 0x7E) continue; else { str[y][p++] = data->names[y][j]; str_unprocessed[y][up++] = data->names[y][j]; } } str[y][83] = '\0'; } mem_free(data); } else { gprintf("invalid IMET header for 0x%08x/0x%08x\n", (u32)(id >> 32), (u32)(id & 0xFFFFFFFF)); return -9; } if(str[lang][0] != '\0') { gdprintf("GetTitleName : title %s\n",str[lang]); snprintf(name,255, "%s", str[lang]); if (return_unicode_name && str_unprocessed[lang][1] != '\0') { memcpy(_dst_uncode_name,&str_unprocessed[lang][0],83); } else if(return_unicode_name) gprintf("WARNING : empty unprocessed string\n"); } else gprintf("GetTitleName: no name found\n"); memset(str,0,10*84); memset(str_unprocessed,0,10*84); return 1; }