EXEC SQL END DECLARE SECTION;
id = *(int *)argv[0];
+
+ EXEC SQL REPEATED SELECT status INTO :flag FROM machine
+ WHERE mach_id = :id;
+ if (flag != 3)
+ return(MR_IN_USE);
EXEC SQL REPEATED SELECT COUNT(login) INTO :cnt FROM users
WHERE potype='POP' AND pop_id = :id;
if (cnt > 0)
int flag, id, cnt = 0;
EXEC SQL END DECLARE SECTION;
-#ifdef notdef
id = *(int *)argv[0];
EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM machine
WHERE snet_id = :id;
if (cnt > 0)
return(MR_IN_USE);
-#endif
return(MR_SUCCESS);
}
return(MR_SUCCESS);
}
+
+/* prefetch_value():
+ * This routine fetches an appropriate value from the numvalues table.
+ * It is a little hack to get around the fact that SQL doesn't let you
+ * do something like INSERT INTO table (foo) VALUES (other_table.bar).
+ *
+ * It is called from the query table as (*v->pre_rtn)(q,Argv,cl) or
+ * from within a setup_...() routine with the appropriate arguments.
+ *
+ * Correct functioning of this routine may depend on the assumption
+ * that this query is an APPEND.
+ */
+
+prefetch_value(q,argv,cl)
+ struct query *q;
+ char **argv;
+ client *cl;
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *name = q->validate->object_id;
+ int value;
+ EXEC SQL END DECLARE SECTION;
+ int status, limit, argc;
+
+ /* set next object id, limiting it if necessary */
+ if(!strcmp(name, "uid") || !strcmp(name, "gid"))
+ limit = 1; /* So far as I know, this isn't needed. Just CMA. */
+ else
+ limit = 0;
+ if((status = set_next_object_id(name, q->rtable, limit)) != MR_SUCCESS)
+ return(status);
+
+ /* fetch object id */
+ EXEC SQL SELECT value INTO :value FROM numvalues WHERE name=:name;
+ if(ingres_errno) return(mr_errcode);
+ if(sqlca.sqlerrd[2] != 1) return(MR_INTERNAL);
+
+ argc = q->argc + q->vcnt; /* end of Argv for APPENDs */
+ sprintf(argv[argc],"%d",value); /** Could save this step by changing tlist from %s to %d **/
+
+ return(MR_SUCCESS);
+}
+
+/* prefetch_filesys():
+ * Fetches the phys_id from filesys based on the filsys_id in argv[0].
+ * Appends the filsys_id and the phys_id to the argv so they can be
+ * referenced in an INSERT into a table other than filesys. Also
+ * see comments at prefetch_value().
+ *
+ * Assumes the existence of a row where filsys_id = argv[0], since a
+ * filesys label has already been resolved to a filsys_id.
+ */
+prefetch_filesys(q,argv,cl)
+ struct query *q;
+ char **argv;
+ client *cl;
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int fid,phid;
+ EXEC SQL END DECLARE SECTION;
+ int argc;
+
+ fid = *(int *)argv[0];
+ EXEC SQL SELECT phys_id INTO :phid FROM filesys WHERE filsys_id = :fid;
+ if(ingres_errno) return(mr_errcode);
+
+ argc=q->argc+q->vcnt;
+ sprintf(argv[argc++],"%d",phid);
+ sprintf(argv[argc],"%d",fid);
+
+ return(MR_SUCCESS);
+}
+
+
+/* setup_ahst():
+ */
+
+setup_ahst(q,argv,cl)
+ struct query *q;
+ char **argv;
+ client *cl;
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *name;
+ int value, id, addr, mask, high, low, cnt;
+ EXEC SQL END DECLARE SECTION;
+ char buf[BUFSIZ];
+ int row;
+ extern int host_access_level, privileged;
+
+ if (!strcmp(q->shortname, "uhst"))
+ row = 1;
+ else
+ row = 0;
+
+ /* sanity check name: must start with a letter, contain only
+ * letters, numerals, and hyphen, and not end with a hyphen.
+ */
+ if (row == 0 || strcmp(argv[1], cl->args->mr_argv[1])) {
+ char *p = argv[row];
+
+ if (!isalpha(*p)) return(MR_BAD_CHAR);
+ for (; *p; p++) {
+ if ((!isalnum(*p) && *p != '-' && *p != '.') ||
+ (*p == '-' && p[1] == '.'))
+ return(MR_BAD_CHAR);
+ }
+ if (*(p-1) == '-') return(MR_BAD_CHAR);
+ }
+
+ /* check for duplicate name */
+ name = argv[row];
+ EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
+ WHERE name = :name;
+ if (ingres_errno) return(mr_errcode);
+ if (cnt != 0) return(MR_EXISTS);
+
+ /* check address */
+ if (!strcmp(argv[9+row], "unassigned"))
+ value = -1;
+ else if (!strcmp(argv[9+row], "unique")) {
+ if (*(int *)argv[8+row] == 0)
+ value = -1;
+ else
+ value = -2;
+ } else
+ value = ntohl(inet_addr(argv[9+row]));
+ if (value == 0) return(MR_ADDRESS);
+ if (value != -1) {
+ id = *(int *)argv[8+row];
+ EXEC SQL SELECT saddr, mask, high, low INTO :addr, :mask, :high, :low
+ FROM subnet WHERE snet_id = :id;
+ if (ingres_errno) return(mr_errcode);
+ if (value != -2) {
+ if ((value & mask) != addr) return(MR_ADDRESS);
+ name = argv[9+row];
+ EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
+ WHERE address = :name;
+ if (ingres_errno) return(mr_errcode);
+ if (cnt > 0) {
+ if (row == 0 || row == 1 && cnt > 1) return(MR_ADDRESS);
+ if (row == 1 && cnt == 1) {
+ EXEC SQL SELECT mach_id INTO :id FROM machine
+ WHERE address = :name;
+ if (id != *(int *)argv[0]) return(MR_ADDRESS);
+ }
+ }
+ } else {
+ for (id = low; id <= high; id++) {
+ if (((id & 0xff) == 0) ||
+ ((id & 0xff) == 255))
+ continue;
+ value = htonl(id);
+ name = (char *)inet_ntoa(value);
+ EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
+ WHERE address = :name;
+ if (ingres_errno) return(mr_errcode);
+ if (cnt == 0) break;
+ }
+ if (cnt != 0)
+ return(MR_ADDRESS);
+ else
+ value = htonl(value);
+ }
+ value = htonl(value);
+ argv[9+row] = strsave(inet_ntoa(value));
+ } else {
+ argv[9+row] = strsave("unassigned");
+ }
+
+ /* status checking */
+ value = atoi(argv[7+row]);
+ if (row == 0 && !(value == 1 || value == 3))
+ return(MR_TYPE);
+ if (row == 1) {
+ id = *(int *)argv[0];
+ EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
+ if (ingres_errno) return(mr_errcode);
+ if (value != cnt) {
+ EXEC SQL UPDATE machine SET statuschange = date('now');
+ }
+ }
+
+ if (row == 0 && !privileged) {
+ /* subnet owner is adding a host */
+ /* Non-query owner must set use to zero */
+ if (atoi(argv[6]) != 0) return(MR_PERM);
+ } else if (row == 1 && !privileged) {
+ EXEC SQL BEGIN DECLARE SECTION;
+ int i8, i12, i13, i7, i9, i14;
+ char s6[33], s10[33], s11[9];
+ EXEC SQL END DECLARE SECTION;
+ /* Non-query owner is restricted in changes that can be made */
+ id = *(int *)argv[0];
+ EXEC SQL SELECT contact, status, address, owner_type, owner_id,
+ acomment, use, snet_id, ocomment INTO :s6, :i8, :s10, :s11, :i12,
+ :i13, :i7, :i9, :i14 FROM machine WHERE mach_id = :id;
+ if (ingres_errno) return(mr_errcode);
+ /* subnet owner cannot change use or ocomment */
+ if ((i7 != atoi(argv[7])) || (i14 != *(int *)argv[14]))
+ return(MR_PERM);
+ /* host owner cannot change contact, status, address, owner_type,
+ * owner_id, acomment, or subnet */
+ if (host_access_level == 2 &&
+ (strcmp(argv[6], strtrim(s6)) || (i8 != atoi(argv[8])) ||
+ strcmp(argv[10], strtrim(s10)) || strcmp(argv[11], strtrim(s11)) ||
+ (i12 != *(int *)argv[12]) || (i13 != *(int *)argv[13]) ||
+ (i9 = *(int *)argv[9])))
+ return(MR_PERM);
+ }
+
+ if ((mr_errcode = prefetch_value(q,argv,cl)) != MR_SUCCESS)
+ return(mr_errcode);
+
+ row = q->argc + q->vcnt + 1;
+ sprintf(buf, "%d",cl->client_id);
+ argv[row] = strsave(buf);
+ argv[row+1] = NULL;
+ return(MR_SUCCESS);
+}
+
+
+/* setup_ahal():
+ */
+
+setup_ahal(q,argv,cl)
+ struct query *q;
+ char **argv;
+ client *cl;
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *name;
+ int cnt;
+ EXEC SQL END DECLARE SECTION;
+ char *p;
+
+ p = name = argv[0];
+ if (!isalpha(*p)) return(MR_BAD_CHAR);
+ for (; *p; p++) {
+ if ((!isalnum(*p) && *p != '-' && *p != '.') ||
+ (*p == '-' && p[1] == '.'))
+ return(MR_BAD_CHAR);
+ }
+ if (*(p-1) == '-') return(MR_BAD_CHAR);
+
+ EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
+ name = :name;
+ if (ingres_errno) return(mr_errcode);
+ if (cnt > 0) return(MR_EXISTS);
+
+ return(MR_SUCCESS);
+}