/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "leafnode.h" static struct article* findarticle(const char* ngstr, const char* msgid) { struct newsgroup* ng = findgroup(ngstr); unsigned long art; static struct article a = { 0, 0UL }; if (ng == 0) return 0; chdirgroup(ng, 1); /* look for an article having same message-id */ getxover(); for (art = xfirst; art <= xlast; art++) { if (xoverinfo[art-xfirst].text) { char* p = strchr(xoverinfo[art-xfirst].text, '\t'); char* q = NULL; if (p) p = strchr(p + 1, '\t'); if (p) p = strchr(p + 1, '\t'); if (p) p = strchr(p + 1, '\t'); if (p) q = strchr(p + 1, '\t'); if (p && q && strncmp(p + 1, msgid, q-p-1) == 0) break; } } if (art <= xlast) { a.ng = ng; a.art = art; return &a; } else { return 0; } } void addarticle(struct articles* p, const struct article* a) { if (p->num + 1 >= p->size) { p->size = (p->num + 1 + 255) / 256 * 256; p->arts = critrealloc(p->arts, p->size * sizeof(struct article), "addarticle"); } p->arts[p->num++] = *a; } struct articles* findarticles(const char* msgid) { static struct articles arts = { 0, 0, 0 }; FILE* f; char* p; assert(msgid != NULL && *msgid != '\0'); if ((f = fopen(getmsgidfname(msgid), "r")) == 0) return 0; p = getaheader(f, "Xref"); /* clear arts */ arts.num = 0; if (!*p) { /* * No Xref header, so look for articles in each newsgroup * by using msgid and "Newsgroups" header. */ char* ngstr = getaheader(f, "Newsgroups"); char* q; fclose(f); for (p = ngstr; p != 0; p = q) { struct article* a; q = strchr(p, ','); if (q) *q++ = '\0'; p = skipspaces(p); a = findarticle(p, msgid); if (a != 0) { addarticle(&arts, a); } } } else { /* * Find Xref header, so use it to build articles' array. * Sometimes, articles may already be expired by texpire, * so this result may be not accurate. */ fclose(f); /* skip 1st strings as hostname */ p = skipnonspaces(p); p = skipspaces(p); /* build articles' array */ while (*p) { char* q; struct newsgroup* ng; unsigned long art; /* fetch string before ':' as newsgroup name */ q = p; while (*q && *q != ':') q++; if (*q == '\0') break; /* cannot find ':'. it means xref: may be broken. */ *q++ = '\0'; ng = findgroup(p); /* fetch string after ':' as article number */ p = skipnonspaces(q); if (*p) *p++ = '\0'; art = strtoul(q, NULL, 10); if (ng && art > 0) { struct article a; a.ng = ng; a.art = art; addarticle(&arts, &a); } } } if (arts.num > 0) return &arts; else return 0; }