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

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