1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
5    Copyright (C) 2016-2019 Bareos GmbH & Co. KG
6 
7    This program is Free Software; you can redistribute it and/or
8    modify it under the terms of version three of the GNU Affero General Public
9    License as published by the Free Software Foundation and included
10    in the file LICENSE.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15    Affero General Public License for more details.
16 
17    You should have received a copy of the GNU Affero General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301, USA.
21 */
22 /*
23  * Kern Sibbald, MM
24  */
25 /**
26  * @file
27  * Lexical scanning of configuration files, used by parsers.
28  */
29 
30 #ifndef BAREOS_LIB_LEX_H_
31 #define BAREOS_LIB_LEX_H_
32 
33 #include "include/bareos.h"
34 
35 /* Lex get_char() return values */
36 #define L_EOF (-1)
37 #define L_EOL (-2)
38 
39 /* Internal tokens */
40 #define BCT_NONE 100
41 
42 /* Tokens returned by get_token() */
43 #define BCT_EOF 101
44 #define BCT_NUMBER 102
45 #define BCT_IPADDR 103
46 #define BCT_IDENTIFIER 104
47 #define BCT_UNQUOTED_STRING 105
48 #define BCT_QUOTED_STRING 106
49 #define BCT_BOB 108 /* begin block */
50 #define BCT_EOB 109 /* end of block */
51 #define BCT_EQUALS 110
52 #define BCT_COMMA 111
53 #define BCT_EOL 112
54 #define BCT_ERROR 200
55 #define BCT_UTF8_BOM 201  /* File starts with a UTF-8 BOM*/
56 #define BCT_UTF16_BOM 202 /* File starts with a UTF-16LE BOM*/
57 
58 /**
59  * The following will be returned only if
60  * the appropriate expect flag has been set
61  */
62 #define BCT_SKIP_EOL 113     /* scan through EOLs */
63 #define BCT_PINT16 114       /* 16 bit positive integer */
64 #define BCT_PINT32 115       /* 32 bit positive integer */
65 #define BCT_PINT32_RANGE 116 /* 32 bit positive integer range */
66 #define BCT_INT16 117        /* 16 bit integer */
67 #define BCT_INT32 118        /* 32 bit integer */
68 #define BCT_INT64 119        /* 64 bit integer */
69 #define BCT_NAME 120         /* name max 128 chars */
70 #define BCT_STRING 121       /* string */
71 #define BCT_PINT64_RANGE 122 /* positive integer range */
72 #define BCT_PINT64 123       /* positive integer range */
73 
74 #define BCT_ALL 0 /* no expectations */
75 
76 /* Lexical state */
77 enum lex_state
78 {
79   lex_none,
80   lex_comment,
81   lex_number,
82   lex_ip_addr,
83   lex_identifier,
84   lex_string,
85   lex_quoted_string,
86   lex_include_quoted_string,
87   lex_include,
88   lex_utf8_bom,    /* we are parsing out a utf8 byte order mark */
89   lex_utf16_le_bom /* we are parsing out a utf-16 (little endian) byte order
90                       mark */
91 };
92 
93 /* Lex scan options */
94 #define LOPT_NO_IDENT 0x1  /* No Identifiers -- use string */
95 #define LOPT_STRING 0x2    /* Force scan for string */
96 #define LOPT_NO_EXTERN 0x4 /* Don't follow @ command */
97 
98 class Bpipe; /* forward reference */
99 
100 /* Lexical context */
101 typedef struct s_lex_context {
102   struct s_lex_context* next; /* pointer to next lexical context */
103   int options;                /* scan options */
104   char* fname;                /* filename */
105   FILE* fd;                   /* file descriptor */
106   POOLMEM* line;              /* input line */
107   POOLMEM* str;               /* string being scanned */
108   int str_len;                /* length of string */
109   int str_max_len;            /* maximum length of string */
110   int line_no;                /* file line number */
111   int col_no;                 /* char position on line */
112   int begin_line_no;          /* line no of beginning of string */
113   enum lex_state state;       /* lex_state variable */
114   int ch;                     /* last char/L_VAL returned by get_char */
115   int token;
116   union {
117     uint16_t pint16_val;
118     uint32_t pint32_val;
119     uint64_t pint64_val;
120     int16_t int16_val;
121     int32_t int32_val;
122     int64_t int64_val;
123   } u;
124   union {
125     uint16_t pint16_val;
126     uint32_t pint32_val;
127     uint64_t pint64_val;
128   } u2;
129   void (*ScanError)(const char* file,
130                     int line,
131                     struct s_lex_context* lc,
132                     const char* msg,
133                     ...);
134   void (*scan_warning)(const char* file,
135                        int line,
136                        struct s_lex_context* lc,
137                        const char* msg,
138                        ...);
139   int err_type; /* message level for ScanError (M_..) */
140   int error_counter;
141   void* caller_ctx; /* caller private data */
142   Bpipe* bpipe;     /* set if we are piping */
143 } LEX;
144 
145 typedef void(LEX_ERROR_HANDLER)(const char* file,
146                                 int line,
147                                 LEX* lc,
148                                 const char* msg,
149                                 ...);
150 typedef void(LEX_WARNING_HANDLER)(const char* file,
151                                   int line,
152                                   LEX* lc,
153                                   const char* msg,
154                                   ...);
155 
156 /**
157  * Lexical scanning errors in parsing conf files
158  */
159 #define scan_err0(lc, msg) lc->ScanError(__FILE__, __LINE__, lc, msg)
160 #define scan_err1(lc, msg, a1) lc->ScanError(__FILE__, __LINE__, lc, msg, a1)
161 #define scan_err2(lc, msg, a1, a2) \
162   lc->ScanError(__FILE__, __LINE__, lc, msg, a1, a2)
163 #define scan_err3(lc, msg, a1, a2, a3) \
164   lc->ScanError(__FILE__, __LINE__, lc, msg, a1, a2, a3)
165 #define scan_err4(lc, msg, a1, a2, a3, a4) \
166   lc->ScanError(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4)
167 #define scan_err5(lc, msg, a1, a2, a3, a4, a5) \
168   lc->ScanError(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4, a5)
169 #define scan_err6(lc, msg, a1, a2, a3, a4, a5, a6) \
170   lc->ScanError(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4, a5, a6)
171 
172 /**
173  * Lexical scanning warnings in parsing conf files
174  */
175 #define scan_warn0(lc, msg) lc->scan_warning(__FILE__, __LINE__, lc, msg)
176 #define scan_warn1(lc, msg, a1) \
177   lc->scan_warning(__FILE__, __LINE__, lc, msg, a1)
178 #define scan_warn2(lc, msg, a1, a2) \
179   lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2)
180 #define scan_warn3(lc, msg, a1, a2, a3) \
181   lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2, a3)
182 #define scan_warn4(lc, msg, a1, a2, a3, a4) \
183   lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4)
184 #define scan_warn5(lc, msg, a1, a2, a3, a4, a5) \
185   lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4, a5)
186 #define scan_warn6(lc, msg, a1, a2, a3, a4, a5, a6) \
187   lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4, a5, a6)
188 
189 void ScanToEol(LEX* lc);
190 int ScanToNextNotEol(LEX* lc);
191 
192 LEX* LexCloseFile(LEX* lf);
193 LEX* lex_open_file(LEX* lf,
194                    const char* fname,
195                    LEX_ERROR_HANDLER* ScanError,
196                    LEX_WARNING_HANDLER* scan_warning);
197 LEX* lex_new_buffer(LEX* lf,
198                     LEX_ERROR_HANDLER* ScanError,
199                     LEX_WARNING_HANDLER* scan_warning);
200 int LexGetChar(LEX* lf);
201 void LexUngetChar(LEX* lf);
202 const char* lex_tok_to_str(int token);
203 int LexGetToken(LEX* lf, int expect);
204 void LexSetDefaultErrorHandler(LEX* lf);
205 void LexSetDefaultWarningHandler(LEX* lf);
206 void LexSetErrorHandlerErrorType(LEX* lf, int err_type);
207 
208 #endif /* BAREOS_LIB_LEX_H_ */
209