00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackConstants.h"
00021 #include "JackDriverLoader.h"
00022 #include "JackTools.h"
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <assert.h>
00026
00027 #ifdef WIN32
00028 #include <process.h>
00029 #endif
00030
00031 using namespace std;
00032
00033 namespace Jack {
00034
00035 #define DEFAULT_TMP_DIR "/tmp"
00036 char* jack_tmpdir = (char*)DEFAULT_TMP_DIR;
00037
00038 int JackTools::GetPID()
00039 {
00040 #ifdef WIN32
00041 return _getpid();
00042 #else
00043 return getpid();
00044 #endif
00045 }
00046
00047 int JackTools::GetUID()
00048 {
00049 #ifdef WIN32
00050 return _getpid();
00051
00052 #else
00053 return getuid();
00054 #endif
00055 }
00056
00057 const char* JackTools::DefaultServerName()
00058 {
00059 const char* server_name;
00060 if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL)
00061 server_name = JACK_DEFAULT_SERVER_NAME;
00062 return server_name;
00063 }
00064
00065
00066 #ifdef WIN32
00067
00068 char* JackTools::UserDir()
00069 {
00070 return "";
00071 }
00072
00073 char* JackTools::ServerDir(const char* server_name, char* server_dir)
00074 {
00075 return "";
00076 }
00077
00078 void JackTools::CleanupFiles(const char* server_name) {}
00079
00080 int JackTools::GetTmpdir()
00081 {
00082 return 0;
00083 }
00084
00085 #else
00086 char* JackTools::UserDir()
00087 {
00088 static char user_dir[JACK_PATH_MAX + 1] = "";
00089
00090
00091 if (user_dir[0] == '\0') {
00092 if (getenv ("JACK_PROMISCUOUS_SERVER")) {
00093 snprintf(user_dir, sizeof(user_dir), "%s/jack", jack_tmpdir);
00094 } else {
00095 snprintf(user_dir, sizeof(user_dir), "%s/jack-%d", jack_tmpdir, GetUID());
00096 }
00097 }
00098
00099 return user_dir;
00100 }
00101
00102
00103 char* JackTools::ServerDir(const char* server_name, char* server_dir)
00104 {
00105
00106
00107
00108 snprintf(server_dir, JACK_PATH_MAX + 1, "%s/%s", UserDir(), server_name);
00109 return server_dir;
00110 }
00111
00112 void JackTools::CleanupFiles(const char* server_name)
00113 {
00114 DIR* dir;
00115 struct dirent *dirent;
00116 char dir_name[JACK_PATH_MAX + 1] = "";
00117 ServerDir(server_name, dir_name);
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 if ((dir = opendir(dir_name)) == NULL) {
00137 return;
00138 }
00139
00140
00141 while ((dirent = readdir(dir)) != NULL) {
00142
00143 char fullpath[JACK_PATH_MAX + 1];
00144
00145 if ((strcmp(dirent->d_name, ".") == 0) || (strcmp (dirent->d_name, "..") == 0)) {
00146 continue;
00147 }
00148
00149 snprintf(fullpath, sizeof(fullpath), "%s/%s", dir_name, dirent->d_name);
00150
00151 if (unlink(fullpath)) {
00152 jack_error("cannot unlink `%s' (%s)", fullpath, strerror(errno));
00153 }
00154 }
00155
00156 closedir(dir);
00157
00158
00159 if (rmdir(dir_name)) {
00160 jack_error("cannot remove `%s' (%s)", dir_name, strerror(errno));
00161 }
00162
00163
00164 if (rmdir(UserDir())) {
00165 if (errno != ENOTEMPTY) {
00166 jack_error("cannot remove `%s' (%s)", UserDir(), strerror(errno));
00167 }
00168 }
00169 }
00170
00171 int JackTools::GetTmpdir() {
00172 FILE* in;
00173 size_t len;
00174 char buf[JACK_PATH_MAX + 2];
00175
00176 if ((in = popen("jackd -l", "r")) == NULL) {
00177 return -1;
00178 }
00179
00180 if (fgets(buf, sizeof(buf), in) == NULL) {
00181 fclose(in);
00182 return -1;
00183 }
00184
00185 len = strlen(buf);
00186
00187 if (buf[len - 1] != '\n') {
00188
00189 fclose(in);
00190 return -1;
00191 }
00192
00193 jack_tmpdir = (char *)malloc(len);
00194 memcpy(jack_tmpdir, buf, len - 1);
00195 jack_tmpdir[len - 1] = '\0';
00196
00197 fclose(in);
00198 return 0;
00199 }
00200 #endif
00201
00202 void JackTools::RewriteName(const char* name, char* new_name) {
00203 size_t i;
00204 for (i = 0; i < strlen(name); i++) {
00205 if ((name[i] == '/') || (name[i] == '\\'))
00206 new_name[i] = '_';
00207 else
00208 new_name[i] = name[i];
00209 }
00210 new_name[i] = '\0';
00211 }
00212
00213
00214 JackArgParser::JackArgParser ( const char* arg )
00215 {
00216 jack_log ( "JackArgParser::JackArgParser, arg_string : '%s'", arg );
00217
00218 fArgc = 0;
00219
00220 if ( strlen(arg) == 0 )
00221 return;
00222 fArgString = string(arg);
00223
00224 const size_t arg_len = fArgString.length();
00225 unsigned int i = 0;
00226 size_t pos = 0;
00227 size_t start = 0;
00228 size_t copy_start = 0;
00229 size_t copy_length = 0;
00230
00231 fArgString += " ";
00232
00233 do {
00234
00235 start = fArgString.find_first_not_of ( ' ', start );
00236
00237 pos = fArgString.find_first_of ( " \"" , start );
00238
00239 if ( pos == string::npos )
00240 pos = arg_len;
00241
00242 if ( fArgString[pos] == '\"' ) {
00243
00244 if ( pos == start ) {
00245 copy_start = start + 1;
00246 pos = fArgString.find ( '\"', ++pos );
00247 copy_length = pos - copy_start;
00248 start = pos + 1;
00249 }
00250
00251 else {
00252 copy_start = start;
00253 copy_length = pos - copy_start;
00254 start = pos;
00255 }
00256 }
00257
00258 if ( fArgString[pos] == ' ' ) {
00259
00260 if ( ( fArgString[start] == '-' ) && ( fArgString[start + 1] != '-' ) ) {
00261 copy_start = start;
00262 copy_length = 2;
00263 start += copy_length;
00264 }
00265
00266 else {
00267 copy_start = start;
00268 copy_length = pos - copy_start;
00269 start = pos + 1;
00270 }
00271 }
00272
00273 fArgv.push_back ( fArgString.substr ( copy_start, copy_length ) );
00274 jack_log ( "JackArgParser::JackArgParser, add : '%s'", (*fArgv.rbegin()).c_str() );
00275 } while ( start < arg_len );
00276
00277
00278 for ( i = 0; i < fArgv.size(); i++ )
00279 if ( fArgv[i].at(0) == '-' )
00280 fArgc++;
00281 }
00282
00283 JackArgParser::~JackArgParser()
00284 {}
00285
00286 string JackArgParser::GetArgString()
00287 {
00288 return fArgString;
00289 }
00290
00291 int JackArgParser::GetNumArgv()
00292 {
00293 return fArgv.size();
00294 }
00295
00296 int JackArgParser::GetArgc()
00297 {
00298 return fArgc;
00299 }
00300
00301 int JackArgParser::GetArgv ( vector<string>& argv )
00302 {
00303 argv = fArgv;
00304 return 0;
00305 }
00306
00307 int JackArgParser::GetArgv ( char** argv )
00308 {
00309
00310 if ( argv )
00311 return -1;
00312
00313 argv = (char**)calloc (fArgv.size(), sizeof(char*));
00314 for ( unsigned int i = 0; i < fArgv.size(); i++ )
00315 {
00316 argv[i] = (char*)calloc(fArgv[i].length(), sizeof(char));
00317 fill_n ( argv[i], fArgv[i].length() + 1, 0 );
00318 fArgv[i].copy ( argv[i], fArgv[i].length() );
00319 }
00320 return 0;
00321 }
00322
00323 void JackArgParser::DeleteArgv ( const char** argv )
00324 {
00325 unsigned int i;
00326 for ( i = 0; i < fArgv.size(); i++ )
00327 free((void*)argv[i]);
00328 free((void*)argv);
00329 }
00330
00331 void JackArgParser::ParseParams ( jack_driver_desc_t* desc, JSList** param_list )
00332 {
00333 string options_list;
00334 unsigned long i = 0;
00335 unsigned int param = 0;
00336 size_t param_id = 0;
00337 JSList* params = NULL;
00338 jack_driver_param_t* intclient_param;
00339
00340 for ( i = 0; i < desc->nparams; i++ )
00341 options_list += desc->params[i].character;
00342
00343 for ( param = 0; param < fArgv.size(); param++ )
00344 {
00345 if ( fArgv[param][0] == '-' )
00346 {
00347
00348 if ( ( param_id = options_list.find_first_of ( fArgv[param].at(1) ) ) != string::npos )
00349 {
00350 intclient_param = static_cast<jack_driver_param_t*> ( calloc ( 1, sizeof ( jack_driver_param_t) ) );
00351 intclient_param->character = desc->params[param_id].character;
00352
00353 switch ( desc->params[param_id].type )
00354 {
00355 case JackDriverParamInt:
00356 if (param + 1 < fArgv.size())
00357 intclient_param->value.i = atoi ( fArgv[param + 1].c_str() );
00358 break;
00359
00360 case JackDriverParamUInt:
00361 if (param + 1 < fArgv.size())
00362 intclient_param->value.ui = strtoul ( fArgv[param + 1].c_str(), NULL, 10 );
00363 break;
00364
00365 case JackDriverParamChar:
00366 if (param + 1 < fArgv.size())
00367 intclient_param->value.c = fArgv[param + 1][0];
00368 break;
00369
00370 case JackDriverParamString:
00371 if (param + 1 < fArgv.size())
00372 fArgv[param + 1].copy ( intclient_param->value.str, min(static_cast<int>(fArgv[param + 1].length()), JACK_DRIVER_PARAM_STRING_MAX) );
00373 break;
00374
00375 case JackDriverParamBool:
00376 intclient_param->value.i = true;
00377 break;
00378 }
00379
00380 params = jack_slist_append ( params, intclient_param );
00381 }
00382
00383 else
00384 jack_error ( "Invalid option '%c'", fArgv[param][1] );
00385 }
00386 }
00387
00388 assert(param_list);
00389 *param_list = params;
00390 }
00391
00392 void JackArgParser::FreeParams ( JSList* param_list )
00393 {
00394 JSList *node_ptr = param_list;
00395 JSList *next_node_ptr;
00396
00397 while (node_ptr) {
00398 next_node_ptr = node_ptr->next;
00399 free(node_ptr->data);
00400 free(node_ptr);
00401 node_ptr = next_node_ptr;
00402 }
00403 }
00404
00405 }
00406