5 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
10 #include <mit-copyright.h>
11 #include "mr_server.h"
15 #include <arpa/inet.h>
16 #include <netinet/in.h>
22 EXEC SQL INCLUDE sqlca;
27 extern int dbms_errno, mr_errcode;
29 EXEC SQL BEGIN DECLARE SECTION;
30 extern char stmt_buf[];
31 EXEC SQL END DECLARE SECTION;
33 EXEC SQL WHENEVER SQLERROR DO dbmserr();
36 int prefetch_value(struct query *q, char **argv, client *cl);
37 int check_nfs(int mach_idx, char *name, char *access);
41 /* Setup routine for add_user
43 * Inputs: argv[0] - login
48 * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid)
49 * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
52 int setup_ausr(struct query *q, char *argv[], client *cl)
55 EXEC SQL BEGIN DECLARE SECTION;
57 EXEC SQL END DECLARE SECTION;
59 if (!strcmp(q->shortname, "uusr") || !strcmp(q->shortname, "uuac"))
63 if (!strcmp(argv[row], UNIQUE_UID) || atoi(argv[row]) == -1)
65 if ((err = set_next_object_id("unix_uid", USERS_TABLE, 1)))
67 EXEC SQL SELECT value INTO :nuid FROM numvalues WHERE name = 'unix_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]);
76 if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
83 /* setup_dusr - verify that the user is no longer being referenced
84 * and may safely be deleted.
87 int setup_dusr(struct query *q, char *argv[], client *cl)
89 EXEC SQL BEGIN DECLARE SECTION;
91 EXEC SQL END DECLARE SECTION;
95 /* For now, only allow users to be deleted if their status is 0 */
96 EXEC SQL SELECT status INTO :flag FROM users WHERE users_id = :id;
97 if (flag != 0 && flag != 4)
100 EXEC SQL DELETE FROM quota WHERE entity_id = :id AND type = 'USER';
101 EXEC SQL DELETE FROM krbmap WHERE users_id = :id;
102 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
103 WHERE member_id = :id AND member_type = 'USER';
106 EXEC SQL SELECT COUNT(label) INTO :cnt FROM filesys
110 EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
111 WHERE acl_id = :id AND acl_type = 'USER';
114 EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
115 WHERE acl_id = :id AND acl_type = 'USER';
118 EXEC SQL SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
119 WHERE acl_id = :id AND acl_type = 'USER';
128 /* setup_spop: verify that there is already a valid POP machine_id in the
129 * pop_id field. Also take care of keeping track of the post office usage.
131 int setup_spop(struct query *q, char *argv[], client *cl)
133 EXEC SQL BEGIN DECLARE SECTION;
135 char type[USERS_POTYPE_SIZE];
136 EXEC SQL END DECLARE SECTION;
138 id = *(int *)argv[0];
139 EXEC SQL SELECT potype, pop_id INTO :type, :mid FROM users
140 WHERE users_id = :id;
141 if (sqlca.sqlerrd[2] == 0)
143 EXEC SQL SELECT mach_id INTO :mid FROM machine
144 WHERE mach_id = :mid;
145 if (sqlca.sqlerrd[2] == 0)
147 if (strcmp(strtrim(type), "POP"))
148 set_pop_usage(mid, 1);
153 /* setup_dpob: Take care of keeping track of the post office usage.
155 int setup_dpob(struct query *q, char *argv[], client *cl)
157 EXEC SQL BEGIN DECLARE SECTION;
159 char type[USERS_POTYPE_SIZE];
160 EXEC SQL END DECLARE SECTION;
162 user = *(int *)argv[0];
163 EXEC SQL SELECT potype, pop_id INTO :type, :id FROM users
164 WHERE users_id = :user;
168 if (!strcmp(strtrim(type), "POP"))
169 set_pop_usage(id, -1);
174 /* setup_dmac - verify that the machine is no longer being referenced
175 * and may safely be deleted.
178 int setup_dmac(struct query *q, char *argv[], client *cl)
180 EXEC SQL BEGIN DECLARE SECTION;
182 EXEC SQL END DECLARE SECTION;
184 id = *(int *)argv[0];
186 EXEC SQL SELECT status INTO :flag FROM machine
190 EXEC SQL SELECT COUNT(login) INTO :cnt FROM users
191 WHERE potype = 'POP' AND pop_id = :id;
194 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM serverhosts
198 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM nfsphys
202 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM hostaccess
206 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printcap
210 EXEC SQL SELECT COUNT(quotaserver) INTO :cnt FROM printcap
211 WHERE quotaserver = :id;
214 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM palladium
218 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM hostalias
223 EXEC SQL DELETE FROM mcmap WHERE mach_id = :id;
230 /* setup_dsnt - verify that the subnet is no longer being referenced
231 * and may safely be deleted.
234 int setup_dsnt(struct query *q, char *argv[], client *cl)
236 EXEC SQL BEGIN DECLARE SECTION;
238 EXEC SQL END DECLARE SECTION;
240 id = *(int *)argv[0];
241 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM machine
249 /* setup_dclu - verify that the cluster is no longer being referenced
250 * and may safely be deleted.
253 int setup_dclu(struct query *q, char *argv[], client *cl)
255 EXEC SQL BEGIN DECLARE SECTION;
257 EXEC SQL END DECLARE SECTION;
259 id = *(int *)argv[0];
260 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM mcmap
264 EXEC SQL SELECT COUNT(clu_id) INTO :cnt FROM svc
274 /* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate
275 * a new gid and put it in argv[6]. Otherwise if argv[6] is UNIQUE_ID but
276 * argv[5] is not, then remember that UNIQUE_ID is being stored by putting
277 * a -1 there. Remember that this is also used for ulis, with the indexes
278 * at 6 & 7. Also check that the list name does not contain uppercase
279 * characters, control characters, @, or :.
282 static int badlistchars[] = {
283 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
284 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
285 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
286 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
287 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
288 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, /* P - _ */
289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
290 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
291 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
292 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
293 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
294 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
295 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
296 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
297 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
298 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
301 int setup_alis(struct query *q, char *argv[], client *cl)
303 EXEC SQL BEGIN DECLARE SECTION;
305 EXEC SQL END DECLARE SECTION;
309 if (!strcmp(q->shortname, "alis"))
311 else if (!strcmp(q->shortname, "ulis"))
314 for (p = (unsigned char *) argv[idx]; *p; p++)
316 if (badlistchars[*p])
320 if (!strcmp(argv[6 + idx], UNIQUE_GID) || atoi(argv[6 + idx]) == -1)
322 if (atoi(argv[5 + idx]))
324 if ((err = set_next_object_id("gid", LIST_TABLE, 1)))
326 EXEC SQL SELECT value INTO :ngid FROM numvalues
330 sprintf(argv[6 + idx], "%d", ngid);
333 strcpy(argv[6 + idx], "-1");
336 if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
343 /* setup_dlis - verify that the list is no longer being referenced
344 * and may safely be deleted.
347 int setup_dlis(struct query *q, char *argv[], client *cl)
350 EXEC SQL BEGIN DECLARE SECTION;
352 EXEC SQL END DECLARE SECTION;
354 id = *(int *)argv[0];
356 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
357 WHERE member_id = :id AND member_type = 'LIST';
361 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
362 WHERE member_id = :id AND member_type = 'LIST';
366 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
371 EXEC SQL SELECT COUNT(label) INTO :cnt FROM filesys WHERE owners = :id;
375 EXEC SQL SELECT COUNT(tag) INTO :cnt FROM capacls WHERE list_id = :id;
379 EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
380 WHERE acl_id = :id AND acl_type = 'LIST' AND list_id != :id;
384 EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
385 WHERE acl_id = :id AND acl_type = 'LIST';
389 EXEC SQL SELECT COUNT(entity_id) INTO :cnt FROM quota
390 WHERE entity_id = :id AND type = 'GROUP';
394 EXEC SQL SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
395 WHERE acl_id = :id AND acl_type = 'LIST';
399 EXEC SQL SELECT COUNT(class) INTO :cnt FROM zephyr z
400 WHERE z.xmt_type = 'LIST' AND z.xmt_id = :id
401 OR z.sub_type = 'LIST' AND z.sub_id = :id
402 OR z.iws_type = 'LIST' AND z.iws_id = :id
403 OR z.iui_type = 'LIST' AND z.iui_id = :id;
411 /* setup_dsin - verify that the service is no longer being referenced
412 * and may safely be deleted.
415 int setup_dsin(struct query *q, char *argv[], client *cl)
417 EXEC SQL BEGIN DECLARE SECTION;
420 EXEC SQL END DECLARE SECTION;
423 EXEC SQL SELECT COUNT(service) INTO :cnt FROM serverhosts
424 WHERE service = UPPER(:svrname);
428 EXEC SQL SELECT inprogress INTO :ec FROM servers
429 WHERE name = UPPER(:svrname);
439 /* setup_dshi - verify that the service-host is no longer being referenced
440 * and may safely be deleted.
443 int setup_dshi(struct query *q, char *argv[], client *cl)
445 EXEC SQL BEGIN DECLARE SECTION;
448 EXEC SQL END DECLARE SECTION;
451 id = *(int *)argv[1];
453 EXEC SQL SELECT inprogress INTO :ec FROM serverhosts
454 WHERE service = UPPER(:svrname) AND mach_id = :id;
465 ** setup_add_filesys - verify existance of referenced file systems
471 ** argv[5] - rwaccess
477 ** * extract directory prefix from name
478 ** * verify mach_id/dir in nfsphys
479 ** * verify rwaccess in {r, w, R, W}
481 ** Side effect: sets variable _var_phys_id to the ID of the physical
482 ** filesystem (nfsphys_id for NFS, 0 for RVD)
485 ** MR_NFS - specified directory not exported
486 ** MR_FILESYS_ACCESS - invalid filesys access
490 EXEC SQL BEGIN DECLARE SECTION;
492 EXEC SQL END DECLARE SECTION;
494 int setup_afil(struct query *q, char *argv[], client *cl)
498 EXEC SQL BEGIN DECLARE SECTION;
500 char ftype[FILESYS_TYPE_SIZE + 10], *rwaccess;
501 EXEC SQL END DECLARE SECTION;
504 mach_id = *(int *)argv[2];
509 sprintf(ftype, "fs_access_%s", type);
510 EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
511 WHERE name = :ftype AND type = 'TYPE' and trans = :rwaccess;
515 return MR_FILESYS_ACCESS;
517 if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
520 if (!strcmp(type, "NFS"))
521 return check_nfs(mach_id, name, rwaccess);
527 /* Verify the arguments, depending on the FStype. Also, if this is an
528 * NFS filesystem, then update any quotas for that filesystem to reflect
532 int setup_ufil(struct query *q, char *argv[], client *cl)
536 EXEC SQL BEGIN DECLARE SECTION;
537 int fid, total, who, ok;
538 char *entity, ftype[FILESYS_TYPE_SIZE + 10], *access;
539 short int total_null;
540 EXEC SQL END DECLARE SECTION;
544 mach_id = *(int *)argv[3];
547 fid = *(int *)argv[0];
551 sprintf(ftype, "fs_access_%s", type);
552 EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
553 WHERE name = :ftype AND type = 'TYPE' AND trans = :access;
557 return MR_FILESYS_ACCESS;
559 EXEC SQL SELECT type INTO :ftype FROM filesys
560 WHERE filsys_id = :fid;
564 if (!strcmp(type, "NFS"))
566 status = check_nfs(mach_id, name, access);
567 EXEC SQL UPDATE quota SET phys_id = :_var_phys_id
568 WHERE filsys_id = :fid;
573 else if (!strcmp(type, "AFS") && strcmp(strtrim(ftype), "AFS")
574 && strcmp(strtrim(ftype), "ERR"))
577 EXEC SQL DELETE FROM quota
578 WHERE type = 'ANY' AND filsys_id = :fid;
579 EXEC SQL SELECT SUM (quota) INTO :total:total_null FROM quota
580 WHERE filsys_id = :fid AND phys_id != 0;
583 if (!total_null && (total != 0))
585 EXEC SQL INSERT INTO quota (quota, filsys_id, phys_id, entity_id,
586 type, modtime, modby, modwith)
587 VALUES (:total, :fid, 0, 0, 'ANY', SYSDATE, :who, :entity);
594 EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid;
602 /* Find the NFS physical partition that the named directory is on.
603 * This is done by comparing the dir against the mount point of the
604 * partition. To make sure we get the correct match when there is
605 * more than one, we sort the query in reverse order by dir name.
608 int check_nfs(int mach_id, char *name, char *access)
610 EXEC SQL BEGIN DECLARE SECTION;
611 char dir[NFSPHYS_DIR_SIZE];
613 EXEC SQL END DECLARE SECTION;
619 EXEC SQL DECLARE csr101 CURSOR FOR
620 SELECT nfsphys_id, dir FROM nfsphys
625 EXEC SQL OPEN csr101;
630 EXEC SQL FETCH csr101 INTO :_var_phys_id, :dir;
647 EXEC SQL CLOSE csr101;
654 /* setup_dfil: free any quota records and fsgroup info associated with
655 * a filesystem when it is deleted. Also adjust the allocation numbers.
658 int setup_dfil(struct query *q, char **argv, client *cl)
660 EXEC SQL BEGIN DECLARE SECTION;
661 int id, total, phys_id;
663 EXEC SQL END DECLARE SECTION;
665 id = *(int *)argv[0];
666 EXEC SQL SELECT SUM (quota) INTO :total:none FROM quota
667 WHERE filsys_id = :id;
672 /** What if there are multiple phys_id's per f/s? (bad data) **/
673 EXEC SQL SELECT phys_id INTO :phys_id FROM filesys
674 WHERE filsys_id = :id;
675 EXEC SQL UPDATE nfsphys SET allocated = allocated - :total
676 WHERE nfsphys_id = :phys_id;
679 EXEC SQL DELETE FROM quota WHERE filsys_id = :id;
680 EXEC SQL DELETE FROM fsgroup WHERE filsys_id = :id;
681 EXEC SQL DELETE FROM fsgroup WHERE group_id = :id;
688 /* setup_dnfp: check to see that the nfs physical partition does not have
689 * any filesystems assigned to it before allowing it to be deleted.
692 int setup_dnfp(struct query *q, char **argv, client *cl)
694 EXEC SQL BEGIN DECLARE SECTION;
697 EXEC SQL END DECLARE SECTION;
699 id = *(int *)argv[0];
701 EXEC SQL SELECT count(fs.rowid) INTO :cnt FROM filesys fs, nfsphys np
702 WHERE fs.mach_id = :id AND fs.phys_id = np.nfsphys_id
703 AND np.mach_id = :id AND np.dir = :dir;
712 /* setup_dqot: Remove allocation from nfsphys before deleting quota.
713 * argv[0] = filsys_id
714 * argv[1] = type if "update_quota" or "delete_quota"
715 * argv[2 or 1] = users_id or list_id
718 int setup_dqot(struct query *q, char **argv, client *cl)
720 EXEC SQL BEGIN DECLARE SECTION;
721 int quota, fs, id, physid;
723 EXEC SQL END DECLARE SECTION;
725 fs = *(int *)argv[0];
726 if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota"))
729 id = *(int *)argv[2];
734 id = *(int *)argv[1];
737 EXEC SQL SELECT quota INTO :quota FROM quota
738 WHERE type = :qtype AND entity_id = :id AND filsys_id = :fs;
739 EXEC SQL SELECT phys_id INTO :physid FROM filesys
740 WHERE filsys_id = :fs;
741 EXEC SQL UPDATE nfsphys SET allocated = allocated - :quota
742 WHERE nfsphys_id = :physid;
750 /* setup add_kerberos_user_mapping: add the string to the string
751 * table if necessary.
754 int setup_akum(struct query *q, char **argv, client *cl)
756 EXEC SQL BEGIN DECLARE SECTION;
759 EXEC SQL END DECLARE SECTION;
762 if (name_to_id(name, STRINGS_TABLE, &id) != MR_SUCCESS)
764 if (q->type != APPEND)
766 id = add_string(name);
767 cache_entry(name, STRINGS_TABLE, id);
771 *(int *)argv[1] = id;
777 * This routine fetches an appropriate value from the numvalues table.
778 * It is a little hack to get around the fact that SQL doesn't let you
779 * do something like INSERT INTO table (foo) VALUES (other_table.bar).
781 * It is called from the query table as (*v->pre_rtn)(q, Argv, cl) or
782 * from within a setup_...() routine with the appropriate arguments.
784 * Correct functioning of this routine may depend on the assumption
785 * that this query is an APPEND.
788 int prefetch_value(struct query *q, char **argv, client *cl)
790 EXEC SQL BEGIN DECLARE SECTION;
791 char *name = q->validate->object_id;
793 EXEC SQL END DECLARE SECTION;
794 int status, limit, argc;
796 /* set next object id, limiting it if necessary */
797 if (!strcmp(name, "unix_uid") || !strcmp(name, "gid"))
798 limit = 1; /* So far as I know, this isn't needed. Just CMA. */
801 if ((status = set_next_object_id(name, q->rtable, limit)) != MR_SUCCESS)
804 /* fetch object id */
805 EXEC SQL SELECT value INTO :value FROM numvalues WHERE name = :name;
808 if (sqlca.sqlerrd[2] != 1)
811 argc = q->argc + q->vcnt; /* end of Argv for APPENDs */
812 sprintf(argv[argc], "%d", value);
817 /* prefetch_filesys():
818 * Fetches the phys_id from filesys based on the filsys_id in argv[0].
819 * Appends the filsys_id and the phys_id to the argv so they can be
820 * referenced in an INSERT into a table other than filesys. Also
821 * see comments at prefetch_value().
823 * Assumes the existence of a row where filsys_id = argv[0], since a
824 * filesys label has already been resolved to a filsys_id.
826 int prefetch_filesys(struct query *q, char **argv, client *cl)
828 EXEC SQL BEGIN DECLARE SECTION;
830 EXEC SQL END DECLARE SECTION;
833 fid = *(int *)argv[0];
834 EXEC SQL SELECT phys_id INTO :phid FROM filesys WHERE filsys_id = :fid;
838 argc = q->argc + q->vcnt;
839 sprintf(argv[argc++], "%d", phid);
840 sprintf(argv[argc], "%d", fid);
849 int setup_ahst(struct query *q, char **argv, client *cl)
851 EXEC SQL BEGIN DECLARE SECTION;
852 char *name, oldname[MACHINE_NAME_SIZE], vendor[MACHINE_VENDOR_SIZE];
853 char *model[MACHINE_MODEL_SIZE], os[MACHINE_OS_SIZE];
854 int value, id, saddr, mask, high, low, cnt;
855 EXEC SQL END DECLARE SECTION;
859 if (!strcmp(q->shortname, "uhst"))
862 EXEC SQL SELECT name, vendor, model, os
863 INTO :oldname, :vendor, :model, :os
864 FROM machine WHERE mach_id = :id;
869 id = *(int *)argv[0];
871 /* sanity check name: must start with a letter, contain only
872 * letters, numerals, and hyphen, and not end with a hyphen.
874 if (row == 0 || strcmp(argv[1], oldname))
882 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
883 (*p == '-' && p[1] == '.'))
890 /* sanity check host vendor: must start with a letter, contain only
891 * letters, numerals, and hyphen, and end with an alphanumeric.
893 if (*argv[row + 1] && (row == 0 || strcmp(argv[2], vendor)))
895 char *p = argv[row + 1];
901 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
902 (*p == '-' && p[1] == '.'))
905 if (!isalnum(*(p - 1)))
909 /* sanity check host type: must start with a letter, contain only
910 * letters, numerals, and hyphen, and end with an alphanumeric.
912 if (*argv[row + 2] && (row == 0 || strcmp(argv[3], model)))
914 char *p = argv[row + 2];
920 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
921 (*p == '-' && p[1] == '.'))
924 if (!isalnum(*(p - 1)))
928 /* sanity check host os: must start with a letter, contain only
929 * letters, numerals, and hyphen, and end with an hyphen alphanumeric.
931 if (*argv[row + 3] && (row == 0 || strcmp(argv[4], os)))
933 char *p = argv[row + 3];
939 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
940 (*p == '-' && p[1] == '.'))
943 if (!isalnum(*(p - 1)))
947 /* check for duplicate name */
949 EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
957 if (!strcmp(argv[9 + row], "unassigned"))
959 else if (!strcmp(argv[9 + row], "unique"))
961 if (*(int *)argv[8 + row] == 0)
968 value = ntohl(inet_addr(argv[9 + row]));
977 * an address or unique was specified.
979 id = *(int *)argv[8 + row];
980 EXEC SQL SELECT saddr, mask, high, low INTO :saddr, :mask, :high, :low
981 FROM subnet WHERE snet_id = :id;
987 * someone specified an IP address for the host record
989 if ((value & mask) != saddr || value < low || value > high)
992 * run the address argument through inet_addr(). This
993 * has the effect that any out of bounds host addrs will
994 * be converted to a valid host addr. We do this now
995 * so that the uniqueness check works. We should also
996 * link in an inet_addr() that returns an error for
999 addr.s_addr = inet_addr(argv[9 + row]);
1000 name = inet_ntoa(addr);
1001 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
1002 WHERE address = :name;
1008 * make IP address is unique. If this a modify request
1009 * (row == 1), then we expect one record to exist.
1011 if (row == 0 || (row == 1 && cnt > 1))
1013 if (row == 1 && cnt == 1)
1015 EXEC SQL SELECT mach_id INTO :id FROM machine
1016 WHERE address = :name;
1017 if (id != *(int *)argv[0])
1025 * a "unique" address was specified. Walk through the
1026 * range specified in the network record, return
1027 * error if no room left.
1029 for (id = low; id <= high; id++)
1031 if (((id & 0xff) == 0) || ((id & 0xff) == 255))
1033 addr.s_addr = htonl(id);
1034 name = inet_ntoa(addr);
1035 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
1036 WHERE address = :name;
1048 * we have an address in value. Convert it to a string and store it.
1050 addr.s_addr = htonl(value);
1051 strcpy(argv[9 + row], inet_ntoa(addr));
1054 strcpy(argv[9 + row], "unassigned");
1056 /* status checking */
1057 value = atoi(argv[7 + row]);
1058 if (row == 0 && !(value == 1 || value == 0))
1062 id = *(int *)argv[0];
1063 EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
1068 EXEC SQL UPDATE machine SET statuschange = SYSDATE
1069 WHERE mach_id = :id;
1074 * If this is an update_host query, we're done.
1080 * For an add_host query, allocate and fill in a new machine id,
1081 * and then insert the creator id.
1083 if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
1086 sprintf(argv[q->argc + q->vcnt + 1], "%d", cl->client_id);
1094 int setup_ahal(struct query *q, char **argv, client *cl)
1096 EXEC SQL BEGIN DECLARE SECTION;
1099 EXEC SQL END DECLARE SECTION;
1107 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
1108 (*p == '-' && p[1] == '.'))
1111 if (*(p - 1) == '-')
1114 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE