void upload_new_resource(const std::string& src_filename, std::string name, std::string desc, S32 compression_info, LLFolderType::EType destination_folder_type, LLInventoryType::EType inv_type, U32 next_owner_perms, U32 group_perms, U32 everyone_perms, const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, void *userdata) { // Generate the temporary UUID. std::string filename = gDirUtilp->getTempFilename(); bool created_temp_file = false; LLTransactionID tid; LLAssetID uuid; LLSD args; std::string exten = gDirUtilp->getExtension(src_filename); U32 codec = LLImageBase::getCodecFromExtension(exten); LLAssetType::EType asset_type = LLAssetType::AT_NONE; std::string error_message; BOOL error = FALSE; if (exten.empty()) { std::string short_name = gDirUtilp->getBaseFileName(filename); // No extension error_message = llformat( "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension", short_name.c_str()); args["FILE"] = short_name; upload_error(error_message, "NofileExtension", filename, args); return; } else if (codec == IMG_CODEC_J2C) { asset_type = LLAssetType::AT_TEXTURE; if (!LLViewerTextureList::verifyUploadFile(src_filename, codec)) { error_message = llformat( "Problem with file %s:\n\n%s\n", src_filename.c_str(), LLImage::getLastError().c_str()); args["FILE"] = src_filename; args["ERROR"] = LLImage::getLastError(); upload_error(error_message, "ProblemWithFile", filename, args); return; } filename = src_filename; } else if (codec != IMG_CODEC_INVALID) { // It's an image file, the upload procedure is the same for all asset_type = LLAssetType::AT_TEXTURE; created_temp_file = true; if (!LLViewerTextureList::createUploadFile(src_filename, filename, codec)) { error_message = llformat( "Problem with file %s:\n\n%s\n", src_filename.c_str(), LLImage::getLastError().c_str()); args["FILE"] = src_filename; args["ERROR"] = LLImage::getLastError(); upload_error(error_message, "ProblemWithFile", filename, args); return; } } else if(exten == "wav") { asset_type = LLAssetType::AT_SOUND; // tag it as audio S32 encode_result = 0; llinfos << "Attempting to encode wav as an ogg file" << llendl; encode_result = encode_vorbis_file(src_filename, filename); created_temp_file = true; if (LLVORBISENC_NOERR != encode_result) { switch(encode_result) { case LLVORBISENC_DEST_OPEN_ERR: error_message = llformat( "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str()); args["FILE"] = filename; upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args); break; default: error_message = llformat("Unknown vorbis encode failure on: %s\n", src_filename.c_str()); args["FILE"] = src_filename; upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args); break; } return; } } else if(exten == "ogg") { asset_type = LLAssetType::AT_SOUND; // tag it as audio filename = src_filename; } else if(exten == "tmp") { // This is a generic .lin resource file asset_type = LLAssetType::AT_OBJECT; LLFILE* in = LLFile::fopen(src_filename, "rb"); /* Flawfinder: ignore */ if (in) { // read in the file header char buf[16384]; /* Flawfinder: ignore */ size_t readbytes; S32 version; if (fscanf(in, "LindenResource\nversion %d\n", &version)) { if (2 == version) { // *NOTE: This buffer size is hard coded into scanf() below. char label[MAX_STRING]; /* Flawfinder: ignore */ char value[MAX_STRING]; /* Flawfinder: ignore */ S32 tokens_read; while (fgets(buf, 1024, in)) { label[0] = '\0'; value[0] = '\0'; tokens_read = sscanf( /* Flawfinder: ignore */ buf, "%254s %254s\n", label, value); llinfos << "got: " << label << " = " << value << llendl; if (EOF == tokens_read) { fclose(in); error_message = llformat("corrupt resource file: %s", src_filename.c_str()); args["FILE"] = src_filename; upload_error(error_message, "CorruptResourceFile", filename, args); return; } if (2 == tokens_read) { if (! strcmp("type", label)) { asset_type = (LLAssetType::EType)(atoi(value)); } } else { if (! strcmp("_DATA_", label)) { // below is the data section break; } } // other values are currently discarded } } else { fclose(in); error_message = llformat("unknown linden resource file version in file: %s", src_filename.c_str()); args["FILE"] = src_filename; upload_error(error_message, "UnknownResourceFileVersion", filename, args); return; } } else { // this is an original binary formatted .lin file // start over at the beginning of the file fseek(in, 0, SEEK_SET); const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256; const S32 MAX_ASSET_NAME_LENGTH = 64; S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH; S16 type_num; // read in and throw out most of the header except for the type if (fread(buf, header_size, 1, in) != 1) { llwarns << "Short read" << llendl; } memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */ asset_type = (LLAssetType::EType)type_num; } // copy the file's data segment into another file for uploading LLFILE* out = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */ created_temp_file = true; if (out) { while((readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ { if (fwrite(buf, 1, readbytes, out) != readbytes) { llwarns << "Short write" << llendl; } } fclose(out); } else { fclose(in); error_message = llformat( "Unable to create output file: %s", filename.c_str()); args["FILE"] = filename; upload_error(error_message, "UnableToCreateOutputFile", filename, args); return; } fclose(in); } else { llinfos << "Couldn't open .lin file " << src_filename << llendl; } } else if (exten == "bvh") { error_message = llformat("We do not currently support bulk upload of animation files\n"); upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); return; } // <edit> else if (exten == "anim" || exten == "animatn") { asset_type = LLAssetType::AT_ANIMATION; filename = src_filename; } // </edit> else { // Unknown extension error_message = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str()); error = TRUE;; } // gen a new transaction ID for this asset tid.generate(); if (!error) { uuid = tid.makeAssetID(gAgent.getSecureSessionID()); // copy this file into the vfs for upload S32 file_size; LLAPRFile infile(filename, LL_APR_RB, &file_size); if (infile.getFileHandle()) { LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE); file.setMaxSize(file_size); const S32 buf_size = 65536; U8 copy_buf[buf_size]; while ((file_size = infile.read(copy_buf, buf_size))) { file.write(copy_buf, file_size); } } else { error_message = llformat( "Unable to access output file: %s", filename.c_str()); error = TRUE; } } if (!error) { std::string t_disp_name = display_name; if (t_disp_name.empty()) { t_disp_name = src_filename; } // <edit> hack to create scripts and gestures if(exten == "lsl" || exten == "gesture" || exten == "notecard") // added notecard Oct 15 2009 { LLInventoryType::EType inv_type = LLInventoryType::IT_GESTURE; if(exten == "lsl") inv_type = LLInventoryType::IT_LSL; else if(exten == "gesture") inv_type = LLInventoryType::IT_GESTURE; else if(exten == "notecard") inv_type = LLInventoryType::IT_NOTECARD; create_inventory_item( gAgent.getID(), gAgent.getSessionID(), gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type)), LLTransactionID::tnull, name, uuid.asString(), // fake asset id, but in vfs asset_type, inv_type, NOT_WEARABLE, PERM_ITEM_UNRESTRICTED, new NewResourceItemCallback); } else // </edit> upload_new_resource(tid, asset_type, name, desc, compression_info, // tid destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms, display_name, callback, expected_upload_cost, userdata); } else { llwarns << error_message << llendl; LLSD args; args["ERROR_MESSAGE"] = error_message; LLNotificationsUtil::add("ErrorMessage", args); } if (created_temp_file && LLFile::remove(filename) == -1) { lldebugs << "unable to remove temp file" << llendl; } }
void upload_new_resource(const std::string& src_filename, std::string name, std::string desc, S32 compression_info, LLAssetType::EType destination_folder_type, LLInventoryType::EType inv_type, U32 next_owner_perms, U32 group_perms, U32 everyone_perms, const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, void *userdata) { // Generate the temporary UUID. std::string filename = gDirUtilp->getTempFilename(); LLTransactionID tid; LLAssetID uuid; LLSD args; std::string exten = gDirUtilp->getExtension(src_filename); LLAssetType::EType asset_type = LLAssetType::AT_NONE; std::string error_message; BOOL error = FALSE; if (exten.empty()) { std::string short_name = gDirUtilp->getBaseFileName(filename); // No extension error_message = llformat( "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension", short_name.c_str()); args["FILE"] = short_name; upload_error(error_message, "NofileExtension", filename, args); return; } else if( exten == "bmp") { asset_type = LLAssetType::AT_TEXTURE; if (!LLViewerImageList::createUploadFile(src_filename, filename, IMG_CODEC_BMP )) { error_message = llformat( "Problem with file %s:\n\n%s\n", src_filename.c_str(), LLImage::getLastError().c_str()); args["FILE"] = src_filename; args["ERROR"] = LLImage::getLastError(); upload_error(error_message, "ProblemWithFile", filename, args); return; } } else if( exten == "tga") { asset_type = LLAssetType::AT_TEXTURE; if (!LLViewerImageList::createUploadFile(src_filename, filename, IMG_CODEC_TGA )) { error_message = llformat("Problem with file %s:\n\n%s\n", src_filename.c_str(), LLImage::getLastError().c_str()); args["FILE"] = src_filename; args["ERROR"] = LLImage::getLastError(); upload_error(error_message, "ProblemWithFile", filename, args); return; } } else if( exten == "jpg" || exten == "jpeg") { asset_type = LLAssetType::AT_TEXTURE; if (!LLViewerImageList::createUploadFile(src_filename, filename, IMG_CODEC_JPEG )) { error_message = llformat("Problem with file %s:\n\n%s\n", src_filename.c_str(), LLImage::getLastError().c_str()); args["FILE"] = src_filename; args["ERROR"] = LLImage::getLastError(); upload_error(error_message, "ProblemWithFile", filename, args); return; } } else if( exten == "png") { asset_type = LLAssetType::AT_TEXTURE; if (!LLViewerImageList::createUploadFile(src_filename, filename, IMG_CODEC_PNG )) { error_message = llformat("Problem with file %s:\n\n%s\n", src_filename.c_str(), LLImage::getLastError().c_str()); args["FILE"] = src_filename; args["ERROR"] = LLImage::getLastError(); upload_error(error_message, "ProblemWithFile", filename, args); return; } } else if(exten == "wav") { asset_type = LLAssetType::AT_SOUND; // tag it as audio S32 encode_result = 0; llinfos << "Attempting to encode wav as an ogg file" << llendl; encode_result = encode_vorbis_file(src_filename, filename); if (LLVORBISENC_NOERR != encode_result) { switch(encode_result) { case LLVORBISENC_DEST_OPEN_ERR: error_message = llformat( "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str()); args["FILE"] = filename; upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args); break; default: error_message = llformat("Unknown vorbis encode failure on: %s\n", src_filename.c_str()); args["FILE"] = src_filename; upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args); break; } return; } } else if(exten == "ogg") { asset_type = LLAssetType::AT_SOUND; // tag it as audio filename = src_filename; } else if(exten == "tmp") { // This is a generic .lin resource file asset_type = LLAssetType::AT_OBJECT; LLFILE* in = LLFile::fopen(src_filename, "rb"); /* Flawfinder: ignore */ if (in) { // read in the file header char buf[16384]; /* Flawfinder: ignore */ S32 read; /* Flawfinder: ignore */ S32 version; if (fscanf(in, "LindenResource\nversion %d\n", &version)) { if (2 == version) { // *NOTE: This buffer size is hard coded into scanf() below. char label[MAX_STRING]; /* Flawfinder: ignore */ char value[MAX_STRING]; /* Flawfinder: ignore */ S32 tokens_read; while (fgets(buf, 1024, in)) { label[0] = '\0'; value[0] = '\0'; tokens_read = sscanf( /* Flawfinder: ignore */ buf, "%254s %254s\n", label, value); llinfos << "got: " << label << " = " << value << llendl; if (EOF == tokens_read) { fclose(in); error_message = llformat("corrupt resource file: %s", src_filename.c_str()); args["FILE"] = src_filename; upload_error(error_message, "CorruptResourceFile", filename, args); return; } if (2 == tokens_read) { if (! strcmp("type", label)) { asset_type = (LLAssetType::EType)(atoi(value)); } } else { if (! strcmp("_DATA_", label)) { // below is the data section break; } } // other values are currently discarded } } else { fclose(in); error_message = llformat("unknown linden resource file version in file: %s", src_filename.c_str()); args["FILE"] = src_filename; upload_error(error_message, "UnknownResourceFileVersion", filename, args); return; } } else { // this is an original binary formatted .lin file // start over at the beginning of the file fseek(in, 0, SEEK_SET); const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256; const S32 MAX_ASSET_NAME_LENGTH = 64; S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH; S16 type_num; // read in and throw out most of the header except for the type if (fread(buf, header_size, 1, in) != 1) { llwarns << "Short read" << llendl; } memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */ asset_type = (LLAssetType::EType)type_num; } // copy the file's data segment into another file for uploading LLFILE* out = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */ if (out) { while((read = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ { if (fwrite(buf, 1, read, out) != read) { llwarns << "Short write" << llendl; } } fclose(out); } else { fclose(in); error_message = llformat( "Unable to create output file: %s", filename.c_str()); args["FILE"] = filename; upload_error(error_message, "UnableToCreateOutputFile", filename, args); return; } fclose(in); } else { llinfos << "Couldn't open .lin file " << src_filename << llendl; } } else if(exten == "ogg") { asset_type = LLAssetType::AT_SOUND; // tag it as audio filename = src_filename; } else if (exten == "bvh") { // <edit> THE F**K WE DON'T //error_message = llformat("We do not currently support bulk upload of animation files\n"); //upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); //return; asset_type = LLAssetType::AT_ANIMATION; S32 file_size; LLAPRFile fp; if(!fp.open(src_filename, LL_APR_RB, LLAPRFile::local, &file_size)) { args["ERROR_MESSAGE"] = llformat("Couldn't read file %s\n", src_filename.c_str()); LLNotifications::instance().add("ErrorMessage", args); return; } char* file_buffer = new char[file_size + 1]; if(!fp.read(file_buffer, file_size)) { fp.close(); delete[] file_buffer; args["ERROR_MESSAGE"] = llformat("Couldn't read file %s\n", src_filename.c_str()); LLNotifications::instance().add("ErrorMessage", args); return; } ELoadStatus load_status = E_ST_OK; S32 line_number = 0; LLBVHLoader* loaderp = new LLBVHLoader(file_buffer, load_status, line_number); /// LLBVHLoader* loaderp = new LLBVHLoader(file_buffer); if(!loaderp->isInitialized()) { fp.close(); delete[] file_buffer; args["ERROR_MESSAGE"] = llformat("Couldn't convert file %s to internal animation format\n", src_filename.c_str()); LLNotifications::instance().add("ErrorMessage", args); return; } S32 buffer_size = loaderp->getOutputSize(); U8* buffer = new U8[buffer_size]; LLDataPackerBinaryBuffer dp(buffer, buffer_size); loaderp->serialize(dp); LLAPRFile apr_file; apr_file.open(filename, LL_APR_WB, LLAPRFile::local); apr_file.write(buffer, buffer_size); delete[] file_buffer; delete[] buffer; fp.close(); apr_file.close(); // </edit> } // <edit> else if (exten == "animatn" || exten == "anim" || exten == "neil") { asset_type = LLAssetType::AT_ANIMATION; filename = src_filename; } else if(exten == "j2k" || exten == "jp2" || exten == "texture" || exten == "j2c") { asset_type = LLAssetType::AT_TEXTURE; filename = src_filename; } else if(exten == "gesture") { asset_type = LLAssetType::AT_GESTURE; filename = src_filename; } else if(exten == "notecard") { asset_type = LLAssetType::AT_NOTECARD; filename = src_filename; } else if(exten == "lsl" || exten == "txt" || exten == "lso" | exten == "rtf") { asset_type = LLAssetType::AT_LSL_TEXT; filename = src_filename; } else if(exten == "eyes" || exten == "gloves" || exten == "hair" || exten == "jacket" || exten == "pants" || exten == "shape" || exten == "shirt" || exten == "shoes" || exten == "skin" || exten == "skirt" || exten == "socks" || exten == "underpants" || exten == "tattoo" || exten == "alpha" || exten == "undershirt" || exten == "bodypart" || exten == "clothing") { asset_type = LLAssetType::AT_CLOTHING; filename = src_filename; } // </edit> else { // Unknown extension // *TODO: Translate? // <edit> //error_message = llformat("Unknown file extension .%s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", exten.c_str()); error_message = llformat("Unknown file extension .%s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, .bvh, .animatn, .ogg, .gesture, .notecard, .lsl, .eyes, .gloves, .hair, .jacket, .pants, .shape, .shirt, .shoes, .skin, .skirt, .socks, .underpants, .undershirt, .bodypart, .clothing, .jp2, .j2k, or .j2c", exten.c_str()); // </edit> error = TRUE;; } // gen a new transaction ID for this asset tid.generate(); if (!error) { uuid = tid.makeAssetID(gAgent.getSecureSessionID()); // copy this file into the vfs for upload S32 file_size; LLAPRFile infile ; infile.open(filename, LL_APR_RB, LLAPRFile::local, &file_size); if (infile.getFileHandle()) { LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE); file.setMaxSize(file_size); const S32 buf_size = 65536; U8 copy_buf[buf_size]; while ((file_size = infile.read(copy_buf, buf_size))) { file.write(copy_buf, file_size); } } else { error_message = llformat( "Unable to access output file: %s", filename.c_str()); error = TRUE; } } if (!error) { std::string t_disp_name = display_name; if (t_disp_name.empty()) { t_disp_name = src_filename; } // <edit> hack to create scripts and gestures if(exten == "lsl" || exten == "gesture" || exten == "notecard" || exten == "txt" || exten == "rtf" || exten == "lso") { LLInventoryType::EType inv_type = LLInventoryType::IT_GESTURE; if(exten == "lsl") inv_type = LLInventoryType::IT_LSL; else if(exten == "gesture") inv_type = LLInventoryType::IT_GESTURE; else if(exten == "notecard") inv_type = LLInventoryType::IT_NOTECARD; create_inventory_item( gAgent.getID(), gAgent.getSessionID(), gInventory.findCategoryUUIDForType(asset_type), LLTransactionID::tnull, name, uuid.asString(), // fake asset id, but in vfs asset_type, inv_type, NOT_WEARABLE, PERM_ITEM_UNRESTRICTED, new NewResourceItemCallback); } else // </edit> upload_new_resource(tid, asset_type, name, desc, compression_info, // tid destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms, display_name, callback, expected_upload_cost, userdata); } else { llwarns << error_message << llendl; LLSD args; args["ERROR_MESSAGE"] = error_message; LLNotifications::instance().add("ErrorMessage", args); if(LLFile::remove(filename) == -1) { lldebugs << "unable to remove temp file" << llendl; } LLFilePicker::instance().reset(); } }