1*a77ebd86SchristosThis is a first attempt to document the grammar used by magic(5), with 2*a77ebd86Schristoshopes of eventually incorporating something like this into the manpage. 3*a77ebd86Schristos 4*a77ebd86SchristosNote: Currently, the parser varies slightly from this, but only in 5*a77ebd86Schristosvery minor ways, e.g., the strflags maybe separated by '/' characters 6*a77ebd86Schristosand at most one strcount is allowed; likewise for regflags. 7*a77ebd86Schristos 8*a77ebd86Schristos------------------------------------------------------------------------ 9*a77ebd86Schristosmagic = 1*query 10*a77ebd86Schristos 11*a77ebd86Schristosquery = line *( 1*level line ) 12*a77ebd86Schristos 13*a77ebd86Schristoslevel = ">" ;; Increment the level by 1. 14*a77ebd86Schristos ;; The first line of a query is at level 0. 15*a77ebd86Schristos 16*a77ebd86Schristosline = offset HWS type HWS test HWS message EOL 17*a77ebd86Schristos 18*a77ebd86Schristos------------------------------------------------------------------------ 19*a77ebd86Schristosoffset = absoffset | reloffset | indoffset 20*a77ebd86Schristos ;; The offset in the file at which to apply 21*a77ebd86Schristos ;; the <test>. 22*a77ebd86Schristos 23*a77ebd86Schristosabsoffset = NUMBER ;; An absolute offset from the start of the file. 24*a77ebd86Schristos 25*a77ebd86Schristosreloffset = "&" NUMBER ;; The offset relative to the last match offset 26*a77ebd86Schristos ;; at one level up. 27*a77ebd86Schristos ;; Not allowed at level == 0. 28*a77ebd86Schristos 29*a77ebd86Schristosindoffset = indoff | relindoff 30*a77ebd86Schristos 31*a77ebd86Schristosindoff = "(" offset1 [ "." size ] [ op disp ] ")" 32*a77ebd86Schristos ;; Read the file at <offset1> of width <size>. 33*a77ebd86Schristos ;; If size is not specified, assume a long. 34*a77ebd86Schristos ;; If <op> is given, then preform that 35*a77ebd86Schristos ;; operation on the result and the <disp>. 36*a77ebd86Schristos 37*a77ebd86Schristosoffset1 = absoffset | reloffset 38*a77ebd86Schristos 39*a77ebd86Schristossize = byte | leshort | beshort | lelong | belong | melong 40*a77ebd86Schristos 41*a77ebd86Schristosbyte = "B" | "b" | "C" | "c" ;; A one-byte value. 42*a77ebd86Schristosleshort = "s" | "h" ;; A two-byte little-endian value. 43*a77ebd86Schristosbeshort = "S" | "H" ;; A two-byte big-endian value. 44*a77ebd86Schristoslelong = "l" ;; A four-byte little-endian value. 45*a77ebd86Schristosbelong = "L" ;; A four-byte big-endian value. 46*a77ebd86Schristosmelong = "m" ;; A four-byte middle-endian value. 47*a77ebd86Schristos 48*a77ebd86Schristosop = [ invert ] ( "+" | "-" | "*" | "/" | "%" | "&" | "|" | "^" ) 49*a77ebd86Schristos 50*a77ebd86Schristosinvert = "~" ;; Flip the bits on result of the <op>. 51*a77ebd86Schristos 52*a77ebd86Schristosdisp = NUMBER | memvalue 53*a77ebd86Schristos 54*a77ebd86Schristosmemvalue = "(" NUMBER ")" 55*a77ebd86Schristos ;; NUMBER is interpreted as an absolute or 56*a77ebd86Schristos ;; relative offset matching that of <offset1>. 57*a77ebd86Schristos ;; Read the file at the resulting offset with 58*a77ebd86Schristos ;; the same size as <offset1> 59*a77ebd86Schristos 60*a77ebd86Schristosrelindoff = "&" indoff ;; add <indoff> to the last match offset at 61*a77ebd86Schristos ;; one level up. 62*a77ebd86Schristos 63*a77ebd86Schristos------------------------------------------------------------------------ 64*a77ebd86Schristostype = [ unsigned ] ( numeric | strtype | default ) 65*a77ebd86Schristos 66*a77ebd86Schristosunsigned = "u" ;; The value is unsigned. 67*a77ebd86Schristos ;; This affects the sign extension of numeric 68*a77ebd86Schristos ;; types and the '<' and '>' compares. It is 69*a77ebd86Schristos ;; intended for numeric types, but allowed on 70*a77ebd86Schristos ;; all types. 71*a77ebd86Schristos 72*a77ebd86Schristosnumeric = ( numtype | datatype ) [ nummask ] 73*a77ebd86Schristos 74*a77ebd86Schristosnumtype = byte | short | long | quad 75*a77ebd86Schristos 76*a77ebd86Schristosbyte = "byte" 77*a77ebd86Schristosshort = "short" | "beshort" | "leshort" 78*a77ebd86Schristoslong = "long" | "lelong" | "belong" | "melong" 79*a77ebd86Schristosquad = "quad" | "lequad" | "bequad" 80*a77ebd86Schristos 81*a77ebd86Schristosdatetype = udate32 | ldate32 | udate64 | ldate64 82*a77ebd86Schristos 83*a77ebd86Schristosudate32 = "date" | "bedate" | "ledate" | "medate" ;; UTC dates 84*a77ebd86Schristosldate32 = "ldate" | "beldate" | "leldate" | "meldate" ;; local dates 85*a77ebd86Schristosudate64 = "qdate" | "leqdate" | "beqdate" ;; UTC dates 86*a77ebd86Schristosldate64 = "qldate" | "leqldate" | "beqldate" ;; local dates 87*a77ebd86Schristos 88*a77ebd86Schristosnummask = op NUMBER 89*a77ebd86Schristos 90*a77ebd86Schristosstrtype = regex | search | string8 | string16 91*a77ebd86Schristos 92*a77ebd86Schristosregex = "regex" [ "/" 1*regflag ] 93*a77ebd86Schristos 94*a77ebd86Schristosregflag = "c" | "s" | linecnt 95*a77ebd86Schristos 96*a77ebd86Schristoslinecnt = NUMBER ;; The number of lines to search. If this 97*a77ebd86Schristos ;; is missing or zero, the rest of the 98*a77ebd86Schristos ;; file is searched. 99*a77ebd86Schristos 100*a77ebd86Schristossearch = "string" [ "/" 1*srchflag ] 101*a77ebd86Schristos 102*a77ebd86Schristossrchflag = strflag | srchcnt 103*a77ebd86Schristos 104*a77ebd86Schristossrchcnt = NUMBER ;; The number of search tries. If this 105*a77ebd86Schristos ;; is missing or zero, the rest of the 106*a77ebd86Schristos ;; file is searched. 107*a77ebd86Schristos 108*a77ebd86Schristosstring8 = ( "string" | "pstring" ) [ "/" 1*strflag ] 109*a77ebd86Schristos 110*a77ebd86Schristosstrflag = "b" | "B" | "c" | "C" 111*a77ebd86Schristos 112*a77ebd86Schristosstring16 = "bestring16" | "lestring16" 113*a77ebd86Schristos 114*a77ebd86Schristosdefault = "default" ;; This is intended to be used with the 115*a77ebd86Schristos ;; <truetest> ("x" below). It is matched if 116*a77ebd86Schristos ;; there has been no previous match at its 117*a77ebd86Schristos ;; level or none since the last default at 118*a77ebd86Schristos ;; that level. It is useful for implementing 119*a77ebd86Schristos ;; switch-like and if/else constructions. 120*a77ebd86Schristos 121*a77ebd86Schristos------------------------------------------------------------------------ 122*a77ebd86Schristostest = numtest | strtest | truetest 123*a77ebd86Schristos ;; Test to preform on <type> read from file. 124*a77ebd86Schristos 125*a77ebd86Schristosnumtest = [ compare ] NUMBER ;; If compare is missing, "=" is assumed. 126*a77ebd86Schristos 127*a77ebd86Schristosstrtest = [ compare ] STRING ;; If compare is missing, "=" is assumed. 128*a77ebd86Schristos ;; Note: If the STRING begins with a <compare> 129*a77ebd86Schristos ;; character, the <compare> field cannot be 130*a77ebd86Schristos ;; omitted. 131*a77ebd86Schristos 132*a77ebd86Schristoscompare = "=" | "!" | "<" | ">" | "&" | "^" 133*a77ebd86Schristos 134*a77ebd86Schristostruetest = "x" ;; This always returns true. 135*a77ebd86Schristos ;; To test for the string "x" use "=x". 136*a77ebd86Schristos 137*a77ebd86Schristos------------------------------------------------------------------------ 138*a77ebd86Schristosmessage = [ nospflag ] ( STRING | FMT_STRING ) 139*a77ebd86Schristos ;; Message to print if test result is true. 140*a77ebd86Schristos 141*a77ebd86Schristosnospflag = %x08 | "\\b" ;; Do not insert a space before the message. 142*a77ebd86Schristos ;; By default, messages are separated by a " ". 143*a77ebd86Schristos 144*a77ebd86Schristos------------------------------------------------------------------------ 145*a77ebd86SchristosHWS = <horizontal white space> 146*a77ebd86SchristosEOL = <end of line marker> 147*a77ebd86SchristosNUMBER = <C-style unsigned number> 148*a77ebd86SchristosSTRING = <C-style string without delimiting quotes> 149*a77ebd86SchristosFMTSTR = <printf format string with exactly one % construct> 150*a77ebd86Schristos 151*a77ebd86Schristos------------------------------------------------------------------------ 152