1 : //=============================================================================
2 : // File <$/src/cpp/prod/services/naming/CosNamingImpl.cpp>
3 : // This file is part of YaOrb : Yet Another Object Request Broker,
4 : // Copyright (c) 2000-2003, Marc Alff.
5 : //
6 : // This program is free software; you can redistribute it and/or
7 : // modify it under the terms of the GNU General Public License
8 : // as published by the Free Software Foundation; either version 2
9 : // of the License, or (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program; if not, write to the Free Software
18 : // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 : //
20 : //=============================================================================
21 :
22 : // Portability
23 : #include "yaorb/config.h"
24 : #include "src/cpp/prod/port/port_stdc.h"
25 : #include "src/cpp/prod/port/port_stdlib.h"
26 : #include "src/cpp/prod/port/port_unistd.h"
27 : #include "src/cpp/prod/port/port_dirent.h"
28 :
29 : #include <sys/types.h>
30 : #include <sys/stat.h>
31 : #include <stdio.h>
32 :
33 : #include <yaorb/CORBA.h>
34 : #include <yaorb/YAORB.h>
35 :
36 : #include "src/cpp/prod/services/naming/CosNamingImpl.h"
37 : #include "src/cpp/prod/tool/String.h"
38 : #include "src/cpp/prod/tool/Assert.h"
39 : #include "src/cpp/prod/protocol/cdr/cdr_file.h"
40 :
41 : // FIXME : use <glib.h> instead
42 : static const char G_DIR_SEPARATOR='/' ;
43 : static const char * const G_DIR_SEPARATOR_S="/" ;
44 :
45 : //=============================================================================
46 : // FILE STRUCTURES
47 : //=============================================================================
48 : //
49 : // The complete Naming service is implemented using files stored
50 : // under the "root directory".
51 : // Each context is implemented by :
52 : // - a directory, named CTXNNNN, under the root directory,
53 : // - a file describing the context name component,
54 : // found in the context directory.
55 : //
56 : // Each binding in a context is implemented by a binding file BNDNNNN.
57 : // This file contains :
58 : // - the name component of the binding,
59 : // - the type of the binding (local context, distant context, object).
60 : // - additional information, depending on the type of binding :
61 : // - local context object id (for local context),
62 : // - distant context IOR (for distant context),
63 : // - object IOR (for object).
64 : //
65 : // $(ROOT_DIR)
66 : // - CTX0000 (directory)
67 : // - CONTEXT (file)
68 : // - name component field.
69 : // - BND0000 (file)
70 : // - name component field.
71 : // - binding type field (local context)
72 : // - local context object id.
73 : // - BND0001 (file)
74 : // - name component field.
75 : // - binding type field (distant context)
76 : // - distant context IOR.
77 : // - BND0002 (file)
78 : // - name component field.
79 : // - binding type field (object)
80 : // - object IOR.
81 : // - CTX0001 (directory)
82 : // - CTX0002 (directory)
83 : // - ...
84 : // - CTXNNNN (directory)
85 : //
86 :
87 : //=============================================================================
88 : // Types
89 : //=============================================================================
90 :
91 : struct ContextImplInfo
92 1 : {
93 : int _id ;
94 : String _dirName ;
95 : String _fileName ;
96 : } ;
97 :
98 : struct FileBinding
99 0 : {
100 : CosNaming::NameComponent _nameComponent ;
101 : CORBA::Octet _type ;
102 : CORBA::String_var _info ;
103 :
104 : void cdr(YAORB::CDR* cdrs) ;
105 : } ;
106 :
107 0 : void FileBinding::cdr(YAORB::CDR* cdrs)
108 : {
109 0 : _nameComponent.cdr(cdrs) ;
110 0 : cdrs->cdr_Octet( & _type) ;
111 0 : _info.cdr(cdrs) ;
112 : }
113 :
114 : //=============================================================================
115 : // Constants
116 : //=============================================================================
117 :
118 : static const CORBA::Octet NAMING_CONTEXT_ID = 0 ;
119 : static const CORBA::Octet NAMING_CONTEXT_IOR = 1 ;
120 : static const CORBA::Octet OBJECT_IOR = 2 ;
121 :
122 : static const char* const BND_PREFIX = "BND" ;
123 : static const int BND_PREFIX_LENGTH = 3 ;
124 :
125 : static const char* const CTX_PREFIX = "CTX" ;
126 : static const int CTX_PREFIX_LENGTH = 3 ;
127 :
128 : static const char* const CTX_FILE_NAME = "CONTEXT" ;
129 :
130 : //=============================================================================
131 : // Static variables
132 : //=============================================================================
133 :
134 1 : static String rootDir ;
135 :
136 : //=============================================================================
137 : // Static methods
138 : //=============================================================================
139 :
140 : static bool readContext(
141 : ContextImplInfo& info,
142 : CosNaming::NameComponent& nc) ;
143 :
144 : static void writeContext(
145 : ContextImplInfo& info,
146 : CosNaming::NameComponent& nc) ;
147 :
148 : void
149 1 : NamingContextImpl::Init(const char* dir)
150 : {
151 1 : if (dir == NULL)
152 : {
153 0 : throw CORBA::BAD_PARAM() ;
154 : }
155 :
156 1 : if (dir[0] == '\0')
157 : {
158 0 : throw CORBA::BAD_PARAM() ;
159 : }
160 :
161 1 : rootDir = dir ;
162 1 : int len = strlen(dir) ;
163 :
164 1 : if (dir[len-1] != G_DIR_SEPARATOR)
165 : {
166 1 : rootDir += G_DIR_SEPARATOR_S ;
167 : }
168 :
169 : //---------------------------------------------------------------------------
170 : // Create the root directory
171 : //---------------------------------------------------------------------------
172 :
173 : struct stat buf ;
174 : int rc ;
175 :
176 1 : rc = stat(rootDir, &buf) ;
177 :
178 1 : if (rc != 0)
179 : {
180 1 : rc = mkdir(rootDir, S_IRWXU) ;
181 :
182 1 : if (rc != 0)
183 : {
184 0 : perror("Can not create Name Service Root Directory") ;
185 0 : throw CORBA::PERSIST_STORE() ;
186 : }
187 : }
188 :
189 : //---------------------------------------------------------------------------
190 : // Create the root context
191 : //---------------------------------------------------------------------------
192 :
193 : ContextImplInfo info ;
194 : bool found ;
195 :
196 1 : info._id = 0L ;
197 1 : info._dirName = rootDir ;
198 1 : info._dirName += "CTX0" ;
199 1 : info._dirName += G_DIR_SEPARATOR_S ;
200 :
201 1 : info._fileName = info._dirName ;
202 1 : info._fileName += CTX_FILE_NAME ;
203 :
204 : CosNaming::NameComponent nc ;
205 : const char* empty = "" ;
206 1 : nc.id = empty ;
207 1 : nc.kind = empty ;
208 :
209 : found = readContext(info, nc) ;
210 :
211 : if ( ! found )
212 : {
213 : writeContext(info, nc) ;
214 : }
215 : }
216 :
217 : CORBA::Object_ptr
218 : NamingContextImpl::resolveInitial(
219 1 : PortableServer::POA_ptr poa)
220 : {
221 : // ObjectId for a context is the context number
222 1 : PortableServer::ObjectId oid ;
223 1 : oid.length(4) ;
224 1 : oid[0] = 0x00 ;
225 1 : oid[1] = 0x00 ;
226 1 : oid[2] = 0x00 ;
227 1 : oid[3] = 0x00 ;
228 :
229 : CORBA::Object_ptr inc ;
230 1 : inc = poa->create_reference_with_id(oid, "FIXME") ;
231 :
232 1 : return inc ;
233 : }
234 :
235 : //=============================================================================
236 : // File bindings implementation
237 : //=============================================================================
238 :
239 : static void writeFileBinding(
240 : ContextImplInfo& info,
241 : FileBinding& fb)
242 : {
243 : // FIXME : BUG if TMPDIR is used.
244 0 : char* filename = tempnam(info._dirName, BND_PREFIX) ;
245 :
246 0 : CDRFile cdrs(filename, YAORB::CDR_WRITE) ;
247 0 : cdrs.cdr_ByteOrder() ;
248 0 : fb.cdr(& cdrs) ;
249 :
250 0 : free(filename) ;
251 : }
252 :
253 : static bool readFileBinding(
254 : ContextImplInfo& info,
255 : const CosNaming::NameComponent& nc,
256 : FileBinding& fb)
257 : {
258 : DIR *dir = NULL ;
259 : struct dirent *entry = NULL ;
260 :
261 : bool found = false ;
262 0 : dir = opendir(info._dirName) ;
263 :
264 0 : while ((entry = readdir(dir)) != NULL)
265 : {
266 0 : if (strncmp(entry->d_name, BND_PREFIX, BND_PREFIX_LENGTH) == 0)
267 : {
268 0 : CDRFile cdrs(entry->d_name, YAORB::CDR_READ) ;
269 0 : cdrs.cdr_ByteOrder() ;
270 0 : fb.cdr(& cdrs) ;
271 :
272 0 : if ( (strcmp(nc.id.in() , fb._nameComponent.id.in() ) == 0)
273 : && (strcmp(nc.kind.in(), fb._nameComponent.kind.in() ) == 0) )
274 : {
275 : found = true ;
276 : break ;
277 0 : }
278 : }
279 : }
280 :
281 0 : closedir(dir) ;
282 :
283 : return found ;
284 : }
285 :
286 : static bool readContext(
287 : ContextImplInfo& info,
288 : CosNaming::NameComponent& nc)
289 : {
290 : int rc ;
291 : struct stat buf ;
292 :
293 1 : rc = stat(info._fileName, & buf) ;
294 :
295 1 : if (rc != 0)
296 : {
297 : return false ;
298 : }
299 :
300 0 : CDRFile cdrs(info._fileName, YAORB::CDR_READ) ;
301 0 : cdrs.cdr_ByteOrder() ;
302 0 : nc.cdr( & cdrs) ;
303 :
304 0 : return true ;
305 : }
306 :
307 : static void writeContext(
308 : ContextImplInfo& info,
309 : CosNaming::NameComponent& nc)
310 : {
311 : int rc ;
312 1 : rc = mkdir(info._dirName, S_IRWXU) ;
313 :
314 1 : if (rc != 0)
315 : {
316 0 : perror("Can not create Naming Context Directory") ;
317 0 : throw CORBA::PERSIST_STORE() ;
318 : }
319 :
320 : try
321 : {
322 1 : CDRFile cdrs(info._fileName, YAORB::CDR_WRITE) ;
323 1 : cdrs.cdr_ByteOrder() ;
324 1 : nc.cdr( & cdrs) ;
325 : }
326 0 : catch (const CORBA::MARSHAL &)
327 : {
328 0 : perror("Can not write Naming Context file") ;
329 0 : throw CORBA::PERSIST_STORE() ;
330 : }
331 : }
332 :
333 : //=============================================================================
334 : // Implementation of CosNaming::NamingContext
335 : //=============================================================================
336 :
337 : void
338 0 : NamingContextImpl::findInfo(ContextImplInfo &info)
339 : {
340 0 : NON_DEV("NamingContextImpl") ;
341 : }
342 :
343 1 : NamingContextImpl::NamingContextImpl()
344 : {
345 1 : }
346 :
347 0 : NamingContextImpl::~NamingContextImpl()
348 : {
349 0 : }
350 :
351 : void
352 : NamingContextImpl::bind(
353 : const CosNaming::Name& n,
354 0 : const CORBA::Object_ptr obj)
355 : {
356 : ContextImplInfo info ;
357 0 : findInfo(info) ;
358 :
359 0 : bind2(info, n, obj) ;
360 : }
361 :
362 : void
363 : NamingContextImpl::bind2(
364 : ContextImplInfo& info,
365 : const CosNaming::Name& n,
366 0 : const CORBA::Object_ptr obj)
367 : {
368 0 : if (n.length() == 0)
369 : {
370 0 : throw CORBA::BAD_PARAM() ;
371 : }
372 :
373 0 : if (n.length() == 1)
374 : {
375 : FileBinding fb ;
376 : bool bound ;
377 :
378 : bound = readFileBinding(info, n[0], fb) ;
379 0 : if (bound)
380 : {
381 0 : throw CosNaming::NamingContext::AlreadyBound() ;
382 : }
383 :
384 : fb._nameComponent = n[0] ;
385 0 : fb._type = OBJECT_IOR ;
386 : // FIXME : fb._info = obj->CORBA::ORB::object_to_string() ;
387 :
388 : writeFileBinding(info, fb) ;
389 : }
390 : else
391 : {
392 : CosNaming::Name prefix = n ;
393 : prefix.length(1) ;
394 :
395 : CORBA::Object_var nc ;
396 0 : nc = resolve2(info, prefix) ;
397 :
398 : CosNaming::NamingContext_var nc2 ;
399 0 : nc2 = CosNaming::NamingContext::_narrow(nc) ;
400 :
401 0 : if ( ! CORBA::is_nil(nc2) )
402 : {
403 : CosNaming::Name suffix ;
404 : suffix.length(n.length() -1) ;
405 :
406 0 : NON_DEV("NamingContextImpl") ;
407 :
408 0 : nc2->bind(suffix, obj) ;
409 : }
410 : else
411 : {
412 0 : NON_DEV("NamingContextImpl") ;
413 : }
414 : }
415 : }
416 :
417 : void
418 : NamingContextImpl::rebind(
419 : const CosNaming::Name& n,
420 0 : const CORBA::Object_ptr obj)
421 : {
422 0 : NON_DEV("NamingContextImpl") ;
423 : }
424 :
425 : void
426 : NamingContextImpl::rebind2(
427 : ContextImplInfo& info,
428 : const CosNaming::Name& n,
429 0 : const CORBA::Object_ptr obj)
430 : {
431 0 : NON_DEV("NamingContextImpl") ;
432 : }
433 :
434 : void
435 : NamingContextImpl::bind_context(
436 : const CosNaming::Name& n,
437 0 : CosNaming::NamingContext_ptr nc)
438 : {
439 0 : NON_DEV("NamingContextImpl") ;
440 : }
441 :
442 : void
443 : NamingContextImpl::bind_context2(
444 : ContextImplInfo& info,
445 : const CosNaming::Name& n,
446 0 : CosNaming::NamingContext_ptr nc)
447 : {
448 0 : NON_DEV("NamingContextImpl") ;
449 : }
450 :
451 : void
452 : NamingContextImpl::rebind_context(
453 : const CosNaming::Name& n,
454 0 : CosNaming::NamingContext_ptr nc)
455 : {
456 0 : NON_DEV("NamingContextImpl") ;
457 : }
458 :
459 : CORBA::Object_ptr
460 : NamingContextImpl::resolve(
461 0 : const CosNaming::Name& n)
462 : {
463 : ContextImplInfo info ;
464 0 : findInfo(info) ;
465 :
466 0 : return resolve2(info, n) ;
467 : }
468 :
469 : CORBA::Object_ptr
470 : NamingContextImpl::resolve2(
471 : ContextImplInfo& info,
472 0 : const CosNaming::Name& n)
473 : {
474 0 : if (n.length() == 0)
475 : {
476 0 : throw CORBA::BAD_PARAM() ;
477 : }
478 :
479 : if (n.length() == 1)
480 : {
481 :
482 : }
483 : else
484 : {
485 :
486 : }
487 :
488 0 : NON_DEV("NamingContextImpl") ;
489 :
490 0 : return CORBA::Object::_nil() ;
491 : }
492 :
493 : void
494 : NamingContextImpl::unbind(
495 0 : const CosNaming::Name& n)
496 : {
497 0 : NON_DEV("NamingContextImpl") ;
498 : }
499 :
500 : CosNaming::NamingContext_ptr
501 0 : NamingContextImpl::new_context(void)
502 : {
503 0 : NON_DEV("NamingContextImpl") ;
504 :
505 0 : return CosNaming::NamingContext::_nil() ;
506 : }
507 :
508 : CosNaming::NamingContext_ptr
509 : NamingContextImpl::bind_new_context(
510 0 : const CosNaming::Name& n)
511 : {
512 0 : NON_DEV("NamingContextImpl") ;
513 :
514 0 : return CosNaming::NamingContext::_nil() ;
515 : }
516 :
517 : void
518 0 : NamingContextImpl::destroy(void)
519 : {
520 0 : NON_DEV("NamingContextImpl") ;
521 : }
522 :
523 : void
524 : NamingContextImpl::list(
525 : CORBA::ULong how_many,
526 : CosNaming::BindingList*& bl,
527 0 : CosNaming::BindingIterator_ptr& bi)
528 : {
529 0 : NON_DEV("NamingContextImpl") ;
530 : }
531 :
532 :
533 : //=============================================================================
534 : // Implementation of CosNaming::BindingIterator
535 : //=============================================================================
536 :
537 :
538 : CORBA::Boolean
539 : BindingIteratorImpl::next_one(
540 0 : const CosNaming::Binding& b)
541 : {
542 0 : NON_DEV("BindingIteratorImpl") ;
543 :
544 : return false ;
545 : }
546 :
547 : CORBA::Boolean
548 : BindingIteratorImpl::next_n(
549 : CORBA::ULong how_many,
550 0 : CosNaming::BindingList*& bl)
551 : {
552 0 : NON_DEV("BindingIteratorImpl") ;
553 :
554 : return false ;
555 : }
556 :
557 : void
558 0 : BindingIteratorImpl::destroy(void)
559 : {
560 0 : NON_DEV("BindingIteratorImpl") ;
561 1 : }
562 1 :
563 0 :
|