+static int trusts_cmdtrustgroupdel(void *source, int cargc, char **cargv) {
+ trustgroup *tg;
+ nick *sender = source;
+
+ if(cargc < 1)
+ return CMD_USAGE;
+
+ tg = tg_strtotg(cargv[0]);
+ if(!tg) {
+ controlreply(sender, "Couldn't look up trustgroup.");
+ return CMD_ERROR;
+ }
+
+ if(tg->hosts) {
+ controlreply(sender, "Delete all hosts before deleting the group.");
+ return CMD_ERROR;
+ }
+
+ triggerhook(HOOK_TRUSTS_DELGROUP, tg);
+ tg_delete(tg);
+ controlreply(sender, "Group deleted.");
+
+ /* TODO: controlwall */
+ return CMD_OK;
+}
+
+static int trusts_cmdtrustdel(void *source, int cargc, char **cargv) {
+ trustgroup *tg;
+ trusthost *th;
+ uint32_t ip, mask;
+ nick *sender = source;
+
+ if(cargc < 2)
+ return CMD_USAGE;
+
+ tg = tg_strtotg(cargv[0]);
+ if(!tg) {
+ controlreply(sender, "Couldn't look up trustgroup.");
+ return CMD_ERROR;
+ }
+
+ if(!trusts_str2cidr(cargv[1], &ip, &mask)) {
+ controlreply(sender, "Invalid IP/mask.");
+ return CMD_ERROR;
+ }
+
+ for(th=tg->hosts;th;th=th->next)
+ if((th->ip == ip) && (th->mask == mask))
+ break;
+
+ if(!th) {
+ controlreply(sender, "Couldn't find that host in that group.");
+ return CMD_ERROR;
+ }
+
+ triggerhook(HOOK_TRUSTS_DELHOST, th);
+ th_delete(th);
+ controlreply(sender, "Host deleted.");
+
+ /* TODO: controlwall */
+ return CMD_OK;
+}
+
+static int modifyname(trustgroup *tg, char *name) {
+ sstring *n = getsstring(name, TRUSTNAMELEN);
+ if(!n)
+ return 0;
+
+ freesstring(tg->name);
+ tg->name = n;
+
+ return 1;
+}
+
+static int modifycomment(trustgroup *tg, char *comment) {
+ sstring *n = getsstring(comment, COMMENTLEN);
+ if(!n)
+ return 0;
+
+ freesstring(tg->comment);
+ tg->comment = n;
+
+ return 1;
+}
+
+static int modifycontact(trustgroup *tg, char *contact) {
+ sstring *n = getsstring(contact, CONTACTLEN);
+ if(!n)
+ return 0;
+
+ freesstring(tg->contact);
+ tg->contact = n;
+
+ return 1;
+}
+
+static int modifytrustedfor(trustgroup *tg, char *num) {
+ unsigned int trustedfor = strtoul(num, NULL, 10);
+
+ if(trustedfor > MAXTRUSTEDFOR)
+ return 0;
+
+ tg->trustedfor = trustedfor;
+
+ return 1;
+}
+
+static int modifymaxperuser(trustgroup *tg, char *num) {
+ unsigned int maxperuser = strtoul(num, NULL, 10);
+
+ if(maxperuser > MAXPERIDENT)
+ return 0;
+
+ tg->maxperident = maxperuser;
+
+ return 1;
+}
+
+static int modifyenforceident(trustgroup *tg, char *num) {
+ if(num[0] == '1') {
+ tg->mode = 1;
+ } else if(num[0] == '0') {
+ tg->mode = 0;
+ } else {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int modifyexpires(trustgroup *tg, char *expires) {
+ int howlong = durationtolong(expires);
+
+ if((howlong <= 0) || (howlong > MAXDURATION))
+ return 0;
+
+ tg->expires = time(NULL) + howlong;
+
+ return 1;
+}
+
+#define MS(x) (struct trustmodification){ .name = # x, .fn = modify ## x }
+
+static int trusts_cmdtrustgroupmodify(void *source, int cargc, char **cargv) {
+ trustgroup *tg;
+ nick *sender = source;
+ char *what, *to, validfields[512];
+ struct trustmodification *mods = (struct trustmodification []){ MS(expires), MS(enforceident), MS(maxperuser), MS(name), MS(contact), MS(comment), MS(trustedfor) };
+ int modcount = sizeof(mods) / sizeof(struct trustmodification);
+ int i;
+ StringBuf b;
+#undef MS
+
+ if(cargc < 3)
+ return CMD_USAGE;
+
+ tg = tg_strtotg(cargv[0]);
+ if(!tg) {
+ controlreply(sender, "Couldn't look up trustgroup.");
+ return CMD_ERROR;
+ }
+
+ what = cargv[1];
+ to = cargv[2];
+
+ sbinit(&b, validfields, sizeof(validfields));
+ for(i=0;i<modcount;i++) {
+ if(!strcmp(what, mods[i].name)) {
+ if(!(mods[i].fn)(tg, to)) {
+ controlreply(sender, "An error occured changing that property, check the syntax.");
+ return CMD_ERROR;
+ }
+ break;
+ }
+
+ if(i > 0)
+ sbaddstr(&b, ", ");
+ sbaddstr(&b, mods[i].name);
+ }
+
+ if(i == modcount) {
+ sbterminate(&b);
+ controlreply(sender, "No such field, valid fields are: %s", validfields);
+ return CMD_ERROR;
+ }
+
+ triggerhook(HOOK_TRUSTS_MODIFYGROUP, tg);
+ tg_update(tg);
+ controlreply(sender, "Group modified.");
+
+ /* TODO: controlwall */
+ return CMD_OK;
+}
+