00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static int count = 0;
00074
00075
00076
00077
00078
00079
00080 static int wild_match_file(register char *m, register char *n)
00081 {
00082 char *ma = m, *lsm = 0, *lsn = 0;
00083 int match = 1;
00084 register unsigned int sofar = 0;
00085
00086
00087 if ((m == 0) || (n == 0) || (!*n))
00088 return 0;
00089
00090 while (*n) {
00091 switch (*m) {
00092 case 0:
00093 do
00094 m--;
00095 while ((m > ma) && (*m == '?'));
00096 if ((m > ma) ? ((*m == '*') && (m[-1] != FILEQUOTE)) : (*m == '*'))
00097 return FILEMATCH;
00098 break;
00099 case FILEWILDS:
00100 do
00101 m++;
00102 while (*m == FILEWILDS);
00103 lsm = m;
00104 lsn = n;
00105 match += sofar;
00106 sofar = 0;
00107 continue;
00108 case FILEWILDQ:
00109 m++;
00110 n++;
00111 continue;
00112 case FILEQUOTE:
00113 m++;
00114 }
00115 if (*m == *n) {
00116 m++;
00117 n++;
00118 sofar++;
00119 continue;
00120 }
00121 if (lsm) {
00122 n = ++lsn;
00123 m = lsm;
00124 sofar = 0;
00125 continue;
00126 }
00127 return 0;
00128 }
00129 while (*m == FILEWILDS)
00130 m++;
00131 return (*m) ? 0 : MATCH;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140 static void free_fdbe(filedb_entry **fdbe)
00141 {
00142 if (!fdbe || !*fdbe)
00143 return;
00144 if ((*fdbe)->filename)
00145 free_null((*fdbe)->filename);
00146 if ((*fdbe)->desc)
00147 free_null((*fdbe)->desc);
00148 if ((*fdbe)->chan)
00149 free_null((*fdbe)->chan);
00150 if ((*fdbe)->uploader)
00151 free_null((*fdbe)->uploader);
00152 if ((*fdbe)->flags_req)
00153 free_null((*fdbe)->flags_req);
00154 free_null(*fdbe);
00155 }
00156
00157
00158
00159 static filedb_entry *_malloc_fdbe(char *file, int line)
00160 {
00161 filedb_entry *fdbe = NULL;
00162
00163 fdbe = calloc(1, sizeof(filedb_entry));
00164
00165
00166 fdbe->_type = TYPE_NEW;
00167 return fdbe;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 static void lockfile(FILE *fdb)
00179 {
00180 struct flock fl;
00181
00182 fl.l_type = F_WRLCK;
00183 fl.l_start = 0;
00184 fl.l_whence = SEEK_SET;
00185 fl.l_len = 0;
00186 fcntl(fileno(fdb), F_SETLKW, &fl);
00187 }
00188
00189
00190
00191 static void unlockfile(FILE * f)
00192 {
00193 struct flock fl;
00194
00195 fl.l_type = F_UNLCK;
00196 fl.l_start = 0;
00197 fl.l_whence = SEEK_SET;
00198 fl.l_len = 0;
00199 fcntl(fileno(f), F_SETLKW, &fl);
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 static int filedb_readtop(FILE *fdb, filedb_top *fdbt)
00211 {
00212 if (fdbt) {
00213
00214 fseek(fdb, 0L, SEEK_SET);
00215 if (feof(fdb))
00216 return 0;
00217 fread(fdbt, 1, sizeof(filedb_top), fdb);
00218 } else
00219 fseek(fdb, sizeof(filedb_top), SEEK_SET);
00220 return 1;
00221 }
00222
00223
00224
00225 static int filedb_writetop(FILE *fdb, filedb_top *fdbt)
00226 {
00227 fseek(fdb, 0L, SEEK_SET);
00228 fwrite(fdbt, 1, sizeof(filedb_top), fdb);
00229 return 1;
00230 }
00231
00232
00233
00234
00235
00236 static int filedb_delfile(FILE *fdb, long pos)
00237 {
00238 filedb_header fdh;
00239
00240 fseek(fdb, pos, SEEK_SET);
00241 if (feof(fdb))
00242 return 0;
00243 fread(&fdh, 1, sizeof(filedb_header), fdb);
00244 fdh.stat = FILE_UNUSED;
00245
00246
00247
00248
00249 fdh.buffer_len += filedb_tot_dynspace(fdh);
00250 filedb_zero_dynspace(fdh);
00251
00252 fseek(fdb, pos, SEEK_SET);
00253 fwrite(&fdh, 1, sizeof(filedb_header), fdb);
00254 return 1;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 static filedb_entry *filedb_findempty(FILE *fdb, int tot)
00270 {
00271 filedb_entry *fdbe;
00272
00273 filedb_readtop(fdb, NULL);
00274 fdbe = filedb_getfile(fdb, ftell(fdb), GET_HEADER);
00275 while (fdbe) {
00276
00277 if ((fdbe->stat & FILE_UNUSED) && (fdbe->buf_len >= tot)) {
00278
00279
00280
00281
00282 if (fdbe->buf_len > (tot + sizeof(filedb_header) + FILEDB_ESTDYN)) {
00283 filedb_entry *fdbe_oe;
00284
00285
00286 fdbe_oe = malloc_fdbe();
00287 fdbe_oe->stat = FILE_UNUSED;
00288 fdbe_oe->pos = fdbe->pos + sizeof(filedb_header) + tot;
00289 fdbe_oe->buf_len = fdbe->buf_len - tot - sizeof(filedb_header);
00290 filedb_movefile(fdb, fdbe_oe->pos, fdbe_oe);
00291 free_fdbe(&fdbe_oe);
00292
00293
00294
00295
00296 fdbe->buf_len = tot;
00297 }
00298 return fdbe;
00299 }
00300 free_fdbe(&fdbe);
00301 fdbe = filedb_getfile(fdb, ftell(fdb), GET_HEADER);
00302 }
00303
00304
00305 fdbe = malloc_fdbe();
00306 fseek(fdb, 0L, SEEK_END);
00307 fdbe->pos = ftell(fdb);
00308 return fdbe;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 static int _filedb_updatefile(FILE *fdb, long pos, filedb_entry *fdbe,
00326 int update, char *file, int line)
00327 {
00328 filedb_header fdh;
00329 int reposition = 0;
00330 int ndyntot, odyntot, nbuftot, obuftot;
00331
00332 memset(&fdh, 0, sizeof(filedb_header));
00333 fdh.uploaded = fdbe->uploaded;
00334 fdh.size = fdbe->size;
00335 fdh.stat = fdbe->stat;
00336 fdh.gots = fdbe->gots;
00337
00338
00339
00340
00341
00342 if (fdbe->filename)
00343 fdh.filename_len = strlen(fdbe->filename) + 1;
00344 if (fdbe->desc)
00345 fdh.desc_len = strlen(fdbe->desc) + 1;
00346 if (fdbe->chan)
00347 fdh.chan_len = strlen(fdbe->chan) + 1;
00348 if (fdbe->uploader)
00349 fdh.uploader_len = strlen(fdbe->uploader) + 1;
00350 if (fdbe->flags_req)
00351 fdh.flags_req_len = strlen(fdbe->flags_req) + 1;
00352
00353 odyntot = fdbe->dyn_len;
00354 obuftot = fdbe->buf_len;
00355 ndyntot = filedb_tot_dynspace(fdh);
00356 nbuftot = obuftot;
00357
00358 if (fdbe->_type == TYPE_EXIST) {
00359
00360
00361
00362
00363 if (update < UPDATE_ALL) {
00364
00365
00366
00367 if (update != UPDATE_SIZE) {
00368 ndyntot = odyntot;
00369 nbuftot = obuftot;
00370 }
00371 } else {
00372
00373 if ((pos != POS_NEW) &&
00374
00375
00376
00377
00378 (ndyntot <= (odyntot + obuftot))) {
00379 nbuftot = (odyntot + obuftot) - ndyntot;
00380 } else {
00381
00382
00383
00384
00385 if (pos != POS_NEW)
00386 filedb_delfile(fdb, pos);
00387 reposition = 1;
00388 }
00389 }
00390 } else {
00391 fdbe->_type = TYPE_EXIST;
00392 reposition = 1;
00393 }
00394
00395
00396 if (reposition) {
00397 filedb_entry *n_fdbe;
00398
00399 n_fdbe = filedb_findempty(fdb, filedb_tot_dynspace(fdh));
00400 fdbe->pos = pos = n_fdbe->pos;
00401
00402
00403
00404 if (n_fdbe->buf_len > 0)
00405
00406
00407
00408 nbuftot = n_fdbe->buf_len - ndyntot;
00409 else
00410 nbuftot = 0;
00411 free_fdbe(&n_fdbe);
00412 }
00413
00414
00415 fdbe->dyn_len = ndyntot;
00416 fdbe->buf_len = fdh.buffer_len = nbuftot;
00417
00418
00419 fseek(fdb, pos, SEEK_SET);
00420 fwrite(&fdh, 1, sizeof(filedb_header), fdb);
00421
00422 if (update == UPDATE_ALL) {
00423 if (fdbe->filename)
00424 fwrite(fdbe->filename, 1, fdh.filename_len, fdb);
00425 if (fdbe->desc)
00426 fwrite(fdbe->desc, 1, fdh.desc_len, fdb);
00427 if (fdbe->chan)
00428 fwrite(fdbe->chan, 1, fdh.chan_len, fdb);
00429 if (fdbe->uploader)
00430 fwrite(fdbe->uploader, 1, fdh.uploader_len, fdb);
00431 if (fdbe->flags_req)
00432 fwrite(fdbe->flags_req, 1, fdh.flags_req_len, fdb);
00433 } else
00434 fseek(fdb, ndyntot, SEEK_CUR);
00435 fseek(fdb, nbuftot, SEEK_CUR);
00436 return 0;
00437 }
00438
00439
00440
00441 static int _filedb_movefile(FILE *fdb, long pos, filedb_entry *fdbe,
00442 char *file, int line)
00443 {
00444 fdbe->_type = TYPE_EXIST;
00445 _filedb_updatefile(fdb, pos, fdbe, UPDATE_ALL, file, line);
00446 return 0;
00447 }
00448
00449
00450
00451 static int _filedb_addfile(FILE *fdb, filedb_entry *fdbe, char *file, int line)
00452 {
00453 fdbe->_type = TYPE_NEW;
00454 _filedb_updatefile(fdb, POS_NEW, fdbe, UPDATE_ALL, file, line);
00455 return 0;
00456 }
00457
00458
00459
00460
00461 #define filedb_read(fdb, entry, len) \
00462 { \
00463 if ((len) > 0) { \
00464 (entry) = malloc((len)); \
00465 fread((entry), 1, (len), (fdb)); \
00466 } \
00467 }
00468
00469
00470
00471
00472
00473
00474 static filedb_entry *_filedb_getfile(FILE *fdb, long pos, int get,
00475 char *file, int line)
00476 {
00477 filedb_entry *fdbe;
00478 filedb_header fdh;
00479
00480
00481 fseek(fdb, pos, SEEK_SET);
00482 fread(&fdh, 1, sizeof(filedb_header), fdb);
00483 if (feof(fdb))
00484 return NULL;
00485
00486
00487 fdbe = _malloc_fdbe(file, line);
00488
00489
00490 fdbe->uploaded = fdh.uploaded;
00491 fdbe->size = fdh.size;
00492 fdbe->stat = fdh.stat;
00493 fdbe->gots = fdh.gots;
00494
00495 fdbe->buf_len = fdh.buffer_len;
00496 fdbe->dyn_len = filedb_tot_dynspace(fdh);
00497 fdbe->pos = pos;
00498 fdbe->_type = TYPE_EXIST;
00499
00500
00501 if (get >= GET_FILENAME) {
00502 filedb_read(fdb, fdbe->filename, fdh.filename_len);
00503 } else
00504 fseek(fdb, fdh.filename_len, SEEK_CUR);
00505 if (get < GET_FULL || (fdh.stat & FILE_UNUSED))
00506 fseek(fdb, filedb_tot_dynspace(fdh) - fdh.filename_len, SEEK_CUR);
00507 else if (get == GET_FULL) {
00508 filedb_read(fdb, fdbe->desc, fdh.desc_len);
00509 filedb_read(fdb, fdbe->chan, fdh.chan_len);
00510 filedb_read(fdb, fdbe->uploader, fdh.uploader_len);
00511 filedb_read(fdb, fdbe->flags_req, fdh.flags_req_len);
00512 }
00513 fseek(fdb, fdh.buffer_len, SEEK_CUR);
00514 return fdbe;
00515 }
00516
00517
00518
00519
00520 static filedb_entry *_filedb_matchfile(FILE *fdb, long pos, char *match,
00521 char *file, int line)
00522 {
00523 filedb_entry *fdbe = NULL;
00524
00525 fseek(fdb, pos, SEEK_SET);
00526 while (!feof(fdb))
00527 {
00528 pos = ftell(fdb);
00529 fdbe = filedb_getfile(fdb, pos, GET_FILENAME);
00530 if (fdbe) {
00531 if (!(fdbe->stat & FILE_UNUSED) &&
00532 wild_match_file(match, fdbe->filename)) {
00533 free_fdbe(&fdbe);
00534 fdbe = _filedb_getfile(fdb, pos, GET_FULL,
00535 file, line);
00536 return fdbe;
00537 }
00538 free_fdbe(&fdbe);
00539 }
00540 }
00541 return NULL;
00542 }
00543
00544
00545
00546
00547 static void filedb_cleanup(FILE *fdb)
00548 {
00549 long oldpos, newpos, temppos;
00550 filedb_entry *fdbe = NULL;
00551
00552 filedb_readtop(fdb, NULL);
00553 newpos = temppos = oldpos = ftell(fdb);
00554 fseek(fdb, oldpos, SEEK_SET);
00555 while (!feof(fdb))
00556 {
00557 fdbe = filedb_getfile(fdb, oldpos, GET_HEADER);
00558 if (fdbe) {
00559 if (fdbe->stat & FILE_UNUSED) {
00560 free_fdbe(&fdbe);
00561 while (!feof(fdb)) {
00562 newpos = ftell(fdb);
00563 fdbe = filedb_getfile(fdb, newpos, GET_FULL);
00564 if (!fdbe)
00565 break;
00566 if (!(fdbe->stat & FILE_UNUSED)) {
00567 temppos = ftell(fdb);
00568 filedb_movefile(fdb, oldpos, fdbe);
00569 oldpos = ftell(fdb);
00570 fseek(fdb, temppos, SEEK_SET);
00571 }
00572 free_fdbe(&fdbe);
00573 }
00574 } else {
00575 free_fdbe(&fdbe);
00576 oldpos = ftell(fdb);
00577 }
00578 }
00579 }
00580 ftruncate(fileno(fdb), oldpos);
00581 }
00582
00583
00584
00585
00586
00587
00588 static void filedb_mergeempty(FILE *fdb)
00589 {
00590 filedb_entry *fdbe_t, *fdbe_i;
00591 int modified;
00592
00593 filedb_readtop(fdb, NULL);
00594 while (!feof(fdb))
00595 {
00596 fdbe_t = filedb_getfile(fdb, ftell(fdb), GET_HEADER);
00597 if (fdbe_t) {
00598 if (fdbe_t->stat & FILE_UNUSED) {
00599 modified = 0;
00600 fdbe_i = filedb_getfile(fdb, ftell(fdb), GET_HEADER);
00601 while (fdbe_i) {
00602
00603 if (!(fdbe_i->stat & FILE_UNUSED))
00604 break;
00605
00606
00607
00608
00609 fdbe_t->buf_len += sizeof(filedb_header) + fdbe_i->buf_len;
00610 modified++;
00611 free_fdbe(&fdbe_i);
00612
00613 fdbe_i = filedb_getfile(fdb, ftell(fdb), GET_HEADER);
00614 }
00615
00616
00617 if (fdbe_i) {
00618 free_fdbe(&fdbe_i);
00619
00620 if (modified)
00621 filedb_updatefile(fdb, fdbe_t->pos, fdbe_t, UPDATE_SIZE);
00622
00623 } else {
00624
00625 ftruncate(fileno(fdb), fdbe_t->pos);
00626 free_fdbe(&fdbe_t);
00627 return;
00628 }
00629 }
00630 free_fdbe(&fdbe_t);
00631 }
00632 }
00633 }
00634
00635
00636
00637
00638 static filedb_entry *filedb_getentry(char *dir, char *fn)
00639 {
00640 FILE *fdb;
00641 filedb_entry *fdbe = NULL;
00642
00643 fdb = filedb_open(dir, 0);
00644 if (fdb) {
00645 filedb_readtop(fdb, NULL);
00646 fdbe = filedb_matchfile(fdb, ftell(fdb), fn);
00647 filedb_close(fdb);
00648 }
00649 return fdbe;
00650 }
00651
00652
00653
00654 static void filedb_initdb(FILE *fdb)
00655 {
00656 filedb_top fdbt;
00657
00658 fdbt.version = FILEDB_NEWEST_VER;
00659 fdbt.timestamp = now;
00660 filedb_writetop(fdb, &fdbt);
00661 }
00662
00663 static void filedb_timestamp(FILE * fdb)
00664 {
00665 filedb_top fdbt;
00666
00667 filedb_readtop(fdb, &fdbt);
00668 fdbt.timestamp = now;
00669 filedb_writetop(fdb, &fdbt);
00670 }
00671
00672
00673
00674
00675
00676
00677
00678 static void filedb_update(char *path, FILE *fdb, int sort)
00679 {
00680 struct dirent *dd = NULL;
00681 struct stat st;
00682 filedb_entry *fdbe = NULL;
00683 DIR *dir = NULL;
00684 long where = 0;
00685 char *name = NULL, *s = NULL;
00686
00687
00688
00689
00690 dir = opendir(path);
00691 if (dir == NULL) {
00692 putlog(LOG_MISC, "*", _("filedb-update: cant open directory!"));
00693 return;
00694 }
00695 dd = readdir(dir);
00696 while (dd != NULL) {
00697 realloc_strcpy(name, dd->d_name);
00698 if (name[0] != '.') {
00699 s = malloc(strlen(path) + strlen(name) + 2);
00700 sprintf(s, "%s/%s", path, name);
00701 stat(s, &st);
00702 free_null(s);
00703 filedb_readtop(fdb, NULL);
00704 fdbe = filedb_matchfile(fdb, ftell(fdb), name);
00705 if (!fdbe) {
00706
00707 fdbe = malloc_fdbe();
00708 realloc_strcpy(fdbe->filename, name);
00709 realloc_strcpy(fdbe->uploader, myname);
00710 fdbe->uploaded = now;
00711 fdbe->size = st.st_size;
00712 if (S_ISDIR(st.st_mode))
00713 fdbe->stat |= FILE_DIR;
00714 filedb_addfile(fdb, fdbe);
00715 } else if (fdbe->size != st.st_size) {
00716
00717 fdbe->size = st.st_size;
00718 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER);
00719 }
00720 free_fdbe(&fdbe);
00721 }
00722 dd = readdir(dir);
00723 }
00724 if (name)
00725 free_null(name);
00726 closedir(dir);
00727
00728
00729
00730
00731 filedb_readtop(fdb, NULL);
00732 fdbe = filedb_getfile(fdb, ftell(fdb), GET_FILENAME);
00733 while (fdbe) {
00734 where = ftell(fdb);
00735 if (!(fdbe->stat & FILE_UNUSED) && !(fdbe->stat & FILE_ISLINK) &&
00736 fdbe->filename) {
00737 s = malloc(strlen(path) + 1 + strlen(fdbe->filename) + 1);
00738 sprintf(s, "%s/%s", path, fdbe->filename);
00739 if (stat(s, &st) != 0)
00740
00741 filedb_delfile(fdb, fdbe->pos);
00742 free_null(s);
00743 }
00744 free_fdbe(&fdbe);
00745 fdbe = filedb_getfile(fdb, where, GET_FILENAME);
00746 }
00747
00748
00749
00750
00751
00752
00753
00754 if (sort)
00755 filedb_cleanup(fdb);
00756 filedb_timestamp(fdb);
00757 }
00758
00759
00760
00761
00762 static char *make_point_path(char *path)
00763 {
00764 char *s2 = NULL, *p = NULL;
00765
00766 realloc_strcpy(s2, path);
00767 if (s2[strlen(s2) - 1] == '/')
00768 s2[strlen(s2) - 1] = 0;
00769 p = s2;
00770 while (*p++)
00771 if (*p == '/')
00772 *p = '.';
00773 return s2;
00774 }
00775
00776
00777
00778 static FILE *filedb_open(char *path, int sort)
00779 {
00780 char *s, *npath;
00781 FILE *fdb;
00782 filedb_top fdbt;
00783 struct stat st;
00784
00785 if (count >= 2)
00786 putlog(LOG_MISC, "*", "(@) warning: %d open filedb's", count);
00787 npath = malloc(strlen(dccdir) + strlen(path) + 1);
00788 simple_sprintf(npath, "%s%s", dccdir, path);
00789
00790 if (filedb_path[0]) {
00791 char *s2;
00792
00793 s2 = make_point_path(path);
00794 s = malloc(strlen(filedb_path) + strlen(s2) + 8);
00795 simple_sprintf(s, "%sfiledb.%s", filedb_path, s2);
00796 free_null(s2);
00797 } else {
00798 s = malloc(strlen(npath) + 10);
00799 simple_sprintf(s, "%s/.filedb", npath);
00800 }
00801 fdb = fopen(s, "r+b");
00802 if (!fdb) {
00803 if (convert_old_files(npath, s)) {
00804 fdb = fopen(s, "r+b");
00805 if (fdb == NULL) {
00806 putlog(LOG_MISC, "*", _("(!) Broken convert to filedb in %s"), npath);
00807 free_null(s);
00808 free_null(npath);
00809 return NULL;
00810 }
00811 lockfile(fdb);
00812 filedb_update(npath, fdb, sort);
00813 count++;
00814 free_null(s);
00815 free_null(npath);
00816 return fdb;
00817 } else {
00818 filedb_top fdbt;
00819
00820
00821 fdb = fopen(s, "w+b");
00822 if (!fdb) {
00823 free_null(s);
00824 free_null(npath);
00825 return NULL;
00826 }
00827 lockfile(fdb);
00828 fdbt.version = FILEDB_NEWEST_VER;
00829 fdbt.timestamp = now;
00830 filedb_writetop(fdb, &fdbt);
00831 filedb_update(npath, fdb, sort);
00832 count++;
00833 free_null(s);
00834 free_null(npath);
00835 return fdb;
00836 }
00837 }
00838
00839 lockfile(fdb);
00840 filedb_readtop(fdb, &fdbt);
00841 if (fdbt.version < FILEDB_NEWEST_VER) {
00842 if (!convert_old_db(&fdb, s)) {
00843
00844
00845
00846
00847 if (fdb)
00848 unlockfile(fdb);
00849 free_null(npath);
00850 free_null(s);
00851 return NULL;
00852 }
00853 filedb_update(npath, fdb, sort);
00854 }
00855 stat(npath, &st);
00856
00857
00858
00859
00860
00861 if (sort || ((now - fdbt.timestamp) > (6 * 3600)) ||
00862 (fdbt.timestamp < st.st_mtime) ||
00863 (fdbt.timestamp < st.st_ctime))
00864
00865 filedb_update(npath, fdb, sort & 1);
00866 else if ((now - fdbt.timestamp) > 300)
00867 filedb_mergeempty(fdb);
00868
00869 count++;
00870 free_null(npath);
00871 free_null(s);
00872 return fdb;
00873 }
00874
00875
00876
00877
00878 static void filedb_close(FILE * fdb)
00879 {
00880 filedb_timestamp(fdb);
00881 fseek(fdb, 0L, SEEK_END);
00882 count--;
00883 unlockfile(fdb);
00884 fclose(fdb);
00885 }
00886
00887
00888
00889
00890
00891 static void filedb_add(FILE * fdb, char *filename, char *nick)
00892 {
00893 filedb_entry *fdbe = NULL;
00894
00895 filedb_readtop(fdb, NULL);
00896
00897 fdbe = filedb_matchfile(fdb, ftell(fdb), filename);
00898 if (!fdbe)
00899 return;
00900 free_null(fdbe->uploader);
00901 realloc_strcpy(fdbe->uploader, nick);
00902 fdbe->uploaded = now;
00903 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL);
00904 free_fdbe(&fdbe);
00905 }
00906
00907
00908
00909
00910 static void filedb_ls(FILE *fdb, int idx, char *mask, int showall)
00911 {
00912 int ok = 0, cnt = 0, is = 0;
00913 char s1[81], *p = NULL;
00914 struct flag_record user = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
00915 filedb_entry *fdbe = NULL;
00916 filelist_t *flist = NULL;
00917
00918 flist = filelist_new();
00919 filedb_readtop(fdb, NULL);
00920 fdbe = filedb_getfile(fdb, ftell(fdb), GET_FULL);
00921 while (fdbe) {
00922 ok = 1;
00923 if (fdbe->stat & FILE_UNUSED)
00924 ok = 0;
00925 if (ok && (fdbe->stat & FILE_DIR) && fdbe->flags_req) {
00926
00927 struct flag_record req = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
00928
00929 break_down_flags(fdbe->flags_req, &req, NULL);
00930 get_user_flagrec(dcc[idx].user, &user, dcc[idx].u.file->chat->con_chan);
00931 if (!flagrec_ok(&req, &user)) {
00932 ok = 0;
00933 }
00934 }
00935 if (ok)
00936 is = 1;
00937 if (ok && !wild_match_file(mask, fdbe->filename))
00938 ok = 0;
00939 if (ok && (fdbe->stat & FILE_HIDDEN) && !(showall))
00940 ok = 0;
00941 if (ok) {
00942
00943 if (cnt == 0) {
00944 dprintf(idx, _("Filename Size Sent by/Date # Gets\n"));
00945 dprintf(idx, _("------------------------------ ---- ------------------- ------\n"));
00946 }
00947 filelist_add(flist, fdbe->filename);
00948 if (fdbe->stat & FILE_DIR) {
00949 char *s2 = NULL, *s3 = NULL;
00950
00951
00952 if (strlen(fdbe->filename) > 45) {
00953
00954 s2 = malloc(strlen(fdbe->filename) + 3);
00955 sprintf(s2, "%s/\n", fdbe->filename);
00956 filelist_addout(flist, s2);
00957 free_null(s2);
00958 } else {
00959 s2 = malloc(strlen(fdbe->filename) + 2);
00960 sprintf(s2, "%s/", fdbe->filename);
00961 }
00962
00963
00964
00965
00966 if ((fdbe->flags_req) &&
00967 (user.global &(USER_MASTER | USER_JANITOR))) {
00968 s3 = malloc(42 + strlen(s2 ? s2 : "") + 6 +
00969 strlen(_("requires")) + strlen(fdbe->flags_req) + 1 +
00970 strlen(fdbe->chan ? fdbe->chan : "") + 1);
00971 sprintf(s3, "%-30s <DIR> (%s %s%s%s)\n", s2, _("requires"),
00972 fdbe->flags_req, fdbe->chan ? " " : "",
00973 fdbe->chan ? fdbe->chan : "");
00974 } else {
00975 s3 = malloc(38 + strlen(s2 ? s2 : ""));
00976 sprintf(s3, "%-30s <DIR>\n", s2 ? s2 : "");
00977 }
00978 if (s2)
00979 free_null(s2);
00980 filelist_addout(flist, s3);
00981 free_null(s3);
00982 } else {
00983 char s2[41], t[50], *s3 = NULL, *s4;
00984
00985 s2[0] = 0;
00986 if (showall) {
00987 if (fdbe->stat & FILE_HIDDEN)
00988 strcat(s2, " (hid)");
00989 }
00990 strftime(t, 10, "%d%b%Y", localtime(&fdbe->uploaded));
00991 if (fdbe->size < 1024)
00992 sprintf(s1, "%5d", fdbe->size);
00993 else
00994 sprintf(s1, "%4dk", (int) (fdbe->size / 1024));
00995
00996 if (strlen(fdbe->filename) > 30) {
00997 s3 = malloc(strlen(fdbe->filename) + 2);
00998 sprintf(s3, "%s\n", fdbe->filename);
00999 filelist_addout(flist, s3);
01000 free_null(s3);
01001
01002 } else
01003 realloc_strcpy(s3, fdbe->filename);
01004 s4 = malloc(69 + strlen(s3 ? s3 : "") + strlen(s1) +
01005 strlen(fdbe->uploader) + strlen(t) + strlen(s2));
01006 sprintf(s4, "%-30s %s %-9s (%s) %6d%s\n", s3 ? s3 : "", s1,
01007 fdbe->uploader, t, fdbe->gots, s2);
01008 if (s3)
01009 free_null(s3);
01010 filelist_addout(flist, s4);
01011 free_null(s4);
01012 }
01013 if (fdbe->desc) {
01014 p = strchr(fdbe->desc, '\n');
01015 while (p != NULL) {
01016 *p = 0;
01017 if ((fdbe->desc)[0]) {
01018 char *sd;
01019
01020 sd = malloc(strlen(fdbe->desc) + 5);
01021 sprintf(sd, " %s\n", fdbe->desc);
01022 filelist_addout(flist, sd);
01023 free_null(sd);
01024 }
01025 strcpy(fdbe->desc, p + 1);
01026 p = strchr(fdbe->desc, '\n');
01027 }
01028 if ((fdbe->desc)[0]) {
01029 char *sd;
01030
01031 sd = malloc(strlen(fdbe->desc) + 5);
01032 sprintf(sd, " %s\n", fdbe->desc);
01033 filelist_addout(flist, sd);
01034 free_null(sd);
01035 }
01036 }
01037 cnt++;
01038 }
01039 free_fdbe(&fdbe);
01040 fdbe = filedb_getfile(fdb, ftell(fdb), GET_FULL);
01041 }
01042 if (is == 0)
01043 dprintf(idx, _("No files in this directory.\n"));
01044 else if (cnt == 0)
01045 dprintf(idx, _("No matching files.\n"));
01046 else {
01047 filelist_sort(flist);
01048 filelist_idxshow(flist, idx);
01049 dprintf(idx, P_("--- %d file.\n", "--- %d files.\n", cnt), cnt);
01050 }
01051 filelist_free(flist);
01052 }
01053
01054
01055
01056
01057
01058 static void filedb_getdesc(char *dir, char *fn, char **desc)
01059 {
01060 filedb_entry *fdbe = NULL;
01061
01062 fdbe = filedb_getentry(dir, fn);
01063 if (fdbe) {
01064 *desc = strdup(fdbe->desc);
01065 free_fdbe(&fdbe);
01066 } else
01067 *desc = NULL;
01068 }
01069
01070 static void filedb_getowner(char *dir, char *fn, char **owner)
01071 {
01072 filedb_entry *fdbe = NULL;
01073
01074 fdbe = filedb_getentry(dir, fn);
01075 if (fdbe) {
01076 *owner = strdup(fdbe->uploader);
01077 free_fdbe(&fdbe);
01078 } else
01079 *owner = NULL;
01080 }
01081
01082 static int filedb_getgots(char *dir, char *fn)
01083 {
01084 filedb_entry *fdbe = NULL;
01085 int gots = 0;
01086
01087 fdbe = filedb_getentry(dir, fn);
01088 if (fdbe) {
01089 gots = fdbe->gots;
01090 free_fdbe(&fdbe);
01091 }
01092 return gots;
01093 }
01094
01095 static void filedb_setdesc(char *dir, char *fn, char *desc)
01096 {
01097 filedb_entry *fdbe = NULL;
01098 FILE *fdb = NULL;
01099
01100 fdb = filedb_open(dir, 0);
01101 if (!fdb)
01102 return;
01103 filedb_readtop(fdb, NULL);
01104 fdbe = filedb_matchfile(fdb, ftell(fdb), fn);
01105 if (fdbe) {
01106 free_null(fdbe->desc);
01107 realloc_strcpy(fdbe->desc, desc);
01108 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL);
01109 free_fdbe(&fdbe);
01110 }
01111 filedb_close(fdb);
01112 }
01113
01114 static void filedb_setowner(char *dir, char *fn, char *owner)
01115 {
01116 filedb_entry *fdbe = NULL;
01117 FILE *fdb = NULL;
01118
01119 fdb = filedb_open(dir, 0);
01120 if (!fdb)
01121 return;
01122 filedb_readtop(fdb, NULL);
01123 fdbe = filedb_matchfile(fdb, ftell(fdb), fn);
01124 if (fdbe) {
01125 free_null(fdbe->uploader);
01126 realloc_strcpy(fdbe->uploader, owner);
01127 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL);
01128 free_fdbe(&fdbe);
01129 }
01130 filedb_close(fdb);
01131 }
01132
01133 static void filedb_getfiles(Tcl_Interp * irp, char *dir)
01134 {
01135 FILE *fdb;
01136 filedb_entry *fdbe;
01137
01138 fdb = filedb_open(dir, 0);
01139 if (!fdb)
01140 return;
01141 filedb_readtop(fdb, NULL);
01142 while (!feof(fdb)) {
01143 fdbe = filedb_getfile(fdb, ftell(fdb), GET_FILENAME);
01144 if (fdbe) {
01145 if (!(fdbe->stat & (FILE_DIR | FILE_UNUSED)))
01146 Tcl_AppendElement(irp, fdbe->filename);
01147 free_fdbe(&fdbe);
01148 }
01149 }
01150 filedb_close(fdb);
01151 }
01152
01153 static void filedb_getdirs(Tcl_Interp * irp, char *dir)
01154 {
01155 FILE *fdb;
01156 filedb_entry *fdbe;
01157
01158 fdb = filedb_open(dir, 0);
01159 if (!fdb)
01160 return;
01161 filedb_readtop(fdb, NULL);
01162 while (!feof(fdb)) {
01163 fdbe = filedb_getfile(fdb, ftell(fdb), GET_FILENAME);
01164 if (fdbe) {
01165 if ((!(fdbe->stat & FILE_UNUSED)) && (fdbe->stat & FILE_DIR))
01166 Tcl_AppendElement(irp, fdbe->filename);
01167 free_fdbe(&fdbe);
01168 }
01169 }
01170 filedb_close(fdb);
01171 }
01172
01173 static void filedb_change(char *dir, char *fn)
01174 {
01175 FILE *fdb;
01176 filedb_entry *fdbe;
01177 int changed = 0;
01178
01179 fdb = filedb_open(dir, 0);
01180 if (!fdb)
01181 return;
01182 filedb_readtop(fdb, NULL);
01183 fdbe = filedb_matchfile(fdb, ftell(fdb), fn);
01184 if (fdbe) {
01185 if (!(fdbe->stat & FILE_DIR))
01186 changed = 1;
01187 if (changed)
01188 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER);
01189 free_fdbe(&fdbe);
01190 }
01191 filedb_close(fdb);
01192 }