ReactOS  0.4.14-dev-358-gbef841c
checkerr.c
Go to the documentation of this file.
1 /* @(#)checkerr.c 1.24 09/07/08 Copyright 2003-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5  "@(#)checkerr.c 1.24 09/07/08 Copyright 2003-2009 J. Schilling";
6 #endif
7 /*
8  * Generic error control for programs that do file i/o.
9  * The error control is usually used by archiving programs.
10  *
11  * The current version does not provide a stable interface.
12  * It does not support multi-threaded programs and it may call
13  * comerr() from the parser. If you use the code before there is
14  * an official stable and "library-compliant" interface, be careful
15  * and watch for changes.
16  *
17  * Copyright (c) 2003-2009 J. Schilling
18  */
19 /*
20  * The contents of this file are subject to the terms of the
21  * Common Development and Distribution License, Version 1.0 only
22  * (the "License"). You may not use this file except in compliance
23  * with the License.
24  *
25  * See the file CDDL.Schily.txt in this distribution for details.
26  *
27  * When distributing Covered Code, include this CDDL HEADER in each
28  * file and include the License file CDDL.Schily.txt from this distribution.
29  */
30 
31 #include <schily/stdio.h>
32 #include <schily/standard.h>
33 #include <schily/patmatch.h>
34 #include <schily/string.h>
35 #include <schily/utypes.h>
36 #include <schily/schily.h>
37 #include <schily/checkerr.h>
38 
39 typedef struct errconf {
40  struct errconf *ec_next; /* Next in list */
41  const Uchar *ec_pat; /* File name pattern */
42  int *ec_aux; /* Aux array from pattern compiler */
43  int ec_alt; /* Alt return from pattern compiler */
44  int ec_plen; /* String length of pattern */
45  UInt32_t ec_flags; /* Error condition flags */
46 } ec_t;
47 
48 LOCAL int *ec_state; /* State array for pattern compiler */
49 LOCAL ec_t *ec_root; /* Root node of error config list */
50 LOCAL ec_t **ec_last = &ec_root; /* Last pointer in root node list */
52 LOCAL BOOL _errflag = TRUE; /* Abort on all errors */
53 
54 EXPORT int errconfig __PR((char *name));
55 LOCAL char *_endword __PR((char *p));
56 LOCAL void parse_errctl __PR((char *line));
57 LOCAL UInt32_t errflags __PR((char *eflag, BOOL doexit));
58 LOCAL ec_t *_errptr __PR((int etype, const char *fname));
59 EXPORT BOOL errhidden __PR((int etype, const char *fname));
60 EXPORT BOOL errwarnonly __PR((int etype, const char *fname));
61 EXPORT BOOL errabort __PR((int etype, const char *fname, BOOL doexit));
62 
63 /*
64  * Read and parse error configuration file
65  */
66 EXPORT int
68  char *name;
69 {
70  char line[8192];
71  FILE *f;
72  int omaxplen = maxplen;
73 
74  if ((f = fileopen(name, "r")) == NULL) {
75  if (errflags(name, FALSE) != 0)
77  else
78  comerr("Cannot open '%s'.\n", name);
79  } else {
80  while (fgetline(f, line, sizeof (line)) >= 0) {
82  }
83  fclose(f);
84  }
85  if (maxplen > omaxplen) {
86  ec_state = ___realloc(ec_state, (maxplen+1)*sizeof (int),
87  "pattern state");
88  }
89  return (1);
90 }
91 
92 LOCAL char *
94  char *p;
95 {
96  /*
97  * Find end of word.
98  */
99  for (; *p != '\0' &&
100  *p != '\t' &&
101  *p != ' ';
102  p++) {
103  ;
104  /* LINTED */
105  }
106  return (p);
107 }
108 
109 LOCAL void
111  char *line;
112 {
113  int plen;
114  char *pattern;
115  ec_t *ep;
116 
117  /*
118  * Find end of word.
119  */
120  pattern = _endword(line);
121 
122  if (pattern == line || *pattern == '\0') {
124  "Bad error configuration line '%s'.\n", line);
125  }
126  /*
127  * Find end of white space after word.
128  */
129  for (pattern++; *pattern != '\0' &&
130  (*pattern == '\t' || *pattern == ' ');
131  pattern++) {
132  ;
133  /* LINTED */
134  }
135  ep = ___malloc(sizeof (ec_t), "errcheck node");
136  ep->ec_flags = errflags(line, TRUE);
137  ep->ec_plen = plen = strlen(pattern);
138  if (ep->ec_plen > maxplen)
139  maxplen = ep->ec_plen;
140  ep->ec_pat = (const Uchar *)___savestr(pattern);
141  ep->ec_aux = ___malloc(plen*sizeof (int), "compiled pattern");
142  if ((ep->ec_alt = patcompile((const Uchar *)pattern,
143  plen, ep->ec_aux)) == 0)
144  comerrno(EX_BAD, "Bad errctl pattern: '%s'.\n", pattern);
145 
146  ep->ec_next = NULL;
147  *ec_last = ep;
148  ec_last = &ep->ec_next;
149 }
150 
151 LOCAL struct eflags {
152  char *fname;
153  UInt32_t fval;
154 } eflags[] = {
155  { "STAT", E_STAT },
156  { "GETACL", E_GETACL },
157  { "OPEN", E_OPEN },
158  { "READ", E_READ },
159  { "WRITE", E_WRITE },
160  { "GROW", E_GROW },
161  { "SHRINK", E_SHRINK },
162  { "MISSLINK", E_MISSLINK },
163  { "NAMETOOLONG", E_NAMETOOLONG },
164  { "FILETOOBIG", E_FILETOOBIG },
165  { "SPECIALFILE", E_SPECIALFILE },
166  { "READLINK", E_READLINK },
167  { "GETXATTR", E_GETXATTR },
168  { "CHDIR", E_CHDIR },
169 
170  { "SETTIME", E_SETTIME },
171  { "SETMODE", E_SETMODE },
172  { "SECURITY", E_SECURITY },
173  { "LSECURITY", E_LSECURITY },
174  { "SAMEFILE", E_SAMEFILE },
175  { "BADACL", E_BADACL },
176  { "SETACL", E_SETACL },
177  { "SETXATTR", E_SETXATTR },
178 
179  { "ALL", E_ALL },
180 
181  { "DIFF", E_DIFF },
182  { "WARN", E_WARN },
183  { "ABORT", E_ABORT },
184 
185  { NULL, 0 }
186 };
187 
188 /*
189  * Convert error condition string into flag word
190  */
191 LOCAL UInt32_t
192 errflags(eflag, doexit)
193  char *eflag;
194  BOOL doexit;
195 {
196  register char *p = eflag;
197  char *ef = _endword(eflag);
198  register struct eflags *ep;
199  register int slen;
200  register UInt32_t nflags = 0;
201 
202  do {
203  for (ep = eflags; ep->fname; ep++) {
204  slen = strlen(ep->fname);
205  if ((strncmp(ep->fname, p, slen) == 0) &&
206  (p[slen] == '|' || p[slen] == ' ' ||
207  p[slen] == '\0')) {
208  nflags |= ep->fval;
209  break;
210  }
211  }
212  if (ep->fname == NULL) {
213  if (doexit)
214  comerrno(EX_BAD, "Bad flag '%s'\n", p);
215  return (0);
216  }
217  p = strchr(p, '|');
218  } while (p < ef && p && *p++ == '|');
219 
220  if ((nflags & ~(UInt32_t)(E_ABORT|E_WARN)) == 0) {
221  if (doexit)
222  comerrno(EX_BAD, "Bad error condition '%s'.\n", eflag);
223  return (0);
224  }
225  return (nflags);
226 }
227 
228 LOCAL ec_t *
229 _errptr(etype, fname)
230  int etype;
231  const char *fname;
232 {
233  ec_t *ep = ec_root;
234  char *ret;
235  const Uchar *name = (const Uchar *)fname;
236  int nlen;
237 
238  if (fname == NULL) {
240  "Implementation botch for errhidden(0x%X, NULL)\n",
241  etype);
242  errmsgno(EX_BAD, "Please report this bug!\n");
243  errmsgno(EX_BAD, "Error cannot be ignored.\n");
244  return ((ec_t *)NULL);
245  }
246  nlen = strlen(fname);
247  while (ep) {
248  if ((ep->ec_flags & etype) != 0) {
249  ret = (char *)patmatch(ep->ec_pat, ep->ec_aux,
250  name, 0,
251  nlen, ep->ec_alt, ec_state);
252  if (ret != NULL && *ret == '\0')
253  return (ep);
254  }
255  ep = ep->ec_next;
256  }
257  return ((ec_t *)NULL);
258 }
259 
260 /*
261  * Check whether error condition should be ignored for file name.
262  */
263 EXPORT BOOL
265  int etype;
266  const char *fname;
267 {
268  ec_t *ep;
269 
270  if ((ep = _errptr(etype, fname)) != NULL) {
271  if ((ep->ec_flags & (E_ABORT|E_WARN)) != 0)
272  return (FALSE);
273  return (TRUE);
274  }
275  return (FALSE);
276 }
277 
278 /*
279  * Check whether error condition should not affect exit code for file name.
280  */
281 EXPORT BOOL
283  int etype;
284  const char *fname;
285 {
286  ec_t *ep;
287 
288  if ((ep = _errptr(etype, fname)) != NULL) {
289  if ((ep->ec_flags & E_WARN) != 0)
290  return (TRUE);
291  return (FALSE);
292  }
293  return (FALSE);
294 }
295 
296 /*
297  * Check whether error condition should be fatal for file name.
298  */
299 EXPORT BOOL
300 errabort(etype, fname, doexit)
301  int etype;
302  const char *fname;
303  BOOL doexit;
304 {
305  ec_t *ep;
306 
307  if ((ep = _errptr(etype, fname)) == NULL) {
308  if (!_errflag)
309  return (FALSE);
310  } else if ((ep->ec_flags & E_ABORT) == 0)
311  return (FALSE);
312 
313  if (doexit) {
314  errmsgno(EX_BAD, "Error is considered fatal, aborting.\n");
315 #ifdef CALL_OTHER_FUNCTION
316  if (other_func != NULL)
317  (*other_func)();
318  else
319 #endif
320  comexit(-3);
321  }
322  return (TRUE);
323 }
#define E_MISSLINK
Definition: checkerr.h:53
#define E_SECURITY
Definition: checkerr.h:67
#define E_SETACL
Definition: checkerr.h:71
EXPORT void * ___malloc(size_t size, char *msg)
Definition: mem.c:53
#define TRUE
Definition: types.h:120
EXPORT void comerr(char *msg, va_alist)
Definition: comerr.c:84
#define E_NAMETOOLONG
Definition: checkerr.h:54
unsigned char Uchar
Definition: utypes.h:45
EXPORT FILE * fileopen(char *name, const char *mode) const
Definition: fileopen.c:20
int * ec_aux
Definition: checkerr.c:42
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define E_WARN
Definition: checkerr.h:79
struct errconf * ec_next
Definition: checkerr.c:40
EXPORT int errconfig __PR((char *name))
#define E_GROW
Definition: checkerr.h:51
#define UConst
Definition: ccomdefs.h:72
EXPORT CHAR * patmatch(PCHAR *pat, const int *aux, const CHAR *str, int soff, int slen, int alt, state) const
Definition: match.c:230
UInt32_t ec_flags
Definition: checkerr.c:45
#define E_CHDIR
Definition: checkerr.h:59
struct errconf ec_t
EXPORT char * ___savestr(char *s) const
Definition: mem.c:97
#define E_GETXATTR
Definition: checkerr.h:58
#define E_READLINK
Definition: checkerr.h:57
LOCAL UInt32_t errflags(char *eflag, BOOL doexit)
Definition: checkerr.c:192
#define E_SPECIALFILE
Definition: checkerr.h:56
#define E_SAMEFILE
Definition: checkerr.h:69
#define E_STAT
Definition: checkerr.h:46
LOCAL void parse_errctl(char *line)
Definition: checkerr.c:110
unsigned int BOOL
Definition: ntddk_ex.h:94
#define E_LSECURITY
Definition: checkerr.h:68
LOCAL BOOL _errflag
Definition: checkerr.c:52
char * fname
Definition: checkerr.c:152
#define E_FILETOOBIG
Definition: checkerr.h:55
smooth NULL
Definition: ftsmooth.c:416
#define E_SETMODE
Definition: checkerr.h:66
LOCAL int maxplen
Definition: checkerr.c:51
Definition: parser.c:48
EXPORT int patcompile(PCHAR *pat, int len, int *aux) const
Definition: match.c:584
#define LOCAL(type)
Definition: jmorecfg.h:289
EXPORT int errconfig(char *name)
Definition: checkerr.c:67
GLfloat f
Definition: glext.h:7540
LOCAL int * ec_state
Definition: checkerr.c:48
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
int ec_plen
Definition: checkerr.c:44
#define E_ALL
Definition: checkerr.h:83
#define E_SHRINK
Definition: checkerr.h:52
int ret
char line[200]
Definition: main.c:97
LOCAL ec_t * ec_root
Definition: checkerr.c:49
EXPORT BOOL errabort(int etype, const char *fname, BOOL doexit)
Definition: checkerr.c:300
#define E_OPEN
Definition: checkerr.h:48
LOCAL ec_t ** ec_last
Definition: checkerr.c:50
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define E_GETACL
Definition: checkerr.h:47
#define E_ABORT
Definition: winerror.h:2366
#define E_DIFF
Definition: checkerr.h:78
EXPORT BOOL errhidden(int etype, const char *fname)
Definition: checkerr.c:264
EXPORT void comexit(int err)
Definition: comerr.c:331
UInt32_t fval
Definition: checkerr.c:153
EXPORT BOOL errwarnonly(int etype, const char *fname)
Definition: checkerr.c:282
#define f
Definition: ke_i.h:83
#define E_READ
Definition: checkerr.h:49
#define E_BADACL
Definition: checkerr.h:70
EXPORT void comerrno(int err, char *msg, va_alist)
Definition: comerr.c:137
char * strchr(const char *String, int ch)
Definition: utclib.c:501
int ec_alt
Definition: checkerr.c:43
Definition: name.c:36
const Uchar * ec_pat
Definition: checkerr.c:41
#define E_SETTIME
Definition: checkerr.h:65
EXPORT void * ___realloc(void *ptr, size_t size, char *msg)
Definition: mem.c:73
static UConst char sccsid[]
Definition: checkerr.c:4
GLfloat GLfloat p
Definition: glext.h:8902
EXPORT int fgetline(FILE *f, char *buf, int len)
Definition: fgetline.c:47
LOCAL char * _endword(char *p)
Definition: checkerr.c:93
#define E_SETXATTR
Definition: checkerr.h:72
LOCAL ec_t * _errptr(int etype, const char *fname)
Definition: checkerr.c:229
GLubyte * pattern
Definition: glext.h:7787
#define E_WRITE
Definition: checkerr.h:50
EXPORT int errmsgno(int err, char *msg, va_alist)
Definition: comerr.c:219
#define EX_BAD
Definition: standard.h:62
GLuint const GLchar * name
Definition: glext.h:6031