CMcC: This is a critcl rendering of some TclX functions useful under Unix.
package provide userid 1.0 critcl::ccode { #include <pwd.h> #include <grp.h> #include <unistd.h> #include <sys/types.h> #include <time.h> #include <tcl.h> static int confNGroups = -1; static int UsernameToUseridResult (Tcl_Interp *interp, char *userName) { struct passwd *pw = getpwnam (userName); Tcl_Obj *resultObj = Tcl_GetObjResult (interp); if (pw == NULL) { Tcl_AppendStringsToObj (resultObj, "unknown user id: ", userName, (char *) NULL); endpwent (); return TCL_ERROR; } Tcl_SetObjResult (interp, Tcl_NewIntObj (pw->pw_uid)); endpwent (); return TCL_OK; } static int UseridToUsernameResult (Tcl_Interp *interp, int userId) { uid_t uid = (uid_t) userId; struct passwd *pw = getpwuid (userId); Tcl_Obj *resultObj = Tcl_GetObjResult (interp); char userIdString[16]; if ((pw == NULL) || ((int) uid != userId)) { sprintf (userIdString, "%d", uid); Tcl_AppendStringsToObj (resultObj, "unknown user id: ", userIdString, NULL); endpwent (); return TCL_ERROR; } Tcl_AppendToObj (resultObj, pw->pw_name, -1); endpwent (); return TCL_OK; } static int GroupnameToGroupidResult (Tcl_Interp *interp, char *groupName) { struct group *grp = getgrnam (groupName); Tcl_Obj *resultObj = Tcl_GetObjResult (interp); if (grp == NULL) { Tcl_AppendStringsToObj (resultObj, "unknown group id: ", groupName, (char *) NULL); return TCL_ERROR; } Tcl_SetIntObj (resultObj, grp->gr_gid); return TCL_OK; } static int GroupidToGroupnameResult (Tcl_Interp *interp, int groupId) { gid_t gid = (gid_t) groupId; struct group *grp = getgrgid (groupId); Tcl_Obj *resultObj = Tcl_GetObjResult (interp); char groupIdString[16]; sprintf (groupIdString, "%d", gid); if ((grp == NULL) || ((int) gid != groupId)) { Tcl_AppendStringsToObj (resultObj, "unknown group id: ", groupIdString, (char *)NULL); endgrent (); return TCL_ERROR; } Tcl_AppendToObj (resultObj, grp->gr_name, -1); endgrent (); return TCL_OK; } } critcl::cproc id_convert_user {Tcl_Interp* interp char* name} ok { return UsernameToUseridResult (interp, name); } critcl::cproc id_convert_userid {Tcl_Interp* interp int uid} ok { return UseridToUsernameResult (interp, uid); } critcl::cproc id_convert_group {Tcl_Interp* interp char* name} ok { return GroupnameToGroupidResult (interp, name); } critcl::cproc id_convert_groupid {Tcl_Interp* interp int gid} ok { return GroupidToGroupnameResult (interp, gid); } critcl::cproc id_effective_user {Tcl_Interp* interp} ok { return UseridToUsernameResult (interp, geteuid ()); } critcl::cproc id_effective_userid {Tcl_Interp* interp} ok { Tcl_SetObjResult (interp, Tcl_NewIntObj (geteuid ())); return TCL_OK; } critcl::cproc id_user {Tcl_Interp* interp} ok { return UseridToUsernameResult (interp, getuid ()); } critcl::cproc id_userid {Tcl_Interp* interp} ok { Tcl_SetObjResult (interp, Tcl_NewIntObj (getuid ())); return TCL_OK; } critcl::cproc id_set_userid {Tcl_Interp* interp int uid} ok { if (setuid ((uid_t) uid) < 0) { Tcl_AppendStringsToObj ( Tcl_GetObjResult (interp), Tcl_PosixError (interp), (char *) NULL); return TCL_ERROR; } return TCL_OK; } critcl::cproc id_effective_group {Tcl_Interp* interp} ok { return GroupidToGroupnameResult (interp, getegid ()); } critcl::cproc id_effective_groupid {Tcl_Interp* interp} ok { Tcl_SetObjResult (interp, Tcl_NewIntObj (getegid ())); return TCL_OK; } critcl::cproc id_group {Tcl_Interp* interp} ok { return GroupidToGroupnameResult (interp, getgid ()); } critcl::cproc id_groupid {Tcl_Interp* interp} ok { Tcl_SetObjResult (interp, Tcl_NewIntObj (getgid ())); return TCL_OK; } critcl::cproc id_set_groupid {Tcl_Interp* interp int gid} ok { if (setgid ((uid_t) gid) < 0) { Tcl_AppendStringsToObj ( Tcl_GetObjResult (interp), Tcl_PosixError (interp), (char *) NULL); return TCL_ERROR; } return TCL_OK; } critcl::cproc id_process {Tcl_Interp* interp} ok { Tcl_SetObjResult (interp, Tcl_NewIntObj (getpid ())); return TCL_OK; } critcl::cproc id_process_parent {Tcl_Interp* interp} ok { Tcl_SetObjResult (interp, Tcl_NewIntObj (getppid ())); return TCL_OK; } critcl::cproc id_process_group {Tcl_Interp* interp} ok { Tcl_SetObjResult (interp, Tcl_NewIntObj (getpgrp ())); return TCL_OK; } critcl::cproc id_process_group_set {Tcl_Interp* interp int pgid} ok { int pid; if (Tcl_IsSafe (interp)) { Tcl_AppendStringsToObj ( Tcl_GetObjResult (interp), "can't set process group from a ", "safe interpeter", (char *) NULL); return TCL_ERROR; } pid = getpid (); setpgid (pid, pgid); return TCL_OK; } critcl::cproc id_host {Tcl_Interp* interp} ok { #ifndef MAXHOSTNAMELEN # define MAXHOSTNAMELEN 256 #endif char hostNameBuf[MAXHOSTNAMELEN]; if (gethostname (hostNameBuf, MAXHOSTNAMELEN) < 0) { Tcl_AppendStringsToObj ( Tcl_GetObjResult (interp), Tcl_PosixError (interp), (char *) NULL); return TCL_ERROR; } hostNameBuf[MAXHOSTNAMELEN-1] = '\0'; Tcl_SetObjResult (interp, Tcl_NewStringObj (hostNameBuf, -1)); return TCL_OK; } critcl::cproc id_groupids {Tcl_Interp* interp} ok { gid_t *groups; int nGroups, groupIndex; Tcl_Obj *newObj; Tcl_Obj *resultObj = Tcl_GetObjResult (interp); if (confNGroups < 0) confNGroups = sysconf (_SC_NGROUPS_MAX); groups = (gid_t *) ckalloc (confNGroups * sizeof (gid_t)); nGroups = getgroups (confNGroups, groups); if (nGroups < 0) { Tcl_AppendStringsToObj (Tcl_GetObjResult (interp), Tcl_PosixError (interp), (char *) NULL); ckfree ((char *) groups); return TCL_ERROR; } for (groupIndex = 0; groupIndex < nGroups; groupIndex++) { newObj = Tcl_NewIntObj(groups[groupIndex]); Tcl_ListObjAppendElement (interp, resultObj, newObj); } ckfree ((char *) groups); return TCL_OK; }