]> andersk Git - moira.git/blame - server/qfollow.pc
Fix setting of mailroutingaddress.
[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>
7ac48069 20
73cf66ba 21EXEC SQL INCLUDE sqlca;
7ac48069 22
23RCSID("$Header$");
73cf66ba 24
03c05291 25extern char *whoami, *table_name[];
26extern int dbms_errno, mr_errcode;
73cf66ba 27
28EXEC SQL BEGIN DECLARE SECTION;
29extern char stmt_buf[];
30EXEC SQL END DECLARE SECTION;
31
03c05291 32EXEC SQL WHENEVER SQLERROR DO dbmserr();
73cf66ba 33
34
35/* FOLLOWUP ROUTINES */
36
03c05291 37/* generic set_modtime routine. This takes the table id from the query,
73cf66ba 38 * and will update the modtime, modby, and modwho fields in the entry in
39 * the table whose name field matches argv[0].
40 */
41
5eaef520 42int set_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 43{
5eaef520 44 char *name, *entity, *table;
45 int who;
73cf66ba 46
5eaef520 47 entity = cl->entity;
48 who = cl->client_id;
49 table = table_name[q->rtable];
50 name = argv[0];
73cf66ba 51
5eaef520 52 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
53 "modwith = '%s' WHERE name = '%s'", table, who, entity, name);
54 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
73cf66ba 55
5eaef520 56 return MR_SUCCESS;
73cf66ba 57}
58
03c05291 59/* generic set_modtime_by_id routine. This takes the table id from
73cf66ba 60 * the query, and the id name from the validate record,
61 * and will update the modtime, modby, and modwho fields in the entry in
62 * the table whose id matches argv[0].
63 */
64
5eaef520 65int set_modtime_by_id(struct query *q, char *argv[], client *cl)
73cf66ba 66{
5eaef520 67 char *entity, *table, *id_name;
68 int who, id;
69
70 entity = cl->entity;
71 who = cl->client_id;
72 table = table_name[q->rtable];
73 id_name = q->validate->object_id;
74
75 id = *(int *)argv[0];
76 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
77 "modwith = '%s' WHERE %s = %d", table, who, entity, id_name, id);
78 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
79 return MR_SUCCESS;
73cf66ba 80}
81
82
83/* Sets the finger modtime on a user record. The users_id will be in argv[0].
84 */
85
5eaef520 86int set_finger_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 87{
5eaef520 88 EXEC SQL BEGIN DECLARE SECTION;
89 int users_id, who;
90 char *entity;
91 EXEC SQL END DECLARE SECTION;
73cf66ba 92
5eaef520 93 entity = cl->entity;
94 who = cl->client_id;
95 users_id = *(int *)argv[0];
73cf66ba 96
5eaef520 97 EXEC SQL UPDATE users SET fmodtime = SYSDATE, fmodby = :who,
98 fmodwith = :entity WHERE users_id = :users_id;
73cf66ba 99
5eaef520 100 return MR_SUCCESS;
73cf66ba 101}
102
103
104/* Sets the pobox modtime on a user record. The users_id will be in argv[0].
105 */
106
5eaef520 107int set_pobox_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 108{
5eaef520 109 EXEC SQL BEGIN DECLARE SECTION;
110 int users_id, who;
111 char *entity;
112 EXEC SQL END DECLARE SECTION;
73cf66ba 113
5eaef520 114 entity = cl->entity;
115 who = cl->client_id;
116 users_id = *(int *)argv[0];
73cf66ba 117
5eaef520 118 EXEC SQL UPDATE users SET pmodtime = SYSDATE, pmodby = :who,
119 pmodwith = :entity WHERE users_id = :users_id;
73cf66ba 120
5eaef520 121 return MR_SUCCESS;
73cf66ba 122}
123
124
125/* Like set_modtime, but uppercases the name first.
126 */
127
5eaef520 128int set_uppercase_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 129{
5eaef520 130 char *name, *entity, *table;
131 int who;
73cf66ba 132
5eaef520 133 entity = cl->entity;
134 who = cl->client_id;
135 table = table_name[q->rtable];
136 name = argv[0];
73cf66ba 137
5eaef520 138 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
139 "modwith = '%s' WHERE name = UPPER('%s')", table, who, entity, name);
140 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
73cf66ba 141
5eaef520 142 return MR_SUCCESS;
73cf66ba 143}
144
145
146/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
147 * is necessary for add_machine_to_cluster becuase the table that query
148 * operates on is "mcm", not "machine".
149 */
150
5eaef520 151int set_mach_modtime_by_id(struct query *q, char *argv[], client *cl)
73cf66ba 152{
5eaef520 153 EXEC SQL BEGIN DECLARE SECTION;
154 char *entity;
155 int who, id;
156 EXEC SQL END DECLARE SECTION;
157
158 entity = cl->entity;
159 who = cl->client_id;
160 id = *(int *)argv[0];
161 EXEC SQL UPDATE machine SET modtime = SYSDATE, modby = :who,
162 modwith = :entity WHERE mach_id = :id;
163
164 return MR_SUCCESS;
73cf66ba 165}
166
167
168/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
169 * is necessary for add_cluster_data and delete_cluster_data becuase the
170 * table that query operates on is "svc", not "cluster".
171 */
172
5eaef520 173int set_cluster_modtime_by_id(struct query *q, char *argv[], client *cl)
73cf66ba 174{
5eaef520 175 EXEC SQL BEGIN DECLARE SECTION;
176 char *entity;
177 int who, id;
178 EXEC SQL END DECLARE SECTION;
179
180 entity = cl->entity;
181 who = cl->client_id;
182
183 id = *(int *)argv[0];
184 EXEC SQL UPDATE clusters SET modtime = SYSDATE, modby = :who,
185 modwith = :entity WHERE clu_id = :id;
186 return MR_SUCCESS;
73cf66ba 187}
188
189
190/* sets the modtime on the serverhost where the service name is in argv[0]
191 * and the mach_id is in argv[1].
192 */
193
5eaef520 194int set_serverhost_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 195{
5eaef520 196 EXEC SQL BEGIN DECLARE SECTION;
197 char *entity, *serv;
198 int who, id;
199 EXEC SQL END DECLARE SECTION;
200
201 entity = cl->entity;
202 who = cl->client_id;
203
204 serv = argv[0];
205 id = *(int *)argv[1];
206 EXEC SQL UPDATE serverhosts
207 SET modtime = SYSDATE, modby = :who, modwith = :entity
208 WHERE service = :serv AND mach_id = :id;
209 return MR_SUCCESS;
73cf66ba 210}
211
212
213/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
214 * directory name is in argv[1].
215 */
216
5eaef520 217int set_nfsphys_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 218{
5eaef520 219 EXEC SQL BEGIN DECLARE SECTION;
220 char *entity, *dir;
221 int who, id;
222 EXEC SQL END DECLARE SECTION;
223
224 entity = cl->entity;
225 who = cl->client_id;
226
227 id = *(int *)argv[0];
228 dir = argv[1];
229 EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who,
230 modwith = :entity WHERE dir = :dir AND mach_id = :id;
231 return MR_SUCCESS;
73cf66ba 232}
233
234
235/* sets the modtime on a filesystem, where argv[0] contains the filesys
236 * label.
237 */
238
5eaef520 239int set_filesys_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 240{
5eaef520 241 EXEC SQL BEGIN DECLARE SECTION;
242 char *label, *entity;
243 int who;
244 extern int _var_phys_id;
245 EXEC SQL END DECLARE SECTION;
246
247 entity = cl->entity;
248 who = cl->client_id;
249
250 label = argv[0];
251 if (!strcmp(q->shortname, "ufil"))
252 label = argv[1];
253
254 EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who,
255 modwith = :entity, phys_id = :_var_phys_id
256 WHERE label = :label;
257 return MR_SUCCESS;
73cf66ba 258}
259
260
261/* sets the modtime on a zephyr class, where argv[0] contains the class
262 * name.
263 */
264
5eaef520 265int set_zephyr_modtime(struct query *q, char *argv[], client *cl)
73cf66ba 266{
5eaef520 267 EXEC SQL BEGIN DECLARE SECTION;
268 char *class, *entity;
269 int who;
270 EXEC SQL END DECLARE SECTION;
73cf66ba 271
5eaef520 272 entity = cl->entity;
273 who = cl->client_id;
73cf66ba 274
5eaef520 275 class = argv[0];
73cf66ba 276
5eaef520 277 EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who,
278 modwith = :entity WHERE class = :class;
73cf66ba 279
5eaef520 280 return MR_SUCCESS;
73cf66ba 281}
282
69eb9470 283/* sets the modtime on an entry in services table, where argv[0] contains
284 * the service name.
285 */
286
287int set_service_modtime(struct query *q, char *argv[], client *cl)
288{
289 EXEC SQL BEGIN DECLARE SECTION;
290 char *service, *protocol, *entity;
291 int who;
292 EXEC SQL END DECLARE SECTION;
293
294 entity = cl->entity;
295 who = cl->client_id;
296
297 service = argv[0];
298 protocol = argv[1];
299
300 EXEC SQL UPDATE services SET modtime = SYSDATE, modby = :who,
301 modwith = :entity WHERE name = :service AND protocol = :protocol;
302
303 return MR_SUCCESS;
304}
73cf66ba 305
306/* fixes the modby field. This will be the second to last thing in the
307 * argv, the argv length is determined from the query structure. It is
308 * passed as a pointer to an integer. This will either turn it into a
309 * username, or # + the users_id.
310 */
5eaef520 311int followup_fix_modby(struct query *q, struct save_queue *sq,
7ac48069 312 struct validate *v, int (*action)(int, char *[], void *),
313 void *actarg, client *cl)
73cf66ba 314{
44d12d58 315 int i, j;
5eaef520 316 char **argv;
317 int id, status;
318
319 i = q->vcnt - 2;
320 while (sq_get_data(sq, &argv))
321 {
322 id = atoi(argv[i]);
323 if (id > 0)
324 status = id_to_name(id, USERS_TABLE, &argv[i]);
325 else
326 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
327 if (status && status != MR_NO_MATCH)
328 return status;
329 (*action)(q->vcnt, argv, actarg);
330 for (j = 0; j < q->vcnt; j++)
331 free(argv[j]);
332 free(argv);
73cf66ba 333 }
5eaef520 334 sq_destroy(sq);
335 return MR_SUCCESS;
73cf66ba 336}
337
73cf66ba 338/**
339 ** followup_ausr - add finger and pobox entries, set_user_modtime
340 **
341 ** Inputs:
342 ** argv[0] - login (add_user)
186dd63b 343 ** argv[U_LAST] - last name
344 ** argv[U_FIRST] - first name
345 ** argv[U_MIDDLE] - middle name
73cf66ba 346 **
347 **/
348
5eaef520 349int followup_ausr(struct query *q, char *argv[], client *cl)
73cf66ba 350{
5eaef520 351 EXEC SQL BEGIN DECLARE SECTION;
352 int who, status;
353 char *login, *entity, *name;
e688520a 354 char fullname[USERS_FIRST_SIZE + USERS_MIDDLE_SIZE + USERS_LAST_SIZE];
5eaef520 355 EXEC SQL END DECLARE SECTION;
73cf66ba 356
5eaef520 357 /* build fullname */
186dd63b 358 if (strlen(argv[U_FIRST]) && strlen(argv[U_MIDDLE]))
359 sprintf(fullname, "%s %s %s", argv[U_FIRST], argv[U_MIDDLE],
360 argv[U_LAST]);
361 else if (strlen(argv[U_FIRST]))
362 sprintf(fullname, "%s %s", argv[U_FIRST], argv[U_LAST]);
5eaef520 363 else
186dd63b 364 sprintf(fullname, "%s", argv[U_LAST]);
73cf66ba 365
5eaef520 366 login = argv[0];
367 who = cl->client_id;
368 entity = cl->entity;
73cf66ba 369
5eaef520 370 /* create finger entry, pobox & set modtime on user */
5eaef520 371 EXEC SQL UPDATE users
372 SET modtime = SYSDATE, modby = :who, modwith = :entity,
373 fullname = NVL(:fullname, CHR(0)), affiliation = type,
374 fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
375 potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
376 WHERE login = :login;
5eaef520 377
5eaef520 378 return MR_SUCCESS;
73cf66ba 379}
5eaef520 380
d6d830a1 381/* followup_gpob: fixes argv[2] and argv[3] based on the pobox type.
382 * Then completes the upcall to the user.
73cf66ba 383 *
d6d830a1 384 * argv[2] is the users_id on input and should be converted to the
385 * pobox name on output. argv[3] is empty on input and should be
386 * converted to an email address on output.
73cf66ba 387 */
388
5eaef520 389int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 390 int (*action)(int, char *[], void *), void *actarg,
391 client *cl)
73cf66ba 392{
5eaef520 393 char **argv;
394 char *ptype, *p;
395 int mid, sid, status, i;
d6d830a1 396 EXEC SQL BEGIN DECLARE SECTION;
22bbb6f0 397 int users_id, pid, iid, bid, eid;
d6d830a1 398 char mach[MACHINE_NAME_SIZE], fs[FILESYS_LABEL_SIZE];
399 char str[STRINGS_STRING_SIZE];
400 EXEC SQL END DECLARE SECTION;
5eaef520 401
402 /* for each row */
403 while (sq_get_data(sq, &argv))
404 {
d6d830a1 405 mr_trim_args(4, argv);
5eaef520 406 ptype = argv[1];
d6d830a1 407 users_id = atoi(argv[2]);
5eaef520 408
02cf90a4 409 EXEC SQL SELECT pop_id, imap_id, box_id, exchange_id INTO :pid, :iid, :bid, :eid
450849e9 410 FROM users WHERE users_id = :users_id;
411 if (sqlca.sqlcode)
412 return MR_USER;
413
414 if (ptype[0] == 'S')
415 {
416 /* SMTP or SPLIT */
417 EXEC SQL SELECT string INTO :str FROM strings
418 WHERE string_id = :bid;
419 if (sqlca.sqlcode)
420 return MR_STRING;
421
422 /* If SMTP, don't bother fetching IMAP and POP boxes. */
423 if (ptype[1] == 'M')
22bbb6f0 424 pid = iid = eid = 0;
450849e9 425 }
426 if (iid)
5eaef520 427 {
450849e9 428 /* IMAP, or SPLIT with IMAP */
429 EXEC SQL SELECT f.label, m.name INTO :fs, :mach
430 FROM filesys f, machine m
431 WHERE f.filsys_id = :iid AND f.mach_id = m.mach_id;
432 if (sqlca.sqlcode)
433 return MR_FILESYS;
434 }
435 if (pid)
436 {
437 /* POP, or SPLIT with POP */
d6d830a1 438 EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
439 WHERE u.users_id = :users_id AND u.pop_id = m.mach_id;
440 if (sqlca.sqlcode)
5eaef520 441 return MR_MACHINE;
450849e9 442 }
22bbb6f0 443 if (eid)
444 {
445 /* EXCHANGE, or SPLIT with EXCHANGE */
446 EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
447 WHERE u.users_id = :users_id AND u.exchange_id = m.mach_id;
448 if (sqlca.sqlcode)
449 return MR_MACHINE;
450 }
450849e9 451
452 free(argv[2]);
453 free(argv[3]);
454
455 /* Now assemble the right answer. */
22bbb6f0 456 if (!strcmp(ptype, "POP") || !strcmp(ptype, "EXCHANGE"))
450849e9 457 {
d6d830a1 458 argv[2] = xstrdup(strtrim(mach));
d6d830a1 459 argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
460 sprintf(argv[3], "%s@%s", argv[0], argv[2]);
5eaef520 461 }
462 else if (!strcmp(ptype, "SMTP"))
463 {
d6d830a1 464 argv[2] = xstrdup(strtrim(str));
465 argv[3] = xstrdup(str);
73cf66ba 466 }
f76b37f2 467 else if (!strcmp(ptype, "IMAP"))
468 {
d6d830a1 469 argv[2] = xstrdup(strtrim(fs));
d6d830a1 470 argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
471 sprintf(argv[3], "%s@%s", argv[0], mach);
f76b37f2 472 }
450849e9 473 else if (!strcmp(ptype, "SPLIT"))
474 {
475 argv[2] = xstrdup(strtrim(str));
476 argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) +
477 strlen(str) + 4);
478 sprintf(argv[3], "%s@%s, %s", argv[0], mach, str);
479 }
5eaef520 480 else /* ptype == "NONE" */
481 goto skip;
5eaef520 482
483 if (!strcmp(q->shortname, "gpob"))
484 {
d6d830a1 485 sid = atoi(argv[5]);
5eaef520 486 if (sid > 0)
d6d830a1 487 status = id_to_name(sid, USERS_TABLE, &argv[5]);
5eaef520 488 else
d6d830a1 489 status = id_to_name(-sid, STRINGS_TABLE, &argv[5]);
490 if (status && status != MR_NO_MATCH)
491 return status;
73cf66ba 492 }
73cf66ba 493
5eaef520 494 (*action)(q->vcnt, argv, actarg);
73cf66ba 495 skip:
5eaef520 496 /* free saved data */
497 for (i = 0; i < q->vcnt; i++)
498 free(argv[i]);
499 free(argv);
73cf66ba 500 }
501
5eaef520 502 sq_destroy(sq);
503 return MR_SUCCESS;
73cf66ba 504}
505
b121cf1b 506/* Fix an ace_name, based on its type. */
507
508static int fix_ace(char *type, char **name)
509{
510 int id = atoi(*name);
511
512 if (!strcmp(type, "LIST"))
513 return id_to_name(id, LIST_TABLE, name);
514 else if (!strcmp(type, "USER"))
515 return id_to_name(id, USERS_TABLE, name);
516 else if (!strcmp(type, "KERBEROS"))
517 return id_to_name(id, STRINGS_TABLE, name);
518 else
519 {
520 free(*name);
521 if (!strcmp(type, "NONE"))
522 *name = xstrdup("NONE");
523 else
524 *name = xstrdup("???");
525 return MR_SUCCESS;
526 }
527}
73cf66ba 528
b121cf1b 529
530/* followup_gsnt: fix the ace_name and modby */
73cf66ba 531
5eaef520 532int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 533 int (*action)(int, char *[], void *), void *actarg,
534 client *cl)
73cf66ba 535{
b121cf1b 536 char **argv;
4f6b1a05 537 int status, idx;
538
539 if (q->version < 8)
540 idx = 0;
541 else
542 idx = 3;
5eaef520 543
544 while (sq_get_data(sq, &argv))
545 {
546 mr_trim_args(q->vcnt, argv);
547
4f6b1a05 548 status = fix_ace(argv[7 + idx], &argv[8 + idx]);
5eaef520 549 if (status && status != MR_NO_MATCH)
550 return status;
fde7313c 551 }
552
b121cf1b 553 return followup_fix_modby(q, sq, v, action, actarg, cl);
fde7313c 554}
555
556
b121cf1b 557/* followup_ghst: fix the ace_name, strings and modby */
fde7313c 558
5eaef520 559int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 560 int (*action)(int, char *[], void *), void *actarg,
561 client *cl)
fde7313c 562{
b121cf1b 563 char **argv;
e4ae0190 564 int id, status, idx;
565
566 if (q->version < 6)
567 idx = 0;
4f6b1a05 568 else if (q->version >= 6 && q->version < 8)
e4ae0190 569 idx = 1;
4f6b1a05 570 else
571 idx = 2;
5eaef520 572
573 while (sq_get_data(sq, &argv))
574 {
575 mr_trim_args(q->vcnt, argv);
576
e4ae0190 577 id = atoi(argv[13 + idx]);
578 status = id_to_name(id, STRINGS_TABLE, &argv[13 + idx]);
5eaef520 579 if (status)
580 return status;
e4ae0190 581 id = atoi(argv[14 + idx]);
582 status = id_to_name(id, STRINGS_TABLE, &argv[14 + idx]);
5eaef520 583 if (status)
584 return status;
e4ae0190 585 id = atoi(argv[16 + idx]);
5eaef520 586 if (id < 0)
e4ae0190 587 status = id_to_name(-id, STRINGS_TABLE, &argv[16 + idx]);
5eaef520 588 else
e4ae0190 589 status = id_to_name(id, USERS_TABLE, &argv[16 + idx]);
5eaef520 590 if (status && status != MR_NO_MATCH)
591 return status;
592
e4ae0190 593 status = fix_ace(argv[11 + idx], &argv[12 + idx]);
5eaef520 594 if (status && status != MR_NO_MATCH)
595 return status;
73cf66ba 596 }
597
b121cf1b 598 return followup_fix_modby(q, sq, v, action, actarg, cl);
73cf66ba 599}
600
601
b121cf1b 602/* followup_glin: fix the ace_name, modace_name, expiration, and modby */
73cf66ba 603
5eaef520 604int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 605 int (*action)(int, char *[], void *), void *actarg,
606 client *cl)
73cf66ba 607{
b121cf1b 608 char **argv;
59c3208b 609 int status;
5eaef520 610
611 while (sq_get_data(sq, &argv))
612 {
613 mr_trim_args(q->vcnt, argv);
614
59c3208b 615 if (q->version == 2)
616 status = fix_ace(argv[7], &argv[8]);
8e3761a2 617 else if (q->version > 2 && q->version < 10)
59c3208b 618 status = fix_ace(argv[8], &argv[9]);
8e3761a2 619 else
620 status = fix_ace(argv[10], &argv[11]);
621
622 if (status && status != MR_NO_MATCH)
623 return status;
624
672173f4 625 if (q->version > 3)
626 {
627 if (q->version < 10)
628 status = fix_ace(argv[10], &argv[11]);
629 else if (q->version >= 10)
630 status = fix_ace(argv[12], &argv[13]);
8e3761a2 631
672173f4 632 if (status && status != MR_NO_MATCH)
633 return status;
634 }
73cf66ba 635
59c3208b 636 if (atoi(argv[6]) == -1)
5eaef520 637 {
e688520a 638 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
5eaef520 639 strcpy(argv[6], UNIQUE_GID);
73cf66ba 640 }
73cf66ba 641 }
642
b121cf1b 643 return followup_fix_modby(q, sq, v, action, actarg, cl);
73cf66ba 644}
645
59c3208b 646/* followup_gsin: fix the ace_name and modby. */
647int followup_gsin(struct query *q, struct save_queue *sq, struct validate *v,
648 int (*action)(int, char *[], void *), void *actarg,
649 client *cl)
650{
651 char **argv;
652 int status;
653
654 while (sq_get_data(sq, &argv))
655 {
656 mr_trim_args(q->vcnt, argv);
657
658 status = fix_ace(argv[11], &argv[12]);
659 if (status && status != MR_NO_MATCH)
660 return status;
661 }
662
663 return followup_fix_modby(q, sq, v, action, actarg, cl);
664}
665
1a9a0a59 666int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
667 int (*action)(int, char *[], void *), void *actarg,
668 client *cl)
669{
b121cf1b 670 char **argv;
671 int status;
1a9a0a59 672
673 while (sq_get_data(sq, &argv))
674 {
675 mr_trim_args(q->vcnt, argv);
676
b121cf1b 677 status = fix_ace(argv[PRINTSERVER_OWNER_TYPE],
678 &argv[PRINTSERVER_OWNER_NAME]);
1a9a0a59 679 if (status && status != MR_NO_MATCH)
680 return status;
681 }
682
683 return followup_fix_modby(q, sq, v, action, actarg, cl);
684}
685
73cf66ba 686
687/* followup_gqot: Fix the entity name, directory name & modby fields
688 * argv[0] = filsys_id
689 * argv[1] = type
690 * argv[2] = entity_id
691 * argv[3] = ascii(quota)
692 */
693
5eaef520 694int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 695 int (*action)(int, char *[], void *), void *actarg,
696 client *cl)
73cf66ba 697{
44d12d58 698 int j;
5eaef520 699 char **argv;
700 EXEC SQL BEGIN DECLARE SECTION;
701 int id;
702 char *name, *label;
703 EXEC SQL END DECLARE SECTION;
704 int status, idx;
705
706 if (!strcmp(q->name, "get_quota") ||
707 !strcmp(q->name, "get_quota_by_filesys"))
708 idx = 4;
709 else
710 idx = 3;
b121cf1b 711
5eaef520 712 while (sq_get_data(sq, &argv))
713 {
714 if (idx == 4)
715 {
716 switch (argv[1][0])
717 {
73cf66ba 718 case 'U':
5eaef520 719 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
720 break;
73cf66ba 721 case 'G':
722 case 'L':
5eaef520 723 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
724 break;
73cf66ba 725 case 'A':
5eaef520 726 free(argv[2]);
e688520a 727 argv[2] = xstrdup("system:anyuser");
5eaef520 728 break;
73cf66ba 729 default:
5eaef520 730 id = atoi(argv[2]);
e688520a 731 argv[2] = xmalloc(8);
5eaef520 732 sprintf(argv[2], "%d", id);
73cf66ba 733 }
734 }
5eaef520 735 id = atoi(argv[idx]);
736 free(argv[idx]);
e688520a 737 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
5eaef520 738 name = argv[idx];
e688520a 739 name[0] = '\0';
5eaef520 740 if (id == 0)
741 {
742 label = argv[0];
743 EXEC SQL SELECT name INTO :name FROM filesys
744 WHERE label = :label;
73cf66ba 745 }
5eaef520 746 else
747 {
748 EXEC SQL SELECT dir INTO :name FROM nfsphys
749 WHERE nfsphys_id = :id;
73cf66ba 750 }
5eaef520 751 if (sqlca.sqlerrd[2] != 1)
752 sprintf(argv[idx], "#%d", id);
753
754 id = atoi(argv[idx + 3]);
755 if (id > 0)
756 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
757 else
758 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
759 if (status && status != MR_NO_MATCH)
760 return status;
761 (*action)(q->vcnt, argv, actarg);
762 for (j = 0; j < q->vcnt; j++)
763 free(argv[j]);
764 free(argv);
73cf66ba 765 }
5eaef520 766 sq_destroy(sq);
767 return MR_SUCCESS;
73cf66ba 768}
769
770
771/* followup_aqot: Add allocation to nfsphys after creating quota.
772 * argv[0] = filsys_id
773 * argv[1] = type if "add_quota" or "update_quota"
774 * argv[2 or 1] = id
775 * argv[3 or 2] = ascii(quota)
776 */
777
5eaef520 778int followup_aqot(struct query *q, char *argv[], client *cl)
73cf66ba 779{
5eaef520 780 EXEC SQL BEGIN DECLARE SECTION;
781 int quota, id, fs, who, physid, table;
782 char *entity, *qtype, *tname;
783 EXEC SQL END DECLARE SECTION;
784 char incr_qual[60];
785 char *incr_argv[2];
786 int status;
787
788 table = q->rtable;
789 tname = table_name[table];
790 fs = *(int *)argv[0];
791 EXEC SQL SELECT phys_id INTO :physid FROM filesys
792 WHERE filsys_id = :fs;
793 if (dbms_errno)
794 return mr_errcode;
795
796 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
797 {
798 qtype = argv[1];
799 id = *(int *)argv[2];
800 quota = atoi(argv[3]);
801 sprintf(incr_qual, "q.filsys_id = %d", fs);
802 }
803 else
804 {
805 qtype = "USER";
806 id = *(int *)argv[1];
807 quota = atoi(argv[2]);
808 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
809 "q.entity_id = %d", fs, qtype, id);
73cf66ba 810 }
811
5eaef520 812 /* quota case of incremental_{before|after} only looks at slot 1 */
813 incr_argv[1] = qtype;
814
815 /* Follows one of many possible gross hacks to fix these particular
816 * conflicts between what is possible in the query table and what
817 * is possible in SQL.
818 */
b9f9ab1c 819 if (q->type == MR_Q_APPEND)
5eaef520 820 {
821 incremental_clear_before();
822 EXEC SQL INSERT INTO quota
823 (filsys_id, type, entity_id, quota, phys_id)
824 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
825 incremental_after(table, incr_qual, incr_argv);
826 }
827 else
828 {
829 incremental_before(table, incr_qual, incr_argv);
830 EXEC SQL UPDATE quota SET quota = :quota
831 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
832 status = mr_errcode;
833 incremental_after(table, incr_qual, incr_argv);
73cf66ba 834 }
835
5eaef520 836 if (dbms_errno)
837 return mr_errcode;
b9f9ab1c 838 if (q->type == MR_Q_APPEND)
5eaef520 839 {
840 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
841 WHERE table_name = :tname;
842 }
843 else
844 {
845 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
846 WHERE table_name = :tname;
73cf66ba 847 }
5eaef520 848
849 /* Proceed with original followup */
850 who = cl->client_id;
851 entity = cl->entity;
852
853 EXEC SQL UPDATE quota
854 SET modtime = SYSDATE, modby = :who, modwith = :entity
855 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
856 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
857 WHERE nfsphys_id = :physid;
858 if (dbms_errno)
859 return mr_errcode;
860 return MR_SUCCESS;
73cf66ba 861}
862
863
864/* Necessitated by the requirement of a correlation name by the incremental
5eaef520 865 * routines, since query table deletes don't provide one.
73cf66ba 866 */
5eaef520 867int followup_dqot(struct query *q, char **argv, client *cl)
73cf66ba 868{
5eaef520 869 char *qtype;
870 int id, fs, table;
871 char *incr_argv[2];
872 EXEC SQL BEGIN DECLARE SECTION;
873 char incr_qual[80], *tname;
874 EXEC SQL END DECLARE SECTION;
875
876 table = q->rtable;
877 tname = table_name[table];
878 fs = *(int *)argv[0];
879 if (!strcmp(q->shortname, "dqot"))
880 {
881 qtype = argv[1];
882 id = *(int *)argv[2];
883 }
884 else
885 {
886 qtype = "USER";
887 id = *(int *)argv[1];
73cf66ba 888 }
5eaef520 889 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
890 fs, qtype, id);
73cf66ba 891
5eaef520 892 /* quota case of incremental_{before|after} only looks at slot 1 */
893 incr_argv[1] = qtype;
73cf66ba 894
5eaef520 895 incremental_before(table, incr_qual, incr_argv);
896 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
897 AND q.entity_id = :id;
898 incremental_clear_after();
73cf66ba 899
5eaef520 900 if (dbms_errno)
901 return mr_errcode;
73cf66ba 902
5eaef520 903 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
904 WHERE table_name = :tname;
905 return MR_SUCCESS;
73cf66ba 906}
907
73cf66ba 908/* followup_gzcl:
909 */
910
5eaef520 911int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 912 int (*action)(int, char *[], void *), void *actarg,
913 client *cl)
73cf66ba 914{
d7ddc011 915 int i, n, status;
5eaef520 916 char **argv;
917
d7ddc011 918 if (q->version < 5)
919 n = 8;
920 else
921 n = 10;
922
5eaef520 923 while (sq_get_data(sq, &argv))
924 {
925 mr_trim_args(q->vcnt, argv);
926
d7ddc011 927 for (i = 1; i < n; i += 2)
5eaef520 928 {
b121cf1b 929 status = fix_ace(argv[i], &argv[i + 1]);
5eaef520 930 if (status && status != MR_NO_MATCH)
931 return status;
73cf66ba 932 }
73cf66ba 933 }
b121cf1b 934
935 return followup_fix_modby(q, sq, v, action, actarg, cl);
73cf66ba 936}
937
938
939/* followup_gsha:
940 */
941
5eaef520 942int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
7ac48069 943 int (*action)(int, char *[], void *), void *actarg,
944 client *cl)
73cf66ba 945{
5eaef520 946 char **argv;
b121cf1b 947 int status;
5eaef520 948
949 while (sq_get_data(sq, &argv))
950 {
951 mr_trim_args(q->vcnt, argv);
952
b121cf1b 953 status = fix_ace(argv[1], &argv[2]);
5eaef520 954 if (status && status != MR_NO_MATCH)
955 return status;
73cf66ba 956 }
b121cf1b 957
958 return followup_fix_modby(q, sq, v, action, actarg, cl);
73cf66ba 959}
960
961
5eaef520 962int _sdl_followup(struct query *q, char *argv[], client *cl)
73cf66ba 963{
85330553 964 if (atoi(argv[0]))
5eaef520 965 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
966 else
967 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
968
969 return MR_SUCCESS;
73cf66ba 970}
971
972
85330553 973int trigger_dcm(struct query *q, char *argv[], client *cl)
73cf66ba 974{
85330553 975 pid_t pid;
e688520a 976 char prog[MAXPATHLEN];
85330553 977
978 sprintf(prog, "%s/startdcm", BIN_DIR);
979 pid = vfork();
980 switch (pid)
5eaef520 981 {
85330553 982 case 0:
983 execl(prog, "startdcm", 0);
984 exit(1);
985
986 case -1:
987 return errno;
988
73cf66ba 989 default:
85330553 990 return MR_SUCCESS;
73cf66ba 991 }
992}
2fb668b0 993
994/* followup_gcon: fix the ace_name, memace_name, and modby */
995
996int followup_gcon(struct query *q, struct save_queue *sq, struct validate *v,
997 int (*action)(int, char *[], void *), void *actarg,
998 client *cl)
999{
1000 char **argv;
73155abd 1001 int status, idx = 0;
1002
1003 if (q->version >= 9)
1004 idx = 1;
2fb668b0 1005
1006 while (sq_get_data(sq, &argv))
1007 {
1008 mr_trim_args(q->vcnt, argv);
1009
73155abd 1010 status = fix_ace(argv[4 + idx], &argv[5 + idx]);
2fb668b0 1011 if (status && status != MR_NO_MATCH)
1012 return status;
1013
73155abd 1014 status = fix_ace(argv[6 + idx], &argv[7 + idx]);
2fb668b0 1015 if (status && status != MR_NO_MATCH)
1016 return status;
1017 }
1018
1019 return followup_fix_modby(q, sq, v, action, actarg, cl);
1020}
1021
3b634eb3 1022/* followup_get_user: fix the modby and creator.
1023 * This assumes that the modby and creator fields are always
1024 * in the same relative position in the argv.
1025 */
1026
1027int followup_get_user(struct query *q, struct save_queue *sq, struct
1028 validate *v, int (*action)(int, char *[], void *),
1029 void *actarg, client *cl)
1030{
1031 char **argv;
1032 int i, j, k, status, id;
1033
1034 i = q->vcnt - 4;
1035 j = q->vcnt - 1;
1036 while (sq_get_data(sq, &argv))
1037 {
1038 mr_trim_args(q->vcnt, argv);
1039
1040 id = atoi(argv[i]);
1041 if (id > 0)
1042 status = id_to_name(id, USERS_TABLE, &argv[i]);
1043 else
1044 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1045 if (status && status != MR_NO_MATCH)
1046 return status;
1047
1048 id = atoi(argv[j]);
1049 if (id > 0)
1050 status = id_to_name(id, USERS_TABLE, &argv[j]);
1051 else
1052 status = id_to_name(-id, STRINGS_TABLE, &argv[j]);
1053 if (status && status != MR_NO_MATCH)
1054 return status;
1055
7902e669 1056 if (q->version > 11)
1057 {
1058 status = fix_ace(argv[15], &argv[16]);
1059 if (status && status != MR_NO_MATCH)
1060 return status;
1061 }
1062
3b634eb3 1063 (*action)(q->vcnt, argv, actarg);
1064 for (k = 0; k < q->vcnt; k++)
1065 free(argv[k]);
1066 free(argv);
1067 }
1068 sq_destroy(sq);
1069 return MR_SUCCESS;
1070}
This page took 0.255941 seconds and 5 git commands to generate.