#define VERSION "1.0" #define AUTHOR "DukePyrolator" /* Jens 'DukePyrolator' Voss newchan) free(cl->newchan); cl->newchan = sstrdup(option2); save_cl_db(); notice_user(s_ChanServ, u, "New Link added"); goto MODCONT; } if (!stricmp("DEL",cmd)) { if (!option1) { notice_user(s_ChanServ, u, HELP_SYNTAX); goto MODCONT; } if (cl = find_cl(option1)) { del_cl(cl); save_cl_db(); notice_user(s_ChanServ, u, "Link for chan %s removed", option1); goto MODCONT; } notice_user(s_ChanServ, u, "no link for this chan"); goto MODCONT; } if (!stricmp("LIST", cmd)) { notice_user(s_ChanServ, u, "Linked Channels:"); for (i = 0; i < 1024; i++) { for (cl = clists[i]; cl; cl = cl->next) { j++; notice_user(s_ChanServ, u, " %i. %s -> %s", j, cl->chan, cl->newchan); } } goto MODCONT; } notice_user(s_ChanServ, u, HELP_SYNTAX); MODCONT: if (cmd) free(cmd); if (option1) free(option1); if (option2) free(option2); return MOD_CONT; } /******************************************************************/ int do_on_join(char *source, int ac, char **av) { User *u; ChanLink *cl; char *buf; if (ac == 3) { buf = sstrdup(av[2]); if (buf[0] == '@') buf++; u = finduser(buf); free(buf); } else return MOD_CONT; if (cl = find_cl(av[1])) { send_cmd(NULL, "SVSPART %s %s %s", u->nick, av[1], "..."); send_cmd(NULL, "SVSJOIN %s %s", u->nick, cl->newchan); return MOD_STOP; } return MOD_CONT; } /******************************************************************/ void insert_cl(ChanLink * cl) { int index = HASH(cl->chan); cl->prev = NULL; cl->next = clists[index]; if (cl->next) cl->next->prev = cl; clists[index] = cl; } /*******************************************************************/ ChanLink *find_cl(char *chan) { ChanLink *cl; if (!chan) return NULL; for (cl = clists[HASH(chan)]; cl; cl = cl->next) { if (!stricmp(cl->chan, chan)) return cl; } return NULL; } /*******************************************************************/ ChanLink *make_cl(char *chan) { ChanLink *cl; cl = scalloc(sizeof(ChanLink), 1); cl->chan = sstrdup(chan); cl->newchan = NULL; cl->flags = 0; insert_cl(cl); return cl; } /*************************************************************************/ int del_cl(ChanLink *cl) { if (cl) { clists[HASH(cl->chan)] = cl->next; if (cl->chan) free(cl->chan); if (cl->newchan) free(cl->newchan); free(cl); } return 0; } /*************************************************************************/ #define SAFE(x) do { \ if ((x) < 0) { \ restore_db(f); \ log_perror("Write error on %s", ChanLinkDB); \ if (time(NULL) - lastwarn > WarningTimeout) { \ anope_cmd_global(NULL, "Write error on %s: %s", ChanLinkDB, \ strerror(errno)); \ lastwarn = time(NULL); \ } \ return; \ } \ } while (0) void save_cl_db(void) { dbFILE *f; int i; ChanLink *cl; static time_t lastwarn = 0; if (!(f = open_db("cs_link", ChanLinkDB, "w", CL_VERSION))) return; for (i = 0; i < 1024; i++) { for (cl = clists[i]; cl; cl = cl->next) { SAFE(write_int8(1, f)); SAFE(write_string(cl->chan, f)); SAFE(write_string(cl->newchan, f)); SAFE(write_int32(cl->flags, f)); SAFE(write_int8(0, f)); } } close_db(f); } #undef SAFE /******************************************************************/ #define SAFE(x) do { \ if ((x) < 0) { \ fatal("Read error on %s", ChanLinkDB); \ failed = 1; \ break; \ } \ } while (0) void load_cl_db(void) { dbFILE *f; int i, c, ver; ChanLink *cl; int failed = 0; char *s; if (!(f = open_db("cs_link", ChanLinkDB, "r", CL_VERSION))) return; ver = get_file_version(f); for (i = 0; i < 1024 && !failed; i++) { while ((c = getc_db(f)) == 1) { if (c != 1) fatal("Invalid format in %s", ChanLinkDB); SAFE(read_string(&s, f)); cl = make_cl(s); free(s); SAFE(read_string(&cl->newchan, f)); SAFE(read_int32(&cl->flags, f)); } } close_db(f); } #undef SAFE /********************************************************************/ /* end of file */ /********************************************************************/