These are the changes to eliminate most of the arbitrary limits in the
authorArt Cancro <ajc@citadel.org>
Fri, 17 Jul 1998 04:38:03 +0000 (04:38 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 17 Jul 1998 04:38:03 +0000 (04:38 +0000)
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.

12 files changed:
citadel/citadel.h
citadel/citserver.c
citadel/database.c
citadel/ipc_c_tcp.c
citadel/messages.c
citadel/msgbase.c
citadel/room_ops.c
citadel/serv_chat.c
citadel/server.h
citadel/support.c
citadel/sysconfig.h
citadel/user_ops.c

index 3c15a7d5cd11a858f95570f8cc374b87360062a5..f4e2fdb9db9c13ef58b2a2aa8395ccb6f8bc11aa 100644 (file)
@@ -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
  */
index ead5ddc5628709b7dbf43150f580f99cd07118d4..8b3cdaa50a2815255590c4d1a5dc94bedfcb3bf5 100644 (file)
@@ -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, "    ");
index 14280397b5808a4472131bc94e0e4cafae4dcd15..792a6fd06c04672f20e711ab53c3eb1e70389198 100644 (file)
@@ -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));
                }
 
index c408136babdb4de2152bd5ecdc535cf264184db8..71b06adef632ebc15a725bfadf59cfe27f9d9076 100644 (file)
@@ -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",
index 051f218f5db2b8406d7de4bc529544de418a8f8a..d5bc7de50659bafe6f16947b62cf5937dc272af1 100644 (file)
@@ -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<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)&&
index a14cec67f8d5803c1232ed13c3237d9828c14801..b0694c53c8309bc07640d75a307be4b0aa64335d 100644 (file)
@@ -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; 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");
        }
 
@@ -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; 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);
@@ -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; 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));
@@ -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; 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) {
@@ -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; 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);
        }
index 240b0edbc225575fe6464858e53df29462f552b9..df50ab7bfdffe74e46b92725f1c055e3fd9bf372 100644 (file)
@@ -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; 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);
        }
 
 
 
 /* 
@@ -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; 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;
                        }
                }
 
@@ -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; 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);
 
@@ -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<MSGSPERRM; ++a) {
-               frbuf.FRnum[a]=0L;
-               }
-       put_fullroom(&frbuf,free_slot);
-
        /* save what we just did... */
        lputroom(&qrbuf,free_slot);
 
index a6b99cb6ce67c3a62d4df92a75944dec9fabf762..22b36ed07ef3cd73f5acfe9561d6e31f0f6acee6 100644 (file)
@@ -19,6 +19,9 @@
 #include "proto.h"
 
 extern struct config config;
+
+typedef struct CitContext t_context;
+
 extern struct CitContext *ContextList;
 
 struct ChatLine *ChatQueue = NULL;
@@ -51,7 +54,7 @@ void allwrite(char *cmdbuf, int flag, char *roomname, char *username)
        {
                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);
@@ -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, "<chat>"))
                   && ((ccptr->cs_flags & CS_STEALTH) == 0)) {
@@ -123,11 +157,12 @@ void do_chat_listing(int allflag)
                        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");
        }
 
@@ -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("<changing rooms>",0, CC->chat_room, NULL);
                           if (!cmdbuf[6])
                              strcpy(CC->chat_room, "Main room");
@@ -246,12 +289,15 @@ void cmd_chat(char *argbuf)
                           }
                           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, "");
 
                        }
@@ -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;
                        }
index c48cec936b3fd3b5799fea3f42c65ade11dacf67..2649c1140371ac2c7d3b87bf6e24d50c2cd87a55 100644 (file)
@@ -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;
index 8ab6d1e756abbd90b61a6c71244ab05c7e74d7ce..896797617c43b0f8c832621718d6d6cc627ea7f9 100644 (file)
@@ -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 
  */ 
index 375439b9f138a057081c036f2a5eeed7081403b0..ee1ccac687d73aef5e6bf0307185f53776d987e4 100644 (file)
 /* 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 ***/
index 6f6df898a47c33d6183b70ab4e1ce9e709eefc76..8c7b0d00a6d3f043a2973b5e84718c0f18c3034c 100644 (file)
@@ -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);
-       /* <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
@@ -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<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));
 
@@ -397,9 +404,6 @@ int create_user(char *newusername)
                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 */
@@ -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; 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);
        }