2 Copyright (C) 2006-2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "JackConstants.h"
21 #include "JackDriverLoader.h"
22 #include "JackTools.h"
23 #include "JackError.h"
38 void JackTools::KillServer()
43 void JackTools::ThrowJackNetException()
45 throw JackNetException();
48 int JackTools::MkDir(const char* path
)
51 return CreateDirectory(path
, NULL
) == 0;
53 return mkdir(path
, 0777) != 0;
57 #define DEFAULT_TMP_DIR "/tmp"
58 char* jack_tmpdir
= (char*)DEFAULT_TMP_DIR
;
60 int JackTools::GetPID()
69 int JackTools::GetUID()
73 //#error "No getuid function available"
79 const char* JackTools::DefaultServerName()
81 const char* server_name
;
82 if ((server_name
= getenv("JACK_DEFAULT_SERVER")) == NULL
)
83 server_name
= JACK_DEFAULT_SERVER_NAME
;
87 /* returns the name of the per-user subdirectory of jack_tmpdir */
90 char* JackTools::UserDir()
95 char* JackTools::ServerDir(const char* server_name
, char* server_dir
)
100 void JackTools::CleanupFiles(const char* server_name
) {}
102 int JackTools::GetTmpdir()
108 char* JackTools::UserDir()
110 static char user_dir
[JACK_PATH_MAX
+ 1] = "";
112 /* format the path name on the first call */
113 if (user_dir
[0] == '\0') {
114 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
115 snprintf(user_dir
, sizeof(user_dir
), "%s/jack", jack_tmpdir
);
117 snprintf(user_dir
, sizeof(user_dir
), "%s/jack-%d", jack_tmpdir
, GetUID());
124 /* returns the name of the per-server subdirectory of jack_user_dir() */
125 char* JackTools::ServerDir(const char* server_name
, char* server_dir
)
127 /* format the path name into the suppled server_dir char array,
128 * assuming that server_dir is at least as large as JACK_PATH_MAX + 1 */
130 snprintf(server_dir
, JACK_PATH_MAX
+ 1, "%s/%s", UserDir(), server_name
);
134 void JackTools::CleanupFiles(const char* server_name
)
137 struct dirent
*dirent
;
138 char dir_name
[JACK_PATH_MAX
+ 1] = "";
139 ServerDir(server_name
, dir_name
);
141 /* On termination, we remove all files that jackd creates so
142 * subsequent attempts to start jackd will not believe that an
143 * instance is already running. If the server crashes or is
144 * terminated with SIGKILL, this is not possible. So, cleanup
145 * is also attempted when jackd starts.
147 * There are several tricky issues. First, the previous JACK
148 * server may have run for a different user ID, so its files
149 * may be inaccessible. This is handled by using a separate
150 * JACK_TMP_DIR subdirectory for each user. Second, there may
151 * be other servers running with different names. Each gets
152 * its own subdirectory within the per-user directory. The
153 * current process has already registered as `server_name', so
154 * we know there is no other server actively using that name.
157 /* nothing to do if the server directory does not exist */
158 if ((dir
= opendir(dir_name
)) == NULL
) {
162 /* unlink all the files in this directory, they are mine */
163 while ((dirent
= readdir(dir
)) != NULL
) {
165 char fullpath
[JACK_PATH_MAX
+ 1];
167 if ((strcmp(dirent
->d_name
, ".") == 0) || (strcmp (dirent
->d_name
, "..") == 0)) {
171 snprintf(fullpath
, sizeof(fullpath
), "%s/%s", dir_name
, dirent
->d_name
);
173 if (unlink(fullpath
)) {
174 jack_error("cannot unlink `%s' (%s)", fullpath
, strerror(errno
));
180 /* now, delete the per-server subdirectory, itself */
181 if (rmdir(dir_name
)) {
182 jack_error("cannot remove `%s' (%s)", dir_name
, strerror(errno
));
185 /* finally, delete the per-user subdirectory, if empty */
186 if (rmdir(UserDir())) {
187 if (errno
!= ENOTEMPTY
) {
188 jack_error("cannot remove `%s' (%s)", UserDir(), strerror(errno
));
193 int JackTools::GetTmpdir()
197 char buf
[JACK_PATH_MAX
+ 2]; /* allow tmpdir to live anywhere, plus newline, plus null */
199 if ((in
= popen("jackd -l", "r")) == NULL
) {
203 if (fgets(buf
, sizeof(buf
), in
) == NULL
) {
210 if (buf
[len
- 1] != '\n') {
211 /* didn't get a whole line */
216 jack_tmpdir
= (char *)malloc(len
);
217 memcpy(jack_tmpdir
, buf
, len
- 1);
218 jack_tmpdir
[len
- 1] = '\0';
225 void JackTools::RewriteName(const char* name
, char* new_name
)
228 for (i
= 0; i
< strlen(name
); i
++) {
229 if ((name
[i
] == '/') || (name
[i
] == '\\'))
232 new_name
[i
] = name
[i
];
239 void BuildClientPath(char* path_to_so
, int path_len
, const char* so_name
)
241 snprintf(path_to_so
, path_len
, ADDON_DIR
"/%s.dll", so_name
);
244 void PrintLoadError(const char* so_name
)
246 // Retrieve the system error message for the last-error code
249 DWORD dw
= GetLastError();
252 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
253 FORMAT_MESSAGE_FROM_SYSTEM
|
254 FORMAT_MESSAGE_IGNORE_INSERTS
,
257 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
261 // Display the error message and exit the process
262 lpDisplayBuf
= (LPVOID
)LocalAlloc(LMEM_ZEROINIT
,
263 (lstrlen((LPCTSTR
)lpMsgBuf
) + lstrlen((LPCTSTR
)so_name
) + 40) * sizeof(TCHAR
));
264 _snprintf((LPTSTR
)lpDisplayBuf
, LocalSize(lpDisplayBuf
) / sizeof(TCHAR
),
265 TEXT("error loading %s err = %s"), so_name
, lpMsgBuf
);
267 jack_error((LPCTSTR
)lpDisplayBuf
);
270 LocalFree(lpDisplayBuf
);
275 void PrintLoadError(const char* so_name
)
277 jack_log("error loading %s err = %s", so_name
, dlerror());
280 void BuildClientPath(char* path_to_so
, int path_len
, const char* so_name
)
282 const char* internal_dir
;
283 if ((internal_dir
= getenv("JACK_INTERNAL_DIR")) == 0) {
284 if ((internal_dir
= getenv("JACK_DRIVER_DIR")) == 0) {
285 internal_dir
= ADDON_DIR
;
289 snprintf(path_to_so
, path_len
, "%s/%s.so", internal_dir
, so_name
);
295 } // end of namespace