long lastseen[MAXROOMS]; /* Last message seen in each room */
char generation[MAXROOMS]; /* Generation # (for private rooms) */
char forget[MAXROOMS]; /* Forgotten generation number */
- long mailnum[MAILSLOTS]; /* Message #'s of each mail message */
unsigned flags; /* See US_ flags below */
int timescalled; /* Total number of logins */
int posted; /* Number of messages posted (ever) */
*/
#define MM_VALID 4 /* New users need validating */
-/****************************************************************************
- * Information returned when a message is written to the message base
- */
-struct smreturn { /* Return from the send_message() */
- long smnumber; /* Message number (if sent) */
- long smpos; /* Position in file (if sent) */
- int smerror; /* Error code */
- };
-
/****************************************************************************
* Room records
*/
*
****************************************************************************/
-struct fullroom {
- long FRnum[MSGSPERRM]; /* Message NUMBERS */
- };
-
-
/*
* Events which might show up in the Citadel Log
*/
/*
* Gracefully terminate the session and thread.
* (This is called as a cleanup handler by the thread library.)
+ *
+ * All NON-system-dependent stuff is done in this function.
+ * System-dependent session/thread cleanup is in cleanup() in sysdep.c
*/
void cleanup_stuff()
{
}
end_critical_section(S_SESSION_TABLE);
+ /* Deallocate any message list we might have in memory */
+ if (CC->msglist != NULL) free(CC->msglist);
+
/* Now get rid of the session and context */
lprintf(7, "cleanup_stuff() is calling RemoveContext(%d)\n", CC->cs_pid);
RemoveContext(CC);
CC->upload_fp = NULL;
CC->cs_pid = con->client_socket; /* not necessarily portable */
CC->FirstExpressMessage = NULL;
+ CC->msglist = NULL;
+ CC->num_msgs = 0;
time(&CC->lastcmd);
time(&CC->lastidle);
strcpy(CC->lastcmdname, " ");
gdbm_reorganize(gdbms[CDB_MSGMAIN]);
end_critical_section(S_MSGMAIN);
- /* defrag the user file */
+ /* defrag the user file and mailboxes */
begin_critical_section(S_USERSUPP);
gdbm_reorganize(gdbms[CDB_USERSUPP]);
+ gdbm_reorganize(gdbms[CDB_MAILBOXES]);
end_critical_section(S_USERSUPP);
- /* defrag the room files */
+ /* defrag the room files and message lists */
begin_critical_section(S_QUICKROOM);
gdbm_reorganize(gdbms[CDB_QUICKROOM]);
- gdbm_reorganize(gdbms[CDB_FULLROOM]);
+ gdbm_reorganize(gdbms[CDB_MSGLISTS]);
end_critical_section(S_QUICKROOM);
/* defrag the floor table */
gdbm_strerror(gdbm_errno));
}
- gdbms[CDB_FULLROOM] = gdbm_open("fullroom.gdbm", 0,
+ gdbms[CDB_FLOORTAB] = gdbm_open("floortab.gdbm", 0,
GDBM_WRCREAT, 0600, NULL);
- if (gdbms[CDB_FULLROOM] == NULL) {
- lprintf(2, "Cannot open fullroom: %s\n",
+ if (gdbms[CDB_FLOORTAB] == NULL) {
+ lprintf(2, "Cannot open floortab: %s\n",
gdbm_strerror(gdbm_errno));
}
- gdbms[CDB_FLOORTAB] = gdbm_open("floortab.gdbm", 0,
+ gdbms[CDB_MSGLISTS] = gdbm_open("msglists.gdbm", 0,
GDBM_WRCREAT, 0600, NULL);
- if (gdbms[CDB_FLOORTAB] == NULL) {
- lprintf(2, "Cannot open floortab: %s\n",
+ if (gdbms[CDB_MSGLISTS] == NULL) {
+ lprintf(2, "Cannot open msglists: %s\n",
+ gdbm_strerror(gdbm_errno));
+ }
+
+ gdbms[CDB_MAILBOXES] = gdbm_open("mailboxes.gdbm", 0,
+ GDBM_WRCREAT, 0600, NULL);
+ if (gdbms[CDB_MAILBOXES] == NULL) {
+ lprintf(2, "Cannot open mailboxes: %s\n",
gdbm_strerror(gdbm_errno));
}
phe=gethostbyname(host);
if (phe) {
- bcopy(phe->h_addr,(char *)&sin.sin_addr,phe->h_length);
+ memcpy(phe->h_addr,(char *)&sin.sin_addr,phe->h_length);
}
else if ((sin.sin_addr.s_addr = inet_addr(host))==INADDR_NONE) {
fprintf(stderr,"Can't get %s host entry: %s\n",
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
- if (c<0) b=(MSGSPERRM-1);
+ if (c<0) b=(MAXMSGS-1);
else b=0;
sprintf(prtfile,"/tmp/CPrt%d",getpid());
start = ( (rdir==1) ? 0 : (num_msgs-1) );
for (a=start; ((a<num_msgs)&&(a>=0)); a=a+rdir) {
while (msg_arr[a]==0L) {
- a=a+rdir; if ((a==MSGSPERRM)||(a==(-1))) return;
+ a=a+rdir; if ((a==MAXMSGS)||(a==(-1))) return;
}
RAGAIN: pagin=((arcflag==0)&&(quotflag==0)&&
return;
}
get_mm();
- get_fullroom(&CC->fullroom,CC->curr_rm);
+ get_msglist(CC->curr_rm);
getuser(&CC->usersupp,CC->curr_user);
- cprintf("%d messages...\n",LISTING_FOLLOWS);
- for (a=0; a<MSGSPERRM; ++a)
- if ((CC->fullroom.FRnum[a] >=0)
+ cprintf("%d %d messages...\n",LISTING_FOLLOWS, CC->num_msgs);
+ if (CC->num_msgs != 0) {
+ for (a=0; a<(CC->num_msgs); ++a)
+ if ((MessageFromList(a) >=0)
&& (
(mode==MSGS_ALL)
-|| ((mode==MSGS_OLD) && (CC->fullroom.FRnum[a] <= CC->usersupp.lastseen[CC->curr_rm]))
-|| ((mode==MSGS_NEW) && (CC->fullroom.FRnum[a] > CC->usersupp.lastseen[CC->curr_rm]))
-|| ((mode==MSGS_NEW) && (CC->fullroom.FRnum[a] >= CC->usersupp.lastseen[CC->curr_rm])
+|| ((mode==MSGS_OLD) && (MessageFromList(a) <= CC->usersupp.lastseen[CC->curr_rm]))
+|| ((mode==MSGS_NEW) && (MessageFromList(a) > CC->usersupp.lastseen[CC->curr_rm]))
+|| ((mode==MSGS_NEW) && (MessageFromList(a) >= CC->usersupp.lastseen[CC->curr_rm])
&& (CC->usersupp.flags & US_LASTOLD))
-|| ((mode==MSGS_LAST)&& (a>=(MSGSPERRM-cm_howmany)))
+|| ((mode==MSGS_LAST)&& (a>=(CC->num_msgs-cm_howmany)))
|| ((mode==MSGS_FIRST)&&(a<cm_howmany))
-|| ((mode==MSGS_GT) && (CC->fullroom.FRnum[a] > cm_gt))
+|| ((mode==MSGS_GT) && (MessageFromList(a) > cm_gt))
)
- )
- cprintf("%ld\n",CC->fullroom.FRnum[a]);
+ ) {
+ cprintf("%ld\n", MessageFromList(a));
+ }
+ }
cprintf("000\n");
}
return;
}
- /* We used to need to check in the current room's fullroom table
+ /* We used to need to check in the current room's message list
* to determine where the message's disk position. We no longer need
* to do this, but we do it anyway as a security measure, in order to
* prevent rogue clients from reading messages not in the current room.
*/
- for (a=0; a<MSGSPERRM; ++a) if (CC->fullroom.FRnum[a] == msg_num) {
- msg_ok = 1;
+
+ msg_ok = 0;
+ if (CC->num_msgs > 0) {
+ for (a=0; a<CC->num_msgs; ++a) {
+ if (MessageFromList(a) == msg_num) {
+ msg_ok = 1;
+ }
+ }
}
+
if (!msg_ok) {
cprintf("%d Message %ld is not in this room.\n",
ERROR, msg_num);
/*
- * message base operation to send a message to the master file
+ * Message base operation to send a message to the master file
+ * (returns new message number)
*/
-void send_message(char *filename, struct smreturn *retbuf, int generate_id)
- /* tempfilename of proper message */
- /* return information */
+long send_message(char *filename, int generate_id)
+ /* tempfilename of proper message */
/* set to 1 to generate an 'I' field */
{
if (message_in_memory == NULL) {
lprintf(2, "Can't allocate memory to save message!\n");
fclose(fp);
- retbuf->smnumber = 0L;
- retbuf->smpos = 0L;
- return;
+ return 0L;
}
lprintf(9, "Reading it into memory\n");
if ( cdb_store(CDB_MSGMAIN, &newmsgid, sizeof(long),
message_in_memory, templen) < 0 ) {
lprintf(2, "Can't store message\n");
- retbuf->smnumber = 0L;
- retbuf->smpos = 0L;
- return;
+ end_critical_section(S_MSGMAIN);
+ free(message_in_memory);
+ return 0L;
}
end_critical_section(S_MSGMAIN);
free(message_in_memory);
/* Finally, return the pointers */
- retbuf->smnumber = newmsgid;
- retbuf->smpos= 1L; /* FIX we really won't be needing this */
+ return(newmsgid);
}
int mailtype, /* local or remote type, see citadel.h */
int generate_id) /* set to 1 to generate an 'I' field */
{
- int a,e;
struct usersupp tempUS;
char aaa[100];
- struct smreturn smreturn;
int hold_rm;
+ struct cdbdata *cdbmb;
+ long *dmailbox;
+ int dnum_mails;
+ long newmsgid;
- send_message(mtmp,&smreturn,generate_id);
+ newmsgid = send_message(mtmp,generate_id);
+ if (newmsgid <= 0L) return;
hold_rm=(-1);
/* if the user is a twit, move to the twit room for posting */
}
/* this call to usergoto() changes rooms if necessary. It also
- causes the latest fullroom structure to be read into memory */
+ causes the latest message list to be read into memory */
usergoto(CC->curr_rm,0);
/* Store the message pointer, but NOT for sent mail! */
/* read in the quickroom record, obtaining a lock... */
lgetroom(&CC->quickroom,CC->curr_rm);
- get_fullroom(&CC->fullroom,CC->curr_rm);
+ get_msglist(CC->curr_rm);
- /* Delete the oldest message if there is one */
- if (CC->fullroom.FRnum[0] != 0L) {
- cdb_delete(CDB_MSGMAIN,
- &CC->fullroom.FRnum[0], sizeof(long));
- }
+ /* FIX here's where we have to to message expiry!! */
- /* Now scroll... */
- for (a=0; a<(MSGSPERRM-1); ++a) {
- CC->fullroom.FRnum[a]=CC->fullroom.FRnum[a+1];
+ /* Now add the new message */
+ CC->num_msgs = CC->num_msgs + 1;
+ CC->msglist = realloc(CC->msglist,
+ ((CC->num_msgs) * sizeof(long)) );
+ if (CC->msglist == NULL) {
+ lprintf(3, "ERROR can't realloc message list!\n");
}
-
- /* ...and add the new message */
- CC->fullroom.FRnum[MSGSPERRM-1]=smreturn.smnumber;
+ SetMessageInList(CC->num_msgs - 1, newmsgid);
/* Write it back to disk. */
- put_fullroom(&CC->fullroom,CC->curr_rm);
+ put_msglist(CC->curr_rm);
/* update quickroom */
- CC->quickroom.QRhighest=CC->fullroom.FRnum[MSGSPERRM-1];
+ CC->quickroom.QRhighest = newmsgid;
lputroom(&CC->quickroom,CC->curr_rm);
}
}
/* local mail - put a copy in the recipient's mailbox */
+ /* FIX here's where we have to handle expiry, stuffed boxes, etc. */
if (mailtype==M_LOCAL) {
if (lgetuser(&tempUS,rec)==0) {
- if (tempUS.mailnum[0] != 0L) {
- cdb_delete(CDB_MSGMAIN, &tempUS.mailnum[0],
- sizeof(long));
+
+ cdbmb = cdb_fetch(CDB_MAILBOXES, &tempUS.usernum, sizeof(long));
+ if (cdbmb != NULL) {
+ memcpy(dmailbox, cdbmb->ptr, cdbmb->len);
+ dnum_mails = cdbmb->len / sizeof(long);
+ cdb_free(cdbmb);
+ }
+ else {
+ dmailbox = NULL;
+ dnum_mails = 0;
+ }
+
+ ++dnum_mails;
+ if (dmailbox == NULL) {
+ dmailbox = malloc(sizeof(long) * dnum_mails);
}
- for (e=0; e<(MAILSLOTS-1); ++e) {
- tempUS.mailnum[e]=tempUS.mailnum[e+1];
+ else {
+ dmailbox = realloc(dmailbox,
+ sizeof(long) * dnum_mails);
}
- tempUS.mailnum[MAILSLOTS-1]=smreturn.smnumber;
+
+ dmailbox[dnum_mails - 1] = newmsgid;
+ cdb_store(CDB_MAILBOXES, &tempUS.usernum, sizeof(long),
+ dmailbox, (dnum_mails * sizeof(long)) );
lputuser(&tempUS,rec);
+ free(dmailbox);
}
}
/* get room records, obtaining a lock... */
lgetroom(&CC->quickroom,CC->curr_rm);
- get_fullroom(&CC->fullroom,CC->curr_rm);
+ get_msglist(CC->curr_rm);
ok = 0;
- for (a=0; a<MSGSPERRM; ++a)
- if (CC->fullroom.FRnum[a]==delnum) {
- CC->fullroom.FRnum[a]=0L;
+ if (CC->num_msgs > 0) for (a=0; a<(CC->num_msgs); ++a) {
+ if (MessageFromList(a) == delnum) {
+ SetMessageInList(a, 0L);
ok = 1;
}
+ }
- sort_fullroom(&CC->fullroom);
- CC->quickroom.QRhighest = CC->fullroom.FRnum[MSGSPERRM-1];
+ CC->num_msgs = sort_msglist(CC->msglist, CC->num_msgs);
+ CC->quickroom.QRhighest = MessageFromList(CC->num_msgs - 1);
- put_fullroom(&CC->fullroom,CC->curr_rm);
+ put_msglist(CC->curr_rm);
lputroom(&CC->quickroom,CC->curr_rm);
if (ok==1) {
cdb_delete(CDB_MSGMAIN, &delnum, sizeof(long));
int a;
int targ_slot;
struct quickroom qtemp;
- struct fullroom ftemp;
int foundit;
+ struct cdbdata *cdbtarg;
+ long *targmsgs;
+ int targ_count;
num = extract_long(args,0);
extract(targ,args,1);
/* yank the message out of the current room... */
lgetroom(&CC->quickroom,CC->curr_rm);
- get_fullroom(&CC->fullroom,CC->curr_rm);
+ get_msglist(CC->curr_rm);
foundit = 0;
- for (a=0; a<MSGSPERRM; ++a) {
- if (CC->fullroom.FRnum[a] == num) {
+ for (a=0; a<(CC->num_msgs); ++a) {
+ if (MessageFromList(a) == num) {
foundit = 1;
- CC->fullroom.FRnum[a] = 0L;
+ SetMessageInList(a, 0L);
}
}
if (foundit) {
- sort_fullroom(&CC->fullroom);
- put_fullroom(&CC->fullroom,CC->curr_rm);
- CC->quickroom.QRhighest = CC->fullroom.FRnum[MSGSPERRM-1];
+ CC->num_msgs = sort_msglist(CC->msglist, CC->num_msgs);
+ put_msglist(CC->curr_rm);
+ CC->quickroom.QRhighest = MessageFromList((CC->num_msgs)-1);
}
lputroom(&CC->quickroom,CC->curr_rm);
if (!foundit) {
return;
}
+ /* put the message into the target room */
lgetroom(&qtemp,targ_slot);
- get_fullroom(&ftemp,targ_slot);
- if (CC->fullroom.FRnum[0] != 0L) {
- cdb_delete(CDB_MSGMAIN, &CC->fullroom.FRnum[0], sizeof(long));
- }
- for (a=0; a<MSGSPERRM-1; ++a) {
- ftemp.FRnum[a]=ftemp.FRnum[a+1];
- }
- ftemp.FRnum[MSGSPERRM-1] = num;
- sort_fullroom(&ftemp);
- qtemp.QRhighest = ftemp.FRnum[MSGSPERRM-1];
- put_fullroom(&ftemp,targ_slot);
+ cdbtarg = cdb_fetch(CDB_MSGLISTS, &targ_slot, sizeof(int));
+ if (cdbtarg != NULL) {
+ targmsgs = malloc(cdbtarg->len);
+ memcpy(targmsgs, cdbtarg->ptr, cdbtarg->len);
+ targ_count = cdbtarg->len / sizeof(long);
+ cdb_free(cdbtarg);
+ }
+ else {
+ targmsgs = NULL;
+ targ_count = 0;
+ }
+
+ ++targ_count;
+ targmsgs = realloc(targmsgs, ((CC->num_msgs) * sizeof(long)));
+ targmsgs[targ_count - 1] = num;
+ targ_count = sort_msglist(targmsgs, targ_count);
+ qtemp.QRhighest = targmsgs[targ_count - 1];
+ cdb_store(CDB_MSGLISTS, &targ_slot, sizeof(int),
+ targmsgs, targ_count * sizeof(long));
+ free(targmsgs);
lputroom(&qtemp,targ_slot);
cprintf("%d ok\n",OK);
}
/* for internal programs, always succeed */
if (((CC->internal_pgm))&&(roombuf->QRflags & QR_INUSE)) return(1);
- /* mail */
- if (roomnum==1) roombuf->QRhighest=userbuf->mailnum[MAILSLOTS-1];
-
/* for regular rooms, check the permissions */
if ((roombuf->QRflags & QR_INUSE)
&& ( (roomnum!=2) || (userbuf->axlevel>=6))
*/
int is_zapped(struct quickroom *roombuf, int roomnum, struct usersupp *userbuf)
{
- if (roomnum==1) roombuf->QRhighest=userbuf->mailnum[MAILSLOTS-1];
if ((roombuf->QRflags & QR_INUSE)
&& (roombuf->QRgen == (userbuf->forget[roomnum]) )
&& ( (roomnum!=2) || ((userbuf->axlevel)>=6))
-void readmail(void) {
- int a;
- for (a=0; a<MSGSPERRM; ++a) {
- CC->fullroom.FRnum[a]=0L;
- }
- for (a=0; a<MAILSLOTS; ++a) {
- CC->fullroom.FRnum[a+(MSGSPERRM-MAILSLOTS)] =
- CC->usersupp.mailnum[a];
- }
- CC->quickroom.QRhighest = CC->usersupp.mailnum[MAILSLOTS-1];
- }
+/*
+ * get_msglist() - retrieve room message pointers
+ */
+void get_msglist(int room_num)
+{
+ struct cdbdata *cdbfr;
+ if (CC->msglist != NULL) {
+ free(CC->msglist);
+ }
+ CC->msglist = NULL;
+ CC->num_msgs = 0;
-void writemail(void) {
- int a;
- lgetuser(&CC->usersupp,CC->curr_user);
- for (a=0; a<MAILSLOTS; ++a) {
- CC->usersupp.mailnum[a] =
- CC->fullroom.FRnum[a+(MSGSPERRM-MAILSLOTS)];
+ if (room_num != 1) {
+ cdbfr = cdb_fetch(CDB_MSGLISTS, &room_num, sizeof(int));
+ }
+ else {
+ cdbfr = cdb_fetch(CDB_MAILBOXES, &CC->usersupp.usernum,
+ sizeof(long));
}
- lputuser(&CC->usersupp,CC->curr_user);
- }
+ if (cdbfr == NULL) {
+ return;
+ }
+ CC->msglist = malloc(cdbfr->len);
+ memcpy(CC->msglist, cdbfr->ptr, cdbfr->len);
+ CC->num_msgs = cdbfr->len / sizeof(long);
+ cdb_free(cdbfr);
+ }
/*
- * get_fullroom() - retrieve room message pointers
+ * put_msglist() - retrieve room message pointers
*/
-void get_fullroom(struct fullroom *frbuf, int room_num)
+void put_msglist(int room_num)
{
- struct cdbdata *cdbfr;
if (room_num != 1) {
- bzero(frbuf, sizeof(struct fullroom));
- cdbfr = cdb_fetch(CDB_FULLROOM, &room_num, sizeof(int));
- if (cdbfr != NULL) {
- memcpy(frbuf, cdbfr->ptr, cdbfr->len);
- cdb_free(cdbfr);
- }
-
+ cdb_store(CDB_MSGLISTS, &room_num, sizeof(int),
+ CC->msglist, (CC->num_msgs * sizeof(long)) );
}
else {
- readmail();
+ cdb_store(CDB_MAILBOXES, &CC->usersupp.usernum, sizeof(long),
+ CC->msglist, (CC->num_msgs * sizeof(long)) );
}
}
/*
- * put_fullroom() - retrieve room message pointers
+ * MessageFromList() - get a message number from the list currently in memory
*/
-void put_fullroom(struct fullroom *frbuf, int room_num)
-{
+long MessageFromList(int whichpos) {
- if (room_num != 1) {
- cdb_store(CDB_FULLROOM, &room_num, sizeof(int),
- frbuf, sizeof(struct fullroom));
+ /* Return zero if the position is invalid */
+ if (whichpos >= CC->num_msgs) return 0L;
+
+ return(CC->msglist[whichpos]);
+ }
+
+/*
+ * SetMessageInList() - set a message number in the list currently in memory
+ */
+void SetMessageInList(int whichpos, long newmsgnum) {
+
+ /* Return zero if the position is invalid */
+ if (whichpos >= CC->num_msgs) return;
+
+ CC->msglist[whichpos] = newmsgnum;
+ }
+
+
+
+/*
+ * sort message pointers
+ * (returns new msg count)
+ */
+int sort_msglist(long listptrs[], int oldcount)
+{
+ int a,b;
+ long hold1, hold2;
+ int numitems;
+
+ numitems = oldcount;
+ if (numitems < 2) return(oldcount);
+
+ /* do the sort */
+ for (a=numitems-2; a>=0; --a) {
+ for (b=0; b<=a; ++b) {
+ if (listptrs[b] > (listptrs[b+1])) {
+ hold1 = listptrs[b];
+ hold2 = listptrs[b+1];
+ listptrs[b] = hold2;
+ listptrs[b+1] = hold1;
+ }
+ }
}
- else {
- writemail();
+
+ /* and yank any nulls */
+ while ( (numitems > 0) && (listptrs[0] == 0L) ) {
+ memcpy(&listptrs[0], &listptrs[1],
+ (sizeof(long) * (CC->num_msgs - 1)) );
+ --numitems;
}
+
+ return(numitems);
}
+
/*
int rmailflag;
int raideflag;
int newmailcount = 0;
+ struct cdbdata *cdbmb;
+ int num_mails;
+ long *mailbox;
CC->curr_rm=where;
getroom(&CC->quickroom,CC->curr_rm);
CC->usersupp.generation[CC->curr_rm]=CC->quickroom.QRgen;
lputuser(&CC->usersupp,CC->curr_user);
- for (a=0; a<MAILSLOTS; ++a)
- if (CC->usersupp.mailnum[a] > CC->usersupp.lastseen[1]) ++newmailcount;
+ /* check for new mail */
+ newmailcount = 0;
+
+ cdbmb = cdb_fetch(CDB_MAILBOXES, &CC->usersupp.usernum, sizeof(long));
+ if (cdbmb != NULL) {
+ num_mails = cdbmb->len / sizeof(long);
+ mailbox = (long *) cdbmb->ptr;
+ if (num_mails > 0) for (a=0; a<num_mails; ++a) {
+ if (mailbox[a] > (CC->usersupp.lastseen[1]))
+ ++newmailcount;
+ }
+ cdb_free(cdbmb);
+ }
/* set info to 1 if the user needs to read the room's info file */
if (CC->quickroom.QRinfo > CC->usersupp.lastseen[CC->curr_rm]) info = 1;
b=0; c=0;
get_mm();
- get_fullroom(&CC->fullroom,CC->curr_rm);
- for (a=0; a<MSGSPERRM; ++a) {
- if (CC->fullroom.FRnum[a]>0L) {
+ get_msglist(CC->curr_rm);
+ for (a=0; a<CC->num_msgs; ++a) {
+ if (MessageFromList(a)>0L) {
++b;
- if (CC->fullroom.FRnum[a]>CC->usersupp.lastseen[CC->curr_rm]) ++c;
+ if (MessageFromList(a)
+ > CC->usersupp.lastseen[CC->curr_rm]) ++c;
}
}
int a;
int kill_ok;
struct floor flbuf;
- struct fullroom frbuf;
+ long MsgToDelete;
kill_ok = extract_int(argbuf,0);
CC->quickroom.QRflags=0;
/* then delete the messages in the room */
- get_fullroom(&frbuf, CC->curr_rm);
- for (a=0; a<MSGSPERRM; ++a) {
- cdb_delete(CDB_MSGMAIN, &frbuf.FRnum[a], sizeof(long));
+ get_msglist(CC->curr_rm);
+ if (CC->num_msgs > 0) for (a=0; a < CC->num_msgs; ++a) {
+ MsgToDelete = MessageFromList(a);
+ cdb_delete(CDB_MSGMAIN, &MsgToDelete, sizeof(long));
}
- put_fullroom(&frbuf, CC->curr_rm);
+ put_msglist(CC->curr_rm);
+ free(CC->msglist);
+ CC->num_msgs = 0;
+ cdb_delete(CDB_MSGLISTS, &CC->curr_rm, sizeof(int));
lputroom(&CC->quickroom,CC->curr_rm);
unsigned create_room(int free_slot, char *new_room_name, int new_room_type, char *new_room_pass, int new_room_floor)
{
struct quickroom qrbuf;
- struct fullroom frbuf;
struct floor flbuf;
- int a;
lgetroom(&qrbuf,free_slot);
strncpy(qrbuf.QRname,new_room_name,19);
++qrbuf.QRgen; if (qrbuf.QRgen>=126) qrbuf.QRgen=10;
qrbuf.QRfloor = new_room_floor;
- /* Initialize a blank fullroom structure */
- get_fullroom(&frbuf,free_slot);
- for (a=0; a<MSGSPERRM; ++a) {
- frbuf.FRnum[a]=0L;
- }
- put_fullroom(&frbuf,free_slot);
-
/* save what we just did... */
lputroom(&qrbuf,free_slot);
#include "proto.h"
extern struct config config;
+
+typedef struct CitContext t_context;
+
extern struct CitContext *ContextList;
struct ChatLine *ChatQueue = NULL;
{
sprintf(bcast,":|<%s whispers %s>", un, cmdbuf);
}
- if (strucmp(cmdbuf,"NOOP")) {
+ if ((strucmp(cmdbuf,"NOOP")) && (flag !=2)) {
fp = fopen(CHATLOG,"a");
fprintf(fp,"%s\n",bcast);
fclose(fp);
DONE_FREEING: end_critical_section(S_CHATQUEUE);
}
+
+t_context *find_context(char **unstr)
+{
+ t_context *t_cc, *found_cc = NULL;
+ char *name, *tptr;
+
+ if ((!*unstr) || (!unstr))
+ return(NULL);
+
+ begin_critical_section(S_SESSION_TABLE);
+ for (t_cc = ContextList; ((t_cc) && (!found_cc)); t_cc = t_cc->next)
+ {
+ if (t_cc->fake_username[0])
+ name = t_cc->fake_username;
+ else
+ name = t_cc->curr_user;
+ tptr = *unstr;
+ if ((!struncmp(name, tptr, strlen(name))) && (tptr[strlen(name)] == ' '))
+ {
+ found_cc = t_cc;
+ *unstr = &(tptr[strlen(name)+1]);
+ }
+ }
+ end_critical_section(S_SESSION_TABLE);
+
+ return(found_cc);
+}
+
/*
* List users in chat. Setting allflag to 1 also lists users elsewhere.
*/
+
+
void do_chat_listing(int allflag)
{
struct CitContext *ccptr;
cprintf(":|\n:| Users currently in chat:\n");
+ begin_critical_section(S_SESSION_TABLE);
for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
if ( (!strucmp(ccptr->cs_room, "<chat>"))
&& ((ccptr->cs_flags & CS_STEALTH) == 0)) {
if ( (strucmp(ccptr->cs_room, "<chat>"))
&& ((ccptr->cs_flags & CS_STEALTH) == 0))
{
- cprintf(":| %-25s <%s>:\n", (ccptr->fake_username[0]) ? ccptr->fake_username : ccptr->curr_user, ccptr->cs_room);
+ cprintf(":| %-25s <%s>:\n", (ccptr->fake_username[0]) ? ccptr->fake_username : ccptr->curr_user, (ccptr->fake_roomname[0]) ? ccptr->fake_roomname : ccptr->cs_room);
}
}
}
+ end_critical_section(S_SESSION_TABLE);
cprintf(":|\n");
}
char hold_cs_room[20];
int MyLastMsg, ThisLastMsg;
struct ChatLine *clptr;
+ struct CitContext *t_context;
int retval;
if (!(CC->logged_in)) {
strcpy(cmdbuf, "");
while(1) {
+ int ok_cmd;
+
+ ok_cmd = 0;
cmdbuf[strlen(cmdbuf) + 1] = 0;
retval = client_read_to(&cmdbuf[strlen(cmdbuf)], 1, 2);
cprintf(":|/join (join new room) \n");
cprintf(":|/quit (return to the BBS) \n");
cprintf(":|\n");
+ ok_cmd = 1;
}
if (!strucmp(cmdbuf,"/who")) {
do_chat_listing(0);
+ ok_cmd = 1;
}
if (!strucmp(cmdbuf,"/whobbs")) {
do_chat_listing(1);
+ ok_cmd = 1;
}
if (!struncmp(cmdbuf,"/me ",4)) {
allwrite(&cmdbuf[4],1, CC->chat_room, NULL);
+ ok_cmd = 1;
}
if (!struncmp(cmdbuf,"/msg ", 5))
{
- strptr1 = strtok(cmdbuf, " ");
- if (strptr1)
+ ok_cmd =1;
+ strptr1 = &cmdbuf[5];
+ if ((t_context = find_context(&strptr1)))
{
- strptr1 = strtok(NULL, " ");
- if (strptr1)
- {
- allwrite(&strptr1[strlen(strptr1)+1], 2, CC->chat_room, CC->curr_user);
- if (struncmp(CC->curr_user, strptr1, strlen(CC->curr_user)))
- allwrite(&strptr1[strlen(strptr1)+1], 2, CC->chat_room, strptr1);
- }
- }
- cprintf("\n");
- }
+ allwrite(strptr1, 2, "", CC->curr_user);
+ if (strucmp(CC->curr_user, t_context->curr_user))
+ allwrite(strptr1, 2, "", t_context->curr_user);
+ }
+ else
+ cprintf(":|User not found.\n", cmdbuf);
+ cprintf("\n");
+ }
if (!struncmp(cmdbuf,"/join ", 6))
{
+ ok_cmd = 1;
allwrite("<changing rooms>",0, CC->chat_room, NULL);
if (!cmdbuf[6])
strcpy(CC->chat_room, "Main room");
}
allwrite("<joining room>",0, CC->chat_room, NULL);
cprintf("\n");
-
}
if ((cmdbuf[0]!='/')&&(strlen(cmdbuf)>0)) {
+ ok_cmd = 1;
allwrite(cmdbuf,0, CC->chat_room, NULL);
}
+ if (!ok_cmd)
+ cprintf(":|Command %s is not understood.\n", cmdbuf);
+
strcpy(cmdbuf, "");
}
ThisLastMsg = ChatLastMsg;
for (clptr=ChatQueue; clptr!=NULL; clptr=clptr->next)
{
- if (
- (clptr->chat_seq > MyLastMsg) &&
- (!struncmp(CC->chat_room, clptr->chat_room, 20)) &&
- ((!clptr->chat_username[0]) || (!struncmp(un, clptr->chat_username, 32)))
- )
- {
- cprintf("%s\n", clptr->chat_text);
- }
+ if ((clptr->chat_seq > MyLastMsg) && ((!clptr->chat_username[0]) || (!struncmp(un, clptr->chat_username, 32))))
+ {
+ if ((!clptr->chat_room[0]) || (!struncmp(CC->chat_room, clptr->chat_room, 20)))
+ {
+ cprintf("%s\n", clptr->chat_text);
+ }
+ }
}
MyLastMsg = ThisLastMsg;
}
struct usersupp usersupp; /* Database record buffers */
struct quickroom quickroom;
- struct fullroom fullroom;
+
+ long *msglist;
+ int num_msgs;
char curr_user[32]; /* name of current user */
int curr_rm; /* index of current room */
#define CDB_MSGMAIN 0 /* message base */
#define CDB_USERSUPP 1 /* user file */
#define CDB_QUICKROOM 2 /* room index */
-#define CDB_FULLROOM 3 /* room message lists */
-#define CDB_FLOORTAB 4 /* floor index */
-#define MAXCDB 5 /* total number of CDB's defined */
+#define CDB_FLOORTAB 3 /* floor index */
+#define CDB_MSGLISTS 4 /* room message lists */
+#define CDB_MAILBOXES 5 /* mailbox message lists */
+#define MAXCDB 6 /* total number of CDB's defined */
struct cdbdata {
size_t len;
}
-/*
- * sort message pointers
- */
-void sort_fullroom(struct fullroom *frptr)
-{
- int a,b;
- long hold;
- for (a=MSGSPERRM-2; a>=0; --a) {
- for (b=0; b<=a; ++b) {
- if ((frptr->FRnum[b]) > (frptr->FRnum[b+1])) {
- hold = frptr->FRnum[b];
- frptr->FRnum[b] = frptr->FRnum[b+1];
- frptr->FRnum[b+1] = hold;
- }
- }
- }
- }
-
/*
* pattern2() - searches for patn within search string, returns pos
*/
/* You may NOT change these values once you set up your system. */
#define MAXROOMS 128 /* Number of rooms in system */
#define MAXFLOORS 16 /* Do not set higher than 127 */
-#define MAILSLOTS 35 /* Number of mail slots per user */
-#define MSGSPERRM 150 /* Messages per room */
-#define CALLLOG 1000 /* Number of entries in call log */
-/* Do not set MAILSLOTS higher than MSGSPERRM */
-
-/* These may be changed at any time. */
-#define MAXUCACHE 10 /* Entries in server user cache */
-
/*** END OF STRUCTURE SIZE VARIABLES ***/
hook_user_login(CC->cs_pid, CC->curr_user);
lgetuser(&CC->usersupp,CC->curr_user);
++(CC->usersupp.timescalled);
- /* <bc> */
CC->fake_username[0] = '\0';
CC->fake_postname[0] = '\0';
CC->fake_hostname[0] = '\0';
CC->fake_roomname[0] = '\0';
CC->last_pager[0] = '\0';
- /* <bc> */
time(&CC->usersupp.lastcall);
/* If this user's name is the name of the system administrator
char filename[64];
struct usersupp usbuf;
int a;
+ struct cdbdata *cdbmb;
+ long *mailbox;
+ int num_mails;
if (getuser(&usbuf, pname) != 0) {
lprintf(5, "Cannot purge user <%s> - not found\n", pname);
}
/* delete any messages in the user's mailbox */
- for (a=0; a<MAILSLOTS; ++a) {
- if (usbuf.mailnum[a] > 0L) {
- cdb_delete(CDB_MSGMAIN, &usbuf.mailnum[a],
- sizeof(long));
+ cdbmb = cdb_fetch(CDB_MAILBOXES, &usbuf.usernum, sizeof(long));
+ if (cdbmb != NULL) {
+ num_mails = cdbmb->len / sizeof(long);
+ mailbox = (long *) cdbmb->ptr;
+ if (num_mails > 0) for (a=0; a<num_mails; ++a) {
+ cdb_delete(CDB_MSGMAIN, &mailbox[a], sizeof(long));
}
+ cdb_free(cdbmb);
+ /* now delete the mailbox itself */
+ cdb_delete(CDB_MAILBOXES, &usbuf.usernum, sizeof(long));
}
+
/* delete the userlog entry */
cdb_delete(CDB_USERSUPP, pname, strlen(pname));
CC->usersupp.generation[a]=(-1);
CC->usersupp.forget[a]=(-1);
}
- for (a=0; a<MAILSLOTS; ++a) {
- CC->usersupp.mailnum[a]=0L;
- }
strcpy(CC->usersupp.password,"");
/* These are the default flags on new accounts */
int regis = 0;
int vali = 0;
int a;
+ struct cdbdata *cdbmb;
+ long *mailbox;
+ int num_mails;
+
if (!(CC->logged_in)) {
cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN);
if (CitControl.MMflags&MM_VALID) vali = 1;
}
- mail=0; /* check for mail */
- for (a=0; a<MAILSLOTS; ++a)
- if ((CC->usersupp.mailnum[a])>(CC->usersupp.lastseen[1]))
- ++mail;
+
+ /* check for mail */
+ mail = 0;
+ cdbmb = cdb_fetch(CDB_MAILBOXES, &CC->usersupp.usernum, sizeof(long));
+ if (cdbmb != NULL) {
+ num_mails = cdbmb->len / sizeof(long);
+ mailbox = (long *) cdbmb->ptr;
+ if (num_mails > 0) for (a=0; a<num_mails; ++a) {
+ if (mailbox[a] > (CC->usersupp.lastseen[1])) ++mail;
+ }
+ cdb_free(cdbmb);
+ }
+
cprintf("%d %d|%d|%d\n",OK,mail,regis,vali);
}