3 * $Id: fattr.c,v 1.3 2002/01/13 14:50:22 mdw Exp $
5 * Handling of file attributes
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of the `fw' port forwarder.
14 * `fw' is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * `fw' is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with `fw'; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.3 2002/01/13 14:50:22 mdw
33 * Delimiter-setting function names change.
35 * Revision 1.2 1999/08/19 18:32:48 mdw
36 * Improve lexical analysis. In particular, `chmod' patterns don't have to
39 * Revision 1.1 1999/07/26 23:33:56 mdw
40 * Support code for new design.
44 /*----- Header files ------------------------------------------------------*/
54 #include <sys/types.h>
65 /*----- Global variables --------------------------------------------------*/
69 /*----- Main code ---------------------------------------------------------*/
71 /* --- @fattr_init@ --- *
73 * Arguments: @fattr *f@ = pointer to file attributes
77 * Use: Initializes a set of file attributes to default values.
80 void fattr_init(fattr
*f
)
82 unsigned um
= umask(0);
89 /* --- @fattr_option@ --- *
91 * Arguments: @scanner *sc@ = pointer to scanner to read
92 * @fattr *f@ = pointer to file attributes to set
94 * Returns: Whether the option was claimed.
96 * Use: Reads file attributes from a scanner.
99 int fattr_option(scanner
*sc
, fattr
*f
)
101 CONF_BEGIN(sc
, "fattr", "file attribute")
103 /* --- Read a file mode specification --- */
105 if (strcmp(sc
->d
.buf
, "mode") == 0) {
108 /* --- Gobble an optional `=' sign --- */
110 conf_undelim(sc
, 0, ",=+-");
115 if (sc
->t
!= CTOK_WORD
)
116 error(sc
, "parse error, expected file mode");
117 conf_undelim(sc
, 0, 0);
119 /* --- If it looks digitlike, read as octal --- */
121 if (isdigit((unsigned char)*sc
->d
.buf
))
122 mode
= strtoul(sc
->d
.buf
, 0, 8) & 07777;
124 /* --- Otherise read as chmod-like characters --- */
128 unsigned mask
= 04700;
132 /* --- Set the default from the umask --- */
135 unsigned um
= umask(0);
140 /* --- Parse the characters --- *
142 * This is a particularly lenient implementation of the usual chmod-
143 * style mode language.
146 for (p
= sc
->d
.buf
; *p
; p
++) {
150 case 'a': mask
= (mask
& state
) | 07777; state
= 07777; break;
151 case 'u': mask
= (mask
& state
) | 04700; state
= 07777; break;
152 case 'g': mask
= (mask
& state
) | 02070; state
= 07777; break;
153 case 'o': mask
= (mask
& state
) | 01007; state
= 07777; break;
155 case '=': mode
&= ~mask
; /* Drop through */
156 case '+': state
= 0; or = 1; break;
157 case '-': state
= 0; or = 0; break;
159 #define APPLY(m) if (or) mode |= ((m) & mask); else mode &= ~((m) & mask);
160 case 'r': state
= 0; APPLY(00444); break;
161 case 'w': state
= 0; APPLY(00222); break;
162 case 'x': state
= 0; APPLY(00111); break;
163 case 's': state
= 0; APPLY(06000); break;
164 case 't': state
= 0; APPLY(01000); break;
167 default: error(sc
, "unknown mode character `%c'", *p
);
177 /* --- Read a file uid specification --- */
179 if (strcmp(sc
->d
.buf
, "uid") == 0 ||
180 strcmp(sc
->d
.buf
, "user") == 0 ||
181 strcmp(sc
->d
.buf
, "owner") == 0) {
185 if (sc
->t
!= CTOK_WORD
)
186 error(sc
, "parse error, expected user name or uid");
187 if (isdigit((unsigned char)*sc
->d
.buf
))
188 f
->uid
= atoi(sc
->d
.buf
);
190 struct passwd
*pw
= getpwnam(sc
->d
.buf
);
192 error(sc
, "unknown user name `%s'", sc
->d
.buf
);
199 /* --- Read a file gid specification --- */
201 if (strcmp(sc
->d
.buf
, "gid") == 0 ||
202 strcmp(sc
->d
.buf
, "group") == 0) {
206 if (sc
->t
!= CTOK_WORD
)
207 error(sc
, "parse error, expected group name or gid");
208 if (isdigit((unsigned char)*sc
->d
.buf
))
209 f
->gid
= atoi(sc
->d
.buf
);
211 struct group
*gr
= getgrnam(sc
->d
.buf
);
213 error(sc
, "unknown user name `%s'", sc
->d
.buf
);
220 /* --- Nothing here for me --- */
225 /* --- @fattr_apply@ --- *
227 * Arguments: @const char *file@ = pointer to filename
228 * @fattr *f@ = pointer to attribute set
230 * Returns: @-1@ if it failed.
232 * Use: Applies file attributes to a file. For best results, try to
233 * create the file with the right permissions and so on. This
234 * call will fix everything up, but there are potential races
235 * which might catch you out if you're not careful.
238 int fattr_apply(const char *file
, fattr
*f
)
240 if (chown(file
, f
->uid
, f
->gid
) == -1 ||
241 chmod(file
, f
->mode
) == -1)
246 /*----- That's all, folks -------------------------------------------------*/