~ubuntu-branches/ubuntu/maverick/ilohamail/maverick

« back to all changes in this revision

Viewing changes to IlohaMail/include/tnef_decoder.inc

  • Committer: Bazaar Package Importer
  • Author(s): Joerg Jaspert
  • Date: 2004-02-04 13:44:37 UTC
  • Revision ID: james.westby@ubuntu.com-20040204134437-kz8j3ui2qa7oq8z2
Tags: upstream-0.8.12
ImportĀ upstreamĀ versionĀ 0.8.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/*
 
3
 * tnef_decoder.php
 
4
 *  Graham Norbury <gnorbury@bondcar.com>
 
5
 *  (c) 2002 (GNU GPL - see ../../COPYING)
 
6
 *
 
7
 *  Functions for decoding TNEF attachments in native PHP
 
8
 *
 
9
 *  Adapted from original designs by:
 
10
 *    Thomas Boll <tb@boll.ch>             [tnef.c]
 
11
 *    Mark Simpson <damned@world.std.com>  [tnef-1.1.1]
 
12
 *
 
13
 */
 
14
 
 
15
define("TNEF_SIGNATURE",      0x223e9f78);
 
16
define("TNEF_LVL_MESSAGE",    0x01);
 
17
define("TNEF_LVL_ATTACHMENT", 0x02);
 
18
 
 
19
define("TNEF_STRING", 0x00010000);
 
20
define("TNEF_TEXT",   0x00020000);
 
21
define("TNEF_BYTE",   0x00060000);
 
22
define("TNEF_WORD",   0x00070000);
 
23
define("TNEF_DWORD",  0x00080000);
 
24
 
 
25
define("TNEF_ASUBJECT",   TNEF_DWORD  | 0x8004);
 
26
define("TNEF_AMCLASS",    TNEF_WORD   | 0x8008);
 
27
define("TNEF_BODYTEXT",   TNEF_TEXT   | 0x800c);
 
28
define("TNEF_ATTACHDATA", TNEF_BYTE   | 0x800f);
 
29
define("TNEF_AFILENAME",  TNEF_STRING | 0x8010);
 
30
define("TNEF_ARENDDATA",  TNEF_BYTE   | 0x9002);
 
31
define("TNEF_AMAPIATTRS", TNEF_BYTE   | 0x9005);
 
32
define("TNEF_AVERSION",   TNEF_DWORD  | 0x9006);
 
33
 
 
34
define("TNEF_MAPI_NULL",           0x0001);
 
35
define("TNEF_MAPI_SHORT",          0x0002);
 
36
define("TNEF_MAPI_INT",            0x0003);
 
37
define("TNEF_MAPI_FLOAT",          0x0004);
 
38
define("TNEF_MAPI_DOUBLE",         0x0005);
 
39
define("TNEF_MAPI_CURRENCY",       0x0006);
 
40
define("TNEF_MAPI_APPTIME",        0x0007);
 
41
define("TNEF_MAPI_ERROR",          0x000a);
 
42
define("TNEF_MAPI_BOOLEAN",        0x000b);
 
43
define("TNEF_MAPI_OBJECT",         0x000d);
 
44
define("TNEF_MAPI_INT8BYTE",       0x0014);
 
45
define("TNEF_MAPI_STRING",         0x001e);
 
46
define("TNEF_MAPI_UNICODE_STRING", 0x001f);
 
47
define("TNEF_MAPI_SYSTIME",        0x0040);
 
48
define("TNEF_MAPI_CLSID",          0x0048);
 
49
define("TNEF_MAPI_BINARY",         0x0102);
 
50
 
 
51
define("TNEF_MAPI_ATTACH_MIME_TAG",      0x370E);
 
52
define("TNEF_MAPI_ATTACH_LONG_FILENAME", 0x3707);
 
53
define("TNEF_MAPI_ATTACH_DATA",          0x3701);
 
54
 
 
55
function tnef_getx($size, &$buf)
 
56
{
 
57
   $value = null;
 
58
   if (strlen($buf) >= $size)
 
59
   {
 
60
      $value = substr($buf, 0, $size);
 
61
      $buf = substr_replace($buf, '', 0, $size);
 
62
   }
 
63
   return $value;
 
64
}
 
65
 
 
66
function tnef_geti8(&$buf)
 
67
{
 
68
   $value = null;
 
69
   if (strlen($buf) >= 1)
 
70
   {
 
71
      $value = ord($buf{0});
 
72
      $buf = substr_replace($buf, '', 0, 1);
 
73
   }
 
74
   return $value;
 
75
}
 
76
 
 
77
function tnef_geti16(&$buf)
 
78
{
 
79
   $value = null;
 
80
   if (strlen($buf) >= 2)
 
81
   {
 
82
      $value = ord($buf{0}) +
 
83
               (ord($buf{1}) << 8);
 
84
      $buf = substr_replace($buf, '', 0, 2);
 
85
   }
 
86
   return $value;
 
87
}
 
