2d52a9919c7e367d8b9d41bbb44463db0fd93b54
[openafs.git] / src / package / test_gram.y
1 %{
2
3 /*
4  * Copyright (C) 1990 Transarc Corporation
5  * Licensed Materials - Property of Transarc
6  * All Rights Reserved
7  *
8  * test_gram.y:
9  *      Special test version of the grammar defining the set of
10  *      things recognized by package, the AFS workstation config-
11  *      uration facility.
12  */
13
14 #include <afs/param.h>
15 #include <sys/param.h>
16 #include <stdio.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)
20 #include <sys/mkdev.h>
21 #endif
22 #ifdef AFS_LINUX20_ENV
23 #include <sys/sysmacros.h>
24 #endif
25 #include "globals.h"
26 #include "package.h"
27
28
29 char *emalloc();
30
31 #if defined(AFS_AIX41_ENV) || defined(AFS_LINUX20_ENV)
32 int test_linecounter;   /*Line number currently being parsed*/
33
34 char *ch2str();
35 char *appendchtostr();
36 #endif /* AFS_AIX41_ENV */ 
37
38 %}
39
40 %union
41 {
42   afs_uint32 usval;
43   int ival;
44   char chval;
45   char *strval;
46   PROTOTYPE protoval;
47   OWNER ownval;
48   MODE modeval;
49 }
50
51 %token WHITESPACE
52 %token COMMENT
53 %token NEWLINE
54 %token BLANKLINE
55 %token REGTYPE
56 %token DIRTYPE
57 %token LNKTYPE
58 %token BLKTYPE
59 %token CHRTYPE
60 %token SOCKTYPE
61 %token PIPETYPE
62 %token <chval> LETTER
63 %token <strval> PATHNAME
64 %token <usval> DIGIT
65 %type <ival> input
66 %type <ival> entry
67 %type <usval> filetype
68 %type <usval> devicetype
69 %type <usval> updatespecs
70 %type <usval> updateflag
71 %type <strval> filename
72 %type <protoval> devprototype
73 %type <protoval> fileprototype
74 %type <ival> devmajor
75 %type <ival> devminor
76 %type <usval> number
77 %type <ownval> ownershipinfo
78 %type <strval> username
79 %type <strval> groupname
80 %type <strval> name
81 %type <modeval> mode
82 %type <usval> octalnumber
83
84
85 %%      /* rules */
86
87 input   :       /* empty */
88                         { $$ = InitializeConfigTree();
89                           test_linecounter = 1; }
90         |       input entry
91                         { $$ = ($1 == 0)? $2 : $1; }
92         ;
93
94 entry   :       COMMENT NEWLINE
95                         { $$ = 0; test_linecounter++; }
96         |       BLANKLINE
97                         { $$ = 0; test_linecounter++; }
98         |       devicetype      /*Specifies type of device to be updated
99                                   - block/char*/
100                 updatespecs     /*Specifies actions during update, if
101                                   necessary*/
102                 filename        /*Name of device being updated*/
103                 devprototype    /*Device numbers for device being updated*/
104                 ownershipinfo   /*Ownership info for device being updated*/
105                 mode            /*Protection bits for file being updated*/
106                 NEWLINE
107                         {
108                           $$ = testAddEntry($1, $2, $3, $4, $5, $6);
109                                 /*Args -
110                                    filetype,
111                                    updatespecs,
112                                    filename,
113                                    devprototype,
114                                    ownershipinfo,
115                                    mode*/
116                           ReleaseEntry($3, $4, $5);
117                           test_linecounter++;
118                         }
119
120         |       filetype        /*Specifies type of file to be updated;
121                                   e.g. regular file, directory, special
122                                   file*/
123                 updatespecs     /*Specifies actions during update, if
124                                   necessary*/
125                 filename        /*Name of file being updated*/
126                 fileprototype   /*Prototype for file being updated, if
127                                   necessary - e.g., directory prefix,
128                                   master copy, device numbers etc.*/
129                 ownershipinfo   /*Ownership info for file being updated,
130                                   should default to info from prototype*/
131                 mode            /*Protection bits for file being updated;
132                                   should default to info from prototype*/
133                 NEWLINE
134                         {
135                           $$ = testAddEntry($1, $2, $3, $4, $5, $6);
136                           /*Args -
137                              filetype,
138                              updatespecs,
139                              filename,
140                              fileprototype,
141                              ownershipinfo,
142                              mode*/
143                           ReleaseEntry($3, $4, $5);
144                           test_linecounter++;
145                         }
146         ;
147
148 devicetype:     BLKTYPE         /*Block device*/
149                         { $$ = S_IFBLK; }
150         |       CHRTYPE         /*Character device*/
151                         { $$ = S_IFCHR; }
152         |       PIPETYPE        /*Named pipe*/
153                         {
154 #ifdef S_IFIFO
155                           $$ = S_IFIFO;
156 #endif /* S_IFIFO */
157                         }
158         ;
159
160 filetype:       REGTYPE         /*Regular file*/
161                         { $$ = S_IFREG; }
162         |       DIRTYPE         /*Directory*/
163                         { $$ = S_IFDIR; }
164         |       LNKTYPE /* symbolic link */
165                         { $$ =S_IFLNK ; }
166         |       SOCKTYPE
167                         {
168 #ifndef AFS_AIX_ENV
169                           $$ = S_IFSOCK;
170 #endif /* AFS_AIX_ENV */
171                         }
172         ;
173
174
175 updatespecs :   /*empty */
176                         { $$ = 0; }
177         |       /*empty */ WHITESPACE
178                         { $$ = 0; }
179         |       updatespecs updateflag
180                         { $$ = $1 | $2; }
181         |       updatespecs updateflag WHITESPACE
182                         { $$ = $1 | $2; }
183         ;
184
185
186 /*
187  * Throw this out later
188  */
189 updateflag:     LETTER
190                         {
191                           switch(yylval.chval)
192                             {
193                               case 'X':
194                                 /*Make this a lost+found directory*/
195                                 $$ = U_LOSTFOUND;
196                                 break;
197
198                               case 'R':
199                                 /*Extra files not configured to be removed*/
200                                 $$ = U_RMEXTRA;
201                                 break;
202
203                               case 'I':
204                                 /*Update only if file not present*/
205                                 $$ = U_NOOVERWRITE;
206                                 break;
207
208                               case 'O':
209                                 /*Rename old copy with a suffix of .old*/
210                                 $$ = U_RENAMEOLD;
211                                 break;
212
213                               case 'A':
214                                 /*Prototype specifies an absolute path
215                                   rather than the prefix*/
216                                 $$ = U_ABSPATH;
217                                 break;
218
219                               case 'Q':
220                                 /*Exit with status=4 if file is updated,
221                                   indicating that a reboot is needed*/
222                                 $$ = U_REBOOT;
223                                 break;
224                             }
225                         }
226         ;
227
228
229 filename        :       PATHNAME        /*Pathname of the file to be
230                                           updated, may not have white-
231                                           space if at eol*/
232                         { $$ = $1; }
233         |       PATHNAME WHITESPACE     /*Pathname of the file to be
234                                           updated*/
235                         { $$ = $1; }
236         ;
237
238 fileprototype:  /* empty */
239                         { $$.flag = P_NONE; }
240         |       filename        /*Pathname of prototype file or directory
241                                   prefix*/
242                         { $$.flag = P_FILE; $$.info.path = $1; }
243         ;
244
245 devprototype:   devmajor WHITESPACE devminor    /*Major & minor device
246                                                   numbers*/
247                         { $$.flag = P_DEV; $$.info.rdev = makedev($1, $3); }
248                         
249         ;
250
251 devmajor        :       number
252                         {
253                           if ((0 > $1) || ($1 > 255))
254                             fatal("%d; invalid device number", $1);
255                           $$ = $1;
256                         }
257         ;
258
259 devminor        :       number
260                         {
261                           if ((0 > $1) || ($1 > 255))
262                             fatal("%d; invalid device number", $1);
263                           $$ = $1;
264                         }
265         |       number WHITESPACE
266                         {
267                           if ((0 > $1) || ($1 > 255))
268                             fatal("%d; invalid device number", $1);
269                           $$ = $1;
270                         }
271         ;
272
273 number  :       DIGIT
274                         { $$ = $1;
275                           dbgprint((stderr, "digit %u\n", $$));
276                         }
277         |       number DIGIT
278                         { $$ = 10 * $1 + $2;
279                           dbgprint((stderr, "10 * %u + %u = %u\n", $1,$2,$$));
280                         }
281         ;
282
283 ownershipinfo:  /* empty */
284                         { $$.username = NULL; $$.groupname = NULL; }
285         |       username groupname
286                         { $$.username = $1; $$.groupname = $2; }
287         ;
288
289 username:       name
290                         { $$ = $1; }
291         |       name WHITESPACE
292                         { $$ = $1; }
293         ;
294
295 groupname:      /* empty */
296                         {$$ = NULL; }
297         |       name
298                         { $$ = $1; }
299         |       name WHITESPACE
300                         { $$ = $1; }
301         ;
302
303 name    :       LETTER
304                         { $$ = ch2str(yylval.chval);  }
305 /*      |       DIGIT
306                         { $$ = ch2str('0'+$1);  } */
307         |       name LETTER
308                         { $$ = appendchtostr($1, $2);  }
309         |       name DIGIT
310                         { $$ = appendchtostr($1, '0'+$2);  }
311         ;
312
313 mode    :       /* empty */
314                         { $$.inherit_flag = TRUE; }
315         |       COMMENT
316                         { $$.inherit_flag = TRUE; }
317         |       octalnumber     /*Last field of entry, may not have
318                                   anything before newline*/
319                         { $$.inherit_flag = FALSE; $$.modeval = (afs_uint32)$1; }
320         |       octalnumber WHITESPACE  /*Last field of entry, but may have
321                                           some whitespace before newline*/
322                         { $$.inherit_flag = FALSE; $$.modeval = (afs_uint32)$1; }
323         |       octalnumber COMMENT     /*Last field of entry, but may have
324                                           a comment before newline*/
325                         { $$.inherit_flag = FALSE; $$.modeval = (afs_uint32)$1; }
326         |       octalnumber WHITESPACE COMMENT  /*Last field of entry, but
327                                                   may have some whitespace
328                                                   and a comment before the
329                                                   newline*/
330                         { $$.inherit_flag = FALSE; $$.modeval = (afs_uint32)$1; }
331         ;
332
333 octalnumber:    DIGIT
334                         { $$ = $1;
335                           dbgprint((stderr, "digit %u\n", $$));
336                         }
337         |       octalnumber DIGIT
338                         { $$ = 8 * $1 + $2;
339                           dbgprint((stderr, "8 * %u + %u = %u\n", $1,$2, $$));
340                         }
341         ;
342
343
344 %%
345
346 #ifndef AFS_AIX41_ENV
347 int test_linecounter;   /*Line number currently being parsed*/
348 #endif /* !AFS_AIX41_ENV */
349
350 char *ch2str(c)
351     char c;
352 /*
353  * Returns the pointer to a string consisting of the character c
354  * terminated by \0.
355  */
356 {
357   char *s;
358   s = (char *)emalloc(2);
359   sprintf(s, "%c", c);
360   return(s);
361 }
362
363 char *appendchtostr(s, c)
364     char c, *s;
365 /*
366  * Returns the pointer to a NULL terminated string containing the
367  * character c appended to the contents of the string s
368  */
369 {
370   char *str;
371   str = (char *)emalloc((unsigned)(strlen(s) + 2));
372   sprintf(str, "%s%c", s, c);
373   free(s);
374   return(str);
375 }
376
377 ReleaseEntry(f, p, o)
378     char *f;
379     PROTOTYPE p;
380     OWNER o;
381 /*
382  * Release storage allocated for various data structures during the
383  * parsing of an entry.
384  */
385 {
386   if (f != NULL) free(f);
387   if ((p.flag == P_FILE) && (p.info.path != NULL)) free(p.info.path);
388   if (o.username != NULL) free(o.username);
389   if (o.groupname != NULL) free(o.groupname);
390 }