]> andersk Git - moira.git/blame - server/qfollow.pc
add svrinstall target that only installs server binaries
[moira.git] / server / qfollow.pc
CommitLineData
7ac48069 1/* $Id$
73cf66ba 2 *
7ac48069 3 * Query followup routines
4 *
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>.
73cf66ba 8 *
9 */
10
73cf66ba 11#include <mit-copyright.h>
73cf66ba 12#include "mr_server.h"
03c05291 13#include "query.h"
7ac48069 14#include "qrtn.h"
15
85330553 16#include <errno.h>
73cf66ba 17#include <ctype.h>
7ac48069 18#include <stdlib.h>
03c05291 19#include <string.h>
73cf66ba 20#ifdef GDSS
21#include "gdss.h"
22#endif /* GDSS */
7ac48069 23
73cf66ba 24EXEC SQL INCLUDE sqlca;
7ac48069 25
26RCSID("$Header$");
73cf66ba 27
03c05291 28extern char *whoami, *table_name[];
29extern int dbms_errno, mr_errcode;
73cf66ba 30
31EXEC SQL BEGIN DECLARE SECTION;
32extern char stmt_buf[];
33EXEC SQL END DECLARE SECTION;
34
03c05291 35EXEC SQL WHENEVER SQLERROR DO dbmserr();
73cf66ba 36
37
38/* FOLLOWUP ROUTINES */
39
03c05291 40/* generic set_modtime routine. This takes the table id from the query,
73cf66ba 41 * and will update the modtime, modby, and modwho fields in the entry in
42 * the table whose name field matches argv[0].
43 */
44
5eaef520 45int set_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 46{
5eaef520 47 char *name, *entity, *table;
48 int who;
73cf66ba 49
5eaef520 50 entity = cl->entity;
51 who = cl->client_id;
52 table = table_name[q->rtable];
53 name = argv[0];
73cf66ba 54
5eaef520 55 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
56 "modwith = '%s' WHERE name = '%s'", table, who, entity, name);
57 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
73cf66ba 58
5eaef520 59 return MR_SUCCESS;
73cf66ba 60}
61
03c05291 62/* generic set_modtime_by_id routine. This takes the table id from
73cf66ba 63 * the query, and the id name from the validate record,
64 * and will update the modtime, modby, and modwho fields in the entry in
65 * the table whose id matches argv[0].
66 */
67
5eaef520 68int set_modtime_by_id(struct query *q, char *argv[], client *cl)
73cf66ba 69{
5eaef520 70 char *entity, *table, *id_name;
71 int who, id;
72
73 entity = cl->entity;
74 who = cl->client_id;
75 table = table_name[q->rtable];
76 id_name = q->validate->object_id;
77
78 id = *(int *)argv[0];
79 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
80 "modwith = '%s' WHERE %s = %d", table, who, entity, id_name, id);
81 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
82 return MR_SUCCESS;
73cf66ba 83}
84
85
86/* Sets the finger modtime on a user record. The users_id will be in argv[0].
87 */
88
5eaef520 89int set_finger_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 90{
5eaef520 91 EXEC SQL BEGIN DECLARE SECTION;
92 int users_id, who;
93 char *entity;
94 EXEC SQL END DECLARE SECTION;
73cf66ba 95
5eaef520 96 entity = cl->entity;
97 who = cl->client_id;
98 users_id = *(int *)argv[0];
73cf66ba 99
5eaef520 100 EXEC SQL UPDATE users SET fmodtime = SYSDATE, fmodby = :who,
101 fmodwith = :entity WHERE users_id = :users_id;
73cf66ba 102
5eaef520 103 return MR_SUCCESS;
73cf66ba 104}
105
106
107/* Sets the pobox modtime on a user record. The users_id will be in argv[0].
108 */
109
5eaef520 110int set_pobox_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 111{
5eaef520 112 EXEC SQL BEGIN DECLARE SECTION;
113 int users_id, who;
114 char *entity;
115 EXEC SQL END DECLARE SECTION;
73cf66ba 116
5eaef520 117 entity = cl->entity;
118 who = cl->client_id;
119 users_id = *(int *)argv[0];
73cf66ba 120
5eaef520 121 EXEC SQL UPDATE users SET pmodtime = SYSDATE, pmodby = :who,
122 pmodwith = :entity WHERE users_id = :users_id;
73cf66ba 123
5eaef520 124 return MR_SUCCESS;
73cf66ba 125}
126
127
128/* Like set_modtime, but uppercases the name first.
129 */
130
5eaef520 131int set_uppercase_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 132{
5eaef520 133 char *name, *entity, *table;
134 int who;
73cf66ba 135
5eaef520 136 entity = cl->entity;
137 who = cl->client_id;
138 table = table_name[q->rtable];
139 name = argv[0];
73cf66ba 140
5eaef520 141 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
142 "modwith = '%s' WHERE name = UPPER('%s')", table, who, entity, name);
143 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
73cf66ba 144
5eaef520 145 return MR_SUCCESS;
73cf66ba 146}
147
148
149/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
150 * is necessary for add_machine_to_cluster becuase the table that query
151 * operates on is "mcm", not "machine".
152 */
153
5eaef520 154int set_mach_modtime_by_id(struct query *q, char *argv[], client *cl)
73cf66ba 155{
5eaef520 156 EXEC SQL BEGIN DECLARE SECTION;
157 char *entity;
158 int who, id;
159 EXEC SQL END DECLARE SECTION;
160
161 entity = cl->entity;
162 who = cl->client_id;
163 id = *(int *)argv[0];
164 EXEC SQL UPDATE machine SET modtime = SYSDATE, modby = :who,
165 modwith = :entity WHERE mach_id = :id;
166
167 return MR_SUCCESS;
73cf66ba 168}
169
170
171/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
172 * is necessary for add_cluster_data and delete_cluster_data becuase the
173 * table that query operates on is "svc", not "cluster".
174 */
175
5eaef520 176int set_cluster_modtime_by_id(struct query *q, char *argv[], client *cl)
73cf66ba 177{
5eaef520 178 EXEC SQL BEGIN DECLARE SECTION;
179 char *entity;
180 int who, id;
181 EXEC SQL END DECLARE SECTION;
182
183 entity = cl->entity;
184 who = cl->client_id;
185
186 id = *(int *)argv[0];
187 EXEC SQL UPDATE clusters SET modtime = SYSDATE, modby = :who,
188 modwith = :entity WHERE clu_id = :id;
189 return MR_SUCCESS;
73cf66ba 190}
191
192
193/* sets the modtime on the serverhost where the service name is in argv[0]
194 * and the mach_id is in argv[1].
195 */
196
5eaef520 197int set_serverhost_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 198{
5eaef520 199 EXEC SQL BEGIN DECLARE SECTION;
200 char *entity, *serv;
201 int who, id;
202 EXEC SQL END DECLARE SECTION;
203
204 entity = cl->entity;
205 who = cl->client_id;
206
207 serv = argv[0];
208 id = *(int *)argv[1];
209 EXEC SQL UPDATE serverhosts
210 SET modtime = SYSDATE, modby = :who, modwith = :entity
211 WHERE service = :serv AND mach_id = :id;
212 return MR_SUCCESS;
73cf66ba 213}
214
215
216/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
217 * directory name is in argv[1].
218 */
219
5eaef520 220int set_nfsphys_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 221{
5eaef520 222 EXEC SQL BEGIN DECLARE SECTION;
223 char *entity, *dir;
224 int who, id;
225 EXEC SQL END DECLARE SECTION;
226
227 entity = cl->entity;
228 who = cl->client_id;
229
230 id = *(int *)argv[0];
231 dir = argv[1];
232 EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who,
233 modwith = :entity WHERE dir = :dir AND mach_id = :id;
234 return MR_SUCCESS;
73cf66ba 235}
236
237
238/* sets the modtime on a filesystem, where argv[0] contains the filesys
239 * label.
240 */
241
5eaef520 242int set_filesys_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 243{
5eaef520 244 EXEC SQL BEGIN DECLARE SECTION;
245 char *label, *entity;
246 int who;
247 extern int _var_phys_id;
248 EXEC SQL END DECLARE SECTION;
249
250 entity = cl->entity;
251 who = cl->client_id;
252
253 label = argv[0];
254 if (!strcmp(q->shortname, "ufil"))
255 label = argv[1];
256
257 EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who,
258 modwith = :entity, phys_id = :_var_phys_id
259 WHERE label = :label;
260 return MR_SUCCESS;
73cf66ba 261}
262
263
264/* sets the modtime on a zephyr class, where argv[0] contains the class
265 * name.
266 */
267
5eaef520 268int set_zephyr_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 269{
5eaef520 270 EXEC SQL BEGIN DECLARE SECTION;
271 char *class, *entity;
272 int who;
273 EXEC SQL END DECLARE SECTION;
73cf66ba 274
5eaef520 275 entity = cl->entity;
276 who = cl->client_id;
73cf66ba 277
5eaef520 278 class = argv[0];
73cf66ba 279
5eaef520 280 EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who,
281 modwith = :entity WHERE class = :class;
73cf66ba 282
5eaef520 283 return MR_SUCCESS;
73cf66ba 284}
285
286
287/* fixes the modby field. This will be the second to last thing in the
288 * argv, the argv length is determined from the query structure. It is
289 * passed as a pointer to an integer. This will either turn it into a
290 * username, or # + the users_id.
291 */
5eaef520 292int followup_fix_modby(struct query *q, struct save_queue *sq,
7ac48069 293 struct validate *v, int (*action)(int, char *[], void *),
294 void *actarg, client *cl)
73cf66ba 295{
44d12d58 296 int i, j;
5eaef520 297 char **argv;
298 int id, status;
299
300 i = q->vcnt - 2;
301 while (sq_get_data(sq, &argv))
302 {
303 id = atoi(argv[i]);
304 if (id > 0)
305 status = id_to_name(id, USERS_TABLE, &argv[i]);
306 else
307 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
308 if (status && status != MR_NO_MATCH)
309 return status;
310 (*action)(q->vcnt, argv, actarg);
311 for (j = 0; j < q->vcnt; j++)
312 free(argv[j]);
313 free(argv);
73cf66ba 314 }
5eaef520 315 sq_destroy(sq);
316 return MR_SUCCESS;
73cf66ba 317}
318
319
320/* After retrieving a user account, fix the modby field and signature.
321 * The modby field is the second to last thing in the
322 * argv, the argv length is determined from the query structure. It is
323 * passed as a pointer to an integer. This will either turn it into a
324 * username, or # + the users_id. Only "gua*" queries have a signature,
325 * these are ones with U_END return values. "gub*" queries also use this
326 * routine but don't have a signature.
327 */
5eaef520 328int followup_guax(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 329 int (*action)(int, char *[], void *), void *actarg,
330 client *cl)
73cf66ba 331{
44d12d58 332 int i, j;
5eaef520 333 char **argv;
73cf66ba 334#ifdef GDSS
e688520a 335 unsigned char sigbuf[512];
5eaef520 336 char *kname;
337 SigInfo si;
338 EXEC SQL BEGIN DECLARE SECTION;
7ac48069 339 int timestamp, who;
5eaef520 340 char *login;
e688520a 341 char rsig[USERS_SIGNATURE_SIZE];
342 EXEC SQL VAR rsig IS STRING(USERS_SIGNATURE_SIZE);
5eaef520 343 EXEC SQL END DECLARE SECTION;
73cf66ba 344#endif /* GDSS */
5eaef520 345 int id, status;
346
347 i = q->vcnt - 2;
348 while (sq_get_data(sq, &argv))
349 {
350 id = atoi(argv[i]);
351 if (id > 0)
352 status = id_to_name(id, USERS_TABLE, &argv[i]);
353 else
354 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
355 if (status && status != MR_NO_MATCH)
356 return status;
73cf66ba 357#ifdef GDSS
5eaef520 358 if (q->vcnt == U_END && strlen(argv[U_SIGNATURE]))
359 {
360 login = strtrim(argv[U_NAME]);
361 EXEC SQL SELECT signature, sigdate, sigwho
362 INTO :rsig, :timestamp, :who FROM users
363 WHERE login = :login;
364 if (dbms_errno)
365 return mr_errcode;
e688520a 366 kname = malloc(0);
5eaef520 367 status = id_to_name(who, STRINGS_TABLE, &kname);
368 si.timestamp = timestamp;
369 si.SigInfoVersion = 0; /* XXXXX this isn't used */
370 kname_parse(si.pname, si.pinst, si.prealm, kname);
371 free(kname);
e688520a 372 si.rawsig = (unsigned char *)xstrdup(rsig);
5eaef520 373 GDSS_Recompose(&si, sigbuf);
374 free(si.rawsig);
375 free(argv[U_SIGNATURE]);
e688520a 376 argv[U_SIGNATURE] = xstrdup(sigbuf);
73cf66ba 377 }
378#endif /* GDSS */
5eaef520 379 (*action)(q->vcnt, argv, actarg);
380 for (j = 0; j < q->vcnt; j++)
381 free(argv[j]);
382 free(argv);
73cf66ba 383 }
5eaef520 384 sq_destroy(sq);
385 return MR_SUCCESS;
73cf66ba 386}
387
388
389/**
390 ** followup_ausr - add finger and pobox entries, set_user_modtime
391 **
392 ** Inputs:
393 ** argv[0] - login (add_user)
394 ** argv[3] - last name
395 ** argv[4] - first name
396 ** argv[5] - middle name
397 **
398 **/
399
5eaef520 400int followup_ausr(struct query *q, char *argv[], client *cl)
73cf66ba 401{
5eaef520 402 EXEC SQL BEGIN DECLARE SECTION;
403 int who, status;
404 char *login, *entity, *name;
e688520a 405 char fullname[USERS_FIRST_SIZE + USERS_MIDDLE_SIZE + USERS_LAST_SIZE];
5eaef520 406 EXEC SQL END DECLARE SECTION;
73cf66ba 407#ifdef GDSS
e688520a 408 char databuf[USERS_LOGIN_SIZE + USERS_CLEARID_SIZE];
5eaef520 409 EXEC SQL BEGIN DECLARE SECTION;
e688520a 410 char rawsig[512];
5eaef520 411 int sigwho, timestamp;
412 EXEC SQL END DECLARE SECTION;
413 SigInfo si;
73cf66ba 414#endif /* GDSS */
415
5eaef520 416 /* build fullname */
417 if (strlen(argv[4]) && strlen(argv[5]))
418 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
419 else if (strlen(argv[4]))
420 sprintf(fullname, "%s %s", argv[4], argv[3]);
421 else
422 sprintf(fullname, "%s", argv[3]);
73cf66ba 423
424#ifdef GDSS
5eaef520 425 if (q->vcnt == U_END && *argv[U_SIGNATURE])
426 {
427 sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]);
428 /* skip bytes for timestamp & kname */
429 si.rawsig = (unsigned char *) rawsig;
430 status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si);
431 if (strlen(rawsig) > mr_sig_length)
432 {
433 com_err(whoami, 0, "GDSS signature would be truncated.");
434 return MR_INTERNAL;
73cf66ba 435 }
5eaef520 436 if (status == 0)
437 {
438 name = kname_unparse(si.pname, si.pinst, si.prealm);
439 status = name_to_id(name, STRINGS_TABLE, &sigwho);
440 if (status == MR_NO_MATCH)
441 sigwho = add_string(name);
442 else if (status)
443 return status;
444 timestamp = si.timestamp;
445 }
446 else
85330553 447 return gdss2et(status);
5eaef520 448 }
449 else
450 {
451 rawsig[0] = '\0';
452 sigwho = 0;
453 timestamp = 0;
454 }
73cf66ba 455#endif /* GDSS */
456
5eaef520 457 login = argv[0];
458 who = cl->client_id;
459 entity = cl->entity;
73cf66ba 460
5eaef520 461 /* create finger entry, pobox & set modtime on user */
73cf66ba 462#ifdef GDSS
5eaef520 463 EXEC SQL UPDATE users
464 SET modtime = SYSDATE, modby = :who, modwith = :entity,
465 fullname = NVL(:fullname, CHR(0)), affiliation = type,
466 signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp,
467 sigwho = :sigwho, fmodtime = SYSDATE, fmodby = :who,
468 fmodwith = :entity, potype = 'NONE', pmodtime = SYSDATE,
469 pmodby = :who, pmodwith = :entity
470 WHERE login = :login;
73cf66ba 471#else /* GDSS */
5eaef520 472 EXEC SQL UPDATE users
473 SET modtime = SYSDATE, modby = :who, modwith = :entity,
474 fullname = NVL(:fullname, CHR(0)), affiliation = type,
475 fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
476 potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
477 WHERE login = :login;
73cf66ba 478#endif /* GDSS */
479
5eaef520 480 return MR_SUCCESS;
73cf66ba 481}
482
483
484/**
03c05291 485 ** followup_uuac - do signature, set_user_modtime
73cf66ba 486 **
487 ** Inputs:
488 ** argv[0] - login (add_user)
489 ** argv[U_SIGNATURE] - sig
490 **
491 **/
492
5eaef520 493int followup_uuac(struct query *q, char *argv[], client *cl)
73cf66ba 494{
5eaef520 495 EXEC SQL BEGIN DECLARE SECTION;
496 int who, status, id;
497 char *entity, *name;
498 EXEC SQL END DECLARE SECTION;
73cf66ba 499#ifdef GDSS
e688520a 500 char databuf[USERS_LOGIN_SIZE + USERS_CLEARID_SIZE];
5eaef520 501 EXEC SQL BEGIN DECLARE SECTION;
e688520a 502 char rawsig[512];
5eaef520 503 char *login;
504 int sigwho, timestamp;
505 EXEC SQL END DECLARE SECTION;
506 SigInfo si;
73cf66ba 507#endif /* GDSS */
5eaef520 508
509 id = *(int *)argv[0];
510 who = cl->client_id;
511 entity = cl->entity;
512
73cf66ba 513#ifdef GDSS
5eaef520 514 if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1])
515 {
e688520a 516 login = malloc(0);
5eaef520 517 status = id_to_name(id, USERS_TABLE, &login);
518 sprintf(databuf, "%s:%s", login, argv[U_MITID + 1]);
519 free(login);
520 /* skip bytes for timestamp & kname */
521 si.rawsig = (unsigned char *) rawsig;
522 status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE + 1],
523 &si);
524 if (strlen(rawsig) > mr_sig_length)
525 {
526 com_err(whoami, 0, "GDSS signature would be truncated.");
527 return MR_INTERNAL;
73cf66ba 528 }
5eaef520 529 if (status == 0)
530 {
531 name = kname_unparse(si.pname, si.pinst, si.prealm);
532 status = name_to_id(name, STRINGS_TABLE, &sigwho);
533 if (status == MR_NO_MATCH)
534 sigwho = add_string(name);
535 else if (status)
536 return status;
537 timestamp = si.timestamp;
538 }
539 else
85330553 540 return gdss2et(status);
5eaef520 541 }
542 else
543 {
544 rawsig[0] = '\0';
545 sigwho = 0;
546 timestamp = 0;
73cf66ba 547 }
548#endif /* GDSS */
5eaef520 549
550 /* create finger entry, pobox & set modtime on user */
73cf66ba 551
552#ifdef GDSS
5eaef520 553 EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity,
554 signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp, sigwho = :sigwho
555 WHERE users_id = :id;
73cf66ba 556#else /* GDSS */
5eaef520 557 EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity
558 WHERE users_id = :id;
73cf66ba 559#endif /* GDSS */
5eaef520 560 return MR_SUCCESS;
73cf66ba 561}
5eaef520 562
73cf66ba 563/* followup_gpob: fixes argv[2] based on the IDs currently there and the
564 * type in argv[1]. Then completes the upcall to the user.
565 *
566 * argv[2] is of the form "123:234" where the first integer is the machine
567 * ID if it is a pop box, and the second is the string ID if it is an SMTP
568 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
569 * are skipped.
570 */
571
5eaef520 572int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 573 int (*action)(int, char *[], void *), void *actarg,
574 client *cl)
73cf66ba 575{
5eaef520 576 char **argv;
577 char *ptype, *p;
578 int mid, sid, status, i;
579
580 /* for each row */
581 while (sq_get_data(sq, &argv))
582 {
583 mr_trim_args(2, argv);
584 ptype = argv[1];
585 p = strchr(argv[2], ':');
586 *p++ = '\0';
587 mid = atoi(argv[2]);
588 sid = atoi(p);
589
590 if (!strcmp(ptype, "POP"))
591 {
592 status = id_to_name(mid, MACHINE_TABLE, &argv[2]);
593 if (status == MR_NO_MATCH)
594 return MR_MACHINE;
595 }
596 else if (!strcmp(ptype, "SMTP"))
597 {
598 status = id_to_name(sid, STRINGS_TABLE, &argv[2]);
599 if (status == MR_NO_MATCH)
600 return MR_STRING;
73cf66ba 601 }
5eaef520 602 else /* ptype == "NONE" */
603 goto skip;
604 if (status)
605 return status;
606
607 if (!strcmp(q->shortname, "gpob"))
608 {
609 sid = atoi(argv[4]);
610 if (sid > 0)
611 status = id_to_name(sid, USERS_TABLE, &argv[4]);
612 else
613 status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
73cf66ba 614 }
5eaef520 615 if (status && status != MR_NO_MATCH)
616 return status;
73cf66ba 617
5eaef520 618 (*action)(q->vcnt, argv, actarg);
73cf66ba 619 skip:
5eaef520 620 /* free saved data */
621 for (i = 0; i < q->vcnt; i++)
622 free(argv[i]);
623 free(argv);
73cf66ba 624 }
625
5eaef520 626 sq_destroy(sq);
627 return MR_SUCCESS;
73cf66ba 628}
629
630
631/* followup_gsnt: fix the ace_name in argv[7]. argv[6] will contain the
632 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[7] into the
633 * proper name based on the type, and repace that string in the argv.
634 * Also fixes the modby field by called followup_fix_modby.
635 */
636
5eaef520 637int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 638 int (*action)(int, char *[], void *), void *actarg,
639 client *cl)
73cf66ba 640{
5eaef520 641 char **argv, *type;
642 int id, i, idx, status;
643
644 idx = 8;
645
646 while (sq_get_data(sq, &argv))
647 {
648 mr_trim_args(q->vcnt, argv);
649
650 id = atoi(argv[i = q->vcnt - 2]);
651 if (id > 0)
652 status = id_to_name(id, USERS_TABLE, &argv[i]);
653 else
654 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
655 if (status && status != MR_NO_MATCH)
656 return status;
657
658 id = atoi(argv[idx]);
659 type = argv[idx - 1];
660
661 if (!strcmp(type, "LIST"))
662 status = id_to_name(id, LIST_TABLE, &argv[idx]);
663 else if (!strcmp(type, "USER"))
664 status = id_to_name(id, USERS_TABLE, &argv[idx]);
665 else if (!strcmp(type, "KERBEROS"))
666 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
667 else if (!strcmp(type, "NONE"))
668 {
669 status = 0;
670 free(argv[idx]);
e688520a 671 argv[idx] = xstrdup("NONE");
5eaef520 672 }
673 else
674 {
675 status = 0;
676 free(argv[idx]);
e688520a 677 argv[idx] = xstrdup("???");
fde7313c 678 }
5eaef520 679 if (status && status != MR_NO_MATCH)
680 return status;
fde7313c 681
5eaef520 682 /* send the data */
683 (*action)(q->vcnt, argv, actarg);
fde7313c 684
5eaef520 685 /* free saved data */
686 for (i = 0; i < q->vcnt; i++)
687 free(argv[i]);
688 free(argv);
fde7313c 689 }
690
5eaef520 691 sq_destroy(sq);
692 return MR_SUCCESS;
fde7313c 693}
694
695
696/* followup_ghst: fix the ace_name in argv[12]. argv[11] will contain the
697 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[12] into the
698 * proper name based on the type, and repace that string in the argv.
699 * Also fixes the modby field by called followup_fix_modby.
700 */
701
5eaef520 702int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 703 int (*action)(int, char *[], void *), void *actarg,
704 client *cl)
fde7313c 705{
5eaef520 706 char **argv, *type;
707 int id, i, idx, status;
708
709 while (sq_get_data(sq, &argv))
710 {
711 mr_trim_args(q->vcnt, argv);
712
713 id = atoi(argv[i = q->vcnt - 2]);
714 if (id > 0)
715 status = id_to_name(id, USERS_TABLE, &argv[i]);
716 else
717 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
718 if (status && status != MR_NO_MATCH)
719 return status;
720
721 id = atoi(argv[13]);
722 status = id_to_name(id, STRINGS_TABLE, &argv[13]);
723 if (status)
724 return status;
725 id = atoi(argv[14]);
726 status = id_to_name(id, STRINGS_TABLE, &argv[14]);
727 if (status)
728 return status;
729 id = atoi(argv[16]);
730 if (id < 0)
731 status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
732 else
733 status = id_to_name(id, USERS_TABLE, &argv[16]);
734 if (status && status != MR_NO_MATCH)
735 return status;
736
737 idx = 12;
738 id = atoi(argv[idx]);
739 type = strtrim(argv[idx - 1]);
740
741 if (!strcmp(type, "LIST"))
742 status = id_to_name(id, LIST_TABLE, &argv[idx]);
743 else if (!strcmp(type, "USER"))
744 status = id_to_name(id, USERS_TABLE, &argv[idx]);
745 else if (!strcmp(type, "KERBEROS"))
746 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
747 else if (!strcmp(type, "NONE"))
748 {
749 status = 0;
750 free(argv[idx]);
e688520a 751 argv[idx] = xstrdup("NONE");
73cf66ba 752 }
5eaef520 753 else
754 {
755 status = 0;
756 free(argv[idx]);
e688520a 757 argv[idx] = xstrdup("???");
5eaef520 758 }
759 if (status && status != MR_NO_MATCH)
760 return status;
73cf66ba 761
5eaef520 762 /* send the data */
763 (*action)(q->vcnt, argv, actarg);
73cf66ba 764
5eaef520 765 /* free saved data */
766 for (i = 0; i < q->vcnt; i++)
767 free(argv[i]);
768 free(argv);
73cf66ba 769 }
770
5eaef520 771 sq_destroy(sq);
772 return MR_SUCCESS;
73cf66ba 773}
774
775
776/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
777 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
778 * proper name based on the type, and repace that string in the argv.
779 * Also fixes the modby field by called followup_fix_modby.
780 */
781
5eaef520 782int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 783 int (*action)(int, char *[], void *), void *actarg,
784 client *cl)
73cf66ba 785{
5eaef520 786 char **argv, *type;
787 int id, i, idx, status;
788
789 idx = 8;
790 if (!strcmp(q->shortname, "gsin"))
791 idx = 12;
792
793 while (sq_get_data(sq, &argv))
794 {
795 mr_trim_args(q->vcnt, argv);
796
797 id = atoi(argv[i = q->vcnt - 2]);
798 if (id > 0)
799 status = id_to_name(id, USERS_TABLE, &argv[i]);
800 else
801 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
802 if (status && status != MR_NO_MATCH)
803 return status;
804
805 id = atoi(argv[idx]);
806 type = argv[idx - 1];
807
808 if (!strcmp(type, "LIST"))
809 status = id_to_name(id, LIST_TABLE, &argv[idx]);
810 else if (!strcmp(type, "USER"))
811 status = id_to_name(id, USERS_TABLE, &argv[idx]);
812 else if (!strcmp(type, "KERBEROS"))
813 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
814 else if (!strcmp(type, "NONE"))
815 {
816 status = 0;
817 free(argv[idx]);
e688520a 818 argv[idx] = xstrdup("NONE");
73cf66ba 819 }
5eaef520 820 else
821 {
822 status = 0;
823 free(argv[idx]);
e688520a 824 argv[idx] = xstrdup("???");
5eaef520 825 }
826 if (status && status != MR_NO_MATCH)
827 return status;
73cf66ba 828
5eaef520 829 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
830 {
e688520a 831 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
5eaef520 832 strcpy(argv[6], UNIQUE_GID);
73cf66ba 833 }
834
5eaef520 835 /* send the data */
836 (*action)(q->vcnt, argv, actarg);
73cf66ba 837
5eaef520 838 /* free saved data */
839 for (i = 0; i < q->vcnt; i++)
840 free(argv[i]);
841 free(argv);
73cf66ba 842 }
843
5eaef520 844 sq_destroy(sq);
845 return MR_SUCCESS;
73cf66ba 846}
847
848
849/* followup_gqot: Fix the entity name, directory name & modby fields
850 * argv[0] = filsys_id
851 * argv[1] = type
852 * argv[2] = entity_id
853 * argv[3] = ascii(quota)
854 */
855
5eaef520 856int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 857 int (*action)(int, char *[], void *), void *actarg,
858 client *cl)
73cf66ba 859{
44d12d58 860 int j;
5eaef520 861 char **argv;
862 EXEC SQL BEGIN DECLARE SECTION;
863 int id;
864 char *name, *label;
865 EXEC SQL END DECLARE SECTION;
866 int status, idx;
867
868 if (!strcmp(q->name, "get_quota") ||
869 !strcmp(q->name, "get_quota_by_filesys"))
870 idx = 4;
871 else
872 idx = 3;
873 while (sq_get_data(sq, &argv))
874 {
875 if (idx == 4)
876 {
877 switch (argv[1][0])
878 {
73cf66ba 879 case 'U':
5eaef520 880 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
881 break;
73cf66ba 882 case 'G':
883 case 'L':
5eaef520 884 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
885 break;
73cf66ba 886 case 'A':
5eaef520 887 free(argv[2]);
e688520a 888 argv[2] = xstrdup("system:anyuser");
5eaef520 889 break;
73cf66ba 890 default:
5eaef520 891 id = atoi(argv[2]);
e688520a 892 argv[2] = xmalloc(8);
5eaef520 893 sprintf(argv[2], "%d", id);
73cf66ba 894 }
895 }
5eaef520 896 id = atoi(argv[idx]);
897 free(argv[idx]);
e688520a 898 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
5eaef520 899 name = argv[idx];
e688520a 900 name[0] = '\0';
5eaef520 901 if (id == 0)
902 {
903 label = argv[0];
904 EXEC SQL SELECT name INTO :name FROM filesys
905 WHERE label = :label;
73cf66ba 906 }
5eaef520 907 else
908 {
909 EXEC SQL SELECT dir INTO :name FROM nfsphys
910 WHERE nfsphys_id = :id;
73cf66ba 911 }
5eaef520 912 if (sqlca.sqlerrd[2] != 1)
913 sprintf(argv[idx], "#%d", id);
914
915 id = atoi(argv[idx + 3]);
916 if (id > 0)
917 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
918 else
919 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
920 if (status && status != MR_NO_MATCH)
921 return status;
922 (*action)(q->vcnt, argv, actarg);
923 for (j = 0; j < q->vcnt; j++)
924 free(argv[j]);
925 free(argv);
73cf66ba 926 }
5eaef520 927 sq_destroy(sq);
928 return MR_SUCCESS;
73cf66ba 929}
930
931
932/* followup_aqot: Add allocation to nfsphys after creating quota.
933 * argv[0] = filsys_id
934 * argv[1] = type if "add_quota" or "update_quota"
935 * argv[2 or 1] = id
936 * argv[3 or 2] = ascii(quota)
937 */
938
5eaef520 939int followup_aqot(struct query *q, char *argv[], client *cl)
73cf66ba 940{
5eaef520 941 EXEC SQL BEGIN DECLARE SECTION;
942 int quota, id, fs, who, physid, table;
943 char *entity, *qtype, *tname;
944 EXEC SQL END DECLARE SECTION;
945 char incr_qual[60];
946 char *incr_argv[2];
947 int status;
948
949 table = q->rtable;
950 tname = table_name[table];
951 fs = *(int *)argv[0];
952 EXEC SQL SELECT phys_id INTO :physid FROM filesys
953 WHERE filsys_id = :fs;
954 if (dbms_errno)
955 return mr_errcode;
956
957 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
958 {
959 qtype = argv[1];
960 id = *(int *)argv[2];
961 quota = atoi(argv[3]);
962 sprintf(incr_qual, "q.filsys_id = %d", fs);
963 }
964 else
965 {
966 qtype = "USER";
967 id = *(int *)argv[1];
968 quota = atoi(argv[2]);
969 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
970 "q.entity_id = %d", fs, qtype, id);
73cf66ba 971 }
972
5eaef520 973 /* quota case of incremental_{before|after} only looks at slot 1 */
974 incr_argv[1] = qtype;
975
976 /* Follows one of many possible gross hacks to fix these particular
977 * conflicts between what is possible in the query table and what
978 * is possible in SQL.
979 */
980 if (q->type == APPEND)
981 {
982 incremental_clear_before();
983 EXEC SQL INSERT INTO quota
984 (filsys_id, type, entity_id, quota, phys_id)
985 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
986 incremental_after(table, incr_qual, incr_argv);
987 }
988 else
989 {
990 incremental_before(table, incr_qual, incr_argv);
991 EXEC SQL UPDATE quota SET quota = :quota
992 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
993 status = mr_errcode;
994 incremental_after(table, incr_qual, incr_argv);
73cf66ba 995 }
996
5eaef520 997 if (dbms_errno)
998 return mr_errcode;
999 flush_name(argv[0], table);
1000 if (q->type == APPEND)
1001 {
1002 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1003 WHERE table_name = :tname;
1004 }
1005 else
1006 {
1007 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1008 WHERE table_name = :tname;
73cf66ba 1009 }
5eaef520 1010
1011 /* Proceed with original followup */
1012 who = cl->client_id;
1013 entity = cl->entity;
1014
1015 EXEC SQL UPDATE quota
1016 SET modtime = SYSDATE, modby = :who, modwith = :entity
1017 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1018 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1019 WHERE nfsphys_id = :physid;
1020 if (dbms_errno)
1021 return mr_errcode;
1022 return MR_SUCCESS;
73cf66ba 1023}
1024
1025
1026/* Necessitated by the requirement of a correlation name by the incremental
5eaef520 1027 * routines, since query table deletes don't provide one.
73cf66ba 1028 */
5eaef520 1029int followup_dqot(struct query *q, char **argv, client *cl)
73cf66ba 1030{
5eaef520 1031 char *qtype;
1032 int id, fs, table;
1033 char *incr_argv[2];
1034 EXEC SQL BEGIN DECLARE SECTION;
1035 char incr_qual[80], *tname;
1036 EXEC SQL END DECLARE SECTION;
1037
1038 table = q->rtable;
1039 tname = table_name[table];
1040 fs = *(int *)argv[0];
1041 if (!strcmp(q->shortname, "dqot"))
1042 {
1043 qtype = argv[1];
1044 id = *(int *)argv[2];
1045 }
1046 else
1047 {
1048 qtype = "USER";
1049 id = *(int *)argv[1];
73cf66ba 1050 }
5eaef520 1051 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1052 fs, qtype, id);
73cf66ba 1053
5eaef520 1054 /* quota case of incremental_{before|after} only looks at slot 1 */
1055 incr_argv[1] = qtype;
73cf66ba 1056
5eaef520 1057 incremental_before(table, incr_qual, incr_argv);
1058 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1059 AND q.entity_id = :id;
1060 incremental_clear_after();
73cf66ba 1061
5eaef520 1062 if (dbms_errno)
1063 return mr_errcode;
1064 flush_name(argv[0], table);
73cf66ba 1065
5eaef520 1066 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1067 WHERE table_name = :tname;
1068 return MR_SUCCESS;
73cf66ba 1069}
1070
1071
5eaef520 1072int followup_gpce(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 1073 int (*action)(int, char *[], void *), void *actarg,
1074 client *cl)
73cf66ba 1075{
44d12d58 1076 int i, j;
5eaef520 1077 char **argv;
1078 int id, status;
1079
1080 i = q->vcnt - 2;
1081 while (sq_get_data(sq, &argv))
1082 {
1083 id = atoi(argv[PCAP_QSERVER]);
1084 status = id_to_name(id, MACHINE_TABLE, &argv[PCAP_QSERVER]);
1085 if (status)
1086 return status;
1087 id = atoi(argv[i]);
1088 if (id > 0)
1089 status = id_to_name(id, USERS_TABLE, &argv[i]);
1090 else
1091 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1092 if (status && status != MR_NO_MATCH)
1093 return status;
1094 (*action)(q->vcnt, argv, actarg);
1095 for (j = 0; j < q->vcnt; j++)
1096 free(argv[j]);
1097 free(argv);
73cf66ba 1098 }
5eaef520 1099 sq_destroy(sq);
1100 return MR_SUCCESS;
73cf66ba 1101}
1102
1103
1104/* followup_gzcl:
1105 */
1106
5eaef520 1107int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 1108 int (*action)(int, char *[], void *), void *actarg,
1109 client *cl)
73cf66ba 1110{
5eaef520 1111 int id, i, status;
1112 char **argv;
1113
1114 while (sq_get_data(sq, &argv))
1115 {
1116 mr_trim_args(q->vcnt, argv);
1117
1118 id = atoi(argv[i = q->vcnt - 2]);
1119 if (id > 0)
1120 status = id_to_name(id, USERS_TABLE, &argv[i]);
1121 else
1122 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1123 if (status && status != MR_NO_MATCH)
1124 return status;
1125
1126 for (i = 1; i < 8; i += 2)
1127 {
1128 id = atoi(argv[i + 1]);
1129 if (!strcmp(argv[i], "LIST"))
1130 status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1131 else if (!strcmp(argv[i], "USER"))
1132 status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1133 else if (!strcmp(argv[i], "KERBEROS"))
1134 status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1135 else if (!strcmp(argv[i], "NONE"))
1136 {
1137 status = 0;
1138 free(argv[i + 1]);
e688520a 1139 argv[i + 1] = xstrdup("NONE");
73cf66ba 1140 }
5eaef520 1141 else
1142 {
1143 status = 0;
1144 free(argv[i + 1]);
e688520a 1145 argv[i + 1] = xstrdup("???");
5eaef520 1146 }
1147 if (status && status != MR_NO_MATCH)
1148 return status;
73cf66ba 1149 }
1150
5eaef520 1151 /* send the data */
1152 (*action)(q->vcnt, argv, actarg);
73cf66ba 1153
5eaef520 1154 /* free saved data */
1155 for (i = 0; i < q->vcnt; i++)
1156 free(argv[i]);
1157 free(argv);
73cf66ba 1158 }
5eaef520 1159 sq_destroy(sq);
1160 return MR_SUCCESS;
73cf66ba 1161}
1162
1163
1164/* followup_gsha:
1165 */
1166
5eaef520 1167int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 1168 int (*action)(int, char *[], void *), void *actarg,
1169 client *cl)
73cf66ba 1170{
5eaef520 1171 char **argv;
1172 int i, id, status;
1173
1174 while (sq_get_data(sq, &argv))
1175 {
1176 mr_trim_args(q->vcnt, argv);
1177
1178 id = atoi(argv[4]);
1179 if (id > 0)
1180 status = id_to_name(id, USERS_TABLE, &argv[4]);
1181 else
1182 status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1183 if (status && status != MR_NO_MATCH)
1184 return status;
1185
1186 id = atoi(argv[2]);
1187 if (!strcmp(argv[1], "LIST"))
1188 status = id_to_name(id, LIST_TABLE, &argv[2]);
1189 else if (!strcmp(argv[1], "USER"))
1190 status = id_to_name(id, USERS_TABLE, &argv[2]);
1191 else if (!strcmp(argv[1], "KERBEROS"))
1192 status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1193 else if (!strcmp(argv[1], "NONE"))
1194 {
1195 status = 0;
1196 free(argv[2]);
e688520a 1197 argv[2] = xstrdup("NONE");
5eaef520 1198 }
1199 else
1200 {
1201 status = 0;
1202 free(argv[2]);
e688520a 1203 argv[2] = xstrdup("???");
73cf66ba 1204 }
5eaef520 1205 if (status && status != MR_NO_MATCH)
1206 return status;
73cf66ba 1207
5eaef520 1208 /* send the data */
1209 (*action)(q->vcnt, argv, actarg);
73cf66ba 1210
5eaef520 1211 /* free saved data */
1212 for (i = 0; i < q->vcnt; i++)
1213 free(argv[i]);
1214 free(argv);
73cf66ba 1215 }
5eaef520 1216 sq_destroy(sq);
1217 return MR_SUCCESS;
73cf66ba 1218}
1219
1220
5eaef520 1221int _sdl_followup(struct query *q, char *argv[], client *cl)
73cf66ba 1222{
85330553 1223 if (atoi(argv[0]))
5eaef520 1224 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1225 else
1226 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1227
1228 return MR_SUCCESS;
73cf66ba 1229}
1230
1231
85330553 1232int trigger_dcm(struct query *q, char *argv[], client *cl)
73cf66ba 1233{
85330553 1234 pid_t pid;
e688520a 1235 char prog[MAXPATHLEN];
85330553 1236
1237 sprintf(prog, "%s/startdcm", BIN_DIR);
1238 pid = vfork();
1239 switch (pid)
5eaef520 1240 {
85330553 1241 case 0:
1242 execl(prog, "startdcm", 0);
1243 exit(1);
1244
1245 case -1:
1246 return errno;
1247
73cf66ba 1248 default:
85330553 1249 return MR_SUCCESS;
73cf66ba 1250 }
1251}
This page took 0.259118 seconds and 5 git commands to generate.