c635b86545ad442c457d76d6290f0c0e9fa76f91
[ardour.git] / libs / ardour / find_session.cc
1 #include <unistd.h>
2 #include <sys/stat.h>
3
4 #include <cstring>
5 #include <climits>
6 #include <cerrno>
7
8 #include <glibmm/miscutils.h>
9
10 #include "pbd/compose.h"
11 #include "pbd/error.h"
12
13 #include "ardour/session_utils.h"
14 #include "ardour/filename_extensions.h"
15 #include "ardour/utils.h"
16
17 #include "i18n.h"
18
19 using namespace std;
20 using namespace PBD;
21
22 int
23 ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew)
24 {
25         struct stat statbuf;
26         char buf[PATH_MAX+1];
27
28         isnew = false;
29
30         if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
31                 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
32                 return -1;
33         }
34
35         str = buf;
36
37         /* check to see if it exists, and what it is */
38
39         if (stat (str.c_str(), &statbuf)) {
40                 if (errno == ENOENT) {
41                         isnew = true;
42                 } else {
43                         error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
44                               << endmsg;
45                         return -1;
46                 }
47         }
48
49         if (!isnew) {
50
51                 /* it exists, so it must either be the name
52                    of the directory, or the name of the statefile
53                    within it.
54                 */
55
56                 if (S_ISDIR (statbuf.st_mode)) {
57
58                         string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
59
60                         if (slash == string::npos) {
61
62                                 /* a subdirectory of cwd, so statefile should be ... */
63
64                                 string tmp = Glib::build_filename (str, str+statefile_suffix);
65
66                                 /* is it there ? */
67
68                                 if (stat (tmp.c_str(), &statbuf)) {
69                                         error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
70                                               << endmsg;
71                                         return -1;
72                                 }
73
74                                 path = str;
75                                 snapshot = str;
76
77                         } else {
78
79                                 /* some directory someplace in the filesystem.
80                                    the snapshot name is the directory name
81                                    itself.
82                                 */
83
84                                 path = str;
85                                 snapshot = str.substr (slash+1);
86
87                         }
88
89                 } else if (S_ISREG (statbuf.st_mode)) {
90
91                         string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
92                         string::size_type suffix;
93
94                         /* remove the suffix */
95
96                         if (slash != string::npos) {
97                                 snapshot = str.substr (slash+1);
98                         } else {
99                                 snapshot = str;
100                         }
101
102                         suffix = snapshot.find (statefile_suffix);
103
104                         if (suffix == string::npos) {
105                                 error << string_compose (_("%1 is not a snapshot file"), str) << endmsg;
106                                 return -1;
107                         }
108
109                         /* remove suffix */
110
111                         snapshot = snapshot.substr (0, suffix);
112
113                         if (slash == string::npos) {
114
115                                 /* we must be in the directory where the
116                                    statefile lives. get it using cwd().
117                                 */
118
119                                 char cwd[PATH_MAX+1];
120
121                                 if (getcwd (cwd, sizeof (cwd)) == 0) {
122                                         error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
123                                               << endmsg;
124                                         return -1;
125                                 }
126
127                                 path = cwd;
128
129                         } else {
130
131                                 /* full path to the statefile */
132
133                                 path = str.substr (0, slash);
134                         }
135
136                 } else {
137
138                         /* what type of file is it? */
139                         error << string_compose (_("unknown file type for session %1"), str) << endmsg;
140                         return -1;
141                 }
142
143         } else {
144
145                 /* its the name of a new directory. get the name
146                    as "dirname" does.
147                 */
148
149                 string::size_type slash = str.find_last_of (G_DIR_SEPARATOR);
150
151                 if (slash == string::npos) {
152
153                         /* no slash, just use the name, but clean it up */
154
155                         path = legalize_for_path (str);
156                         snapshot = path;
157
158                 } else {
159
160                         path = str;
161                         snapshot = str.substr (slash+1);
162                 }
163         }
164
165         return 0;
166 }