source: npl/mailserver/dspam/dspam-3.10.2/src/tools.hash_drv/csscompress.c @ c5c522c

gcc484ntopperl-5.22
Last change on this file since c5c522c was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/* $Id: csscompress.c,v 1.838 2011/11/16 00:19:14 sbajic Exp $ */
2
3/*
4 DSPAM
5 COPYRIGHT (C) 2002-2012 DSPAM PROJECT
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Affero General Public License as
9 published by the Free Software Foundation, either version 3 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20*/
21
22/* csscompress.c - Compress a hash database's extents */
23
24#ifdef HAVE_CONFIG_H
25#include <auto-config.h>
26#endif
27
28#include <string.h>
29#include <sys/types.h>
30#include <sys/mman.h>
31#include <sys/stat.h>
32#include <sys/uio.h>
33#include <dirent.h>
34#include <unistd.h>
35#include <errno.h>
36#include <stdlib.h>
37#include <stdio.h>
38#include <fcntl.h>
39#include <signal.h>
40#include <libgen.h>
41#include <errno.h>
42
43#ifdef TIME_WITH_SYS_TIME
44#   include <sys/time.h>
45#   include <time.h>
46#else
47#   ifdef HAVE_SYS_TIME_H
48#       include <sys/time.h>
49#   else
50#       include <time.h>
51#   endif
52#endif
53
54#define READ_ATTRIB(A)          _ds_read_attribute(agent_config, A)
55#define MATCH_ATTRIB(A, B)      _ds_match_attribute(agent_config, A, B)
56
57int DO_DEBUG
58#ifdef DEBUG
59= 1
60#else
61= 0
62#endif
63;
64
65#include "read_config.h"
66#include "hash_drv.h"
67#include "error.h"
68#include "language.h"
69 
70#define SYNTAX "syntax: csscompress [filename]"
71
72int csscompress(const char *filename);
73
74int main(int argc, char *argv[]) {
75  int r;
76
77  if (argc<2) {
78    fprintf(stderr, "%s\n", SYNTAX);
79    exit(EXIT_FAILURE);
80  }
81   
82  agent_config = read_config(NULL);
83  if (!agent_config) {
84    LOG(LOG_ERR, ERR_AGENT_READ_CONFIG);
85    exit(EXIT_FAILURE);
86  }
87
88  r = csscompress(argv[1]);
89 
90  if (r) {
91    fprintf(stderr, "csscompress failed on error %d\n", r);
92    exit(EXIT_FAILURE);
93  }
94  exit(EXIT_SUCCESS);
95}
96
97int csscompress(const char *filename) {
98  unsigned long i;
99  hash_drv_header_t header;
100  void *offset;
101  unsigned long reclen, extent = 0;
102  struct _hash_drv_map old, new;
103  hash_drv_spam_record_t rec;
104  unsigned long filepos;
105  char newfile[128];
106  struct stat st;
107  char *filenamecopy;
108  unsigned long max_seek     = HASH_SEEK_MAX;
109  unsigned long max_extents  = 0;
110  unsigned long extent_size  = HASH_EXTENT_MAX;
111  int pctincrease = 0;
112  int flags = 0;
113
114  if (READ_ATTRIB("HashExtentSize"))
115    extent_size = strtol(READ_ATTRIB("HashExtentSize"), NULL, 0);
116
117  if (READ_ATTRIB("HashMaxExtents"))
118    max_extents = strtol(READ_ATTRIB("HashMaxExtents"), NULL, 0);
119
120  if (MATCH_ATTRIB("HashAutoExtend", "on"))
121    flags = HMAP_AUTOEXTEND;
122
123  if (READ_ATTRIB("HashMaxSeek"))
124     max_seek = strtol(READ_ATTRIB("HashMaxSeek"), NULL, 0);
125
126  if (READ_ATTRIB("HashPctIncrease")) {
127    pctincrease = atoi(READ_ATTRIB("HashPctIncrease"));
128    if (pctincrease > 100) {
129        LOG(LOG_ERR, "HashPctIncrease out of range; ignoring");
130        pctincrease = 0;
131    }
132  }
133
134  filenamecopy = strdup(filename);
135  if (filenamecopy == NULL)
136    return EFAILURE;
137
138  snprintf(newfile, sizeof(newfile), "/%s/.dspam%u.css", dirname((char *)filenamecopy), (unsigned int) getpid());
139
140  if (stat(filename, &st) < 0)
141    return EFAILURE;
142
143  if (_hash_drv_open(filename, &old, 0, max_seek,
144                     max_extents, extent_size, pctincrease, flags))
145  {
146    return EFAILURE;
147  }
148
149  /* determine total record length */
150  header = old.addr;
151  reclen = 0;
152  while((unsigned long) header < (unsigned long) ((unsigned long) old.addr + old.file_len)) {
153    unsigned long max = header->hash_rec_max;
154    reclen += max;
155    offset = header;
156    offset = (void *)((unsigned long) offset + sizeof(struct _hash_drv_header));
157    max *= sizeof(struct _hash_drv_spam_record);
158    offset = (void *)((unsigned long) offset + max);
159    header = offset;
160  }
161
162  if (_hash_drv_open(newfile, &new, reclen,  max_seek,
163                     max_extents, extent_size, pctincrease, flags))
164  {
165    _hash_drv_close(&old);
166    return EFAILURE;
167  }
168
169  /* preserve counters, permissions, and ownership */
170  memcpy(&(new.header->totals), &(old.header->totals), sizeof(new.header->totals));
171
172  if (fchown(new.fd, st.st_uid, st.st_gid) < 0) {
173    _hash_drv_close(&new);
174    _hash_drv_close(&old);
175    unlink(newfile);
176    return EFAILURE;
177  }
178
179  if (fchmod(new.fd, st.st_mode) < 0) {
180    _hash_drv_close(&new);
181    _hash_drv_close(&old);
182    unlink(newfile);
183    return EFAILURE;
184  }
185
186  filepos = sizeof(struct _hash_drv_header);
187  header = old.addr;
188  while(filepos < old.file_len) {
189    printf("compressing %lu records in extent %lu\n", header->hash_rec_max, extent);
190    extent++;
191    for(i=0;i<header->hash_rec_max;i++) {
192      rec = (void *)((unsigned long) old.addr + filepos);
193      if (rec->hashcode) {
194        if (_hash_drv_set_spamrecord(&new, rec, 0)) {
195          LOG(LOG_WARNING, "aborting on error");
196          _hash_drv_close(&new);
197          _hash_drv_close(&old);
198          unlink(newfile);
199          return EFAILURE;
200        }
201      }
202      filepos += sizeof(struct _hash_drv_spam_record);
203    }
204    offset = (void *)((unsigned long) old.addr + filepos);
205    header = offset;
206    filepos += sizeof(struct _hash_drv_header);
207  }
208
209  _hash_drv_close(&new);
210  _hash_drv_close(&old);
211  if (rename(newfile, filename))
212    fprintf(stderr, "rename(%s, %s): %s\n", newfile, filename, strerror(errno));
213  return 0;
214}
Note: See TracBrowser for help on using the repository browser.