static void _handle_backup (player *pl, world *w, command_reader& reader) { if (!pl->has ("command.world.world.backup")) { pl->message (messages::not_allowed ()); return; } mkdir ("data/backups", 0744); mkdir (("data/backups/" + std::string (w->get_name ())).c_str (), 0744); std::string dest = w->get_path (); dest.erase (0, 12); // remove "data/worlds/" part dest.insert (0, "data/backups/" + std::string (w->get_name ()) + "/"); int backup_num = _determine_backup_number (dest.c_str ()); std::ostringstream ss; ss << dest << "." << backup_num; w->save_all (); if (!_copy_file (ss.str ().c_str (), w->get_path ())) pl->message ("§4 * §cFailed to save backup§4."); else { pl->message ("§eBackup saved"); ss.str (std::string ()); ss << "§7 | Use §e/world restore §b" << backup_num << " §7to restore this backup."; pl->message (ss.str ()); } }
static void _handle_restore (player *pl, world *w, command_reader& reader) { if (!pl->has ("command.world.world.restore")) { pl->message (messages::not_allowed ()); return; } if (!reader.has_next ()) { pl->message ("§c * §7Usage§f: §e/world restore §cbackup-number"); return; } int backup_num; auto arg = reader.next (); if (!arg.is_int () || ((backup_num = arg.as_int ()) <= 0)) { pl->message ("§c * §7The backup number should a positive non-zero integer§c."); return; } std::string src = w->get_path (); src.erase (0, 12); // remove "data/worlds/" part src.insert (0, "data/backups/" + std::string (w->get_name ()) + "/"); std::ostringstream ss; ss << src << "." << backup_num; FILE *f = std::fopen (ss.str ().c_str (), "rb"); if (!f) { pl->message ("§c * §7Backup does not exist§c."); return; } std::fclose (f); _copy_file (w->get_path (), ss.str ().c_str ()); w->reload_world (w->get_name ()); w->get_players ().all ( [] (player *pl) { std::cout << "W a" << std::endl; pl->rejoin_world (); std::cout << "W b" << std::endl; pl->message ("§bWorld reloaded"); }); ss.str (std::string ()); ss << "§eRestored backup #§b" << backup_num; pl->message (ss.str ()); }
/// @brief Responds to a TruncateFile command MavlinkFTP::ErrorCode MavlinkFTP::_workTruncateFile(PayloadHeader* payload) { char file[kMaxDataLength]; const char temp_file[] = "/fs/microsd/.trunc.tmp"; strncpy(file, _data_as_cstring(payload), kMaxDataLength); payload->size = 0; // emulate truncate(file, payload->offset) by // copying to temp and overwrite with O_TRUNC flag. struct stat st; if (stat(file, &st) != 0) { return kErrFailErrno; } if (!S_ISREG(st.st_mode)) { errno = EISDIR; return kErrFailErrno; } // check perms allow us to write (not romfs) if (!(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) { errno = EROFS; return kErrFailErrno; } if (payload->offset == (unsigned)st.st_size) { // nothing to do return kErrNone; } else if (payload->offset == 0) { // 1: truncate all data int fd = ::open(file, O_TRUNC | O_WRONLY); if (fd < 0) { return kErrFailErrno; } ::close(fd); return kErrNone; } else if (payload->offset > (unsigned)st.st_size) { // 2: extend file int fd = ::open(file, O_WRONLY); if (fd < 0) { return kErrFailErrno; } if (lseek(fd, payload->offset - 1, SEEK_SET) < 0) { ::close(fd); return kErrFailErrno; } bool ok = 1 == ::write(fd, "", 1); ::close(fd); return (ok)? kErrNone : kErrFailErrno; } else { // 3: truncate if (_copy_file(file, temp_file, payload->offset) != 0) { return kErrFailErrno; } if (_copy_file(temp_file, file, payload->offset) != 0) { return kErrFailErrno; } if (::unlink(temp_file) != 0) { return kErrFailErrno; } return kErrNone; } }
/* * Function: _setup_install_log * Description: Copy the install_log file from /tmp to the target * filesystem and add a timestamp to the name. * Set up a symlink to this new file from either * install_log or upgrade_log in hte same directory. * If the log is open for writing, close & reopen * at the new location. * This function was moved here from libspmisvc so * it could use some knowledge about the log file. * * Until after 2.6, set up a symbolic link from * var/sadm/install_data for backwards compatibility * as stated in PSARC/1994/331. * Scope: publice * Parameters: none * Return: Pointer to new logfile on success * NULL on failure */ char * _setup_install_log(void) { int reopen = 0; char *dated_path, *new_logpath; char *old_logpath = "/var/sadm/install_data/upgrade_log"; FILE *tmpf; static char new_path[MAXPATHLEN] = ""; if (get_install_type() == CMNUpgrade) { (void) sprintf(new_path, "%s%s/upgrade_log", get_rootdir(), "/var/sadm/system/logs"); new_logpath = new_path + strlen(get_rootdir()); /* * If there is a symbolic link in the old location, * remove it. If there is a file, not a sym link, * move it to the new location in the dated form. * Remove ths after 2.6 */ (void) rm_link_mv_file(old_logpath, new_logpath); /* * Remove an existing symlink, or rename the log file * to a dated form. */ (void) rm_link_mv_file(new_logpath, new_logpath); /* * Create a new dated log file & symlink */ if ((tmpf = fopen(new_path, "w")) == NULL) { return (NULL); } (void) fclose(tmpf); if ((dated_path = (char *)rm_link_mv_file(new_logpath, new_logpath)) == NULL) { return (NULL); } (void) chmod(dated_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); (void) symlink(basename(dated_path), new_path); /* * Remove this after 2.6 */ { char tmppath[MAXPATHLEN]; (void) sprintf(tmppath, "%s/%s", get_rootdir(), old_logpath); (void) symlink("../system/logs/upgrade_log", tmppath); } } else { /* * Initial install */ (void) sprintf(new_path, "%s%s/install_log", get_rootdir(), "/var/sadm/system/logs"); new_logpath = new_path + strlen(get_rootdir()); /* * Remove this after 2.6 */ { char tmppath[MAXPATHLEN]; (void) sprintf(tmppath, "%s/var/sadm/install_data/install_log", get_rootdir()); (void) symlink("../system/logs/install_log", tmppath); } } /* * If we've started writing a log file, copy it to the * permanent location. */ if (access(TMPLOGFILE, F_OK) == 0) { if (_log_file != NULL) { reopen = 1; (void) fclose(_log_file); _log_file = NULL; } if (_copy_file(new_path, TMPLOGFILE) == ERROR) { return (NULL); } if (reopen != 0) { if ((_log_file = fopen(new_path, "a")) == NULL) { /* * Punt */ return (NULL); } } } return (new_path); }
/// @brief Responds to a TruncateFile command MavlinkFTP::ErrorCode MavlinkFTP::_workTruncateFile(PayloadHeader *payload) { strncpy(_work_buffer1, _root_dir, _work_buffer1_len); strncpy(_work_buffer1 + _root_dir_len, _data_as_cstring(payload), _work_buffer1_len - _root_dir_len); // ensure termination _work_buffer1[_work_buffer1_len - 1] = '\0'; payload->size = 0; #ifdef __PX4_NUTTX // emulate truncate(_work_buffer1, payload->offset) by // copying to temp and overwrite with O_TRUNC flag (NuttX does not support truncate()). const char temp_file[] = PX4_ROOTFSDIR"/fs/microsd/.trunc.tmp"; struct stat st; if (stat(_work_buffer1, &st) != 0) { return kErrFailErrno; } if (!S_ISREG(st.st_mode)) { errno = EISDIR; return kErrFailErrno; } // check perms allow us to write (not romfs) if (!(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) { errno = EROFS; return kErrFailErrno; } if (payload->offset == (unsigned)st.st_size) { // nothing to do return kErrNone; } else if (payload->offset == 0) { // 1: truncate all data int fd = ::open(_work_buffer1, O_TRUNC | O_WRONLY); if (fd < 0) { return kErrFailErrno; } ::close(fd); return kErrNone; } else if (payload->offset > (unsigned)st.st_size) { // 2: extend file int fd = ::open(_work_buffer1, O_WRONLY); if (fd < 0) { return kErrFailErrno; } if (lseek(fd, payload->offset - 1, SEEK_SET) < 0) { ::close(fd); return kErrFailErrno; } bool ok = 1 == ::write(fd, "", 1); ::close(fd); return (ok) ? kErrNone : kErrFailErrno; } else { // 3: truncate if (_copy_file(_work_buffer1, temp_file, payload->offset) != 0) { return kErrFailErrno; } if (_copy_file(temp_file, _work_buffer1, payload->offset) != 0) { return kErrFailErrno; } if (::unlink(temp_file) != 0) { return kErrFailErrno; } return kErrNone; } #else int ret = truncate(_work_buffer1, payload->offset); if (ret == 0) { return kErrNone; } return kErrFailErrno; #endif /* __PX4_NUTTX */ }