1 /*****************************************************************************
2  * HPUCODE --- Uuencoded files from FTN messagebase extractor
3  *****************************************************************************
4  * Copyright (C) 2002  Max Chernogor & Husky Team
5  *
6  * http://husky.sf.net
7  *
8  * This file is part of HUSKY fidonet package.
9  *
10  * HUSKY is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by the
12  * Free Software Foundation; either version 2, or (at your option) any
13  * later version.
14  *
15  * HUSKY is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with HPT; see the file COPYING.  If not, write to the Free
22  * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *****************************************************************************/
24 /* $Id$ */
25 
26 #include <errno.h>
27 #include <huskylib/huskylib.h>
28 #include "uuecode.h"
29 #include "dupe.h"
30 
31 
32 FILE *fDupe;
33 
34 s_dupeMemory *CommonDupes=NULL;
35 static time_t  tCR=0;
36 static time_t  maxTimeLifeDupesInArea=0;
37 
compareEntries(char * p_e1,char * p_e2)38 int compareEntries(char *p_e1, char *p_e2) {
39    const s_textDupeEntry  *atxt,   *btxt;
40    int rc = 1;
41    const void *e1 = (const void *)p_e1, *e2 = (const void *)p_e2;
42 
43    atxt = e1; btxt = e2;
44    rc = strcmp(atxt->filename, btxt->filename);
45    if (rc == 0) rc = strcmp(atxt->from, btxt->from);
46    if (rc == 0) rc = strcmp(atxt->areaname, btxt->areaname);
47 
48    return rc;
49 }
50 
writeEntry(char * p_entry)51 int writeEntry(char *p_entry) {
52    const s_textDupeEntry  *entxt;
53    const void *entry = (const void *)p_entry;
54 
55    entxt = entry;
56    if ( (tCR - entxt->timeCreated) < maxTimeLifeDupesInArea)
57    {
58        fprintf(fDupe,"%s %s %s %lu\n",
59          entxt->filename,entxt->areaname,entxt->from,
60          (unsigned long)entxt->timeCreated);
61    }
62 
63    return 1;
64 }
65 
deleteEntry(char * entry)66 int deleteEntry(char *entry) {
67 
68     if(entry)
69     {
70         s_textDupeEntry  *entxt;
71         entxt = (s_textDupeEntry *)entry;
72         nfree(entxt->from);
73         nfree(entxt->filename);
74         nfree(entxt->areaname);
75         nfree(entxt);
76     }
77     return 1;
78 }
79 
doReading(FILE * f,s_dupeMemory * mem)80 void doReading(FILE *f, s_dupeMemory *mem) {
81    s_textDupeEntry  *entxt;
82    char *line;
83    char fname[MAX],echoname[MAX],fromname[MAX];
84    time_t timecr=0;
85 
86    while( (line = readLine(f)) != NULL )
87    {
88       if(sscanf(line, "%s %s %s %ld",
89          fname, echoname, fromname, (signed long*)(&timecr)
90          ) != 4)
91          continue;
92 
93       entxt = (s_textDupeEntry*) scalloc(1,sizeof(s_textDupeEntry));
94 
95       entxt->filename = sstrdup(fname);
96       entxt->areaname = sstrdup(echoname);
97       entxt->from     = sstrdup(fromname);
98       entxt->timeCreated = timecr;
99 
100       tree_add(&(mem->avlTree), compareEntries, (char *) entxt, deleteEntry);
101 
102       nfree(line);
103    }
104 }
105 
readDupeFile()106 s_dupeMemory *readDupeFile() {
107    FILE *f;
108    char *fileName=NULL;
109    s_dupeMemory *dupeMemory;
110 
111    dupeMemory = smalloc(sizeof(s_dupeMemory));
112    tree_init(&(dupeMemory->avlTree),1);
113 
114    xstrscat(&fileName, config->dupeHistoryDir, "uuecode.dup", NULL);
115    w_log('2', "Reading dupes from %s", fileName);
116 
117    f = fopen(fileName, "rb");
118    if (f != NULL) { w_log(LL_FILE,"dupe.c:readDupeFile(): opened %s (\"rb\" mode)",fileName);
119        /*  readFile */
120        doReading(f, dupeMemory);
121        fclose(f);
122        w_log(LL_FILE, "Reading dupes done");
123    } else {
124        if (fexist(fileName)) w_log('2', "Error reading dupes");
125        else if( errno != ENOENT)
126          w_log('2', "Dupe base read error: %s", strerror(errno) );
127    }
128 
129    nfree(fileName);
130 
131    return dupeMemory;
132 }
133 
freeDupeMemory()134 void freeDupeMemory() {
135 
136    if (CommonDupes != NULL) {
137       tree_mung(&(CommonDupes -> avlTree), deleteEntry);
138       nfree(CommonDupes);
139    };
140 }
141 
createDupeFile(char * name)142 int createDupeFile(char *name) {
143    FILE *f;
144 
145 /*    w_log(LL_SRCLINE,"dupe.c:%u:createDupeFile() name='%s'", __LINE__, name); */
146 
147    f = fopen(name, "wb");
148    if (f!= NULL) {
149       w_log(LL_FILE,"dupe.c:createDupeFile(): opened %s (\"wb\" mode)",name);
150 
151       fDupe = f;
152       tree_trav(&(CommonDupes->avlTree), writeEntry);
153       fDupe = NULL;
154 
155       fclose(f);
156       freeDupeMemory();
157 
158       return 0;
159    } else return 1;
160 }
161 
162 
writeToDupeFile()163 int writeToDupeFile() {
164    char *fileName=NULL;
165 
166    int  rc = 0;
167 
168    xstrscat(&fileName, config->dupeHistoryDir, "uuecode.dup", NULL);
169 
170    if (CommonDupes != NULL) {
171       if (tree_count(&(CommonDupes->avlTree)) > 0) {
172          rc = createDupeFile(fileName);
173       }
174    }
175    nfree(fileName);
176    return rc;
177 }
178 
179 
dupeDetection(s_textDupeEntry * msg)180 int dupeDetection(s_textDupeEntry *msg) {
181 
182    int pos=0;
183    int nRet = 1;
184    if (CommonDupes == NULL)
185    {
186       CommonDupes = readDupeFile(); /* read Dupes */
187       time( &tCR );
188       maxTimeLifeDupesInArea = config->areasMaxDupeAge > 30 ?
189                                config->areasMaxDupeAge*86400:
190                                30*86400;
191    }
192    while ( msg->from[pos] != '\0' )
193    {
194       if( (msg->from[pos] == ' ') || (msg->from[pos] == '\t'))
195          msg->from[pos] = '_';
196       pos++;
197    }
198    msg->timeCreated = tCR;
199    if (tree_add(&(CommonDupes->avlTree), compareEntries, (char *) msg, deleteEntry)) {
200       nRet = 1;
201    }
202    else {
203       nRet = 0;
204    }
205    return nRet;
206 }
207 
208