Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / utils / nslist / nsdel.cpp
blobffcd6f21cb60f1ac108cfa1a4780452d60a80e19
2 //=============================================================================
3 /**
4 * @file nsdel.cpp
6 * Naming Service del utility
8 * @author Carlos O'Ryan <coryan@uci.edu> enhanced Jan 15
9 * @author 2001 Paul Caffrey <denginere@hotmail.com> redone Jun 21
10 * @author 2006 Simon Massey <sma@prismtech.com>
12 //=============================================================================
15 #include "orbsvcs/CosNamingC.h"
16 #include "orbsvcs/Time_Utilities.h"
17 #include "tao/AnyTypeCode/Any.h"
18 #include "tao/Messaging/Messaging.h"
19 #include "tao/PolicyC.h"
20 #include "ace/Time_Value.h"
21 #include "ace/Log_Msg.h"
22 #include "ace/OS_NS_stdio.h"
23 #include "ace/OS_NS_string.h"
24 #include "ace/OS_NS_ctype.h"
25 #include "ace/Argv_Type_Converter.h"
27 //============================================================================
28 namespace
30 //==========================================================================
31 CORBA::Object_ptr
32 set_rtt(CORBA::ORB_ptr orb, CORBA::Object_ptr obj, ACE_Time_Value const& rtt)
34 if (rtt != ACE_Time_Value::zero)
36 #if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
37 TimeBase::TimeT roundTripTimeoutVal;
38 ORBSVCS_Time::Time_Value_to_TimeT(roundTripTimeoutVal, rtt);
40 CORBA::Any anyObjectVal;
41 anyObjectVal <<= roundTripTimeoutVal;
42 CORBA::PolicyList polList (1);
43 polList.length (1);
45 polList[0] = orb->create_policy(Messaging::RELATIVE_RT_TIMEOUT_POLICY_TYPE,
46 anyObjectVal);
48 CORBA::Object_var obj2 = obj->_set_policy_overrides(polList, CORBA::SET_OVERRIDE);
49 polList[0]->destroy();
50 return obj2._retn();
51 #else
52 ACE_DEBUG ((LM_DEBUG, "RTT not supported in TAO build.\n"));
53 #endif
55 return CORBA::Object::_duplicate(obj);
57 } // end of local unnamed namespace
59 int
60 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
62 int err = 0;
63 CosNaming::Name the_name (0);
64 CORBA::ORB_var orb;
66 try
68 // Contact the orb
69 orb = CORBA::ORB_init (argc, argv);
71 // Scan through the command line options
72 bool
73 failed = false,
74 quiet = false,
75 destroy = false;
76 const ACE_TCHAR *const pname = argv[0];
77 const ACE_TCHAR *nameService = 0;
78 ACE_TCHAR kindsep = ACE_TEXT('.');
79 ACE_TCHAR ctxsep[] = ACE_TEXT("/");
80 ACE_TCHAR *name = 0;
81 ACE_Time_Value
82 rtt = ACE_Time_Value::zero;
84 if (0 < argc)
86 while (0 < --argc)
88 ++argv;
89 if (0 == ACE_OS::strcmp (*argv, ACE_TEXT ("--ns")))
91 if (!--argc)
93 ACE_DEBUG ((LM_DEBUG,
94 "Error: --ns requires an argument\n"));
95 failed= true;
97 else
99 ++argv;
100 if (nameService)
102 ACE_DEBUG ((LM_DEBUG,
103 "Error: more than one --ns.\n"));
104 failed= true;
106 else
107 nameService = *argv;
110 else if (0 == ACE_OS::strcmp (*argv, ACE_TEXT ("--quiet")))
112 quiet = true;
114 else if (0 == ACE_OS::strcmp (*argv, ACE_TEXT ("--name")))
116 if (name)
118 ACE_DEBUG ((LM_DEBUG,
119 "Error: more than one --name\n"));
120 failed = true;
122 else if (!--argc)
124 ACE_DEBUG ((LM_DEBUG,
125 "Error: --name requires an argument\n"));
126 failed = true;
128 else
129 name = *(++argv);
131 else if (0 == ACE_OS::strcmp (*argv, ACE_TEXT ("--ctxsep")))
133 if (!--argc)
135 ACE_DEBUG ((LM_DEBUG,
136 "Error: --ctxsep requires a character\n"));
137 failed = true;
139 else if (1 != ACE_OS::strlen(*(++argv)))
141 ACE_DEBUG ((LM_DEBUG,
142 "Error: --ctxsep takes a single character (not %s)\n", *argv));
143 failed = true;
145 else
146 ctxsep[0] = (*argv)[0];
148 else if (0 == ACE_OS::strcmp (*argv, ACE_TEXT ("--kindsep")))
150 if (!--argc)
152 ACE_DEBUG ((LM_DEBUG,
153 "Error: --kindsep requires a character\n"));
154 failed = true;
156 else if (1 != ACE_OS::strlen(*(++argv)))
158 ACE_DEBUG ((LM_DEBUG,
159 "Error: --kindsep takes a single character (not %s)\n", *argv));
160 failed = true;
162 else
163 kindsep = (*argv)[0];
165 else if (0 == ACE_OS::strcmp(*argv, ACE_TEXT ("--rtt")))
167 if (rtt != ACE_Time_Value::zero)
169 ACE_DEBUG ((LM_DEBUG,
170 "Error: --rtt given more than once\n"));
171 failed = true;
173 else if (!--argc || !ACE_OS::ace_isdigit (ACE_TEXT_ALWAYS_CHAR (*(++argv))[0]))
175 ACE_DEBUG ((LM_DEBUG,
176 "Error: --rtt requires a number\n"));
177 failed = true;
179 else
180 rtt.set(ACE_OS::atoi (ACE_TEXT_ALWAYS_CHAR (*argv)), 0);
182 else if (0 == ACE_OS::strcmp (*argv, ACE_TEXT ("--destroy")))
184 destroy = true;
186 else
188 ACE_DEBUG ((LM_DEBUG,
189 "Unknown option %s\n", *argv));
190 failed = true;
195 if (!name || failed)
197 ACE_DEBUG ((LM_DEBUG,
198 "\nUsage:\n %s --name <name>\n"
199 "optional:\n"
200 " --ns <ior>\n"
201 " --ctxsep <character>\n"
202 " --kindsep <character>\n"
203 " --destroy\n"
204 " --quiet\n"
205 " --rtt <seconds> {Sets the relative round trip timeout policy}\n\n",
206 "where <name> uses the --ctxsep character (defaults to /)\n"
207 "to separate sub-contexts and --kindsep (defaults to .)\n"
208 "to separate ID & Kind. Will destroy a naming context\n"
209 "before unbinding if --destroy is given, otherwise it\n"
210 "will orphan them. Connects to default NameService\n"
211 "unless --ns is given. Displays all ID/Kinds found\n"
212 "on path unless --quiet is given.\n",
213 pname));
214 orb->destroy ();
215 return 1;
218 // Contact the name service
219 CORBA::Object_var nc_obj;
220 if (nameService)
221 nc_obj = orb->string_to_object (nameService);
222 else
223 nc_obj = orb->resolve_initial_references ("NameService");
225 nc_obj = set_rtt(orb.in(), nc_obj.in (), rtt);
226 CosNaming::NamingContext_var root_nc =
227 CosNaming::NamingContext::_narrow (nc_obj.in ());
229 if (CORBA::is_nil (root_nc.in ()))
231 ACE_DEBUG ((LM_DEBUG,
232 "Error: nil naming context\n"));
233 orb->destroy ();
234 return 1;
237 // Assemble the name from the user string given
238 ACE_TCHAR *cp;
239 while (0 != (cp = ACE_OS::strtok (name, ctxsep)))
241 const int index= the_name.length();
242 the_name.length (index+1);
243 ACE_TCHAR *kind = const_cast<ACE_TCHAR*> (ACE_OS::strchr (cp, kindsep));
244 if (kind)
246 *kind = '\0';
247 the_name[index].kind= CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(++kind));
249 the_name[index].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(cp));
250 name = 0; // way strtok works
253 // Attempt to locate the object and destroy/unbind it
254 CORBA::Object_var
255 obj = root_nc->resolve (the_name);
256 root_nc->unbind (the_name);
257 if (!quiet)
259 unsigned int index;
260 for (index= 0u; index < the_name.length()-1u; ++index)
262 if (the_name[index].kind && the_name[index].kind[0])
263 ACE_DEBUG ((LM_DEBUG, "Found ID: %C (Kind: %C)\n",
264 the_name[index].id.in(),
265 the_name[index].kind.in()));
266 else
267 ACE_DEBUG ((LM_DEBUG, "Found ID: %C\n",
268 the_name[index].id.in()));
270 ACE_DEBUG ((LM_DEBUG, "UnBound ID: %C",
271 the_name[index].id.in()));
272 if (the_name[index].kind && the_name[index].kind[0])
273 ACE_DEBUG ((LM_DEBUG, " (Kind: %C)\n",
274 the_name[index].kind.in()));
275 ACE_DEBUG ((LM_DEBUG, "\n"));
278 if (!quiet || destroy) {
279 bool failure = false;
280 try {
281 obj = set_rtt(orb.in (), obj.in (), rtt);
282 CosNaming::NamingContext_var this_nc =
283 CosNaming::NamingContext::_narrow (obj.in ());
284 if (!CORBA::is_nil (this_nc.in ()))
286 if (destroy)
288 if (!quiet)
289 ACE_DEBUG ((LM_DEBUG,"Destroying\n"));
290 this_nc->destroy( );
292 else if (!quiet)
294 CORBA::String_var str =
295 orb->object_to_string (obj.in ());
296 ACE_DEBUG ((LM_DEBUG,
297 "\n*** Possiably Orphaned Naming Context ***\n%C\n\n", str.in()));
300 else if (destroy && !quiet)
301 ACE_DEBUG ((LM_DEBUG,"Can't Destroy object, it is not a naming context!\n"));
303 catch (const CORBA::OBJECT_NOT_EXIST&)
305 if (!quiet)
306 ACE_DEBUG ((LM_DEBUG, "{Object does not exist!}\n"));
307 failure = true;
309 catch (const CORBA::TRANSIENT&)
311 if (!quiet)
312 ACE_DEBUG ((LM_DEBUG, "{Object is transient!}\n"));
313 failure = true;
315 catch (const CORBA::TIMEOUT&)
317 if (!quiet)
318 ACE_DEBUG ((LM_DEBUG, "{Operation timed out!}\n"));
319 failure = true;
322 if (failure && !quiet)
324 if (destroy) {
325 ACE_DEBUG ((LM_DEBUG, "Failed to destroy context.\n"));
327 else {
328 ACE_DEBUG ((LM_DEBUG, "Failed to check for orphaned naming context.\n"));
333 catch (const CosNaming::NamingContext::NotFound& nf)
335 unsigned int index;
336 const unsigned int limit= the_name.length()-nf.rest_of_name.length();
337 ACE_DEBUG ((LM_DEBUG, "\nError:\n"));
338 for (index= 0u; index < limit; ++index)
340 if (the_name[index].kind && the_name[index].kind[0])
341 ACE_DEBUG ((LM_DEBUG, "ID: %C (Kind: %C)\n",
342 the_name[index].id.in(),
343 the_name[index].kind.in()));
344 else
345 ACE_DEBUG ((LM_DEBUG, "ID: %C\n",
346 the_name[index].id.in()));
348 const char *why= "Unknown reason";
349 switch (nf.why)
351 case CosNaming::NamingContext::missing_node:
352 why= "\nThe following node is missing";
353 break;
354 case CosNaming::NamingContext::not_context:
355 why= "\nThe following is a final object binding, not a naming context";
356 break;
357 case CosNaming::NamingContext::not_object:
358 why= "\nThe following is a naming context, not a final object binding";
359 break;
361 nf._tao_print_exception (why);
362 for (index= 0u; index < nf.rest_of_name.length(); ++index)
364 if (nf.rest_of_name[index].kind && nf.rest_of_name[index].kind[0])
365 ACE_DEBUG ((LM_DEBUG, "ID: %C (Kind: %C)\n",
366 nf.rest_of_name[index].id.in(),
367 nf.rest_of_name[index].kind.in()));
368 else
369 ACE_DEBUG ((LM_DEBUG, "ID: %C\n",
370 nf.rest_of_name[index].id.in()));
372 ++err;
374 catch (const CORBA::Exception& ex)
376 ACE_DEBUG ((LM_DEBUG, "\nError:\n"));
377 ex._tao_print_exception ("Exception in nsdel");
378 ++err;
383 orb->destroy ();
385 catch (const CORBA::Exception& ex)
387 ACE_DEBUG ((LM_DEBUG, "\nError:\n"));
388 ex._tao_print_exception ("Exception in while shutting down");
389 ++err;
391 return err;