]> andersk Git - moira.git/blame - server/qfollow.pc
add uprn, apsv, gpsv, upsv, dpsv
[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
2884200f 563
73cf66ba 564/* followup_gpob: fixes argv[2] based on the IDs currently there and the
565 * type in argv[1]. Then completes the upcall to the user.
566 *
567 * argv[2] is of the form "123:234" where the first integer is the machine
568 * ID if it is a pop box, and the second is the string ID if it is an SMTP
569 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
570 * are skipped.
571 */
572
5eaef520 573int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 574 int (*action)(int, char *[], void *), void *actarg,
575 client *cl)
73cf66ba 576{
5eaef520 577 char **argv;
578 char *ptype, *p;
579 int mid, sid, status, i;
580
581 /* for each row */
582 while (sq_get_data(sq, &argv))
583 {
584 mr_trim_args(2, argv);
585 ptype = argv[1];
586 p = strchr(argv[2], ':');
587 *p++ = '\0';
588 mid = atoi(argv[2]);
589 sid = atoi(p);
590
591 if (!strcmp(ptype, "POP"))
592 {
593 status = id_to_name(mid, MACHINE_TABLE, &argv[2]);
594 if (status == MR_NO_MATCH)
595 return MR_MACHINE;
596 }
597 else if (!strcmp(ptype, "SMTP"))
598 {
599 status = id_to_name(sid, STRINGS_TABLE, &argv[2]);
600 if (status == MR_NO_MATCH)
601 return MR_STRING;
73cf66ba 602 }
5eaef520 603 else /* ptype == "NONE" */
604 goto skip;
605 if (status)
606 return status;
607
608 if (!strcmp(q->shortname, "gpob"))
609 {
610 sid = atoi(argv[4]);
611 if (sid > 0)
612 status = id_to_name(sid, USERS_TABLE, &argv[4]);
613 else
614 status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
73cf66ba 615 }
5eaef520 616 if (status && status != MR_NO_MATCH)
617 return status;
73cf66ba 618
5eaef520 619 (*action)(q->vcnt, argv, actarg);
73cf66ba 620 skip:
5eaef520 621 /* free saved data */
622 for (i = 0; i < q->vcnt; i++)
623 free(argv[i]);
624 free(argv);
73cf66ba 625 }
626
5eaef520 627 sq_destroy(sq);
628 return MR_SUCCESS;
73cf66ba 629}
630
631
632/* followup_gsnt: fix the ace_name in argv[7]. argv[6] will contain the
633 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[7] into the
634 * proper name based on the type, and repace that string in the argv.
635 * Also fixes the modby field by called followup_fix_modby.
636 */
637
5eaef520 638int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 639 int (*action)(int, char *[], void *), void *actarg,
640 client *cl)
73cf66ba 641{
5eaef520 642 char **argv, *type;
643 int id, i, idx, status;
644
645 idx = 8;
646
647 while (sq_get_data(sq, &argv))
648 {
649 mr_trim_args(q->vcnt, argv);
650
651 id = atoi(argv[i = q->vcnt - 2]);
652 if (id > 0)
653 status = id_to_name(id, USERS_TABLE, &argv[i]);
654 else
655 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
656 if (status && status != MR_NO_MATCH)
657 return status;
658
659 id = atoi(argv[idx]);
660 type = argv[idx - 1];
661
662 if (!strcmp(type, "LIST"))
663 status = id_to_name(id, LIST_TABLE, &argv[idx]);
664 else if (!strcmp(type, "USER"))
665 status = id_to_name(id, USERS_TABLE, &argv[idx]);
666 else if (!strcmp(type, "KERBEROS"))
667 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
668 else if (!strcmp(type, "NONE"))
669 {
670 status = 0;
671 free(argv[idx]);
e688520a 672 argv[idx] = xstrdup("NONE");
5eaef520 673 }
674 else
675 {
676 status = 0;
677 free(argv[idx]);
e688520a 678 argv[idx] = xstrdup("???");
fde7313c 679 }
5eaef520 680 if (status && status != MR_NO_MATCH)
681 return status;
fde7313c 682
5eaef520 683 /* send the data */
684 (*action)(q->vcnt, argv, actarg);
fde7313c 685
5eaef520 686 /* free saved data */
687 for (i = 0; i < q->vcnt; i++)
688 free(argv[i]);
689 free(argv);
fde7313c 690 }
691
5eaef520 692 sq_destroy(sq);
693 return MR_SUCCESS;
fde7313c 694}
695
696
697/* followup_ghst: fix the ace_name in argv[12]. argv[11] will contain the
698 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[12] into the
699 * proper name based on the type, and repace that string in the argv.
700 * Also fixes the modby field by called followup_fix_modby.
701 */
702
5eaef520 703int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 704 int (*action)(int, char *[], void *), void *actarg,
705 client *cl)
fde7313c 706{
5eaef520 707 char **argv, *type;
708 int id, i, idx, status;
709
710 while (sq_get_data(sq, &argv))
711 {
712 mr_trim_args(q->vcnt, argv);
713
714 id = atoi(argv[i = q->vcnt - 2]);
715 if (id > 0)
716 status = id_to_name(id, USERS_TABLE, &argv[i]);
717 else
718 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
719 if (status && status != MR_NO_MATCH)
720 return status;
721
722 id = atoi(argv[13]);
723 status = id_to_name(id, STRINGS_TABLE, &argv[13]);
724 if (status)
725 return status;
726 id = atoi(argv[14]);
727 status = id_to_name(id, STRINGS_TABLE, &argv[14]);
728 if (status)
729 return status;
730 id = atoi(argv[16]);
731 if (id < 0)
732 status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
733 else
734 status = id_to_name(id, USERS_TABLE, &argv[16]);
735 if (status && status != MR_NO_MATCH)
736 return status;
737
738 idx = 12;
739 id = atoi(argv[idx]);
740 type = strtrim(argv[idx - 1]);
741
742 if (!strcmp(type, "LIST"))
743 status = id_to_name(id, LIST_TABLE, &argv[idx]);
744 else if (!strcmp(type, "USER"))
745 status = id_to_name(id, USERS_TABLE, &argv[idx]);
746 else if (!strcmp(type, "KERBEROS"))
747 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
748 else if (!strcmp(type, "NONE"))
749 {
750 status = 0;
751 free(argv[idx]);
e688520a 752 argv[idx] = xstrdup("NONE");
73cf66ba 753 }
5eaef520 754 else
755 {
756 status = 0;
757 free(argv[idx]);
e688520a 758 argv[idx] = xstrdup("???");
5eaef520 759 }
760 if (status && status != MR_NO_MATCH)
761 return status;
73cf66ba 762
5eaef520 763 /* send the data */
764 (*action)(q->vcnt, argv, actarg);
73cf66ba 765
5eaef520 766 /* free saved data */
767 for (i = 0; i < q->vcnt; i++)
768 free(argv[i]);
769 free(argv);
73cf66ba 770 }
771
5eaef520 772 sq_destroy(sq);
773 return MR_SUCCESS;
73cf66ba 774}
775
776
777/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
778 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
779 * proper name based on the type, and repace that string in the argv.
780 * Also fixes the modby field by called followup_fix_modby.
781 */
782
5eaef520 783int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 784 int (*action)(int, char *[], void *), void *actarg,
785 client *cl)
73cf66ba 786{
5eaef520 787 char **argv, *type;
788 int id, i, idx, status;
789
790 idx = 8;
791 if (!strcmp(q->shortname, "gsin"))
792 idx = 12;
793
794 while (sq_get_data(sq, &argv))
795 {
796 mr_trim_args(q->vcnt, argv);
797
798 id = atoi(argv[i = q->vcnt - 2]);
799 if (id > 0)
800 status = id_to_name(id, USERS_TABLE, &argv[i]);
801 else
802 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
803 if (status && status != MR_NO_MATCH)
804 return status;
805
806 id = atoi(argv[idx]);
807 type = argv[idx - 1];
808
809 if (!strcmp(type, "LIST"))
810 status = id_to_name(id, LIST_TABLE, &argv[idx]);
811 else if (!strcmp(type, "USER"))
812 status = id_to_name(id, USERS_TABLE, &argv[idx]);
813 else if (!strcmp(type, "KERBEROS"))
814 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
815 else if (!strcmp(type, "NONE"))
816 {
817 status = 0;
818 free(argv[idx]);
e688520a 819 argv[idx] = xstrdup("NONE");
73cf66ba 820 }
5eaef520 821 else
822 {
823 status = 0;
824 free(argv[idx]);
e688520a 825 argv[idx] = xstrdup("???");
5eaef520 826 }
827 if (status && status != MR_NO_MATCH)
828 return status;
73cf66ba 829
5eaef520 830 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
831 {
e688520a 832 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
5eaef520 833 strcpy(argv[6], UNIQUE_GID);
73cf66ba 834 }
835
5eaef520 836 /* send the data */
837 (*action)(q->vcnt, argv, actarg);
73cf66ba 838
5eaef520 839 /* free saved data */
840 for (i = 0; i < q->vcnt; i++)
841 free(argv[i]);
842 free(argv);
73cf66ba 843 }
844
5eaef520 845 sq_destroy(sq);
846 return MR_SUCCESS;
73cf66ba 847}
848
1a9a0a59 849int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
850 int (*action)(int, char *[], void *), void *actarg,
851 client *cl)
852{
853 char **argv, *type;
854 int id, i, status;
855
856 while (sq_get_data(sq, &argv))
857 {
858 mr_trim_args(q->vcnt, argv);
859
860 id = atoi(argv[PRINTSERVER_OWNER_NAME]);
861 type = argv[PRINTSERVER_OWNER_TYPE];
862
863 if (!strcmp(type, "LIST"))
864 status = id_to_name(id, LIST_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
865 else if (!strcmp(type, "USER"))
866 status = id_to_name(id, USERS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
867 else if (!strcmp(type, "KERBEROS"))
868 status = id_to_name(id, STRINGS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
869 else
870 {
871 status = 0;
872 free(argv[PRINTSERVER_OWNER_NAME]);
873 argv[PRINTSERVER_OWNER_NAME] = xstrdup("NONE");
874 }
875 if (status && status != MR_NO_MATCH)
876 return status;
877 }
878
879 return followup_fix_modby(q, sq, v, action, actarg, cl);
880}
881
73cf66ba 882
883/* followup_gqot: Fix the entity name, directory name & modby fields
884 * argv[0] = filsys_id
885 * argv[1] = type
886 * argv[2] = entity_id
887 * argv[3] = ascii(quota)
888 */
889
5eaef520 890int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 891 int (*action)(int, char *[], void *), void *actarg,
892 client *cl)
73cf66ba 893{
44d12d58 894 int j;
5eaef520 895 char **argv;
896 EXEC SQL BEGIN DECLARE SECTION;
897 int id;
898 char *name, *label;
899 EXEC SQL END DECLARE SECTION;
900 int status, idx;
901
902 if (!strcmp(q->name, "get_quota") ||
903 !strcmp(q->name, "get_quota_by_filesys"))
904 idx = 4;
905 else
906 idx = 3;
907 while (sq_get_data(sq, &argv))
908 {
909 if (idx == 4)
910 {
911 switch (argv[1][0])
912 {
73cf66ba 913 case 'U':
5eaef520 914 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
915 break;
73cf66ba 916 case 'G':
917 case 'L':
5eaef520 918 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
919 break;
73cf66ba 920 case 'A':
5eaef520 921 free(argv[2]);
e688520a 922 argv[2] = xstrdup("system:anyuser");
5eaef520 923 break;
73cf66ba 924 default:
5eaef520 925 id = atoi(argv[2]);
e688520a 926 argv[2] = xmalloc(8);
5eaef520 927 sprintf(argv[2], "%d", id);
73cf66ba 928 }
929 }
5eaef520 930 id = atoi(argv[idx]);
931 free(argv[idx]);
e688520a 932 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
5eaef520 933 name = argv[idx];
e688520a 934 name[0] = '\0';
5eaef520 935 if (id == 0)
936 {
937 label = argv[0];
938 EXEC SQL SELECT name INTO :name FROM filesys
939 WHERE label = :label;
73cf66ba 940 }
5eaef520 941 else
942 {
943 EXEC SQL SELECT dir INTO :name FROM nfsphys
944 WHERE nfsphys_id = :id;
73cf66ba 945 }
5eaef520 946 if (sqlca.sqlerrd[2] != 1)
947 sprintf(argv[idx], "#%d", id);
948
949 id = atoi(argv[idx + 3]);
950 if (id > 0)
951 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
952 else
953 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
954 if (status && status != MR_NO_MATCH)
955 return status;
956 (*action)(q->vcnt, argv, actarg);
957 for (j = 0; j < q->vcnt; j++)
958 free(argv[j]);
959 free(argv);
73cf66ba 960 }
5eaef520 961 sq_destroy(sq);
962 return MR_SUCCESS;
73cf66ba 963}
964
965
966/* followup_aqot: Add allocation to nfsphys after creating quota.
967 * argv[0] = filsys_id
968 * argv[1] = type if "add_quota" or "update_quota"
969 * argv[2 or 1] = id
970 * argv[3 or 2] = ascii(quota)
971 */
972
5eaef520 973int followup_aqot(struct query *q, char *argv[], client *cl)
73cf66ba 974{
5eaef520 975 EXEC SQL BEGIN DECLARE SECTION;
976 int quota, id, fs, who, physid, table;
977 char *entity, *qtype, *tname;
978 EXEC SQL END DECLARE SECTION;
979 char incr_qual[60];
980 char *incr_argv[2];
981 int status;
982
983 table = q->rtable;
984 tname = table_name[table];
985 fs = *(int *)argv[0];
986 EXEC SQL SELECT phys_id INTO :physid FROM filesys
987 WHERE filsys_id = :fs;
988 if (dbms_errno)
989 return mr_errcode;
990
991 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
992 {
993 qtype = argv[1];
994 id = *(int *)argv[2];
995 quota = atoi(argv[3]);
996 sprintf(incr_qual, "q.filsys_id = %d", fs);
997 }
998 else
999 {
1000 qtype = "USER";
1001 id = *(int *)argv[1];
1002 quota = atoi(argv[2]);
1003 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
1004 "q.entity_id = %d", fs, qtype, id);
73cf66ba 1005 }
1006
5eaef520 1007 /* quota case of incremental_{before|after} only looks at slot 1 */
1008 incr_argv[1] = qtype;
1009
1010 /* Follows one of many possible gross hacks to fix these particular
1011 * conflicts between what is possible in the query table and what
1012 * is possible in SQL.
1013 */
1014 if (q->type == APPEND)
1015 {
1016 incremental_clear_before();
1017 EXEC SQL INSERT INTO quota
1018 (filsys_id, type, entity_id, quota, phys_id)
1019 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
1020 incremental_after(table, incr_qual, incr_argv);
1021 }
1022 else
1023 {
1024 incremental_before(table, incr_qual, incr_argv);
1025 EXEC SQL UPDATE quota SET quota = :quota
1026 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
1027 status = mr_errcode;
1028 incremental_after(table, incr_qual, incr_argv);
73cf66ba 1029 }
1030
5eaef520 1031 if (dbms_errno)
1032 return mr_errcode;
1033 flush_name(argv[0], table);
1034 if (q->type == APPEND)
1035 {
1036 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1037 WHERE table_name = :tname;
1038 }
1039 else
1040 {
1041 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1042 WHERE table_name = :tname;
73cf66ba 1043 }
5eaef520 1044
1045 /* Proceed with original followup */
1046 who = cl->client_id;
1047 entity = cl->entity;
1048
1049 EXEC SQL UPDATE quota
1050 SET modtime = SYSDATE, modby = :who, modwith = :entity
1051 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1052 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1053 WHERE nfsphys_id = :physid;
1054 if (dbms_errno)
1055 return mr_errcode;
1056 return MR_SUCCESS;
73cf66ba 1057}
1058
1059
1060/* Necessitated by the requirement of a correlation name by the incremental
5eaef520 1061 * routines, since query table deletes don't provide one.
73cf66ba 1062 */
5eaef520 1063int followup_dqot(struct query *q, char **argv, client *cl)
73cf66ba 1064{
5eaef520 1065 char *qtype;
1066 int id, fs, table;
1067 char *incr_argv[2];
1068 EXEC SQL BEGIN DECLARE SECTION;
1069 char incr_qual[80], *tname;
1070 EXEC SQL END DECLARE SECTION;
1071
1072 table = q->rtable;
1073 tname = table_name[table];
1074 fs = *(int *)argv[0];
1075 if (!strcmp(q->shortname, "dqot"))
1076 {
1077 qtype = argv[1];
1078 id = *(int *)argv[2];
1079 }
1080 else
1081 {
1082 qtype = "USER";
1083 id = *(int *)argv[1];
73cf66ba 1084 }
5eaef520 1085 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1086 fs, qtype, id);
73cf66ba 1087
5eaef520 1088 /* quota case of incremental_{before|after} only looks at slot 1 */
1089 incr_argv[1] = qtype;
73cf66ba 1090
5eaef520 1091 incremental_before(table, incr_qual, incr_argv);
1092 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1093 AND q.entity_id = :id;
1094 incremental_clear_after();
73cf66ba 1095
5eaef520 1096 if (dbms_errno)
1097 return mr_errcode;
1098 flush_name(argv[0], table);
73cf66ba 1099
5eaef520 1100 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1101 WHERE table_name = :tname;
1102 return MR_SUCCESS;
73cf66ba 1103}
1104
73cf66ba 1105/* followup_gzcl:
1106 */
1107
5eaef520 1108int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 1109 int (*action)(int, char *[], void *), void *actarg,
1110 client *cl)
73cf66ba 1111{
5eaef520 1112 int id, i, status;
1113 char **argv;
1114
1115 while (sq_get_data(sq, &argv))
1116 {
1117 mr_trim_args(q->vcnt, argv);
1118
1119 id = atoi(argv[i = q->vcnt - 2]);
1120 if (id > 0)
1121 status = id_to_name(id, USERS_TABLE, &argv[i]);
1122 else
1123 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1124 if (status && status != MR_NO_MATCH)
1125 return status;
1126
1127 for (i = 1; i < 8; i += 2)
1128 {
1129 id = atoi(argv[i + 1]);
1130 if (!strcmp(argv[i], "LIST"))
1131 status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1132 else if (!strcmp(argv[i], "USER"))
1133 status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1134 else if (!strcmp(argv[i], "KERBEROS"))
1135 status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1136 else if (!strcmp(argv[i], "NONE"))
1137 {
1138 status = 0;
1139 free(argv[i + 1]);
e688520a 1140 argv[i + 1] = xstrdup("NONE");
73cf66ba 1141 }
5eaef520 1142 else
1143 {
1144 status = 0;
1145 free(argv[i + 1]);
e688520a 1146 argv[i + 1] = xstrdup("???");
5eaef520 1147 }
1148 if (status && status != MR_NO_MATCH)
1149 return status;
73cf66ba 1150 }
1151
5eaef520 1152 /* send the data */
1153 (*action)(q->vcnt, argv, actarg);
73cf66ba 1154
5eaef520 1155 /* free saved data */
1156 for (i = 0; i < q->vcnt; i++)
1157 free(argv[i]);
1158 free(argv);
73cf66ba 1159 }
5eaef520 1160 sq_destroy(sq);
1161 return MR_SUCCESS;
73cf66ba 1162}
1163
1164
1165/* followup_gsha:
1166 */
1167
5eaef520 1168int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 1169 int (*action)(int, char *[], void *), void *actarg,
1170 client *cl)
73cf66ba 1171{
5eaef520 1172 char **argv;
1173 int i, id, status;
1174
1175 while (sq_get_data(sq, &argv))
1176 {
1177 mr_trim_args(q->vcnt, argv);
1178
1179 id = atoi(argv[4]);
1180 if (id > 0)
1181 status = id_to_name(id, USERS_TABLE, &argv[4]);
1182 else
1183 status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1184 if (status && status != MR_NO_MATCH)
1185 return status;
1186
1187 id = atoi(argv[2]);
1188 if (!strcmp(argv[1], "LIST"))
1189 status = id_to_name(id, LIST_TABLE, &argv[2]);
1190 else if (!strcmp(argv[1], "USER"))
1191 status = id_to_name(id, USERS_TABLE, &argv[2]);
1192 else if (!strcmp(argv[1], "KERBEROS"))
1193 status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1194 else if (!strcmp(argv[1], "NONE"))
1195 {
1196 status = 0;
1197 free(argv[2]);
e688520a 1198 argv[2] = xstrdup("NONE");
5eaef520 1199 }
1200 else
1201 {
1202 status = 0;
1203 free(argv[2]);
e688520a 1204 argv[2] = xstrdup("???");
73cf66ba 1205 }
5eaef520 1206 if (status && status != MR_NO_MATCH)
1207 return status;
73cf66ba 1208
5eaef520 1209 /* send the data */
1210 (*action)(q->vcnt, argv, actarg);
73cf66ba 1211
5eaef520 1212 /* free saved data */
1213 for (i = 0; i < q->vcnt; i++)
1214 free(argv[i]);
1215 free(argv);
73cf66ba 1216 }
5eaef520 1217 sq_destroy(sq);
1218 return MR_SUCCESS;
73cf66ba 1219}
1220
1221
5eaef520 1222int _sdl_followup(struct query *q, char *argv[], client *cl)
73cf66ba 1223{
85330553 1224 if (atoi(argv[0]))
5eaef520 1225 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1226 else
1227 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1228
1229 return MR_SUCCESS;
73cf66ba 1230}
1231
1232
85330553 1233int trigger_dcm(struct query *q, char *argv[], client *cl)
73cf66ba 1234{
85330553 1235 pid_t pid;
e688520a 1236 char prog[MAXPATHLEN];
85330553 1237
1238 sprintf(prog, "%s/startdcm", BIN_DIR);
1239 pid = vfork();
1240 switch (pid)
5eaef520 1241 {
85330553 1242 case 0:
1243 execl(prog, "startdcm", 0);
1244 exit(1);
1245
1246 case -1:
1247 return errno;
1248
73cf66ba 1249 default:
85330553 1250 return MR_SUCCESS;
73cf66ba 1251 }
1252}
This page took 0.261308 seconds and 5 git commands to generate.