/* Copyright (C) 2000-1 drscholl@users.sourceforge.net This is free software distributed under the terms of the GNU Public License. $Id: add_file.c,v 1.100 2001/09/29 05:21:51 drscholl Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "opennap.h" #include "debug.h" #ifndef ROUTING_ONLY /* allowed bitrates for MPEG V1/V2 Layer III */ const int BitRate[18] = { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 192, 224, 256, 320 }; /* allowed sample rates for MPEG V2/3 */ const int SampleRate[6] = { 16000, 24000, 22050, 32000, 44100, 48000 }; #if DEBUG int validate_flist (FileList * p) { int count = 0; DList *list; ASSERT_RETURN_IF_FAIL (VALID_LEN (p, sizeof (FileList)), 0); ASSERT_RETURN_IF_FAIL (p->magic == MAGIC_FLIST, 0); ASSERT_RETURN_IF_FAIL (VALID_LEN (p->key, strlen (p->key) + 1), 0); for (list = p->list; list; list = list->next, count++) ; ASSERT_RETURN_IF_FAIL (p->count == count, 0); return 1; } #endif /* its assumed that `key' is all lowercase */ static void sInsertFile (HASH * table, char *key, DATUM * d, TokenRef * ref) { FileList *files; DList *dlist; ASSERT (table != 0); ASSERT (key != 0); ASSERT (d != 0); files = hash_lookup (table, key); /* if there is no entry for this particular word, create one now */ if (!files) { files = CALLOC (1, sizeof (FileList)); if (!files) { OUTOFMEMORY ("sInsertFile"); return; } #if DEBUG files->magic = MAGIC_FLIST; #endif files->key = STRDUP (key); if (!files->key) { OUTOFMEMORY ("sInsertFile"); FREE (files); return; } if (hash_add (table, files->key, files)) { FREE (files->key); FREE (files); return; } } ASSERT (validate_flist (files)); dlist = CALLOC (1, sizeof (DList)); if (!dlist) { OUTOFMEMORY ("list"); if (!files->list) hash_remove (table, files->key); return; } dlist->data = d; /* order is not important, push to beginning of list for speed */ if (files->list) files->list->prev = dlist; dlist->next = files->list; files->list = dlist; files->count++; /* this is conditional since we don't keep track of the key when * inserting the hash value for the RESUME function. */ if (ref) { /* we keep a pointer to the flist in which this file is inserted, * and the individual list element so that deletion doesn't require * scanning the entire list (which could be quite long). */ ref->flist = files; ref->dlist = dlist; /* allows for quick deletion */ } } /* common code for inserting a file into the various hash tables */ static void sInsertDatum (DATUM * info, char *av) { LIST *tokens, *ptr; unsigned int fsize; char *p; int numTokens; int i; ASSERT (info != 0); ASSERT (av != 0); if (!info->user->con->uopt->files) { /* create the hash table */ info->user->con->uopt->files = hash_init (257, (hash_destroy) free_datum); if (!info->user->con->uopt->files) { OUTOFMEMORY ("sInsertDatum"); return; } } hash_add (info->user->con->uopt->files, info->filename, info); if (option (ON_IGNORE_SUFFIX)) { if ((p = strrchr (av, '.'))) *p = 0; } /* split the filename into words */ tokens = tokenize (av, NULL); numTokens = list_count (tokens); if (numTokens > kOMaxTokens) { log_message ("sInsertDatum: file has %d tokens (%d max)", numTokens, kOMaxTokens); /* strip of the leading tokens since these will be the least * specific. */ while (numTokens > kOMaxTokens) { ptr = tokens; tokens = tokens->next; FREE (ptr); numTokens--; } } /* the filename may not consist of any searchable words, in which * case its not entered into the index. this file will only be seen * when browsing the user possessing it */ if (numTokens > 0) { info->tokens = MALLOC (sizeof (TokenRef) * numTokens); if (!info->tokens) { OUTOFMEMORY ("sInsertToken"); hash_remove (info->user->con->uopt->files, info->filename); FREE (info->filename); FREE (info); list_free (tokens, 0); return; } info->numTokens = numTokens; for (i = 0, ptr = tokens; i < numTokens; i++, ptr = ptr->next) sInsertFile (File_Table, ptr->data, info, &info->tokens[i]); list_free (tokens, 0); } #if RESUME /* index by md5 hash */ sInsertFile (MD5, info->hash, info, 0); #endif fsize = info->size / 1024; /* in kbytes */ info->user->shared++; info->user->libsize += fsize; Num_Gigs += fsize; /* this is actually kB, not gB */ Num_Files++; Local_Files++; info->user->sharing = 1; /* note that we began sharing */ } static DATUM * sNewDatum (char *filename, char *hash) { DATUM *info = CALLOC (1, sizeof (DATUM)); (void) hash; if (!info) { OUTOFMEMORY ("sNewDatum"); return 0; } info->filename = STRDUP (filename); if (!info->filename) { OUTOFMEMORY ("sNewDatum"); FREE (info); return 0; } #if RESUME info->hash = STRDUP (hash); if (!info->hash) { OUTOFMEMORY ("sNewDatum"); FREE (info->filename); FREE (info); return 0; } #endif return info; } static int sBitrateToMask (int bitrate, USER * user) { unsigned int i; for (i = 0; i < sizeof (BitRate) / sizeof (int); i++) { if (bitrate <= BitRate[i]) return i; } log_message ("sBitrateToMask(): invalid bit rate %d (%s, \"%s\")", bitrate, user->nick, user->clientinfo); return 0; /* invalid bitrate */ } static int sFreqToMask (int freq, USER * user) { unsigned int i; for (i = 0; i < sizeof (SampleRate) / sizeof (int); i++) { if (freq <= SampleRate[i]) return i; } log_message ("sFreqToMask(): invalid sample rate %d (%s, \"%s\")", freq, user->nick, user->clientinfo); return 0; } /* 100 ""