1 /* mod-hostserv.c - HostServ module for srvx
2 * Copyright 2012-2013 pk910, Stricted, NurPech
4 * This file is part of srvx.
6 * srvx is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with srvx; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 /* Adds new section to srvx.conf:
26 * "toplevel_access" "600";
27 * "fallback_other_assignment" "1"; //fall back to another assignment when active assignment gets removed
28 * "manager_can_rename_toplevel" "0"; //managers of a toplevel group may rename the whole group
29 * "manager_can_del_toplevel" "0"; //managers of a toplevel group may delete the whole group
30 * "manager_can_rename_secondlevel" "0"; //managers of a secondlevel group may rename the whole group
31 * "manager_can_del_secondlevel" "0"; //managers of a secondlevel group may delete the whole group
35 * After you started srvx make the bot active:
36 /msg opserv bind hostserv * hostserv.*
37 /msg opserv bind hostserv help *modcmd.help
48 #define KEY_TOPLEVEL "TopLevel"
49 #define KEY_SECONDLEVEL "SecondLevel"
50 #define KEY_MANAGERS "Manager"
51 #define KEY_ASSIGNMENTS "Assignments"
52 #define KEY_ACTIVE "active"
54 #define HS_FAKEHOST_SPECIAL_CHARS "_-:;" /* alphanum already included */
56 #define HS_ASSIGNMENTSTATE_AUTO -1
57 #define HS_ASSIGNMENTSTATE_OFF 0
58 #define HS_ASSIGNMENTSTATE_ON 1
60 #define HS_FHPARSE_SUCCESS 0
61 #define HS_FHPARSE_INVALID 1
62 #define HS_FHPARSE_UNKNOWN 2
64 static const struct message_entry msgtab[] = {
65 { "HSMSG_ACCESS_DENIED", "Access denied." },
66 { "HSMSG_ASSIGNED_FAKEHOSTS", "Assigned Fakehosts for User $b%s$b:" },
67 { "HSMSG_ASSIGNED_FAKEHOST", " $b%s.%s$b" },
68 { "HSMSG_ASSIGNED_FAKEHOST_ACTTIVE", " $b%s.%s$b (active)" },
69 { "HSMSG_ASSIGNED_FAKEHOST_NOT_ACTIVE", "Fakehost $b%s.%s.$b is not active." },
70 { "HSMSG_ASSIGN_HOWTO", "Use $bset xxx.yyy$b to activate one of the listed fakehosts or $bset *$b to use the default fakehost." },
71 { "HSMSG_ASSIGNED_NONE", " None." },
72 { "HSMSG_MANAGED_FAKEHOSTS", "Fakehosts managed by User $b%s$b:" },
73 { "HSMSG_MANAGED_TOPLEVEL", " $b*.%s$b fakehosts: %d assignments: %d" },
74 { "HSMSG_MANAGED_TOPLEVEL_OWN", " $b*.%s$b fakehosts: %d assignments: %d (active)" },
75 { "HSMSG_MANAGED_FAKEHOST", " $b%s.%s$b assignments: %d" },
76 { "HSMSG_MANAGE_HOWTO", "Use $bview xxx.yyy$b to view more information about a fakehost group." },
77 { "HSMSG_UNKNOWN_FAKEHOST", "Fakehost $b%s.%s$b is unknown or you have no access to manage it." },
78 { "HSMSG_TOPLEVEL_FAKEHOSTS", "Fakehosts in group $b*.%s$b:" },
79 { "HSMSG_TOPLEVEL_FAKEHOST", " $b%s.%s$b assignments: %d managers: %d" },
80 { "HSMSG_TOPLEVEL_INVALID", "The name of the group you entered is invalid ($b%s$b)" },
81 { "HSMSG_MANAGERS_TOPLEVEL", "Managers of group $b*.%s$b:" },
82 { "HSMSG_MANAGERS_FAKEHOST", "Managers of group $b%s.%s$b:" },
83 { "HSMSG_MANAGERS_MANAGERS", " %s" },
84 { "HSMSG_FAKEHOST_ASSIGNMENTS", "Assignments in group $b%s.%s$b:" },
85 { "HSMSG_FAKEHOST_ASSIGNMENT", " $b%s$b (%s.%s.%s)" },
86 { "HSMSG_FAKEHOST_ASSIGNMENT_ACTIVE", " $b%s$b (%s.%s.%s) active" },
87 { "HSMSG_FAKEHOST_SET_SUCCESS", "$b%s.%s$b where set successfully." },
88 { "HSMSG_FAKEHOST_TOPLEVEL_ADDED", "Group $b%s$b successfully added." },
89 { "HSMSG_FAKEHOST_TOPLEVEL_ALREADY_EXISTS", "Group $b%s$b already exists." },
90 { "HSMSG_FAKEHOST_TOPLEVEL_DELETED", "Group $b%s$b successfully deleted." },
91 { "HSMSG_FAKEHOST_SECONDLEVEL_ADDED", "Group $b%s.%s$b successfully added." },
92 { "HSMSG_FAKEHOST_SECONDLEVEL_ALREADY_EXISTS", "Group $b%s.%s$b already exists." },
93 { "HSMSG_FAKEHOST_SECONDLEVEL_DELETED", "Group $b%s.%s$b successfully deleted." },
94 { "HSMSG_FAKEHOST_RENAMED", "Group $b%s.%s$b renamed to $b%s.%s$b." },
95 { "HSMSG_MANAGER_ALREADY", "$b%s$b is already a manager of %s.%s" },
96 { "HSMSG_MANAGER_ADDED", "$b%s$b is now a manager of %s.%s" },
97 { "HSMSG_MANAGER_NOT", "$b%s$b is not a manager of %s.%s" },
98 { "HSMSG_MANAGER_DELETED", "$b%s$b is no longer a manager of %s.%s" },
99 { "HSMSG_FAKEHOST_ASSIGN_SUCCESS", "Group $b%s.%s$b was assigned successfully." },
100 { "HSMSG_FAKEHOST_ASSIGNED", "Group $b%s.%s$b is already assigned to the user." },
101 { "HSMSG_FAKEHOST_UNASSIGN_SUCCESS", "Group $b%s.%s$b was unassigned successfully." },
110 int fallback_other_assignment : 1;
111 int manager_can_del_toplevel : 1;
112 int manager_can_del_secondlevel : 1;
113 int manager_can_rename_toplevel : 1;
114 int manager_can_rename_secondlevel : 1;
117 const char *hostserv_module_deps[] = { NULL };
118 struct userNode *hostserv;
119 struct helpfile *hostserv_helpfile;
120 static struct module *hostserv_module;
121 static struct service *hostserv_service;
122 static struct log_type *HS_LOG;
123 static struct hs_toplevel *toplevels = NULL;
124 static struct hs_user *hostserv_users = NULL;
126 /* FAKEHOST STRUCTS */
129 struct hs_manager *managers;
130 struct hs_secondlevel *secondlevel;
131 struct hs_toplevel *next;
134 struct hs_secondlevel {
135 struct hs_toplevel *toplevel;
137 struct hs_manager *managers;
138 struct hs_assignment *assignments;
139 struct hs_secondlevel *next;
142 struct hs_assignment {
143 struct hs_secondlevel *secondlevel;
144 struct hs_user *user;
146 struct hs_assignment *next;
147 struct hs_assignment *unext; /* for hs_user */
154 struct hs_user *user;
155 struct hs_manager *next;
156 struct hs_manager *unext; /* for hs_user */
160 struct handle_info *hi;
161 struct hs_assignment *assignments;
162 struct hs_manager *managements;
163 struct hs_user *next;
166 /* temporary structs */
167 struct hs_fakehost_info {
171 struct hs_toplevel *tlfh;
172 struct hs_secondlevel *slfh;
175 /* MANAGEMENT FUNCTIONS for FAKEHOST STRUCTS */
176 static void hs_del_secondlevel(struct hs_secondlevel *slfh, int remove_from_tlfh);
177 static void hs_del_manager(struct hs_manager *manager, int remove_from_object);
178 static void hs_del_assignment(struct hs_assignment *assignment, int remove_from_slfh);
179 static void hs_del_user(struct hs_user *user);
180 static void hs_activate_assignment(struct hs_user *user, struct hs_assignment *assignment);
182 static void hs_free_all() {
183 struct hs_toplevel *tlfh, *next_tlfh;
184 struct hs_secondlevel *slfh, *next_slfh;
185 struct hs_assignment *assng, *next_assng;
186 struct hs_manager *manager, *next_manager;
187 struct hs_user *user, *next_user;
188 for(tlfh = toplevels; tlfh; tlfh = next_tlfh) {
189 next_tlfh = tlfh->next;
190 for(manager = tlfh->managers; manager; manager = next_manager) {
191 next_manager = manager->next;
194 for(slfh = tlfh->secondlevel; slfh; slfh = next_slfh) {
195 next_slfh = slfh->next;
196 for(manager = slfh->managers; manager; manager = next_manager) {
197 next_manager = manager->next;
200 for(assng = slfh->assignments; assng; assng = next_assng) {
201 next_assng = assng->next;
204 free(slfh->fakehost);
207 free(tlfh->fakehost);
210 for(user = hostserv_users; user; user = next_user) {
211 next_user = user->next;
215 hostserv_users = NULL;
218 static struct hs_toplevel *hs_add_toplevel(const char *name) {
219 struct hs_toplevel *tlfh = calloc(1, sizeof(*tlfh));
220 tlfh->fakehost = strdup(name);
221 tlfh->next = toplevels;
226 static void hs_del_toplevel(struct hs_toplevel *tlfh) {
227 //unassign all assignments
228 struct hs_secondlevel *slfh, *next_slfh;
229 struct hs_manager *manager, *next_manager;
230 for(manager = tlfh->managers; manager; manager = next_manager) {
231 next_manager = manager->next;
232 hs_del_manager(manager, 0);
234 for(slfh = tlfh->secondlevel; slfh; slfh = next_slfh) {
235 next_slfh = slfh->next;
236 hs_del_secondlevel(slfh, 0);
239 struct hs_toplevel *ctlfh, *last_tlfh = NULL;
240 for(ctlfh = toplevels; ctlfh; ctlfh = ctlfh->next) {
243 last_tlfh->next = ctlfh->next;
245 toplevels = ctlfh->next;
249 free(tlfh->fakehost);
253 static void hs_rename_toplevel(struct hs_toplevel *tlfh, const char *name) {
254 struct hs_secondlevel *slfh;
255 struct hs_assignment *assng;
257 free(tlfh->fakehost);
258 tlfh->fakehost = strdup(name);
260 //trigger rename for all assignments
261 for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) {
262 for(assng = slfh->assignments; assng; assng = assng->next) {
264 hs_activate_assignment(assng->user, assng);
270 static struct hs_secondlevel *hs_add_secondlevel(struct hs_toplevel *tlfh, const char *name) {
271 struct hs_secondlevel *slfh = calloc(1, sizeof(*slfh));
272 slfh->toplevel = tlfh;
273 slfh->fakehost = strdup(name);
274 slfh->next = tlfh->secondlevel;
275 tlfh->secondlevel = slfh;
279 static void hs_del_secondlevel(struct hs_secondlevel *slfh, int remove_from_tlfh) {
280 if(remove_from_tlfh) {
281 struct hs_secondlevel *cslfh, *prev_slfh = NULL;
282 for(cslfh = slfh->toplevel->secondlevel; cslfh; cslfh = cslfh->next) {
285 prev_slfh->next = slfh->next;
287 slfh->toplevel->secondlevel = slfh->next;
293 struct hs_assignment *assng, *next_assng;
294 struct hs_manager *manager, *next_manager;
295 for(manager = slfh->managers; manager; manager = next_manager) {
296 next_manager = manager->next;
297 hs_del_manager(manager, 0);
299 for(assng = slfh->assignments; assng; assng = next_assng) {
300 next_assng = assng->next;
301 hs_del_assignment(assng, 0);
303 free(slfh->fakehost);
307 static void hs_rename_secondlevel(struct hs_secondlevel *slfh, const char *name) {
308 struct hs_assignment *assng;
310 free(slfh->fakehost);
311 slfh->fakehost = strdup(name);
313 //trigger rename for all assignments
314 for(assng = slfh->assignments; assng; assng = assng->next) {
316 hs_activate_assignment(assng->user, assng);
321 static struct hs_manager *hs_add_manager_toplevel(struct hs_toplevel *tlfh, struct hs_user *user) {
322 struct hs_manager *manager = calloc(1, sizeof(*manager));
323 manager->user = user;
325 manager->object = tlfh;
326 manager->unext = user->managements;
327 user->managements = manager;
328 manager->next = tlfh->managers;
329 tlfh->managers = manager;
333 static struct hs_manager *hs_add_manager_secondlevel(struct hs_secondlevel *slfh, struct hs_user *user) {
334 struct hs_manager *manager = calloc(1, sizeof(*manager));
335 manager->user = user;
337 manager->object = slfh;
338 manager->unext = user->managements;
339 user->managements = manager;
340 manager->next = slfh->managers;
341 slfh->managers = manager;
345 static void hs_del_manager(struct hs_manager *manager, int remove_from_object) {
346 struct hs_manager *cmanager, *prev_manager = NULL;
347 if(remove_from_object) {
348 if(manager->type == 1) {
349 struct hs_toplevel *tlfh = manager->object;
350 for(cmanager = tlfh->managers; cmanager; cmanager = cmanager->next) {
351 if(cmanager == manager) {
353 prev_manager->next = manager->next;
355 tlfh->managers = manager->next;
358 prev_manager = cmanager;
360 } else if(manager->type == 2) {
361 struct hs_secondlevel *slfh = manager->object;
362 for(cmanager = slfh->managers; cmanager; cmanager = cmanager->next) {
363 if(cmanager == manager) {
365 prev_manager->next = manager->next;
367 slfh->managers = manager->next;
370 prev_manager = cmanager;
375 if(remove_from_object != 2) {
376 for(cmanager = manager->user->managements; cmanager; cmanager = cmanager->unext) {
377 if(cmanager == manager) {
379 prev_manager->unext = manager->unext;
381 manager->user->managements = manager->unext;
384 prev_manager = cmanager;
386 if(manager->user->managements == NULL && manager->user->assignments == NULL)
387 hs_del_user(manager->user);
392 static void hs_activate_assignment(struct hs_user *user, struct hs_assignment *assignment) {
393 struct hs_toplevel *tlfh;
394 struct hs_secondlevel *slfh;
395 struct hs_assignment *assgn;
396 char fakehost[HOSTLEN];
398 assert((!assignment || (assignment->user == user)));
400 if(user->assignments) {
401 for(assgn = user->assignments; assgn; assgn = assgn->unext)
405 if(user->hi->fakehost) {
406 free(user->hi->fakehost);
407 user->hi->fakehost = NULL;
411 slfh = assignment->secondlevel;
412 tlfh = slfh->toplevel;
413 snprintf(fakehost, sizeof(fakehost), "$.%s.%s", slfh->fakehost, tlfh->fakehost);
414 user->hi->fakehost = strdup(fakehost);
415 assignment->active = 1;
418 apply_fakehost(user->hi, NULL);
421 static struct hs_assignment *hs_add_assignment(struct hs_secondlevel *slfh, struct hs_user *user, int active) {
422 struct hs_assignment *assignment = calloc(1, sizeof(*assignment));
423 assignment->secondlevel = slfh;
424 assignment->user = user;
425 if(active == HS_ASSIGNMENTSTATE_AUTO)
426 assignment->active = (user->assignments == NULL ? 1 : 0);
428 assignment->active = (active == HS_ASSIGNMENTSTATE_ON ? 1 : 0);
429 assignment->next = slfh->assignments;
430 slfh->assignments = assignment;
431 assignment->unext = user->assignments;
432 user->assignments = assignment;
433 if(assignment->active) {
434 hs_activate_assignment(user, assignment);
439 static void hs_del_assignment(struct hs_assignment *assignment, int remove_from_slfh) {
440 struct hs_assignment *cassignment, *prev_assignment = NULL;
441 if(remove_from_slfh) {
442 for(cassignment = assignment->secondlevel->assignments; cassignment; cassignment = cassignment->next) {
443 if(cassignment == assignment) {
445 prev_assignment->next = assignment->next;
447 assignment->secondlevel->assignments = assignment->next;
450 prev_assignment = cassignment;
452 prev_assignment = NULL;
454 if(remove_from_slfh != 2) {
455 prev_assignment = NULL;
456 for(cassignment = assignment->user->assignments; cassignment; cassignment = cassignment->unext) {
457 if(cassignment == assignment) {
459 prev_assignment->unext = assignment->unext;
461 assignment->user->assignments = assignment->unext;
464 prev_assignment = cassignment;
467 if(assignment->active) {
468 /* use another assignment - or fall back to default user host? */
470 if(hostserv_conf.fallback_other_assignment && assignment->user->assignments) {
471 /* try to find another assignment from same slfh first */
472 for(cassignment = assignment->secondlevel->assignments; cassignment; cassignment = cassignment->next) {
473 if(cassignment != assignment && cassignment->user == assignment->user)
476 /* use another tlfh assignment */
478 cassignment = assignment->user->assignments;
480 hs_activate_assignment(assignment->user, cassignment);
483 if(assignment->user->managements == NULL && assignment->user->assignments == NULL)
484 hs_del_user(assignment->user);
489 static struct hs_assignment *hs_get_assignment(struct hs_secondlevel *slfh, struct hs_user *user) {
490 struct hs_assignment *cassignment;
491 for(cassignment = slfh->assignments; cassignment; cassignment = cassignment->next) {
492 if(cassignment->user == user)
498 static struct hs_user *hs_get_user(struct handle_info *hi, int create) {
499 struct hs_user *cuser;
500 for(cuser = hostserv_users; cuser; cuser = cuser->next) {
505 cuser = calloc(1, sizeof(*cuser));
507 cuser->next = hostserv_users;
508 hostserv_users = cuser;
514 static void hs_del_user(struct hs_user *user) {
515 if(user->managements) {
516 struct hs_manager *manager, *next_manager;
517 for(manager = user->managements; manager; manager = next_manager) {
518 next_manager = manager->unext;
519 hs_del_manager(manager, 2);
522 if(user->assignments) {
523 struct hs_assignment *assng, *next_assng;
524 for(assng = user->assignments; assng; assng = next_assng) {
525 next_assng = assng->unext;
526 hs_del_assignment(assng, 2);
529 struct hs_user *cuser, *prev_user = NULL;
530 for(cuser = hostserv_users; cuser; cuser = cuser->next) {
533 prev_user->next = user->next;
535 hostserv_users = user->next;
543 /* END OF MANAGEMENT FUNCTIONS */
545 static int check_management_access(struct handle_info *hi, struct hs_toplevel *tlfh, struct hs_secondlevel *slfh) {
548 if(hi->opserv_level >= hostserv_conf.toplevel_access)
550 struct hs_user *user = hs_get_user(hi, 0);
553 struct hs_manager *manager;
555 for(manager = user->managements; manager; manager = manager->next) {
556 if(manager->type == 2 && manager->object == slfh)
561 for(manager = user->managements; manager; manager = manager->next) {
562 if(manager->type == 1 && manager->object == tlfh)
569 struct hs_fakehost_info parse_fakehost_info(char *fakehost, int fix_name_case) {
570 struct hs_fakehost_info fhinfo;
572 for(i = strlen(fakehost)-1; i >= 0; i--) {
573 if(!isalnum(fakehost[i]) && !strchr(HS_FAKEHOST_SPECIAL_CHARS, fakehost[i])) {
574 fhinfo.parse_state = HS_FHPARSE_INVALID;
578 fhinfo.slfh_name = fakehost;
579 fhinfo.tlfh_name = strchr(fakehost, '.');
580 if(!fhinfo.tlfh_name) {
581 fhinfo.parse_state = HS_FHPARSE_INVALID;
584 fhinfo.tlfh_name[0] = '\0';
586 if(strchr(fhinfo.tlfh_name, '.')) {
587 fhinfo.parse_state = HS_FHPARSE_INVALID;
589 fhinfo.tlfh_name[0] = '\0';
592 if(!irccasecmp(fhinfo.slfh_name, "*"))
593 fhinfo.slfh_name = NULL;
594 struct hs_toplevel *tlfh;
595 struct hs_secondlevel *slfh;
596 for(tlfh = toplevels; tlfh; tlfh = tlfh->next) {
597 if(!irccasecmp(tlfh->fakehost, fhinfo.tlfh_name)) break;
602 fhinfo.parse_state = HS_FHPARSE_UNKNOWN;
605 if(fhinfo.slfh_name) {
606 for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) {
607 if(!irccasecmp(slfh->fakehost, fhinfo.slfh_name)) break;
611 fhinfo.parse_state = HS_FHPARSE_UNKNOWN;
617 //simply copy the stored fakehosts over the given ones
618 strcpy(fhinfo.tlfh_name, fhinfo.tlfh->fakehost);
619 strcpy(fhinfo.slfh_name, fhinfo.slfh->fakehost);
621 fhinfo.parse_state = HS_FHPARSE_SUCCESS;
627 static void cmd_view_toplevel_information(UNUSED_ARG(struct userNode *user), UNUSED_ARG(struct svccmd *cmd), struct hs_toplevel *tlfh) {
628 reply("HSMSG_TOPLEVEL_FAKEHOSTS", tlfh->fakehost);
629 struct hs_secondlevel *slfh;
630 if(!tlfh->secondlevel)
631 reply("HSMSG_ASSIGNED_NONE");
633 for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) {
634 struct hs_manager *cmanager;
636 for(cmanager = slfh->managers; cmanager; cmanager = cmanager->next)
638 struct hs_assignment *assignment;
640 for(assignment = slfh->assignments; assignment; assignment = assignment->next)
642 reply("HSMSG_TOPLEVEL_FAKEHOST", slfh->fakehost, tlfh->fakehost, assignments, managers);
644 reply("HSMSG_MANAGERS_TOPLEVEL", tlfh->fakehost);
645 struct hs_manager *cmanager;
647 reply("HSMSG_ASSIGNED_NONE");
649 char managerBuf[351];
651 for(cmanager = tlfh->managers; cmanager; cmanager = cmanager->next) {
652 if(managerPos + strlen(cmanager->user->hi->handle) + 2 >= 350) {
653 reply("HSMSG_MANAGERS_MANAGERS", managerBuf);
656 managerPos += sprintf(managerBuf + managerPos, (managerPos ? ", %s" : "%s"), cmanager->user->hi->handle);
658 reply("HSMSG_MANAGERS_MANAGERS", managerBuf);
662 static void cmd_view_secondlevel_information(UNUSED_ARG(struct userNode *user), UNUSED_ARG(struct svccmd *cmd), struct hs_secondlevel *slfh) {
663 reply("HSMSG_FAKEHOST_ASSIGNMENTS", slfh->fakehost, slfh->toplevel->fakehost);
664 struct hs_assignment *assignment;
665 for(assignment = slfh->assignments; assignment; assignment = assignment->next) {
666 reply((assignment->active ? "HSMSG_FAKEHOST_ASSIGNMENT_ACTIVE" : "HSMSG_FAKEHOST_ASSIGNMENT"), assignment->user->hi->handle, assignment->user->hi->handle, slfh->fakehost, slfh->toplevel->fakehost);
668 reply("HSMSG_MANAGERS_FAKEHOST", slfh->fakehost, slfh->toplevel->fakehost);
669 struct hs_manager *cmanager;
671 reply("HSMSG_ASSIGNED_NONE");
673 char managerBuf[351];
675 for(cmanager = slfh->managers; cmanager; cmanager = cmanager->next) {
676 if(managerPos + strlen(cmanager->user->hi->handle) + 2 >= 350) {
677 reply("HSMSG_MANAGERS_MANAGERS", managerBuf);
680 managerPos += sprintf(managerBuf + managerPos, (managerPos ? ", %s" : "%s"), cmanager->user->hi->handle);
682 reply("HSMSG_MANAGERS_MANAGERS", managerBuf);
686 static MODCMD_FUNC(cmd_view) {
687 struct handle_info *hi;
688 if(argc >= 2 && !strchr(argv[1], '.')) {
689 if (!(hi = modcmd_get_handle_info(user, argv[1])))
691 } else if(argc >= 2) {
692 if (!(hi = user->handle_info)) {
693 reply("NSMSG_MUST_AUTH");
696 struct hs_fakehost_info fhinfo = parse_fakehost_info(argv[1], 0);
697 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
698 reply("HSMSG_TOPLEVEL_INVALID", argv[1]);
700 } else if(fhinfo.parse_state == HS_FHPARSE_UNKNOWN) {
701 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
705 if(!check_management_access(hi, fhinfo.tlfh, NULL)) {
706 reply("HSMSG_ACCESS_DENIED");
709 cmd_view_toplevel_information(user, cmd, fhinfo.tlfh);
712 if(!check_management_access(hi, fhinfo.tlfh, fhinfo.slfh)) {
713 reply("HSMSG_ACCESS_DENIED");
716 cmd_view_secondlevel_information(user, cmd, fhinfo.slfh);
720 if (!(hi = user->handle_info)) {
721 reply("NSMSG_MUST_AUTH");
725 struct hs_user *huser = hs_get_user(hi, 0);
726 reply("HSMSG_ASSIGNED_FAKEHOSTS", hi->handle);
729 struct hs_assignment *assignment;
730 for(assignment = huser->assignments; assignment; assignment = assignment->unext) {
731 reply((assignment->active ? "HSMSG_ASSIGNED_FAKEHOST_ACTTIVE" : "HSMSG_ASSIGNED_FAKEHOST"), assignment->secondlevel->fakehost, assignment->secondlevel->toplevel->fakehost);
734 if(assigncount && huser->hi == user->handle_info)
735 reply("HSMSG_ASSIGN_HOWTO");
738 reply("HSMSG_ASSIGNED_NONE");
739 if(user->handle_info == hi && hi->opserv_level >= hostserv_conf.toplevel_access) {
740 struct hs_toplevel *tlfh;
741 for(tlfh = toplevels; tlfh; tlfh = tlfh->next) {
742 struct hs_secondlevel *slfh;
743 struct hs_assignment *assignment;
744 int slfhs = 0, assignments = 0;
745 for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) {
747 for(assignment = slfh->assignments; assignment; assignment = assignment->next)
750 reply("HSMSG_MANAGED_TOPLEVEL", tlfh->fakehost, slfhs, assignments);
752 reply("HSMSG_MANAGE_HOWTO");
753 } else if(huser && huser->managements) {
754 reply("HSMSG_MANAGED_FAKEHOSTS", hi->handle);
755 struct hs_manager *manager;
756 for(manager = huser->managements; manager; manager = manager->unext) {
757 if(manager->type == 1) {
758 struct hs_toplevel *tlfh = manager->object;
759 struct hs_secondlevel *slfh;
760 struct hs_assignment *assignment;
761 int slfhs = 0, assignments = 0;
762 for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) {
764 for(assignment = slfh->assignments; assignment; assignment = assignment->next)
767 reply("HSMSG_MANAGED_TOPLEVEL", tlfh->fakehost, slfhs, assignments);
770 for(manager = huser->managements; manager; manager = manager->next) {
771 if(manager->type == 2) {
772 struct hs_secondlevel *slfh = manager->object;
773 struct hs_toplevel *tlfh = slfh->toplevel;
774 //check if the user is already a manager of the tlfh
775 struct hs_manager *cmanager;
776 for(cmanager = tlfh->managers; cmanager; cmanager = cmanager->next) {
777 if(cmanager->user == huser) break;
779 if(cmanager) continue;
780 struct hs_assignment *assignment;
782 for(assignment = slfh->assignments; assignment; assignment = assignment->next)
784 reply("HSMSG_MANAGED_FAKEHOST", slfh->fakehost, tlfh->fakehost, assignments);
787 if(huser->hi == user->handle_info)
788 reply("HSMSG_MANAGE_HOWTO");
793 static MODCMD_FUNC(cmd_addhost) {
794 struct handle_info *hi;
795 if (!(hi = user->handle_info)) {
796 reply("NSMSG_MUST_AUTH");
799 struct hs_fakehost_info fhinfo = parse_fakehost_info(argv[1], 1);
800 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
801 reply("HSMSG_TOPLEVEL_INVALID", argv[1]);
804 if(!fhinfo.slfh_name) {
805 if(!check_management_access(hi, NULL, NULL)) {
806 reply("HSMSG_ACCESS_DENIED");
809 if(fhinfo.parse_state != HS_FHPARSE_UNKNOWN) {
810 reply("HSMSG_FAKEHOST_TOPLEVEL_ALREADY_EXISTS", fhinfo.slfh_name, fhinfo.tlfh_name);
813 hs_add_toplevel(fhinfo.tlfh_name);
814 reply("HSMSG_FAKEHOST_TOPLEVEL_ADDED", fhinfo.tlfh_name);
817 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
820 if(!check_management_access(hi, fhinfo.tlfh, NULL)) {
821 reply("HSMSG_ACCESS_DENIED");
824 if(fhinfo.parse_state != HS_FHPARSE_UNKNOWN) {
825 reply("HSMSG_FAKEHOST_SECONDLEVEL_ALREADY_EXISTS", fhinfo.slfh_name, fhinfo.tlfh_name);
828 hs_add_secondlevel(fhinfo.tlfh, fhinfo.slfh_name);
829 reply("HSMSG_FAKEHOST_SECONDLEVEL_ADDED", fhinfo.slfh_name, fhinfo.tlfh_name);
834 static MODCMD_FUNC(cmd_delhost) {
835 struct handle_info *hi;
836 if (!(hi = user->handle_info)) {
837 reply("NSMSG_MUST_AUTH");
840 struct hs_fakehost_info fhinfo = parse_fakehost_info(argv[1], 1);
841 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
842 reply("HSMSG_TOPLEVEL_INVALID", argv[1]);
844 } else if(fhinfo.parse_state == HS_FHPARSE_UNKNOWN) {
845 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
849 if(!check_management_access(hi, (hostserv_conf.manager_can_del_toplevel ? fhinfo.tlfh : NULL), NULL)) { /* manager access is enough to delete whole toplevel? */
850 reply("HSMSG_ACCESS_DENIED");
853 hs_del_toplevel(fhinfo.tlfh);
854 reply("HSMSG_FAKEHOST_TOPLEVEL_DELETED", fhinfo.tlfh_name);
856 if(!check_management_access(hi, fhinfo.tlfh, (hostserv_conf.manager_can_del_secondlevel ? fhinfo.slfh : NULL))) {
857 reply("HSMSG_ACCESS_DENIED");
860 hs_del_secondlevel(fhinfo.slfh, 1);
861 reply("HSMSG_FAKEHOST_SECONDLEVEL_DELETED", fhinfo.slfh_name, fhinfo.tlfh_name);
866 static MODCMD_FUNC(cmd_renamehost) {
867 struct handle_info *hi;
868 if (!(hi = user->handle_info)) {
869 reply("NSMSG_MUST_AUTH");
873 struct hs_fakehost_info fhinfo = parse_fakehost_info(argv[1], 1);
874 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
875 reply("HSMSG_TOPLEVEL_INVALID", argv[1]);
877 } else if(fhinfo.parse_state == HS_FHPARSE_UNKNOWN) {
878 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
882 struct hs_fakehost_info new_fhinfo = parse_fakehost_info(argv[2], 0);
883 if(new_fhinfo.parse_state == HS_FHPARSE_INVALID) {
884 reply("HSMSG_TOPLEVEL_INVALID", argv[1]);
886 } else if(new_fhinfo.parse_state != HS_FHPARSE_UNKNOWN && (irccasecmp(fhinfo.tlfh_name, new_fhinfo.tlfh_name) || (new_fhinfo.slfh && new_fhinfo.slfh_name && irccasecmp(fhinfo.slfh_name, new_fhinfo.slfh_name)))) {
887 reply("HSMSG_FAKEHOST_TOPLEVEL_ALREADY_EXISTS", new_fhinfo.slfh_name, new_fhinfo.tlfh_name);
892 if(!check_management_access(hi, (hostserv_conf.manager_can_rename_toplevel ? fhinfo.tlfh : NULL), NULL)) { /* manager access is enough to delete whole toplevel? */
893 reply("HSMSG_ACCESS_DENIED");
896 if(new_fhinfo.slfh_name) {
897 //can't rename toplevel into secondlevel fakehost!
898 new_fhinfo.tlfh_name--;
899 new_fhinfo.tlfh_name[0] = '.';
900 reply("HSMSG_TOPLEVEL_INVALID", new_fhinfo.slfh_name);
903 if(strcmp(new_fhinfo.tlfh_name, fhinfo.tlfh->fakehost))
904 hs_rename_toplevel(fhinfo.tlfh, new_fhinfo.tlfh_name);
905 reply("HSMSG_FAKEHOST_RENAMED", fhinfo.slfh_name, fhinfo.tlfh_name, new_fhinfo.slfh_name, new_fhinfo.tlfh_name);
907 if(!check_management_access(hi, fhinfo.tlfh, (hostserv_conf.manager_can_rename_secondlevel ? fhinfo.slfh : NULL))) {
908 reply("HSMSG_ACCESS_DENIED");
911 if(irccasecmp(new_fhinfo.tlfh_name, fhinfo.tlfh_name)) {
912 //can't rename toplevel and secondlevel fakehost with one command!
913 new_fhinfo.tlfh_name--;
914 new_fhinfo.tlfh_name[0] = '.';
915 reply("HSMSG_TOPLEVEL_INVALID", new_fhinfo.slfh_name);
918 if(strcmp(new_fhinfo.slfh_name, fhinfo.slfh->fakehost))
919 hs_rename_secondlevel(fhinfo.slfh, new_fhinfo.slfh_name);
920 reply("HSMSG_FAKEHOST_RENAMED", fhinfo.slfh_name, fhinfo.tlfh_name, new_fhinfo.slfh_name, new_fhinfo.tlfh_name);
925 static MODCMD_FUNC(cmd_addmanager) {
926 struct handle_info *hi;
928 if(!strchr(argv[1], '.')) {
929 if (!(hi = modcmd_get_handle_info(user, argv[1])))
933 if (!(hi = modcmd_get_handle_info(user, argv[2])))
937 struct hs_fakehost_info fhinfo = parse_fakehost_info(fakehost, 1);
938 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
939 reply("HSMSG_TOPLEVEL_INVALID", fakehost);
941 } else if(fhinfo.parse_state == HS_FHPARSE_UNKNOWN) {
942 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
945 if(!check_management_access(user->handle_info, fhinfo.tlfh, fhinfo.slfh)) {
946 reply("HSMSG_ACCESS_DENIED");
949 struct hs_user *huser = hs_get_user(hi, 1);
950 struct hs_manager *manager;
952 for(manager = huser->managements; manager; manager = manager->next) {
953 if(manager->type == 2 && manager->object == fhinfo.slfh) {
954 reply("HSMSG_MANAGER_ALREADY", hi->handle, fhinfo.slfh_name, fhinfo.tlfh_name);
959 for(manager = huser->managements; manager; manager = manager->next) {
960 if(manager->type == 1 && manager->object == fhinfo.tlfh) {
961 reply("HSMSG_MANAGER_ALREADY", hi->handle, "*", fhinfo.tlfh_name);
966 hs_add_manager_secondlevel(fhinfo.slfh, huser);
968 hs_add_manager_toplevel(fhinfo.tlfh, huser);
969 reply("HSMSG_MANAGER_ADDED", hi->handle, fhinfo.slfh_name, fhinfo.tlfh_name);
973 static MODCMD_FUNC(cmd_delmanager) {
974 struct handle_info *hi;
976 if(!strchr(argv[1], '.')) {
977 if (!(hi = modcmd_get_handle_info(user, argv[1])))
981 if (!(hi = modcmd_get_handle_info(user, argv[2])))
985 struct hs_fakehost_info fhinfo = parse_fakehost_info(fakehost, 1);
986 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
987 reply("HSMSG_TOPLEVEL_INVALID", fakehost);
989 } else if(fhinfo.parse_state == HS_FHPARSE_UNKNOWN) {
990 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
993 if(!check_management_access(user->handle_info, fhinfo.tlfh, fhinfo.slfh)) {
994 reply("HSMSG_ACCESS_DENIED");
997 struct hs_user *huser = hs_get_user(hi, 0);
998 struct hs_manager *manager;
1000 reply("HSMSG_MANAGER_NOT", hi->handle, fhinfo.slfh_name, fhinfo.tlfh_name);
1004 for(manager = huser->managements; manager; manager = manager->next) {
1005 if(manager->type == 2 && manager->object == fhinfo.slfh)
1009 reply("HSMSG_MANAGER_NOT", hi->handle, fhinfo.slfh_name, fhinfo.tlfh_name);
1013 for(manager = huser->managements; manager; manager = manager->next) {
1014 if(manager->type == 1 && manager->object == fhinfo.tlfh)
1018 reply("HSMSG_MANAGER_NOT", hi->handle, "*", fhinfo.tlfh_name);
1022 hs_del_manager(manager, 1);
1023 reply("HSMSG_MANAGER_DELETED", hi->handle, fhinfo.slfh_name, fhinfo.tlfh_name);
1027 static MODCMD_FUNC(cmd_set) {
1028 struct handle_info *hi;
1029 struct hs_user *hs_user;
1030 struct hs_assignment *assignment;
1031 struct hs_toplevel *tlfh;
1032 struct hs_secondlevel *slfh;
1034 if (!(hi = user->handle_info)) {
1035 reply("NSMSG_MUST_AUTH");
1038 hs_user = hs_get_user(hi, 0);
1040 return 0; //nothing to do here
1041 if(!strcmp(argv[1], "*")) {
1042 hs_activate_assignment(hs_user, NULL);
1045 struct hs_fakehost_info fhinfo = parse_fakehost_info(argv[1], 1);
1046 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
1047 reply("HSMSG_TOPLEVEL_INVALID", argv[1]);
1049 } else if(fhinfo.parse_state == HS_FHPARSE_UNKNOWN) {
1050 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
1053 for(assignment = hs_user->assignments; assignment; assignment = assignment->unext) {
1054 slfh = assignment->secondlevel;
1055 tlfh = slfh->toplevel;
1056 if(tlfh == fhinfo.tlfh && slfh == fhinfo.slfh) {
1057 hs_activate_assignment(hs_user, assignment);
1058 reply("HSMSG_FAKEHOST_SET_SUCCESS", slfh->fakehost, tlfh->fakehost);
1062 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
1067 static MODCMD_FUNC(cmd_assign) {
1068 struct handle_info *hi;
1070 if(!strchr(argv[1], '.')) {
1071 if (!(hi = modcmd_get_handle_info(user, argv[1])))
1075 if (!(hi = modcmd_get_handle_info(user, argv[2])))
1079 if (!user->handle_info) {
1080 reply("NSMSG_MUST_AUTH");
1083 struct hs_fakehost_info fhinfo = parse_fakehost_info(fakehost, 1);
1084 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
1085 reply("HSMSG_TOPLEVEL_INVALID", fakehost);
1087 } else if(fhinfo.parse_state == HS_FHPARSE_UNKNOWN || !fhinfo.slfh) {
1088 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
1091 struct hs_user *hs_user = hs_get_user(hi, 1);
1092 if(!check_management_access(user->handle_info, fhinfo.tlfh, fhinfo.slfh)) {
1093 reply("HSMSG_ACCESS_DENIED");
1096 if(hs_get_assignment(fhinfo.slfh, hs_user)) {
1097 reply("HSMSG_FAKEHOST_ASSIGNED", fhinfo.slfh_name, fhinfo.tlfh_name);
1100 hs_add_assignment(fhinfo.slfh, hs_user, HS_ASSIGNMENTSTATE_AUTO);
1101 reply("HSMSG_FAKEHOST_ASSIGN_SUCCESS", fhinfo.slfh_name, fhinfo.tlfh_name);
1105 static MODCMD_FUNC(cmd_unassign) {
1106 struct handle_info *hi;
1108 if(!strchr(argv[1], '.')) {
1109 if (!(hi = modcmd_get_handle_info(user, argv[1])))
1113 if (!(hi = modcmd_get_handle_info(user, argv[2])))
1117 if (!user->handle_info) {
1118 reply("NSMSG_MUST_AUTH");
1121 struct hs_fakehost_info fhinfo = parse_fakehost_info(fakehost, 1);
1122 if(fhinfo.parse_state == HS_FHPARSE_INVALID) {
1123 reply("HSMSG_TOPLEVEL_INVALID", fakehost);
1125 } else if(fhinfo.parse_state == HS_FHPARSE_UNKNOWN || !fhinfo.slfh) {
1126 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
1129 struct hs_assignment *assignment;
1130 struct hs_user *hs_user = hs_get_user(hi, 0);
1132 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
1135 if(!check_management_access(user->handle_info, fhinfo.tlfh, fhinfo.slfh)) {
1136 reply("HSMSG_ACCESS_DENIED");
1139 if(!(assignment = hs_get_assignment(fhinfo.slfh, hs_user))) {
1140 reply("HSMSG_UNKNOWN_FAKEHOST", fhinfo.slfh_name, fhinfo.tlfh_name);
1143 hs_del_assignment(assignment, 1);
1144 reply("HSMSG_FAKEHOST_UNASSIGN_SUCCESS", fhinfo.slfh_name, fhinfo.tlfh_name);
1148 static void hostserv_conf_read(void) {
1152 str = "modules/hostserv";
1153 if (!(conf_node = conf_get_data(str, RECDB_OBJECT))) {
1154 log_module(HS_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", str);
1158 str = database_get_data(conf_node, "nick", RECDB_QSTRING);
1159 if(hostserv_conf.nick && strcmp(hostserv_conf.nick, str)) {
1162 hostserv_conf.nick = str;
1164 str = database_get_data(conf_node, "modes", RECDB_QSTRING);
1165 hostserv_conf.modes = (str ? str : NULL);
1167 str = database_get_data(conf_node, "toplevel_access", RECDB_QSTRING);
1168 unsigned int toplevel_access = atoi(str);
1169 hostserv_conf.toplevel_access = (toplevel_access ? toplevel_access : 600);
1171 str = database_get_data(conf_node, "fallback_other_assignment", RECDB_QSTRING);
1172 hostserv_conf.fallback_other_assignment = (atoi(str) ? 1 : 0);
1174 str = database_get_data(conf_node, "manager_can_del_toplevel", RECDB_QSTRING);
1175 hostserv_conf.manager_can_del_toplevel = (atoi(str) ? 1 : 0);
1177 str = database_get_data(conf_node, "manager_can_del_secondlevel", RECDB_QSTRING);
1178 hostserv_conf.manager_can_del_secondlevel = (atoi(str) ? 1 : 0);
1180 str = database_get_data(conf_node, "manager_can_rename_toplevel", RECDB_QSTRING);
1181 hostserv_conf.manager_can_rename_toplevel = (atoi(str) ? 1 : 0);
1183 str = database_get_data(conf_node, "manager_can_rename_secondlevel", RECDB_QSTRING);
1184 hostserv_conf.manager_can_rename_secondlevel = (atoi(str) ? 1 : 0);
1186 /*str = database_get_data(conf_node, "description", RECDB_QSTRING);
1187 hostserv_conf.description = (str ? str : NULL);*/
1190 static int hostserv_saxdb_read_secondlevel(const char *name, void *data, UNUSED_ARG(void *extra));
1191 static int hostserv_saxdb_read_assignments(const char *name, void *data, UNUSED_ARG(void *extra));
1193 static int hostserv_saxdb_read_toplevel(const char *name, void *data, UNUSED_ARG(void *extra)) {
1194 struct record_data *rd = data;
1195 struct hs_toplevel *tlfh;
1196 struct hs_manager *managerTL;
1197 struct hs_user *user;
1198 struct dict *object;
1200 if (rd->type == RECDB_OBJECT) {
1201 dict_t db = GET_RECORD_OBJECT(rd);
1204 tlfh = hs_add_toplevel(name);
1206 if ((object = database_get_data(db, KEY_MANAGERS, RECDB_OBJECT))) {
1207 for (it = dict_first(object); it; it = iter_next(it)) {
1208 user = hs_get_user(get_handle_info(iter_key(it)), 1);
1209 //rd = iter_data(it);
1210 /* nothing in here, yet */
1211 managerTL = hs_add_manager_toplevel(tlfh, user);
1212 if (database_get_data(db, KEY_ACTIVE, RECDB_QSTRING))
1213 managerTL->active = 1;
1215 managerTL->active = 0;
1219 if ((object = database_get_data(db, KEY_SECONDLEVEL, RECDB_OBJECT)))
1220 dict_foreach(object, hostserv_saxdb_read_secondlevel, tlfh);
1225 static int hostserv_saxdb_read_secondlevel(const char *name, void *data, UNUSED_ARG(void *extra)) {
1226 struct record_data *rd = data;
1227 struct hs_toplevel *tlfh = extra;
1228 struct hs_secondlevel *slfh;
1229 struct hs_manager *managerSL;
1230 struct hs_user *user;
1231 struct dict *object;
1233 if (rd->type == RECDB_OBJECT) {
1234 dict_t db = GET_RECORD_OBJECT(rd);
1237 slfh = hs_add_secondlevel(tlfh, name);
1239 if ((object = database_get_data(db, KEY_MANAGERS, RECDB_OBJECT))) {
1240 for (it = dict_first(object); it; it = iter_next(it)) {
1241 user = hs_get_user(get_handle_info(iter_key(it)), 1);
1242 //rd = iter_data(it);
1243 /* nothing in here, yet */
1244 managerSL = hs_add_manager_secondlevel(slfh, user);
1245 if (database_get_data(db, KEY_ACTIVE, RECDB_QSTRING))
1246 managerSL->active = 1;
1248 managerSL->active = 0;
1252 if ((object = database_get_data(db, KEY_ASSIGNMENTS, RECDB_OBJECT)))
1253 dict_foreach(object, hostserv_saxdb_read_assignments, slfh);
1258 static int hostserv_saxdb_read_assignments(const char *name, void *data, UNUSED_ARG(void *extra)) {
1259 struct record_data *rd = data;
1260 struct hs_secondlevel *slfh = extra;
1261 struct hs_user *user;
1264 if (rd->type == RECDB_OBJECT) {
1265 dict_t db = GET_RECORD_OBJECT(rd);
1267 user = hs_get_user(get_handle_info(name), 1);
1268 active = (database_get_data(db, KEY_ACTIVE, RECDB_QSTRING) ? HS_ASSIGNMENTSTATE_ON : HS_ASSIGNMENTSTATE_OFF);
1270 hs_add_assignment(slfh, user, active);
1277 hostserv_saxdb_read(struct dict *db)
1279 struct dict *object;
1281 if ((object = database_get_data(db, KEY_TOPLEVEL, RECDB_OBJECT)))
1282 dict_foreach(object, hostserv_saxdb_read_toplevel, NULL);
1288 hostserv_saxdb_write(struct saxdb_context *ctx)
1290 struct hs_toplevel *tlfh;
1291 struct hs_secondlevel *slfh;
1292 struct hs_assignment *assng;
1293 struct hs_manager *manager;
1295 saxdb_start_record(ctx, KEY_TOPLEVEL, 1);
1296 for(tlfh = toplevels; tlfh; tlfh = tlfh->next) {
1297 saxdb_start_record(ctx, tlfh->fakehost, 1);
1299 saxdb_start_record(ctx, KEY_MANAGERS, 1);
1300 for(manager = tlfh->managers; manager; manager = manager->next) {
1301 saxdb_start_record(ctx, manager->user->hi->handle, 0);
1302 //additional manager information?
1304 saxdb_write_int(ctx, KEY_ACTIVE, manager->active);
1305 saxdb_end_record(ctx);
1307 saxdb_end_record(ctx);
1309 saxdb_start_record(ctx, KEY_SECONDLEVEL, 1);
1310 for(slfh = tlfh->secondlevel; slfh; slfh = slfh->next) {
1311 saxdb_start_record(ctx, slfh->fakehost, 1);
1313 saxdb_start_record(ctx, KEY_MANAGERS, 1);
1314 for(manager = slfh->managers; manager; manager = manager->next) {
1315 saxdb_start_record(ctx, manager->user->hi->handle, 0);
1316 //additional manager information?
1318 saxdb_write_int(ctx, KEY_ACTIVE, manager->active);
1319 saxdb_end_record(ctx);
1321 saxdb_end_record(ctx);
1323 saxdb_start_record(ctx, KEY_ASSIGNMENTS, 1);
1324 for(assng = slfh->assignments; assng; assng = assng->next) {
1325 saxdb_start_record(ctx, assng->user->hi->handle, 0);
1326 //additional assignment information?
1328 saxdb_write_int(ctx, KEY_ACTIVE, assng->active);
1329 saxdb_end_record(ctx);
1331 saxdb_end_record(ctx);
1333 saxdb_end_record(ctx);
1335 saxdb_end_record(ctx);
1337 saxdb_end_record(ctx);
1339 saxdb_end_record(ctx);
1345 static void hostserv_db_cleanup(void) {
1349 int hostserv_init() {
1350 HS_LOG = log_register_type("HostServ", "file:hostserv.log");
1352 const char *nick, *modes;
1353 if((nick = conf_get_data("modules/hostserv/nick", RECDB_QSTRING))) {
1354 modes = conf_get_data("modules/hostserv/modes", RECDB_QSTRING);
1355 hostserv = AddLocalUser(nick, nick, NULL, "Host Service", modes);
1356 hostserv_service = service_register(hostserv);
1357 hostserv_service->trigger = '*';
1360 conf_register_reload(hostserv_conf_read);
1361 reg_exit_func(hostserv_db_cleanup);
1362 saxdb_register("HostServ", hostserv_saxdb_read, hostserv_saxdb_write);
1363 hostserv_module = module_register("HostServ", HS_LOG, "mod-hostserv.help", NULL);
1364 modcmd_register(hostserv_module, "view", cmd_view, 0, MODCMD_REQUIRE_AUTHED, NULL);
1365 modcmd_register(hostserv_module, "addmanager", cmd_addmanager, 3, MODCMD_REQUIRE_AUTHED, NULL);
1366 modcmd_register(hostserv_module, "delmanager", cmd_delmanager, 3, MODCMD_REQUIRE_AUTHED, NULL);
1367 modcmd_register(hostserv_module, "set", cmd_set, 2, MODCMD_REQUIRE_AUTHED, NULL);
1368 modcmd_register(hostserv_module, "assign", cmd_assign, 3, MODCMD_REQUIRE_AUTHED, NULL);
1369 modcmd_register(hostserv_module, "unassign", cmd_unassign, 3, MODCMD_REQUIRE_AUTHED, NULL);
1370 modcmd_register(hostserv_module, "addhost", cmd_addhost, 2, MODCMD_REQUIRE_AUTHED, NULL);
1371 modcmd_register(hostserv_module, "delhost", cmd_delhost, 2, MODCMD_REQUIRE_AUTHED, NULL);
1372 modcmd_register(hostserv_module, "renamehost", cmd_renamehost, 3, MODCMD_REQUIRE_AUTHED, NULL);
1373 message_register_table(msgtab);
1377 int hostserv_finalize(void) {
1381 str = "modules/hostserv";
1382 if (!(conf_node = conf_get_data(str, RECDB_OBJECT))) {
1383 log_module(HS_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", str);
1387 str = database_get_data(conf_node, "nick", RECDB_QSTRING);
1388 if (str) hostserv_conf.nick = str;
1390 str = database_get_data(conf_node, "modes", RECDB_QSTRING);
1391 if (str) hostserv_conf.modes = str;