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