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