merge with master and fix 4 conflicts by hand
[ardour.git] / libs / ardour / find_session.cc
1 /*
2     Copyright (C) 2012 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <unistd.h>
21 #include <sys/stat.h>
22
23 #include <cstring>
24 #include <climits>
25 #include <cerrno>
26
27 #include <glibmm/miscutils.h>
28
29 #include "pbd/compose.h"
30 #include "pbd/pathexpand.h"
31 #include "pbd/error.h"
32
33 #include "ardour/filename_extensions.h"
34 #include "ardour/utils.h"
35 #include "ardour/session_utils.h"
36
37 #include "i18n.h"
38
39 using namespace std;
40 using namespace PBD;
41
42 namespace ARDOUR {
43
44 int
45 find_session (string str, string& path, string& snapshot, bool& isnew)
46 {
47         struct stat statbuf;
48
49         isnew = false;
50
51         str = canonical_path (str);
52
53         /* check to see if it exists, and what it is */
54
55         if (stat (str.c_str(), &statbuf)) {
56                 if (errno == ENOENT) {
57                         isnew = true;
58                 } else {
59                         error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
60                               << endmsg;
61                         return -1;
62                 }
63         }
64
65         if (!isnew) {
66
67                 /* it exists, so it must either be the name
68                    of the directory, or the name of the statefile
69                    within it.
70                 */
71
72                 if (S_ISDIR (statbuf.st_mode)) {
73
74                         string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
75
76                         if (slash == string::npos) {
77
78                                 /* a subdirectory of cwd, so statefile should be ... */
79
80                                 string tmp = Glib::build_filename (str, str+statefile_suffix);
81
82                                 /* is it there ? */
83
84                                 if (stat (tmp.c_str(), &statbuf)) {
85                                         error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
86                                               << endmsg;
87                                         return -1;
88                                 }
89
90                                 path = str;
91                                 snapshot = str;
92
93                         } else {
94
95                                 /* some directory someplace in the filesystem.
96                                    the snapshot name is the directory name
97                                    itself.
98                                 */
99
100                                 path = str;
101                                 snapshot = str.substr (slash+1);
102
103                         }
104
105                 } else if (S_ISREG (statbuf.st_mode)) {
106
107                         string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
108                         string::size_type suffix;
109
110                         /* remove the suffix */
111
112                         if (slash != string::npos) {
113                                 snapshot = str.substr (slash+1);
114                         } else {
115                                 snapshot = str;
116                         }
117
118                         suffix = snapshot.find (statefile_suffix);
119
120                         if (suffix == string::npos) {
121                                 error << string_compose (_("%1 is not a snapshot file"), str) << endmsg;
122                                 return -1;
123                         }
124
125                         /* remove suffix */
126
127                         snapshot = snapshot.substr (0, suffix);
128
129                         if (slash == string::npos) {
130
131                                 /* we must be in the directory where the
132                                    statefile lives. get it using cwd().
133                                 */
134
135                                 char cwd[PATH_MAX+1];
136
137                                 if (getcwd (cwd, sizeof (cwd)) == 0) {
138                                         error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
139                                               << endmsg;
140                                         return -1;
141                                 }
142
143                                 path = cwd;
144
145                         } else {
146
147                                 /* full path to the statefile */
148
149                                 path = str.substr (0, slash);
150                         }
151
152                 } else {
153
154                         /* what type of file is it? */
155                         error << string_compose (_("unknown file type for session %1"), str) << endmsg;
156                         return -1;
157                 }
158
159         } else {
160
161                 /* its the name of a new directory. get the name
162                    as "dirname" does.
163                 */
164
165                 string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
166
167                 if (slash == string::npos) {
168
169                         /* no slash, just use the name, but clean it up */
170
171                         path = legalize_for_path (str);
172                         snapshot = path;
173
174                 } else {
175
176                         path = str;
177                         snapshot = str.substr (slash+1);
178                 }
179         }
180
181         return 0;
182 }
183
184 }  // namespace ARDOUR