/* * Copyright (c) 1998,1999,2000 Kazushi (Jam) Marukawa * All rights of my changes are reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice in the documentation and/or other materials provided with * the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef SOCKS #include #endif #include #ifdef BSD #include #endif #include #include #include #include #include #include #include #include #include #include "leafnode.h" #include "leafnode.h" const char* spooldir = 0; const char* libdir = 0; const char* defspooldir = SPOOLDIR; const char* deflibdir = LIBDIR; const char* version = VERSION; const char* id = "@(#) leafnode+ " VERSION; static char s[PATH_MAX+1024]; /* long string, used as temporary */ void initconfig(void) { if (spooldir == 0) if ((spooldir = getenv("SPOOLDIR")) == 0) spooldir = defspooldir; if (libdir == 0) if ((libdir = getenv("LEAFNODE")) == 0) if ((libdir = getenv("LIBDIR")) == 0) libdir = deflibdir; } const char* getconfigfname(void) { static struct string a = { 0, 0 }; initconfig(); sprintf(s, "%s/config", libdir); setstring(&a, s); return a.str; } const char* getinfofname(void) { static struct string a = { 0, 0 }; initconfig(); sprintf(s, "%s/groupinfo", libdir); setstring(&a, s); return a.str; } const char* getinfonewfname(void) { static struct string a = { 0, 0 }; initconfig(); sprintf(s, "%s/groupinfo.new", libdir); setstring(&a, s); return a.str; } const char* getactivefname(const char* servername) { static struct string a = { 0, 0 }; assert(servername != 0 && *servername != '\0'); initconfig(); sprintf(s, "%s/%s.active", libdir, servername); setstring(&a, s); return a.str; } const char* getserverfname(const char* servername) { static struct string a = { 0, 0 }; assert(servername != 0 && *servername != '\0'); initconfig(); sprintf(s, "%s/%s", libdir, servername); setstring(&a, s); return a.str; } const char* getservernewfname(const char* servername) { static struct string a = { 0, 0 }; assert(servername != 0 && *servername != '\0'); initconfig(); sprintf(s, "%s/%s.new", libdir, servername); setstring(&a, s); return a.str; } const char* getinterestingdname(void) { static struct string a = { 0, 0 }; initconfig(); sprintf(s, "%s/interesting.groups", spooldir); setstring(&a, s); return a.str; } const char* getinterestingngfname(const struct newsgroup* ng) { static struct string a = { 0, 0 }; assert(ng != 0); initconfig(); sprintf(s, "%s/interesting.groups/%s", spooldir, ng->name); setstring(&a, s); return a.str; } const char* getinterestingngdotfname(const struct newsgroup* ng) { static struct string a = { 0, 0 }; assert(ng != 0); initconfig(); sprintf(s, "%s/interesting.groups/.%s", spooldir, ng->name); setstring(&a, s); return a.str; } const char* getoutgoingdname(void) { static struct string a = { 0, 0 }; initconfig(); sprintf(s, "%s/out.going", spooldir); setstring(&a, s); return a.str; } extern const char* getoutgoingfname(const char* fname) { static struct string a = { 0, 0 }; initconfig(); sprintf(s, "%s/out.going/%s", spooldir, fname); setstring(&a, s); return a.str; } const char* getfailedpostingsdname(void) { static struct string a = { 0, 0 }; initconfig(); sprintf(s, "%s/failed.postings", spooldir); setstring(&a, s); return a.str; } const char* getfailedpostingsfname(const char* fname) { static struct string a = { 0, 0 }; initconfig(); sprintf(s, "%s/failed.postings/%s", spooldir, fname); setstring(&a, s); return a.str; } const char* getngdname(const struct newsgroup* ng) { static struct string a = { 0, 0 }; char* p; assert(ng != 0); initconfig(); sprintf(s, "%s/%s", spooldir, ng->name); p = s + strlen(spooldir) + 1; while (*p) { if (*p == '.') *p = '/'; else *p = tolower(*p); p++; } setstring(&a, s); return a.str; } const char* getartfname(const struct newsgroup* ng, const unsigned long art) { static struct string a = { 0, 0 }; assert(ng != 0 && art > 0); initconfig(); sprintf(s, "%s/%lu", getngdname(ng), art); setstring(&a, s); return a.str; } static enum { OLD, NEW } hashalg = OLD; const char* getmsgiddname(const unsigned int hash) { static struct string a = { 0, 0 }; initconfig(); if (hashalg == OLD) sprintf(s, "%s/message.id/%03d", spooldir, hash); else sprintf(s, "%s/message.id/X%03d", spooldir, hash); setstring(&a, s); return a.str; } const char* getmsgidfname(const char* msgid) { static struct string a = { 0, 0 }; char msgidbuf[1024]; unsigned long hash; char* p; assert(msgid != 0 && *msgid != '\0'); strcpy(msgidbuf, msgid); msgid = p = skipspaces(msgidbuf); *skipnonspaces(p) = '\0'; initconfig(); hash = 0; if (hashalg == OLD) { int i; char* q = p; /* uniform message-id */ i = strlen(spooldir) + 16; do { if (*q == '/') *q = '@'; else if (*q == '>') q[1] = '\0'; hash += (int)(*q++); hash += ++i; } while (*q); hash = (hash % 999) + 1; } else { char* q = p; int i; /* uniform message-id */ i = 1; while (*q != '\0') { if (*q == '/') *q = '@'; hash += i++ * (int)(*q++); } /* calculate index */ hash = hash % 997; } sprintf(s, "%s/%s", getmsgiddname(hash), msgid); setstring(&a, s); return a.str; }