source: trunk/athena/bin/discuss/libds/conv_mgr.c @ 1730

Revision 1730, 5.3 KB checked in by srz, 35 years ago (diff)
Added flag routines, and version check.
Line 
1/*
2 *
3 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/discuss/libds/conv_mgr.c,v $
4 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/discuss/libds/conv_mgr.c,v 1.10 1989-01-29 17:20:06 srz Exp $
5 *
6 *      Copyright (C) 1986 by the Massachusetts Institute of Technology
7 *
8 * conv_mgr () -- File that contains procedure to handle conversations.  This
9 *                allows multiplexing of RPC stream, setting up the correct
10 *                stream for the given module.
11 *
12 */
13
14#ifndef __STDC__
15#define const
16#endif
17
18#ifndef lint
19static const char rcsid_conv_mgr_c[] =
20    "$Header: /afs/dev.mit.edu/source/repository/athena/bin/discuss/libds/conv_mgr.c,v 1.10 1989-01-29 17:20:06 srz Exp $";
21#endif lint
22
23#include <errno.h>
24#include <string.h>
25#include "rpc.h"
26#define NULL 0
27
28char *malloc (), *realloc();
29
30
31/* conversation structure */
32struct conv {
33     char *module;
34     int port;
35     char *hostname;
36     char *service_id;
37     rpc_conversation rc;
38     int server_version;
39     int result;
40};
41
42/* variables for managing conversation table */
43static struct conv *conv_base;
44static int num_convs;
45static int max_convs;
46
47static int cur_conv = -1;
48
49/*
50 *
51 * get_module () -- Procedure to return the current module.  Returns a
52 *                  character string (static storage)
53 *
54 */
55char *
56get_module ()
57{
58     if (conv_base == NULL || cur_conv == -1)
59          return (NULL);
60
61     return (conv_base [cur_conv].module);
62}
63
64/*
65 *
66 * set_module () -- Procedure to bind the set of procedure calls with a
67 *                  module.  Binds them for all remote procedure calls in
68 *                  the current process.  Thus people who want to do this
69 *                  temporarily should do a "get_module" to restore it back.
70 *
71 *
72 */
73void set_module (module,fatal_error,result)
74    char *module;
75    int *fatal_error,*result;
76{
77     char *hostname, *service_id;
78     int port,i;
79     rpc_conversation rc;
80     struct conv *convp;
81
82     *fatal_error = 0;
83     *result = 0;
84
85     /* check to see if we've set up the module table */
86     if (conv_base == NULL) {
87          conv_base = (struct conv *) malloc (5 * sizeof (struct conv));
88          max_convs = 5;
89     }
90
91     /* see if there's a real module there */
92     if (!module) {
93             cur_conv = -1;
94             return;
95     }
96
97     /* check if we're setting our current module */
98     if (cur_conv != -1) {
99          if (!strcmp (module, conv_base[cur_conv].module)) {
100               set_rpc (conv_base[cur_conv].rc);
101               return;
102          }
103     }
104
105     /* Now loop through all, looking for module names for comparison */
106     for (i = 0; i < num_convs; i++) {
107          if (!strcmp (module, conv_base[i].module)) { /* match */
108               if (conv_base[i].result != 0) { /* errored out before */
109                    *result = conv_base[i].result;
110                    *fatal_error = 1;
111                    return;
112               }
113               set_rpc (conv_base[i].rc);
114               cur_conv = i;
115               return;
116          }
117     }
118
119     /* not found -- we're going to have to resolve the module name. */
120     resolve_module (module, &port, &hostname, &service_id, result);
121     if (*result) {
122          *fatal_error = 1;
123          return;
124     }
125
126     /* Check through conversations, looking for resolved module */
127     for (i = 0; i < num_convs; i++) {
128          convp = &conv_base [i];
129          if (convp -> port == port && !namcmp (hostname, convp -> hostname)
130              && !strcmp (service_id, convp -> service_id)) {
131              /* found match, record */
132              if (conv_base[i].result != 0) {           /* errored out */
133                  *result = conv_base[i].result;
134                  *fatal_error = 1;
135                  return;
136              }
137              rc = convp -> rc;
138              set_rpc (rc);
139              goto create_entry;
140          }
141     }
142
143     /* Not found.  Create the rpc conversation */
144     rc = open_rpc (hostname, port, service_id, result);
145     if (rc == NULL) {
146          *fatal_error = 1;
147          if (*result == EINTR) {               /* control-C: don't create conversation */
148               return;
149          }
150     }
151
152create_entry:
153     if (num_convs == max_convs) {
154         max_convs += 2;
155         conv_base = (struct conv *) realloc (conv_base,
156                                              max_convs*sizeof (struct conv));
157     }
158
159     cur_conv = num_convs++;
160     convp = &conv_base [cur_conv];
161     convp -> rc = rc;
162     convp -> result = 0;
163     if (rc == NULL) {                  /* error opening, but 'remember' it */
164          convp -> result = *result;
165          cur_conv = -1;
166     }
167     convp -> hostname = malloc (strlen (hostname)+1);
168     strcpy (convp -> hostname, hostname);
169     convp -> service_id = malloc (strlen (service_id)+1);
170     strcpy (convp -> service_id, service_id);
171     convp -> module = malloc (strlen (module)+1);
172     strcpy (convp -> module, module);
173     convp -> port = port;
174
175     convp -> server_version = get_server_version();
176     return;
177}
178
179/*
180 *
181 * flush_convs () -- Routine to flush all conversations.
182 *
183 */
184void flush_convs ()
185{
186     int i,j;
187     struct conv *convp;
188
189     if (conv_base == NULL)
190          return;
191
192     for (i = 0; i < num_convs; i++) {
193          convp = &conv_base[i];
194
195          if (convp -> rc)
196               close_rpc (convp -> rc);
197          free(convp -> module);
198          free(convp -> hostname);
199          free(convp -> service_id);
200       
201          /* tromp on future conversations */
202          for (j = i+1; j < num_convs; j++) {
203               if (convp -> rc == conv_base[j].rc)
204                    conv_base[j].rc = NULL;
205          }
206          convp -> rc = 0;
207     }
208     
209     free (conv_base);
210     conv_base = NULL;
211     num_convs = 0;
212     max_convs = 0;
213     cur_conv = -1;
214}
215
216get_conv_server_version()
217{
218     if (cur_conv == -1)
219          return(SERVER_0);
220
221     return (conv_base[cur_conv].server_version);
222}
Note: See TracBrowser for help on using the repository browser.