]>
git.zerfleddert.de Git - micropolis/blob - src/tclx/src/tclxchmd.c
4 * Chmod, chown and chgrp Tcl commands.
5 *-----------------------------------------------------------------------------
6 * Copyright 1992 Karl Lehenbauer and Mark Diekhans.
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose and without fee is hereby granted, provided
10 * that the above copyright notice appear in all copies. Karl Lehenbauer and
11 * Mark Diekhans make no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
14 *-----------------------------------------------------------------------------
15 * $Id: tclXchmod.c,v 2.0 1992/10/16 04:50:26 markd Rel $
16 *-----------------------------------------------------------------------------
22 * Prototypes of internal functions.
25 ConvSymMode
_ANSI_ARGS_((Tcl_Interp
*interp
,
31 *-----------------------------------------------------------------------------
34 * Parse and convert symbolic file permissions as specified by chmod(C).
37 * o interp - Pointer to the current interpreter, error messages will be
38 * returned in the result.
39 * o symMode - The symbolic permissions to parse.
40 * o modeVal - The existing permissions value on a file.
43 * The new permissions, or -1 if invalid permissions where supplied.
45 *-----------------------------------------------------------------------------
48 ConvSymMode (Tcl_Interp
*interp
, char *symMode
, int modeVal
)
51 int user
, group
, other
;
52 char operator, *scanPtr
;
53 int rwxMask
, ugoMask
, setUID
, sticky
, locking
;
58 while (*scanPtr
!= '\0') {
59 user
= group
= other
= FALSE
;
64 while (! ((*scanPtr
== '+') ||
69 user
= group
= other
= TRUE
;
87 * If none where specified, that means all.
90 if (! (user
|| group
|| other
))
91 user
= group
= other
= TRUE
;
93 operator = *scanPtr
++;
96 * Decode the permissions
100 setUID
= sticky
= locking
= FALSE
;
103 * Scan permissions field
105 while (! ((*scanPtr
== ',') || (*scanPtr
== 0))) {
132 * Build mode map of specified values.
138 newMode
|= rwxMask
<< 6;
142 newMode
|= rwxMask
<< 3;
151 if ((setUID
|| locking
) && group
)
157 * Add to cumulative mode based on operator.
162 else if (operator == '-')
164 else if (operator == '=')
165 modeVal
|= (modeVal
& ugoMask
) | newMode
;
173 Tcl_AppendResult (interp
, "invalid file mode \"", symMode
, "\"",
179 *-----------------------------------------------------------------------------
182 * Implements the TCL chmod command:
183 * chmod mode filelist
186 * Standard TCL results, may return the UNIX system error message.
188 *-----------------------------------------------------------------------------
192 ClientData clientData
,
198 int idx
, modeVal
, fileArgc
, absMode
;
200 struct stat fileStat
;
203 Tcl_AppendResult (interp
, tclXWrongArgs
, argv
[0],
204 " mode filelist", (char *) NULL
);
208 if (isdigit (argv
[1][0])) {
209 if (Tcl_GetInt (interp
, argv
[1], &modeVal
) != TCL_OK
)
215 if (Tcl_SplitList (interp
, argv
[2], &fileArgc
, &fileArgv
) != TCL_OK
)
218 for (idx
= 0; idx
< fileArgc
; idx
++) {
220 if (stat (fileArgv
[idx
], &fileStat
) != 0)
222 modeVal
= ConvSymMode (interp
, argv
[1], fileStat
.st_mode
& 07777);
226 if (chmod (fileArgv
[idx
], (unsigned short) modeVal
) < 0)
231 ckfree ((char *) fileArgv
);
236 * Error accessing file, assumes file name is fileArgv [idx].
238 Tcl_AppendResult (interp
, fileArgv
[idx
], ": ", Tcl_UnixError (interp
),
242 ckfree ((char *) fileArgv
);
247 *-----------------------------------------------------------------------------
250 * Implements the TCL chown command:
251 * chown owner filelist
252 * chown {owner group} filelist
255 * Standard TCL results, may return the UNIX system error message.
257 *-----------------------------------------------------------------------------
261 ClientData clientData
,
267 int idx
, ownArgc
, fileArgc
;
268 char **ownArgv
, **fileArgv
= NULL
;
269 struct stat fileStat
;
270 int useOwnerGrp
, chGroup
, ownerId
, groupId
;
271 struct passwd
*passwdPtr
;
272 struct group
*groupPtr
;
273 int result
= TCL_ERROR
;
276 Tcl_AppendResult (interp
, tclXWrongArgs
, argv
[0],
277 " owner|{owner group} filelist", (char *) NULL
);
281 if (Tcl_SplitList (interp
, argv
[1], &ownArgc
, &ownArgv
) != TCL_OK
)
283 if ((ownArgc
< 1) || (ownArgc
> 2)) {
284 interp
->result
= "owner arg should be: owner or {owner group}";
288 useOwnerGrp
= (ownArgv
[1][0] == '\0');
294 * Get the owner id, either convert the name or use it as an integer.
296 passwdPtr
= getpwnam (ownArgv
[0]);
297 if (passwdPtr
!= NULL
)
298 ownerId
= passwdPtr
->pw_uid
;
300 if (!Tcl_StrToInt (ownArgv
[0], 10, &ownerId
)) {
301 Tcl_AppendResult (interp
, "unknown user id: ", ownArgv
[0],
307 * Get the group id, this is either the specified id or name, or the
308 * if associated with the specified user.
312 if (passwdPtr
== NULL
) {
313 passwdPtr
= getpwuid (ownerId
);
314 if (passwdPtr
!= NULL
) {
315 Tcl_AppendResult (interp
, "unknown user id: ",
316 ownArgv
[0], (char *) NULL
);
320 groupId
= passwdPtr
->pw_gid
;
322 groupPtr
= getgrnam (ownArgv
[1]);
323 if (groupPtr
!= NULL
)
324 groupId
= groupPtr
->gr_gid
;
326 if (!Tcl_StrToInt (ownArgv
[1], 10, &groupId
)) {
327 Tcl_AppendResult (interp
, "unknown group id: ",
328 ownArgv
[1], (char *) NULL
);
334 if (Tcl_SplitList (interp
, argv
[2], &fileArgc
, &fileArgv
) != TCL_OK
)
337 for (idx
= 0; idx
< fileArgc
; idx
++) {
339 if (stat (fileArgv
[idx
], &fileStat
) != 0) {
340 Tcl_AppendResult (interp
, fileArgv
[idx
], ": ",
341 Tcl_UnixError (interp
), (char *) NULL
);
344 groupId
= fileStat
.st_gid
;
347 if (chown (fileArgv
[idx
], ownerId
, groupId
) < 0) {
348 Tcl_AppendResult (interp
, fileArgv
[idx
], ": ",
349 Tcl_UnixError (interp
), (char *) NULL
);
353 } /* Modify each file */
357 ckfree ((char *) ownArgv
);
358 if (fileArgv
!= NULL
)
359 ckfree ((char *) fileArgv
);
364 *-----------------------------------------------------------------------------
367 * Implements the TCL chgrp command:
368 * chgrp group filelist
371 * Standard TCL results, may return the UNIX system error message.
373 *-----------------------------------------------------------------------------
377 ClientData clientData
,
383 int idx
, fileArgc
, groupId
, result
= TCL_ERROR
;
385 struct stat fileStat
;
386 struct group
*groupPtr
;
389 Tcl_AppendResult (interp
, tclXWrongArgs
, argv
[0],
390 " group filelist", (char *) NULL
);
394 groupPtr
= getgrnam (argv
[1]);
395 if (groupPtr
!= NULL
)
396 groupId
= groupPtr
->gr_gid
;
398 if (!Tcl_StrToInt (argv
[1], 10, &groupId
)) {
399 Tcl_AppendResult (interp
, "unknown group id: ", argv
[1],
404 if (Tcl_SplitList (interp
, argv
[2], &fileArgc
, &fileArgv
) != TCL_OK
)
407 for (idx
= 0; idx
< fileArgc
; idx
++) {
408 if ((stat (fileArgv
[idx
], &fileStat
) != 0) ||
409 (chown (fileArgv
[idx
], fileStat
.st_uid
, groupId
) < 0)) {
410 Tcl_AppendResult (interp
, fileArgv
[idx
], ": ",
411 Tcl_UnixError (interp
), (char *) NULL
);
414 } /* Modify each file */
418 ckfree ((char *) fileArgv
);