Merge branch 'master' into windows
[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
36 #include "i18n.h"
37
38 using namespace std;
39 using namespace PBD;
40
41 namespace ARDOUR {
42
43 int
44 find_session (string str, string& path, string& snapshot, bool& isnew)
45 {
46         struct stat statbuf;
47
48         isnew = false;
49
50         str = canonical_path (str);
51
52         /* check to see if it exists, and what it is */
53
54         if (stat (str.c_str(), &statbuf)) {
55                 if (errno == ENOENT) {
56                         isnew = true;
57                 } else {
58                         error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
59                               << endmsg;
60                         return -1;
61                 }
62         }
63
64         if (!isnew) {
65
66                 /* it exists, so it must either be the name
67                    of the directory, or the name of the statefile
68                    within it.
69                 */
70
71                 if (S_ISDIR (statbuf.st_mode)) {
72
73                         string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
74
75                         if (slash == string::npos) {
76
77                                 /* a subdirectory of cwd, so statefile should be ... */
78
79                                 string tmp = Glib::build_filename (str, str+statefile_suffix);
80
81                                 /* is it there ? */
82
83                                 if (stat (tmp.c_str(), &statbuf)) {
84                                         error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
85                                               << endmsg;
86                                         return -1;
87                                 }
88
89                                 path = str;
90                                 snapshot = str;
91
92                         } else {
93
94                                 /* some directory someplace in the filesystem.
95                                    the snapshot name is the directory name
96                                    itself.
97                                 */
98
99                                 path = str;
100                                 snapshot = str.substr (slash+1);
101
102                         }
103
104                 } else if (S_ISREG (statbuf.st_mode)) {
105
106                         string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
107                         string::size_type suffix;
108
109                         /* remove the suffix */
110
111                         if (slash != string::npos) {
112                                 snapshot = str.substr (slash+1);
113                         } else {
114                                 snapshot = str;
115                         }
116
117                         suffix = snapshot.find (statefile_suffix);
118
119                         if (suffix == string::npos) {
120                                 error << string_compose (_("%1 is not a snapshot file"), str) << endmsg;
121                                 return -1;
122                         }
123
124                         /* remove suffix */
125
126                         snapshot = snapshot.substr (0, suffix);
127
128                         if (slash == string::npos) {
129
130                                 /* we must be in the directory where the
131                                    statefile lives. get it using cwd().
132                                 */
133
134                                 char cwd[PATH_MAX+1];
135
136                                 if (getcwd (cwd, sizeof (cwd)) == 0) {
137                                         error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
138                                               << endmsg;
139                                         return -1;
140                                 }
141
142                                 path = cwd;
143
144                         } else {
145
146                                 /* full path to the statefile */
147
148                                 path = str.substr (0, slash);
149                         }
150
151                 } else {
152
153                         /* what type of file is it? */
154                         error << string_compose (_("unknown file type for session %1"), str) << endmsg;
155                         return -1;
156                 }
157
158         } else {
159
160                 /* its the name of a new directory. get the name
161                    as "dirname" does.
162                 */
163
164                 string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
165
166                 if (slash == string::npos) {
167
168                         /* no slash, just use the name, but clean it up */
169
170                         path = legalize_for_path (str);
171                         snapshot = path;
172
173                 } else {
174
175                         path = str;
176                         snapshot = str.substr (slash+1);
177                 }
178         }
179
180         return 0;
181 }
182
183 }  // namespace ARDOUR