00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef lint
00029 static const char rcsid[] = "$Id: compress.c,v 1.10 2003-12-11 00:49:10 wcc Exp $";
00030 #endif
00031
00032 #define MODULE_NAME "compress"
00033 #define MAKING_COMPRESS
00034
00035 #include <string.h>
00036 #include <errno.h>
00037 #include <zlib.h>
00038
00039 #include "lib/eggdrop/module.h"
00040
00041 #ifdef HAVE_MMAP
00042 # include <sys/types.h>
00043 # include <sys/mman.h>
00044 # include <sys/stat.h>
00045 #endif
00046 #include "compress.h"
00047
00048 #define start compress_LTX_start
00049
00050 #define BUFLEN 512
00051
00052
00053 static eggdrop_t *egg = NULL;
00054
00055 static unsigned int compressed_files;
00056 static unsigned int uncompressed_files;
00057 static unsigned int compress_level;
00058
00059
00060 static int uncompress_to_file(char *f_src, char *f_target);
00061 static int compress_to_file(char *f_src, char *f_target, int mode_num);
00062 static int compress_file(char *filename, int mode_num);
00063 static int uncompress_file(char *filename);
00064 static int is_compressedfile(char *filename);
00065
00066 #include "tclcompress.c"
00067
00068
00069
00070
00071
00072
00073 static int is_compressedfile(char *filename)
00074 {
00075 char buf1[50], buf2[50];
00076 FILE *fin;
00077 register int len1, len2, i;
00078
00079 memset(buf1, 0, 50);
00080 memset(buf2, 0, 50);
00081 if (!is_file(filename))
00082 return COMPF_FAILED;
00083
00084
00085
00086 fin = gzopen(filename, "rb");
00087 if (!fin)
00088 return COMPF_FAILED;
00089 len1 = gzread(fin, buf1, sizeof(buf1));
00090 if (len1 < 0)
00091 return COMPF_FAILED;
00092 if (gzclose(fin) != Z_OK)
00093 return COMPF_FAILED;
00094
00095
00096
00097 fin = fopen(filename, "rb");
00098 if (!fin)
00099 return COMPF_FAILED;
00100 len2 = fread(buf2, 1, sizeof(buf2), fin);
00101 if (ferror(fin))
00102 return COMPF_FAILED;
00103 fclose(fin);
00104
00105
00106
00107 if (len1 != len2)
00108 return COMPF_COMPRESSED;
00109 for (i = 0; i < sizeof(buf1); i++)
00110 if (buf1[i] != buf2[i])
00111 return COMPF_COMPRESSED;
00112 return COMPF_UNCOMPRESSED;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122 static int uncompress_to_file(char *f_src, char *f_target)
00123 {
00124 char buf[BUFLEN];
00125 int len;
00126 FILE *fin, *fout;
00127
00128 if (!is_file(f_src)) {
00129 putlog(LOG_MISC, "*", _("Failed to uncompress file `%s': not a file."),
00130 f_src);
00131 return COMPF_ERROR;
00132 }
00133 fin = gzopen(f_src, "rb");
00134 if (!fin) {
00135 putlog(LOG_MISC, "*", _("Failed to uncompress file `%s': gzopen failed."),
00136 f_src);
00137 return COMPF_ERROR;
00138 }
00139
00140 fout = fopen(f_target, "wb");
00141 if (!fout) {
00142 putlog(LOG_MISC, "*", _("Failed to uncompress file `%1$s': open failed: %2$s."),
00143 f_src, strerror(errno));
00144 return COMPF_ERROR;
00145 }
00146
00147 while (1) {
00148 len = gzread(fin, buf, sizeof(buf));
00149 if (len < 0) {
00150 putlog(LOG_MISC, "*", _("Failed to uncompress file `%s': gzread failed."),
00151 f_src);
00152 return COMPF_ERROR;
00153 }
00154 if (!len)
00155 break;
00156 if ((int) fwrite(buf, 1, (unsigned int) len, fout) != len) {
00157 putlog(LOG_MISC, "*", _("Failed to uncompress file `%1$s': fwrite failed: %2$s."),
00158 f_src, strerror(errno));
00159 return COMPF_ERROR;
00160 }
00161 }
00162 if (fclose(fout)) {
00163 putlog(LOG_MISC, "*", _("Failed to uncompress file `%1$s': fclose failed: %2$s."),
00164 f_src, strerror(errno));
00165 return COMPF_ERROR;
00166 }
00167 if (gzclose(fin) != Z_OK) {
00168 putlog(LOG_MISC, "*", _("Failed to uncompress file `%s': gzclose failed."),
00169 f_src);
00170 return COMPF_ERROR;
00171 }
00172 uncompressed_files++;
00173 return COMPF_SUCCESS;
00174 }
00175
00176
00177
00178 inline static void adjust_mode_num(int *mode)
00179 {
00180 if (*mode > 9)
00181 *mode = 9;
00182 else if (*mode < 0)
00183 *mode = 0;
00184 }
00185
00186 #ifdef HAVE_MMAP
00187
00188
00189 static int compress_to_file_mmap(FILE *fout, FILE *fin)
00190 {
00191 int len, ifd = fileno(fin);
00192 char *buf;
00193 struct stat st;
00194
00195
00196 if (fstat(ifd, &st) < 0)
00197 return COMPF_ERROR;
00198 if (st.st_size <= 0)
00199 return COMPF_ERROR;
00200
00201
00202 buf = mmap(0, st.st_size, PROT_READ, MAP_SHARED, ifd, 0);
00203 if (buf < 0)
00204 return COMPF_ERROR;
00205
00206
00207 len = gzwrite(fout, buf, st.st_size);
00208 if (len != (int) st.st_size)
00209 return COMPF_ERROR;
00210
00211 munmap(buf, st.st_size);
00212 fclose(fin);
00213 if (gzclose(fout) != Z_OK)
00214 return COMPF_ERROR;
00215 return COMPF_SUCCESS;
00216 }
00217 #endif
00218
00219
00220
00221 static int compress_to_file(char *f_src, char *f_target, int mode_num)
00222 {
00223 char buf[BUFLEN], mode[5];
00224 FILE *fin, *fout;
00225 int len;
00226
00227 adjust_mode_num(&mode_num);
00228 snprintf(mode, sizeof mode, "wb%d", mode_num);
00229
00230 if (!is_file(f_src)) {
00231 putlog(LOG_MISC, "*", _("Failed to compress file `%s': not a file."),
00232 f_src);
00233 return COMPF_ERROR;
00234 }
00235 fin = fopen(f_src, "rb");
00236 if (!fin) {
00237 putlog(LOG_MISC, "*", _("Failed to compress file `%1$s': open failed: %2$s."),
00238 f_src, strerror(errno));
00239 return COMPF_ERROR;
00240 }
00241
00242 fout = gzopen(f_target, mode);
00243 if (!fout) {
00244 putlog(LOG_MISC, "*", _("Failed to compress file `%s': gzopen failed."),
00245 f_src);
00246 return COMPF_ERROR;
00247 }
00248
00249 #ifdef HAVE_MMAP
00250 if (compress_to_file_mmap(fout, fin) == COMPF_SUCCESS) {
00251 compressed_files++;
00252 return COMPF_SUCCESS;
00253 } else {
00254
00255
00256
00257 gzclose(fout);
00258 fout = gzopen(f_target, mode);
00259 }
00260 #endif
00261
00262 while (1) {
00263 len = fread(buf, 1, sizeof(buf), fin);
00264 if (ferror(fin)) {
00265 putlog(LOG_MISC, "*", _("Failed to compress file `%1$s': fread failed: %2$s"),
00266 f_src, strerror(errno));
00267 return COMPF_ERROR;
00268 }
00269 if (!len)
00270 break;
00271 if (gzwrite(fout, buf, (unsigned int) len) != len) {
00272 putlog(LOG_MISC, "*", _("Failed to compress file `%s': gzwrite failed."),
00273 f_src);
00274 return COMPF_ERROR;
00275 }
00276 }
00277 fclose(fin);
00278 if (gzclose(fout) != Z_OK) {
00279 putlog(LOG_MISC, "*", _("Failed to compress file `%s': gzclose failed."),
00280 f_src);
00281 return COMPF_ERROR;
00282 }
00283 compressed_files++;
00284 return COMPF_SUCCESS;
00285 }
00286
00287
00288
00289 static int compress_file(char *filename, int mode_num)
00290 {
00291 char *temp_fn, randstr[5];
00292 int ret;
00293
00294
00295 temp_fn = malloc(strlen(filename) + 5);
00296 make_rand_str(randstr, 4);
00297 strcpy(temp_fn, filename);
00298 strcat(temp_fn, randstr);
00299
00300
00301 ret = compress_to_file(filename, temp_fn, mode_num);
00302
00303
00304
00305
00306 if (ret == COMPF_SUCCESS)
00307 movefile(temp_fn, filename);
00308
00309 free(temp_fn);
00310 return ret;
00311 }
00312
00313
00314
00315 static int uncompress_file(char *filename)
00316 {
00317 char *temp_fn, randstr[5];
00318 int ret;
00319
00320
00321 temp_fn = malloc(strlen(filename) + 5);
00322 make_rand_str(randstr, 4);
00323 strcpy(temp_fn, filename);
00324 strcat(temp_fn, randstr);
00325
00326
00327 ret = uncompress_to_file(filename, temp_fn);
00328
00329
00330
00331
00332 if (ret == COMPF_SUCCESS)
00333 movefile(temp_fn, filename);
00334
00335 free(temp_fn);
00336 return ret;
00337 }
00338
00339
00340
00341
00342
00343 static tcl_ints my_tcl_ints[] = {
00344 {"compress_level", &compress_level},
00345 {NULL, NULL}
00346 };
00347
00348 static int compress_report(int idx, int details)
00349 {
00350 if (details) {
00351 dprintf(idx, P_(" Compressed %u file,", " Compressed %u files,",
00352 compressed_files), compressed_files);
00353 dprintf(idx, P_(" uncompressed %u file.\n", " uncompressed %u files.\n",
00354 uncompressed_files), uncompressed_files);
00355 }
00356 return 0;
00357 }
00358
00359 static char *compress_close()
00360 {
00361 rem_help_reference("compress.help");
00362 rem_tcl_commands(my_tcl_cmds);
00363 rem_tcl_ints(my_tcl_ints);
00364 module_undepend(MODULE_NAME);
00365 return NULL;
00366 }
00367
00368 EXPORT_SCOPE char *start();
00369
00370 static Function compress_table[] =
00371 {
00372
00373 (Function) start,
00374 (Function) compress_close,
00375 (Function) 0,
00376 (Function) compress_report,
00377
00378 (Function) compress_to_file,
00379 (Function) compress_file,
00380 (Function) uncompress_to_file,
00381 (Function) uncompress_file,
00382
00383 (Function) is_compressedfile,
00384 };
00385
00386 char *start(eggdrop_t *eggdrop)
00387 {
00388 egg = eggdrop;
00389 compressed_files = 0;
00390 uncompressed_files = 0;
00391 compress_level = 9;
00392
00393 module_register(MODULE_NAME, compress_table, 1, 1);
00394 if (!module_depend(MODULE_NAME, "eggdrop", 107, 0)) {
00395 module_undepend(MODULE_NAME);
00396 return _("This module needs eggdrop1.7.0 or later");
00397 }
00398 add_tcl_ints(my_tcl_ints);
00399 add_tcl_commands(my_tcl_cmds);
00400 add_help_reference("compress.help");
00401 return NULL;
00402 }