Version 0 of userid

Updated 2004-05-21 10:25:56 by CMCc

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;
    }