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