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