]> andersk Git - moira.git/blame - server/mr_scall.c
Fetch the list_id of the 'proxy' capacl at startup
[moira.git] / server / mr_scall.c
CommitLineData
7ac48069 1/* $Id$
2 *
3 * Do RPC
a3cf6921 4 *
7ac48069 5 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
a3cf6921 8 *
a3cf6921 9 */
10
c801de4c 11#include <mit-copyright.h>
7ac48069 12#include "mr_server.h"
13#include "query.h"
14
57c08162 15#include <sys/stat.h>
7ac48069 16#include <sys/types.h>
17
960b073b 18#include <arpa/inet.h>
7ac48069 19#include <netinet/in.h>
20
78849033 21#include <errno.h>
7ac48069 22#include <fcntl.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26
27RCSID("$Header$");
28
a3cf6921 29extern int nclients;
85330553 30extern client **clients;
a3cf6921 31extern char *whoami;
32
03c05291 33extern int dbms_errno, mr_errcode;
78543660 34
7ac48069 35void do_call(client *cl);
36void free_rtn_tuples(client *cp);
85330553 37int retr_callback(int argc, char **argv, void *p_cl);
38int list_users(client *cl);
8691463b 39void do_retr(client *cl);
40void do_access(client *cl);
7ac48069 41void get_motd(client *cl);
42
a3cf6921 43char *procnames[] = {
5eaef520 44 "noop",
45 "auth",
46 "shutdown",
47 "query",
48 "access",
49 "dcm",
50 "motd",
630e8323 51};
52
85330553 53int newqueries;
a3cf6921 54
85330553 55void client_read(client *cl)
a3cf6921 56{
85330553 57 int status, pn;
58
8691463b 59 status = mr_cont_receive(cl->con, &cl->req);
60 if (status == -1)
61 return;
62 else if (status != MR_SUCCESS)
5eaef520 63 {
8691463b 64 cl->state = CL_CLOSING;
85330553 65 if (status != MR_NOT_CONNECTED)
66 com_err(whoami, status, "while reading from socket");
5eaef520 67 return;
68 }
85330553 69
8691463b 70 pn = cl->req.u.mr_procno;
85330553 71 if (pn < 0 || pn > MR_MAX_PROC)
5eaef520 72 {
85330553 73 com_err(whoami, 0, "procno out of range");
74 client_reply(cl, MR_UNKNOWN_PROC);
8691463b 75 mr_destroy_reply(cl->req);
85330553 76 return;
5eaef520 77 }
8691463b 78 log_args(procnames[pn], 2, cl->req.mr_argc, cl->req.mr_argv);
5eaef520 79
85330553 80 if (dormant == ASLEEP && pn != MR_NOOP && pn != MR_MOTD)
5eaef520 81 {
85330553 82 client_reply(cl, MR_DOWN);
83 com_err(whoami, MR_DOWN, "(query refused)");
8691463b 84 mr_destroy_reply(cl->req);
5eaef520 85 return;
86 }
87
88 /* make sure this gets cleared before every operation */
89 dbms_errno = 0;
90
91 switch (pn)
92 {
93 case MR_NOOP:
85330553 94 client_reply(cl, MR_SUCCESS);
e688520a 95 break;
5eaef520 96
97 case MR_AUTH:
8691463b 98 do_auth(cl);
e688520a 99 break;
5eaef520 100
101 case MR_QUERY:
8691463b 102 do_retr(cl);
e688520a 103 break;
5eaef520 104
105 case MR_ACCESS:
8691463b 106 do_access(cl);
e688520a 107 break;
5eaef520 108
109 case MR_SHUTDOWN:
110 do_shutdown(cl);
e688520a 111 break;
5eaef520 112
113 case MR_DO_UPDATE:
85330553 114 client_reply(cl, MR_PERM);
e688520a 115 break;
5eaef520 116
117 case MR_MOTD:
118 get_motd(cl);
e688520a 119 break;
5eaef520 120 }
8691463b 121 mr_destroy_reply(cl->req);
122 memset(&cl->req, 0, sizeof(mr_params));
a3cf6921 123}
124
85330553 125/* Set the final return status for a query. We always keep one more
126 free slot in cl->tuples[] than we're using so that this can't fail */
127void client_reply(client *cl, long status)
ed31e0d1 128{
85330553 129 cl->tuples[cl->ntuples].u.mr_status = status;
130 cl->tuples[cl->ntuples].mr_argc = 0;
131 cl->tuples[cl->ntuples].mr_argl = NULL;
132 cl->tuples[cl->ntuples].mr_argv = NULL;
133 cl->ntuples++;
5eaef520 134}
ed31e0d1 135
85330553 136void client_return_tuple(client *cl, int argc, char **argv)
78849033 137{
8691463b 138 if (cl->state == CL_CLOSING || dbms_errno)
85330553 139 return;
5eaef520 140
85330553 141 if (cl->ntuples == cl->tuplessize - 1)
5eaef520 142 {
85330553 143 int newsize = (cl->tuplessize + 4) * 2;
144 mr_params *newtuples;
145
146 newtuples = realloc(cl->tuples, newsize * sizeof(mr_params));
147 if (!newtuples)
148 {
149 free_rtn_tuples(cl);
150 dbms_errno = mr_errcode = MR_NO_MEM;
151 return;
152 }
153 cl->tuplessize = newsize;
154 cl->tuples = newtuples;
5eaef520 155 }
5eaef520 156
85330553 157 cl->tuples[cl->ntuples].u.mr_status = MR_MORE_DATA;
158 cl->tuples[cl->ntuples].mr_argc = argc;
159 cl->tuples[cl->ntuples].mr_argl = NULL;
160 cl->tuples[cl->ntuples].mr_argv = mr_copy_args(argv, argc);
161 cl->ntuples++;
78849033 162}
163
85330553 164void client_write(client *cl)
de24f12d 165{
85330553 166 int status;
5eaef520 167
85330553 168 status = mr_send(cl->con, &cl->tuples[cl->nexttuple]);
169 if (status)
5eaef520 170 {
85330553 171 com_err(whoami, status, "writing to socket");
8691463b 172 cl->state = CL_CLOSING;
85330553 173 }
174 else
175 {
176 cl->nexttuple++;
177 if (cl->nexttuple == cl->ntuples)
178 free_rtn_tuples(cl);
5eaef520 179 }
de24f12d 180}
78849033 181
85330553 182void free_rtn_tuples(client *cl)
a3cf6921 183{
85330553 184 for (cl->ntuples--; cl->ntuples >= 0; cl->ntuples--)
185 free_argv(cl->tuples[cl->ntuples].mr_argv,
186 cl->tuples[cl->ntuples].mr_argc);
187 free(cl->tuples);
188
189 cl->tuples = xmalloc(sizeof(mr_params));
190 cl->tuplessize = 1;
191 cl->ntuples = cl->nexttuple = 0;
192}
5eaef520 193
8691463b 194void do_retr(client *cl)
85330553 195{
196 char *queryname;
197 int status;
5eaef520 198
8691463b 199 if (cl->req.mr_argc < 1)
5eaef520 200 {
85330553 201 client_reply(cl, MR_ARGS);
5eaef520 202 com_err(whoami, MR_ARGS, "got nameless query");
203 return;
204 }
8691463b 205 queryname = cl->req.mr_argv[0];
85330553 206 newqueries++;
5eaef520 207
208 if (!strcmp(queryname, "_list_users"))
85330553 209 status = list_users(cl);
5eaef520 210 else
8691463b 211 status = mr_process_query(cl, queryname, cl->req.mr_argc - 1,
212 cl->req.mr_argv + 1, retr_callback, cl);
85330553 213
214 client_reply(cl, status);
215
85330553 216 com_err(whoami, 0, "Query complete.");
217}
218
219int retr_callback(int argc, char **argv, void *p_cl)
220{
221 client *cl = p_cl;
222
223 mr_trim_args(argc, argv);
224 client_return_tuple(cl, argc, argv);
a3cf6921 225}
78849033 226
8691463b 227void do_access(client *cl)
3630192b 228{
85330553 229 int status;
230
8691463b 231 if (cl->req.mr_argc < 1)
5eaef520 232 {
85330553 233 client_reply(cl, MR_ARGS);
5eaef520 234 com_err(whoami, MR_ARGS, "got nameless access");
235 return;
236 }
5eaef520 237
8691463b 238 status = mr_check_access(cl, cl->req.mr_argv[0], cl->req.mr_argc - 1,
239 cl->req.mr_argv + 1);
85330553 240 client_reply(cl, status);
5eaef520 241
242 com_err(whoami, 0, "Access check complete.");
3630192b 243}
8165c536 244
85330553 245void get_motd(client *cl)
8165c536 246{
85330553 247 int motd;
248 char *buffer;
249 struct stat statb;
5eaef520 250
85330553 251 if (stat(MOIRA_MOTD_FILE, &statb) == -1)
5eaef520 252 {
85330553 253 client_reply(cl, MR_SUCCESS);
254 return;
255 }
256
257 buffer = malloc(statb.st_size + 1);
258 if (!buffer)
259 {
260 client_reply(cl, MR_NO_MEM);
261 return;
262 }
5eaef520 263
85330553 264 motd = open(MOIRA_MOTD_FILE, 0, O_RDONLY);
265 if (motd)
266 {
267 read(motd, buffer, statb.st_size);
268 close(motd);
269 buffer[statb.st_size] = '\0';
270 client_return_tuple(cl, 1, &buffer);
271 client_reply(cl, MR_SUCCESS);
5eaef520 272 }
85330553 273 else
274 client_reply(cl, errno);
8165c536 275
85330553 276 free(buffer);
277}
57c08162 278
85330553 279int list_users(client *cl)
57c08162 280{
85330553 281 char *argv[5];
282 char buf[30];
283 char buf1[30];
284 int i;
285 char *cp;
5eaef520 286
85330553 287 for (i = 0; i < nclients; i++)
288 {
289 client *c = clients[i];
290 argv[0] = c->clname;
291 argv[1] = inet_ntoa(c->haddr.sin_addr);
292 argv[2] = buf;
293 sprintf(buf, "port %d", ntohs(c->haddr.sin_port));
294 argv[3] = ctime(&c->last_time_used);
295 cp = strchr(argv[3], '\n');
296 if (cp)
297 *cp = '\0';
298 argv[4] = buf1;
299 sprintf(buf1, "[#%d]", c->id);
300 client_return_tuple(cl, 5, argv);
301 }
302 return MR_SUCCESS;
57c08162 303}
85330553 304
This page took 0.141845 seconds and 5 git commands to generate.