/*! * @brief ゲームプレイ中のフロア一時保存出力処理メインルーチン / Attempt to save the temporally saved-floor data * @param sf_ptr 保存フロア参照ポインタ * @param mode 保存オプション * @return なし */ bool save_floor(saved_floor_type *sf_ptr, u32b mode) { FILE *old_fff = NULL; byte old_xor_byte = 0; u32b old_v_stamp = 0; u32b old_x_stamp = 0; char floor_savefile[1024]; int fd = -1; bool ok = FALSE; if (!(mode & SLF_SECOND)) { #ifdef SET_UID # ifdef SECURE /* Get "games" permissions */ beGames(); # endif #endif } /* We have one file already opened */ else { /* Backup original values */ old_fff = fff; old_xor_byte = xor_byte; old_v_stamp = v_stamp; old_x_stamp = x_stamp; } /* New savefile */ sprintf(floor_savefile, "%s.F%02d", savefile, (int)sf_ptr->savefile_id); /* Grab permissions */ safe_setuid_grab(); /* Remove it */ fd_kill(floor_savefile); /* Drop permissions */ safe_setuid_drop(); /* Attempt to save the player */ /* No file yet */ fff = NULL; /* File type is "SAVE" */ FILE_TYPE(FILE_TYPE_SAVE); /* Grab permissions */ safe_setuid_grab(); /* Create the savefile */ fd = fd_make(floor_savefile, 0644); /* Drop permissions */ safe_setuid_drop(); /* File is okay */ if (fd >= 0) { /* Close the "fd" */ (void)fd_close(fd); /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fff = my_fopen(floor_savefile, "wb"); /* Drop permissions */ safe_setuid_drop(); /* Successful open */ if (fff) { /* Write the savefile */ if (save_floor_aux(sf_ptr)) ok = TRUE; /* Attempt to close it */ if (my_fclose(fff)) ok = FALSE; } /* Remove "broken" files */ if (!ok) { /* Grab permissions */ safe_setuid_grab(); (void)fd_kill(floor_savefile); /* Drop permissions */ safe_setuid_drop(); } } if (!(mode & SLF_SECOND)) { #ifdef SET_UID # ifdef SECURE /* Drop "games" permissions */ bePlayer(); # endif #endif } /* We have one file already opened */ else { /* Restore original values */ fff = old_fff; xor_byte = old_xor_byte; v_stamp = old_v_stamp; x_stamp = old_x_stamp; } /* Return the result */ return ok; }
/*! * @brief セーブデータ書き込みのサブルーチン / * Medium level player saver * @return 成功すればtrue * @details * XXX XXX XXX Angband 2.8.0 will use "fd" instead of "fff" if possible */ static bool save_player_aux(char *name) { bool ok = FALSE; int fd = -1; int mode = 0644; /* No file yet */ fff = NULL; /* File type is "SAVE" */ FILE_TYPE(FILE_TYPE_SAVE); /* Grab permissions */ safe_setuid_grab(); /* Create the savefile */ fd = fd_make(name, mode); /* Drop permissions */ safe_setuid_drop(); /* File is okay */ if (fd >= 0) { /* Close the "fd" */ (void)fd_close(fd); /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fff = my_fopen(name, "wb"); /* Drop permissions */ safe_setuid_drop(); /* Successful open */ if (fff) { /* Write the savefile */ if (wr_savefile_new()) ok = TRUE; /* Attempt to close it */ if (my_fclose(fff)) ok = FALSE; } /* Grab permissions */ safe_setuid_grab(); /* Remove "broken" files */ if (!ok) (void)fd_kill(name); /* Drop permissions */ safe_setuid_drop(); } /* Failure */ if (!ok) return (FALSE); counts_write(0, playtime); /* Successful save */ character_saved = TRUE; /* Success */ return (TRUE); }
/* * Initialize a "*_info" array * * Note that we let each entry have a unique "name" and "text" string, * even if the string happens to be empty (everyone has a unique '\0'). */ static errr init_info(cptr filename, header *head) { int fd; errr err = 1; FILE *fp; /* General buffer */ char buf[1024]; #ifdef ALLOW_TEMPLATES /*** Load the binary image file ***/ /* Build the filename */ path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format("%s.raw", filename)); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd >= 0) { #ifdef CHECK_MODIFICATION_TIME err = check_modification_date(fd, format("%s.txt", filename)); #endif /* CHECK_MODIFICATION_TIME */ /* Attempt to parse the "raw" file */ if (!err) err = init_info_raw(fd, head); /* Close it */ fd_close(fd); } /* Do we have to parse the *.txt file? */ if (err) { /*** Make the fake arrays ***/ /* Allocate the "*_info" array */ C_MAKE(head->info_ptr, head->info_size, char); /* MegaHack -- make "fake" arrays */ if (z_info) { C_MAKE(head->name_ptr, z_info->fake_name_size, char); C_MAKE(head->text_ptr, z_info->fake_text_size, char); } /*** Load the ascii template file ***/ /* Build the filename */ path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, format("%s.txt", filename)); /* Open the file */ fp = my_fopen(buf, "r"); /* Parse it */ if (!fp) quit(format("Cannot open '%s.txt' file.", filename)); /* Parse the file */ err = init_info_txt(fp, buf, head, head->parse_info_txt); /* Close it */ my_fclose(fp); /* Errors */ if (err) display_parse_error(filename, err, buf); /*** Dump the binary image file ***/ /* File type is "DATA" */ FILE_TYPE(FILE_TYPE_DATA); /* Build the filename */ path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format("%s.raw", filename)); /* Attempt to open the file */ fd = fd_open(buf, O_RDONLY); /* Failure */ if (fd < 0) { int mode = 0644; /* Grab permissions */ safe_setuid_grab(); /* Create a new file */ fd = fd_make(buf, mode); /* Drop permissions */ safe_setuid_drop(); /* Failure */ if (fd < 0) { char why[1024]; /* Message */ strnfmt(why, sizeof(why), "Cannot create the '%s' file!", buf); /* Crash and burn */ quit(why); } } /* Close it */ fd_close(fd); /* Grab permissions */ safe_setuid_grab(); /* Attempt to create the raw file */ fd = fd_open(buf, O_WRONLY); /* Drop permissions */ safe_setuid_drop(); /* Dump to the file */ if (fd >= 0) { /* Dump it */ fd_write(fd, (cptr)head, head->head_size); /* Dump the "*_info" array */ fd_write(fd, head->info_ptr, head->info_size); /* Dump the "*_name" array */ fd_write(fd, head->name_ptr, head->name_size); /* Dump the "*_text" array */ fd_write(fd, head->text_ptr, head->text_size); /* Close */ fd_close(fd); } /*** Kill the fake arrays ***/ /* Free the "*_info" array */ KILL(head->info_ptr); /* MegaHack -- Free the "fake" arrays */ if (z_info) { KILL(head->name_ptr); KILL(head->text_ptr); } #endif /* ALLOW_TEMPLATES */ /*** Load the binary image file ***/ /* Build the filename */ path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format("%s.raw", filename)); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd < 0) quit(format("Cannot load '%s.raw' file.", filename)); /* Attempt to parse the "raw" file */ err = init_info_raw(fd, head); /* Close it */ fd_close(fd); /* Error */ if (err) quit(format("Cannot parse '%s.raw' file.", filename)); #ifdef ALLOW_TEMPLATES } #endif /* ALLOW_TEMPLATES */ /* Success */ return (0); }
/*! * @brief 保存フロア配列を初期化する / Initialize saved_floors array. * @param force テンポラリファイルが残っていた場合も警告なしで強制的に削除する。 * @details Make sure that old temporal files are not remaining as gurbages. * @return なし */ void init_saved_floors(bool force) { char floor_savefile[1024]; int i; int fd = -1; BIT_FLAGS mode = 0644; #ifdef SET_UID # ifdef SECURE /* Get "games" permissions */ beGames(); # endif #endif for (i = 0; i < MAX_SAVED_FLOORS; i++) { saved_floor_type *sf_ptr = &saved_floors[i]; /* File name */ sprintf(floor_savefile, "%s.F%02d", savefile, i); /* Grab permissions */ safe_setuid_grab(); /* Try to create the file */ fd = fd_make(floor_savefile, mode); /* Drop permissions */ safe_setuid_drop(); /* Failed! */ if (fd < 0) { if (!force) { #ifdef JP msg_print("エラー:古いテンポラリ・ファイルが残っています。"); msg_print("短愚蛮怒を二重に起動していないか確認してください。"); msg_print("過去に短愚蛮怒がクラッシュした場合は一時ファイルを"); msg_print("強制的に削除して実行を続けられます。"); if (!get_check("強制的に削除してもよろしいですか?")) quit("実行中止"); #else msg_print("Error: There are old temporal files."); msg_print("Make sure you are not running two game processes simultaneously."); msg_print("If the temporal files are garbages of old crashed process, "); msg_print("you can delete it safely."); if (!get_check("Do you delete old temporal files? ")) quit("Aborted."); #endif force = TRUE; } } else { /* Close the "fd" */ (void)fd_close(fd); } /* Grab permissions */ safe_setuid_grab(); /* Simply kill the temporal file */ (void)fd_kill(floor_savefile); /* Drop permissions */ safe_setuid_drop(); sf_ptr->floor_id = 0; } /* No floor_id used yet (No.0 is reserved to indicate non existance) */ max_floor_id = 1; /* vist_mark is from 1 */ latest_visit_mark = 1; /* A sign to mark temporal files */ saved_floor_file_sign = (u32b)time(NULL); /* No next floor yet */ new_floor_id = 0; /* No change floor mode yet */ change_floor_mode = 0; #ifdef SET_UID # ifdef SECURE /* Drop "games" permissions */ bePlayer(); # endif #endif }
/* * Prepare z-term hooks to call send_*_to_chuukei_server()'s */ void prepare_movie_hooks(void) { char buf[1024]; char tmp[80]; if (movie_mode) { movie_mode = 0; #ifdef CHUUKEI if (!chuukei_server) disable_chuukei_server(); #else disable_chuukei_server(); #endif fd_close(movie_fd); #ifdef JP msg_print("録画を終了しました。"); #else msg_print("Stopped recording."); #endif } else { sprintf(tmp, "%s.amv", player_base); #ifdef JP if (get_string("ムービー記録ファイル: ", tmp, 80)) #else if (get_string("Movie file name: ", tmp, 80)) #endif { int fd; path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp); fd = fd_open(buf, O_RDONLY); /* Existing file */ if (fd >= 0) { char out_val[160]; /* Close the file */ (void)fd_close(fd); /* Build query */ #ifdef JP (void)sprintf(out_val, "現存するファイルに上書きしますか? (%s)", buf); #else (void)sprintf(out_val, "Replace existing file %s? ", buf); #endif /* Ask */ if (!get_check(out_val)) return; movie_fd = fd_open(buf, O_WRONLY | O_TRUNC); } else { movie_fd = fd_make(buf, 0644); } if (!movie_fd) { #ifdef JP msg_print("ファイルを開けません!"); #else msg_print("Can not open file."); #endif return; } movie_mode = 1; #ifdef CHUUKEI if (!chuukei_server) prepare_chuukei_hooks(); #else prepare_chuukei_hooks(); #endif do_cmd_redraw(); } } }