src/file_c.c

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

Generated on Mon May 28 04:25:19 2007 for BattletechMUX by  doxygen 1.4.7