Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / lib / api / c / api_pattern.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-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 //%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                  
24 //%%  (c) Copyright 1993, 1994 International Business Machines Corp.    
25 //%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                   
26 //%%  (c) Copyright 1993, 1994 Novell, Inc.                             
27 //%%  $TOG: api_pattern.C /main/5 1999/09/17 18:26:08 mgreess $                                                         
28 /*
29  *
30  * @(#)api_pattern.C    1.29 07 Sep 1993
31  *
32  * Tool Talk API - api_pattern.cc
33  *
34  * Copyright (c) 1990,1992 by Sun Microsystems, Inc.
35  */
36
37 #include "util/tt_path.h"
38 #include "mp/mp_c.h"
39 #include "mp/mp_pat_context.h"
40 #include "mp/mp_c_msg_context.h"
41 #include "api/c/tt_c.h"
42 #include "api/c/api_api.h"
43 #include "api/c/api_mp.h"
44 #include "api/c/api_handle.h"
45 #include "util/tt_audit.h"
46 #include <unistd.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49
50 char *          _tt_pattern_print(Tt_pattern);
51 Tt_status       _tt_pattern_xarg_add(Tt_pattern, Tt_mode, const char *, 
52                                      xdrproc_t , void *);
53 Tt_status       _tt_pattern_context_add(Tt_pattern, const char *, const char *);
54 Tt_status       _tt_pattern_icontext_add(Tt_pattern, const char *, int );
55 Tt_status       _tt_pattern_xcontext_add(Tt_pattern p, const char *slotname,
56                         xdrproc_t xdr_proc, void *value);
57 Tt_status       _tt_pattern_opnum_add(Tt_pattern, int);
58 Tt_status       _tt_pattern_bcontext_add(Tt_pattern, const char *,
59                                          const unsigned char *, int);
60 Tt_status       _tt_session_types_load(const char *);
61 Tt_status       _tt_context_join(const char *, const char *);
62 Tt_status       _tt_icontext_join(const char *, int);
63 Tt_status       _tt_bcontext_join(const char *, const unsigned char *, int);
64 Tt_status       _tt_context_quit(const char *, const char *);
65 Tt_status       _tt_icontext_quit(const char *, int);
66 Tt_status       _tt_bcontext_quit(const char *, const unsigned char *, int);
67 Tt_status       _tt_xcontext_join(const char *, xdrproc_t, void *);
68 Tt_status       _tt_xcontext_quit(const char *, xdrproc_t, void *);
69
70
71 char *
72 tt_pattern_print(Tt_pattern p)
73 {
74         _Tt_audit audit;
75         Tt_status status = audit.entry("P", TT_PATTERN_PRINT, p);
76         char *result;
77
78         if (status != TT_OK) {
79                 audit.exit((char *)error_pointer(status));
80                 return (char *)error_pointer(status);
81         }
82
83         result = _tt_pattern_print(p);
84         audit.exit(result);
85
86         return result;
87 }
88
89
90 /* 
91  * extern "C" { int _tt_x_pattern_match(Tt_pattern p, Tt_message m); }
92  */
93
94 Tt_pattern
95 tt_pattern_create(void)
96 {
97         _Tt_audit audit;
98         Tt_status status = audit.entry("v", TT_PATTERN_CREATE, 0);
99         Tt_pattern result;
100
101         if (status != TT_OK) {
102                 audit.exit((Tt_pattern)error_pointer(status));
103                 return (Tt_pattern)error_pointer(status);
104         }
105
106         result =  _tt_pattern_create();
107
108         audit.exit(result);       
109
110         return result;
111 }
112
113 Tt_status
114 tt_pattern_destroy(Tt_pattern p)
115 {
116         _Tt_audit audit;
117         Tt_status status = audit.entry("P", TT_PATTERN_DESTROY, p);
118
119         if (status != TT_OK) {
120                 audit.exit(status);       
121                 return status;
122         }
123
124         status = _tt_pattern_destroy(p);
125         audit.exit(status);       
126
127         return status;
128 }
129
130
131 Tt_status
132 tt_pattern_register(Tt_pattern p)
133 {
134         _Tt_audit audit;
135         Tt_status status = audit.entry("P", TT_PATTERN_REGISTER, p);
136
137         if (status != TT_OK) {
138                 audit.exit(status);       
139                 return status;
140         }
141
142         status = _tt_pattern_register(p);
143         audit.exit(status);       
144
145         return status;
146 }
147
148
149 Tt_status
150 tt_pattern_unregister(Tt_pattern p)
151 {
152         _Tt_audit audit;
153         Tt_status status = audit.entry("P", TT_PATTERN_UNREGISTER, p);
154
155         if (status != TT_OK) {
156                 audit.exit(status);       
157                 return status;
158         }
159
160         status = _tt_pattern_unregister(p);
161         audit.exit(status);       
162
163         return status;
164 }
165
166
167 Tt_status
168 tt_pattern_callback_add(Tt_pattern p, Tt_message_callback f)
169 {
170         _Tt_audit audit;
171         Tt_status status = audit.entry("PX", TT_PATTERN_CALLBACK_ADD, p, f);
172
173         if (status != TT_OK) {
174                 audit.exit(status);       
175                 return status;
176         }
177
178         status = _tt_pattern_callback_add(p, f);
179         audit.exit(status);       
180
181         return status;
182 }
183
184
185 void *
186 tt_pattern_user(Tt_pattern p, int key)
187 {
188         _Tt_audit audit;
189         Tt_status status = audit.entry("Pi", TT_PATTERN_USER, p, key);
190         void *result;
191
192         if (status != TT_OK) {
193                 audit.exit((void *)error_pointer(status));
194                 return (void *)error_pointer(status);
195         }
196
197         result = _tt_pattern_user(p, key);
198         audit.exit(result);
199
200         return result;
201 }
202
203
204 Tt_status
205 tt_pattern_user_set(Tt_pattern p, int key, void *v)
206 {
207         _Tt_audit audit;
208         Tt_status status = audit.entry("PiA", TT_PATTERN_USER_SET, p, key, v);
209
210         if (status != TT_OK) {
211                 audit.exit(status);       
212                 return status;
213         }
214
215         status = _tt_pattern_user_set(p,key, v);
216         audit.exit(status);
217
218         return status;
219
220 }
221
222
223 Tt_category
224 tt_pattern_category(Tt_pattern p)
225 {
226         _Tt_audit audit;
227         Tt_status status = audit.entry("P", TT_PATTERN_CATEGORY, p);
228         Tt_category result;
229
230         if (status != TT_OK) {
231                 audit.exit((Tt_category)error_int(status));
232                 return (Tt_category)error_int(status);
233         }
234
235         result = _tt_pattern_category(p);
236         audit.exit(result);
237
238         return result;
239 }
240
241
242 Tt_status
243 tt_pattern_category_set(Tt_pattern p, Tt_category c)
244 {
245         _Tt_audit audit;
246         Tt_status status = audit.entry("Pa", TT_PATTERN_CATEGORY_SET, p, c);
247
248         if (status != TT_OK) {
249                 audit.exit(status);       
250                 return status;
251         }
252
253         status = _tt_pattern_category_set(p, c);
254         audit.exit(status);
255
256         return status;
257 }
258
259
260 Tt_status
261 tt_pattern_arg_add(Tt_pattern p, Tt_mode n,
262                     const char *vtype, const char *value)
263 {
264         _Tt_audit audit;
265         Tt_status status = audit.entry("POTA", TT_PATTERN_ARG_ADD, p, n,
266                                         vtype, value);
267
268         if (status != TT_OK) {
269                 audit.exit(status);       
270                 return status;
271         }
272
273         status = _tt_pattern_arg_add(p, n, vtype, value);
274         audit.exit(status);
275
276         return status;
277 }
278
279
280 Tt_status
281 tt_pattern_barg_add(Tt_pattern p, Tt_mode n, const char *vtype, 
282                      const unsigned char *value, int len)
283 {
284         _Tt_audit audit;
285         Tt_status status = audit.entry("POTnI", TT_PATTERN_BARG_ADD, p, n,
286                                         vtype, value, len);
287
288         if (status != TT_OK) {
289                 audit.exit(status);       
290                 return status;
291         }
292
293         status = _tt_pattern_barg_add(p, n, vtype, value, len);
294         audit.exit(status);
295
296         return status;
297 }
298
299
300 Tt_status
301 tt_pattern_iarg_add(Tt_pattern p, Tt_mode n, const char *vtype, int value)
302 {
303         _Tt_audit audit;
304         Tt_status status = audit.entry("POTi", TT_PATTERN_IARG_ADD, p, n,
305                                         vtype, value);
306
307         if (status != TT_OK) {
308                 audit.exit(status);       
309                 return status;
310         }
311
312         status =  _tt_pattern_iarg_add(p, n, vtype, value);
313         audit.exit(status);
314
315         return status;
316
317 }
318
319
320 Tt_status
321 tt_pattern_xarg_add(Tt_pattern p, Tt_mode n, const char *vtype, 
322                      xdrproc_t xdr_proc, void *value)
323 {
324         _Tt_audit audit;
325         Tt_status status = audit.entry("POTXA", TT_PATTERN_XARG_ADD, p,
326                                         n, vtype, xdr_proc, value);
327
328         if (status != TT_OK) {
329                 audit.exit(status);       
330                 return status;
331         }
332
333         status = _tt_pattern_xarg_add(p, n, vtype, xdr_proc, value);
334         audit.exit(status);
335
336         return status;
337 }
338
339
340 Tt_status
341 tt_pattern_context_add(Tt_pattern p, const char *slotname, const char *value)
342 {
343         _Tt_audit audit;
344         Tt_status status = audit.entry("PSC", TT_PATTERN_CONTEXT_ADD, p,
345                                             slotname, value);
346
347         if (status != TT_OK) {
348                 audit.exit(status);       
349                 return status;
350         }
351
352         status = _tt_pattern_context_add(p, slotname, value);
353         audit.exit(status);
354
355         return status;
356 }
357
358
359 Tt_status
360 tt_pattern_icontext_add(Tt_pattern p, const char *slotname, int value)
361 {
362         _Tt_audit audit;
363         Tt_status status = audit.entry("PSi", TT_PATTERN_ICONTEXT_ADD, p,
364                                             slotname, value);
365
366         if (status != TT_OK) {
367                 audit.exit(status);       
368                 return status;
369         }
370
371         status = _tt_pattern_icontext_add(p, slotname, value);
372         audit.exit(status);
373
374         return status;
375 }
376
377
378 Tt_status
379 tt_pattern_xcontext_add(Tt_pattern p, const char *slotname,
380                         xdrproc_t xdr_proc, void *value)
381 {
382         _Tt_audit audit;
383         Tt_status status = audit.entry("PSXA", TT_PATTERN_XCONTEXT_ADD, p,
384                                             slotname, xdr_proc, value);
385
386         if (status != TT_OK) {
387                 audit.exit(status);       
388                 return status;
389         }
390
391         status = _tt_pattern_xcontext_add(p, slotname, xdr_proc, value);
392         audit.exit(status);
393
394         return status;
395 }
396
397
398 Tt_status
399 tt_pattern_bcontext_add(Tt_pattern p, const char *slotname,
400                         const unsigned char *value, int len)
401 {
402         _Tt_audit audit;
403         Tt_status status = audit.entry("PlnI", TT_PATTERN_BCONTEXT_ADD, p,
404                                             slotname, (void *) value, len);
405
406         if (status != TT_OK) {
407                 audit.exit(status);       
408                 return status;
409         }
410
411         status = _tt_pattern_bcontext_add(p, slotname, value, len);
412         audit.exit(status);
413
414         return status;
415 }
416
417
418 Tt_status
419 tt_pattern_class_add(Tt_pattern p, Tt_class c)
420 {
421         _Tt_audit audit;
422         Tt_status status = audit.entry("PL", TT_PATTERN_CLASS_ADD, p, c);
423
424         if (status != TT_OK) {
425                 audit.exit(status);       
426                 return status;
427         }
428
429         status = _tt_pattern_class_add(p, c);
430         audit.exit(status);
431
432         return status;
433 }
434
435
436 Tt_status
437 tt_pattern_file_add(Tt_pattern p, const char *filepath)
438 {
439         _Tt_audit audit;
440         Tt_status status = audit.entry("PC", TT_PATTERN_FILE_ADD, p, filepath);
441
442         if (status != TT_OK) {
443                 audit.exit(status);       
444                 return status;
445         }
446
447         status = _tt_pattern_file_add(p, filepath);
448         audit.exit(status);
449
450         return status;
451 }
452
453
454 Tt_status
455 tt_pattern_object_add(Tt_pattern  p, const char * objid)
456 {
457         _Tt_audit audit;
458         Tt_status status = audit.entry("Po", TT_PATTERN_OBJECT_ADD, p,
459                                          objid);
460
461         if (status != TT_OK) {
462                 audit.exit(status);       
463                 return status;
464         }
465
466         status = _tt_pattern_object_add(p, objid);
467         audit.exit(status);
468
469         return status;
470 }
471
472
473 Tt_status
474 tt_pattern_op_add(Tt_pattern p, const char *opname)
475 {
476         _Tt_audit audit;
477         Tt_status status = audit.entry("PC", TT_PATTERN_OP_ADD, p,
478                                          opname);
479
480         if (status != TT_OK) {
481                 audit.exit(status);       
482                 return status;
483         }
484
485         status = _tt_pattern_op_add(p, opname);
486         audit.exit(status);
487
488         return status;
489 }
490
491
492 Tt_status
493 tt_pattern_opnum_add(Tt_pattern p, int opnum)
494 {
495         _Tt_audit audit;
496         Tt_status status = audit.entry("Pi", TT_PATTERN_OPNUM_ADD, p, opnum);
497
498         if (status != TT_OK) {
499                 audit.exit(status);       
500                 return status;
501         }
502
503         status = _tt_pattern_opnum_add(p, opnum);
504         audit.exit(status);
505
506         return status;
507 }
508
509
510 Tt_status
511 tt_pattern_otype_add(Tt_pattern  p, const char * otype)
512 {
513         _Tt_audit audit;
514         Tt_status status = audit.entry("PC", TT_PATTERN_OTYPE_ADD, p, otype);
515
516         if (status != TT_OK) {
517                 audit.exit(status);       
518                 return status;
519         }
520
521         status = _tt_pattern_otype_add(p, otype);
522         audit.exit(status);
523
524         return status;
525 }
526
527
528 Tt_status
529 tt_pattern_address_add(Tt_pattern p, Tt_address d)
530 {
531         _Tt_audit audit;
532         Tt_status status = audit.entry("PD", TT_PATTERN_ADDRESS_ADD, p, d);
533
534         if (status != TT_OK) {
535                 audit.exit(status);       
536                 return status;
537         }
538
539         status = _tt_pattern_address_add(p, d);
540         audit.exit(status);
541
542         return status;
543 }
544
545
546 Tt_status
547 tt_pattern_disposition_add(Tt_pattern p, Tt_disposition r)
548 {
549         _Tt_audit audit;
550         Tt_status status = audit.entry("Pd", TT_PATTERN_DISPOSITION_ADD, p, r);
551
552         if (status != TT_OK) {
553                 audit.exit(status);       
554                 return status;
555         }
556
557         status = _tt_pattern_disposition_add(p, r);
558         audit.exit(status);
559
560         return status;
561 }
562
563
564 Tt_status
565 tt_pattern_scope_add(Tt_pattern p, Tt_scope s)
566 {
567         _Tt_audit audit;
568         Tt_status status = audit.entry("PS", TT_PATTERN_SCOPE_ADD, p, s);
569
570         if (status != TT_OK) {
571                 audit.exit(status);       
572                 return status;
573         }
574
575         status = _tt_pattern_scope_add(p, s);
576         audit.exit(status);
577
578         return status;
579 }
580
581
582 Tt_status
583 tt_pattern_sender_add(Tt_pattern p, const char *procid)
584 {
585         _Tt_audit audit;
586         Tt_status status = audit.entry("PC", TT_PATTERN_SENDER_ADD, p, procid);
587
588         if (status != TT_OK) {
589                 audit.exit(status);       
590                 return status;
591         }
592
593         status = _tt_pattern_sender_add(p, procid);
594         audit.exit(status);
595
596         return status;
597 }
598
599
600 Tt_status
601 tt_pattern_sender_ptype_add(Tt_pattern p, const char *ptid)
602 {
603         _Tt_audit audit;
604         Tt_status status = audit.entry("PC", TT_PATTERN_SENDER_PTYPE_ADD, p,
605                                         ptid);
606
607         if (status != TT_OK) {
608                 audit.exit(status);       
609                 return status;
610         }
611
612         status = _tt_pattern_sender_ptype_add(p, ptid);
613         audit.exit(status);
614
615         return status;
616 }
617
618
619 Tt_status
620 tt_pattern_session_add(Tt_pattern p, const char *sessid)
621 {
622         _Tt_audit audit;
623         Tt_status status = audit.entry("PC", TT_PATTERN_SESSION_ADD, p,
624                                         sessid);
625
626         if (status != TT_OK) {
627                 audit.exit(status);       
628                 return status;
629         }
630
631         status = _tt_pattern_session_add(p, sessid);
632         audit.exit(status);
633
634         return status;
635 }
636
637
638 Tt_status
639 tt_pattern_state_add(Tt_pattern p, Tt_state s)
640 {
641         _Tt_audit audit;
642         Tt_status status = audit.entry("Pe", TT_PATTERN_STATE_ADD, p, s);
643
644         if (status != TT_OK) {
645                 audit.exit(status);       
646                 return status;
647         }
648
649         status = _tt_pattern_state_add(p, s);
650         audit.exit(status);
651
652         return status;
653 }
654
655
656 Tt_status
657 tt_ptype_declare(const char * ptid)
658 {
659         _Tt_audit audit;
660         Tt_status status = audit.entry("C", TT_PTYPE_DECLARE, ptid);
661
662         if (status != TT_OK) {
663                 audit.exit(status);       
664                 return status;
665         }
666
667         status = _tt_ptype_declare(ptid);
668         audit.exit(status);
669
670         return status;
671 }
672
673
674 Tt_status
675 tt_ptype_undeclare(const char * ptid)
676 {
677         _Tt_audit audit;
678         Tt_status status = audit.entry("C", TT_PTYPE_UNDECLARE, ptid);
679
680         if (status != TT_OK) {
681                 audit.exit(status);       
682                 return status;
683         }
684
685         status = _tt_ptype_undeclare(ptid);
686         audit.exit(status);
687
688         return status;
689 }
690
691
692 Tt_status
693 tt_ptype_exists(const char * ptid)
694 {
695         _Tt_audit audit;
696         Tt_status status = audit.entry("C", TT_PTYPE_EXISTS, ptid);
697
698         if (status != TT_OK) {
699                 audit.exit(status);       
700                 return status;
701         }
702
703         status = _tt_ptype_exists(ptid);
704         audit.exit(status);
705
706         return status;
707 }
708
709
710 Tt_status
711 tt_session_types_load(const char * sessid, const char *filename)
712 {
713         _Tt_audit audit;
714         Tt_status status = audit.entry("EC", TT_SESSION_TYPES_LOAD, sessid,
715                                         filename);
716
717         if (status != TT_OK) {
718                 audit.exit(status);       
719                 return status;
720         }
721
722         // XXX: Should check that the supplied sessid is the session that the
723         // default procid is talking to, but we don't have a tt_session_equal.
724
725         // Really, things like
726         // tt_ptype_exists that don\'t really require a procid should
727         // all take a sessid and do this, to pave the way for a possible
728         // implementation that allows multiple sessions per procid.
729
730         status = _tt_session_types_load(filename);
731         audit.exit(status);
732
733         return status;
734 }
735
736
737 Tt_status
738 tt_context_join(const char *slotname, const char *value)
739 {
740         _Tt_audit audit;
741         Tt_status status = audit.entry("lC", TT_CONTEXT_JOIN, slotname,
742                                         value);
743
744         if (status != TT_OK) {
745                 audit.exit(status);       
746                 return status;
747         }
748
749         status = _tt_context_join(slotname, value);
750         audit.exit(status);
751
752         return status;
753 }
754
755
756 Tt_status
757 tt_icontext_join(const char *slotname, int value)
758 {
759         _Tt_audit audit;
760         Tt_status status = audit.entry("li", TT_ICONTEXT_JOIN, slotname, value);
761
762         if (status != TT_OK) {
763                 audit.exit(status);       
764                 return status;
765         }
766
767         status = _tt_icontext_join(slotname, value);
768         audit.exit(status);
769
770         return status;
771 }
772
773
774 Tt_status
775 tt_bcontext_join(const char *slotname, const unsigned char *value, int len)
776 {
777         _Tt_audit audit;
778         Tt_status status = audit.entry("lnI", TT_BCONTEXT_JOIN, slotname,
779                                         value, len);
780
781         if (status != TT_OK) {
782                 audit.exit(status);       
783                 return status;
784         }
785
786         status = _tt_bcontext_join(slotname, value, len);
787         audit.exit(status);
788
789         return status;
790 }
791
792
793 Tt_status
794 tt_context_quit(const char *slotname, const char *value)
795 {
796         _Tt_audit audit;
797         Tt_status status = audit.entry("lC", TT_CONTEXT_QUIT, slotname,
798                                         value);
799
800         if (status != TT_OK) {
801                 audit.exit(status);       
802                 return status;
803         }
804
805         status = _tt_context_quit(slotname, value);
806         audit.exit(status);
807
808         return status;
809 }
810
811
812 Tt_status
813 tt_icontext_quit(const char *slotname, int value)
814 {
815         _Tt_audit audit;
816         Tt_status status = audit.entry("li", TT_ICONTEXT_QUIT, slotname, value);
817
818         if (status != TT_OK) {
819                 audit.exit(status);       
820                 return status;
821         }
822
823         status = _tt_icontext_quit(slotname, value);
824         audit.exit(status);
825
826         return status;
827 }
828
829
830 Tt_status
831 tt_bcontext_quit(const char *slotname, const unsigned char *value, int len)
832 {
833         _Tt_audit audit;
834         Tt_status status = audit.entry("lnI", TT_BCONTEXT_QUIT, slotname,
835                                         value, len);
836
837         if (status != TT_OK) {
838                 audit.exit(status);       
839                 return status;
840         }
841
842         status = _tt_bcontext_quit(slotname, value, len);
843         audit.exit(status);
844
845         return status;
846 }
847
848
849 Tt_status
850 tt_xcontext_join(const char *slotname, xdrproc_t xdr_proc, void *value)
851 {
852         _Tt_audit audit;
853         Tt_status status = audit.entry("lXA", TT_XCONTEXT_JOIN, slotname,
854                                         xdr_proc, value);
855
856         if (status != TT_OK) {
857                 audit.exit(status);       
858                 return status;
859         }
860
861         status = _tt_xcontext_join(slotname, xdr_proc, value);
862         audit.exit(status);
863
864         return status;
865 }
866
867
868 Tt_status
869 tt_xcontext_quit(const char *slotname, xdrproc_t xdr_proc, void *value)
870 {
871         _Tt_audit audit;
872         Tt_status status = audit.entry("lXA", TT_XCONTEXT_QUIT, slotname,
873                                         xdr_proc, value);
874
875         if (status != TT_OK) {
876                 audit.exit(status);       
877                 return status;
878         }
879
880         status = _tt_xcontext_quit(slotname, xdr_proc, value);
881         audit.exit(status);
882
883         return status;
884 }
885
886
887 /***************************************************************************
888   Patterns (FSpec A.9)
889 ***************************************************************************/
890
891
892 // Print the pattern the user has passed in into a buffer & return
893 // that buffer to him.
894 char *
895 _tt_pattern_print(Tt_pattern p)
896 {
897         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
898         _Tt_string      buf;
899
900         pat->print(buf);
901
902         return _tt_strdup(buf);
903 }
904
905
906 /* 
907  * Creation, alteration, and destruction (FSpec A.9.1)
908  */
909
910 /* 
911  * Create a new pattern object and returns a handle for it; use this
912  * handle in future calls to manipulate the pattern object.
913  */
914 Tt_pattern
915 _tt_pattern_create(void)
916 {
917         Tt_pattern result;
918         _Tt_pattern_ptr pat;
919
920         pat = new _Tt_pattern();
921         result = _tt_htab->lookup_phandle(pat);
922         return result;
923 }
924
925 /* 
926  * Destroys a pattern object. Destroying a pattern object implicitly
927  * unregisters the pattern.
928  */
929 Tt_status
930 _tt_pattern_destroy(Tt_pattern p)
931 {
932         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
933         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
934         Tt_status       status;
935
936         PCOMMIT;
937
938         status = _tt_c_mp->default_c_procid()->del_pattern(pat->id());
939         _tt_htab->clear(p);
940
941         //
942         // Ignore errors about pattern not found. This prevents
943         // tt_pattern_unregister(pat) followed by tt_pattern_destroy(pat)
944         // from returning a warning. (bug #1158125)
945         //
946         if (status == TT_WRN_NOTFOUND) {
947           status = TT_OK;
948         }
949         return status;
950 }
951
952
953 /* 
954  * Registers the pattern constructed in the pattern object with the
955  * message server, so that the process will start receiving messages that
956  * match the pattern. Once a pattern is registered, no further changes
957  * can be made in the pattern (except for the implicit changes performed
958  * by joining files and sessions)
959  */
960 Tt_status
961 _tt_pattern_register(Tt_pattern p)
962 {
963         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
964         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
965         Tt_status       st;
966
967         if (pat->is_registered()) {
968                 return TT_ERR_INVALID;
969         }
970         PCOMMIT;
971         st = _tt_c_mp->default_c_procid()->add_pattern(pat);
972         if (st == TT_OK) {
973                 pat->set_registered();
974         }
975         return st;
976 }
977
978
979 /* 
980  * Unregisters the pattern so that the process stops receiving messages
981  * that match it.
982  */
983 Tt_status
984 _tt_pattern_unregister(Tt_pattern p)
985 {
986         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
987         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
988         Tt_status       st;
989
990         if (! pat->is_registered()) {
991                 return TT_OK;
992         }
993         PCOMMIT;
994         st = _tt_c_mp->default_c_procid()->del_pattern(pat->id());
995         if (st == TT_OK) {
996                 pat->clr_registered();
997         }
998         return st;
999 }
1000
1001
1002 /* 
1003  * Sets a callback on messages retrieved through pattern p
1004  */
1005 Tt_status
1006 _tt_pattern_callback_add(Tt_pattern p, Tt_message_callback f)
1007 {
1008         if (! _tt_mp) {
1009                 return(TT_ERR_NOMP);
1010         }
1011
1012         if (_tt_pointer_error(p)!=TT_OK) return TT_ERR_POINTER;
1013         return _tt_htab->add_callback(p,f);
1014 }
1015
1016
1017 void *
1018 _tt_pattern_user(Tt_pattern p, int key)
1019 {
1020         return _tt_htab->fetch(p,key);
1021 }
1022
1023
1024 Tt_status
1025 _tt_pattern_user_set(Tt_pattern p,int key, void *v)
1026 {
1027         return _tt_htab->store(p,key,v);
1028 }
1029
1030
1031 /* 
1032  * Category (FSpec A.9.3)
1033  */
1034
1035 /* 
1036  * Returns the category of the pattern object associated with p.
1037  */
1038 Tt_category
1039 _tt_pattern_category(Tt_pattern p)
1040 {
1041         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1042
1043         // _Tt_pattern::category seems not to exist.
1044         return pat->category();
1045 }
1046
1047
1048 /* 
1049  * Sets the category of the pattern object associated with p.
1050  */
1051 Tt_status
1052 _tt_pattern_category_set(Tt_pattern p, Tt_category c)
1053 {
1054         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1055
1056         return(pat->set_category(c));
1057 }
1058
1059
1060 /* 
1061  * Pattern Attributes (FSpec A.9.4)
1062  */
1063
1064
1065 /* 
1066  * Adds a new argument to a message object. vtype is the name of a valid
1067  * value type. Use NULL for values of mode out.
1068  */
1069 Tt_status
1070 _tt_pattern_arg_add(Tt_pattern p, Tt_mode n,
1071                     const char *vtype, const char *value)
1072 {
1073         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1074         _Tt_arg_ptr     arg;
1075
1076         arg = new _Tt_arg(n, vtype);
1077         // NULL arg value means leave value unset (which matches everything)
1078         if (value != (char *)0) {
1079                 arg->set_data_string(value);
1080         }
1081
1082         return pat->add_arg(arg);
1083 }
1084
1085
1086 /* 
1087  * Adds a new opaque argument to a pattern.
1088  */
1089 Tt_status
1090 _tt_pattern_barg_add(Tt_pattern p, Tt_mode n, const char *vtype, 
1091                      const unsigned char *value, int len)
1092 {
1093         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1094         _Tt_arg_ptr     arg;
1095
1096
1097         arg = new _Tt_arg(n, vtype);
1098
1099         // NULL arg value means leave value unset (which matches everything)
1100         if (value != (unsigned char *) 0)  {
1101                 arg->set_data_string( _Tt_string(value, len) );
1102         }
1103
1104         return pat->add_arg(arg);
1105 }
1106
1107
1108 /* 
1109  * Adds a new integer argument to a pattern object. vtype is the name of
1110  * a valid value type. 
1111  */
1112 Tt_status
1113 _tt_pattern_iarg_add(Tt_pattern p, Tt_mode n, const char *vtype, 
1114                      int value)
1115 {
1116         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1117         _Tt_arg_ptr     arg;
1118
1119         arg = new _Tt_arg(n, vtype);
1120         arg->set_data_int(value);
1121         return pat->add_arg(arg);
1122 }
1123
1124
1125 /* 
1126  * Adds a new argument w/ an XDR'ed value to a pattern object.
1127  */
1128 Tt_status
1129 _tt_pattern_xarg_add(Tt_pattern p, Tt_mode n, const char *vtype, 
1130                      xdrproc_t xdr_proc, void *value)
1131 {
1132         _Tt_pattern_ptr pat_p = _tt_htab->lookup_pat(p);
1133         _Tt_arg_ptr     arg;
1134
1135
1136         // Encode the XDR arg or return failure.
1137         _Tt_string xdr_arg;
1138
1139         if (_tt_xdr_encode(xdr_proc, value, xdr_arg) == 0) {
1140                 return TT_ERR_XDR;
1141         }
1142
1143         // Set the argument.
1144         arg = new _Tt_arg(n, vtype);
1145
1146         _Tt_string s(xdr_arg);
1147         if (!s.is_null()) {
1148                 arg->set_data_string(s);
1149         }
1150         return pat_p->add_arg(arg);
1151 }
1152
1153
1154 /* 
1155  * Adds a string value to a context slot.
1156  */
1157 Tt_status
1158 _tt_pattern_context_add(Tt_pattern p, const char *slotname, const char *value)
1159 {
1160         _Tt_pattern_ptr         pat = _tt_htab->lookup_pat(p);
1161         _Tt_pat_context_ptr     cntxt;
1162         Tt_status               status;
1163
1164         int add = 0;
1165         cntxt = pat->context(slotname);
1166         if (cntxt.is_null()) {
1167                 cntxt = new _Tt_pat_context;
1168                 if (cntxt.is_null()) {
1169                         return TT_ERR_NOMEM;
1170                 }
1171                 status = cntxt->setName(slotname);
1172                 if (status != TT_OK) {
1173                         return status;
1174                 }
1175                 add = 1;
1176         }
1177         // NULL value means leave value unset (which matches everything)
1178         if (value != (char *)0) {
1179                 _Tt_string valString(value);
1180                 status = cntxt->addValue(valString);
1181                 if (status != TT_OK) {
1182                         return status;
1183                 }
1184         }
1185         if (add) {
1186                 return pat->add_context( cntxt );
1187         }
1188         return status;
1189 }
1190
1191
1192 /* 
1193  * Adds an integer value to a context slot.
1194  */
1195 Tt_status
1196 _tt_pattern_icontext_add(Tt_pattern p, const char *slotname, int value)
1197 {
1198         _Tt_pattern_ptr         pat = _tt_htab->lookup_pat(p);
1199         _Tt_pat_context_ptr     cntxt;
1200         Tt_status               status;
1201
1202         int add = 0;
1203         cntxt = pat->context(slotname);
1204         if (cntxt.is_null()) {
1205                 cntxt = new _Tt_pat_context;
1206                 if (cntxt.is_null()) {
1207                         return TT_ERR_NOMEM;
1208                 }
1209                 status = cntxt->setName(slotname);
1210                 if (status != TT_OK) {
1211                         return status;
1212                 }
1213                 add = 1;
1214         }
1215         status = cntxt->addValue(value);
1216         if (status != TT_OK) {
1217                 return status;
1218         }
1219         if (add) {
1220                 return pat->add_context(cntxt);
1221         }
1222         return status;
1223 }
1224
1225
1226 /* 
1227  * XDR equivalent of tt_pattern_bcontext_add.
1228  */
1229 Tt_status
1230 _tt_pattern_xcontext_add(Tt_pattern p, const char *slotname,
1231                         xdrproc_t xdr_proc, void *value)
1232 {
1233         int                     add = 0;
1234         _Tt_pattern_ptr         pat_p = _tt_htab->lookup_pat(p);
1235         _Tt_pat_context_ptr     cntxt_p;
1236         Tt_status               status;
1237  
1238
1239         cntxt_p = pat_p->context(slotname);
1240         if (cntxt_p.is_null()) {
1241                 cntxt_p = new _Tt_pat_context;
1242                 if (cntxt_p.is_null()) {
1243                         return TT_ERR_NOMEM;
1244                 }
1245                 status = cntxt_p->setName(slotname);
1246                 if (status != TT_OK) {
1247                         return status;
1248                 }
1249                 add = 1;
1250         }
1251
1252         // Encode the XDR context or return failure.
1253         _Tt_string      xdr_context;
1254  
1255         if (_tt_xdr_encode(xdr_proc, value, xdr_context) == 0) {
1256                 return TT_ERR_XDR;
1257         }
1258  
1259         // add the XDR'ed context
1260         status = cntxt_p->addValue(xdr_context);
1261         if (status != TT_OK) {
1262                 return status;
1263         }
1264         if (add) {
1265                 return pat_p->add_context(cntxt_p);
1266         }
1267         return status;
1268 }
1269
1270
1271 /* 
1272  * Adds a byte-string value to a context slot.
1273  */
1274 Tt_status
1275 _tt_pattern_bcontext_add(Tt_pattern p, const char *slotname,
1276                         const unsigned char *value, int len)
1277 {
1278         _Tt_pattern_ptr         pat = _tt_htab->lookup_pat(p);
1279         _Tt_pat_context_ptr     cntxt;
1280         Tt_status               status;
1281
1282
1283         int add = 0;
1284         cntxt = pat->context( slotname );
1285         if (cntxt.is_null()) {
1286                 cntxt = new _Tt_pat_context;
1287                 if (cntxt.is_null()) {
1288                         return TT_ERR_NOMEM;
1289                 }
1290                 status = cntxt->setName( slotname );
1291                 if (status != TT_OK) {
1292                         return status;
1293                 }
1294                 add = 1;
1295         }
1296         // NULL value means leave value unset (which matches everything)
1297         if (value != (unsigned char *)0) {
1298                 _Tt_string valString( value, len );
1299
1300                 status = cntxt->addValue( valString );
1301                 if (status != TT_OK) {
1302                         return status;
1303                 }
1304         }
1305         if (add) {
1306                 return pat->add_context( cntxt );
1307         }
1308         return status;
1309 }
1310
1311
1312 Tt_status
1313 _tt_pattern_class_add(Tt_pattern p, Tt_class c)
1314 {
1315         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1316
1317         return(pat->add_message_class(c));
1318 }
1319
1320
1321 Tt_status
1322 _tt_pattern_file_add(Tt_pattern p, const char *filepath)
1323 {
1324         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1325
1326         return(pat->add_netfile(filepath));
1327 }
1328
1329
1330 Tt_status
1331 _tt_pattern_object_add(Tt_pattern  p, const char * objid)
1332 {
1333         _Tt_string      oid = objid;
1334         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1335
1336         return(pat->add_object(oid.unquote_nulls()));
1337 }
1338
1339
1340 Tt_status
1341 _tt_pattern_op_add(Tt_pattern p, const char *opname)
1342 {
1343         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1344
1345         return(pat->add_op(opname));
1346 }
1347
1348
1349 Tt_status
1350 _tt_pattern_opnum_add(Tt_pattern p, int opnum)
1351 {
1352
1353         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1354
1355         return(pat->add_opnum(opnum));
1356 }
1357
1358
1359 Tt_status
1360 _tt_pattern_otype_add(Tt_pattern  p, const char * otype)
1361 {
1362         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1363         Tt_status rc;
1364
1365         if (TT_WRN_LAST < (rc = _tt_valid_otype(otype))) {
1366                 return rc;
1367         }
1368         return(pat->add_otype(otype));
1369 }
1370
1371
1372 Tt_status
1373 _tt_pattern_address_add(Tt_pattern p, Tt_address d)
1374 {
1375         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1376
1377         return(pat->add_paradigm(d));
1378 }
1379
1380
1381 Tt_status
1382 _tt_pattern_disposition_add(Tt_pattern p,Tt_disposition r)
1383 {
1384
1385         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1386
1387         return(pat->add_reliability(r));
1388 }
1389
1390
1391 Tt_status
1392 _tt_pattern_scope_add(Tt_pattern p, Tt_scope s)
1393 {
1394         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1395
1396         return(pat->add_scope(s));
1397 }
1398
1399
1400 Tt_status
1401 _tt_pattern_sender_add(Tt_pattern p, const char *procid)
1402 {
1403         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1404
1405         return(pat->add_sender(procid));
1406 }
1407
1408
1409 Tt_status
1410 _tt_pattern_sender_ptype_add(Tt_pattern p, const char *ptid)
1411 {
1412         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1413
1414         return(pat->add_sender_ptype(ptid));
1415 }
1416
1417
1418 Tt_status
1419 _tt_pattern_session_add(Tt_pattern p, const char *sessid)
1420 {
1421
1422         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1423         _Tt_session_ptr sptr;
1424         _Tt_string      strsessid = (char *)0;
1425         Tt_status       status;
1426
1427         // Add the P on if isn't already.
1428         _prepend_P_to_sessid(sessid, strsessid);
1429
1430         status = _tt_c_mp->find_session(strsessid, sptr, 1);
1431         if (TT_OK != status) return status;
1432
1433         return(pat->add_session(sptr->id()));
1434 }
1435
1436
1437 Tt_status
1438 _tt_pattern_state_add(Tt_pattern p, Tt_state s)
1439 {
1440         _Tt_pattern_ptr pat = _tt_htab->lookup_pat(p);
1441
1442         return(pat->add_state(s));
1443 }
1444
1445
1446 /* 
1447  * --> Experimental function for PE internal dispatch. Not to be advertised
1448  * in the header files yet.
1449  */
1450 /* 
1451  * int
1452  * _tt_x_pattern_match(Tt_pattern p, Tt_message m)
1453  * {
1454  *      _Tt_message_ptr msg;
1455  *      _Tt_pattern_ptr pat;
1456  * 
1457  *      if (tt_ptr_error(m) != TT_OK || tt_ptr_error(p) != TT_OK) {
1458  *              return(0);
1459  *      }
1460  *      msg = _tt_htab->lookup_msg(m);
1461  *      pat = _tt_htab->lookup_pat(p);
1462  *      if (msg.is_null() || pat.is_null()) {
1463  *              return(0);
1464  *      }
1465  *      return(pat->match(msg));
1466  * }
1467  */
1468
1469 /* 
1470  * Ptype functions (FSpec A.10)
1471  */
1472
1473
1474 /* 
1475  * Used to declare a ptype for a process.
1476  */
1477 Tt_status
1478 _tt_ptype_declare(const char * ptid)
1479 {
1480         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1481         Tt_status       status;
1482         _Tt_string      sptid;
1483
1484         PCOMMIT;
1485         sptid = ptid;
1486         status = _tt_c_mp->default_c_procid()->declare_ptype(sptid);
1487         if (status < TT_WRN_LAST) {
1488                 _tt_c_mp->default_c_procid()->set_default_ptype(sptid);
1489         }
1490
1491         return status;
1492 }
1493
1494 /* 
1495  * Used to undeclare a ptype for a process.
1496  */
1497 Tt_status
1498 _tt_ptype_undeclare(const char * ptid)
1499 {
1500         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1501         Tt_status       status;
1502         _Tt_string      sptid;
1503
1504         PCOMMIT;
1505         sptid = ptid;
1506         status = _tt_c_mp->default_c_procid()->undeclare_ptype(sptid);
1507         return status;
1508 }
1509
1510 /* 
1511  * Used to check if a ptype is known by the default session.
1512  */
1513 Tt_status
1514 _tt_ptype_exists(const char * ptid)
1515 {
1516         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1517         Tt_status       status;
1518         _Tt_string      sptid;
1519
1520         PCOMMIT;
1521         sptid = ptid;
1522         status = _tt_c_mp->default_c_procid()->exists_ptype(sptid);
1523         return status;
1524 }
1525
1526 /* 
1527  * Used to load new types into the default session.
1528  */
1529 Tt_status
1530 _tt_session_types_load(const char *filename)
1531 {
1532         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1533         Tt_status       status;
1534             
1535         PCOMMIT;
1536
1537         int fd;
1538         struct stat typefile_stat;
1539
1540         if (-1==(fd=open(filename, O_RDONLY))) {
1541                 return TT_ERR_FILE;
1542         }
1543         fcntl(fd, F_SETFD, 1);  /* Close on exec */
1544
1545         if (-1==fstat(fd, &typefile_stat)) {
1546                 close(fd);
1547                 return TT_ERR_FILE;
1548         }
1549         _Tt_string typebuffer((int)typefile_stat.st_size);
1550         if (typefile_stat.st_size !=
1551             read(fd, (void *)(char *)typebuffer,
1552                  (unsigned int)typefile_stat.st_size)) {
1553                 close(fd);
1554                 return TT_ERR_FILE;
1555         }
1556         if (-1==close(fd)) {
1557                 return TT_ERR_FILE;
1558         }
1559         status = _tt_c_mp->default_c_procid()->load_types(typebuffer);
1560         return status;
1561 }
1562
1563
1564 /*
1565  * Contexts and static patterns
1566  */
1567
1568 /*
1569  * Add a string context to all patterns.
1570  */
1571 Tt_status
1572 _tt_context_join(const char *slotname, const char *value)
1573 {
1574         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1575         Tt_status               status;
1576
1577         PCOMMIT;
1578
1579         _Tt_c_msg_context_ptr cntxt = new _Tt_c_msg_context;
1580
1581         status = cntxt->setName( slotname );
1582         if (status != TT_OK) {
1583                 return status;
1584         }
1585         _Tt_string valString( value );
1586         status = cntxt->setValue( valString );
1587         if (status != TT_OK) {
1588                 return status;
1589         }
1590
1591         return cntxt->c_join( *_tt_c_mp->default_c_procid()->default_session(),
1592                               _tt_c_mp->default_c_procid() );
1593 }
1594
1595
1596 /*
1597  * Add an integer context to all patterns.
1598  */
1599 Tt_status
1600 _tt_icontext_join(const char *slotname, int value)
1601 {
1602         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1603         Tt_status               status;
1604
1605         PCOMMIT;
1606
1607         _Tt_c_msg_context_ptr cntxt = new _Tt_c_msg_context;
1608         status = cntxt->setName( slotname );
1609         if (status != TT_OK) {
1610                 return status;
1611         }
1612         status = cntxt->setValue( value );
1613         if (status != TT_OK) {
1614                 return status;
1615         }
1616
1617         return cntxt->c_join( *_tt_c_mp->default_c_procid()->default_session(),
1618                               _tt_c_mp->default_c_procid() );
1619 }
1620
1621
1622 /*
1623  * Add a byte-array context to all patterns.
1624  */
1625 Tt_status
1626 _tt_bcontext_join(const char *slotname, const unsigned char *value, int len)
1627 {
1628         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1629         Tt_status               status;
1630
1631         PCOMMIT;
1632
1633         _Tt_c_msg_context_ptr cntxt = new _Tt_c_msg_context;
1634         status = cntxt->setName( slotname );
1635         if (status != TT_OK) {
1636                 return status;
1637         }
1638         _Tt_string valString( value, len );
1639         status = cntxt->setValue( valString );
1640         if (status != TT_OK) {
1641                 return status;
1642         }
1643
1644         return cntxt->c_join( *_tt_c_mp->default_c_procid()->default_session(),
1645                              _tt_c_mp->default_c_procid() );
1646 }
1647
1648
1649 /*
1650  * Remove a string context from all patterns.
1651  */
1652 Tt_status
1653 _tt_context_quit(const char *slotname, const char *value)
1654 {
1655         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1656         Tt_status               status;
1657
1658         PCOMMIT;
1659
1660         _Tt_c_msg_context_ptr cntxt = new _Tt_c_msg_context;
1661         status = cntxt->setName( slotname );
1662         if (status != TT_OK) {
1663                 return status;
1664         }
1665         _Tt_string valString( value );
1666         status = cntxt->setValue( valString );
1667         if (status != TT_OK) {
1668                 return status;
1669         }
1670
1671         return cntxt->c_quit( *_tt_c_mp->default_c_procid()->default_session(),
1672                              _tt_c_mp->default_c_procid() );
1673 }
1674
1675
1676 /*
1677  * Remove an integer context from all patterns.
1678  */
1679 Tt_status
1680 _tt_icontext_quit(const char *slotname, int value)
1681 {
1682         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1683         Tt_status               status;
1684
1685         PCOMMIT;
1686
1687         _Tt_c_msg_context_ptr cntxt = new _Tt_c_msg_context;
1688         status = cntxt->setName( slotname );
1689         if (status != TT_OK) {
1690                 return status;
1691         }
1692         status = cntxt->setValue( value );
1693         if (status != TT_OK) {
1694                 return status;
1695         }
1696
1697         return cntxt->c_quit( *_tt_c_mp->default_c_procid()->default_session(),
1698                              _tt_c_mp->default_c_procid() );
1699 }
1700
1701
1702 /*
1703  * Remove a byte-array context from all patterns.
1704  */
1705 Tt_status
1706 _tt_bcontext_quit(const char *slotname, const unsigned char *value, int len)
1707 {
1708         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1709         Tt_status        status;
1710
1711         PCOMMIT;
1712
1713         _Tt_c_msg_context_ptr cntxt = new _Tt_c_msg_context;
1714         status = cntxt->setName( slotname );
1715         if (status != TT_OK) {
1716                 return status;
1717         }
1718         _Tt_string valString( value, len );
1719         status = cntxt->setValue( valString );
1720         if (status != TT_OK) {
1721                 return status;
1722         }
1723
1724         return cntxt->c_quit(*_tt_c_mp->default_c_procid()->default_session(),
1725                              _tt_c_mp->default_c_procid());
1726 }
1727
1728
1729 /*
1730  * XDR equivalent of tt_bcontext_join.
1731  */
1732 Tt_status
1733 _tt_xcontext_join(const char *slotname, xdrproc_t xdr_proc, void *value)
1734 {
1735         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1736         Tt_status       status;
1737
1738         PCOMMIT;
1739
1740         _Tt_c_msg_context_ptr cntxt_p = new _Tt_c_msg_context;
1741
1742         status = cntxt_p->setName(slotname);
1743         if (status != TT_OK) {
1744                 return status;
1745         }
1746
1747         // Encode the XDR context or return failure.
1748         _Tt_string xdr_context;
1749
1750         if (_tt_xdr_encode(xdr_proc, value, xdr_context) == 0) {
1751                 return TT_ERR_XDR;
1752         }
1753
1754         // join the new context to the existing patterns
1755         _Tt_string valString(xdr_context);
1756
1757         status = cntxt_p->setValue(valString);
1758         if (status != TT_OK) {
1759                 return status;
1760         }
1761  
1762         return cntxt_p->c_join( *_tt_c_mp->default_c_procid()->default_session(),
1763                               _tt_c_mp->default_c_procid() );
1764 }
1765
1766
1767 /*
1768  * XDR equivalent of tt_bcontext_quit.
1769  */
1770 Tt_status
1771 _tt_xcontext_quit(const char *slotname, xdrproc_t xdr_proc, void *value)
1772 {
1773         _Tt_c_procid    *d_procid = _tt_c_mp->default_c_procid().c_pointer();
1774         Tt_status       status;
1775
1776         PCOMMIT;
1777
1778         // setup target context.
1779         _Tt_c_msg_context_ptr cntxt_p;
1780
1781         cntxt_p = new _Tt_c_msg_context;
1782         status = cntxt_p->setName(slotname);
1783         if (status != TT_OK) {
1784                 return status;
1785         }
1786
1787         // Encode the XDR context or return failure.
1788         _Tt_string xdr_context;
1789  
1790         if (_tt_xdr_encode(xdr_proc, value, xdr_context) == 0) {
1791                 return TT_ERR_XDR;
1792         }
1793
1794         // try to quit the specified, now encoded, context.
1795         _Tt_string valString(xdr_context);
1796
1797         status = cntxt_p->setValue(valString);
1798         if (status != TT_OK) {
1799                 return status;
1800         }
1801
1802         return cntxt_p->c_quit(*_tt_c_mp->default_c_procid()->default_session(),
1803                                _tt_c_mp->default_c_procid());
1804 }