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