void GameTracker::AddDirectory(const QString& dir) { if (!QFileInfo(dir).exists()) return; addPath(dir); UpdateDirectory(dir); }
void SaveFileDialog::Confirm() { Logger().debugStream() << "SaveFileDialog::Confirm: Confirming"; if(!CheckChoiceValidity()){ Logger().debugStream() << "SaveFileDialog::Confirm: Invalid choice. abort."; return; } /// Check if we chose a directory std::string choice = m_name_edit->Text(); fs::path current_dir ( m_current_dir_edit->Text() ); if ( !choice.empty() ) { fs::path chosen = current_dir / choice; if ( fs::is_directory ( chosen ) ) { Logger().debugStream() << "SaveFileDialog::Confirm: " << chosen << " is a directory. Listing content."; UpdateDirectory ( PathString ( chosen ) ); return; } else { Logger().debugStream() << "SaveFileDialog::Confirm: File " << chosen << " chosen."; } } else { Logger().debugStream() << "SaveFileDialog::Confirm: Returning no file."; } CloseClicked(); }
void COptionsDirectoriesPage::ApplySettings(bool UpdateScreen) { UpdateDirectory(m_PluginDir, Directory_PluginSelected); UpdateDirectory(m_AutoSaveDir, Directory_NativeSaveSelected); UpdateDirectory(m_InstantSaveDir, Directory_InstantSaveSelected); UpdateDirectory(m_ScreenShotDir, Directory_SnapShotSelected); UpdateDirectory(m_TextureDir, Directory_TextureSelected); UpdateDefaultSelected(m_PluginDefault, Directory_PluginUseSelected); UpdateDefaultSelected(m_AutoSaveDefault, Directory_NativeSaveUseSelected); UpdateDefaultSelected(m_InstantDefault, Directory_InstantSaveUseSelected); UpdateDefaultSelected(m_ScreenShotDefault, Directory_SnapShotUseSelected); UpdateDefaultSelected(m_TextureDefault, Directory_TextureUseSelected); if (UpdateScreen) { UpdatePageSettings(); } }
/** \fn GalleryDatabaseHelper::UpdateData(ImageMetadata *) * \brief Updates either a directory or a file in the database * \param im Information of the given item * \return void */ void GalleryDatabaseHelper::UpdateData(ImageMetadata *im) { if (!im) return; if (im->m_type == kSubDirectory || im->m_type == kUpDirectory) UpdateDirectory(im); if (im->m_type == kImageFile || im->m_type == kVideoFile) UpdateFile(im); }
void SaveFileDialog::BrowseDirectories() { std::vector<std::pair<std::string, std::string> > dummy; FileDlg dlg ( m_current_dir_edit->Text(), "", false, false, dummy ); dlg.SelectDirectories ( true ); dlg.Run(); if ( !dlg.Result().empty() ) { // Normalize the path by converting it into a path and back fs::path choice ( *dlg.Result().begin() ); UpdateDirectory ( PathString ( fs::canonical ( choice ) ) ); } }
status_t SlideShowSaver::StartSaver(BView *view, bool preview) { UpdateShowCaption(); UpdateShowBorder(); if (UpdateDirectory() != B_OK) return B_ERROR; // Read ticksize setting and set it as the delay UpdateTickSize(); return B_OK; }
// Called by fSettings to notify that someone has changed // a setting. For example, if the user changes a setting // on the config panel, this will be called to notify this // object. void SlideShowSaver::SettingChanged(uint32 setting) { switch (setting) { case CHANGE_CAPTION: UpdateShowCaption(); break; case CHANGE_BORDER: UpdateShowBorder(); break; case CHANGE_DIRECTORY: UpdateDirectory(); break; case CHANGE_DELAY: UpdateTickSize(); break; default: break; } }
/**************************************************************************** * FileSelector * * Browse directories and select a file from the file listing * return ROM size * ****************************************************************************/ int FileSelector(int type) { short p; int i; int old = -1; char fname[MAXPATHLEN]; FILE *snap; gui_menu *m = &menu_selector; #ifdef HW_RVL int x,y; gui_butn *button; #endif /* Background overlay */ if (config.bg_overlay) { bg_filesel[1].state |= IMAGE_VISIBLE; } else { bg_filesel[1].state &= ~IMAGE_VISIBLE; } /* Hide all cartridge labels */ for (i=0; i<FILETYPE_MAX; i++) { bg_filesel[9+i].state &= ~IMAGE_VISIBLE; } /* Cartridge type */ if (type < 0) { /* Recent game list -> select all cartridge type */ for (i=0; i<FILETYPE_MAX; i++) { bg_filesel[9+i].data = Cart_png[i]; } } else { /* Clear all cartridges type */ for (i=0; i<FILETYPE_MAX; i++) { bg_filesel[9+i].data = NULL; } /* Select cartridge type */ bg_filesel[9 + type].data = Cart_png[type]; bg_filesel[9 + type].state |= IMAGE_VISIBLE; } /* Initialize Menu */ GUI_InitMenu(m); string_offset = 0; while (1) { /* ROM file snapshot/database */ if (old != selection) { /* close any existing texture first */ gxTextureClose(&bg_filesel[8].texture); bg_filesel[8].state &= ~IMAGE_VISIBLE; old = selection; string_offset = 0; if (!filelist[selection].flags) { /* recent game list -> variable game types */ if (type < 0) { /* hide all cartridge labels */ for (i=0; i<FILETYPE_MAX; i++) { bg_filesel[9+i].state &= ~IMAGE_VISIBLE; } /* detect cartridge type */ type = history.entries[selection].filetype; /* show selected cartridge label */ bg_filesel[9 + type].state |= IMAGE_VISIBLE; /* default screenshot file path */ sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename); /* restore recent type flag */ type = -1; } else { /* default screenshot file path */ sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename); } /* remove original file extension */ i = strlen(fname) - 1; while ((i > 0) && (fname[i] != '.')) i--; if (i > 0) fname[i] = 0; /* add PNG file extension */ strcat(fname, ".png"); /* try to load screenshot file */ snap = fopen(fname, "rb"); if (snap) { bg_filesel[8].texture = gxTextureOpenPNG(0,snap); if (bg_filesel[8].texture) { bg_filesel[8].state |= IMAGE_VISIBLE; } fclose(snap); } } } /* update helper */ if (m->selected != -1) { /* out of focus */ strcpy(action_select.comment,""); } else if (filelist[selection].flags) { /* this is a directory */ strcpy(action_select.comment,"Open Directory"); } else { /* this is a ROM file */ strcpy(action_select.comment,"Load File"); } /* Draw menu*/ GUI_DrawMenu(m); #ifdef HW_RVL if (Shutdown) { gxTextureClose(&w_pointer); GUI_DeleteMenu(m); GUI_FadeOut(); shutdown(); SYS_ResetSystem(SYS_POWEROFF, 0, 0); } else if (m_input.ir.valid) { /* get cursor position */ x = m_input.ir.x; y = m_input.ir.y; /* draw wiimote pointer */ gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); /* ensure we are in the selectable area */ if ((x < 380) && (y >= 108) && (y <= 368)) { /* find selected item */ selection = (y - 108) / 26; if (selection > 9) selection = 9; selection += offset; if (selection >= maxfiles) selection = old; /* reset selection */ m->selected = -1; } else { /* disable selection */ m->selected = m->max_buttons + 2; /* find selected button */ for (i=0; i<2; i++) { button = m->arrows[i]; if (button) { if (button->state & BUTTON_VISIBLE) { if ((x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) { m->selected = m->max_buttons + i; break; } } } } } } else { /* reset selection */ m->selected = -1; } #endif /* copy EFB to XFB */ gxSetScreen(); p = m_input.keys; /* highlight next item */ if (p & PAD_BUTTON_DOWN) { selection++; if (selection == maxfiles) selection = offset = 0; if ((selection - offset) >= 10) offset += 10; } /* highlight previous item */ else if (p & PAD_BUTTON_UP) { selection--; if (selection < 0) { selection = maxfiles - 1; offset = maxfiles - 10; } if (selection < offset) offset -= 10; if (offset < 0) offset = 0; } /* go back one page */ else if (p & (PAD_TRIGGER_L | PAD_BUTTON_LEFT)) { if (maxfiles >= 10) { selection -= 10; if (selection < 0) { selection = offset = 0; } else if (selection < offset) { offset -= 10; if (offset < 0) offset = 0; } } } /* go forward one page */ else if (p & (PAD_TRIGGER_R | PAD_BUTTON_RIGHT)) { if (maxfiles >= 10) { selection += 10; if (selection > maxfiles - 1) { /* last page */ selection = maxfiles - 1; offset = maxfiles - 10; } else if (selection >= (offset + 10)) { /* next page */ offset += 10; if (offset > (maxfiles - 10)) offset = maxfiles - 10; } } } /* quit */ else if (p & PAD_TRIGGER_Z) { GUI_DeleteMenu(m); return 0; } /* previous directory */ else if (p & PAD_BUTTON_B) { string_offset = 0; /* update browser directory (and get current folder)*/ if (UpdateDirectory(1, prev_folder)) { /* get directory entries */ maxfiles = ParseDirectory(); /* clear selection by default */ selection = offset = 0; old = -1; /* select previous directory */ for (i=0; i<maxfiles; i++) { if ((filelist[i].flags) && !strcmp(prev_folder,filelist[i].filename)) { selection = i; while (i >= (offset + 10)) { offset += 10; if (offset > (maxfiles - 10)) offset = maxfiles - 10; } break; } } } else { /* exit */ GUI_DeleteMenu(m); return 0; } } /* open selected file or directory */ else if (p & PAD_BUTTON_A) { string_offset = 0; /* ensure we are in focus area */ if (m->selected < m->max_buttons) { if (filelist[selection].flags) { /* get new directory */ UpdateDirectory(0, filelist[selection].filename); /* get directory entries */ maxfiles = ParseDirectory(); /* clear selection by default */ selection = offset = 0; old = -1; } else { /* load ROM file from device */ int ret = LoadFile(selection); /* exit menu */ GUI_DeleteMenu(m); /* return ROM size (or zero if an error occured) */ return ret; } } #ifdef HW_RVL /* arrow buttons selected */ else if (m->selected == m->max_buttons) { /* up arrow */ selection--; if (selection < 0) { selection = maxfiles - 1; offset = selection - 10 + 1; } if (selection < offset) offset -= 10; if (offset < 0) offset = 0; } else if (m->selected == (m->max_buttons+1)) { /* down arrow */ selection++; if (selection == maxfiles) selection = offset = 0; if ((selection - offset) >= 10) offset += 10; } #endif } } }
/**************************************************************************** * FileSelector * * Browse directories and select a file from the file listing * return ROM size * ****************************************************************************/ int FileSelector(int type) { short p; int i; int old = -1; char fname[MAXPATHLEN]; FILE *snap; gui_menu *m = &menu_selector; int offset_ = -1; int selection_ = -1; int maxfiles_ = -1; #ifdef HW_RVL int x,y; gui_butn *button; #endif /* Background overlay */ if (config.bg_overlay) { bg_filesel[1].state |= IMAGE_VISIBLE; } else { bg_filesel[1].state &= ~IMAGE_VISIBLE; } /* Hide all cartridge labels */ for (i=0; i<FILETYPE_MAX; i++) { bg_filesel[9+i].data = NULL; bg_filesel[9+i].state &= ~IMAGE_VISIBLE; } /* System ROM selection */ if (type >= FILETYPE_MAX) { /* Save current ROM browser */ offset_ = offset; maxfiles_ = maxfiles; selection_ = selection; /* Initialize ROM browser */ maxfiles = ParseDirectory(); selection = offset = 0; while (selection < maxfiles) { if (strstr(config.sys_rom[type-FILETYPE_MAX], filelist[selection].filename)) { offset = selection; while ((offset > (maxfiles - 10)) && (offset > 0)) { offset--; } break; } selection++; } /* By default, select first file in directory if ROM is not found */ if (selection >= maxfiles) { selection = 0; } /* Set menu title and cartridge label type */ switch (type - FILETYPE_MAX) { case 0: { strcpy(m->title,"Sega CD (USA) BIOS Selection"); type = FILETYPE_MD; break; } case 1: { strcpy(m->title,"Mega CD (PAL) BIOS Selection"); type = FILETYPE_MD; break; } case 2: { strcpy(m->title,"Mega CD (JAP) BIOS Selection"); type = FILETYPE_MD; break; } case 3: { strcpy(m->title,"Mega Drive/Genesis BootROM Selection"); type = FILETYPE_MD; break; } case 4: { strcpy(m->title,"Master System (USA) BootROM Selection"); type = FILETYPE_MS; break; } case 5: { strcpy(m->title,"Master System (PAL) BootROM Selection"); type = FILETYPE_MS; break; } case 6: { strcpy(m->title,"Master System (JAP) BootROM Selection"); type = FILETYPE_MS; break; } case 7: { strcpy(m->title,"Game Gear BootROM Selection"); type = FILETYPE_GG; break; } case 8: { strcpy(m->title,"Game Genie ROM Selection"); type = FILETYPE_MD; break; } case 9: { strcpy(m->title,"Action Replay (Pro) ROM Selection"); type = FILETYPE_MD; break; } case 10: { strcpy(m->title,"Sonic & Knuckles ROM Selection"); type = FILETYPE_MD; break; } case 11: { strcpy(m->title,"Sonic 2 & Knuckles ROM Selection"); type = FILETYPE_MD; break; } } } else { /* reset menu title */ strcpy(m->title, "Game Selection"); } /* Set default helper for Back button */ strcpy(m->helpers[0]->comment, "Exit"); /* Check if we are not browsing recent file list */ if (type >= 0) { /* Select cartridge type */ bg_filesel[9 + type].data = Cart_png[type]; bg_filesel[9 + type].state |= IMAGE_VISIBLE; /* Get current directory */ char *dir = GetCurrentDirectory(); /* Get current directory name length */ int size = strlen(dir); /* Check if we are not in Root directory */ if (size > 1) { if (dir[size - 2] != ':') { /* Update helper for Back button */ strcpy(m->helpers[0]->comment, "Previous Directory"); } } /* Initialize directory icon */ dir_icon.texture = gxTextureOpenPNG(Browser_dir_png,0); dir_icon.w = dir_icon.texture->width; dir_icon.h = dir_icon.texture->height; dir_icon.x = 26; dir_icon.y = (26 - dir_icon.h)/2; } /* Initialize selection bar */ bar_over.texture = gxTextureOpenPNG(Overlay_bar_png,0); bar_over.w = bar_over.texture->width; bar_over.h = bar_over.texture->height; bar_over.x = 16; bar_over.y = (26 - bar_over.h)/2; /* Initialize Menu */ GUI_InitMenu(m); string_offset = 0; while (1) { /* ROM file snapshot/database */ if (old != selection) { /* close any screenshot texture first */ gxTextureClose(&bg_filesel[8].texture); bg_filesel[8].state &= ~IMAGE_VISIBLE; old = selection; string_offset = 0; if (!filelist[selection].flags) { /* recent game list -> variable game types */ if (type < 0) { /* check if game type has changed */ type = history.entries[selection].filetype; if (!(bg_filesel[9 + type].state & IMAGE_VISIBLE)) { /* hide all cartridge labels */ for (i=0; i<FILETYPE_MAX; i++) { gxTextureClose(&bg_filesel[9 + i].texture); bg_filesel[9 + i].state &= ~IMAGE_VISIBLE; } /* open cartridge label texture */ bg_filesel[9 + type].texture = gxTextureOpenPNG(Cart_png[type],0); /* show selected cartridge label */ bg_filesel[9 + type].state |= IMAGE_VISIBLE; } /* default screenshot file path */ sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename); /* restore recent type flag */ type = -1; } else { /* default screenshot file path */ sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename); } /* remove original file extension */ i = strlen(fname) - 1; while ((i > 0) && (fname[i] != '.')) i--; if (i > 0) fname[i] = 0; /* add PNG file extension */ strcat(fname, ".png"); /* try to load screenshot file */ snap = fopen(fname, "rb"); if (snap) { bg_filesel[8].texture = gxTextureOpenPNG(0,snap); if (bg_filesel[8].texture) { bg_filesel[8].state |= IMAGE_VISIBLE; } fclose(snap); } } } /* update Action button helper */ if (m->selected != -1) { /* out of focus */ strcpy(action_select.comment,""); } else if (filelist[selection].flags) { /* this is a directory */ strcpy(action_select.comment,"Open Directory"); } else { /* this is a ROM file */ if (offset_ != -1) { /* System ROM browser */ strcpy(action_select.comment,"Select File"); } else { /* Normal ROM browser */ strcpy(action_select.comment,"Load File"); } } /* Draw menu*/ GUI_DrawMenu(m); #ifdef HW_RVL if (Shutdown) { gxTextureClose(&bar_over.texture); gxTextureClose(&dir_icon.texture); gxTextureClose(&w_pointer); GUI_DeleteMenu(m); GUI_FadeOut(); shutdown(); SYS_ResetSystem(SYS_POWEROFF, 0, 0); } else if (m_input.ir.valid) { /* get cursor position */ x = m_input.ir.x; y = m_input.ir.y; /* draw wiimote pointer */ gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); /* ensure we are in the selectable area */ if ((x < 380) && (y >= 108) && (y <= 368)) { /* find selected item */ selection = (y - 108) / 26; if (selection > 9) selection = 9; selection += offset; if (selection >= maxfiles) selection = old; /* reset selection */ m->selected = -1; } else { /* disable selection */ m->selected = m->max_buttons + 2; /* find selected button */ for (i=0; i<2; i++) { button = m->arrows[i]; if (button) { if (button->state & BUTTON_VISIBLE) { if ((x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) { m->selected = m->max_buttons + i; break; } } } } } } else { /* reset selection */ m->selected = -1; } #endif /* copy EFB to XFB */ gxSetScreen(); p = m_input.keys; /* highlight next item */ if (p & PAD_BUTTON_DOWN) { selection++; if (selection >= maxfiles) selection = offset = 0; else if (selection >= (offset + 10)) offset++; } /* highlight previous item */ else if (p & PAD_BUTTON_UP) { selection--; if (selection < 0) { selection = maxfiles - 1; offset = maxfiles - 10; if (offset < 0) offset = 0; } else if (selection < offset) offset --; } /* go back one page */ else if (p & (PAD_TRIGGER_L | PAD_BUTTON_LEFT)) { if (maxfiles >= 10) { selection -= 10; if (selection < 0) { /* first page */ selection = offset = 0; } else if (selection < offset) { /* previous page */ offset -= 10; if (offset < 0) offset = 0; } } } /* go forward one page */ else if (p & (PAD_TRIGGER_R | PAD_BUTTON_RIGHT)) { if (maxfiles >= 10) { selection += 10; if (selection > maxfiles - 1) { /* last page */ selection = maxfiles - 1; offset = maxfiles - 10; } else if (selection >= (offset + 10)) { /* next page */ offset += 10; if (offset > (maxfiles - 10)) offset = maxfiles - 10; } } } /* quit */ else if (p & PAD_TRIGGER_Z) { /* System ROM selection */ if (offset_ != -1) { /* restore current ROM browser */ offset = offset_; maxfiles = maxfiles_; selection = selection_; } gxTextureClose(&bar_over.texture); gxTextureClose(&dir_icon.texture); GUI_DeleteMenu(m); return -1; } /* previous directory */ else if (p & PAD_BUTTON_B) { string_offset = 0; /* recent ROM list */ if (type < 0) { /* exit */ gxTextureClose(&bar_over.texture); gxTextureClose(&dir_icon.texture); GUI_DeleteMenu(m); return -1; } /* update browser directory (and get current folder)*/ if (UpdateDirectory(1, prev_folder)) { /* get directory entries */ maxfiles = ParseDirectory(); /* Get current directory */ char *dir = GetCurrentDirectory(); /* current directory name length */ int size = strlen(dir); /* Adjust helper for back button */ if ((size > 1) && (dir[size - 2] != ':')) { /* Back button goes up one directory */ strcpy(m->helpers[0]->comment, "Previous Directory"); } else { /* Back button exits from root directory */ strcpy(m->helpers[0]->comment, "Exit"); } /* clear selection by default */ selection = offset = 0; old = -1; /* select previous directory */ for (i=0; i<maxfiles; i++) { if ((filelist[i].flags) && !strcmp(prev_folder,filelist[i].filename)) { selection = i; while (i >= (offset + 10)) { offset += 10; if (offset > (maxfiles - 10)) offset = maxfiles - 10; } break; } } } else { /* System ROM selection */ if (offset_ != -1) { /* restore current ROM browser */ offset = offset_; maxfiles = maxfiles_; selection = selection_; } /* Exit */ gxTextureClose(&bar_over.texture); gxTextureClose(&dir_icon.texture); GUI_DeleteMenu(m); return -1; } } /* open selected file or directory */ else if (p & PAD_BUTTON_A) { string_offset = 0; /* ensure we are in focus area */ if (m->selected < m->max_buttons) { if (filelist[selection].flags) { /* get new directory */ UpdateDirectory(0, filelist[selection].filename); /* get directory entries */ maxfiles = ParseDirectory(); /* clear selection by default */ selection = offset = 0; old = -1; } else { int ret; /* System ROM selection */ if (offset_ != -1) { /* return ROM file index */ ret = selection; /* restore current ROM browser */ offset = offset_; maxfiles = maxfiles_; selection = selection_; } else { /* load ROM file from device then return ROM size (zero if an error occured) */ ret = LoadFile(selection); } /* exit menu */ gxTextureClose(&bar_over.texture); gxTextureClose(&dir_icon.texture); GUI_DeleteMenu(m); return ret; } } #ifdef HW_RVL /* arrow buttons selected */ else if (m->selected == m->max_buttons) { /* up arrow */ selection--; if (selection < 0) { selection = maxfiles - 1; offset = selection - 10 + 1; } if (selection < offset) offset -= 10; if (offset < 0) offset = 0; } else if (m->selected == (m->max_buttons+1)) { /* down arrow */ selection++; if (selection == maxfiles) selection = offset = 0; if ((selection - offset) >= 10) offset += 10; } #endif } } }
// Write pending operations into ZIP archive bool csArchive::WriteZipArchive () { char temp_file[MAXPATHLEN]; FILE *temp; char buff [16 * 1024]; bool success = false; int n = 0; // Check if file is opened for reading first if (!file) return false; // Step one: Copy archive file into a temporary file, // skipping entries marked as 'deleted' strcpy (temp_file, TEMP_DIR); int tmplen = strlen (temp_file); APPEND_SLASH (temp_file, tmplen); sprintf (&temp_file[tmplen], TEMP_FILE); if ((temp = fopen (temp_file, "w+b")) == NULL) return false; /* Cannot create temporary file */ fseek (file, 0, SEEK_SET); while (fread (buff, 1, sizeof (hdr_local), file) == sizeof (hdr_local)) { size_t bytes_to_copy, bytes_to_skip; ArchiveEntry *this_file = NULL; if (memcmp (buff, hdr_local, sizeof (hdr_local)) == 0) { // local header ZIP_local_file_header lfh; if (!ReadLFH (lfh, file)) goto temp_failed; char *this_name = new char[lfh.filename_length + 1]; if (fread (this_name, 1, lfh.filename_length, file) < lfh.filename_length) { delete [] this_name; goto temp_failed; } this_name[lfh.filename_length] = 0; if (IsDeleted (this_name)) { skip_entry: bytes_to_skip = lfh.extra_field_length + lfh.csize; bytes_to_copy = 0; delete [] this_name; } else { this_file = (ArchiveEntry *) FindName (this_name); if (!this_file) /* This means we found a entry in archive which is not * present in our `dir' array: this means either the ZIP * file has changed after we read the ZIP directory, * or this is a `pure directory' entry (which we ignore * during reading). In any case, just copy it unchanged * into the output file. */ goto skip_entry; delete [] this_name; if (this_file->info.csize != lfh.csize) goto temp_failed; /* Broken archive */ this_file->ReadExtraField (file, lfh.extra_field_length); bytes_to_skip = 0; bytes_to_copy = lfh.csize; if (!this_file->WriteLFH (temp)) goto temp_failed; /* Write error */ } } else if (memcmp (buff, hdr_central, sizeof (hdr_central)) == 0) { // central directory header ZIP_central_directory_file_header cdfh; if (!ReadCDFH (cdfh, file)) goto temp_failed; bytes_to_copy = 0; bytes_to_skip = cdfh.filename_length + cdfh.extra_field_length + cdfh.file_comment_length; } else if (memcmp (buff, hdr_endcentral, sizeof (hdr_endcentral)) == 0) { // end-of-central-directory header ZIP_end_central_dir_record ecdr; char buff [ZIP_END_CENTRAL_DIR_RECORD_SIZE]; if (fread (buff, 1, ZIP_END_CENTRAL_DIR_RECORD_SIZE, file) < ZIP_END_CENTRAL_DIR_RECORD_SIZE) goto temp_failed; LoadECDR (ecdr, buff); bytes_to_copy = 0; bytes_to_skip = ecdr.zipfile_comment_length; } else { // Unknown chunk type goto temp_failed; } /* endif */ if (bytes_to_skip) fseek (file, bytes_to_skip, SEEK_CUR); while (bytes_to_copy) { size_t size; if (bytes_to_copy > sizeof (buff)) size = sizeof (buff); else size = bytes_to_copy; if ((fread (buff, 1, size, file) < size) || (fwrite (buff, 1, size, temp) < size)) goto temp_failed; bytes_to_copy -= size; } } /* endwhile */ /* Now we have to append all files that were added to archive */ for (n = 0; n < lazy.Length (); n++) { ArchiveEntry *f = lazy.Get (n); if (!f->WriteFile (temp)) goto temp_failed; /* Write error */ } /* endfor */ /* And finaly write central directory structure */ if (!WriteCentralDirectory (temp)) goto temp_failed; /* Now copy temporary file into archive. If we'll get a error in process, */ /* we're lost! I don't know for a good solution for this without wasting */ /* disk space for yet another copy of the archive :-( */ { fseek (temp, 0, SEEK_END); size_t fsize = ftell (temp); fseek (temp, 0, SEEK_SET); fclose (file); if ((file = fopen (filename, "wb")) == NULL) { file = fopen (filename, "rb"); goto temp_failed; } while (fsize) { size_t bytes_read = fread (buff, 1, sizeof (buff), temp); if (fwrite (buff, 1, bytes_read, file) < bytes_read) { /* Yuck! Keep at least temporary file */ fclose (temp); fclose (file); file = fopen (filename, "rb"); return false; } fsize -= bytes_read; } /* Hurray! We're done */ fclose (file); file = fopen (filename, "rb"); } /* Now if we are here, all operations have been successful */ UpdateDirectory (); success = true; temp_failed: fclose (temp); unlink (temp_file); return success; }