#ifdef RCS
static char rcsid[]="$Id: tell.c,v 1.1.1.1 2000/11/13 02:42:49 holsta Exp $";
#endif
/******************************************************************************
* Internetting Cooperating Programmers
* ----------------------------------------------------------------------------
*
* ____ PROJECT
* | _ \ __ _ _ __ ___ ___ _ __
* | | | |/ _` | '_ \ / __/ _ \ '__|
* | |_| | (_| | | | | (_| __/ |
* |____/ \__,_|_| |_|\___\___|_| the IRC bot
*
* All files in this archive are subject to the GNU General Public License.
*
* $Source: /cvsroot/dancer/dancer/src/tell.c,v $
* $Revision: 1.1.1.1 $
* $Date: 2000/11/13 02:42:49 $
* $Author: holsta $
* $State: Exp $
* $Locker: $
*
* ---------------------------------------------------------------------------
*****************************************************************************/
#include "dancer.h"
#include "trio.h"
#include "strio.h"
#include "function.h"
#include "user.h"
#include "transfer.h"
#include "tell.h"
#include "list.h"
#include "news.h"
/* --- Global ----------------------------------------------------- */
extern time_t now;
extern char nickname[];
extern char tellfile[];
extern int tellmonths;
extern itemident *current;
int numTell = 0;
itemtell *tellHead = NULL;
static int tellId = 0;
/* --- AddTell ---------------------------------------------------- */
itemtell *AddTell(char *sender, char *receiver, char *msg, time_t when)
{
char *ptr;
itemtell *t;
snapshot;
ptr = StrIndexLast(receiver, '!');
if (ptr) {
/*
* In case we have a nick-part in the receiver-pattern, we scan for the
* '!' and points to the rest of the string instead
*/
receiver = ++ptr;
}
if (NULL == StrIndex(receiver, '@')) /* illegal pattern, we can't use this one */
return NULL;
if (IsPrefix(receiver)) /* Skip prefix */
++receiver;
t = NewEntry(itemtell);
if (t) {
InsertLast(tellHead, t);
t->sender = StrDuplicate(sender);
t->receiver = StrDuplicate(receiver);
t->rcvdomain = Userdomain(receiver);
t->message = StrDuplicate(msg);
t->when = when;
t->id = ++tellId;
numTell++;
}
return t;
}
/* --- FreeTell --------------------------------------------------- */
void FreeTell(void *v)
{
itemtell *t;
snapshot;
t = (itemtell *)v;
if (t) {
if (t->sender)
StrFree(t->sender);
if (t->receiver)
StrFree(t->receiver);
if (t->rcvdomain)
StrFree(t->rcvdomain);
if (t->message)
StrFree(t->message);
numTell--;
}
}
/* --- ReportTell ------------------------------------------------- */
inline void ReportTell(char *from, itemtell *t)
{
snapshot;
Sendf(from, "%s %s \"%s\" %s %s", t->sender, GetText(msg_said),
t->message, TimeAgo(t->when), GetText(msg_ago));
}
/* --- TellNotify ------------------------------------------------- */
void TellNotify(itemguest *g)
{
extern bool chat;
extern itemclient *client;
char msgstr[MINIBUFFER], newstr[MINIBUFFER];
long news = 0;
int mcnt = 0;
itemuser *u;
itemtell *t, *tt;
itemnews *n;
itemlist *l;
snapshot;
chat = FALSE;
client = NULL;
for (t = First(tellHead); t; t = Next(t)) {
if (Match(t->receiver, g->ident->userdomain)) {
tt = t;
mcnt++;
}
else {
u = g->ident->user;
if (u) {
for (l = First(u->domainhead); l; l = Next(l)) {
if (Match(l->pointer, t->receiver)) {
tt = t;
mcnt++;
break;
}
}
}
}
}
g->msgs = mcnt;
if (g->ident->user) {
current = g->ident; /* silly fix */
news = NewsRead(g->ident->user->newsid, &n);
}
/* News and Tells combined: */
switch (mcnt + news) {
case 0: /* none */
break;
case 1: /* tell immediately */
if (mcnt) {
ReportTell(g->ident->nick, tt);
DeleteEntry(tellHead, tt, FreeTell);
g->msgs = 0;
}
else {
NewsReport(g->ident);
}
break;
default: /* TELLME to tell you */
if (mcnt) {
StrFormatMax(msgstr, sizeof(msgstr), "%d %s ", mcnt,
(mcnt > 1) ? GetText(msg_msgs) : GetText(msg_msg));
}
if (news) {
StrFormatMax(newstr, sizeof(newstr), " %d %s ",
(int)news, GetText(msg_news_items));
}
SendNickf(g->ident->nick, GetText(msg_i_have_tells),
mcnt ? msgstr : "",
(news && mcnt) ? GetText(msg_and) : "",
news ? newstr : "",
nickname);
break;
}
}
/* --- TellNext --------------------------------------------------- */
void TellNext(char *from, itemguest *g, itemtell *t, bool all)
{
snapshot;
ReportTell(from, t);
g->msgs--;
if (!all && (g->msgs > 0)) {
Sendf(from, GetText(msg_you_have_more), g->msgs,
(g->msgs > 1) ? GetText(msg_msgs) : GetText(msg_msg));
}
DeleteEntry(tellHead, t, FreeTell);
}
/* --- TellMe ----------------------------------------------------- */
void TellMe(char *from, char *host, bool all)
{
int count = 0;
itemlist *l;
itemtell *t, *next;
itemguest *g;
snapshot;
g = current->guest;
if (g) {
for (t = First(tellHead); t; t = next) {
next = Next(t);
if (Match(t->receiver, host)) {
TellNext(from, g, t, all);
if (!all)
return;
count++;
}
else if (g->ident->user) {
for (l = First(g->ident->user->domainhead); l; l = Next(l)) {
if (Match(t->receiver, l->pointer)) {
TellNext(from, g, t, all);
if (!all)
return;
count++;
break;
}
}
}
}
if (0 == count) {
if (current->user && NewsRead(current->user->newsid, NULL))
NewsReport(current);
else
Send(from, GetText(msg_no_msgs_or_news));
}
}
else
Send(from, GetText(msg_please_join_channel));
}
/* --- TellAdd ---------------------------------------------------- */
void TellAdd(char *from, char *sender, char *receiver, char *msg)
{
itemtell *t;
snapshot;
if (receiver && (t = AddTell(sender, receiver, msg, now))) {
TellSave();
Sendf(from, GetText(msg_message_stored), t->rcvdomain, t->id);
}
else {
if (NULL == receiver)
receiver = "<empty>";
Sendf(from, GetText(msg_error_message_pattern), receiver);
}
}
/* --- TellDel ---------------------------------------------------- */
void TellDel(char *from, char *uhost, char *which)
{
char buf[MIDBUFFER];
char *ptr;
bool deleted = FALSE;
long id;
itemtell *t;
snapshot;
id = StrToLong(which, &ptr, 10);
if (which != ptr) { /* Find number */
for (t = First(tellHead); t; t = Next(t)) {
/* Not t->sender, but Userdomain of host part */
if (t->id == id) {
if (1 == StrScan(t->sender, "%*[^!]!%"MIDBUFFERTXT"[^\n]", buf)) {
ptr = Userdomain(buf);
if (ptr) {
if (Match(uhost, ptr)) {
deleted = TRUE;
Sendf(from, GetText(msg_had_been_removed), t->id);
DeleteEntry(tellHead, t, FreeTell);
}
else {
Sendf(from, GetText(msg_not_your_messageid), t->id);
}
StrFree(ptr);
}
break;
}
}
}
if ((NULL == t) && !deleted)
Send(from, GetText(msg_no_such_id));
}
}
/* --- TellList --------------------------------------------------- */
void TellList(char *from, char *uhost)
{
char *ptr;
int count = 0;
itemtell *t;
snapshot;
for (t = First(tellHead); t; t = Next(t)) {
ptr = StrIndex(t->sender, '!');
if (ptr) {
if (Match(uhost, ptr + 1)) {
if (0 == count)
Send(from, GetText(msg_you_have_stored_these));
Sendf(from, "%d: %s %s %s", t->id, t->receiver,
TimeAgo(t->when), GetText(msg_ago));
count++;
}
}
}
if (0 == count)
Send(from, GetText(msg_tell_list_empty));
}
/* --- TellInit --------------------------------------------------- */
void TellInit(void)
{
char buffer[MAXLINE], sender[MINIBUFFER], receiver[MINIBUFFER], msg[BIGBUFFER];
time_t when;
FILE *f;
snapshot;
tellHead = NewList(itemtell);
if (tellfile[0] && (f = fopen(tellfile, "r"))) {
if (fgets(buffer, sizeof(buffer), f)) {
tellId = atoi(buffer);
while (fgets(buffer, sizeof(buffer), f)) {
if (4 == StrScan(buffer, "%"MINIBUFFERTXT"s %"MINIBUFFERTXT"s %d %"BIGBUFFERTXT"[^\n]",
sender, receiver, &when, msg))
AddTell(sender, receiver, msg, when);
}
}
fclose(f);
}
}
/* --- TellSave --------------------------------------------------- */
void TellSave(void)
{
char tempfile[MIDBUFFER];
bool ok = TRUE;
itemtell *t;
FILE *f;
snapshot;
if ((char)0 == tellfile[0])
return;
StrFormatMax(tempfile, sizeof(tempfile), "%s~", tellfile);
f = fopen(tempfile, "w");
if (f) {
if (0 > fprintf(f, "%d\n", tellId)) {
ok = FALSE;
}
else {
for (t = First(tellHead); t; t = Next(t)) {
/* Ignore messages older than two months */
if ((now - t->when) < tellmonths*SECINMONTH) {
if (0 > fprintf(f, "%s %s %d %s\n", t->sender, t->receiver,
t->when, t->message)) {
ok = FALSE;
break;
}
}
}
}
fclose(f);
if (ok)
rename(tempfile, tellfile);
}
}
/* --- TellCleanup ------------------------------------------------ */
void TellCleanup(void)
{
snapshot;
TellSave();
DeleteList(tellHead, FreeTell);
}
syntax highlighted by Code2HTML, v. 0.9.1