]>
Commit | Line | Data |
---|---|---|
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 | 21 | EXEC SQL INCLUDE sqlca; |
7ac48069 | 22 | |
23 | RCSID("$Header$"); | |
73cf66ba | 24 | |
03c05291 | 25 | extern char *whoami, *table_name[]; |
26 | extern int dbms_errno, mr_errcode; | |
73cf66ba | 27 | |
28 | EXEC SQL BEGIN DECLARE SECTION; | |
29 | extern char stmt_buf[]; | |
30 | EXEC SQL END DECLARE SECTION; | |
31 | ||
03c05291 | 32 | EXEC 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 | 42 | int 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 | 65 | int 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 | 86 | int 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 | 107 | int 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 | 128 | int 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 | 151 | int 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 | 173 | int 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 | 194 | int 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 | 217 | int 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 | 239 | int 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 | 265 | int 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 | ||
287 | int 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 | 311 | int 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 | 349 | int 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 | 389 | int 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; |
450849e9 | 397 | int users_id, pid, iid, bid; |
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 | |
450849e9 | 409 | EXEC SQL SELECT pop_id, imap_id, box_id INTO :pid, :iid, :bid |
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') | |
424 | pid = iid = 0; | |
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 | } |
443 | ||
444 | free(argv[2]); | |
445 | free(argv[3]); | |
446 | ||
447 | /* Now assemble the right answer. */ | |
448 | if (!strcmp(ptype, "POP")) | |
449 | { | |
d6d830a1 | 450 | argv[2] = xstrdup(strtrim(mach)); |
d6d830a1 | 451 | argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2); |
452 | sprintf(argv[3], "%s@%s", argv[0], argv[2]); | |
5eaef520 | 453 | } |
454 | else if (!strcmp(ptype, "SMTP")) | |
455 | { | |
d6d830a1 | 456 | argv[2] = xstrdup(strtrim(str)); |
457 | argv[3] = xstrdup(str); | |
73cf66ba | 458 | } |
f76b37f2 | 459 | else if (!strcmp(ptype, "IMAP")) |
460 | { | |
d6d830a1 | 461 | argv[2] = xstrdup(strtrim(fs)); |
d6d830a1 | 462 | argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2); |
463 | sprintf(argv[3], "%s@%s", argv[0], mach); | |
f76b37f2 | 464 | } |
450849e9 | 465 | else if (!strcmp(ptype, "SPLIT")) |
466 | { | |
467 | argv[2] = xstrdup(strtrim(str)); | |
468 | argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + | |
469 | strlen(str) + 4); | |
470 | sprintf(argv[3], "%s@%s, %s", argv[0], mach, str); | |
471 | } | |
5eaef520 | 472 | else /* ptype == "NONE" */ |
473 | goto skip; | |
5eaef520 | 474 | |
475 | if (!strcmp(q->shortname, "gpob")) | |
476 | { | |
d6d830a1 | 477 | sid = atoi(argv[5]); |
5eaef520 | 478 | if (sid > 0) |
d6d830a1 | 479 | status = id_to_name(sid, USERS_TABLE, &argv[5]); |
5eaef520 | 480 | else |
d6d830a1 | 481 | status = id_to_name(-sid, STRINGS_TABLE, &argv[5]); |
482 | if (status && status != MR_NO_MATCH) | |
483 | return status; | |
73cf66ba | 484 | } |
73cf66ba | 485 | |
5eaef520 | 486 | (*action)(q->vcnt, argv, actarg); |
73cf66ba | 487 | skip: |
5eaef520 | 488 | /* free saved data */ |
489 | for (i = 0; i < q->vcnt; i++) | |
490 | free(argv[i]); | |
491 | free(argv); | |
73cf66ba | 492 | } |
493 | ||
5eaef520 | 494 | sq_destroy(sq); |
495 | return MR_SUCCESS; | |
73cf66ba | 496 | } |
497 | ||
b121cf1b | 498 | /* Fix an ace_name, based on its type. */ |
499 | ||
500 | static int fix_ace(char *type, char **name) | |
501 | { | |
502 | int id = atoi(*name); | |
503 | ||
504 | if (!strcmp(type, "LIST")) | |
505 | return id_to_name(id, LIST_TABLE, name); | |
506 | else if (!strcmp(type, "USER")) | |
507 | return id_to_name(id, USERS_TABLE, name); | |
508 | else if (!strcmp(type, "KERBEROS")) | |
509 | return id_to_name(id, STRINGS_TABLE, name); | |
510 | else | |
511 | { | |
512 | free(*name); | |
513 | if (!strcmp(type, "NONE")) | |
514 | *name = xstrdup("NONE"); | |
515 | else | |
516 | *name = xstrdup("???"); | |
517 | return MR_SUCCESS; | |
518 | } | |
519 | } | |
73cf66ba | 520 | |
b121cf1b | 521 | |
522 | /* followup_gsnt: fix the ace_name and modby */ | |
73cf66ba | 523 | |
5eaef520 | 524 | int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 525 | int (*action)(int, char *[], void *), void *actarg, |
526 | client *cl) | |
73cf66ba | 527 | { |
b121cf1b | 528 | char **argv; |
4f6b1a05 | 529 | int status, idx; |
530 | ||
531 | if (q->version < 8) | |
532 | idx = 0; | |
533 | else | |
534 | idx = 3; | |
5eaef520 | 535 | |
536 | while (sq_get_data(sq, &argv)) | |
537 | { | |
538 | mr_trim_args(q->vcnt, argv); | |
539 | ||
4f6b1a05 | 540 | status = fix_ace(argv[7 + idx], &argv[8 + idx]); |
5eaef520 | 541 | if (status && status != MR_NO_MATCH) |
542 | return status; | |
fde7313c | 543 | } |
544 | ||
b121cf1b | 545 | return followup_fix_modby(q, sq, v, action, actarg, cl); |
fde7313c | 546 | } |
547 | ||
548 | ||
b121cf1b | 549 | /* followup_ghst: fix the ace_name, strings and modby */ |
fde7313c | 550 | |
5eaef520 | 551 | int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 552 | int (*action)(int, char *[], void *), void *actarg, |
553 | client *cl) | |
fde7313c | 554 | { |
b121cf1b | 555 | char **argv; |
e4ae0190 | 556 | int id, status, idx; |
557 | ||
558 | if (q->version < 6) | |
559 | idx = 0; | |
4f6b1a05 | 560 | else if (q->version >= 6 && q->version < 8) |
e4ae0190 | 561 | idx = 1; |
4f6b1a05 | 562 | else |
563 | idx = 2; | |
5eaef520 | 564 | |
565 | while (sq_get_data(sq, &argv)) | |
566 | { | |
567 | mr_trim_args(q->vcnt, argv); | |
568 | ||
e4ae0190 | 569 | id = atoi(argv[13 + idx]); |
570 | status = id_to_name(id, STRINGS_TABLE, &argv[13 + idx]); | |
5eaef520 | 571 | if (status) |
572 | return status; | |
e4ae0190 | 573 | id = atoi(argv[14 + idx]); |
574 | status = id_to_name(id, STRINGS_TABLE, &argv[14 + idx]); | |
5eaef520 | 575 | if (status) |
576 | return status; | |
e4ae0190 | 577 | id = atoi(argv[16 + idx]); |
5eaef520 | 578 | if (id < 0) |
e4ae0190 | 579 | status = id_to_name(-id, STRINGS_TABLE, &argv[16 + idx]); |
5eaef520 | 580 | else |
e4ae0190 | 581 | status = id_to_name(id, USERS_TABLE, &argv[16 + idx]); |
5eaef520 | 582 | if (status && status != MR_NO_MATCH) |
583 | return status; | |
584 | ||
e4ae0190 | 585 | status = fix_ace(argv[11 + idx], &argv[12 + idx]); |
5eaef520 | 586 | if (status && status != MR_NO_MATCH) |
587 | return status; | |
73cf66ba | 588 | } |
589 | ||
b121cf1b | 590 | return followup_fix_modby(q, sq, v, action, actarg, cl); |
73cf66ba | 591 | } |
592 | ||
593 | ||
b121cf1b | 594 | /* followup_glin: fix the ace_name, modace_name, expiration, and modby */ |
73cf66ba | 595 | |
5eaef520 | 596 | int followup_glin(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 597 | int (*action)(int, char *[], void *), void *actarg, |
598 | client *cl) | |
73cf66ba | 599 | { |
b121cf1b | 600 | char **argv; |
59c3208b | 601 | int status; |
5eaef520 | 602 | |
603 | while (sq_get_data(sq, &argv)) | |
604 | { | |
605 | mr_trim_args(q->vcnt, argv); | |
606 | ||
59c3208b | 607 | if (q->version == 2) |
608 | status = fix_ace(argv[7], &argv[8]); | |
8e3761a2 | 609 | else if (q->version > 2 && q->version < 10) |
59c3208b | 610 | status = fix_ace(argv[8], &argv[9]); |
8e3761a2 | 611 | else |
612 | status = fix_ace(argv[10], &argv[11]); | |
613 | ||
614 | if (status && status != MR_NO_MATCH) | |
615 | return status; | |
616 | ||
672173f4 | 617 | if (q->version > 3) |
618 | { | |
619 | if (q->version < 10) | |
620 | status = fix_ace(argv[10], &argv[11]); | |
621 | else if (q->version >= 10) | |
622 | status = fix_ace(argv[12], &argv[13]); | |
8e3761a2 | 623 | |
672173f4 | 624 | if (status && status != MR_NO_MATCH) |
625 | return status; | |
626 | } | |
73cf66ba | 627 | |
59c3208b | 628 | if (atoi(argv[6]) == -1) |
5eaef520 | 629 | { |
e688520a | 630 | argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1); |
5eaef520 | 631 | strcpy(argv[6], UNIQUE_GID); |
73cf66ba | 632 | } |
73cf66ba | 633 | } |
634 | ||
b121cf1b | 635 | return followup_fix_modby(q, sq, v, action, actarg, cl); |
73cf66ba | 636 | } |
637 | ||
59c3208b | 638 | /* followup_gsin: fix the ace_name and modby. */ |
639 | int followup_gsin(struct query *q, struct save_queue *sq, struct validate *v, | |
640 | int (*action)(int, char *[], void *), void *actarg, | |
641 | client *cl) | |
642 | { | |
643 | char **argv; | |
644 | int status; | |
645 | ||
646 | while (sq_get_data(sq, &argv)) | |
647 | { | |
648 | mr_trim_args(q->vcnt, argv); | |
649 | ||
650 | status = fix_ace(argv[11], &argv[12]); | |
651 | if (status && status != MR_NO_MATCH) | |
652 | return status; | |
653 | } | |
654 | ||
655 | return followup_fix_modby(q, sq, v, action, actarg, cl); | |
656 | } | |
657 | ||
1a9a0a59 | 658 | int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v, |
659 | int (*action)(int, char *[], void *), void *actarg, | |
660 | client *cl) | |
661 | { | |
b121cf1b | 662 | char **argv; |
663 | int status; | |
1a9a0a59 | 664 | |
665 | while (sq_get_data(sq, &argv)) | |
666 | { | |
667 | mr_trim_args(q->vcnt, argv); | |
668 | ||
b121cf1b | 669 | status = fix_ace(argv[PRINTSERVER_OWNER_TYPE], |
670 | &argv[PRINTSERVER_OWNER_NAME]); | |
1a9a0a59 | 671 | if (status && status != MR_NO_MATCH) |
672 | return status; | |
673 | } | |
674 | ||
675 | return followup_fix_modby(q, sq, v, action, actarg, cl); | |
676 | } | |
677 | ||
73cf66ba | 678 | |
679 | /* followup_gqot: Fix the entity name, directory name & modby fields | |
680 | * argv[0] = filsys_id | |
681 | * argv[1] = type | |
682 | * argv[2] = entity_id | |
683 | * argv[3] = ascii(quota) | |
684 | */ | |
685 | ||
5eaef520 | 686 | int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 687 | int (*action)(int, char *[], void *), void *actarg, |
688 | client *cl) | |
73cf66ba | 689 | { |
44d12d58 | 690 | int j; |
5eaef520 | 691 | char **argv; |
692 | EXEC SQL BEGIN DECLARE SECTION; | |
693 | int id; | |
694 | char *name, *label; | |
695 | EXEC SQL END DECLARE SECTION; | |
696 | int status, idx; | |
697 | ||
698 | if (!strcmp(q->name, "get_quota") || | |
699 | !strcmp(q->name, "get_quota_by_filesys")) | |
700 | idx = 4; | |
701 | else | |
702 | idx = 3; | |
b121cf1b | 703 | |
5eaef520 | 704 | while (sq_get_data(sq, &argv)) |
705 | { | |
706 | if (idx == 4) | |
707 | { | |
708 | switch (argv[1][0]) | |
709 | { | |
73cf66ba | 710 | case 'U': |
5eaef520 | 711 | status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]); |
712 | break; | |
73cf66ba | 713 | case 'G': |
714 | case 'L': | |
5eaef520 | 715 | status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]); |
716 | break; | |
73cf66ba | 717 | case 'A': |
5eaef520 | 718 | free(argv[2]); |
e688520a | 719 | argv[2] = xstrdup("system:anyuser"); |
5eaef520 | 720 | break; |
73cf66ba | 721 | default: |
5eaef520 | 722 | id = atoi(argv[2]); |
e688520a | 723 | argv[2] = xmalloc(8); |
5eaef520 | 724 | sprintf(argv[2], "%d", id); |
73cf66ba | 725 | } |
726 | } | |
5eaef520 | 727 | id = atoi(argv[idx]); |
728 | free(argv[idx]); | |
e688520a | 729 | argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE); |
5eaef520 | 730 | name = argv[idx]; |
e688520a | 731 | name[0] = '\0'; |
5eaef520 | 732 | if (id == 0) |
733 | { | |
734 | label = argv[0]; | |
735 | EXEC SQL SELECT name INTO :name FROM filesys | |
736 | WHERE label = :label; | |
73cf66ba | 737 | } |
5eaef520 | 738 | else |
739 | { | |
740 | EXEC SQL SELECT dir INTO :name FROM nfsphys | |
741 | WHERE nfsphys_id = :id; | |
73cf66ba | 742 | } |
5eaef520 | 743 | if (sqlca.sqlerrd[2] != 1) |
744 | sprintf(argv[idx], "#%d", id); | |
745 | ||
746 | id = atoi(argv[idx + 3]); | |
747 | if (id > 0) | |
748 | status = id_to_name(id, USERS_TABLE, &argv[idx + 3]); | |
749 | else | |
750 | status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]); | |
751 | if (status && status != MR_NO_MATCH) | |
752 | return status; | |
753 | (*action)(q->vcnt, argv, actarg); | |
754 | for (j = 0; j < q->vcnt; j++) | |
755 | free(argv[j]); | |
756 | free(argv); | |
73cf66ba | 757 | } |
5eaef520 | 758 | sq_destroy(sq); |
759 | return MR_SUCCESS; | |
73cf66ba | 760 | } |
761 | ||
762 | ||
763 | /* followup_aqot: Add allocation to nfsphys after creating quota. | |
764 | * argv[0] = filsys_id | |
765 | * argv[1] = type if "add_quota" or "update_quota" | |
766 | * argv[2 or 1] = id | |
767 | * argv[3 or 2] = ascii(quota) | |
768 | */ | |
769 | ||
5eaef520 | 770 | int followup_aqot(struct query *q, char *argv[], client *cl) |
73cf66ba | 771 | { |
5eaef520 | 772 | EXEC SQL BEGIN DECLARE SECTION; |
773 | int quota, id, fs, who, physid, table; | |
774 | char *entity, *qtype, *tname; | |
775 | EXEC SQL END DECLARE SECTION; | |
776 | char incr_qual[60]; | |
777 | char *incr_argv[2]; | |
778 | int status; | |
779 | ||
780 | table = q->rtable; | |
781 | tname = table_name[table]; | |
782 | fs = *(int *)argv[0]; | |
783 | EXEC SQL SELECT phys_id INTO :physid FROM filesys | |
784 | WHERE filsys_id = :fs; | |
785 | if (dbms_errno) | |
786 | return mr_errcode; | |
787 | ||
788 | if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot")) | |
789 | { | |
790 | qtype = argv[1]; | |
791 | id = *(int *)argv[2]; | |
792 | quota = atoi(argv[3]); | |
793 | sprintf(incr_qual, "q.filsys_id = %d", fs); | |
794 | } | |
795 | else | |
796 | { | |
797 | qtype = "USER"; | |
798 | id = *(int *)argv[1]; | |
799 | quota = atoi(argv[2]); | |
800 | sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND " | |
801 | "q.entity_id = %d", fs, qtype, id); | |
73cf66ba | 802 | } |
803 | ||
5eaef520 | 804 | /* quota case of incremental_{before|after} only looks at slot 1 */ |
805 | incr_argv[1] = qtype; | |
806 | ||
807 | /* Follows one of many possible gross hacks to fix these particular | |
808 | * conflicts between what is possible in the query table and what | |
809 | * is possible in SQL. | |
810 | */ | |
811 | if (q->type == APPEND) | |
812 | { | |
813 | incremental_clear_before(); | |
814 | EXEC SQL INSERT INTO quota | |
815 | (filsys_id, type, entity_id, quota, phys_id) | |
816 | VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid); | |
817 | incremental_after(table, incr_qual, incr_argv); | |
818 | } | |
819 | else | |
820 | { | |
821 | incremental_before(table, incr_qual, incr_argv); | |
822 | EXEC SQL UPDATE quota SET quota = :quota | |
823 | WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id; | |
824 | status = mr_errcode; | |
825 | incremental_after(table, incr_qual, incr_argv); | |
73cf66ba | 826 | } |
827 | ||
5eaef520 | 828 | if (dbms_errno) |
829 | return mr_errcode; | |
5eaef520 | 830 | if (q->type == APPEND) |
831 | { | |
832 | EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE | |
833 | WHERE table_name = :tname; | |
834 | } | |
835 | else | |
836 | { | |
837 | EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE | |
838 | WHERE table_name = :tname; | |
73cf66ba | 839 | } |
5eaef520 | 840 | |
841 | /* Proceed with original followup */ | |
842 | who = cl->client_id; | |
843 | entity = cl->entity; | |
844 | ||
845 | EXEC SQL UPDATE quota | |
846 | SET modtime = SYSDATE, modby = :who, modwith = :entity | |
847 | WHERE filsys_id = :fs and type = :qtype and entity_id = :id; | |
848 | EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota | |
849 | WHERE nfsphys_id = :physid; | |
850 | if (dbms_errno) | |
851 | return mr_errcode; | |
852 | return MR_SUCCESS; | |
73cf66ba | 853 | } |
854 | ||
855 | ||
856 | /* Necessitated by the requirement of a correlation name by the incremental | |
5eaef520 | 857 | * routines, since query table deletes don't provide one. |
73cf66ba | 858 | */ |
5eaef520 | 859 | int followup_dqot(struct query *q, char **argv, client *cl) |
73cf66ba | 860 | { |
5eaef520 | 861 | char *qtype; |
862 | int id, fs, table; | |
863 | char *incr_argv[2]; | |
864 | EXEC SQL BEGIN DECLARE SECTION; | |
865 | char incr_qual[80], *tname; | |
866 | EXEC SQL END DECLARE SECTION; | |
867 | ||
868 | table = q->rtable; | |
869 | tname = table_name[table]; | |
870 | fs = *(int *)argv[0]; | |
871 | if (!strcmp(q->shortname, "dqot")) | |
872 | { | |
873 | qtype = argv[1]; | |
874 | id = *(int *)argv[2]; | |
875 | } | |
876 | else | |
877 | { | |
878 | qtype = "USER"; | |
879 | id = *(int *)argv[1]; | |
73cf66ba | 880 | } |
5eaef520 | 881 | sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d", |
882 | fs, qtype, id); | |
73cf66ba | 883 | |
5eaef520 | 884 | /* quota case of incremental_{before|after} only looks at slot 1 */ |
885 | incr_argv[1] = qtype; | |
73cf66ba | 886 | |
5eaef520 | 887 | incremental_before(table, incr_qual, incr_argv); |
888 | EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype | |
889 | AND q.entity_id = :id; | |
890 | incremental_clear_after(); | |
73cf66ba | 891 | |
5eaef520 | 892 | if (dbms_errno) |
893 | return mr_errcode; | |
73cf66ba | 894 | |
5eaef520 | 895 | EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE |
896 | WHERE table_name = :tname; | |
897 | return MR_SUCCESS; | |
73cf66ba | 898 | } |
899 | ||
73cf66ba | 900 | /* followup_gzcl: |
901 | */ | |
902 | ||
5eaef520 | 903 | int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 904 | int (*action)(int, char *[], void *), void *actarg, |
905 | client *cl) | |
73cf66ba | 906 | { |
d7ddc011 | 907 | int i, n, status; |
5eaef520 | 908 | char **argv; |
909 | ||
d7ddc011 | 910 | if (q->version < 5) |
911 | n = 8; | |
912 | else | |
913 | n = 10; | |
914 | ||
5eaef520 | 915 | while (sq_get_data(sq, &argv)) |
916 | { | |
917 | mr_trim_args(q->vcnt, argv); | |
918 | ||
d7ddc011 | 919 | for (i = 1; i < n; i += 2) |
5eaef520 | 920 | { |
b121cf1b | 921 | status = fix_ace(argv[i], &argv[i + 1]); |
5eaef520 | 922 | if (status && status != MR_NO_MATCH) |
923 | return status; | |
73cf66ba | 924 | } |
73cf66ba | 925 | } |
b121cf1b | 926 | |
927 | return followup_fix_modby(q, sq, v, action, actarg, cl); | |
73cf66ba | 928 | } |
929 | ||
930 | ||
931 | /* followup_gsha: | |
932 | */ | |
933 | ||
5eaef520 | 934 | int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 935 | int (*action)(int, char *[], void *), void *actarg, |
936 | client *cl) | |
73cf66ba | 937 | { |
5eaef520 | 938 | char **argv; |
b121cf1b | 939 | int status; |
5eaef520 | 940 | |
941 | while (sq_get_data(sq, &argv)) | |
942 | { | |
943 | mr_trim_args(q->vcnt, argv); | |
944 | ||
b121cf1b | 945 | status = fix_ace(argv[1], &argv[2]); |
5eaef520 | 946 | if (status && status != MR_NO_MATCH) |
947 | return status; | |
73cf66ba | 948 | } |
b121cf1b | 949 | |
950 | return followup_fix_modby(q, sq, v, action, actarg, cl); | |
73cf66ba | 951 | } |
952 | ||
953 | ||
5eaef520 | 954 | int _sdl_followup(struct query *q, char *argv[], client *cl) |
73cf66ba | 955 | { |
85330553 | 956 | if (atoi(argv[0])) |
5eaef520 | 957 | EXEC SQL ALTER SESSION SET SQL_TRACE TRUE; |
958 | else | |
959 | EXEC SQL ALTER SESSION SET SQL_TRACE FALSE; | |
960 | ||
961 | return MR_SUCCESS; | |
73cf66ba | 962 | } |
963 | ||
964 | ||
85330553 | 965 | int trigger_dcm(struct query *q, char *argv[], client *cl) |
73cf66ba | 966 | { |
85330553 | 967 | pid_t pid; |
e688520a | 968 | char prog[MAXPATHLEN]; |
85330553 | 969 | |
970 | sprintf(prog, "%s/startdcm", BIN_DIR); | |
971 | pid = vfork(); | |
972 | switch (pid) | |
5eaef520 | 973 | { |
85330553 | 974 | case 0: |
975 | execl(prog, "startdcm", 0); | |
976 | exit(1); | |
977 | ||
978 | case -1: | |
979 | return errno; | |
980 | ||
73cf66ba | 981 | default: |
85330553 | 982 | return MR_SUCCESS; |
73cf66ba | 983 | } |
984 | } | |
2fb668b0 | 985 | |
986 | /* followup_gcon: fix the ace_name, memace_name, and modby */ | |
987 | ||
988 | int followup_gcon(struct query *q, struct save_queue *sq, struct validate *v, | |
989 | int (*action)(int, char *[], void *), void *actarg, | |
990 | client *cl) | |
991 | { | |
992 | char **argv; | |
73155abd | 993 | int status, idx = 0; |
994 | ||
995 | if (q->version >= 9) | |
996 | idx = 1; | |
2fb668b0 | 997 | |
998 | while (sq_get_data(sq, &argv)) | |
999 | { | |
1000 | mr_trim_args(q->vcnt, argv); | |
1001 | ||
73155abd | 1002 | status = fix_ace(argv[4 + idx], &argv[5 + idx]); |
2fb668b0 | 1003 | if (status && status != MR_NO_MATCH) |
1004 | return status; | |
1005 | ||
73155abd | 1006 | status = fix_ace(argv[6 + idx], &argv[7 + idx]); |
2fb668b0 | 1007 | if (status && status != MR_NO_MATCH) |
1008 | return status; | |
1009 | } | |
1010 | ||
1011 | return followup_fix_modby(q, sq, v, action, actarg, cl); | |
1012 | } | |
1013 | ||
3b634eb3 | 1014 | /* followup_get_user: fix the modby and creator. |
1015 | * This assumes that the modby and creator fields are always | |
1016 | * in the same relative position in the argv. | |
1017 | */ | |
1018 | ||
1019 | int followup_get_user(struct query *q, struct save_queue *sq, struct | |
1020 | validate *v, int (*action)(int, char *[], void *), | |
1021 | void *actarg, client *cl) | |
1022 | { | |
1023 | char **argv; | |
1024 | int i, j, k, status, id; | |
1025 | ||
1026 | i = q->vcnt - 4; | |
1027 | j = q->vcnt - 1; | |
1028 | while (sq_get_data(sq, &argv)) | |
1029 | { | |
1030 | mr_trim_args(q->vcnt, argv); | |
1031 | ||
1032 | id = atoi(argv[i]); | |
1033 | if (id > 0) | |
1034 | status = id_to_name(id, USERS_TABLE, &argv[i]); | |
1035 | else | |
1036 | status = id_to_name(-id, STRINGS_TABLE, &argv[i]); | |
1037 | if (status && status != MR_NO_MATCH) | |
1038 | return status; | |
1039 | ||
1040 | id = atoi(argv[j]); | |
1041 | if (id > 0) | |
1042 | status = id_to_name(id, USERS_TABLE, &argv[j]); | |
1043 | else | |
1044 | status = id_to_name(-id, STRINGS_TABLE, &argv[j]); | |
1045 | if (status && status != MR_NO_MATCH) | |
1046 | return status; | |
1047 | ||
1048 | (*action)(q->vcnt, argv, actarg); | |
1049 | for (k = 0; k < q->vcnt; k++) | |
1050 | free(argv[k]); | |
1051 | free(argv); | |
1052 | } | |
1053 | sq_destroy(sq); | |
1054 | return MR_SUCCESS; | |
1055 | } | |
1056 | ||
1057 | ||
1058 | ||
1059 |