88
 
 
89
function tnef_geti32(&$buf)
 
90
{
 
91
   $value = null;
 
92
   if (strlen($buf) >= 4)
 
93
   {
 
94
      $value = ord($buf{0}) +
 
95
               (ord($buf{1}) << 8) +
 
96
               (ord($buf{2}) << 16) +
 
97
               (ord($buf{3}) << 24);
 
98
      $buf = substr_replace($buf, '', 0, 4);
 
99
   }
 
100
   return $value;
 
101
}
 
102
 
 
103
function tnef_decode_attribute($attribute, &$buf)
 
104
{
 
105
   global $debug, $download;
 
106
 
 
107
   $length = tnef_geti32($buf);
 
108
   $value = tnef_getx($length, $buf); //data
 
109
   tnef_geti16($buf); //checksum
 
110
 
 
111
   if ($debug)
 
112
   {
 
113
      printf("ATTRIBUTE[%08x] %d bytes\n", $attribute, $length);
 
114
   }
 
115
 
 
116
   switch($attribute)
 
117
   {
 
118
      case TNEF_BODYTEXT:
 
119
         if (!$download)
 
120
         {
 
121
            printf("<b>Embedded message:</b><pre>%s</pre>",$value);
 
122
         }
 
123
         break;
 
124
 
 
125
      default:
 
126
   }
 
127
}
 
128
 
 
129
function extract_mapi_attrs($buf, &$attachment_data)
 
130
{
 
131
   global $debug;
 
132
 
 
133
   tnef_geti32($buf); // number of attributes
 
134
   while(strlen($buf) > 0)
 
135
   {
 
136
      $value = null;
 
137
      $length = 0;
 
138
      $attr_type = tnef_geti16($buf);
 
139
      $attr_name = tnef_geti16($buf);
 
140
      if ($debug)
 
141
      {
 
142
         printf("mapi attribute: %04x:%04x\n", $attr_type, $attr_name);
 
143
      }
 
144
      switch($attr_type)
 
145
      {
 
146
         case TNEF_MAPI_SHORT:
 
147
            $value = tnef_geti16($buf);
 
148
            break;
 
149
 
 
150
         case TNEF_MAPI_INT:
 
151
         case TNEF_MAPI_BOOLEAN:
 
152
            $value = tnef_geti32($buf);
 
153
            break;
 
154
 
 
155
         case TNEF_MAPI_FLOAT:
 
156
            $value = tnef_getx(4, $buf);
 
157
            break;
 
158
 
 
159
         case TNEF_MAPI_DOUBLE:
 
160
         case TNEF_MAPI_SYSTIME:
 
161
            $value = tnef_getx(8, $buf);
 
162
            break;
 
163
 
 
164
         case TNEF_MAPI_STRING:
 
165
         case TNEF_MAPI_UNICODE_STRING:
 
166
         case TNEF_MAPI_BINARY:
 
167
         case TNEF_MAPI_OBJECT:
 
168
            $num_vals = tnef_geti32($buf);
 
169
            for ($i = 0; $i < $num_vals; $i++) // usually just 1
 
170
            {
 
171
               $length = tnef_geti32($buf);
 
172
               $buflen = $length + ((4 - ($length % 4)) % 4); // pad to next 4 byte boundary
 
173
               $value = substr(tnef_getx($buflen, $buf), 0, $length); // read and truncate to length
 
174
            }
 
175
            break;
 
176
 
 
177
         default:
 
178
            if ($debug)
 
179
            {
 
180
               echo("Unknown mapi attribute!\n");
 
181
            }
 
182
      }
 
183
 
 
184
      // store any interesting attributes
 
185
      switch($attr_name)
 
186
      {
 
187
         case TNEF_MAPI_ATTACH_LONG_FILENAME: // used in preference to AFILENAME value
 
188
            $attachment_data[0]['name'] = ereg_replace('.*[\/](.*)$', '\1', $value); // strip path
 
189
            break;
 
190
 
 
191
         case TNEF_MAPI_ATTACH_MIME_TAG: // Is this ever set, and what is format?
 
192
            $attachment_data[0]['type0'] = ereg_replace('^(.*)/.*', '\1', $value);
 
193
            $attachment_data[0]['type1'] = ereg_replace('.*/(.*)$', '\1', $value);
 
194
            break;
 
195
 
 
196
         case TNEF_MAPI_ATTACH_DATA:
 
197
            tnef_getx(16, $value); // skip the next 16 bytes (unknown data)
 
198
            array_shift($attachment_data); // eliminate the current (bogus) attachment
 
199
            do_tnef_decode($value, $attachment_data); // recursively process the attached message
 
200
            break;
 
201
 
 
202
         default:
 
203
      }
 
204
   }
 
205
}
 
206
 
 
207
function tnef_decode_message(&$buf)
 
208
{
 
209
   global $debug;
 
210
 
 
211
   if ($debug)
 
212
   {
 
213
      echo("MESSAGE ");
 
214
   }
 
215
 
 
216
   $attribute = tnef_geti32($buf);
 
217
   tnef_decode_attribute($attribute, $buf);
 
218
}
 
