static void filedb_setlink(char *dir, char *fn, char *link) { filedb_entry *fdbe = NULL; FILE *fdb = NULL; fdb = filedb_open(dir, 0); if (!fdb) return; filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), fn); if (fdbe) { /* Change existing one? */ if ((fdbe->stat & FILE_DIR) || !fdbe->sharelink) return; if (!link || !link[0]) filedb_delfile(fdb, fdbe->pos); else { my_free(fdbe->sharelink); malloc_strcpy(fdbe->sharelink, link); filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL); } free_fdbe(&fdbe); return; } fdbe = malloc_fdbe(); malloc_strcpy(fdbe->uploader, botnetnick); malloc_strcpy(fdbe->filename, fn); malloc_strcpy(fdbe->sharelink, link); fdbe->uploaded = now; filedb_addfile(fdb, fdbe); free_fdbe(&fdbe); filedb_close(fdb); }
static int tcl_setflags(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { FILE *fdb; filedb_entry *fdbe; char *s = NULL, *p, *d; BADARGS(3, 4, " dir ?flags ?channel??"); malloc_strcpy(s, argv[1]); if (s[strlen(s) - 1] == '/') s[strlen(s) - 1] = 0; p = strrchr(s, '/'); if (p == NULL) { p = s; d = ""; } else { *p = 0; p++; d = s; } fdb = filedb_open(d, 0); if (!fdb) { Tcl_AppendResult(irp, "-3", NULL); /* filedb access failed */ my_free(s); return TCL_OK; } filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), p); my_free(s); if (!fdbe) { Tcl_AppendResult(irp, "-1", NULL); /* No such dir */ return TCL_OK; } if (!(fdbe->stat & FILE_DIR)) { Tcl_AppendResult(irp, "-2", NULL); /* Not a dir */ return TCL_OK; } if (argc >= 3) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; char f[100]; break_down_flags(argv[2], &fr, NULL); build_flags(f, &fr, NULL); malloc_strcpy(fdbe->flags_req, f); } else my_free(fdbe->flags_req); if (argc == 4) malloc_strcpy(fdbe->chan, argv[3]); filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL); free_fdbe(&fdbe); filedb_close(fdb); Tcl_AppendResult(irp, "0", NULL); return TCL_OK; }
/* Adds information for a newly added file. Actually the name * is misleading, as the file is added in filedb_open() and we * only add information in here. */ static void filedb_add(FILE *fdb, char *filename, char *nick) { filedb_entry *fdbe = NULL; filedb_readtop(fdb, NULL); /* When the filedb was opened, a record was already created. */ fdbe = filedb_matchfile(fdb, ftell(fdb), filename); if (!fdbe) return; my_free(fdbe->uploader); malloc_strcpy(fdbe->uploader, nick); fdbe->uploaded = now; filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL); free_fdbe(&fdbe); }
/* Merges empty entries to one big entry, if they directly * follow each other. Does this for the complete DB. * This considerably speeds up several actions performed on * the db. */ static void filedb_mergeempty(FILE *fdb) { filedb_entry *fdbe_t, *fdbe_i; int modified; filedb_readtop(fdb, NULL); while (!feof(fdb)) { fdbe_t = filedb_getfile(fdb, ftell(fdb), GET_HEADER); if (fdbe_t) { if (fdbe_t->stat & FILE_UNUSED) { modified = 0; fdbe_i = filedb_getfile(fdb, ftell(fdb), GET_HEADER); while (fdbe_i) { /* Is this entry in use? */ if (!(fdbe_i->stat & FILE_UNUSED)) break; /* It is, exit loop. */ /* Woohoo, found an empty entry. Append it's space to * our target entry's buffer space. */ fdbe_t->buf_len += sizeof(filedb_header) + fdbe_i->buf_len; modified++; free_fdbe(&fdbe_i); /* Get next file entry */ fdbe_i = filedb_getfile(fdb, ftell(fdb), GET_HEADER); } /* Did we exit the loop because of a used entry? */ if (fdbe_i) { free_fdbe(&fdbe_i); /* Did we find any empty entries before? */ if (modified) filedb_updatefile(fdb, fdbe_t->pos, fdbe_t, UPDATE_SIZE); /* ... or because we hit EOF? */ } else { /* Truncate trailing empty entries and exit. */ ftruncate(fileno(fdb), fdbe_t->pos); free_fdbe(&fdbe_t); return; } } free_fdbe(&fdbe_t); } } }
static void filedb_setowner(char *dir, char *fn, char *owner) { filedb_entry *fdbe = NULL; FILE *fdb = NULL; fdb = filedb_open(dir, 0); if (!fdb) return; filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), fn); if (fdbe) { my_free(fdbe->uploader); malloc_strcpy(fdbe->uploader, owner); filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL); free_fdbe(&fdbe); } filedb_close(fdb); }
static void filedb_setdesc(char *dir, char *fn, char *desc) { filedb_entry *fdbe = NULL; FILE *fdb = NULL; fdb = filedb_open(dir, 0); if (!fdb) return; filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), fn); if (fdbe) { free_null(fdbe->desc); realloc_strcpy(fdbe->desc, desc); filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL); free_fdbe(&fdbe); } filedb_close(fdb); }
static void filedb_change(char *dir, char *fn) { FILE *fdb; filedb_entry *fdbe; int changed = 0; fdb = filedb_open(dir, 0); if (!fdb) return; filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), fn); if (fdbe) { if (!(fdbe->stat & FILE_DIR)) changed = 1; if (changed) filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER); free_fdbe(&fdbe); } filedb_close(fdb); }
static void filedb_change(char *dir, char *fn, int what) { FILE *fdb; filedb_entry *fdbe; int changed = 0; fdb = filedb_open(dir, 0); if (!fdb) return; filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), fn); if (fdbe) { if (!(fdbe->stat & FILE_DIR)) { switch (what) { case FILEDB_SHARE: fdbe->stat |= FILE_SHARE; break; case FILEDB_UNSHARE: fdbe->stat &= ~FILE_SHARE; break; } changed = 1; } switch (what) { case FILEDB_HIDE: fdbe->stat |= FILE_HIDDEN; changed = 1; break; case FILEDB_UNHIDE: fdbe->stat &= ~FILE_HIDDEN; changed = 1; break; } if (changed) filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER); free_fdbe(&fdbe); } filedb_close(fdb); }
/* Updates the specified filedb in several ways: * * 1. Adds all new files from the directory to the db. * 2. Removes all stale entries from the db. * 3. Optimises the db. */ static void filedb_update(char *path, FILE *fdb, int sort) { struct dirent *dd = NULL; struct stat st; filedb_entry *fdbe = NULL; DIR *dir = NULL; long where = 0; char *name = NULL, *s = NULL; /* * FIRST: make sure every real file is in the database */ dir = opendir(path); if (dir == NULL) { putlog(LOG_MISC, "*", FILES_NOUPDATE); return; } dd = readdir(dir); while (dd != NULL) { malloc_strcpy(name, dd->d_name); if (name[0] != '.') { s = nmalloc(strlen(path) + strlen(name) + 2); sprintf(s, "%s/%s", path, name); stat(s, &st); my_free(s); filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), name); if (!fdbe) { /* new file! */ fdbe = malloc_fdbe(); malloc_strcpy(fdbe->filename, name); malloc_strcpy(fdbe->uploader, botnetnick); fdbe->uploaded = now; fdbe->size = st.st_size; if (S_ISDIR(st.st_mode)) fdbe->stat |= FILE_DIR; filedb_addfile(fdb, fdbe); } else if (fdbe->size != st.st_size) { /* update size if needed */ fdbe->size = st.st_size; filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER); } free_fdbe(&fdbe); } dd = readdir(dir); } if (name) my_free(name); closedir(dir); /* * SECOND: make sure every db file is real */ filedb_readtop(fdb, NULL); fdbe = filedb_getfile(fdb, ftell(fdb), GET_FILENAME); while (fdbe) { where = ftell(fdb); if (!(fdbe->stat & FILE_UNUSED) && !(fdbe->stat & FILE_ISLINK) && fdbe->filename) { s = nmalloc(strlen(path) + 1 + strlen(fdbe->filename) + 1); sprintf(s, "%s/%s", path, fdbe->filename); if (stat(s, &st) != 0) /* gone file */ filedb_delfile(fdb, fdbe->pos); my_free(s); } free_fdbe(&fdbe); fdbe = filedb_getfile(fdb, where, GET_FILENAME); } /* * THIRD: optimise database * * Instead of sorting, we only clean up the db, because sorting is now * done on-the-fly when we display the file list. */ if (sort) filedb_cleanup(fdb); /* Cleanup DB */ filedb_timestamp(fdb); /* Write new timestamp */ }
static int tcl_mkdir(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { FILE *fdb; filedb_entry *fdbe; char *s = NULL, *t, *d, *p; struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; BADARGS(2, 4, " dir ?required-flags ?channel??"); malloc_strcpy(s, argv[1]); if (s[strlen(s) - 1] == '/') s[strlen(s) - 1] = 0; p = strrchr(s, '/'); if (p == NULL) { p = s; d = ""; } else { *p = 0; p++; d = s; } fdb = filedb_open(d, 0); if (!fdb) { Tcl_AppendResult(irp, "-3", NULL); /* filedb access failed */ my_free(s); return TCL_OK; } filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), p); if (!fdbe) { t = nmalloc(strlen(dccdir) + strlen(d) + strlen(p) + 2); sprintf(t, "%s%s/%s", dccdir, d, p); if (mkdir(t, 0755) != 0) { Tcl_AppendResult(irp, "1", NULL); my_free(t); my_free(s); filedb_close(fdb); return TCL_OK; } fdbe = malloc_fdbe(); fdbe->stat = FILE_DIR; malloc_strcpy(fdbe->filename, argv[1]); fdbe->uploaded = now; } else if (!(fdbe->stat & FILE_DIR)) { Tcl_AppendResult(irp, "2", NULL); free_fdbe(&fdbe); my_free(s); filedb_close(fdb); return TCL_OK; } if (argc >= 3) { char f[100]; break_down_flags(argv[2], &fr, NULL); build_flags(f, &fr, NULL); malloc_strcpy(fdbe->flags_req, f); } else if (fdbe->flags_req) { my_free(fdbe->flags_req); } if (argc == 4) { malloc_strcpy(fdbe->chan, argv[3]); } else if (fdbe->chan) my_free(fdbe->chan); if (!fdbe->pos) fdbe->pos = POS_NEW; filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL); filedb_close(fdb); free_fdbe(&fdbe); Tcl_AppendResult(irp, "0", NULL); return TCL_OK; }