CTRACE(tfp, "\tFile is not editable.\n");
CTRACE((tfp, "\tFile is not editable.\n")); #endif
PUBLIC BOOL HTEditable ARGS1(	CONST char *,	filename){#ifdef NO_GROUPS    return NO;		/* Safe answer till we find the correct algorithm */#else    GETGROUPS_T groups[NGROUPS];    uid_t	myUid;    int		ngroups;			/* The number of groups	 */    struct stat fileStatus;    int		i;    if (stat(filename, &fileStatus))		/* Get details of filename */	return NO;				/* Can't even access file! */    ngroups = getgroups(NGROUPS, groups);	/* Groups to which I belong  */    myUid = geteuid();				/* Get my user identifier */    if (TRACE) {	int i2;	fprintf(tfp,	    "File mode is 0%o, uid=%d, gid=%d. My uid=%d, %d groups (",	    (unsigned int) fileStatus.st_mode,	    (int) fileStatus.st_uid,	    (int) fileStatus.st_gid,	    (int) myUid,	    (int) ngroups);	for (i2 = 0; i2 < ngroups; i2++)	    fprintf(tfp, " %d", (int) groups[i2]);	fprintf(tfp, ")\n");    }    if (fileStatus.st_mode & 0002)		/* I can write anyway? */	return YES;    if ((fileStatus.st_mode & 0200)		/* I can write my own file? */     && (fileStatus.st_uid == myUid))	return YES;    if (fileStatus.st_mode & 0020)		/* Group I am in can write? */    {	for (i = 0; i < ngroups; i++) {	    if (groups[i] == fileStatus.st_gid)		return YES;	}    }    CTRACE(tfp, "\tFile is not editable.\n");    return NO;					/* If no excuse, can't do */#endif /* NO_GROUPS */}