mux/src/file_c.cpp

Go to the documentation of this file.
00001 // file_c.cpp -- File cache management.
00002 //
00003 // $Id: file_c.cpp,v 1.6 2006/01/07 23:05:01 sdennis Exp $
00004 //
00005 
00006 #include "copyright.h"
00007 #include "autoconf.h"
00008 #include "config.h"
00009 #include "externs.h"
00010 
00011 #include "command.h"
00012 #include "file_c.h"
00013 
00014 typedef struct filecache_block_hdr FBLKHDR;
00015 typedef struct filecache_block FBLOCK;
00016 
00017 struct filecache_block
00018 {
00019     struct filecache_block_hdr
00020     {
00021         struct filecache_block *nxt;
00022         unsigned int nchars;
00023     } hdr;
00024     char data[MBUF_SIZE - sizeof(struct filecache_block_hdr)];
00025 };
00026 
00027 struct filecache_hdr
00028 {
00029     char **ppFilename;
00030     FBLOCK *fileblock;
00031     const char *desc;
00032 };
00033 
00034 typedef struct filecache_hdr FCACHE;
00035 
00036 #define FBLOCK_SIZE (MBUF_SIZE - sizeof(FBLKHDR))
00037 
00038 static FCACHE fcache[] =
00039 {
00040     { &mudconf.conn_file,    NULL,   "Conn" },
00041     { &mudconf.site_file,    NULL,   "Conn/Badsite" },
00042     { &mudconf.down_file,    NULL,   "Conn/Down" },
00043     { &mudconf.full_file,    NULL,   "Conn/Full" },
00044     { &mudconf.guest_file,   NULL,   "Conn/Guest" },
00045     { &mudconf.creg_file,    NULL,   "Conn/Reg" },
00046     { &mudconf.crea_file,    NULL,   "Crea/Newuser" },
00047     { &mudconf.regf_file,    NULL,   "Crea/RegFaill" },
00048     { &mudconf.motd_file,    NULL,   "Motd" },
00049     { &mudconf.wizmotd_file, NULL,   "Wizmotd" },
00050     { &mudconf.quit_file,    NULL,   "Quit" },
00051     { NULL,                  NULL,   NULL }
00052 };
00053 
00054 static NAMETAB list_files[] =
00055 {
00056     {"badsite_connect",  1,  CA_WIZARD,  FC_CONN_SITE},
00057     {"connect",          2,  CA_WIZARD,  FC_CONN},
00058     {"create_register",  2,  CA_WIZARD,  FC_CREA_REG},
00059     {"down",             1,  CA_WIZARD,  FC_CONN_DOWN},
00060     {"full",             1,  CA_WIZARD,  FC_CONN_FULL},
00061     {"guest_motd",       1,  CA_WIZARD,  FC_CONN_GUEST},
00062     {"motd",             1,  CA_WIZARD,  FC_MOTD},
00063     {"newuser",          1,  CA_WIZARD,  FC_CREA_NEW},
00064     {"quit",             1,  CA_WIZARD,  FC_QUIT},
00065     {"register_connect", 1,  CA_WIZARD,  FC_CONN_REG},
00066     {"wizard_motd",      1,  CA_WIZARD,  FC_WIZMOTD},
00067     { NULL,              0,  0,          0}
00068 };
00069 
00070 void do_list_file(dbref executor, dbref caller, dbref enactor, int extra, char *arg)
00071 {
00072     UNUSED_PARAMETER(caller);
00073     UNUSED_PARAMETER(enactor);
00074     UNUSED_PARAMETER(extra);
00075 
00076     int flagvalue;
00077     if (!search_nametab(executor, list_files, arg, &flagvalue))
00078     {
00079         display_nametab(executor, list_files, "Unknown file.  Use one of:", true);
00080         return;
00081     }
00082     fcache_send(executor, flagvalue);
00083 }
00084 
00085 static FBLOCK *fcache_fill(FBLOCK *fp, char ch)
00086 {
00087     if (fp->hdr.nchars >= sizeof(fp->data))
00088     {
00089         // We filled the current buffer.  Go get a new one.
00090         //
00091         FBLOCK *tfp = fp;
00092         fp = (FBLOCK *) alloc_mbuf("fcache_fill");
00093         fp->hdr.nxt = NULL;
00094         fp->hdr.nchars = 0;
00095         tfp->hdr.nxt = fp;
00096     }
00097     fp->data[fp->hdr.nchars++] = ch;
00098     return fp;
00099 }
00100 
00101 static int fcache_read(FBLOCK **cp, char *filename)
00102 {
00103     int n, nmax, tchars, fd;
00104     char *buff;
00105     FBLOCK *fp, *tfp;
00106 
00107     // Free a prior buffer chain.
00108     //
00109     fp = *cp;
00110     while (fp != NULL)
00111     {
00112         tfp = fp->hdr.nxt;
00113         free_mbuf(fp);
00114         fp = tfp;
00115     }
00116     *cp = NULL;
00117 
00118     // Read the text file into a new chain.
00119     //
00120     if ((fd = open(filename, O_RDONLY|O_BINARY)) == -1)
00121     {
00122         // Failure: log the event
00123         //
00124         STARTLOG(LOG_PROBLEMS, "FIL", "OPEN");
00125         buff = alloc_mbuf("fcache_read.LOG");
00126         sprintf(buff, "Couldn't open file '%s'.", filename);
00127         log_text(buff);
00128         free_mbuf(buff);
00129         ENDLOG
00130         return -1;
00131     }
00132     DebugTotalFiles++;
00133     buff = alloc_lbuf("fcache_read.temp");
00134 
00135     // Set up the initial cache buffer to make things easier.
00136     //
00137     fp = (FBLOCK *) alloc_mbuf("fcache_read.first");
00138     fp->hdr.nxt = NULL;
00139     fp->hdr.nchars = 0;
00140     *cp = fp;
00141     tchars = 0;
00142 
00143     // Process the file, one lbuf at a time.
00144     //
00145     nmax = read(fd, buff, LBUF_SIZE);
00146     while (nmax > 0)
00147     {
00148         for (n = 0; n < nmax; n++)
00149         {
00150             switch (buff[n])
00151             {
00152             case '\n':
00153                 fp = fcache_fill(fp, '\r');
00154                 fp = fcache_fill(fp, '\n');
00155                 tchars += 2;
00156             case '\0':
00157             case '\r':
00158                 break;
00159             default:
00160                 fp = fcache_fill(fp, buff[n]);
00161                 tchars++;
00162             }
00163         }
00164         nmax = read(fd, buff, LBUF_SIZE);
00165     }
00166     free_lbuf(buff);
00167     if (close(fd) == 0)
00168     {
00169         DebugTotalFiles--;
00170     }
00171 
00172     // If we didn't read anything in, toss the initial buffer.
00173     //
00174     if (fp->hdr.nchars == 0)
00175     {
00176         *cp = NULL;
00177         free_mbuf(fp);
00178     }
00179     return tchars;
00180 }
00181 
00182 void fcache_rawdump(SOCKET fd, int num)
00183 {
00184     if ((num < 0) || (num > FC_LAST))
00185     {
00186         return;
00187     }
00188 
00189     FBLOCK *fp = fcache[num].fileblock;
00190     int cnt, remaining;
00191     char *start;
00192 
00193     while (fp != NULL)
00194     {
00195         start = fp->data;
00196         remaining = fp->hdr.nchars;
00197         while (remaining > 0)
00198         {
00199             cnt = SOCKET_WRITE(fd, start, remaining, 0);
00200             if (cnt < 0)
00201             {
00202                 return;
00203             }
00204             remaining -= cnt;
00205             start += cnt;
00206         }
00207         fp = fp->hdr.nxt;
00208     }
00209     return;
00210 }
00211 
00212 void fcache_dump(DESC *d, int num)
00213 {
00214     if ((num < 0) || (num > FC_LAST))
00215     {
00216         return;
00217     }
00218     FBLOCK *fp = fcache[num].fileblock;
00219 
00220     while (fp != NULL)
00221     {
00222         queue_write_LEN(d, fp->data, fp->hdr.nchars);
00223         fp = fp->hdr.nxt;
00224     }
00225 }
00226 
00227 void fcache_send(dbref player, int num)
00228 {
00229     DESC *d;
00230 
00231     DESC_ITER_PLAYER(player, d)
00232     {
00233         fcache_dump(d, num);
00234     }
00235 }
00236 
00237 void fcache_load(dbref player)
00238 {
00239     FCACHE *fp;
00240     char *buff, *bufc, *sbuf;
00241 
00242     buff = bufc = alloc_lbuf("fcache_load.lbuf");
00243     sbuf = alloc_sbuf("fcache_load.sbuf");
00244     for (fp = fcache; fp->ppFilename; fp++)
00245     {
00246         int i = fcache_read(&fp->fileblock, *fp->ppFilename);
00247         if (  player != NOTHING
00248            && !Quiet(player))
00249         {
00250             mux_ltoa(i, sbuf);
00251             if (fp == fcache)
00252             {
00253                 safe_str("File sizes: ", buff, &bufc);
00254             }
00255             else
00256             {
00257                 safe_str("  ", buff, &bufc);
00258             }
00259             safe_str(fp->desc, buff, &bufc);
00260             safe_str("...", buff, &bufc);
00261             safe_str(sbuf, buff, &bufc);
00262         }
00263     }
00264     *bufc = '\0';
00265     if (  player != NOTHING
00266        && !Quiet(player))
00267     {
00268         notify(player, buff);
00269     }
00270     free_lbuf(buff);
00271     free_sbuf(sbuf);
00272 }
00273 
00274 void fcache_init(void)
00275 {
00276     FCACHE *fp = fcache;
00277     for (fp = fcache; fp->ppFilename; fp++)
00278     {
00279         fp->fileblock = NULL;
00280     }
00281 
00282     fcache_load(NOTHING);
00283 }

Generated on Mon May 28 04:40:09 2007 for MUX by  doxygen 1.4.7