From: Art Cancro Date: Fri, 17 Jul 1998 04:38:03 +0000 (+0000) Subject: These are the changes to eliminate most of the arbitrary limits in the X-Git-Tag: v7.86~8427 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=acfea2084c5b599e967ecbfdddd88e762b3b3179 These are the changes to eliminate most of the arbitrary limits in the system, such as the maximum number of messages in a room, or the maximum number of messages in a user mailbox. The only remaining arbitrary limits are the number of room slots in the system (MAXROOMS) and the number of floor slots (MAXFLOORS). I don't know if we'll be able to nix those. Right now, rooms and mailboxes will grow infinitely. We now have to impement artificial constraints. --- diff --git a/citadel/citadel.h b/citadel/citadel.h index 3c15a7d5c..f4e2fdb9d 100644 --- a/citadel/citadel.h +++ b/citadel/citadel.h @@ -74,7 +74,6 @@ struct usersupp { /* User record */ 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) */ @@ -115,15 +114,6 @@ struct CitControl { */ #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 */ @@ -147,11 +137,6 @@ struct quickroom { * ****************************************************************************/ -struct fullroom { - long FRnum[MSGSPERRM]; /* Message NUMBERS */ - }; - - /* * Events which might show up in the Citadel Log */ diff --git a/citadel/citserver.c b/citadel/citserver.c index ead5ddc56..8b3cdaa50 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -58,6 +58,9 @@ void master_cleanup() { /* * 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() { @@ -83,6 +86,9 @@ 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); @@ -608,6 +614,8 @@ void *context_loop(struct CitContext *con) 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, " "); diff --git a/citadel/database.c b/citadel/database.c index 14280397b..792a6fd06 100644 --- a/citadel/database.c +++ b/citadel/database.c @@ -42,15 +42,16 @@ void defrag_databases() { 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 */ @@ -88,17 +89,24 @@ void open_databases() { 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)); } diff --git a/citadel/ipc_c_tcp.c b/citadel/ipc_c_tcp.c index c408136ba..71b06adef 100644 --- a/citadel/ipc_c_tcp.c +++ b/citadel/ipc_c_tcp.c @@ -77,7 +77,7 @@ char *protocol; { 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", diff --git a/citadel/messages.c b/citadel/messages.c index 051f218f5..d5bc7de50 100644 --- a/citadel/messages.c +++ b/citadel/messages.c @@ -882,7 +882,7 @@ void readmsgs(int c, int rdir, int q) /* read contents of a room */ 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()); @@ -916,7 +916,7 @@ void readmsgs(int c, int rdir, int q) /* read contents of a room */ start = ( (rdir==1) ? 0 : (num_msgs-1) ); for (a=start; ((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)&& diff --git a/citadel/msgbase.c b/citadel/msgbase.c index a14cec67f..b0694c53c 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -165,25 +165,28 @@ void cmd_msgs(char *cmdbuf) 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; afullroom.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)&&(afullroom.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"); } @@ -336,14 +339,21 @@ void output_message(char *msgid, int mode, int headers_only) 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; afullroom.FRnum[a] == msg_num) { - msg_ok = 1; + + msg_ok = 0; + if (CC->num_msgs > 0) { + for (a=0; anum_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); @@ -586,11 +596,11 @@ void cmd_msg3(char *cmdbuf) /* - * 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 */ { @@ -613,9 +623,7 @@ void send_message(char *filename, struct smreturn *retbuf, int generate_id) 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"); @@ -633,17 +641,16 @@ void send_message(char *filename, struct smreturn *retbuf, int generate_id) 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); } @@ -711,13 +718,16 @@ void save_message(char *mtmp, /* file containing proper message */ 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 */ @@ -734,7 +744,7 @@ void save_message(char *mtmp, /* file containing proper message */ } /* 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! */ @@ -742,27 +752,24 @@ void save_message(char *mtmp, /* file containing proper message */ /* 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); } @@ -784,17 +791,35 @@ void save_message(char *mtmp, /* file containing proper message */ } /* 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); } } @@ -1145,19 +1170,20 @@ void cmd_dele(char *delstr) /* 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; afullroom.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)); @@ -1177,8 +1203,10 @@ void cmd_move(char *args) 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); @@ -1211,19 +1239,19 @@ void cmd_move(char *args) /* 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; afullroom.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) { @@ -1231,18 +1259,28 @@ void cmd_move(char *args) 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; alen); + 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); } diff --git a/citadel/room_ops.c b/citadel/room_ops.c index 240b0edbc..df50ab7bf 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -21,9 +21,6 @@ int is_known(struct quickroom *roombuf, int roomnum, struct usersupp *userbuf) /* 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)) @@ -58,7 +55,6 @@ int has_newmsgs(struct quickroom *roombuf, int roomnum, struct usersupp *userbuf */ 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)) @@ -198,69 +194,115 @@ void lputfloor(struct floor *flbuf, int floor_num) -void readmail(void) { - int a; - for (a=0; afullroom.FRnum[a]=0L; - } - for (a=0; afullroom.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; ausersupp.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); } + /* @@ -444,6 +486,9 @@ void usergoto(int where, int display_result) 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); @@ -452,19 +497,31 @@ void usergoto(int where, int display_result) CC->usersupp.generation[CC->curr_rm]=CC->quickroom.QRgen; lputuser(&CC->usersupp,CC->curr_user); - for (a=0; ausersupp.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 (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; afullroom.FRnum[a]>0L) { + get_msglist(CC->curr_rm); + for (a=0; anum_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; } } @@ -914,7 +971,7 @@ void cmd_kill(char *argbuf) int a; int kill_ok; struct floor flbuf; - struct fullroom frbuf; + long MsgToDelete; kill_ok = extract_int(argbuf,0); @@ -941,11 +998,15 @@ void cmd_kill(char *argbuf) CC->quickroom.QRflags=0; /* then delete the messages in the room */ - get_fullroom(&frbuf, CC->curr_rm); - for (a=0; acurr_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); @@ -993,9 +1054,7 @@ int get_free_room_slot(int search_dir) 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); @@ -1011,13 +1070,6 @@ unsigned create_room(int free_slot, char *new_room_name, int new_room_type, char ++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", un, cmdbuf); } - if (strucmp(cmdbuf,"NOOP")) { + if ((strucmp(cmdbuf,"NOOP")) && (flag !=2)) { fp = fopen(CHATLOG,"a"); fprintf(fp,"%s\n",bcast); fclose(fp); @@ -100,14 +103,45 @@ void allwrite(char *cmdbuf, int flag, char *roomname, char *username) 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, "")) && ((ccptr->cs_flags & CS_STEALTH) == 0)) { @@ -123,11 +157,12 @@ void do_chat_listing(int allflag) if ( (strucmp(ccptr->cs_room, "")) && ((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"); } @@ -140,6 +175,7 @@ void cmd_chat(char *argbuf) char hold_cs_room[20]; int MyLastMsg, ThisLastMsg; struct ChatLine *clptr; + struct CitContext *t_context; int retval; if (!(CC->logged_in)) { @@ -164,6 +200,9 @@ void cmd_chat(char *argbuf) strcpy(cmdbuf, ""); while(1) { + int ok_cmd; + + ok_cmd = 0; cmdbuf[strlen(cmdbuf) + 1] = 0; retval = client_read_to(&cmdbuf[strlen(cmdbuf)], 1, 2); @@ -208,35 +247,39 @@ void cmd_chat(char *argbuf) 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("",0, CC->chat_room, NULL); if (!cmdbuf[6]) strcpy(CC->chat_room, "Main room"); @@ -246,12 +289,15 @@ void cmd_chat(char *argbuf) } allwrite("",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, ""); } @@ -266,14 +312,13 @@ void cmd_chat(char *argbuf) 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; } diff --git a/citadel/server.h b/citadel/server.h index c48cec936..2649c1140 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -21,7 +21,9 @@ struct CitContext { 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 */ @@ -119,9 +121,10 @@ struct ChatLine { #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; diff --git a/citadel/support.c b/citadel/support.c index 8ab6d1e75..896797617 100644 --- a/citadel/support.c +++ b/citadel/support.c @@ -168,24 +168,6 @@ int getstring(FILE *fp, char *string) } -/* - * 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 */ diff --git a/citadel/sysconfig.h b/citadel/sysconfig.h index 375439b9f..ee1ccac68 100644 --- a/citadel/sysconfig.h +++ b/citadel/sysconfig.h @@ -57,13 +57,5 @@ /* 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 ***/ diff --git a/citadel/user_ops.c b/citadel/user_ops.c index 6f6df898a..8c7b0d00a 100644 --- a/citadel/user_ops.c +++ b/citadel/user_ops.c @@ -211,13 +211,11 @@ void session_startup(void) { hook_user_login(CC->cs_pid, CC->curr_user); lgetuser(&CC->usersupp,CC->curr_user); ++(CC->usersupp.timescalled); - /* */ 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'; - /* */ time(&CC->usersupp.lastcall); /* If this user's name is the name of the system administrator @@ -329,6 +327,9 @@ void purge_user(char *pname) { 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); @@ -336,13 +337,19 @@ void purge_user(char *pname) { } /* delete any messages in the user's mailbox */ - for (a=0; 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; ausersupp.generation[a]=(-1); CC->usersupp.forget[a]=(-1); } - for (a=0; ausersupp.mailnum[a]=0L; - } strcpy(CC->usersupp.password,""); /* These are the default flags on new accounts */ @@ -975,6 +979,10 @@ void cmd_chek(void) { 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); @@ -989,10 +997,19 @@ void cmd_chek(void) { if (CitControl.MMflags&MM_VALID) vali = 1; } - mail=0; /* check for mail */ - for (a=0; ausersupp.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 (CC->usersupp.lastseen[1])) ++mail; + } + cdb_free(cdbmb); + } + cprintf("%d %d|%d|%d\n",OK,mail,regis,vali); }