File: body.c

package info (click to toggle)
sn 0.3.8-6.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 888 kB
  • ctags: 853
  • sloc: ansic: 9,260; sh: 483; makefile: 209
file content (92 lines) | stat: -rw-r--r-- 2,108 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
 * This file is part of the sn package.
 * Distribution of sn is covered by the GNU GPL. See file COPYING.
 * Copyright  1998-2000 Harold Tay.
 * Copyright  2000- Patrik Rdman.
 */

/*
 * How to deal with article bodies, which may be compressed.
 * On input, compression takes place in store.c without our help.
 * Caller must not free the article body on return.
 */

#ifdef USE_ZLIB

#include <stdlib.h>
#include <string.h>
#include <zconf.h>
#include <zlib.h>
#include "art.h"

static const char ver_ctrl_id[] = "$Id: body.c 29 2004-04-24 23:02:38Z patrik $";

int body (char **artbod, int *len)
{
   static char *bodbuf = NULL;
   z_stream zs;
   int e, msize, inc;

   if (bodbuf)
   {
      free(bodbuf);
      bodbuf = NULL;
   }

   if (*len < 0)
      return 1;
   if (0 == *len || *len < COMPRESS_MAGIC_LEN)
      return 0;
   for (e = 0; e < COMPRESS_MAGIC_LEN; e++)
      if ((*artbod)[e] != COMPRESS_MAGIC[e])
         return 0;

   inc = (*len / 2) + 1;
   zs.next_out = malloc(msize = zs.avail_out = 5 * inc);
   if (!(bodbuf = (char *) zs.next_out))
      return -1;
   zs.next_in = (unsigned char *) *artbod + COMPRESS_MAGIC_LEN;
   zs.avail_in = (unsigned) (*len - COMPRESS_MAGIC_LEN);
   zs.zalloc = 0;
   zs.zfree = 0;
   if ((e = inflateInit(&zs)))
      return 0;

   while (0 == (e = inflate(&zs, Z_NO_FLUSH)))
      if (zs.avail_out < 10)
      {
         char *tmp;
         int used;

         if (!(tmp = malloc(msize + inc)))
            goto bomb;
         used = msize - zs.avail_out;
         memcpy(tmp, bodbuf, used);
         zs.next_out = (unsigned char *) tmp + used;
         msize += inc;
         zs.avail_out += inc;
         free(bodbuf);
         bodbuf = tmp;
      }

   inflateEnd(&zs);
   if (Z_STREAM_END == e
       #if 0
       /* I have this problem; apparently I'm the only one who does */
       || Z_DATA_ERROR == e
       #endif
      )
   {
      *len = zs.next_out - (unsigned char *) bodbuf;
      *artbod = bodbuf;
      bodbuf[*len] = '\0';
      return 0;
   }

bomb:
   free(bodbuf);
   bodbuf = NULL;
   return -1;
}

#endif /* USE_ZLIB */