diff -burN eggdrop1.6.17.orig/doc/tcl-commands.doc eggdrop1.6.17/doc/tcl-commands.doc --- eggdrop1.6.17.orig/doc/tcl-commands.doc 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/doc/tcl-commands.doc 2004-11-01 14:21:10.565861080 +0100 @@ -1258,6 +1258,17 @@ Module: filesys + +***### SHARE MODULE COMMANDS ###*** + + noshare [ ...] + Description: executes command with setting noshare = 1 in code, + that means, if you i.e. do chattr using this command, + bot will make changes on his userlist, but won't send changes + to other bots. This is useful in some situations. + Returns: whatever is returned by + Module: share + *** MISCELLANEOUS COMMANDS *** bind [proc-name] diff -burN eggdrop1.6.17.orig/doc/USERS eggdrop1.6.17/doc/USERS --- eggdrop1.6.17.orig/doc/USERS 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/doc/USERS 2004-11-01 14:21:10.567860776 +0100 @@ -77,6 +77,11 @@ u (unshared) user record is not sent to other bots. + s (protected) is working similar like u flag, but changes can be made + only from bot that is aggressively sharing with us (Hub). + User cannot be changed by bot that is connected below + this bot. (This flag can be useful in multilevel sharing) + h (highlight) use bold text in help/text files. All global flags other then u, h, b, c, x, j, and p are also diff -burN eggdrop1.6.17.orig/eggdrop.conf eggdrop1.6.17/eggdrop.conf --- eggdrop1.6.17.orig/eggdrop.conf 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/eggdrop.conf 2004-11-01 14:21:10.570860320 +0100 @@ -1145,11 +1145,21 @@ # changes from other bots should be ignored? #set private-globals "mnot" +# When sharing user lists, which channel flags changes from other bots +# should be ignored? +#set private-chanflags "mn" + # When sharing user lists, don't accept ANY userfile changes from other # bots? Paranoid people should use this feature on their hub bot. This # will force all userlist changes to be made via the hub. #set private-user 0 +# When you have multilevel botnet, this option permits hub, to make changes, +# even when private-global, private-chanflags and/or private-user are set. +# NOTE: this option doesn't permit hub to force flags filtered by +# private-globals +#set permit-hub 1 + # This setting makes the bot discard its own bot records in favor of # the ones sent by the hub. # NOTE: No passwords or botflags are shared, only ports and diff -burN eggdrop1.6.17.orig/help/cmds2.help eggdrop1.6.17/help/cmds2.help --- eggdrop1.6.17.orig/help/cmds2.help 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/help/cmds2.help 2004-11-01 14:21:10.572860016 +0100 @@ -372,6 +372,7 @@ %bp%b - party-line (user has access to the partyline) %bq%b - quiet (user cannot gain voice on any channel) %br%b - dehalfop (user cannot gain halfops on any channel) + %bs%b - protected (when sharing changes can be made only by hub) %bt%b - botnet master (user has access to features related to the botnet) %bu%b - unshared (user's user record is not sent to other bots) %bv%b - voice (user gets +v automatically on +autovoice channels) diff -burN eggdrop1.6.17.orig/src/cmds.c eggdrop1.6.17/src/cmds.c --- eggdrop1.6.17.orig/src/cmds.c 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/src/cmds.c 2004-11-01 14:21:10.576859408 +0100 @@ -1551,8 +1551,8 @@ mns.chan &= ~(BOT_SHARE); } if (!glob_owner(user)) { - pls.global &=~(USER_OWNER | USER_MASTER | USER_BOTMAST | USER_UNSHARED); - mns.global &=~(USER_OWNER | USER_MASTER | USER_BOTMAST | USER_UNSHARED); + pls.global &=~(USER_OWNER | USER_MASTER | USER_BOTMAST | USER_UNSHARED | USER_PROTECTED); + mns.global &=~(USER_OWNER | USER_MASTER | USER_BOTMAST | USER_UNSHARED | USER_PROTECTED); if (chan) { pls.chan &= ~USER_OWNER; diff -burN eggdrop1.6.17.orig/src/flags.h eggdrop1.6.17/src/flags.h --- eggdrop1.6.17.orig/src/flags.h 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/src/flags.h 2004-11-01 14:21:10.577859256 +0100 @@ -44,8 +44,8 @@ /* * userflags: - * abcdefgh?jklmnopqr?tuvwxyz + user defined A-Z - * unused letters: is + * abcdefgh?jklmnopqrstuvwxyz + user defined A-Z + * unused letters: i * * botflags: * 0123456789ab????ghi??l???p?rs??????? @@ -55,7 +55,7 @@ * a??defg???klmno?qr??uv??yz + user defined A-Z * unused letters: bchijpstwx */ -#define USER_VALID 0x03fbfeff /* Sum of all USER_ flags */ +#define USER_VALID 0x03fffeff /* Sum of all USER_ flags */ #define CHAN_VALID 0x03777c79 /* Sum of all CHAN_ flags */ #define BOT_VALID 0x7fe689C1 /* Sum of all BOT_ flags */ @@ -78,7 +78,7 @@ #define USER_PARTY 0x00008000 /* p user has party line access */ #define USER_QUIET 0x00010000 /* q user is global de-voice */ #define USER_DEHALFOP 0x00020000 /* r user is global de-halfop */ -#define USER_S 0x00040000 /* s unused */ +#define USER_PROTECTED 0x00040000 /* s user is protected (cannot be removed/changed by downlinks */ #define USER_BOTMAST 0x00080000 /* t user is botnet master */ #define USER_UNSHARED 0x00100000 /* u not shared with sharebots */ #define USER_VOICE 0x00200000 /* v user is +v on all channels */ @@ -166,6 +166,7 @@ #define glob_hilite(x) ((x).global & USER_HIGHLITE) #define chan_exempt(x) ((x).chan & USER_EXEMPT) #define glob_exempt(x) ((x).global & USER_EXEMPT) +#define glob_protected(x) ((x).global & USER_PROTECTED) #define bot_global(x) ((x).bot & BOT_GLOBAL) #define bot_chan(x) ((x).chan & BOT_AGGRESSIVE) diff -burN eggdrop1.6.17.orig/src/mod/share.mod/share.c eggdrop1.6.17/src/mod/share.mod/share.c --- eggdrop1.6.17.orig/src/mod/share.mod/share.c 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/src/mod/share.mod/share.c 2004-11-01 14:27:44.822924896 +0100 @@ -50,11 +50,14 @@ static int private_global = 0; static int private_user = 0; static char private_globals[50]; +static char private_chanflags[50]; static int allow_resync = 0; static struct flag_record fr = { 0, 0, 0, 0, 0, 0 }; static int resync_time = 900; static int overr_local_bots = 0; /* Override local bots? */ +static int permit_hub = 0; /* Permit hub to do changes even, when we use private_*, */ + /* but not private_globals (this have a reason) */ /* Store info for sharebots */ struct share_msgq { @@ -81,6 +84,7 @@ static void q_resync(char *, struct chanset_t *); static void cancel_user_xfer(int, void *); static int private_globals_bitmask(); +static int private_chanflags_bitmask(); #include "share.h" @@ -314,7 +318,7 @@ char *hand; struct userrec *u; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { hand = newsplit(&par); u = get_user_by_handle(userlist, hand); if (u && !(u->flags & USER_UNSHARED)) { @@ -336,26 +340,33 @@ int bfl, ofl; module_entry *me; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { hand = newsplit(&par); u = get_user_by_handle(userlist, hand); - if (u && !(u->flags & USER_UNSHARED)) { + if (u && !(u->flags & USER_UNSHARED) && !IS_USER_PROTECTED(u, idx)) { atr = newsplit(&par); cst = findchan_by_dname(par); if (!par[0] || (cst && channel_shared(cst))) { - if (!(dcc[idx].status & STAT_GETTING) && (cst || !private_global)) - shareout_but(cst, idx, "a %s %s %s\n", hand, atr, par); noshare = 1; if (par[0] && cst) { + int pchbm = 0; + if (!PERMIT_HUB(idx)) + pchbm = private_chanflags_bitmask(); fr.match = (FR_CHAN | FR_BOT); + /* bot's sharing flags */ get_user_flagrec(dcc[idx].user, &fr, par); if (bot_chan(fr) || bot_global(fr)) { fr.match = FR_CHAN; fr2.match = FR_CHAN; break_down_flags(atr, &fr, 0); get_user_flagrec(u, &fr2, par); - fr.chan = (fr2.chan & BOT_AGGRESSIVE) | - (fr.chan & ~BOT_AGGRESSIVE); + fr.chan = (fr2.chan & BOT_AGGRESSIVE) | (fr.chan & ~BOT_AGGRESSIVE); + /* Checking for forced flags */ + if ( (pchbm & USER_OWNER) && chan_owner(fr) && !chan_owner(fr2)) + fr.chan &= ~(USER_MASTER | USER_OP); + else if ( (pchbm & USER_MASTER) && chan_master(fr) && !chan_master(fr2)) + fr.chan &= ~USER_OP; + fr.chan = (fr2.chan & pchbm) | (fr.chan & ~pchbm); set_user_flagrec(u, &fr, par); check_dcc_chanattrs(u, par, fr.chan, fr2.chan); noshare = 0; @@ -372,7 +383,7 @@ putlog(LOG_CMDS, "*", "Rejected flags for unshared channel %s from %s", par, dcc[idx].nick); - } else if (!private_global) { + } else if (!private_global || PERMIT_HUB(idx)) { int pgbm = private_globals_bitmask(); /* Don't let bot flags be altered */ @@ -391,15 +402,18 @@ if (!(dcc[idx].status & STAT_GETTING)) putlog(LOG_CMDS, "*", "%s: chattr %s %s", dcc[idx].nick, hand, s); if ((me = module_find("irc", 0, 0))) { + struct chanset_t *tmpcst; Function *func = me->funcs; - for (cst = chanset; cst; cst = cst->next) - (func[IRC_RECHECK_CHANNEL]) (cst, 0); + for (tmpcst = chanset; tmpcst; tmpcst = tmpcst->next) + (func[IRC_RECHECK_CHANNEL]) (tmpcst, 0); } } else putlog(LOG_CMDS, "*", "Rejected global flags for %s from %s", hand, dcc[idx].nick); noshare = 0; + if (!(dcc[idx].status & STAT_GETTING) && (cst || !private_global || PERMIT_HUB(idx))) + shareout_but(cst, idx, "a %s %s %s\n", hand, s, par); } } } @@ -411,7 +425,7 @@ struct chanset_t *chan; struct userrec *u; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { user = newsplit(&par); if ((u = get_user_by_handle(userlist, user))) { chan = findchan_by_dname(par); @@ -440,7 +454,7 @@ struct chanset_t *chan; struct userrec *u; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { user = newsplit(&par); if ((u = get_user_by_handle(userlist, user))) { chan = findchan_by_dname(par); @@ -466,13 +480,13 @@ char *nick, *host, *pass, s[100]; struct userrec *u; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { nick = newsplit(&par); host = newsplit(&par); pass = newsplit(&par); if (!(u = get_user_by_handle(userlist, nick)) || - !(u->flags & USER_UNSHARED)) { + !((u->flags & USER_UNSHARED) || IS_USER_PROTECTED(u, idx))) { fr.global = 0; fr.match = FR_GLOBAL; @@ -517,9 +531,9 @@ struct userrec *u; /* If user is a share bot, ignore command */ - if ((dcc[idx].status & STAT_SHARE) && !private_user && + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx)) && (u = get_user_by_handle(userlist, par)) && - !(u->flags & USER_UNSHARED) && + !(u->flags & USER_UNSHARED) && !IS_USER_PROTECTED(u, idx) && !((u->flags & USER_BOT) && (bot_flags(u) & BOT_SHARE))) { noshare = 1; if (deluser(par)) { @@ -535,10 +549,10 @@ char *hand; struct userrec *u; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { hand = newsplit(&par); if ((u = get_user_by_handle(userlist, hand)) && - !(u->flags & USER_UNSHARED)) { + !(u->flags & USER_UNSHARED) && !IS_USER_PROTECTED(u, idx)) { shareout_but(NULL, idx, "+h %s %s\n", hand, par); set_user(&USERENTRY_HOSTS, u, par); putlog(LOG_CMDS, "*", "%s: +host %s %s", dcc[idx].nick, hand, par); @@ -551,10 +565,10 @@ char *hand, p[32]; struct userrec *u; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { hand = newsplit(&par); if (!(u = get_user_by_handle(userlist, hand)) || - !(u->flags & USER_UNSHARED)) { + !((u->flags & USER_UNSHARED) || IS_USER_PROTECTED(u, idx))) { if (!(dcc[idx].status & STAT_GETTING)) shareout_but(NULL, idx, "+bh %s %s\n", hand, par); /* Add bot to userlist if not there */ @@ -577,10 +591,10 @@ char *hand; struct userrec *u; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { hand = newsplit(&par); if ((u = get_user_by_handle(userlist, hand)) && - !(u->flags & USER_UNSHARED)) { + !(u->flags & USER_UNSHARED) && !IS_USER_PROTECTED(u, idx)) { shareout_but(NULL, idx, "-h %s %s\n", hand, par); noshare = 1; delhost_by_handle(hand, par); @@ -597,11 +611,11 @@ struct user_entry_type *uet; struct user_entry *e; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { key = newsplit(&par); hand = newsplit(&par); if (!(u = get_user_by_handle(userlist, hand)) || - !(u->flags & USER_UNSHARED)) { + !((u->flags & USER_UNSHARED) || IS_USER_PROTECTED(u,idx))) { if (!(uet = find_entry_type(key))) /* If it's not a supported type, forget it */ debug2("Ignore ch %s from %s (unknown type)", key, dcc[idx].nick); @@ -645,10 +659,10 @@ struct chanset_t *cst; struct userrec *u; - if ((dcc[idx].status & STAT_SHARE) && !private_user) { + if ((dcc[idx].status & STAT_SHARE) && (!private_user || PERMIT_HUB(idx))) { hand = newsplit(&par); if ((u = get_user_by_handle(userlist, hand)) && - !(u->flags & USER_UNSHARED) && share_greet) { + !(u->flags & USER_UNSHARED) && !IS_USER_PROTECTED(u, idx) && share_greet) { chan = newsplit(&par); cst = findchan_by_dname(chan); fr.match = (FR_CHAN | FR_BOT); @@ -2039,11 +2053,13 @@ {"private-global", &private_global}, {"private-user", &private_user}, {"override-bots", &overr_local_bots}, + {"permit-hub", &permit_hub}, {NULL, NULL} }; static tcl_strings my_strings[] = { {"private-globals", private_globals, 50, 0}, + {"private-chanflags", private_chanflags, 50, 0}, {NULL, NULL, 0, 0} }; @@ -2062,6 +2078,38 @@ {NULL, NULL, NULL, NULL} }; +static int tcl_noshare STDVAR +{ + int res; + char *x; + + if (argc < 2) { + Tcl_AppendResult(irp, "wrong # args: should be \"", + argv[0], " arg ?arg ...?\"", NULL); + return TCL_ERROR; + } + + Context; + + noshare = 1; + + x = Tcl_Merge(argc - 1, argv + 1); + res = Tcl_Eval(irp, x); + Tcl_Free((char *) x); + + noshare = 0; + + Context; + return res; +} + + +static tcl_cmds my_tclcmds[] = +{ + {"noshare", tcl_noshare}, + {NULL, NULL} +}; + static char *share_close() { int i; @@ -2094,6 +2142,7 @@ delay_free_mem(); rem_tcl_ints(my_ints); rem_tcl_strings(my_strings); + rem_tcl_commands(my_tclcmds); rem_builtins(H_dcc, my_cmds); rem_help_reference("share.help"); return NULL; @@ -2213,6 +2262,7 @@ DCC_BOT.kill = cancel_user_xfer; add_tcl_ints(my_ints); add_tcl_strings(my_strings); + add_tcl_commands(my_tclcmds); add_builtins(H_dcc, my_cmds); uff_init(); uff_addtable(internal_uff_table); @@ -2226,3 +2276,11 @@ break_down_flags(private_globals, &fr, 0); return fr.global; } + +int private_chanflags_bitmask() +{ + struct flag_record fr = {FR_CHAN, 0, 0, 0, 0, 0}; + + break_down_flags(private_chanflags, &fr, 0); + return fr.chan; +} diff -burN eggdrop1.6.17.orig/src/mod/share.mod/share.h eggdrop1.6.17/src/mod/share.mod/share.h --- eggdrop1.6.17.orig/src/mod/share.mod/share.h 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/src/mod/share.mod/share.h 2004-11-01 14:21:10.583858344 +0100 @@ -52,6 +52,11 @@ * `priority'. */ } uff_table_t; +/* Do we allow hub to change user value */ +#define PERMIT_HUB(x) (permit_hub && (dcc[x].status & STAT_AGGRESSIVE)) +/* Is user protected and if he is do we allow changes? */ +#define IS_USER_PROTECTED(user,idx) (!(dcc[idx].status & STAT_AGGRESSIVE) && (user->flags & USER_PROTECTED)) + #ifndef MAKING_SHARE /* 4 - 7 */ #define finish_share ((void (*) (int))share_funcs[4]) diff -burN eggdrop1.6.17.orig/src/patch.h eggdrop1.6.17/src/patch.h --- eggdrop1.6.17.orig/src/patch.h 2004-11-01 12:48:53.000000000 +0100 +++ eggdrop1.6.17/src/patch.h 2004-11-01 14:21:10.584858192 +0100 @@ -36,7 +36,7 @@ * * */ -/* PATCH GOES HERE */ +patch("multilevel_sharing"); /* * *