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

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