219
 
 
220
function tnef_decode_attachment(&$buf, &$attachment_data)
 
221
{
 
222
   global $debug;
 
223
 
 
224
   if ($debug)
 
225
   {
 
226
      echo("ATTACHMENT ");
 
227
   }
 
228
 
 
229
   $attribute = tnef_geti32($buf);
 
230
   switch($attribute)
 
231
   {    
 
232
      case TNEF_ARENDDATA: // marks start of new attachment
 
233
         $length = tnef_geti32($buf);
 
234
         tnef_getx($length, $buf);
 
235
         tnef_geti16($buf); //checksum
 
236
         if ($debug)
 
237
         {
 
238
            printf("ARENDDATA[%08x]: %d bytes\n", $attribute, $length);
 
239
         }
 
240
         // add a new default data block to hold details of this attachment
 
241
         // reverse order is easier to handle later!
 
242
         array_unshift($attachment_data, array('type0'  => 'application',
 
243
                                               'type1'  => 'octet-stream',
 
244
                                               'name'   => 'unknown',
 
245
                                               'stream' => ''));
 
246
         break;
 
247
 
 
248
      case TNEF_AFILENAME: // filename
 
249
         $length = tnef_geti32($buf);
 
250
         $attachment_data[0]['name'] = ereg_replace('.*[\/](.*)$',
 
251
                                                    '\1',
 
252
                                                    tnef_getx($length, $buf)); // strip path
 
253
         tnef_geti16($buf); //checksum
 
254
         if ($debug)
 
255
         {
 
256
            printf("AFILENAME[%08x]: %s\n", $attribute, $attachment_data[0]['name']);
 
257
         }
 
258
         break;
 
259
 
 
260
      case TNEF_ATTACHDATA: // the attachment itself
 
261
         $length = tnef_geti32($buf);
 
262
         $attachment_data[0]['size'] = $length;
 
263
         $attachment_data[0]['stream'] = tnef_getx($length, $buf);
 
264
         tnef_geti16($buf); //checksum
 
265
         if ($debug)
 
266
         {
 
267
            printf("ATTACHDATA[%08x]: %d bytes\n", $attribute, $length);
 
268
         }
 
269
         break;
 
270
 
 
271
      case TNEF_AMAPIATTRS:
 
272
         $length = tnef_geti32($buf);
 
273
         $value = tnef_getx($length, $buf);
 
274
         tnef_geti16($buf); //checksum
 
275
         if ($debug)
 
276
         {
 
277
            printf("AMAPIATTRS[%08x]: %d bytes\n", $attribute, $length);
 
278
         }
 
279
         extract_mapi_attrs($value, $attachment_data);
 
280
         break;
 
281
 
 
282
      default:
 
283
         tnef_decode_attribute($attribute, $buf);
 
284
   }
 
285
}
 
286
 
 
287
function do_tnef_decode(&$buf, &$attachment_data)
 
288
{
 
289
   global $debug;
 
290
 
 
291
   $tnef_signature = tnef_geti32($buf);
 
292
   if ($tnef_signature == TNEF_SIGNATURE)
 
293
   {
 
294
      $tnef_key = tnef_geti16($buf);
 
295
      if ($debug)
 
296
      {
 
297
         printf("Signature: 0x%08x\nKey: 0x%04x\n", $tnef_signature, $tnef_key);
 
298
      }
 
299
 
 
300
      while (strlen($buf) > 0)
 
301
      {
 
302
         $lvl_type = tnef_geti8($buf);
 
303
         switch($lvl_type)
 
304
         {
 
305
            case TNEF_LVL_MESSAGE:
 
306
               tnef_decode_message($buf);
 
307
               break;
 
308
 
 
309
            case TNEF_LVL_ATTACHMENT:
 
310
               tnef_decode_attachment($buf, $attachment_data);
 
311
               break;
 
312
 
 
313
            default:
 
314
               if ($debug)
 
315
               {
 
316
                  echo("Invalid file format!");
 
317
               }
 
318
               break 2;
 
319
         }
 
320
      }
 
321
   }
 
322
   else
 
323
   {
 
324
      if ($debug)
 
325
      {
 
326
         echo("Invalid file format!");
 
327
      }
 
328
   }
 
329
}
 
330
 
 
331
function tnef_decode($buf)
 
332
{
 
333
   global $debug;
 
334
 
 
335
   $attachment_data = array();
 
336
 
 
337
   if ($debug)
 
338
   {
 
339
      echo("<pre>");
 
340
   }
 
341
 
 
342
   do_tnef_decode($buf, $attachment_data);
 
343
 
 
344
   if ($debug)
 
345
   {
 
346
      echo("</pre>");
 
347
   }
 
348
   return array_reverse($attachment_data);
 
349
 
 
350
}
 
351
 
 
352
?>
 
 
b'\\ No newline at end of file'