da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * library interface to file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the sum of the hacks {s5,v10,planix} is _____ than the parts
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const char id[] = "\n@(#)$Id: magic library (AT&T Research) 2008-09-10 $\0\n";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char lib[] = "libast:magic";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ctype.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ccode.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <dt.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <modex.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <regex.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <swap.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define T(m) (*m?ERROR_translate(NiL,NiL,lib,m):m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define match(s,p) strgrpmatch(s,p,NiL,0,STR_LEFT|STR_RIGHT|STR_ICASE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAXNEST 10 /* { ... } nesting limit */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MINITEM 4 /* magic buffer rounding */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct /* identifier dictionary entry */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char name[16]; /* identifier name */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int value; /* identifier value */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dtlink_t link; /* dictionary link */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Info_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Edit /* edit substitution */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Edit* next; /* next in list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regex_t* from; /* from pattern */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Edit_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct Entry;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct /* loop info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Entry* lab; /* call this function */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int start; /* start here */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int size; /* increment by this amount */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int count; /* dynamic loop count */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset; /* dynamic offset */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Loop_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Entry /* magic file entry */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Entry* next; /* next in list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* expr; /* offset expression */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin union
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Entry* lab;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regex_t* sub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Loop_t* loop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } value; /* comparison value */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* desc; /* file description */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* mime; /* file mime type */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long offset; /* offset in bytes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long mask; /* mask before compare */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char cont; /* continuation operation */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char type; /* datum type */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char op; /* comparison operation */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char nest; /* { or } nesting operation */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char swap; /* forced swap order */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Entry_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CC_BIT 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if (CC_MAPS*CC_BIT) <= (CHAR_BIT*2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef unsigned short Cctype_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef unsigned long Cctype_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CC_text 0x01
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CC_control 0x02
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CC_latin 0x04
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CC_binary 0x08
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CC_utf_8 0x10
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CC_notext CC_text /* CC_text is flipped before checking */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CC_MASK (CC_binary|CC_latin|CC_control|CC_text)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CCTYPE(c) (((c)>0240)?CC_binary:((c)>=0200)?CC_latin:((c)<040&&(c)!=007&&(c)!=011&&(c)!=012&&(c)!=013&&(c)!=015)?CC_control:CC_text)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_NONE 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_ASM 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_C 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_COBOL 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_COPYBOOK 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_CPLUSPLUS 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_FORTRAN 6
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_HTML 7
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_INCL1 8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_INCL2 9
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_INCL3 10
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_MAM1 11
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_MAM2 12
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_MAM3 13
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_NOTEXT 14
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_PL1 15
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_YACC 16
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ID_MAX ID_YACC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_atime 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_blocks 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_ctime 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_fstype 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_gid 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_mode 6
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_mtime 7
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_name 8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_nlink 9
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_size 10
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INFO_uid 11
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _MAGIC_PRIVATE_ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Magicdisc_t* disc; /* discipline */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Vmalloc_t* vm; /* vmalloc region */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Entry_t* magic; /* parsed magic table */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Entry_t* magiclast; /* last entry in magic */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* mime; /* MIME type */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* x2n; /* CC_ALIEN=>CC_NATIVE */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char fbuf[SF_BUFSIZE + 1]; /* file data */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char xbuf[SF_BUFSIZE + 1]; /* indirect file data */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char nbuf[256]; /* !CC_NATIVE data */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char mbuf[64]; /* mime string */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char sbuf[64]; /* type suffix string */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char tbuf[2 * PATH_MAX]; /* type string */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Cctype_t cctype[UCHAR_MAX + 1]; /* char code types */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned int count[UCHAR_MAX + 1]; /* char frequency count */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned int multi[UCHAR_MAX + 1]; /* muti char count */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int keep[MAXNEST]; /* ckmagic nest stack */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* cap[MAXNEST]; /* ckmagic mime stack */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* msg[MAXNEST]; /* ckmagic text stack */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Entry_t* ret[MAXNEST]; /* ckmagic return stack */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fbsz; /* fbuf size */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fbmx; /* fbuf max size */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int xbsz; /* xbuf size */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int swap; /* swap() operation */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long flags; /* disc+open flags */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long xoff; /* xbuf offset */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int identifier[ID_MAX + 1]; /* Info_t identifier */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* fp; /* fbuf fp */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* tmp; /* tmp string */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regdisc_t redisc; /* regex discipline */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dtdisc_t dtdisc; /* dict discipline */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t* idtab; /* identifier dict */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t* infotab; /* info keyword dict */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <magic.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Info_t dict[] = /* keyword dictionary */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "COMMON", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "COMPUTE", ID_COBOL },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "COMP", ID_COPYBOOK },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "COMPUTATIONAL",ID_COPYBOOK },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "DCL", ID_PL1 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "DEFINED", ID_PL1 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "DIMENSION", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "DIVISION", ID_COBOL },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "FILLER", ID_COPYBOOK },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "FIXED", ID_PL1 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "FUNCTION", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "HTML", ID_HTML },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "INTEGER", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "MAIN", ID_PL1 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "OPTIONS", ID_PL1 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "PERFORM", ID_COBOL },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "PIC", ID_COPYBOOK },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "REAL", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "REDEFINES", ID_COPYBOOK },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "S9", ID_COPYBOOK },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "SECTION", ID_COBOL },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "SELECT", ID_COBOL },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "SUBROUTINE", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "TEXT", ID_ASM },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "VALUE", ID_COPYBOOK },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "attr", ID_MAM3 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "binary", ID_YACC },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "block", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "bss", ID_ASM },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "byte", ID_ASM },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "char", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "class", ID_CPLUSPLUS },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "clr", ID_NOTEXT },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "comm", ID_ASM },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "common", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "data", ID_ASM },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "dimension", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "done", ID_MAM2 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "double", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "even", ID_ASM },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "exec", ID_MAM3 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "extern", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "float", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "function", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "globl", ID_ASM },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "h", ID_INCL3 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "html", ID_HTML },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "include", ID_INCL1 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "int", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "integer", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "jmp", ID_NOTEXT },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "left", ID_YACC },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "libc", ID_INCL2 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "long", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "make", ID_MAM1 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "mov", ID_NOTEXT },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "private", ID_CPLUSPLUS },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "public", ID_CPLUSPLUS },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "real", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "register", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "right", ID_YACC },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "sfio", ID_INCL2 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "static", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "stdio", ID_INCL2 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "struct", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "subroutine", ID_FORTRAN },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "sys", ID_NOTEXT },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "term", ID_YACC },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "text", ID_ASM },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "tst", ID_NOTEXT },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "type", ID_YACC },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "typedef", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "u", ID_INCL2 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "union", ID_YACC },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "void", ID_C },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Info_t info[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "atime", INFO_atime },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "blocks", INFO_blocks },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "ctime", INFO_ctime },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "fstype", INFO_fstype },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "gid", INFO_gid },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "mode", INFO_mode },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "mtime", INFO_mtime },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "name", INFO_name },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "nlink", INFO_nlink },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "size", INFO_size },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "uid", INFO_uid },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return pointer to data at offset off and size siz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingetdata(register Magic_t* mp, register long off, register int siz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register long n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (off < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (off + siz <= mp->fbsz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return mp->fbuf + off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (off < mp->xoff || off + siz > mp->xoff + mp->xbsz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (off + siz > mp->fbmx)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (off / (SF_BUFSIZE / 2)) * (SF_BUFSIZE / 2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfseek(mp->fp, n, SEEK_SET) != n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mp->xbsz = sfread(mp->fp, mp->xbuf, sizeof(mp->xbuf) - 1)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->xoff = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->xbsz = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->xbuf[mp->xbsz] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->xoff = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (off + siz > mp->xoff + mp->xbsz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return mp->xbuf + off - mp->xoff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * @... evaluator for strexpr()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic long
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinindirect(const char* cs, char** e, void* handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s = (char*)cs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Magic_t* mp = (Magic_t*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register long n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '@')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *++s == '(' ? strexpr(s, e, indirect, mp) : strtol(s, e, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*(s = *e))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'B':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = getdata(mp, n, 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *(unsigned char*)p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (char*)cs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'h':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'H':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = getdata(mp, n, 2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = swapget(mp->swap, p, 2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (char*)cs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'Q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = getdata(mp, n, 8))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = swapget(mp->swap, p, 8);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (char*)cs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isalnum(*s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = getdata(mp, n, 4))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = swapget(mp->swap, p, 4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (char*)cs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *e = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "%s in indirect expression", *e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * emit regex error message
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregmessage(Magic_t* mp, regex_t* re, int code)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[128];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regerror(code, re, buf, sizeof(buf));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 3, "regex: %s", buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * decompose vcodex(3) method composition
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvcdecomp(char* b, char* e, unsigned char* m, unsigned char* x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* map;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin const char* o;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int a;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin map = CCMAP(CC_ASCII, CC_NATIVE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = '^';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (m < (x - 1) && !*(m + 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * obsolete indices
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!a)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin o = "old, ";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (b < e && (c = *o++))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch (*m)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 0: o = "delta"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 1: o = "huffman"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 2: o = "huffgroup"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 3: o = "arith"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 4: o = "bwt"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 5: o = "rle"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 6: o = "mtf"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 7: o = "transpose"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 8: o = "table"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 9: o = "huffpart"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 50: o = "map"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 100: o = "recfm"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 101: o = "ss7"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin default: o = "UNKNOWN"; break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin m += 2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (b < e && (c = *o++))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (b < e && m < x && (c = *m++))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (map)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = map[c];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b >= e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (m < x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (n<<7) | (*m & 0x7f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*m++ & 0x80))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n >= (x - m))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check for magic table match in buf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinckmagic(register Magic_t* mp, const char* file, char* buf, struct stat* st, unsigned long off)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Entry_t* ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int level = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int call = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* base = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regmatch_t matches[10];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->swap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = mp->msg[0] = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = mp->cap[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->keep[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (ep = mp->magic; ep; ep = ep->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fun:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->nest == '{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++level >= MAXNEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin call = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->keep[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = mp->msg[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = mp->cap[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->keep[level] = mp->keep[level - 1] != 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->msg[level] = b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->cap[level] = mp->mime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ep->cont)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '#':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->keep[level] && b > buf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->swap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = mp->msg[0] = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = mp->cap[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->type == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '$':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->keep[level] && call < (MAXNEST - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->ret[++call] = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = ep->value.lab;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = mp->ret[call--];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->op == 'l')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '|':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->keep[level] > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checknest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mp->keep[level])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = mp->msg[level];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = mp->cap[level];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checknest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin p = "";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin num = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!ep->expr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = ep->offset + off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ep->offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = strexpr(ep->expr, NiL, indirect, mp) + off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_atime:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = st->st_atime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'D';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_blocks:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = iblocks(st);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'N';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_ctime:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = st->st_ctime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'D';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_fstype:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = fmtfs(st);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = toupper(ep->type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_gid:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->type == 'e' || ep->type == 'm' || ep->type == 's')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = fmtgid(st->st_gid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = toupper(ep->type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = st->st_gid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'N';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_mode:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->type == 'e' || ep->type == 'm' || ep->type == 's')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = fmtmode(st->st_mode, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = toupper(ep->type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = modex(st->st_mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'N';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_mtime:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = st->st_ctime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'D';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_name:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (base = strrchr(file, '/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = (char*)file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = toupper(ep->type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_nlink:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = st->st_nlink;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'N';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_size:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = st->st_size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'N';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INFO_uid:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->type == 'e' || ep->type == 'm' || ep->type == 's')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = fmtuid(st->st_uid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = toupper(ep->type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = st->st_uid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'N';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ep->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = *(unsigned char*)p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'h':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, 2)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = swapget(ep->swap ? (~ep->swap ^ mp->swap) : mp->swap, p, 2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'd':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, 4)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = swapget(ep->swap ? (~ep->swap ^ mp->swap) : mp->swap, p, 4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, 8)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = swapget(ep->swap ? (~ep->swap ^ mp->swap) : mp->swap, p, 8);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'e':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'E':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!ep->value.sub)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = regexec(ep->value.sub, p, elementsof(matches), matches, 0)) || (c = regsubexec(ep->value.sub, p, elementsof(matches), matches)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mp->fbsz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c >= sizeof(mp->nbuf))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = sizeof(mp->nbuf) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = (char*)memcpy(mp->nbuf, p, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p[c] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ccmapstr(mp->x2n, p, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = regexec(ep->value.sub, p, elementsof(matches), matches, 0)) || (c = regsubexec(ep->value.sub, p, elementsof(matches), matches)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != REG_NOMATCH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regmessage(mp, ep->value.sub, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = ep->value.sub->re_sub->re_buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = T(ep->desc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = *q ? q : p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->keep[level]++ && b > buf && *(b - 1) != ' ' && *t && *t != ',' && *t != '.' && *t != '\b')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += sfsprintf(b, PATH_MAX - (b - buf), *q ? q : "%s", p + (*p == '\b'));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->mime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = ep->mime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checknest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, ep->mask)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkstr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'm':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'M':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'S':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin checkstr:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ep->value.str == '*' && !*(ep->value.str + 1) && isprint(*p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((ep->type == 'm' || ep->type == 'M') ? strmatch(p, ep->value.str) : !memcmp(p, ep->value.str, ep->mask))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p == mp->nbuf || ep->mask >= sizeof(mp->nbuf))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = (char*)memcpy(mp->nbuf, p, ep->mask);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p[ep->mask] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ccmapstr(mp->x2n, p, ep->mask);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = T(ep->desc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->keep[level]++ && b > buf && *(b - 1) != ' ' && *q && *q != ',' && *q != '.' && *q != '\b')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (t = p; (c = *t) >= 0 && c <= 0177 && isprint(c) && c != '\n'; t++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += sfsprintf(b, PATH_MAX - (b - buf), q + (*q == '\b'), p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->mime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = ep->mime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checknest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mask = ep->mask)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num &= mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ep->op)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '@':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (num == ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->cont != '#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mask)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mask = ~mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->type == 'h')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((num = swapget(mp->swap = 1, p, 2) & mask) == ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(mp->swap & (mp->swap + 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->swap = 7;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto swapped;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (ep->type == 'l')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = 1; c < 4; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((num = swapget(mp->swap = c, p, 4) & mask) == ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(mp->swap & (mp->swap + 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->swap = 7;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto swapped;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (ep->type == 'q')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = 1; c < 8; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((num = swapget(mp->swap = c, p, 8) & mask) == ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto swapped;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '!':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (num != ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '^':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (num ^ ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (num > ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (num < ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (num > 0 && mp->keep[level] && call < (MAXNEST - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!ep->value.loop->count)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.loop->count = num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.loop->offset = off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off = ep->value.loop->start;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!--ep->value.loop->count)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off = ep->value.loop->offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off += ep->value.loop->size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->ret[++call] = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = ep->value.loop->lab;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'm':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mp->swap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = ckmagic(mp, file, b + (b > buf), st, num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->swap = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b > buf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += strlen(b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _UWIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* gp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(t = strrchr(file, '.')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, "/reg/classes_root/%s", t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(t = sfstruse(mp->tmp)) || !(rp = sfopen(NiL, t, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ep->desc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ep->mime = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin gp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (t = sfgetr(rp, '\n', 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strneq(t, "Content Type=", 13))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->mime = vmnewof(mp->vm, ep->mime, char, sfvalue(rp), 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(ep->mime, t + 13);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (gp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, "/reg/classes_root/%s", t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((e = sfstruse(mp->tmp)) && (gp = sfopen(NiL, e, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->desc = vmnewof(mp->vm, ep->desc, char, strlen(t), 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(ep->desc, t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ep->mime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(rp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!gp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*ep->mime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = T(ep->desc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strncasecmp(t, "microsoft", 9))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t += 9;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (isspace(*t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = "application/x-ms-";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->mime = vmnewof(mp->vm, ep->mime, char, strlen(t), strlen(e));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = strcopy(ep->mime, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = *t++) && c != '.' && c != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *e++ = isupper(c) ? tolower(c) : c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (t = sfgetr(gp, '\n', 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t && !streq(t, "\"\""))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->desc = vmnewof(mp->vm, ep->desc, char, sfvalue(gp), 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(ep->desc, t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(gp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*ep->desc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (t = T(ep->desc); *t; t++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t == '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mp->keep[level])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->keep[level] = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = ep->mime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->cont == '#' && !mp->keep[level])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->keep[level] = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, 4)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (c<<7) | (*p & 0x7f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (*p++ & 0x80);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getdata(mp, num, c)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->keep[level]++ && b > buf && *(b - 1) != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = ',';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = vcdecomp(b, buf + PATH_MAX, (unsigned char*)p, (unsigned char*)p + c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checknest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin swapped:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = T(ep->desc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->keep[level]++ && b > buf && *(b - 1) != ' ' && *q && *q != ',' && *q != '.' && *q != '\b')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->type == 'd' || ep->type == 'D')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += sfsprintf(b, PATH_MAX - (b - buf), q + (*q == '\b'), fmttime("%?%l", (time_t)num));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (ep->type == 'v')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += sfsprintf(b, PATH_MAX - (b - buf), q + (*q == '\b'), fmtversion(num));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += sfsprintf(b, PATH_MAX - (b - buf), q + (*q == '\b'), num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->mime && *ep->mime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = ep->mime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin checknest:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->nest == '}')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mp->keep[level])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = mp->msg[level];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = mp->cap[level];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (level > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->keep[level - 1] = mp->keep[level];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (--level < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->keep[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->cont == '&')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->keep[level] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checknest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->keep[level] && b > buf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check english language stats
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinckenglish(register Magic_t* mp, int pun, int badpun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int vowl = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int freq = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int rare = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (5 * badpun > pun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (2 * mp->count[';'] > mp->count['E'] + mp->count['e'])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mp->count['>'] + mp->count['<'] + mp->count['/']) > mp->count['E'] + mp->count['e'])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = "aeiou"; *s; s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vowl += mp->count[toupper(*s)] + mp->count[*s];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = "etaion"; *s; s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin freq += mp->count[toupper(*s)] + mp->count[*s];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = "vjkqxz"; *s; s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rare += mp->count[toupper(*s)] + mp->count[*s];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 5 * vowl >= mp->fbsz - mp->count[' '] && freq >= 10 * rare;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check programming language stats
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincklang(register Magic_t* mp, const char* file, char* buf, struct stat* st)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* suff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int badpun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int code;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Cctype_t flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Info_t* ip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = (unsigned char*)mp->fbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = b + mp->fbsz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memzero(mp->count, sizeof(mp->count));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memzero(mp->multi, sizeof(mp->multi));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memzero(mp->identifier, sizeof(mp->identifier));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check character coding
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (b < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= mp->cctype[*b++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = (unsigned char*)mp->fbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin code = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = CC_ASCII;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = CC_MASK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = 0; c < CC_MAPS; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags ^= CC_text;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags & CC_MASK) < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = flags & CC_MASK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags >>= CC_BIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & (CC_binary|CC_notext)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q != CC_NATIVE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin code = q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ccmaps(mp->fbuf, mp->fbsz, q, CC_NATIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b[0] == '#' && b[1] == '!')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (b += 2; b < e && isspace(*b); b++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = (char*)b; b < e && isprint(*b); b++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) || match(s, "/*bin*/*") || !access(s, F_OK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t = strrchr(s, '/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = t + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (t = s; *t; t++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isspace(*t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(mp->mbuf, sizeof(mp->mbuf), "application/x-%s", *s ? s : "sh");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = mp->mbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(s, "*sh"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t1 = T("command");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(s, "sh"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t1 = T("interpreter");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(mp->sbuf, sizeof(mp->sbuf), T("%s%s script"), s, t1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = mp->sbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = (unsigned char*)mp->fbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin badpun = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pun = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (b < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *b++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->count[c]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == q && (q != '*' || *b == '/' && b++))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi[q]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isalpha(c) || c == '_')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (char*)b - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!isdigit(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s > mp->fbuf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*(s - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*b == ':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi[':']++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '.':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (((char*)b - s) == 3 && (s == (mp->fbuf + 1) || *(s - 2) == '\n'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi['.']++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*b == '{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (char*)b + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '{':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s == t && *b == '}')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi['X']++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mp->idtab)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->idtab = dtnew(mp->vm, &mp->dtdisc, Dthash))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (q = 0; q < elementsof(dict); q++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(mp->idtab, &dict[q]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 3, "out of space");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->idtab)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(b - 1) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ip = (Info_t*)dtmatch(mp->idtab, s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->identifier[ip->value]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(b - 1) = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\t':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b == (unsigned char*)(mp->fbuf + 1) || *(b - 2) == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi['\t']++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '"':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\'':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '/':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*b == '*')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = *b++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*b == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '$':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*b == '(' && *(b + 1) != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi['$']++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '{':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '}':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '[':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ']':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi[c]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi[c]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto punctuation;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*b == ':' && isspace(*(b + 1)) && b > (unsigned char*)(mp->fbuf + 1) && isspace(*(b - 2)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi[':']++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto punctuation;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '.':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ',':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '%':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ';':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin punctuation:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pun++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*b != ' ' && *b != '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin badpun++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (b < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->count[*b++]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = (t1 = strrchr(file, '/')) ? t1 + 1 : (char*)file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin suff = (t1 = strrchr(base, '.')) ? t1 + 1 : "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "*sh|bat|cmd"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(base, "*@(mkfile)"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_mk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(base, "*@(makefile|.mk)"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_make;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(base, "*@(mamfile|.mam)"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_mam;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "[cly]?(pp|xx|++)|cc|ll|yy"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "f"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_fortran;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "htm+(l)"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_html;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "cpy"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_copybook;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "cob|cbl|cb2"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_cobol;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "pl[1i]"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_pl1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "tex"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_tex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(suff, "asm|s"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto id_asm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) && (!suff || suff != strchr(suff, '.')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_sh:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("command script");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/sh";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strmatch(mp->fbuf, "From * [0-9][0-9]:[0-9][0-9]:[0-9][0-9] *"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("mail message");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "message/rfc822";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(base, "*@(mkfile)"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_mk:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = "mkfile";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/mk";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (match(base, "*@(makefile|.mk)") || mp->multi['\t'] >= mp->count[':'] && (mp->multi['$'] > 0 || mp->multi[':'] > 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_make:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = "makefile";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/make";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->multi['.'] >= 3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("nroff input");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-troff";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->multi['X'] >= 3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("TeX input");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-tex";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->fbsz < SF_BUFSIZE &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (mp->multi['('] == mp->multi[')'] &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi['{'] == mp->multi['}'] &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi['['] == mp->multi[']']) ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->fbsz >= SF_BUFSIZE &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (mp->multi['('] >= mp->multi[')'] &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi['{'] >= mp->multi['}'] &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->multi['['] >= mp->multi[']']))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mp->identifier[ID_INCL1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c >= 2 && mp->identifier[ID_INCL2] >= c && mp->identifier[ID_INCL3] >= c && mp->count['.'] >= c ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->identifier[ID_C] >= 5 && mp->count[';'] >= 5 ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->count['='] >= 20 && mp->count[';'] >= 20)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_c:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t1 = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t2 = "c ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t3 = T("program");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*suff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'C':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-cc";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'L':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t1 = "lex ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-lex";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t3 = T("header");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_YACC] < 5 || mp->count['%'] < 5)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-cc";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'y':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'Y':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t1 = "yacc ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-yacc";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_CPLUSPLUS] >= 3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t2 = "c++ ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-c++";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(mp->sbuf, sizeof(mp->sbuf), "%s%s%s", t1, t2, t3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = mp->sbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_MAM1] >= 2 && mp->identifier[ID_MAM3] >= 2 &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (mp->fbsz < SF_BUFSIZE && mp->identifier[ID_MAM1] == mp->identifier[ID_MAM2] ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->fbsz >= SF_BUFSIZE && mp->identifier[ID_MAM1] >= mp->identifier[ID_MAM2]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_mam:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("mam program");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-mam";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_FORTRAN] >= 8)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_fortran:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("fortran program");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-fortran";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_HTML] > 0 && mp->count['<'] >= 8 && (c = mp->count['<'] - mp->count['>']) >= -2 && c <= 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_html:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("html input");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "text/html";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_COPYBOOK] > 0 && mp->identifier[ID_COBOL] == 0 && (c = mp->count['('] - mp->count[')']) >= -2 && c <= 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_copybook:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("cobol copybook");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-cobol";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_COBOL] > 0 && mp->identifier[ID_COPYBOOK] > 0 && (c = mp->count['('] - mp->count[')']) >= -2 && c <= 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_cobol:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("cobol program");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-cobol";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_PL1] > 0 && (c = mp->count['('] - mp->count[')']) >= -2 && c <= 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_pl1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("pl1 program");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-pl1";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->count['{'] >= 6 && (c = mp->count['{'] - mp->count['}']) >= -2 && c <= 2 && mp->count['\\'] >= mp->count['{'])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_tex:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("TeX input");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "text/tex";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->identifier[ID_ASM] >= 4)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id_asm:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("as program");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/x-as";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ckenglish(mp, pun, badpun))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("english text");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "text/plain";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto qualify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (streq(base, "core"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "x-system/core";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T("core dump");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & (CC_binary|CC_notext))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = (unsigned char*)mp->fbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = b + mp->fbsz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *b++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c & 0x80)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c <<= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 4:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b < e && (*b++ & 0xc0) != 0x80)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 3:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b < e && (*b++ & 0xc0) != 0x80)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b < e && (*b++ & 0xc0) != 0x80)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b >= e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~(CC_binary|CC_notext);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= CC_utf_8;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & (CC_binary|CC_notext))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long d = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((q = mp->fbsz / UCHAR_MAX) >= 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * compression/encryption via standard deviation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = 0; c < UCHAR_MAX; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pun = mp->count[c] - q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d += pun * pun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d /= mp->fbsz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (d <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("binary");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (d < 4)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("encrypted");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (d < 16)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("packed");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (d < 64)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("compressed");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (d < 256)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("delta");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("data");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/octet-stream";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "text/plain";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & CC_utf_8)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (flags & CC_control) ? T("utf-8 text with control characters") : T("utf-8 text");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (flags & CC_latin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (flags & CC_control) ? T("latin text with control characters") : T("latin text");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (flags & CC_control) ? T("text with control characters") : T("text");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qualify:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!flags && mp->count['\n'] >= mp->count['\r'] && mp->count['\n'] <= (mp->count['\r'] + 1) && mp->count['\r'])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = "dos ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "text/dos";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (code)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (code == CC_ASCII)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(buf, PATH_MAX, "ascii %s%s", t, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(buf, PATH_MAX, "ebcdic%d %s%s", code - 1, t, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "text/ebcdic";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(buf, PATH_MAX, "%s%s", t, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the basic magic string for file,st in buf,size
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintype(register Magic_t* mp, const char* file, struct stat* st, char* buf, int size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!S_ISREG(st->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISDIR(st->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "x-system/dir";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T("directory");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISLNK(st->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "x-system/lnk";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s += sfsprintf(s, PATH_MAX, T("symbolic link to "));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pathgetlink(file, s, size - (s - buf)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T("cannot read symbolic link text");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISBLK(st->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "x-system/blk";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(buf, PATH_MAX, T("block special (%s)"), fmtdev(st));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISCHR(st->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "x-system/chr";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(buf, PATH_MAX, T("character special (%s)"), fmtdev(st));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISFIFO(st->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "x-system/fifo";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return "fifo";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_ISSOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISSOCK(st->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "x-system/sock";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return "socket";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(mp->fbmx = st->st_size))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("empty");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!mp->fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("cannot read");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->fbsz = sfread(mp->fp, mp->fbuf, sizeof(mp->fbuf) - 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->fbsz < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = fmterror(errno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (mp->fbsz == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("empty");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->fbuf[mp->fbsz] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->xoff = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->xbsz = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = ckmagic(mp, file, buf, st, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = cklang(mp, file, buf, st);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mp->mime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = "application/unknown";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((t = strchr(mp->mime, '%')) && *(t + 1) == 's' && !*(t + 2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* be;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* me;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = mp->mime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin me = (m = mp->mime = mp->fbuf) + sizeof(mp->fbuf) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (m < me && b < t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *m++ = *b++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = t = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(be = strchr(t, ' ')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin be = b + strlen(b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(be - 1) == ',' || strneq(be + 1, "data", 4) || strneq(be + 1, "file", 4))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = be + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (m < me && b < be)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*m++ = *b++) == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(m - 1) = '-';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * low level for magicload()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinload(register Magic_t* mp, char* file, register Sfio_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Entry_t* ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* p3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int lge;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int lev;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int cont;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Info_t* ip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Entry_t* ret;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Entry_t* first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Entry_t* last = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Entry_t* fun['z' - 'a' + 1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memzero(fun, sizeof(fun));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cont = '$';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ent = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lev = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ret = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.file = file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = ep = vmnewof(mp->vm, 0, Entry_t, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (p = sfgetr(fp, '\n', 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*p); p++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * nesting
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '#':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cont = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '{':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++lev < MAXNEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->nest = *p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 1, "{ ... } operator nesting too deep -- %d max", MAXNEST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '}':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!last || lev <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "`%c': invalid nesting", *p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (lev-- == ent)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ent = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->cont = ':';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->offset = ret->offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->nest = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->op = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->desc = "[RETURN]";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = ret->next = vmnewof(mp->vm, 0, Entry_t, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ret = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last->nest = *p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(p + 1) == '{' || *(p + 1) == '(' && *p != '+' && *p != '>' && *p != '&' && *p != '|')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n >= 'a' && n <= 'z')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n -= 'a';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "%c: invalid function name", n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ret && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "%c: function has no return", ret->offset + 'a');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p == '{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ent = ++lev;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ret = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->desc = "[FUNCTION]";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(p + 1) != ')' && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "%c: invalid function call argument list", n + 'a');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->desc = "[CALL]";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->cont = cont;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->offset = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->nest = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->op = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = ep->next = vmnewof(mp->vm, 0, Entry_t, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ret)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fun[n] = last->value.lab = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(last->value.lab = fun[n]) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "%c: function not defined", n + 'a');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!ep->nest)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->nest = (lev > 0 && lev != ent) ? ('0' + lev - !!ent) : ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * continuation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cont = '$';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(p + 1) == *p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * old style nesting push
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!lev && last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lev = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last->nest = '{';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (last->cont == '>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last->cont = '&';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->nest = '1';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '+':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '&':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '|':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->cont = *p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mp->flags & MAGIC_VERBOSE) && !isalpha(*p) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 1, "`%c': invalid line continuation operator", *p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '*':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '0': case '1': case '2': case '3': case '4':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '5': case '6': case '7': case '8': case '9':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->cont = (lev > 0) ? '&' : '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (old)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (lev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * old style nesting pop
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lev = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last->nest = '}';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->nest = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->cont == '&')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->cont = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isdigit(*p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * absolute offset
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->offset = strton(p, &next, NiL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p2 = next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p2 = p; *p2 && !isspace(*p2); p2++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*p2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 1, "not enough fields: `%s'", p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * offset expression
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p2++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->expr = vmstrdup(mp->vm, p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isalpha(*p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->offset = (ip = (Info_t*)dtmatch(mp->infotab, p)) ? ip->value : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*p == '(' && ep->cont == '>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert old style indirection to @
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = ep->expr + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '@':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*--p == ')')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ep->expr = '@';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*p2); p2++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p = p2; *p2 && !isspace(*p2); p2++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*p2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 1, "not enough fields: `%s'", p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p2++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * type
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*p == 'b' || *p == 'l') && *(p + 1) == 'e')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->swap = ~(*p == 'l' ? 7 : 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p == 's')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(p + 1) == 'h')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'h';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 's';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*p == 'a')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 's';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = *p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = strchr(p, '&'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * old style mask
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->mask = strton(++p, NiL, NiL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*p2); p2++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->mask)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--p2 = '=';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * comparison operation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = p2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p2 = strchr(p, '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p2++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int qe = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int qn = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * assume balanced {}[]()\\""'' field
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p2 = p;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (n = *p2++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '{':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!qe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qe = '}';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (qe == '}')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qn++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!qe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qe = ')';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (qe == ')')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qn++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '[':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!qe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qe = ']';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (qe == ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qn++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '}':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ']':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (qe == n && qn > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qn--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '"':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\'':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!qe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qe = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (qe == n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qe = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p2++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!qe && isspace(n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(p2 - 1) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p2--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lge = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->type == 'e' || ep->type == 'm' || ep->type == 's')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->op = '=';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p == '&')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->mask = strton(++p, &next, NiL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '*':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->op = *p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p == '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ep->op)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lge = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lge = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '!':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '@':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->op = *p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p == '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'x':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->op = '*';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->op = '=';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->mask)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.num = ep->mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->op != '*' && !ep->value.num)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->type == 'e')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->value.sub = vmnewof(mp->vm, 0, regex_t, 1, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.sub->re_disc = &mp->redisc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(n = regcomp(ep->value.sub, p, REG_DELIMITED|REG_LENIENT|REG_NULL|REG_DISCIPLINE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p += ep->value.sub->re_npat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(n = regsubcomp(ep->value.sub, p, NiL, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p += ep->value.sub->re_npat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regmessage(mp, ep->value.sub, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.sub = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*p && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 1, "invalid characters after substitution: %s", p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (ep->type == 'm')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->mask = stresc(p) + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.str = vmnewof(mp->vm, 0, char, ep->mask + 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(ep->value.str, p, ep->mask);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((!ep->expr || !ep->offset) && !strmatch(ep->value.str, "\\!\\(*\\)"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.str[ep->mask - 1] = '*';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (ep->type == 's')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->mask = stresc(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.str = vmnewof(mp->vm, 0, char, ep->mask, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(ep->value.str, p, ep->mask);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*p == '\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stresc(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.num = *(unsigned char*)(p + 1) + lge;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (strmatch(p, "+([a-z])\\(*\\)"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->type = 'V';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->op = *p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*p && *p++ != '(');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ep->op)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < 'a' || n > 'z')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "%c: invalid function name", n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!fun[n -= 'a'])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "%c: function not defined", n + 'a');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.loop = vmnewof(mp->vm, 0, Loop_t, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.loop->lab = fun[n];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*p && *p++ != ',');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.loop->start = strton(p, &t, NiL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*t && *t++ != ',');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.loop->size = strton(t, &t, NiL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'm':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->desc = vmnewof(mp->vm, 0, char, 32, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->mime = vmnewof(mp->vm, 0, char, 32, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 1, "%-.*s: unknown function", p - t, t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.num = strton(p, NiL, NiL, 0) + lge;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->op == '@')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.num = swapget(0, (char*)&ep->value.num, sizeof(ep->value.num));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file description
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*p2); p2++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = strchr(p2, '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check for message catalog index
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isalpha(*p2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p3 = p2; isalnum(*p3); p3++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p3++ == ':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isdigit(*p3); p3++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*p3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p2 = p; isspace(*p2); p2++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = strchr(p2, '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stresc(p2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->desc = vmstrdup(mp->vm, p2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*p); p++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->mime = vmstrdup(mp->vm, p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->desc = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get next entry
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = ep->next = vmnewof(mp->vm, 0, Entry_t, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->magiclast)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->magiclast->next = first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->magic = first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->magiclast = last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmfree(mp->vm, ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (lev < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 1, "too many } operators");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (lev > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 1, "not enough } operators");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ret)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "%c: function has no return", ret->offset + 'a');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.file = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * load a magic file into mp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmagicload(register Magic_t* mp, const char* file, unsigned long flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int found;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int list;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->flags = mp->disc->flags | flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin found = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (list = !(s = (char*)file) || !*s || (*s == '-' || *s == '.') && !*(s + 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = getenv(MAGIC_FILE_ENV)) || !*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = MAGIC_FILE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!list)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (e = strchr(s, ':'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ok, so ~ won't work for the last list element
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * we do it for MAGIC_FILES_ENV anyway
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((strneq(s, "~/", n = 2) || strneq(s, "$HOME/", n = 6) || strneq(s, "${HOME}/", n = 8)) && (t = getenv("HOME")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(mp->tmp, t, -1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s += n - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(mp->tmp, s, e - s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = sfstruse(mp->tmp)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || streq(s, "-"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = MAGIC_FILE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp = sfopen(NiL, s, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (list)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(t = pathpath(mp->fbuf, s, "", PATH_REGULAR|PATH_READ)) && !strchr(s, '/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(mp->fbuf, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, "%s/%s", MAGIC_DIR, mp->fbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = sfstruse(mp->tmp)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(t = pathpath(mp->fbuf, s, "", PATH_REGULAR|PATH_READ)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp = sfopen(NiL, t, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 3, "%s: cannot open magic file", s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin found = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = load(mp, s, fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n && !list)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = e + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!found)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->flags & MAGIC_VERBOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 2, "cannot find magic file");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nospace:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->disc->errorf)(mp, mp->disc, 3, "out of space");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open a magic session
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinMagic_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmagicopen(Magicdisc_t* disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Magic_t* mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Vmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* map[CC_MAPS + 1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(mp = vmnewof(vm, 0, Magic_t, 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmclose(vm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->id = lib;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->disc = disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->vm = vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->flags = disc->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->redisc.re_version = REG_VERSION;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->redisc.re_flags = REG_NOFREE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->redisc.re_errorf = (regerror_t)disc->errorf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->redisc.re_resizef = (regresize_t)vmgetmem;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->redisc.re_resizehandle = (void*)mp->vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->dtdisc.key = offsetof(Info_t, name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->dtdisc.link = offsetof(Info_t, link);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(mp->tmp = sfstropen()) || !(mp->infotab = dtnew(mp->vm, &mp->dtdisc, Dthash)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n < elementsof(info); n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(mp->infotab, &info[n]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < CC_MAPS; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin map[i] = ccmap(i, CC_ASCII);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->x2n = ccmap(CC_ALIEN, CC_NATIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n <= UCHAR_MAX; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = CC_MAPS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (--i >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ccmapchr(map[i], n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (f << CC_BIT) | CCTYPE(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->cctype[n] = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bad:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin magicclose(mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close a magicopen() session
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmagicclose(register Magic_t* mp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->tmp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfstrclose(mp->tmp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->vm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmclose(mp->vm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the magic string for file with optional stat info st
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmagictype(register Magic_t* mp, Sfio_t* fp, const char* file, register struct stat* st)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_t off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->flags = mp->disc->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->mime = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!st)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("cannot stat");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->fp = fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off = sfseek(mp->fp, (off_t)0, SEEK_CUR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = type(mp, file, st, mp->tbuf, sizeof(mp->tbuf));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(mp->fp, off, SEEK_SET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(mp->flags & MAGIC_MIME))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISREG(st->st_mode) && (st->st_size > 0) && (st->st_size < 128))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, "%s ", T("short"));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, "%s", s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mp->fp && (st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, ", %s", S_ISDIR(st->st_mode) ? T("searchable") : T("executable"));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (st->st_mode & S_ISUID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, ", setuid=%s", fmtuid(st->st_uid));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (st->st_mode & S_ISGID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, ", setgid=%s", fmtgid(st->st_gid));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (st->st_mode & S_ISVTX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(mp->tmp, ", sticky");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = sfstruse(mp->tmp)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("out of space");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp->flags & MAGIC_MIME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = mp->mime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = T("error");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * list the magic table in mp on sp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmagiclist(register Magic_t* mp, register Sfio_t* sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Entry_t* ep = mp->magic;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Entry_t* rp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->flags = mp->disc->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "cont\toffset\ttype\top\tmask\tvalue\tmime\tdesc\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%c %c\t", ep->cont, ep->nest);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->expr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%s", ep->expr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%ld", ep->offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "\t%s%c\t%c\t%lo\t", ep->swap == (char)~3 ? "L" : ep->swap == (char)~0 ? "B" : "", ep->type, ep->op, ep->mask);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ep->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'm':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sp, fmtesc(ep->value.str), -1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'V':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (ep->op)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "loop(%d,%d,%d,%d)", ep->value.loop->start, ep->value.loop->size, ep->value.loop->count, ep->value.loop->offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "vcodex()");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%p", ep->value.str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%lo", ep->value.num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "\t%s\t%s\n", ep->mime ? ep->mime : "", fmtesc(ep->desc));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->cont == '$' && !ep->value.lab->mask)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rp = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = ep->value.lab;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->cont == ':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->value.lab->mask = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = ep->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}