1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27
28 #ifdef REV_INFO
29 #ifndef lint
30 static char rcsid[] = "$XConsortium: MrmItop.c /main/15 1996/11/13 13:58:55 drk $"
31 #endif
32 #endif
33
34
35 /*
36 *++
37 * FACILITY:
38 *
39 * UIL Resource Manager (URM): IDB facility
40 *
41 * ABSTRACT:
42 *
43 * This module contains the publicly accessible top-level
44 * IDB read & common (to read and write operations) routines.
45 *
46 *--
47 */
48
49
50 /*
51 *
52 * INCLUDE FILES
53 *
54 */
55
56 #include <Mrm/MrmAppl.h>
57 #include <Mrm/Mrm.h>
58 #include <Mrm/IDB.h>
59
60
61 /*
62 *
63 * TABLE OF CONTENTS
64 *
65 * UrmIdbOpenFileRead Open a file for read access
66 *
67 * UrmIdbOpenBuffer Open a file contained in a buffer
68 *
69 * UrmIdbCloseFile Close an open file
70 *
71 * UrmIdbGetIndexedResource Get indexed resource from file
72 *
73 * UrmIdbFindIndexedResource Find indexed resource(s) in file
74 *
75 * UrmIdbGetRIDResource Get resource id'ed resource from file
76 *
77 * UrmIdbGetResourceId Get next resource id in file
78 *
79 * Idb__FIL_Valid Validate file id
80 */
81
82
83 /*
84 *++
85 *
86 * PROCEDURE DESCRIPTION:
87 *
88 * IdbOpenFile opens the requested IDB database file, and returns a
89 * handle or id which is used in all subsequent IDB operations.
90 * IdbOpenFile initializes the file's index structures and sets up
91 * any buffers it needs. The database file is opened for read access only.
92 *
93 * FORMAL PARAMETERS:
94 *
95 * name A system-dependent string specifying the IDB file
96 * to be opened.
97 * os_ext An operating-system specific structure which
98 * supports using specific file system features
99 * file_id_return returns the IDB file id used in all other IDB routines
100 * fname_return returns the name of the file actually opened
101 * (via strcpy). Should be at least 256 chars.
102 *
103 * IMPLICIT INPUTS:
104 *
105 * IMPLICIT OUTPUTS:
106 *
107 * FUNCTION VALUE:
108 *
109 * MrmSUCCESS operation succeeded
110 * MrmNOT_FOUND existing file not found
111 * MrmFAILURE operation failed, no further reason
112 *
113 * SIDE EFFECTS:
114 *
115 * 1. Acquires memory for the file descriptor.
116 *
117 *--
118 */
119
120 Cardinal
121 UrmIdbOpenFileRead (String name,
122 MrmOsOpenParamPtr os_ext,
123 IDBFile *file_id_return,
124 char *fname_return)
125 {
126
127 /*
128 * Local variables
129 */
130 Cardinal result ; /* function results */
131 IDBLowLevelFilePtr fileid ; /* low-level id for file */
132 IDBFile filedesc ; /* new file descriptor */
133 int ndx ; /* loop index */
134
135
136 /*
137 * Attempt to open the file.
138 */
139 result = Idb__FU_OpenFile
140 (name, URMReadAccess, os_ext, &fileid, fname_return) ;
141 if ( result != MrmSUCCESS ) return result ;
142
143 /*
144 * File successfully opened. Acquire a file descriptor and initialize it.
145 */
146 filedesc = (IDBFile) XtMalloc (sizeof(IDBOpenFile)) ;
147 if ( filedesc == NULL )
148 {
149 Idb__FU_CloseFile (fileid, FALSE);
150 return MrmFAILURE ;
151 }
152
153 filedesc->validation = IDBOpenFileValid ;
154 filedesc->access = URMReadAccess ;
155 filedesc->lowlevel_id = fileid ;
156 filedesc->last_record = 0 ;
157 filedesc->last_data_record = 0 ;
158 filedesc->get_count = 0 ;
159 filedesc->put_count = 0 ;
160 filedesc->class_ctable = NULL;
161 filedesc->resource_ctable = NULL;
162 filedesc->byte_swapped = FALSE ;
163 filedesc->in_memory = FALSE ;
164 filedesc->uid_buffer = NULL ;
165 for ( ndx=IDBrtMin ; ndx<=IDBrtMax ; ndx++ )
166 filedesc->rt_counts[ndx] = 0 ;
167
168 /*
169 * Read the file header record info into the file descriptor
170 */
171 result = Idb__HDR_GetHeader (filedesc) ;
172 if ( result != MrmSUCCESS )
173 {
174 UrmIdbCloseFile (filedesc, TRUE) ;
175 return result ;
176 }
177
178 /*
179 * File successfully opened
180 */
181 *file_id_return = filedesc ;
182 return MrmSUCCESS ;
183
184 }
185
186
187 /*
188 *++
189 *
190 * PROCEDURE DESCRIPTION:
191 *
192 * This is a simplified version of UrmIdbOpenFile which opens
193 * a buffer contained in memory.
194 *
195 * FORMAL PARAMETERS:
196 *
197 * uid_buffer the buffer containing the uid file
198 * file_id_return returns the IDB file id used in all other IDB routines
199 *
200 * IMPLICIT INPUTS:
201 *
202 * IMPLICIT OUTPUTS:
203 *
204 * FUNCTION VALUE:
205 *
206 * MrmSUCCESS operation succeeded
207 * MrmNOT_FOUND existing file not found
208 * MrmFAILURE operation failed, no further reason
209 *
210 * SIDE EFFECTS:
211 *
212 * 1. Acquires memory for the file descriptor.
213 *
214 *--
215 */
216
217 Cardinal
UrmIdbOpenBuffer(unsigned char * uid_buffer,IDBFile * file_id_return)218 UrmIdbOpenBuffer (unsigned char *uid_buffer,
219 IDBFile *file_id_return)
220 {
221
222 /*
223 * Local variables
224 */
225 Cardinal result ; /* function results */
226 IDBFile filedesc ; /* new file descriptor */
227 int ndx ; /* loop index */
228
229
230 filedesc = (IDBFile) XtMalloc (sizeof(IDBOpenFile)) ;
231 if ( filedesc == NULL ) return MrmFAILURE ;
232
233 filedesc->validation = IDBOpenFileValid ;
234 filedesc->access = URMReadAccess ;
235 filedesc->lowlevel_id = NULL ;
236 filedesc->last_record = 0 ;
237 filedesc->last_data_record = 0 ;
238 filedesc->get_count = 0 ;
239 filedesc->put_count = 0 ;
240 filedesc->class_ctable = NULL;
241 filedesc->resource_ctable = NULL;
242 filedesc->byte_swapped = FALSE ;
243 filedesc->in_memory = TRUE ;
244 filedesc->uid_buffer = uid_buffer ;
245 for ( ndx=IDBrtMin ; ndx<=IDBrtMax ; ndx++ )
246 filedesc->rt_counts[ndx] = 0 ;
247
248 /*
249 * Read the file header record info into the file descriptor
250 */
251 result = Idb__HDR_GetHeader (filedesc) ;
252 if ( result != MrmSUCCESS ) return result ;
253
254 /*
255 * Buffer ready
256 */
257 *file_id_return = filedesc ;
258 return MrmSUCCESS ;
259
260 }
261
262
263
264 /*
265 *++
266 *
267 * PROCEDURE DESCRIPTION:
268 *
269 * If the file was opened for read access, then UrmIdbCloseFile simply
270 * closes it. If it was opened for write acccess, then UrmIdbCloseFile
271 * uses keep_new_file to determine its behavior. If keep_new_file is
272 * true, then the file's index structures are updated, the file is
273 * closed, and it becomes the newest version of the database file.
274 * If keep_new_file is false, then the working copy of the file is closed
275 * and deleted, retaining the previous version of the file as the latest
276 * version. In all cases, UrmIdbCloseFile frees all memory structures
277 * associated with the file.
278 *
279 * FORMAL PARAMETERS:
280 *
281 * file_id The IDB file id returned by IdbOpenFile
282 * keep_new_file true if database is to be permanently updated;
283 * false to quit without changing the database
284 *
285 * IMPLICIT INPUTS:
286 *
287 * IMPLICIT OUTPUTS:
288 *
289 * FUNCTION VALUE:
290 *
291 * MrmSUCCESS operation succeeded
292 * MrmFAILURE operation failed
293 *
294 * SIDE EFFECTS:
295 *
296 *--
297 */
298
299 /*ARGSUSED*/
300 Cardinal
UrmIdbCloseFile(IDBFile file_id,Boolean keep_new_file)301 UrmIdbCloseFile (IDBFile file_id,
302 Boolean keep_new_file) /* unused */
303 {
304
305 /*
306 * Local variables
307 */
308 Cardinal result ; /* function results */
309
310 /*
311 * Local macros
312 */
313 #define _error_close() \
314 { \
315 Idb__FU_CloseFile(file_id->lowlevel_id,TRUE) ; \
316 file_id->validation = 0 ; \
317 XtFree((char*)file_id) ; \
318 return MrmFAILURE ; \
319 }
320
321 if ( (result=Idb__FIL_Valid(file_id)) != MrmSUCCESS ) return result ;
322
323 /*
324 * We are serious about closing this file so deallocate the class and resource
325 * tables before we do anything else.
326 */
327
328 if (file_id->class_ctable != NULL)
329 XtFree ((char*)file_id->class_ctable);
330 if (file_id->resource_ctable != NULL)
331 XtFree ((char*)file_id->resource_ctable);
332
333 /*
334 * If the file was opened for write, update its header
335 */
336 if ( file_id->access == URMWriteAccess )
337 {
338 result = Idb__HDR_PutHeader ( file_id ) ;
339 if ( result != MrmSUCCESS ) _error_close () ;
340 }
341
342 /*
343 * Decommit the file's buffers
344 */
345 result = Idb__BM_DecommitAll (file_id) ;
346 if ( result != MrmSUCCESS ) _error_close () ;
347
348 /*
349 * Close the file and deallocate the file descriptor
350 */
351 result = Idb__FU_CloseFile (file_id->lowlevel_id, FALSE) ;
352 file_id->validation = 0 ;
353 XtFree ((char*)file_id) ;
354
355 /*
356 * File successfully closed
357 */
358 return MrmSUCCESS ;
359
360 }
361
362
363
364 /*
365 *++
366 *
367 * PROCEDURE DESCRIPTION:
368 *
369 * IdbGetIndexedResource attempts to retrieve a resource record with
370 * a matching index. The entry's group and type must match the filters
371 * when these are not null (RMCcNull and RMCtNull respectively). If a
372 * matching entry is found, its resource group, type, access, and data
373 * block are returned in the resource context. The resource context
374 * memory buffer will be reallocated as required to hold the data block.
375 *
376 * FORMAL PARAMETERS:
377 *
378 * file_id The IDB file id returned by IdbOpenFile
379 * index case-sensitive index for the entry to match
380 * group_filter if not null, entry found must match this group
381 * type_filter if not null, entry found must match this type
382 * context_id URM resource context to receieve data block
383 *
384 * IMPLICIT INPUTS:
385 *
386 * IMPLICIT OUTPUTS:
387 *
388 * FUNCTION VALUE:
389 *
390 * MrmSUCCESS operation succeeded
391 * MrmNOT_FOUND entry not found
392 * MrmWRONG_GROUP entry didn't match group filter
393 * MrmWRONG_TYPE entry didn't match type filter
394 * MrmFAILURE operation failed, no further reason
395 *
396 * SIDE EFFECTS:
397 *
398 *--
399 */
400
401 Cardinal
UrmIdbGetIndexedResource(IDBFile file_id,String index,MrmGroup group_filter,MrmType type_filter,URMResourceContextPtr context_id)402 UrmIdbGetIndexedResource (IDBFile file_id,
403 String index,
404 MrmGroup group_filter,
405 MrmType type_filter,
406 URMResourceContextPtr context_id)
407 {
408
409 /*
410 * Local variables
411 */
412 Cardinal result ; /* function results */
413 IDBDataHandle data_entry ; /* return new data entry */
414 MrmCode group ; /* data entry's group */
415 MrmCode type ; /* data entry's type */
416
417
418 if ( (result=Idb__FIL_Valid(file_id)) != MrmSUCCESS ) return result ;
419
420 /*
421 * Attempt to find the item.
422 */
423 result = Idb__INX_ReturnItem (file_id, index, &data_entry) ;
424 if ( result != MrmSUCCESS ) return result ;
425 result = Idb__DB_GetDataEntry (file_id, data_entry, context_id) ;
426 if ( result != MrmSUCCESS ) return result ;
427
428 /*
429 * Check group and type against filters.
430 */
431 group = UrmRCGroup (context_id) ;
432 type = UrmRCType (context_id) ;
433 if ( (group_filter!=URMgNul) && (group_filter!=group) )
434 return MrmWRONG_GROUP ;
435 if ( (type_filter!=URMtNul) && (type_filter!=type) )
436 return MrmWRONG_TYPE ;
437
438 /*
439 * Item successfuly retrieved
440 */
441 return MrmSUCCESS ;
442
443 }
444
445
446
447 /*
448 *++
449 *
450 * PROCEDURE DESCRIPTION:
451 *
452 * IdbFindIndexedResource locates and lists all resources in the
453 * database which match the given filters. The entries in the
454 * index list will be in alphabetical order. The index strings must
455 * be deallocated by the caller using UrmFreePlistContents. This
456 * routine returns MrmSUCCESS even if no entries (0 entries) are found.
457 * Failure returns are used only for internal and other errors.
458 *
459 * The number of entries in index_list is not reset to 0 when
460 * the search begins; its state is as the caller gives it.
461 *
462 * FORMAL PARAMETERS:
463 *
464 * file_id The IDB file id returned by IdbOpenFile
465 * group_filter if not null, entries found must match this group
466 * type_filter if not null, entries found must match this type
467 * index_list A pointer list in which to return index
468 * strings for matches. The required strings
469 * are automatically allocated.
470 *
471 * IMPLICIT INPUTS:
472 *
473 * IMPLICIT OUTPUTS:
474 *
475 * FUNCTION VALUE:
476 *
477 * MrmSUCCESS operation succeeded
478 * MrmFAILURE operation failed, no further reason
479 *
480 * SIDE EFFECTS:
481 *
482 *--
483 */
484
485 Cardinal
UrmIdbFindIndexedResource(IDBFile file_id,MrmGroup group_filter,MrmType type_filter,URMPointerListPtr index_list)486 UrmIdbFindIndexedResource (IDBFile file_id,
487 MrmGroup group_filter,
488 MrmType type_filter,
489 URMPointerListPtr index_list)
490 {
491
492 /*
493 * Local variables
494 */
495 Cardinal result ; /* function results */
496
497
498 /*
499 * Validate file id, then initiate search with the root node. Return
500 * immediately if there are no indexed resources.
501 */
502 if ( (result=Idb__FIL_Valid(file_id)) != MrmSUCCESS ) return result ;
503
504 if ( file_id->num_indexed <= 0 ) return MrmSUCCESS ;
505 return Idb__INX_FindResources (file_id, file_id->index_root,
506 group_filter, type_filter, index_list) ;
507
508 }
509
510
511
512 /*
513 *++
514 *
515 * PROCEDURE DESCRIPTION:
516 *
517 * IdbGetRIDResource attempts to retrieve a resource record with a
518 * matching resource id. If there is a resource record associated with
519 * the resource id, it is returned - the resource group, type, and data
520 * block are set in the resource context. The memory buffer in the
521 * resource context is reallocated automatically as require to hold the
522 * data block.
523 *
524 * FORMAL PARAMETERS:
525 *
526 * file_id The IDB file id returned by IdbOpenFile
527 * resource_id resource id matching entry
528 * group_filter if not null, entries found must match this group
529 * type_filter if not null, entries found must match this type
530 * context_id to return data block
531 *
532 * IMPLICIT INPUTS:
533 *
534 * IMPLICIT OUTPUTS:
535 *
536 * FUNCTION VALUE:
537 *
538 * MrmSUCCESS operation succeeded
539 * MrmNOT_FOUND entry not found
540 * MrmWRONG_GROUP entry didn't match group filter
541 * MrmWRONG_TYPE entry didn't match type filter
542 * MrmFAILURE operation failed, no further reason
543 *
544 * SIDE EFFECTS:
545 *
546 *--
547 */
548
549 Cardinal
UrmIdbGetRIDResource(IDBFile file_id,MrmResource_id resource_id,MrmGroup group_filter,MrmType type_filter,URMResourceContextPtr context_id)550 UrmIdbGetRIDResource (IDBFile file_id,
551 MrmResource_id resource_id,
552 MrmGroup group_filter,
553 MrmType type_filter,
554 URMResourceContextPtr context_id)
555 {
556
557 /*
558 * Local variables
559 */
560 Cardinal result ; /* function results */
561 IDBDataHandle data_entry ; /* return new data entry */
562 MrmCode group ; /* data entry's group */
563 MrmCode type ; /* data entry's type */
564
565
566 if ( (result=Idb__FIL_Valid(file_id)) != MrmSUCCESS ) return result ;
567
568 /*
569 * Attempt to find the item.
570 */
571 result = Idb__RID_ReturnItem (file_id, resource_id, TRUE, &data_entry) ;
572 if ( result != MrmSUCCESS ) return result ;
573 result = Idb__DB_GetDataEntry (file_id, data_entry, context_id) ;
574 if ( result != MrmSUCCESS ) return result ;
575
576 /*
577 * Check group and type against filters.
578 */
579 group = UrmRCGroup (context_id) ;
580 type = UrmRCType (context_id) ;
581 if ( (group_filter!=URMgNul) && (group_filter!=group) )
582 return MrmWRONG_GROUP ;
583 if ( (type_filter!=URMtNul) && (type_filter!=type) )
584 return MrmWRONG_TYPE ;
585
586 /*
587 * Item successfuly retrieved
588 */
589 return MrmSUCCESS ;
590
591 }
592
593 /*
594 *++
595 *
596 * PROCEDURE DESCRIPTION:
597 *
598 * IdbGetResourceId returns the next available resource id in the file
599 *
600 * FORMAL PARAMETERS:
601 *
602 * file_id The IDB file id returned by IdbOpenFile
603 * resource_id_return To return new resource id
604 * IMPLICIT INPUTS:
605 *
606 * IMPLICIT OUTPUTS:
607 *
608 * FUNCTION VALUE:
609 *
610 * MrmSUCCESS operation succeeded
611 * MrmFAILURE operation failed, no further reason given
612 *
613 * SIDE EFFECTS:
614 *
615 *--
616 */
617
618 Cardinal
UrmIdbGetResourceId(IDBFile file_id,MrmResource_id * resource_id_return)619 UrmIdbGetResourceId (IDBFile file_id,
620 MrmResource_id *resource_id_return)
621 {
622
623 /*
624 * Local variables
625 */
626 Cardinal result ; /* function results */
627 IDBResource resource_id;
628
629 if ( (result=Idb__FIL_Valid((IDBFile)file_id)) != MrmSUCCESS ) return result ;
630 result = Idb__RID_NextRID ((IDBFile)file_id,
631 &resource_id) ;
632 *resource_id_return = resource_id;
633 return result ;
634
635 }
636
637
638
639 /*
640 *++
641 *
642 * PROCEDURE DESCRIPTION:
643 *
644 * This routine performs a validity check on a (supposed) IDB file
645 * pointer. It should probably signal errors, but currently just
646 * returns a code.
647 *
648 * FORMAL PARAMETERS:
649 *
650 * file_id Supposed pointer to file descriptor to validate
651 *
652 * IMPLICIT INPUTS:
653 *
654 * IMPLICIT OUTPUTS:
655 *
656 * FUNCTION VALUE:
657 *
658 * MrmSUCCESS operation succeeded
659 * MrmFAILURE some other failure
660 *
661 * SIDE EFFECTS:
662 *
663 *--
664 */
665
666 Cardinal
Idb__FIL_Valid(IDBFile file_id)667 Idb__FIL_Valid (IDBFile file_id)
668 {
669
670 if ( file_id == NULL ) return MrmFAILURE ;
671 if ( file_id->validation != IDBOpenFileValid ) return MrmFAILURE ;
672 return MrmSUCCESS ;
673
674 }
675
676