X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fmod-memoserv.c;h=78c7887e446827ba5ad20d9cb0f4b294daf27fcf;hb=80d9ed728be4b02ac483f3339cbb184f6602d15b;hp=0a0ee697fbee5b329651cb83044df93d9ae322e0;hpb=222e1b0003536cf7b47858961d4b56d45c6d6606;p=srvx.git diff --git a/src/mod-memoserv.c b/src/mod-memoserv.c index 0a0ee69..78c7887 100644 --- a/src/mod-memoserv.c +++ b/src/mod-memoserv.c @@ -1,11 +1,12 @@ -/* memoserv.c - MemoServ module for srvx +/* mod-memoserv.c - MemoServ module for srvx * Copyright 2003-2004 Martijn Smit and srvx Development Team * - * This program is free software; you can redistribute it and/or modify + * This file is part of srvx. + * + * srvx is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. Important limitations are - * listed in the COPYING file that accompanies this software. + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,7 +14,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, email srvx-maintainers@srvx.net. + * along with srvx; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* Adds new section to srvx.conf: @@ -54,9 +56,13 @@ #define KEY_RECIPIENT "to" #define KEY_FROM "from" #define KEY_MESSAGE "msg" +#undef KEY_READ /* thanks microsoft! */ #define KEY_READ "read" +#define KEY_ACCOUNTS "accounts" +#define KEY_MESSAGES "messages" static const struct message_entry msgtab[] = { + { "MSMSG_CANNOT_SEND_SELF", "You cannot send to yourself." }, { "MSMSG_CANNOT_SEND", "You cannot send to account $b%s$b." }, { "MSMSG_MEMO_SENT", "Message sent to $b%s$b." }, { "MSMSG_NO_MESSAGES", "You have no messages." }, @@ -72,7 +78,7 @@ static const struct message_entry msgtab[] = { { "MSMSG_EXPIRY", "Messages will be expired when they are %s old (%d seconds)." }, { "MSMSG_MESSAGES_EXPIRED", "$b%lu$b message(s) expired." }, { "MSMSG_MEMOS_INBOX", "You have $b%d$b new message(s) in your inbox and %d old messages. Use /msg $S LIST to list them." }, - { "MSMSG_NEW_MESSAGE", "You have a new message from $b%s$b." }, + { "MSMSG_NEW_MESSAGE", "You have a new message from $b%s$b (ID $b%d$b)." }, { "MSMSG_DELETED_ALL", "Deleted all of your messages." }, { "MSMSG_USE_CONFIRM", "Please use /msg $S DELETE * $bCONFIRM$b to delete $uall$u of your messages." }, { "MSMSG_STATUS_TOTAL", "I have $b%u$b memos in my database." }, @@ -88,12 +94,12 @@ struct memo { struct memo_account *recipient; struct memo_account *sender; char *message; - time_t sent; + unsigned long sent; unsigned int is_read : 1; }; DECLARE_LIST(memoList, struct memo*); -DEFINE_LIST(memoList, struct memo*); +DEFINE_LIST(memoList, struct memo*) /* memo_account.flags fields */ #define MEMO_NOTIFY_NEW 1 @@ -109,13 +115,15 @@ struct memo_account { static struct { struct userNode *bot; - int message_expiry; + unsigned long message_expiry; } memoserv_conf; const char *memoserv_module_deps[] = { NULL }; static struct module *memoserv_module; static struct log_type *MS_LOG; -static unsigned long memosSent, memosExpired; +static unsigned long memoCount; +static unsigned long memosSent; +static unsigned long memosExpired; static struct dict *memos; /* memo_account->handle->handle -> memo_account */ static struct memo_account * @@ -143,6 +151,7 @@ delete_memo(struct memo *memo) memoList_remove(&memo->sender->sent, memo); free(memo->message); free(memo); + memoCount--; } static void @@ -164,10 +173,10 @@ do_expire(void) { dict_iterator_t it; for (it = dict_first(memos); it; it = iter_next(it)) { - struct memo_account *acct = iter_data(it); + struct memo_account *account = iter_data(it); unsigned int ii; - for (ii = 0; ii < acct->sent.used; ++ii) { - struct memo *memo = acct->sent.list[ii]; + for (ii = 0; ii < account->sent.used; ++ii) { + struct memo *memo = account->sent.list[ii]; if ((now - memo->sent) > memoserv_conf.message_expiry) { delete_memo(memo); memosExpired++; @@ -187,7 +196,7 @@ expire_memos(UNUSED_ARG(void *data)) } static struct memo* -add_memo(time_t sent, struct memo_account *recipient, struct memo_account *sender, char *message) +add_memo(unsigned long sent, struct memo_account *recipient, struct memo_account *sender, char *message) { struct memo *memo; @@ -202,23 +211,29 @@ add_memo(time_t sent, struct memo_account *recipient, struct memo_account *sende memo->sent = sent; memo->message = strdup(message); memosSent++; + memoCount++; return memo; } static int -memoserv_can_send(struct userNode *bot, struct userNode *user, struct memo_account *acct) +memoserv_can_send(struct userNode *bot, struct userNode *user, struct memo_account *account) { extern struct userData *_GetChannelUser(struct chanData *channel, struct handle_info *handle, int override, int allow_suspended); struct userData *dest; if (!user->handle_info) return 0; - if (!(acct->flags & MEMO_DENY_NONCHANNEL)) + if (user->handle_info == account->handle) { + send_message(user, bot, "MSMSG_CANNOT_SEND_SELF"); + return 0; + } + if (!(account->flags & MEMO_DENY_NONCHANNEL)) return 1; - for (dest = acct->handle->channels; dest; dest = dest->u_next) - if (_GetChannelUser(dest->channel, user->handle_info, 1, 0)) + for (dest = account->handle->channels; dest; dest = dest->u_next) { + if (dest->seen && _GetChannelUser(dest->channel, user->handle_info, 1, 0)) return 1; - send_message(user, bot, "MSMSG_CANNOT_SEND", acct->handle->handle); + } + send_message(user, bot, "MSMSG_CANNOT_SEND", account->handle->handle); return 0; } @@ -260,7 +275,7 @@ static MODCMD_FUNC(cmd_send) if (ma->flags & MEMO_NOTIFY_NEW) { struct userNode *other; for (other = ma->handle->users; other; other = other->next_authed) - send_message(other, cmd->parent->bot, "MSMSG_NEW_MESSAGE", user->nick); + send_message(other, cmd->parent->bot, "MSMSG_NEW_MESSAGE", user->nick, ma->recvd.used - 1); } reply("MSMSG_MEMO_SENT", ma->handle->handle); return 1; @@ -272,15 +287,15 @@ static MODCMD_FUNC(cmd_list) struct memo *memo; unsigned int ii; char posted[24]; - struct tm tm; + time_t feh; if (!(ma = memoserv_get_account(user->handle_info))) return 0; reply("MSMSG_LIST_HEAD"); for (ii = 0; (ii < ma->recvd.used) && (ii < 15); ++ii) { memo = ma->recvd.list[ii]; - localtime_r(&memo->sent, &tm); - strftime(posted, sizeof(posted), "%I:%M %p, %m/%d/%Y", &tm); + feh = memo->sent; + strftime(posted, sizeof(posted), "%I:%M %p, %m/%d/%Y", localtime(&feh)); reply("MSMSG_LIST_FORMAT", ii, memo->sender->handle->handle, posted); } if (ii == 0) @@ -298,14 +313,14 @@ static MODCMD_FUNC(cmd_read) unsigned int memoid; struct memo *memo; char posted[24]; - struct tm tm; + time_t memo_sent; if (!(ma = memoserv_get_account(user->handle_info))) return 0; if (!(memo = find_memo(user, cmd, ma, argv[1], &memoid))) return 0; - localtime_r(&memo->sent, &tm); - strftime(posted, sizeof(posted), "%I:%M %p, %m/%d/%Y", &tm); + memo_sent = memo->sent; + strftime(posted, sizeof(posted), "%I:%M %p, %m/%d/%Y", localtime(&memo_sent)); reply("MSMSG_MEMO_HEAD", memoid, memo->sender->handle->handle, posted); send_message_type(4, user, cmd->parent->bot, "%s", memo->message); memo->is_read = 1; @@ -355,7 +370,7 @@ static MODCMD_FUNC(cmd_expiry) return 1; } - intervalString(interval, memoserv_conf.message_expiry); + intervalString(interval, memoserv_conf.message_expiry, user->handle_info); reply("MSMSG_EXPIRY", interval, memoserv_conf.message_expiry); return 1; } @@ -434,7 +449,7 @@ static MODCMD_FUNC(cmd_set_private) static MODCMD_FUNC(cmd_status) { - reply("MSMSG_STATUS_TOTAL", dict_size(memos)); + reply("MSMSG_STATUS_TOTAL", memoCount); reply("MSMSG_STATUS_EXPIRED", memosExpired); reply("MSMSG_STATUS_SENT", memosSent); return 1; @@ -457,14 +472,14 @@ memoserv_conf_read(void) } static int -memoserv_saxdb_read(struct dict *db) +memoserv_saxdb_read_messages(struct dict *db) { char *str; struct handle_info *sender, *recipient; struct record_data *hir; struct memo *memo; dict_iterator_t it; - time_t sent; + unsigned long sent; for (it = dict_first(db); it; it = iter_next(it)) { hir = iter_data(it); @@ -477,7 +492,7 @@ memoserv_saxdb_read(struct dict *db) log_module(MS_LOG, LOG_ERROR, "Date sent not present in memo %s; skipping", iter_key(it)); continue; } - sent = atoi(str); + sent = strtoul(str, NULL, 0); if (!(str = database_get_data(hir->d.object, KEY_RECIPIENT, RECDB_QSTRING))) { log_module(MS_LOG, LOG_ERROR, "Recipient not present in memo %s; skipping", iter_key(it)); @@ -507,20 +522,79 @@ memoserv_saxdb_read(struct dict *db) return 0; } +static void +memoserv_saxdb_read_accounts(struct dict *db) +{ + struct memo_account *ma; + struct handle_info *hi; + struct record_data *rd; + dict_iterator_t it; + const char *str; + + for (it = dict_first(db); it; it = iter_next(it)) { + hi = get_handle_info(iter_key(it)); + if (hi == NULL) { + log_module(MS_LOG, LOG_WARNING, "No account known for %s.", iter_key(it)); + continue; + } + + ma = memoserv_get_account(hi); + if (ma == NULL) { + log_module(MS_LOG, LOG_WARNING, "Unable to allocate memory for account %s.", iter_key(it)); + continue; + } + + rd = iter_data(it); + if (rd->type == RECDB_QSTRING) { + str = rd->d.qstring; + } else { + log_module(MS_LOG, LOG_WARNING, "Unexpected rectype %d for accounts/%s.", rd->type, iter_key(it)); + continue; + } + + if (str != NULL) + ma->flags = strtol(str, NULL, 0); + } +} + +static int +memoserv_saxdb_read(struct dict *db) +{ + struct dict *obj; + + obj = database_get_data(db, KEY_ACCOUNTS, RECDB_OBJECT); + if (obj == NULL) { + return memoserv_saxdb_read_messages(db); + } else { + memoserv_saxdb_read_accounts(obj); + obj = database_get_data(db, KEY_MESSAGES, RECDB_OBJECT); + return memoserv_saxdb_read_messages(obj); + } +} + static int memoserv_saxdb_write(struct saxdb_context *ctx) { dict_iterator_t it; struct memo_account *ma; struct memo *memo; - char str[7]; + char str[17]; unsigned int id = 0, ii; + saxdb_start_record(ctx, "accounts", 1); + for (it = dict_first(memos); it; it = iter_next(it)) { + ma = iter_data(it); + saxdb_write_int(ctx, ma->handle->handle, ma->flags); + } + saxdb_end_record(ctx); + + saxdb_start_record(ctx, "messages", 1); for (it = dict_first(memos); it; it = iter_next(it)) { ma = iter_data(it); for (ii = 0; ii < ma->recvd.used; ++ii) { memo = ma->recvd.list[ii]; - saxdb_start_record(ctx, inttobase64(str, id++, sizeof(str)), 0); + snprintf(str, sizeof(str), "%x", id++); + saxdb_start_record(ctx, str, 0); saxdb_write_int(ctx, KEY_SENT, memo->sent); saxdb_write_string(ctx, KEY_RECIPIENT, memo->recipient->handle->handle); saxdb_write_string(ctx, KEY_FROM, memo->sender->handle->handle); @@ -530,6 +604,8 @@ memoserv_saxdb_write(struct saxdb_context *ctx) saxdb_end_record(ctx); } } + saxdb_end_record(ctx); + return 0; }