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