void check_extension( char *package, char *name, int *major, int *minor, int *revision ) { int error; char tmp[2048]; FILE *f; *(int*)&tmp[0] = 0; memset( &tmp[4], 0, 2044 ); fwrite( "Checking extension ...", 1, 22, stdout ); strcpy( tmp, package ); error = chdir( tmp ); if ( error < 0 ) { print_error( -2, "extension '%s' not accessible: %s\n", package, strerror( *(int*)(__errno_location( )) ) ); } f = (FILE*)fopen( "id", "r" ); if ( f == 0 ) print_error( -6, "'id' file not readable.\n" ); else { __isoc99_fscanf( f, "%[<GRASS extension package>] ", &tmp ); if ( strcmp( "<GRASS extension package>", tmp ) ) { fclose( f ); print_error( -6, "unknown file identifier.\n" ); } } fclose( f ); get_package_name( ".", name ); f = (FILE*)fopen( "version", "r" ); if ( f == 0 ) print_error( -6, "'version' file not readable.\n" ); else { nc_fgets_nb( tmp, 2048, f ); minor[0] = 0; revision[0] = 0; error = __isoc99_sscanf( tmp, "%i.%i.%i", major, minor, revision ); if ( error <= 0 ) { fclose( f ); print_error( -6, "invalid or missing version information.\n" ); } } print_done( ); chdir( ".." ); fclose( f ); return; }
void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest,bool p_give_internet) { const int CHUNK_AXML_FILE = 0x00080003; const int CHUNK_RESOURCEIDS = 0x00080180; const int CHUNK_STRINGS = 0x001C0001; const int CHUNK_XML_END_NAMESPACE = 0x00100101; const int CHUNK_XML_END_TAG = 0x00100103; const int CHUNK_XML_START_NAMESPACE = 0x00100100; const int CHUNK_XML_START_TAG = 0x00100102; const int CHUNK_XML_TEXT = 0x00100104; const int UTF8_FLAG = 0x00000100; Vector<String> string_table; uint32_t ofs=0; uint32_t header = decode_uint32(&p_manifest[ofs]); uint32_t filesize = decode_uint32(&p_manifest[ofs+4]); ofs+=8; // print_line("FILESIZE: "+itos(filesize)+" ACTUAL: "+itos(p_manifest.size())); uint32_t string_count; uint32_t styles_count; uint32_t string_flags; uint32_t string_data_offset; uint32_t styles_offset; uint32_t string_table_begins; uint32_t string_table_ends; Vector<uint8_t> stable_extra; while(ofs < p_manifest.size()) { uint32_t chunk = decode_uint32(&p_manifest[ofs]); uint32_t size = decode_uint32(&p_manifest[ofs+4]); switch(chunk) { case CHUNK_STRINGS: { int iofs=ofs+8; string_count=decode_uint32(&p_manifest[iofs]); styles_count=decode_uint32(&p_manifest[iofs+4]); uint32_t string_flags=decode_uint32(&p_manifest[iofs+8]); string_data_offset=decode_uint32(&p_manifest[iofs+12]); styles_offset=decode_uint32(&p_manifest[iofs+16]); /* printf("string count: %i\n",string_count); printf("flags: %i\n",string_flags); printf("sdata ofs: %i\n",string_data_offset); printf("styles ofs: %i\n",styles_offset); */ uint32_t st_offset=iofs+20; string_table.resize(string_count); uint32_t string_end=0; string_table_begins=st_offset; for(int i=0;i<string_count;i++) { uint32_t string_at = decode_uint32(&p_manifest[st_offset+i*4]); string_at+=st_offset+string_count*4; ERR_EXPLAIN("Unimplemented, can't read utf8 string table."); ERR_FAIL_COND(string_flags&UTF8_FLAG); if (string_flags&UTF8_FLAG) { } else { uint32_t len = decode_uint16(&p_manifest[string_at]); Vector<CharType> ucstring; ucstring.resize(len+1); for(int j=0;j<len;j++) { uint16_t c=decode_uint16(&p_manifest[string_at+2+2*j]); ucstring[j]=c; } string_end=MAX(string_at+2+2*len,string_end); ucstring[len]=0; string_table[i]=ucstring.ptr(); } // print_line("String "+itos(i)+": "+string_table[i]); } for(int i=string_end;i<(ofs+size);i++) { stable_extra.push_back(p_manifest[i]); } // printf("stable extra: %i\n",int(stable_extra.size())); string_table_ends=ofs+size; // print_line("STABLE SIZE: "+itos(size)+" ACTUAL: "+itos(string_table_ends)); } break; case CHUNK_XML_START_TAG: { int iofs=ofs+8; uint32_t line=decode_uint32(&p_manifest[iofs]); uint32_t nspace=decode_uint32(&p_manifest[iofs+8]); uint32_t name=decode_uint32(&p_manifest[iofs+12]); uint32_t check=decode_uint32(&p_manifest[iofs+16]); String tname=string_table[name]; // printf("NSPACE: %i\n",nspace); //printf("NAME: %i (%s)\n",name,tname.utf8().get_data()); //printf("CHECK: %x\n",check); uint32_t attrcount=decode_uint32(&p_manifest[iofs+20]); iofs+=28; //printf("ATTRCOUNT: %x\n",attrcount); for(int i=0;i<attrcount;i++) { uint32_t attr_nspace=decode_uint32(&p_manifest[iofs]); uint32_t attr_name=decode_uint32(&p_manifest[iofs+4]); uint32_t attr_value=decode_uint32(&p_manifest[iofs+8]); uint32_t attr_flags=decode_uint32(&p_manifest[iofs+12]); uint32_t attr_resid=decode_uint32(&p_manifest[iofs+16]); String value; if (attr_value!=0xFFFFFFFF) value=string_table[attr_value]; else value="Res #"+itos(attr_resid); String attrname = string_table[attr_name]; String nspace; if (attr_nspace!=0xFFFFFFFF) nspace=string_table[attr_nspace]; else nspace=""; printf("ATTR %i NSPACE: %i\n",i,attr_nspace); printf("ATTR %i NAME: %i (%s)\n",i,attr_name,attrname.utf8().get_data()); printf("ATTR %i VALUE: %i (%s)\n",i,attr_value,value.utf8().get_data()); printf("ATTR %i FLAGS: %x\n",i,attr_flags); printf("ATTR %i RESID: %x\n",i,attr_resid); //replace project information if (tname=="manifest" && attrname=="package") { print_line("FOUND PACKAGE"); string_table[attr_value]=get_package_name(); } //print_line("tname: "+tname); //print_line("nspace: "+nspace); //print_line("attrname: "+attrname); if (tname=="manifest" && /*nspace=="android" &&*/ attrname=="versionCode") { print_line("FOUND versioncode"); encode_uint32(version_code,&p_manifest[iofs+16]); } if (tname=="manifest" && /*nspace=="android" &&*/ attrname=="versionName") { print_line("FOUND versionname"); if (attr_value==0xFFFFFFFF) { WARN_PRINT("Version name in a resource, should be plaintext") } else string_table[attr_value]=version_name; } if (tname=="activity" && /*nspace=="android" &&*/ attrname=="screenOrientation") { encode_uint32(orientation==0?0:1,&p_manifest[iofs+16]); /* print_line("FOUND screen orientation"); if (attr_value==0xFFFFFFFF) { WARN_PRINT("Version name in a resource, should be plaintext") } else { string_table[attr_value]=(orientation==0?"landscape":"portrait"); }*/ } if (tname=="uses-permission" && /*nspace=="android" &&*/ attrname=="name") { if (value.begins_with("godot.custom")) { int which = value.get_slice(".",2).to_int(); if (which>=0 && which<MAX_USER_PERMISSIONS && user_perms[which].strip_edges()!="") { string_table[attr_value]=user_perms[which].strip_edges(); } } else if (value.begins_with("godot.")) { String perm = value.get_slice(".",1); print_line("PERM: "+perm+" HAS: "+itos(perms.has(perm))); if (perms.has(perm) || (p_give_internet && perm=="INTERNET")) { string_table[attr_value]="android.permission."+perm; } } } if (tname=="supports-screens" ) { if (attrname=="smallScreens") { encode_uint32(screen_support[SCREEN_SMALL]?0xFFFFFFFF:0,&p_manifest[iofs+16]); } else if (attrname=="normalScreens") { encode_uint32(screen_support[SCREEN_NORMAL]?0xFFFFFFFF:0,&p_manifest[iofs+16]); } else if (attrname=="largeScreens") { encode_uint32(screen_support[SCREEN_LARGE]?0xFFFFFFFF:0,&p_manifest[iofs+16]); } else if (attrname=="xlargeScreens") { encode_uint32(screen_support[SCREEN_XLARGE]?0xFFFFFFFF:0,&p_manifest[iofs+16]); } } iofs+=20; } } break; } printf("chunk %x: size: %d\n",chunk,size); ofs+=size; }