X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ffind_session.cc;h=7644422f6f701eb86b0eafbc9a4d39613a9d12fe;hb=0eaf7b1e18ba0f6e9ce600f0a99c0fd218b44d81;hp=417902b8051392dca1adfebd1b08ed582c448405;hpb=e0aaed6d65f160c328cb8b56d7c6552ee15d65e2;p=ardour.git diff --git a/libs/ardour/find_session.cc b/libs/ardour/find_session.cc index 417902b805..7644422f6f 100644 --- a/libs/ardour/find_session.cc +++ b/libs/ardour/find_session.cc @@ -1,39 +1,62 @@ +/* + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include -#include #include #include #include +#include "pbd/gstdio_compat.h" + +#include +#include + +#include "pbd/basename.h" #include "pbd/compose.h" +#include "pbd/file_archive.h" +#include "pbd/pathexpand.h" #include "pbd/error.h" -#include "ardour/session_utils.h" #include "ardour/filename_extensions.h" #include "ardour/utils.h" +#include "ardour/session_utils.h" -#include "i18n.h" +#include "pbd/i18n.h" +using namespace std; using namespace PBD; +namespace ARDOUR { + int -ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew) +find_session (string str, string& path, string& snapshot, bool& isnew) { - struct stat statbuf; - char buf[PATH_MAX+1]; + GStatBuf statbuf; isnew = false; - if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) { - error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg; - return -1; - } + str = canonical_path (str); - str = buf; - /* check to see if it exists, and what it is */ - if (stat (str.c_str(), &statbuf)) { + if (g_stat (str.c_str(), &statbuf)) { if (errno == ENOENT) { isnew = true; } else { @@ -52,21 +75,17 @@ ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew) if (S_ISDIR (statbuf.st_mode)) { - string::size_type slash = str.find_last_of ('/'); - + string::size_type slash = str.find_last_of (G_DIR_SEPARATOR); + if (slash == string::npos) { - + /* a subdirectory of cwd, so statefile should be ... */ - string tmp; - tmp = str; - tmp += '/'; - tmp += str; - tmp += statefile_suffix; + string tmp = Glib::build_filename (str, str+statefile_suffix); /* is it there ? */ - - if (stat (tmp.c_str(), &statbuf)) { + + if (g_stat (tmp.c_str(), &statbuf)) { error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno)) << endmsg; return -1; @@ -84,16 +103,16 @@ ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew) path = str; snapshot = str.substr (slash+1); - + } } else if (S_ISREG (statbuf.st_mode)) { - - string::size_type slash = str.find_last_of ('/'); + + string::size_type slash = str.find_last_of (G_DIR_SEPARATOR); string::size_type suffix; /* remove the suffix */ - + if (slash != string::npos) { snapshot = str.substr (slash+1); } else { @@ -101,19 +120,22 @@ ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew) } suffix = snapshot.find (statefile_suffix); - - if (suffix == string::npos) { - error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg; + + const string::size_type start_pos_of_extension = snapshot.size () - strlen (statefile_suffix); + // we should check the start of extension position + // because files '*.ardour.bak' are possible + if (suffix != start_pos_of_extension) { + error << string_compose (_("%1 is not a snapshot file"), str) << endmsg; return -1; } /* remove suffix */ snapshot = snapshot.substr (0, suffix); - + if (slash == string::npos) { - - /* we must be in the directory where the + + /* we must be in the directory where the statefile lives. get it using cwd(). */ @@ -133,7 +155,7 @@ ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew) path = str.substr (0, slash); } - + } else { /* what type of file is it? */ @@ -147,17 +169,17 @@ ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew) as "dirname" does. */ - string::size_type slash = str.find_last_of ('/'); + string::size_type slash = str.find_last_of (G_DIR_SEPARATOR); if (slash == string::npos) { - + /* no slash, just use the name, but clean it up */ - + path = legalize_for_path (str); snapshot = path; - + } else { - + path = str; snapshot = str.substr (slash+1); } @@ -165,3 +187,101 @@ ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew) return 0; } + +/* check if zip is a session-archive, + * return > 0 if file is not an archive + * return < 0 if unzip failed + * return 0 on success. path and snapshot are set. + */ +int +inflate_session (const std::string& zipfile, const std::string& target_dir, string& path, string& snapshot) +{ + if (zipfile.find (session_archive_suffix) == string::npos) { + return 1; + } + + try { + PBD::FileArchive ar (zipfile); + std::vector files = ar.contents (); + + if (files.size () == 0) { + error << _("Archive is empty") << endmsg; + return 2; + } + + /* session archives are expected to be named after the archive */ + std::string bn = Glib::path_get_dirname (files.front()); + if (bn.empty ()) { + error << _("Archive does not contain a session folder") << endmsg; + return 3; + } + + size_t sep = bn.find_first_of ('/'); + + if (sep != string::npos) { + bn = bn.substr (0, sep); + } + + if (bn.empty ()) { + error << _("Archive does not contain a valid session structure") << endmsg; + return 4; + } + + string sn = Glib::build_filename (bn, bn + statefile_suffix); + + if (std::find (files.begin(), files.end(), sn) == files.end()) { + error << _("Archive does not contain a session file") << endmsg; + return 5; + } + + /* check if target folder exists */ + string dest = Glib::build_filename (target_dir, bn); + if (Glib::file_test (dest, Glib::FILE_TEST_EXISTS)) { + error << string_compose (_("Destination '%1' already exists."), dest) << endmsg; + return -1; + } + + if (0 == ar.inflate (target_dir)) { + info << string_compose (_("Extracted session-archive to '%1'."), dest) << endmsg; + path = dest; + snapshot = bn; + return 0; + } + + } catch (...) { + error << _("Error reading file-archive") << endmsg; + return 6; + } + + error << _("Error extracting file-archive") << endmsg; + return -2; +} + +string inflate_error (int e) { + switch (e) { + case 0: + return _("No Error"); + case 1: + return string_compose (_("File extension is not %1"), session_archive_suffix); + case 2: + return _("Archive is empty"); + case 3: + return _("Archive does not contain a session folder"); + case 4: + return _("Archive does not contain a valid session structure"); + case 5: + return _("Archive does not contain a session file"); + case 6: + return _("Error reading file-archive"); + case -1: + return _("Destination folder already exists."); + case -2: + return _("Error extracting file-archive"); + default: + assert (0); + break; + } + return _("Unknown Error"); +} + +} // namespace ARDOUR