3 * $Id: fattr.c,v 1.1 1999/07/26 23:33:56 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.1 1999/07/26 23:33:56 mdw
33 * Support code for new design.
37 /*----- Header files ------------------------------------------------------*/
47 #include <sys/types.h>
58 /*----- Global variables --------------------------------------------------*/
62 /*----- Main code ---------------------------------------------------------*/
64 /* --- @fattr_init@ --- *
66 * Arguments: @fattr *f@ = pointer to file attributes
70 * Use: Initializes a set of file attributes to default values.
73 void fattr_init(fattr *f)
75 unsigned um = umask(0);
82 /* --- @fattr_option@ --- *
84 * Arguments: @scanner *sc@ = pointer to scanner to read
85 * @fattr *f@ = pointer to file attributes to set
87 * Returns: Whether the option was claimed.
89 * Use: Reads file attributes from a scanner.
92 int fattr_option(scanner *sc, fattr *f)
94 CONF_BEGIN(sc, "fattr", "file attribute")
96 /* --- Read a file mode specification --- */
98 if (strcmp(sc->d.buf, "mode") == 0) {
101 /* --- Gobble an optional `=' sign --- */
107 if (sc->t != CTOK_WORD)
108 error(sc, "parse error, expected file mode");
110 /* --- If it looks digitlike, read as octal --- */
112 if (isdigit((unsigned char)*sc->d.buf))
113 mode = strtoul(sc->d.buf, 0, 8) & 07777;
115 /* --- Otherise read as chmod-like characters --- */
119 unsigned mask = 07777;
122 /* --- Set the default from the umask --- */
125 unsigned um = umask(0);
130 /* --- Parse the characters --- *
132 * This is a particularly lenient implementation of the usual chmod-
133 * style mode language.
136 for (p = sc->d.buf; *p; p++) {
140 case 'a': mask = 07777; break;
141 case 'u': mask = 04700; break;
142 case 'g': mask = 02070; break;
143 case 'o': mask = 01007; break;
145 case '=': mode &= ~mask; break;
146 case '-': or = 0; break;
147 case '+': or = 1; break;
149 #define APPLY(m) if (or) mode |= ((m) & mask); else mode &= ~((m) & mask);
150 case 'r': APPLY(00444); break;
151 case 'w': APPLY(00222); break;
152 case 'x': APPLY(00111); break;
153 case 's': APPLY(06000); break;
154 case 't': APPLY(01000); break;
157 default: error(sc, "unknown mode character `%c'", *p);
167 /* --- Read a file uid specification --- */
169 if (strcmp(sc->d.buf, "uid") == 0 ||
170 strcmp(sc->d.buf, "user") == 0 ||
171 strcmp(sc->d.buf, "owner") == 0) {
175 if (sc->t != CTOK_WORD)
176 error(sc, "parse error, expected user name or uid");
177 if (isdigit((unsigned char)*sc->d.buf))
178 f->uid = atoi(sc->d.buf);
180 struct passwd *pw = getpwnam(sc->d.buf);
182 error(sc, "unknown user name `%s'", sc->d.buf);
189 /* --- Read a file gid specification --- */
191 if (strcmp(sc->d.buf, "gid") == 0 ||
192 strcmp(sc->d.buf, "group") == 0) {
196 if (sc->t != CTOK_WORD)
197 error(sc, "parse error, expected group name or gid");
198 if (isdigit((unsigned char)*sc->d.buf))
199 f->gid = atoi(sc->d.buf);
201 struct group *gr = getgrnam(sc->d.buf);
203 error(sc, "unknown user name `%s'", sc->d.buf);
210 /* --- Nothing here for me --- */
215 /* --- @fattr_apply@ --- *
217 * Arguments: @const char *file@ = pointer to filename
218 * @fattr *f@ = pointer to attribute set
220 * Returns: @-1@ if it failed.
222 * Use: Applies file attributes to a file. For best results, try to
223 * create the file with the right permissions and so on. This
224 * call will fix everything up, but there are potential races
225 * which might catch you out if you're not careful.
228 int fattr_apply(const char *file, fattr *f)
230 if (chown(file, f->uid, f->gid) == -1 ||
231 chmod(file, f->mode) == -1)
236 /*----- That's all, folks -------------------------------------------------*/