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

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