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