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