]> andersk Git - moira.git/blame - server/mr_scall.c
Command line printer manipulation client, and build goo.
[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
c44ddfa7 35int max_version;
36
7ac48069 37void do_call(client *cl);
38void free_rtn_tuples(client *cp);
85330553 39int retr_callback(int argc, char **argv, void *p_cl);
40int list_users(client *cl);
8691463b 41void do_retr(client *cl);
42void do_access(client *cl);
7ac48069 43void get_motd(client *cl);
c44ddfa7 44void do_version(client *cl);
7ac48069 45
a3cf6921 46char *procnames[] = {
5eaef520 47 "noop",
48 "auth",
49 "shutdown",
50 "query",
51 "access",
52 "dcm",
53 "motd",
ed00e35e 54 "proxy",
c44ddfa7 55 "version",
991417e4 56 "auth_krb5",
630e8323 57};
58
85330553 59int newqueries;
a3cf6921 60
85330553 61void client_read(client *cl)
a3cf6921 62{
85330553 63 int status, pn;
64
8691463b 65 status = mr_cont_receive(cl->con, &cl->req);
66 if (status == -1)
67 return;
68 else if (status != MR_SUCCESS)
5eaef520 69 {
8691463b 70 cl->state = CL_CLOSING;
85330553 71 if (status != MR_NOT_CONNECTED)
72 com_err(whoami, status, "while reading from socket");
5eaef520 73 return;
74 }
85330553 75
8691463b 76 pn = cl->req.u.mr_procno;
85330553 77 if (pn < 0 || pn > MR_MAX_PROC)
5eaef520 78 {
85330553 79 com_err(whoami, 0, "procno out of range");
80 client_reply(cl, MR_UNKNOWN_PROC);
187dc9ed 81 goto out;
5eaef520 82 }
8691463b 83 log_args(procnames[pn], 2, cl->req.mr_argc, cl->req.mr_argv);
5eaef520 84
85330553 85 if (dormant == ASLEEP && pn != MR_NOOP && pn != MR_MOTD)
5eaef520 86 {
85330553 87 client_reply(cl, MR_DOWN);
88 com_err(whoami, MR_DOWN, "(query refused)");
187dc9ed 89 goto out;
5eaef520 90 }
91
92 /* make sure this gets cleared before every operation */
93 dbms_errno = 0;
94
95 switch (pn)
96 {
97 case MR_NOOP:
85330553 98 client_reply(cl, MR_SUCCESS);
e688520a 99 break;
5eaef520 100
101 case MR_AUTH:
8691463b 102 do_auth(cl);
e688520a 103 break;
5eaef520 104
105 case MR_QUERY:
8691463b 106 do_retr(cl);
e688520a 107 break;
5eaef520 108
109 case MR_ACCESS:
8691463b 110 do_access(cl);
e688520a 111 break;
5eaef520 112
113 case MR_SHUTDOWN:
114 do_shutdown(cl);
e688520a 115 break;
5eaef520 116
117 case MR_DO_UPDATE:
85330553 118 client_reply(cl, MR_PERM);
e688520a 119 break;
5eaef520 120
121 case MR_MOTD:
122 get_motd(cl);
e688520a 123 break;
ed00e35e 124
125 case MR_PROXY:
126 do_proxy(cl);
127 break;
c44ddfa7 128
129 case MR_SETVERSION:
130 do_version(cl);
131 break;
991417e4 132
133 case MR_KRB5_AUTH:
134 do_krb5_auth(cl);
135 break;
136
5eaef520 137 }
187dc9ed 138
139out:
8691463b 140 mr_destroy_reply(cl->req);
141 memset(&cl->req, 0, sizeof(mr_params));
a3cf6921 142}
143
85330553 144/* Set the final return status for a query. We always keep one more
145 free slot in cl->tuples[] than we're using so that this can't fail */
146void client_reply(client *cl, long status)
ed31e0d1 147{
85330553 148 cl->tuples[cl->ntuples].u.mr_status = status;
149 cl->tuples[cl->ntuples].mr_argc = 0;
150 cl->tuples[cl->ntuples].mr_argl = NULL;
151 cl->tuples[cl->ntuples].mr_argv = NULL;
152 cl->ntuples++;
5eaef520 153}
ed31e0d1 154
85330553 155void client_return_tuple(client *cl, int argc, char **argv)
78849033 156{
8691463b 157 if (cl->state == CL_CLOSING || dbms_errno)
85330553 158 return;
5eaef520 159
85330553 160 if (cl->ntuples == cl->tuplessize - 1)
5eaef520 161 {
85330553 162 int newsize = (cl->tuplessize + 4) * 2;
163 mr_params *newtuples;
164
165 newtuples = realloc(cl->tuples, newsize * sizeof(mr_params));
166 if (!newtuples)
167 {
168 free_rtn_tuples(cl);
169 dbms_errno = mr_errcode = MR_NO_MEM;
170 return;
171 }
172 cl->tuplessize = newsize;
173 cl->tuples = newtuples;
5eaef520 174 }
5eaef520 175
85330553 176 cl->tuples[cl->ntuples].u.mr_status = MR_MORE_DATA;
177 cl->tuples[cl->ntuples].mr_argc = argc;
178 cl->tuples[cl->ntuples].mr_argl = NULL;
179 cl->tuples[cl->ntuples].mr_argv = mr_copy_args(argv, argc);
180 cl->ntuples++;
78849033 181}
182
85330553 183void client_write(client *cl)
de24f12d 184{
85330553 185 int status;
5eaef520 186
85330553 187 status = mr_send(cl->con, &cl->tuples[cl->nexttuple]);
188 if (status)
5eaef520 189 {
85330553 190 com_err(whoami, status, "writing to socket");
8691463b 191 cl->state = CL_CLOSING;
85330553 192 }
193 else
194 {
195 cl->nexttuple++;
196 if (cl->nexttuple == cl->ntuples)
197 free_rtn_tuples(cl);
5eaef520 198 }
de24f12d 199}
78849033 200
85330553 201void free_rtn_tuples(client *cl)
a3cf6921 202{
85330553 203 for (cl->ntuples--; cl->ntuples >= 0; cl->ntuples--)
204 free_argv(cl->tuples[cl->ntuples].mr_argv,
205 cl->tuples[cl->ntuples].mr_argc);
206 free(cl->tuples);
207
208 cl->tuples = xmalloc(sizeof(mr_params));
209 cl->tuplessize = 1;
210 cl->ntuples = cl->nexttuple = 0;
211}
5eaef520 212
8691463b 213void do_retr(client *cl)
85330553 214{
215 char *queryname;
216 int status;
5eaef520 217
8691463b 218 if (cl->req.mr_argc < 1)
5eaef520 219 {
85330553 220 client_reply(cl, MR_ARGS);
5eaef520 221 com_err(whoami, MR_ARGS, "got nameless query");
222 return;
223 }
8691463b 224 queryname = cl->req.mr_argv[0];
85330553 225 newqueries++;
5eaef520 226
227 if (!strcmp(queryname, "_list_users"))
85330553 228 status = list_users(cl);
5eaef520 229 else
8691463b 230 status = mr_process_query(cl, queryname, cl->req.mr_argc - 1,
231 cl->req.mr_argv + 1, retr_callback, cl);
85330553 232
233 client_reply(cl, status);
234
85330553 235 com_err(whoami, 0, "Query complete.");
236}
237
238int retr_callback(int argc, char **argv, void *p_cl)
239{
240 client *cl = p_cl;
241
242 mr_trim_args(argc, argv);
243 client_return_tuple(cl, argc, argv);
a3cf6921 244}
78849033 245
8691463b 246void do_access(client *cl)
3630192b 247{
85330553 248 int status;
249
8691463b 250 if (cl->req.mr_argc < 1)
5eaef520 251 {
85330553 252 client_reply(cl, MR_ARGS);
5eaef520 253 com_err(whoami, MR_ARGS, "got nameless access");
254 return;
255 }
5eaef520 256
8691463b 257 status = mr_check_access(cl, cl->req.mr_argv[0], cl->req.mr_argc - 1,
258 cl->req.mr_argv + 1);
85330553 259 client_reply(cl, status);
5eaef520 260
261 com_err(whoami, 0, "Access check complete.");
3630192b 262}
8165c536 263
c44ddfa7 264void do_version(client *cl)
265{
266 if (cl->req.mr_argc != 1)
267 {
268 client_reply(cl, MR_ARGS);
269 com_err(whoami, MR_ARGS, "incorrect number of arguments");
270 return;
271 }
272
273 cl->version = atoi(cl->req.mr_argv[0]);
274 if (cl->version == -1)
275 cl->version = max_version;
276
277 client_reply(cl, cl->version == max_version ? MR_SUCCESS :
278 cl->version < max_version ? MR_VERSION_LOW : MR_VERSION_HIGH);
279}
280
85330553 281void get_motd(client *cl)
8165c536 282{
85330553 283 int motd;
284 char *buffer;
285 struct stat statb;
5eaef520 286
85330553 287 if (stat(MOIRA_MOTD_FILE, &statb) == -1)
5eaef520 288 {
85330553 289 client_reply(cl, MR_SUCCESS);
290 return;
291 }
292
293 buffer = malloc(statb.st_size + 1);
294 if (!buffer)
295 {
296 client_reply(cl, MR_NO_MEM);
297 return;
298 }
5eaef520 299
85330553 300 motd = open(MOIRA_MOTD_FILE, 0, O_RDONLY);
301 if (motd)
302 {
303 read(motd, buffer, statb.st_size);
304 close(motd);
305 buffer[statb.st_size] = '\0';
306 client_return_tuple(cl, 1, &buffer);
307 client_reply(cl, MR_SUCCESS);
5eaef520 308 }
85330553 309 else
310 client_reply(cl, errno);
8165c536 311
85330553 312 free(buffer);
313}
57c08162 314
85330553 315int list_users(client *cl)
57c08162 316{
85330553 317 char *argv[5];
318 char buf[30];
319 char buf1[30];
320 int i;
321 char *cp;
5eaef520 322
85330553 323 for (i = 0; i < nclients; i++)
324 {
325 client *c = clients[i];
326 argv[0] = c->clname;
327 argv[1] = inet_ntoa(c->haddr.sin_addr);
328 argv[2] = buf;
329 sprintf(buf, "port %d", ntohs(c->haddr.sin_port));
330 argv[3] = ctime(&c->last_time_used);
331 cp = strchr(argv[3], '\n');
332 if (cp)
333 *cp = '\0';
334 argv[4] = buf1;
335 sprintf(buf1, "[#%d]", c->id);
336 client_return_tuple(cl, 5, argv);
337 }
338 return MR_SUCCESS;
57c08162 339}
85330553 340
This page took 0.845594 seconds and 5 git commands to generate.