source: trunk/src/sh_filetype.c @ 539

Last change on this file since 539 was 539, checked in by katerina, 3 years ago

Fixes for tickets #431 (OpenBSD compatibility) and #432 (compiler warnings).

File size: 18.0 KB
Line 
1/* SAMHAIN file system integrity testing                                   */
2/* Copyright (C) 2011 Rainer Wichmann                                      */
3/*                                                                         */
4/*  This program is free software; you can redistribute it                 */
5/*  and/or modify                                                          */
6/*  it under the terms of the GNU General Public License as                */
7/*  published by                                                           */
8/*  the Free Software Foundation; either version 2 of the License, or      */
9/*  (at your option) any later version.                                    */
10/*                                                                         */
11/*  This program is distributed in the hope that it will be useful,        */
12/*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
13/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
14/*  GNU General Public License for more details.                           */
15/*                                                                         */
16/*  You should have received a copy of the GNU General Public License      */
17/*  along with this program; if not, write to the Free Software            */
18/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
19
20#include "config_xor.h"
21
22#ifndef NULL
23#if !defined(__cplusplus)
24#define NULL ((void*)0)
25#else
26#define NULL (0)
27#endif
28#endif
29
30#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
31
32#include "samhain.h"
33#include "sh_mem.h"
34#include "sh_error_min.h"
35#include "sh_utils.h"
36
37#define FIL__ _("sh_filetype.c")
38
39#include <string.h>
40#include <stdlib.h>
41#include <ctype.h>
42
43/* #define SH_FILE_MAIN 1 */
44#ifdef  SH_FILE_MAIN
45#include <stdio.h>
46#define _(a) a
47#define N_(a) a
48#define sl_strlcpy strncpy
49#endif
50
51#define SH_FTYPE_MAX 32
52
53/* List of filetype description, in the format:
54 * offset : type(0=text, 1=binary) : length(if binary) : G1 : G2 : G3 : Name : Teststring
55 *
56 * This list is mostly taken from the 'filetype' library by Paul L Daniels.
57 *
58 * Copyright (c) 2003, PLD
59 * All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or
62 * without modification, are permitted provided that the
63 * following conditions are met:
64 *
65 *  * Redistributions of source code must retain the above
66 *  copyright notice, this list of conditions and the following
67 *  disclaimer.
68 * 
69 *  * Redistributions in binary form must reproduce the above
70 *  copyright notice, this list of conditions and the following
71 *  disclaimer in the documentation and/or other materials provided
72 *  with the distribution.
73 * 
74 *  * Neither the name of the PLD nor the names of its contributors
75 *  may be used to endorse or promote products derived from this software
76 *  without specific prior written permission.
77 * 
78 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
79 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
80 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
81 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
82 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
83 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
84 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
85 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
86 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
87 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
88 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
89 *  POSSIBILITY OF SUCH DAMAGE.
90 */
91
92
93char * sh_ftype_list[] = {
94
95  N_("6:0:0:IMAGE:COMPRESSED:JPG:JFIF Jpeg:JFIF"),
96  N_("0:0:0:IMAGE:COMPRESSED:PNG:PNG:=89PNG=0d=0a=1a=0a"),
97  N_("0:0:0:IMAGE:COMPRESSED:JPG:JFIF Jpeg:=FF=D8=FF"),
98  N_("0:0:0:IMAGE:COMPRESSED:GIF:GIF:GIF97a"),
99  N_("0:0:0:IMAGE:COMPRESSED:GIF:GIF:GIF89a"),
100  N_("0:0:0:IMAGE:COMPRESSED:GIF:GIF:GIF87a"),
101  N_("0:1:4:IMAGE:COMPRESSED:TIFF:TIFF-LE:II=2A=00"),
102  N_("0:1:4:IMAGE:COMPRESSED:TIFF:TIFF-BE:MM=00=2A"),
103  N_("0:1:2:IMAGE:COMPRESSED:PCX:PCX25:=0A=00"),
104  N_("0:1:2:IMAGE:COMPRESSED:PCX:PCX28WP:=0A=02"),
105  N_("0:1:2:IMAGE:COMPRESSED:PCX:PCX28NP:=0A=03"),
106  N_("0:1:2:IMAGE:COMPRESSED:PCX:PCX30:=0A=05"),
107  N_("0:0:0:IMAGE:RAW:BMP:Bitmap:BM"),
108  N_("0:0:0:IMAGE:RAW:XPM:XPM:/* XPM */"),
109  N_("0:0:0:IMAGE:SPECIAL:AUTOCAD:DWT:AC=31=30=31"),
110  N_("0:0:0:IMAGE:SPECIAL:AUTOCAD:DWF:(DWF V"),
111  N_("0:0:0:IMAGE:SPECIAL:AUTOCAD:WMF:=D7=CD=C6=9A"),
112  N_("0:0:0:IMAGE:SPECIAL:AUTOCAD:DWG:AC10"),
113  N_("8:0:0:IMAGE:SPECIAL:COREL:CorelDraw:CDR"),
114  N_("0:0:0:IMAGE:SPECIAL:FITS:Fits file:SIMPLE=20=20="),
115  N_("1536:0:0:IMAGE:SPECIAL:VISIO:VisioDraw:Visio"),
116  N_("128:0:0:IMAGE:SPECIAL:DICM:DICOM medical:DICM"),
117  N_("0:0:0:IMAGE:SPECIAL:PHS:Photoshop:8BPS"),
118  N_("0:0:0:IMAGE:SPECIAL:XCF:Gimp XCF:gimp xcf"),
119  N_("0:0:0:MOVIE:COMPRESSED:RIFF:RIFF/AVI Movie:RIFF"),
120  N_("0:0:0:MOVIE:RAW:MOV:SGI Movie:MOVI:.mov SGI Movie"),
121  N_("0:1:4:MOVIE:COMPRESSED:MPG:Mpeg 2:=00=00=01=BA"),
122  N_("0:1:4:MOVIE:COMPRESSED:MPG:Mpeg 2:=00=00=01=B3"),
123  N_("4:0:0:MOVIE:COMPRESSED:QT:QuickTime:moov"),
124  N_("4:0:0:MOVIE:COMPRESSED:QT:QuickTime:mdat"),
125  N_("36:0:0:MOVIE:COMPRESSED:QT:QuickTime:moov"),
126  N_("36:0:0:MOVIE:COMPRESSED:QT:QuickTime:mdat"),
127  N_("68:0:0:MOVIE:COMPRESSED:QT:QuickTime:moov"),
128  N_("68:0:0:MOVIE:COMPRESSED:QT:QuickTime:mdat"),
129  N_("0:1:3:MOVIE:COMPRESSED:FLI:FLIC animation:=00=11=AF"),
130  N_("0:0:0:MOVIE:COMPRESSED:FLASH:Flash data:FWS"),
131  N_("0:0:0:MOVIE:COMPRESSED:FLASH:Flash data:CWS"),
132  N_("0:0:0:MOVIE:COMPRESSED:FLASH:Flash video:FLV"),
133  N_("0:0:0:MOVIE:COMPRESSED:WMV:WMV:=30=26=B2=75=8E=66=CF"),
134  N_("0:0:0:AUDIO:RAW:SND:Sun Audio:.snd"),
135  N_("0:0:0:AUDIO:RAW:EMOD:EMOD:Mod"),
136  N_("1080:0:0:AUDIO:RAW:MOD:SoundTracker (.M.K):.M.K"),
137  N_("1080:0:0:AUDIO:RAW:MOD:SoundTracker (M.K.):M.K."),
138  N_("1080:0:0:AUDIO:RAW:MOD:NoiseTracker:N.T."),
139  N_("1080:0:0:AUDIO:RAW:MOD:SoundTracker (M!K!):M!K!"),
140  N_("1080:0:0:AUDIO:RAW:MOD:SoundTracker (M&K!):M&K!"),
141  N_("8:0:0:AUDIO:RAW:WAVE:Wave:WAVE"),
142  N_("0:1:4:AUDIO:RAW:DEC:DEC-Audio:=00=64=73=2E"),
143  N_("0:0:0:AUDIO:STANDARD:MIDI:Midi:MThd"),
144  N_("0:0:0:AUDIO:COMPRESSED:REAL:RealMedia:.RMF"),
145  N_("0:0:0:AUDIO:COMPRESSED:OGG:Ogg Vorbis:OggS"),
146  N_("0:0:0:AUDIO:COMPRESSED:FLAC:Flac:fLaC"),
147  N_("0:1:5:AUDIO:COMPRESSED:MP3:MP3 Audio:=49=44=33=02=00"),
148  N_("0:1:5:AUDIO:COMPRESSED:MP3:MP3 Audio:=49=44=33=03=00"),
149  N_("0:1:5:AUDIO:COMPRESSED:MP3:MP3 Audio:=49=44=33=04=00"),
150  N_("0:1:2:AUDIO:COMPRESSED:MP3:MP3 Audio:=ff=fb"),
151  N_("0:1:2:AUDIO:COMPRESSED:MP3:MP3 Audio:=ff=fa"),
152  N_("2:0:0:ARCHIVE:COMPRESSED:LHA:Lha 0:-lh0-"),
153  N_("2:0:0:ARCHIVE:COMPRESSED:LHA:Lha 1:-lh1-"),
154  N_("2:0:0:ARCHIVE:COMPRESSED:LHA:Lha 4:-lz4-"),
155  N_("2:0:0:ARCHIVE:COMPRESSED:LHA:Lha z5:-lz5-"),
156  N_("2:0:0:ARCHIVE:COMPRESSED:LHA:Lha 5:-lh5-"),
157  N_("0:0:0:ARCHIVE:COMPRESSED:RAR:RarArchive:Rar!"),
158  N_("0:0:0:ARCHIVE:COMPRESSED:ZIP:PkZip:PK=03=04"),
159  N_("0:0:0:ARCHIVE:COMPRESSED:7Z:7-Zip:=37=7A=BC=AF=27=1C"),
160  N_("0:0:0:ARCHIVE:COMPRESSED:COMPRESS:Compress:=1F=89"),
161  N_("0:0:0:ARCHIVE:COMPRESSED:GZIP:Gzip:=1F=8B"),
162  N_("0:0:0:ARCHIVE:COMPRESSED:BZIP2:Bzip2:BZh"),
163  N_("0:0:0:ARCHIVE:COMPRESSED:ARJ:ARJ:=60=ea"),
164  N_("0:0:0:ARCHIVE:COMPRESSED:ARJ:ARJ:=ea=60"),
165  N_("0:0:0:ARCHIVE:COMPRESSED:HPAK:HPack:HPAK"),
166  N_("0:0:0:ARCHIVE:COMPRESSED:JAM:Jam:=E9,=01JAM"),
167  N_("0:0:0:ARCHIVE:COMPRESSED:SQUISH:Squish:SQSH"),
168  N_("0:1:8:ARCHIVE:COMPRESSED:CAB:MS Cabinet:MSCF=00=00=00=00"),
169  N_("20:0:0:ARCHIVE:COMPRESSED:ZOO:Zoo:=FD=C4=A7=DC"),
170  N_("0:0:0:ARCHIVE:COMPRESSED:XPK:Amiga XPK Archive:XPKF"),
171  N_("0:0:0:ARCHIVE:PACKAGE:RPM:RPM:=ED=AB=EE=DB"),
172  N_("0:0:0:ARCHIVE:PACKAGE:DEB:DEB:!<arch>=0A""debian"),
173  N_("0:0:0:ARCHIVE:UNIX:AR:AR:!<arch>"),
174  N_("0:0:0:ARCHIVE:UNIX:AR:AR:<ar>"),
175  N_("257:1:8:ARCHIVE:UNIX:TAR:TAR:ustar=20=20=00"),
176  N_("257:1:6:ARCHIVE:UNIX:TAR:TAR:ustar=00"),
177  N_("0:0:0:LIBRARY:JAVA:CLASS:Java:=CA=FE=BA=BE"),
178  N_("2108:0:0:DOCUMENT:OFFICE:WORD:Word v5:MSWordDoc"),
179  N_("2112:0:0:DOCUMENT:OFFICE:WORD:Word v5:MSWordDoc"),
180  N_("2080:0:0:DOCUMENT:OFFICE:EXCEL:Excel v4:Microsoft Excel"),
181  N_("2080:0:0:DOCUMENT:OFFICE:WORD:MS Word:Microsoft Word"),
182  N_("0:0:0:DOCUMENT:OFFICE:WORD:Word:=94=A6=2E"),
183  N_("512:1:19:DOCUMENT:OFFICE:WORD:Word:R=00o=00o=00t=00 =00""E=00n=00t=00r=00y"),
184  N_("0:1:9:DOCUMENT:OFFICE:ALL:MSOffice:=D0=CF=11=E0=A1=B1=1A=E1=00"),
185  N_("0:0:0:DOCUMENT:ADOBE:PDF:PortableDocument:%PDF-"),
186  N_("0:0:0:DOCUMENT:ADOBE:EPS:EncapsulatedPS:%!PS-ADOBE EPS"),
187  N_("0:0:0:DOCUMENT:STANDARD:RTF:RichText:{\\rtf"),
188  N_("6:1:4:DOCUMENT:STANDARD:RTF:RichText Compressed:=00=00LZ"),
189  N_("6:0:0:DOCUMENT:ID:VCARD:VCARD:vcard"),
190  N_("0:0:0:EXECUTABLE:DOS:EXE:DosExe:MZ"),
191  N_("0:0:0:EXECUTABLE:DOS:EXE:DosExe:LZ"),
192  N_("0:0:0:EXECUTABLE:DOS:COM:DosCom 1:=E9"),
193  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Bourne:#!/bin/sh"),
194  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Bourne:#! /bin/sh"),
195  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Bourne:#!/bin/bash"),
196  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Bourne:#! /bin/bash"),
197  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Bourne:#!/usr/bin/bash"),
198  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Bourne:#! /usr/bin/bash"),
199  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Csh:#!/usr/bin/csh"),
200  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Csh:#! /usr/bin/csh"),
201  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Csh:#!/bin/csh"),
202  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Csh:#! /bin/csh"),
203  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Korn:#! /usr/bin/ksh"),
204  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Korn:#!/usr/bin/ksh"),
205  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Korn:#! /bin/ksh"),
206  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Korn:#!/bin/ksh"),
207  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Tenex:#!/usr/bin/tcsh"),
208  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Tenex:#! /usr/bin/tcsh"),
209  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Tenex:#!/bin/tcsh"),
210  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Tenex:#! /bin/tcsh"),
211  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Zsh:#!/usr/bin/zsh"),
212  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Zsh:#! /usr/bin/zsh"),
213  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Zsh:#!/bin/zsh"),
214  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Zsh:#! /bin/zsh"),
215  N_("0:0:0:EXECUTABLE:UNIX:SHELL:ash:#!/usr/bin/ash"),
216  N_("0:0:0:EXECUTABLE:UNIX:SHELL:ash:#! /usr/bin/ash"),
217  N_("0:0:0:EXECUTABLE:UNIX:SHELL:ash:#!/bin/ash"),
218  N_("0:0:0:EXECUTABLE:UNIX:SHELL:ash:#! /bin/ash"),
219  N_("0:0:0:EXECUTABLE:UNIX:SHELL:awk:#!/usr/bin/nawk"),
220  N_("0:0:0:EXECUTABLE:UNIX:SHELL:awk:#! /usr/bin/nawk"),
221  N_("0:0:0:EXECUTABLE:UNIX:SHELL:awk:#!/bin/nawk"),
222  N_("0:0:0:EXECUTABLE:UNIX:SHELL:awk:#! /bin/nawk"),
223  N_("0:0:0:EXECUTABLE:UNIX:SHELL:awk:#!/bin/gawk"),
224  N_("0:0:0:EXECUTABLE:UNIX:SHELL:awk:#! /bin/gawk"),
225  N_("0:0:0:EXECUTABLE:UNIX:SHELL:awk:#!/bin/awk"),
226  N_("0:0:0:EXECUTABLE:UNIX:SHELL:awk:#! /bin/awk"),
227  N_("0:0:0:EXECUTABLE:UNIX:SHELL:perl:#!/usr/bin/perl"),
228  N_("0:0:0:EXECUTABLE:UNIX:SHELL:perl:#! /usr/bin/perl"),
229  N_("0:0:0:EXECUTABLE:UNIX:SHELL:perl:#!/bin/perl"),
230  N_("0:0:0:EXECUTABLE:UNIX:SHELL:perl:#! /bin/perl"),
231  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Shell script:#!/"),
232  N_("0:0:0:EXECUTABLE:UNIX:SHELL:Shell script:#! /"),
233  N_("0:0:0:EXECUTABLE:UNIX:ELF:Linux ELF32:=7f""ELF=01"),
234  N_("0:0:0:EXECUTABLE:UNIX:ELF:Linux ELF:=7f""ELF=02"),
235  N_("0:0:0:EXECUTABLE:DOS:COM:DosCom 2:=8c"),
236  N_("0:0:0:EXECUTABLE:DOS:COM:DosCom 3:=eb"),
237  N_("0:0:0:EXECUTABLE:DOS:COM:DosCom 4:=b8"),
238  N_("0:1:4:EXECUTABLE:AMIGAOS:EXECUTABLE:AmigaOS Executable:=00=00=03=F3"),
239  N_("0:1:20:DATABASE:ANY:ACCESS:MSAccess:=00=01=00=00Standard=20Jet=20""DB=00"),
240  N_("0:1:2:DATABASE:ANY:MYSQL:MySQL database:=fe=01"),
241  N_("0:1:4:DATABASE:ANY:MYSQL:MySQL database:=fe=fe=03=00"),
242  N_("0:1:4:DATABASE:ANY:MYSQL:MySQL database:=fe=fe=07=00"),
243  N_("0:1:4:DATABASE:ANY:MYSQL:MySQL database:=fe=fe=05=00"),
244  N_("0:1:4:DATABASE:ANY:MYSQL:MySQL database:=fe=fe=06=00"),
245 
246  NULL, 
247  NULL, 
248  NULL, 
249  NULL, 
250
251  NULL, 
252  NULL, 
253  NULL, 
254  NULL, 
255
256  NULL, 
257  NULL, 
258  NULL, 
259  NULL, 
260
261  NULL, 
262  NULL, 
263  NULL, 
264  NULL, 
265
266  NULL,
267};
268
269static unsigned int    sh_ftype_def = 0;
270
271#define SH_FTYPE_ADD  16
272
273struct sh_ftype_rec {
274  size_t offset;
275  size_t length;
276  char   pattern[SH_FTYPE_MAX];
277
278  char   type[SH_FTYPE_MAX];
279};
280
281
282struct sh_ftype_rec ** sh_ftype_arr = NULL;
283static unsigned int    sh_ftype_nn  = 0;
284
285#if !defined(SH_FILE_MAIN)
286
287static unsigned int    sh_ftype_usr = 0;
288
289extern char * unquote_string (const char * str, size_t len);
290
291int sh_restrict_add_ftype(const char * str)
292{
293  size_t len;
294  char * cond;
295
296  if (sh_ftype_def == 0)
297    {
298      while(sh_ftype_list[sh_ftype_def] != NULL) ++sh_ftype_def;
299    }
300
301  if (!str) 
302    {
303      if (sh_ftype_usr > 0)
304        {
305          unsigned int i, j = sh_ftype_def;
306         
307          for (i = 0; i < sh_ftype_usr; ++i)
308            {
309              SH_FREE(sh_ftype_list[j+i]);
310              sh_ftype_list[j+i] = NULL;
311            }   
312          sh_ftype_usr = 0;
313        }
314
315      if (sh_ftype_arr)
316        {
317          unsigned int i = 0;
318         
319          while(sh_ftype_arr[i] != NULL)
320            {
321              SH_FREE(sh_ftype_arr[i]);
322              ++i;
323            }
324          SH_FREE(sh_ftype_arr);
325          sh_ftype_arr = NULL;
326        }
327    }
328  else if (sh_ftype_usr < SH_FTYPE_ADD)
329    {
330      len = strlen(str);
331      cond = unquote_string(str, len);
332      sh_ftype_list[sh_ftype_def+sh_ftype_usr] = cond;
333      ++sh_ftype_usr;
334    }
335  else
336    {
337      return -1;
338    }
339  return 0;
340}
341
342
343#endif
344
345
346static int init_record(unsigned int n, char * define,
347                       struct sh_ftype_rec * record)
348{
349  unsigned int offset, dtype, length, i = 0, xn = 0;
350  char type[SH_FTYPE_MAX];
351  char pattern[SH_FTYPE_MAX];
352
353  char * end;
354  char * start;
355 
356  offset = strtoul(define, &end, 0);
357  if (*end != ':')
358    return -1;
359
360  start = end; ++start;
361  dtype  = strtoul(start,  &end, 0);
362  if (*end != ':')
363    return -1;
364
365  start = end; ++start;
366  length = strtoul(start,  &end, 0);
367  if (*end != ':')
368    return -1;
369 
370  start = end; ++start;
371
372  while (*start && (i < sizeof(type)))
373    {
374      type[i] = *start; ++start;
375      if (type[i] == ':') 
376        ++xn;
377      if (xn == 3)
378        {
379          type[i] = '\0';
380          break;
381        }
382      ++i;
383    }
384  if (xn != 3)
385    return -1;
386
387  start = strchr(start, ':');
388
389  if (!start)
390    return -1;
391
392  ++start;
393
394  if (dtype == 0)
395    {
396      sl_strlcpy(pattern, start, sizeof(pattern));
397      length = strlen(pattern);
398    }
399  else if (length <= sizeof(pattern))
400    {
401      memcpy(pattern, start, length);
402    }
403  else
404    {
405      return -1;
406    }
407
408  for (i = 0; i < n; ++i)
409    {
410      if (sh_ftype_arr[i]->length <= length &&
411          sh_ftype_arr[i]->offset == offset)
412        {
413          if (0 == memcmp(sh_ftype_arr[i]->pattern, pattern, 
414                          sh_ftype_arr[i]->length))
415            {
416#ifdef  SH_FILE_MAIN
417              fprintf(stderr, 
418                      "Pattern %d (%s / %s) override by earlier pattern %d (%s / %s)\n",
419                      n, type, pattern,
420                      i, sh_ftype_arr[i]->type, sh_ftype_arr[i]->pattern);
421#else
422              char errbuf[256];
423             
424              sl_snprintf(errbuf, sizeof(errbuf),
425                          _("Pattern %d (%s) override by earlier pattern %d (%s)"),
426                          n, type,
427                          i, sh_ftype_arr[i]->type);
428              sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
429                              errbuf,
430                              _("init_record"));
431#endif
432            }
433        }
434    }
435
436
437  record->offset = offset;
438  record->length = length;
439  memcpy(record->pattern, pattern, length);
440  sl_strlcpy(record->type, type, SH_FTYPE_MAX);
441
442  return 0;
443}
444
445static void file_arr_init()
446{
447  unsigned int i, nn = 0;
448
449  if (sh_ftype_def == 0)
450    {
451      while(sh_ftype_list[sh_ftype_def] != NULL) ++sh_ftype_def;
452    }
453
454  while (sh_ftype_list[nn] != NULL) ++nn;
455
456#ifdef  SH_FILE_MAIN
457  printf("%d definitions found, defined = %d\n", nn, sh_ftype_def);
458#endif
459
460#ifdef  SH_FILE_MAIN
461  sh_ftype_arr = calloc((nn+1), sizeof(struct sh_ftype_rec *));
462#else
463  sh_ftype_arr = SH_ALLOC((nn+1) * sizeof(struct sh_ftype_rec *));
464#endif
465
466  for(i = 0; i < nn; i++)
467    {
468#ifdef  SH_FILE_MAIN
469      sh_ftype_arr[i] = calloc(1, sizeof(struct sh_ftype_rec));
470#else
471      sh_ftype_arr[i] = SH_ALLOC(sizeof(struct sh_ftype_rec));
472#endif
473
474      memset(sh_ftype_arr[i], 0, sizeof(struct sh_ftype_rec));
475      if (i < sh_ftype_def) 
476        {
477          char   * p  = _(sh_ftype_list[i]);
478          size_t len  = strlen(p);
479          char * cond = unquote_string(p, len); 
480         
481          init_record(i,             cond, sh_ftype_arr[i]);
482        }
483      else 
484        {
485          init_record(i, sh_ftype_list[i], sh_ftype_arr[i]);
486        }
487    }
488  sh_ftype_arr[nn] = NULL;
489  sh_ftype_nn      = nn;
490
491  return;
492}
493
494static char * check_filetype(char * filetype, 
495                             const char * buffer, size_t buflen)
496{
497  unsigned int i;
498  const char * p;
499
500  if (!sh_ftype_arr)
501    {
502      file_arr_init();
503    }
504 
505  for (i = 0; i < sh_ftype_nn; ++i)
506    {
507      if (sh_ftype_arr[i]->length > 0 && 
508          (sh_ftype_arr[i]->length + sh_ftype_arr[i]->offset) < buflen)
509        {
510          p = &buffer[sh_ftype_arr[i]->offset];
511
512          if (0 == memcmp(p, sh_ftype_arr[i]->pattern, sh_ftype_arr[i]->length))
513            {
514              sl_strlcpy(filetype, sh_ftype_arr[i]->type, SH_FTYPE_MAX);
515              return (filetype);
516            }
517        }
518    }
519
520  if (buflen > 0) {
521
522    int flag = 0;
523
524    p = buffer;
525    for (i = 0; i < buflen; ++i) {
526      if (*p == '\0')
527        {
528          sl_strlcpy(filetype, _("FILE:BINARY:UNKNOWN"), SH_FTYPE_MAX);
529          goto out;
530        }
531      else if (!isgraph((int)*p) && !isspace((int)*p))
532        {
533          flag = 1;
534        }
535      ++p;
536    }
537    if (flag == 0)
538      {
539        sl_strlcpy(filetype, _("FILE:TEXT:ASCII"), SH_FTYPE_MAX);
540        goto out;
541      }
542  }
543  sl_strlcpy(filetype, _("FILE:UNKNOWN:UNKNOWN"), SH_FTYPE_MAX);
544 out:
545  return filetype;
546}
547
548#if !defined(SH_FILE_MAIN)
549
550int matches_filetype(SL_TICKET ft, char * test_type)
551{
552  char buffer[3072];
553  char filetype[SH_FTYPE_MAX];
554  long len;
555
556  len = sl_read_timeout (ft, buffer, sizeof(buffer), 12, S_TRUE);
557
558  sl_rewind(ft);
559
560  if (len > 0)
561    {
562      check_filetype(filetype, buffer, len);
563    }
564  else
565    {
566      sl_strlcpy(filetype, _("FILE:UNKNOWN:UNKNOWN"), SH_FTYPE_MAX);
567    }
568
569  if (0 == strcmp(filetype, test_type))
570    {
571      return 1;
572    }
573
574  return 0;
575}
576
577#else
578/* SH_FILE_MAIN */
579#include <unistd.h>
580
581int main (int argc, char * argv[])
582{
583  char buffer[3072];
584  char filetype[SH_FTYPE_MAX];
585  size_t len;
586
587  FILE * fh = fopen(argv[1], "r");
588
589  if (fh)
590    {
591      int fd = fileno(fh);
592
593      len = read(fd, buffer, 3072);
594
595      check_filetype(filetype, buffer, len);
596
597      fprintf(stdout, "%s: %s\n", argv[1], filetype);
598
599      fclose(fh);
600     
601      return 0;
602    }
603  return 1;
604}
605#endif
606
607#endif
608/* #if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE) */
Note: See TracBrowser for help on using the repository browser.