00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "config.h"
00020
00021 #include <errno.h>
00022 #include <stdlib.h>
00023
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026
00027 #include <assert_pp.h>
00028 #include <factory_library.h>
00029
00030 #include <corba.h>
00031
00032 #include <string>
00033
00034 #include "ltdl.h"
00035
00036
00037 #define private public
00038 #include "ior-handler.h"
00039 #undef private
00040
00041
00042 #include "HeyParser.hh"
00043
00044 using namespace std;
00045
00046 #if !defined(__XSTRING)
00047
00048
00049
00050
00051
00052 #define __XSTRING(x) __STRING(x)
00053 #endif
00054
00055 enum {
00056 CDB_DEBUG,
00057 CDB_LIST,
00058 };
00059
00060
00061
00062
00063
00064
00065 enum {
00066 CDF_DEBUG = (1L << CDB_DEBUG),
00067 CDF_LIST = (1L << CDB_LIST),
00068 };
00069
00070
00071
00072
00073
00074
00075
00076 static struct {
00077 unsigned long cd_Flags;
00078 const char *cd_InterfaceType;
00079 } cbhey_data;
00080
00081
00082
00083
00084
00085
00086 static void cbhUsage(const char *prog_name)
00087 {
00088 require(prog_name != NULL);
00089
00090 cerr << "Generic CPU Broker control program.\n"
00091 << "Usage: "
00092 << prog_name
00093 << " [options] <ior> <verb> <specifiers> ...\n"
00094 << endl
00095 << "Options:\n"
00096 << " -h\t\tThis help message.\n"
00097 << " -V\t\tShow the version number.\n"
00098
00099 << " -d\t\tTurn on debugging messages.\n"
00100 << " -l\t\tList the supported types.\n"
00101 << " -c <type>\tCast the object to the given interface.\n"
00102
00103 << endl
00104
00105 << "Package: " << PACKAGE_STRING << endl
00106 << "Contact: " << PACKAGE_BUGREPORT << endl
00107
00108 ;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 static int cbhProcessOptions(int &argc_inout, char **&argv_inout)
00122 {
00123 int ch, retval = 0;
00124 char *prog_name;
00125 char **argv;
00126 int argc;
00127
00128 argc = argc_inout;
00129 argv = argv_inout;
00130 prog_name = argv[0];
00131 while( ((ch = getopt(argc, argv, "hVldc:")) != -1) &&
00132 (retval == 0) )
00133 {
00134 switch( ch )
00135 {
00136 case 'c':
00137 cbhey_data.cd_InterfaceType = optarg;
00138 break;
00139 case 'd':
00140 cbhey_data.cd_Flags |= CDF_DEBUG;
00141 break;
00142 case 'l':
00143 cbhey_data.cd_Flags |= CDF_LIST;
00144 break;
00145 case 'V':
00146 cerr << PACKAGE_VERSION << endl;
00147 retval = -1;
00148 break;
00149 case 'h':
00150 case '?':
00151 default:
00152 retval = 1;
00153 break;
00154 }
00155 }
00156 argc_inout -= optind;
00157 argv_inout += optind;
00158
00159 argc_inout += 1;
00160 argv_inout -= 1;
00161 argv_inout[0] = prog_name;
00162 return( retval );
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 static void interpret_ior(IorHandler *ioh,
00174 char *thisIor,
00175 struct IOR_Manager *thisIorInfo)
00176 {
00177 int numCharsToSkip;
00178 int validTypeId = 0;
00179 int ulongValue;
00180
00181
00182 int numHexCharsRead = 4;
00183
00184
00185
00186 int validTypeIdLen = 0;
00187
00188 while (!validTypeIdLen)
00189 {
00190 ioh->skipNullOctets((char *)(thisIor + numHexCharsRead),
00191 &numCharsToSkip, 1);
00192 numHexCharsRead += numCharsToSkip;
00193
00194
00195 ulongValue = ioh->getOctet2Field((char *)(thisIor + numHexCharsRead),
00196 &numCharsToSkip);
00197
00198 if (ulongValue == 0)
00199 {
00200 return;
00201 }
00202
00203 numHexCharsRead += numCharsToSkip;
00204
00205 if (ulongValue > 4)
00206 {
00207 validTypeIdLen = 1;
00208 thisIorInfo->typeIdLen = ulongValue;
00209 }
00210
00211 ioh->skipNullOctets((char *)(thisIor + numHexCharsRead),
00212 &numCharsToSkip, 1);
00213 numHexCharsRead += numCharsToSkip;
00214
00215
00216 ACE_OS::strncpy (thisIorInfo->typeId,
00217 ioh->getString((char *)(thisIor + numHexCharsRead),
00218 2 * thisIorInfo->typeIdLen),
00219 thisIorInfo->typeIdLen);
00220
00221
00222
00223
00224 ioh->getIdlInterface(thisIorInfo->typeId, &validTypeId);
00225
00226 if (!validTypeId)
00227 {
00228 validTypeIdLen = 0;
00229 numHexCharsRead -= numCharsToSkip;
00230 }
00231 }
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 static const char *type_from_ior(const char *ior)
00243 {
00244 static IorHandler ior_handler;
00245
00246 const char *retval = NULL;
00247
00248 require(ior != NULL);
00249
00250 if( cbhey_data.cd_InterfaceType != NULL )
00251 {
00252 retval = cbhey_data.cd_InterfaceType;
00253 }
00254 else if( strncmp("IOR:", ior, 4) == 0 )
00255 {
00256 interpret_ior(&ior_handler, (char *)ior, &ior_handler.parsedIOR);
00257 retval = ior_handler.parsedIOR.typeId;
00258 }
00259 else if( strncmp("file://", ior, 7) == 0 )
00260 {
00261 int fd;
00262
00263 if( (fd = open((char *)&ior[7], O_RDONLY)) >= 0 )
00264 {
00265 char ior_buf[MAX_IOR_LEN];
00266 int len;
00267
00268 len = read(fd, ior_buf, MAX_IOR_LEN - 1);
00269 ior_buf[len] = '\0';
00270 interpret_ior(&ior_handler, ior_buf, &ior_handler.parsedIOR);
00271 retval = ior_handler.parsedIOR.typeId;
00272 close(fd);
00273 }
00274 else
00275 {
00276 perror("open");
00277 }
00278 }
00279 else
00280 {
00281 errno = EINVAL;
00282 }
00283 return( retval );
00284 }
00285
00286
00287
00288
00289 struct scan_payload;
00290
00291
00292
00293
00294
00295
00296
00297
00298 static int scan_file(const char *path, struct scan_payload *sp);
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 static int scan_path(const char *path, struct scan_payload *sp);
00309
00310
00311
00312
00313
00314
00315
00316
00317 static int scan_directory(const char *path, struct scan_payload *sp);
00318
00319
00320
00321
00322
00323
00324
00325
00326 static int scan_path_list(char *path_list, struct scan_payload *sp);
00327
00328 static int scan_directory(const char *path, struct scan_payload *sp)
00329 {
00330 int retval = EINVAL;
00331 DIR *dir;
00332
00333 require(path != NULL);
00334 require(sp != NULL);
00335
00336 if( (dir = opendir(path)) != NULL )
00337 {
00338 struct dirent *de;
00339
00340 while( (retval != 0) && ((de = readdir(dir)) != NULL) )
00341 {
00342 if( (strcmp(de->d_name, ".") == 0) ||
00343 (strcmp(de->d_name, "..") == 0) )
00344 {
00345 }
00346 else
00347 {
00348 string sub_path = path;
00349
00350 sub_path += "/";
00351 sub_path += de->d_name;
00352 retval = scan_path(sub_path.c_str(), sp);
00353 }
00354 }
00355 closedir(dir);
00356 }
00357 else
00358 {
00359 retval = errno;
00360 }
00361 return( retval );
00362 }
00363
00364 static int scan_path(const char *path, struct scan_payload *sp)
00365 {
00366 int retval = EINVAL;
00367 struct stat st;
00368
00369 require(path != NULL);
00370 require(sp != NULL);
00371
00372 if( stat(path, &st) == 0 )
00373 {
00374 if( st.st_mode & S_IFDIR )
00375 {
00376 retval = scan_directory(path, sp);
00377 }
00378 else
00379 {
00380 retval = scan_file(path, sp);
00381 }
00382 }
00383 else
00384 {
00385 retval = errno;
00386 }
00387 return( retval );
00388 }
00389
00390 static int scan_path_list(char *path_list, struct scan_payload *sp)
00391 {
00392 int retval = EINVAL;
00393 char *path;
00394
00395 require(path_list != NULL);
00396 require(sp != NULL);
00397
00398 while( (retval != 0) && ((path = strsep(&path_list, ":")) != NULL) )
00399 {
00400 retval = scan_path(path, sp);
00401 }
00402 return( retval );
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 struct scan_payload {
00415 const char *sp_hey_server_hint;
00416 lt_dlhandle sp_handle;
00417 factory_method_t sp_method;
00418 };
00419
00420 static int scan_file(const char *path, struct scan_payload *sp)
00421 {
00422 int retval = EINVAL;
00423 lt_dlhandle dlh;
00424
00425 require(path != NULL);
00426 require(sp != NULL);
00427
00428 if( (dlh = lt_dlopenext(path)) != NULL )
00429 {
00430 factory_method_t fm;
00431 int rc = EINVAL;
00432
00433 if( cbhey_data.cd_Flags & CDF_LIST )
00434 {
00435 cerr << " Library: " << path << endl;
00436 }
00437 if( ((fm = (factory_method_t)
00438 lt_dlsym(dlh, __XSTRING(FACTORY_METHOD_SYMBOL))) != NULL) &&
00439 ((rc = flFactoryMethod(fm, FLO_QUERY,
00440 FMA_HeyServerHint, sp->sp_hey_server_hint,
00441 FMA_TAG_DONE)) == 0) )
00442 {
00443 sp->sp_handle = dlh;
00444 sp->sp_method = fm;
00445 retval = 0;
00446 }
00447 else
00448 {
00449 if( cbhey_data.cd_Flags & CDF_DEBUG )
00450 {
00451 cerr << path
00452 << ": does not support type: "
00453 << (sp->sp_hey_server_hint == NULL ?
00454 "" :
00455 sp->sp_hey_server_hint)
00456 << endl;
00457 }
00458 lt_dlclose(dlh);
00459 retval = rc;
00460 }
00461 }
00462 else
00463 {
00464 if( cbhey_data.cd_Flags & CDF_DEBUG )
00465 {
00466 cerr << path << ": " << lt_dlerror() << endl;
00467 }
00468 retval = errno;
00469 }
00470 return( retval );
00471 }
00472
00473
00474
00475
00476
00477
00478
00479 static int scan_cbhey_paths(struct scan_payload *sp)
00480 {
00481 int retval = ENOENT;
00482 char *path_list;
00483
00484 require(sp != NULL);
00485
00486 if( (path_list = getenv("CBHEY_PATH")) != NULL )
00487 {
00488 retval = scan_path_list(path_list, sp);
00489 }
00490 if( retval != 0 )
00491 {
00492 retval = scan_path(__XSTRING(PACKAGE_DIRECTORY) "/lib", sp);
00493 }
00494 return( retval );
00495 }
00496
00497 int main(int argc, char *argv[])
00498 {
00499 const char *prog_name = argv[0];
00500 int retval = EXIT_FAILURE;
00501
00502 #if defined(HAVE_ACE)
00503 ACE_Log_Msg::instance()->priority_mask(0, ACE_Log_Msg::PROCESS);
00504 #endif
00505
00506 try
00507 {
00508 CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
00509 int rc;
00510
00511 rc = cbhProcessOptions(argc, argv);
00512 if( lt_dlinit() != 0 )
00513 {
00514 cerr << "Unable to initialize dynamic libraries\n";
00515 }
00516 else if( rc == 0 )
00517 {
00518 struct scan_payload sp;
00519
00520 memset(&sp, 0, sizeof(sp));
00521 if( cbhey_data.cd_Flags & CDF_LIST )
00522 {
00523 cout << "Supported interface/implementation types:" << endl;
00524 scan_cbhey_paths(&sp);
00525 retval = EXIT_SUCCESS;
00526 }
00527 else if( argc >= 3 )
00528 {
00529 HeyParser hp(argc, (const char **)argv);
00530 CORBA::Object_var obj;
00531 const char *obj_ior;
00532
00533 obj_ior = hp.who();
00534 obj = orb->string_to_object(obj_ior);
00535 if( CORBA::is_nil(obj.in()) )
00536 {
00537 cerr << "Null object" << endl;
00538 retval = 10;
00539 }
00540 else if( (sp.sp_hey_server_hint = type_from_ior(obj_ior)) ==
00541 NULL )
00542 {
00543 cerr << "Error: Invalid IOR: " << obj_ior << endl;
00544 }
00545 else if( scan_cbhey_paths(&sp) == 0 )
00546 {
00547 retval = flFactoryMethod(
00548 sp.sp_method, FLO_HEY,
00549 FMA_ORB, orb.in(),
00550 FMA_HeyServerHint, sp.sp_hey_server_hint,
00551 FMA_HeyParser, &hp,
00552 FMA_TAG_DONE);
00553 lt_dlclose(sp.sp_handle);
00554 }
00555 else
00556 {
00557 cerr << "Error: Unable to find handler library for "
00558 << sp.sp_hey_server_hint
00559 << endl;
00560 }
00561 }
00562 else
00563 {
00564 cbhUsage(prog_name);
00565 }
00566 }
00567 else
00568 {
00569 if( rc >= 0 )
00570 {
00571 cbhUsage(prog_name);
00572 }
00573 }
00574 }
00575 catch(const HeyParserException &he)
00576 {
00577 cerr << "Parse error: " << he << endl;
00578 }
00579 catch(const CORBA::SystemException &e)
00580 {
00581 cerr << "Caught Exception: " << e << endl;
00582 }
00583 catch(...)
00584 {
00585 cerr << "Caught an unhandled exception" << endl;
00586 }
00587
00588 return( retval );
00589 }