6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
7 * For copying and distribution information, please see the file
13 static char *rcsid_qsupport_dc = "$Header$";
16 #include <mit-copyright.h>
18 #include "mr_server.h"
23 EXEC SQL INCLUDE sqlca;
24 EXEC SQL INCLUDE sqlda;
27 extern char *whoami, *strsave();
28 extern int ingres_errno, mr_errcode;
30 EXEC SQL BEGIN DECLARE SECTION;
31 extern char stmt_buf[];
32 EXEC SQL END DECLARE SECTION;
34 EXEC SQL WHENEVER SQLERROR CALL ingerr;
39 /* Setup routine for add_user
41 * Inputs: argv[0] - login
46 * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid)
47 * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
50 setup_ausr(q, argv, cl)
52 register char *argv[];
56 EXEC SQL BEGIN DECLARE SECTION;
58 EXEC SQL END DECLARE SECTION;
60 if (!strcmp(q->shortname, "uusr") || !strcmp(q->shortname, "uuac"))
64 if (!strcmp(argv[row], UNIQUE_UID) || atoi(argv[row]) == -1) {
65 if (set_next_object_id("uid", "users", 1))
66 return(MR_INGRES_ERR);
67 EXEC SQL SELECT value INTO :nuid FROM numvalues WHERE name = 'uid';
68 if (sqlca.sqlerrd[2] != 1)
70 sprintf(argv[row], "%d", nuid);
73 if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[row]) == -1) {
74 sprintf(argv[0], "#%s", argv[row]);
77 if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
84 /* setup_dusr - verify that the user is no longer being referenced
85 * and may safely be deleted.
88 int setup_dusr(q, argv)
92 EXEC SQL BEGIN DECLARE SECTION;
94 EXEC SQL END DECLARE SECTION;
98 /* For now, only allow users to be deleted if their status is 0 */
99 EXEC SQL REPEATED SELECT status INTO :flag FROM users
100 WHERE users_id = :id;
101 if (flag != 0 && flag != 4)
104 EXEC SQL REPEATED DELETE FROM quota WHERE entity_id = :id AND type='USER';
105 EXEC SQL REPEATED DELETE FROM krbmap WHERE users_id = :id;
106 EXEC SQL REPEATED SELECT COUNT(member_id) INTO :cnt FROM imembers
107 WHERE member_id = :id AND member_type = 'USER';
110 EXEC SQL REPEATED SELECT COUNT(label) INTO :cnt FROM filesys
114 EXEC SQL REPEATED SELECT COUNT(name) INTO :cnt FROM list
115 WHERE acl_id = :id AND acl_type = 'USER';
118 EXEC SQL REPEATED SELECT COUNT(name) INTO :cnt FROM servers
119 WHERE acl_id = :id AND acl_type = 'USER';
122 EXEC SQL REPEATED SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
123 WHERE acl_id = :id AND acl_type = 'USER';
132 /* setup_spop: verify that there is already a valid POP machine_id in the
133 * pop_id field. Also take care of keeping track of the post office usage.
135 int setup_spop(q, argv)
139 EXEC SQL BEGIN DECLARE SECTION;
142 EXEC SQL END DECLARE SECTION;
144 id = *(int *)argv[0];
145 EXEC SQL REPEATED SELECT potype, pop_id INTO :type, :mid FROM users
146 WHERE users_id = :id;
147 if(sqlca.sqlerrd[2] = 0)
149 EXEC SQL REPEATED SELECT mach_id INTO :mid FROM machine
150 WHERE mach_id = :mid;
151 if (sqlca.sqlerrd[2] = 0)
153 if (strcmp(strtrim(type), "POP"))
154 set_pop_usage(mid, 1);
159 /* setup_dpob: Take care of keeping track of the post office usage.
161 int setup_dpob(q, argv)
165 EXEC SQL BEGIN DECLARE SECTION;
168 EXEC SQL END DECLARE SECTION;
170 user = *(int *)argv[0];
171 EXEC SQL REPEATED SELECT potype, pop_id INTO :type, :id FROM users
172 WHERE users_id = :user;
173 if (ingres_errno) return(mr_errcode);
175 if (!strcmp(strtrim(type), "POP"))
176 set_pop_usage(id, -1);
181 /* setup_dmac - verify that the machine is no longer being referenced
182 * and may safely be deleted.
185 int setup_dmac(q, argv)
189 EXEC SQL BEGIN DECLARE SECTION;
191 EXEC SQL END DECLARE SECTION;
193 id = *(int *)argv[0];
195 EXEC SQL REPEATED SELECT status INTO :flag FROM machine
199 EXEC SQL REPEATED SELECT COUNT(login) INTO :cnt FROM users
200 WHERE potype='POP' AND pop_id = :id;
203 EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM serverhosts
207 EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM nfsphys
211 EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM hostaccess
215 EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM printcap
219 EXEC SQL REPEATED SELECT COUNT(quotaserver) INTO :cnt FROM printcap
220 WHERE quotaserver = :id;
223 EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM palladium
228 EXEC SQL REPEATED DELETE FROM mcmap WHERE mach_id = :id;
229 if (ingres_errno) return(mr_errcode);
234 /* setup_dsnt - verify that the subnet is no longer being referenced
235 * and may safely be deleted.
238 int setup_dsnt(q, argv)
242 EXEC SQL BEGIN DECLARE SECTION;
243 int flag, id, cnt = 0;
244 EXEC SQL END DECLARE SECTION;
246 id = *(int *)argv[0];
247 EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM machine
255 /* setup_dclu - verify that the cluster is no longer being referenced
256 * and may safely be deleted.
259 int setup_dclu(q, argv)
263 EXEC SQL BEGIN DECLARE SECTION;
265 EXEC SQL END DECLARE SECTION;
267 id = *(int *)argv[0];
268 EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM mcmap
272 EXEC SQL REPEATED SELECT COUNT(clu_id) INTO :cnt FROM svc
282 /* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate
283 * a new gid and put it in argv[6]. Otherwise if argv[6] is UNIQUE_ID but
284 * argv[5] is not, then remember that UNIQUE_ID is being stored by putting
285 * a -1 there. Remember that this is also used for ulis, with the indexes
286 * at 6 & 7. Also check that the list name does not contain uppercase
287 * characters, control characters, @, or :.
290 static int badlistchars[] = {
291 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
292 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
293 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
294 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
295 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
296 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, /* P - _ */
297 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
299 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
300 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
301 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
302 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
303 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
304 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
305 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
306 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
309 int setup_alis(q, argv, cl)
314 EXEC SQL BEGIN DECLARE SECTION;
316 EXEC SQL END DECLARE SECTION;
320 if (!strcmp(q->shortname, "alis"))
322 else if (!strcmp(q->shortname, "ulis"))
325 for (p = (unsigned char *) argv[idx]; *p; p++)
326 if (badlistchars[*p])
329 if (!strcmp(argv[6 + idx], UNIQUE_GID) || atoi(argv[6 + idx]) == -1) {
330 if (atoi(argv[5 + idx])) {
331 if (set_next_object_id("gid", "list", 1))
332 return(MR_INGRES_ERR);
333 EXEC SQL REPEATED SELECT value INTO :ngid FROM numvalues
335 if (ingres_errno) return(mr_errcode);
336 sprintf(argv[6 + idx], "%d", ngid);
338 strcpy(argv[6 + idx], "-1");
342 if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
349 /* setup_dlis - verify that the list is no longer being referenced
350 * and may safely be deleted.
353 int setup_dlis(q, argv)
359 id = *(int *)argv[0];
360 sprintf(stmt_buf,"SELECT member_id FROM imembers WHERE member_id = %d AND member_type='LIST'",id);
361 if(ec=mr_select_any(stmt_buf)) {
362 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
365 sprintf(stmt_buf,"SELECT member_id FROM imembers WHERE list_id = %d",id);
366 if(ec=mr_select_any(stmt_buf)) {
367 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
370 sprintf(stmt_buf,"SELECT label FROM filesys WHERE owners = %d",id);
371 if(ec=mr_select_any(stmt_buf)) {
372 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
375 sprintf(stmt_buf,"SELECT tag FROM capacls WHERE list_id = %d",id);
376 if(ec=mr_select_any(stmt_buf)) {
377 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
380 sprintf(stmt_buf,"SELECT name FROM list WHERE acl_id = %d AND acl_type='LIST' AND list_id != %d",id,id);
381 if(ec=mr_select_any(stmt_buf)) {
382 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
385 sprintf(stmt_buf,"SELECT name FROM servers WHERE acl_id = %d AND acl_type='LIST'",id);
386 if(ec=mr_select_any(stmt_buf)) {
387 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
390 sprintf(stmt_buf,"SELECT entity_id FROM quota WHERE entity_id = %d AND type='GROUP'",id);
391 if(ec=mr_select_any(stmt_buf)) {
392 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
395 sprintf(stmt_buf,"SELECT acl_id FROM hostaccess WHERE acl_id = %d AND acl_type='LIST'",id);
396 if(ec=mr_select_any(stmt_buf)) {
397 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
400 sprintf(stmt_buf,"SELECT class FROM zephyr z \
401 WHERE z.xmt_type = 'LIST' AND z.xmt_id = %d \
402 OR z.sub_type = 'LIST' AND z.sub_id = %d \
403 OR z.iws_type = 'LIST' AND z.iws_id = %d \
404 OR z.iui_type = 'LIST' AND z.iui_id = %d",id,id,id,id);
405 if(ec=mr_select_any(stmt_buf)) {
406 if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
413 /* setup_dsin - verify that the service is no longer being referenced
414 * and may safely be deleted.
417 int setup_dsin(q, argv)
421 EXEC SQL BEGIN DECLARE SECTION;
424 EXEC SQL END DECLARE SECTION;
426 sprintf(stmt_buf,"SELECT service FROM serverhosts WHERE service = UPPERCASE('%s')",argv[0]);
427 if(ec=mr_select_any(stmt_buf)) {
435 EXEC SQL SELECT inprogress INTO :ec FROM servers
436 WHERE name=UPPERCASE(:svrname);
446 /* setup_dshi - verify that the service-host is no longer being referenced
447 * and may safely be deleted.
450 int setup_dshi(q, argv)
454 EXEC SQL BEGIN DECLARE SECTION;
457 EXEC SQL END DECLARE SECTION;
460 id = *(int *)argv[1];
462 EXEC SQL SELECT inprogress INTO :ec FROM serverhosts
463 WHERE service=UPPERCASE(:svrname) AND mach_id = :id;
475 ** setup_add_filesys - verify existance of referenced file systems
487 ** * extract directory prefix from name
488 ** * verify mach_id/dir in nfsphys
489 ** * verify access in {r, w, R, W}
491 ** Side effect: sets variable _var_phys_id to the ID of the physical
492 ** filesystem (nfsphys_id for NFS, 0 for RVD)
495 ** MR_NFS - specified directory not exported
496 ** MR_FILESYS_ACCESS - invalid filesys access
500 EXEC SQL BEGIN DECLARE SECTION;
502 EXEC SQL END DECLARE SECTION;
504 setup_afil(q, argv, cl)
511 EXEC SQL BEGIN DECLARE SECTION;
513 char ftype[32], *access;
514 EXEC SQL END DECLARE SECTION;
517 mach_id = *(int *)argv[2];
522 sprintf(ftype, "fs_access_%s", type);
523 EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
524 WHERE name = :ftype AND type = 'TYPE' and trans = :access;
525 if (ingres_errno) return(mr_errcode);
526 if (ok == 0) return(MR_FILESYS_ACCESS);
528 if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
531 if (!strcmp(type, "NFS"))
532 return (check_nfs(mach_id, name, access));
538 /* Verify the arguments, depending on the FStype. Also, if this is an
539 * NFS filesystem, then update any quotas for that filesystem to reflect
543 setup_ufil(q, argv, cl)
550 EXEC SQL BEGIN DECLARE SECTION;
551 int fid, total, who, ok;
552 char *entity, ftype[32], *access;
553 short int total_null;
554 EXEC SQL END DECLARE SECTION;
558 mach_id = *(int *)argv[3];
561 fid = *(int *)argv[0];
565 sprintf(ftype, "fs_access_%s", type);
566 EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
567 WHERE name = :ftype AND type='TYPE' AND trans = :access;
568 if (ingres_errno) return(mr_errcode);
569 if (ok == 0) return(MR_FILESYS_ACCESS);
571 EXEC SQL SELECT type INTO :ftype FROM filesys
572 WHERE filsys_id = :fid;
574 if (ingres_errno) return(mr_errcode);
576 if (!strcmp(type, "NFS")) {
577 status = check_nfs(mach_id, name, access);
578 EXEC SQL UPDATE quota SET phys_id = :_var_phys_id
579 WHERE filsys_id = :fid;
580 if (ingres_errno) return(mr_errcode);
582 } else if (!strcmp(type, "AFS") && strcmp(ftype, "AFS")) {
584 EXEC SQL REPEATED DELETE FROM quota
585 WHERE type = 'ANY' AND filsys_id = :fid;
586 EXEC SQL SELECT SUM (quota) INTO :total:total_null FROM quota
587 WHERE filsys_id = :fid AND phys_id != 0;
588 if (ingres_errno) return(mr_errcode);
589 if (!total_null && (total != 0)) {
591 * append quota (quota = total, filsys_id = fid,
592 * phys_id = 0, entity_id = 0, type = "ANY",
593 * modtime = "now", modby = who, modwith = entity)
595 EXEC SQL INSERT INTO quota (quota, filsys_id, phys_id, entity_id,
596 type, modtime, modby, modwith)
597 VALUES (:total, :fid, 0, 0,
598 'ANY', 'now', :who, :entity) ;
599 if (ingres_errno) return(mr_errcode);
602 EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid;
603 if (ingres_errno) return(mr_errcode);
609 /* Find the NFS physical partition that the named directory is on.
610 * This is done by comparing the dir against the mount point of the
611 * partition. To make sure we get the correct match when there is
612 * more than one, we sort the query in reverse order by dir name.
615 check_nfs(mach_id, name, access)
616 EXEC SQL BEGIN DECLARE SECTION;
618 EXEC SQL END DECLARE SECTION;
622 EXEC SQL BEGIN DECLARE SECTION;
624 EXEC SQL END DECLARE SECTION;
631 EXEC SQL DECLARE csr101 CURSOR FOR
632 SELECT nfsphys_id, TRIM (dir) FROM nfsphys
633 WHERE mach_id = :mach_id
637 EXEC SQL OPEN csr101;
641 EXEC SQL FETCH csr101 INTO :_var_phys_id, :dir;
642 if(sqlca.sqlcode != 0) break;
646 if (*cp1++ != *cp2) break;
654 EXEC SQL CLOSE csr101;
661 /* setup_dfil: free any quota records and fsgroup info associated with
662 * a filesystem when it is deleted. Also adjust the allocation numbers.
665 setup_dfil(q, argv, cl)
670 EXEC SQL BEGIN DECLARE SECTION;
671 int id, total, phys_id;
673 EXEC SQL END DECLARE SECTION;
675 id = *(int *)argv[0];
676 EXEC SQL REPEATED SELECT SUM (quota) INTO :total:none FROM quota
677 WHERE filsys_id = :id;
681 /** What if there are multiple phys_id's per f/s? (bad data) **/
682 EXEC SQL REPEATED SELECT phys_id INTO :phys_id FROM filesys
683 WHERE filsys_id = :id;
684 EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :total
685 WHERE nfsphys_id = :phys_id;
688 EXEC SQL REPEATED DELETE FROM quota WHERE filsys_id = :id;
690 EXEC SQL REPEATED DELETE FROM fsgroup WHERE filsys_id = :id;
691 EXEC SQL REPEATED DELETE FROM fsgroup WHERE group_id = :id;
692 if (ingres_errno) return(mr_errcode);
697 /* setup_dnfp: check to see that the nfs physical partition does not have
698 * any filesystems assigned to it before allowing it to be deleted.
701 setup_dnfp(q, argv, cl)
706 EXEC SQL BEGIN DECLARE SECTION;
709 EXEC SQL END DECLARE SECTION;
711 id = *(int *)argv[0];
713 EXEC SQL REPEATED SELECT count(fs.tid) INTO :cnt FROM filesys fs, nfsphys np
714 WHERE fs.mach_id = :id AND fs.phys_id = np.nfsphys_id
715 AND np.mach_id = :id AND np.dir = :dir;
724 /* setup_dqot: Remove allocation from nfsphys before deleting quota.
725 * argv[0] = filsys_id
726 * argv[1] = type if "update_quota" or "delete_quota"
727 * argv[2 or 1] = users_id or list_id
730 setup_dqot(q, argv, cl)
735 EXEC SQL BEGIN DECLARE SECTION;
736 int quota, fs, id, physid;
738 EXEC SQL END DECLARE SECTION;
740 fs = *(int *)argv[0];
741 if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota")) {
743 id = *(int *)argv[2];
746 id = *(int *)argv[1];
749 EXEC SQL REPEATED SELECT quota INTO :quota FROM quota
750 WHERE type = :qtype AND entity_id = :id AND filsys_id = :fs;
751 EXEC SQL REPEATED SELECT phys_id INTO :physid FROM filesys
752 WHERE filsys_id = :fs;
753 EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :quota
754 WHERE nfsphys_id = :physid;
756 if (ingres_errno) return(mr_errcode);
761 /* setup_sshi: don't exclusive lock the machine table during
762 * set_server_host_internal.
764 /** Not allowed under (INGRES) SQL **/
765 setup_sshi(q, argv, cl)
772 EXEC SQL set lockmode session where readlock = system;
779 /* setup add_kerberos_user_mapping: add the string to the string
780 * table if necessary.
783 setup_akum(q, argv, cl)
788 EXEC SQL BEGIN DECLARE SECTION;
791 EXEC SQL END DECLARE SECTION;
794 if (name_to_id(name, "STRING", &id) != MR_SUCCESS) {
795 if (q->type != APPEND) return(MR_STRING);
797 cache_entry(name, "STRING", id);
799 if (ingres_errno) return(mr_errcode);
800 *(int *)argv[1] = id;
806 * This routine fetches an appropriate value from the numvalues table.
807 * It is a little hack to get around the fact that SQL doesn't let you
808 * do something like INSERT INTO table (foo) VALUES (other_table.bar).
810 * It is called from the query table as (*v->pre_rtn)(q,Argv,cl) or
811 * from within a setup_...() routine with the appropriate arguments.
813 * Correct functioning of this routine may depend on the assumption
814 * that this query is an APPEND.
817 prefetch_value(q,argv,cl)
822 EXEC SQL BEGIN DECLARE SECTION;
823 char *name = q->validate->object_id;
825 EXEC SQL END DECLARE SECTION;
826 int status, limit, argc;
828 /* set next object id, limiting it if necessary */
829 if(!strcmp(name, "uid") || !strcmp(name, "gid"))
830 limit = 1; /* So far as I know, this isn't needed. Just CMA. */
833 if((status = set_next_object_id(name, q->rtable, limit)) != MR_SUCCESS)
836 /* fetch object id */
837 EXEC SQL SELECT value INTO :value FROM numvalues WHERE name=:name;
838 if(ingres_errno) return(mr_errcode);
839 if(sqlca.sqlerrd[2] != 1) return(MR_INTERNAL);
841 argc = q->argc + q->vcnt; /* end of Argv for APPENDs */
842 sprintf(argv[argc],"%d",value); /** Could save this step by changing tlist from %s to %d **/
847 /* prefetch_filesys():
848 * Fetches the phys_id from filesys based on the filsys_id in argv[0].
849 * Appends the filsys_id and the phys_id to the argv so they can be
850 * referenced in an INSERT into a table other than filesys. Also
851 * see comments at prefetch_value().
853 * Assumes the existence of a row where filsys_id = argv[0], since a
854 * filesys label has already been resolved to a filsys_id.
856 prefetch_filesys(q,argv,cl)
861 EXEC SQL BEGIN DECLARE SECTION;
863 EXEC SQL END DECLARE SECTION;
866 fid = *(int *)argv[0];
867 EXEC SQL SELECT phys_id INTO :phid FROM filesys WHERE filsys_id = :fid;
868 if(ingres_errno) return(mr_errcode);
870 argc=q->argc+q->vcnt;
871 sprintf(argv[argc++],"%d",phid);
872 sprintf(argv[argc],"%d",fid);
881 setup_ahst(q,argv,cl)
886 EXEC SQL BEGIN DECLARE SECTION;
888 int value, id, addr, mask, high, low, cnt;
889 EXEC SQL END DECLARE SECTION;
892 extern int host_access_level, privileged;
894 if (!strcmp(q->shortname, "uhst"))
899 /* sanity check name: must start with a letter, contain only
900 * letters, numerals, and hyphen, and not end with a hyphen.
902 if (row == 0 || strcmp(argv[1], cl->args->mr_argv[1])) {
905 if (!isalpha(*p)) return(MR_BAD_CHAR);
907 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
908 (*p == '-' && p[1] == '.'))
911 if (*(p-1) == '-') return(MR_BAD_CHAR);
914 /* sanity check host vendor: must start with a letter, contain only
915 * letters, numerals, and hyphen, and end with an alphanumeric.
917 if (*argv[row+1] && (row == 0 || strcmp(argv[2], cl->args->mr_argv[2]))) {
918 char *p = argv[row+1];
920 if (!isalpha(*p)) return(MR_BAD_CHAR);
922 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
923 (*p == '-' && p[1] == '.'))
926 if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
929 /* sanity check host type: must start with a letter, contain only
930 * letters, numerals, and hyphen, and end with an alphanumeric.
932 if (*argv[row+2] && (row == 0 || strcmp(argv[3], cl->args->mr_argv[3]))) {
933 char *p = argv[row+2];
935 if (!isalpha(*p)) return(MR_BAD_CHAR);
937 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
938 (*p == '-' && p[1] == '.'))
941 if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
944 /* sanity check host vendor: must start with a letter, contain only
945 * letters, numerals, and hyphen, and end with an hyphen alphanumeric.
947 if (*argv[row+3] && (row == 0 || strcmp(argv[4], cl->args->mr_argv[4]))) {
948 char *p = argv[row+3];
950 if (!isalpha(*p)) return(MR_BAD_CHAR);
952 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
953 (*p == '-' && p[1] == '.'))
956 if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
959 /* check for duplicate name */
961 EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
963 if (ingres_errno) return(mr_errcode);
964 if (cnt != 0) return(MR_EXISTS);
967 if (!strcmp(argv[9+row], "unassigned"))
969 else if (!strcmp(argv[9+row], "unique")) {
970 if (*(int *)argv[8+row] == 0)
975 value = ntohl(inet_addr(argv[9+row]));
976 if (value == -1) return(MR_ADDRESS);
978 if (value == 0) return(MR_ADDRESS);
980 id = *(int *)argv[8+row];
981 EXEC SQL SELECT saddr, mask, high, low INTO :addr, :mask, :high, :low
982 FROM subnet WHERE snet_id = :id;
983 if (ingres_errno) return(mr_errcode);
985 if ((value & mask) != addr) return(MR_ADDRESS);
987 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
988 WHERE address = :name;
989 if (ingres_errno) return(mr_errcode);
991 if (row == 0 || row == 1 && cnt > 1) return(MR_ADDRESS);
992 if (row == 1 && cnt == 1) {
993 EXEC SQL SELECT mach_id INTO :id FROM machine
994 WHERE address = :name;
995 if (id != *(int *)argv[0]) return(MR_ADDRESS);
999 for (id = low; id <= high; id++) {
1000 if (((id & 0xff) == 0) ||
1001 ((id & 0xff) == 255))
1004 name = (char *)inet_ntoa(value);
1005 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
1006 WHERE address = :name;
1007 if (ingres_errno) return(mr_errcode);
1008 if (cnt == 0) break;
1013 value = htonl(value);
1015 value = htonl(value);
1016 strcpy(argv[9+row], inet_ntoa(value));
1018 strcpy(argv[9+row], "unassigned");
1021 /* status checking */
1022 value = atoi(argv[7+row]);
1023 if (row == 0 && !(value == 1 || value == 0))
1026 id = *(int *)argv[0];
1027 EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
1028 if (ingres_errno) return(mr_errcode);
1030 EXEC SQL UPDATE machine SET statuschange = date('now')
1031 WHERE mach_id = :id;
1035 if (row == 0 && !privileged) {
1036 /* subnet owner is adding a host */
1037 /* Non-query owner must set use to zero */
1038 if (atoi(argv[6]) != 0) return(MR_PERM);
1039 } else if (row == 1 && !privileged) {
1040 EXEC SQL BEGIN DECLARE SECTION;
1041 int i8, i12, i13, i7, i9, i14;
1042 char s6[33], s10[33], s11[9];
1043 EXEC SQL END DECLARE SECTION;
1044 /* Non-query owner is restricted in changes that can be made */
1045 id = *(int *)argv[0];
1046 EXEC SQL SELECT contact, status, address, owner_type, owner_id,
1047 acomment, use, snet_id, ocomment INTO :s6, :i8, :s10, :s11, :i12,
1048 :i13, :i7, :i9, :i14 FROM machine WHERE mach_id = :id;
1049 if (ingres_errno) return(mr_errcode);
1050 /* subnet owner cannot change use, comment, or network */
1051 if ((i7 != atoi(argv[7])) || (i14 != *(int *)argv[14]) ||
1052 (i9 != *(int *)argv[9]))
1054 /* host owner cannot change contact, status, address, owner_type,
1055 * owner_id, acomment, or subnet */
1056 if (host_access_level == 2 &&
1057 (strcmp(argv[6], strtrim(s6)) || (i8 != atoi(argv[8])) ||
1058 strcmp(argv[10], strtrim(s10)) ||strcmp(argv[11], strtrim(s11)) ||
1059 (i12 != *(int *)argv[12]) || (i13 != *(int *)argv[13]) ||
1060 (i9 != *(int *)argv[9])))
1065 * If this is an update_host query, we're done.
1071 * For an add_host query, allocate and fill in a new machine id,
1072 * and then insert the creator id.
1074 if ((mr_errcode = prefetch_value(q,argv,cl)) != MR_SUCCESS)
1077 sprintf(argv[q->argc + q->vcnt + 1], "%d",cl->client_id);
1085 setup_ahal(q,argv,cl)
1090 EXEC SQL BEGIN DECLARE SECTION;
1093 EXEC SQL END DECLARE SECTION;
1097 if (!isalpha(*p)) return(MR_BAD_CHAR);
1099 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
1100 (*p == '-' && p[1] == '.'))
1101 return(MR_BAD_CHAR);
1103 if (*(p-1) == '-') return(MR_BAD_CHAR);
1105 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
1107 if (ingres_errno) return(mr_errcode);
1108 if (cnt > 0) return(MR_EXISTS);