⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclunixfcmd.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 4 页
字号:
	Tcl_AppendResult(interp, "could not set owner for file \"", 			 Tcl_GetString(fileName), "\": ", 			 Tcl_PosixError(interp), (char *) NULL);	return TCL_ERROR;    }    return TCL_OK;}/* *--------------------------------------------------------------------------- * * SetPermissionsAttribute * *      Sets the file to the given permission. * * Results: *      Standard TCL result. * * Side effects: *      The permission of the file is changed. *       *--------------------------------------------------------------------------- */static intSetPermissionsAttribute(interp, objIndex, fileName, attributePtr)    Tcl_Interp *interp;		    /* The interp we are using for errors. */    int objIndex;		    /* The index of the attribute. */    Tcl_Obj *fileName;  	    /* The name of the file (UTF-8). */    Tcl_Obj *attributePtr;	    /* The attribute to set. */{    long mode;    mode_t newMode;    int result;    CONST char *native;    /*     * First try if the string is a number     */    if (Tcl_GetLongFromObj(NULL, attributePtr, &mode) == TCL_OK) {        newMode = (mode_t) (mode & 0x00007FFF);    } else {	Tcl_StatBuf buf;	char *modeStringPtr = Tcl_GetString(attributePtr);	/*	 * Try the forms "rwxrwxrwx" and "ugo=rwx"	 *	 * We get the current mode of the file, in order to allow for	 * ug+-=rwx style chmod strings.	 */	result = TclpObjStat(fileName, &buf);	if (result != 0) {	    Tcl_AppendResult(interp, "could not read \"", 		    Tcl_GetString(fileName), "\": ",		    Tcl_PosixError(interp), (char *) NULL);	    return TCL_ERROR;	}	newMode = (mode_t) (buf.st_mode & 0x00007FFF);	if (GetModeFromPermString(NULL, modeStringPtr, &newMode) != TCL_OK) {	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),		    "unknown permission string format \"",		    modeStringPtr, "\"", (char *) NULL);	    return TCL_ERROR;	}    }    native = Tcl_FSGetNativePath(fileName);    result = chmod(native, newMode);		/* INTL: Native. */    if (result != 0) {	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),		"could not set permissions for file \"", 		Tcl_GetString(fileName), "\": ",		Tcl_PosixError(interp), (char *) NULL);	return TCL_ERROR;    }    return TCL_OK;}/* *--------------------------------------------------------------------------- * * TclpObjListVolumes -- * *	Lists the currently mounted volumes, which on UNIX is just /. * * Results: *	The list of volumes. * * Side effects: *	None. * *--------------------------------------------------------------------------- */Tcl_Obj*TclpObjListVolumes(void){    Tcl_Obj *resultPtr = Tcl_NewStringObj("/",1);    Tcl_IncrRefCount(resultPtr);    return resultPtr;}/* *---------------------------------------------------------------------- * * GetModeFromPermString -- * *	This procedure is invoked to process the "file permissions" *	Tcl command, to check for a "rwxrwxrwx" or "ugoa+-=rwxst" string. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */static intGetModeFromPermString(interp, modeStringPtr, modePtr)    Tcl_Interp *interp;		/* The interp we are using for errors. */    char *modeStringPtr;	/* Permissions string */    mode_t *modePtr;		/* pointer to the mode value */{    mode_t newMode;    mode_t oldMode;		/* Storage for the value of the old mode				 * (that is passed in), to allow for the				 * chmod style manipulation */    int i,n, who, op, what, op_found, who_found;    /*     * We start off checking for an "rwxrwxrwx" style permissions string     */    if (strlen(modeStringPtr) != 9) {        goto chmodStyleCheck;    }    newMode = 0;    for (i = 0; i < 9; i++) {	switch (*(modeStringPtr+i)) {	    case 'r':		if ((i%3) != 0) {		    goto chmodStyleCheck;		}		newMode |= (1<<(8-i));		break;	    case 'w':		if ((i%3) != 1) {		    goto chmodStyleCheck;		}		newMode |= (1<<(8-i));		break;	    case 'x':		if ((i%3) != 2) {		    goto chmodStyleCheck;		}		newMode |= (1<<(8-i));		break;	    case 's':		if (((i%3) != 2) || (i > 5)) {		    goto chmodStyleCheck;		}		newMode |= (1<<(8-i));		newMode |= (1<<(11-(i/3)));		break;	    case 'S':		if (((i%3) != 2) || (i > 5)) {		    goto chmodStyleCheck;		}		newMode |= (1<<(11-(i/3)));		break;	    case 't':		if (i != 8) {		    goto chmodStyleCheck;		}		newMode |= (1<<(8-i));		newMode |= (1<<9);		break;	    case 'T':		if (i != 8) {		    goto chmodStyleCheck;		}		newMode |= (1<<9);		break;	    case '-':		break;	    default:		/*		 * Oops, not what we thought it was, so go on		 */		goto chmodStyleCheck;	}    }    *modePtr = newMode;    return TCL_OK;    chmodStyleCheck:    /*     * We now check for an "ugoa+-=rwxst" style permissions string     */    for (n = 0 ; *(modeStringPtr+n) != '\0' ; n = n + i) {	oldMode = *modePtr;	who = op = what = op_found = who_found = 0;	for (i = 0 ; *(modeStringPtr+n+i) != '\0' ; i++ ) {	    if (!who_found) {		/* who */		switch (*(modeStringPtr+n+i)) {		    case 'u' :			who |= 0x9c0;			continue;		    case 'g' :			who |= 0x438;			continue;		    case 'o' :			who |= 0x207;			continue;		    case 'a' :			who |= 0xfff;			continue;		}	    }	    who_found = 1;	    if (who == 0) {		who = 0xfff;	    }	    if (!op_found) {		/* op */		switch (*(modeStringPtr+n+i)) {		    case '+' :			op = 1;			op_found = 1;			continue;		    case '-' :			op = 2;			op_found = 1;			continue;		    case '=' :			op = 3;			op_found = 1;			continue;		    default  :			return TCL_ERROR;			break;		}	    }	    /* what */	    switch (*(modeStringPtr+n+i)) {		case 'r' :		    what |= 0x124;		    continue;		case 'w' :		    what |= 0x92;		    continue;		case 'x' :		    what |= 0x49;		    continue;		case 's' :		    what |= 0xc00;		    continue;		case 't' :		    what |= 0x200;		    continue;		case ',' :		    break;		default  :		    return TCL_ERROR;		    break;	    }	    if (*(modeStringPtr+n+i) == ',') {		i++;		break;	    }	}	switch (op) {	    case 1 :		*modePtr = oldMode | (who & what);		continue;	    case 2 :		*modePtr = oldMode & ~(who & what);		continue;	    case 3 :		*modePtr = (oldMode & ~who) | (who & what);		continue;	}    }    return TCL_OK;}/* *--------------------------------------------------------------------------- * * TclpObjNormalizePath -- * *	This function scans through a path specification and replaces *	it, in place, with a normalized version.  A normalized version *	is one in which all symlinks in the path are replaced with *	their expanded form (except a symlink at the very end of the *	path). * * Results: *	The new 'nextCheckpoint' value, giving as far as we could *	understand in the path. * * Side effects: *	The pathPtr string, is modified. * *--------------------------------------------------------------------------- */intTclpObjNormalizePath(interp, pathPtr, nextCheckpoint)    Tcl_Interp *interp;    Tcl_Obj *pathPtr;    int nextCheckpoint;{    char *currentPathEndPosition;    int pathLen;    char cur;    char *path = Tcl_GetStringFromObj(pathPtr, &pathLen);#ifndef NO_REALPATH    char normPath[MAXPATHLEN];    Tcl_DString ds;    CONST char *nativePath; #endif    /*      * We add '1' here because if nextCheckpoint is zero we know     * that '/' exists, and if it isn't zero, it must point at     * a directory separator which we also know exists.     */    currentPathEndPosition = path + nextCheckpoint;    if (*currentPathEndPosition == '/') {	currentPathEndPosition++;    }#ifndef NO_REALPATH    /* For speed, try to get the entire path in one go */    if (nextCheckpoint == 0) {        char *lastDir = strrchr(currentPathEndPosition, '/');	if (lastDir != NULL) {	    nativePath = Tcl_UtfToExternalDString(NULL, path, 						  lastDir - path, &ds);	    if (Realpath(nativePath, normPath) != NULL) {		nextCheckpoint = lastDir - path;		goto wholeStringOk;	    }	}    }    /* Else do it the slow way */#endif        while (1) {	cur = *currentPathEndPosition;	if ((cur == '/') && (path != currentPathEndPosition)) {	    /* Reached directory separator */	    Tcl_DString ds;	    CONST char *nativePath;	    int accessOk;	    nativePath = Tcl_UtfToExternalDString(NULL, path, 		    currentPathEndPosition - path, &ds);	    accessOk = access(nativePath, F_OK);	    Tcl_DStringFree(&ds);	    if (accessOk != 0) {		/* File doesn't exist */		break;	    }	    /* Update the acceptable point */	    nextCheckpoint = currentPathEndPosition - path;	} else if (cur == 0) {	    /* Reached end of string */	    break;	}	currentPathEndPosition++;    }    /*      * We should really now convert this to a canonical path.  We do     * that with 'realpath' if we have it available.  Otherwise we could     * step through every single path component, checking whether it is a      * symlink, but that would be a lot of work, and most modern OSes      * have 'realpath'.     */#ifndef NO_REALPATH    /*      * If we only had '/foo' or '/' then we never increment nextCheckpoint     * and we don't need or want to go through 'Realpath'.  Also, on some     * platforms, passing an empty string to 'Realpath' will give us the     * normalized pwd, which is not what we want at all!     */    if (nextCheckpoint == 0) return 0;        nativePath = Tcl_UtfToExternalDString(NULL, path, nextCheckpoint, &ds);    if (Realpath(nativePath, normPath) != NULL) {	int newNormLen;	wholeStringOk:	newNormLen = strlen(normPath);	if ((newNormLen == Tcl_DStringLength(&ds))		&& (strcmp(normPath, nativePath) == 0)) {	    /* String is unchanged */	    Tcl_DStringFree(&ds);	    if (path[nextCheckpoint] != '\0') {		nextCheckpoint++;	    }	    return nextCheckpoint;	}		/* 	 * Free up the native path and put in its place the	 * converted, normalized path.	 */	Tcl_DStringFree(&ds);	Tcl_ExternalToUtfDString(NULL, normPath, (int) newNormLen, &ds);	if (path[nextCheckpoint] != '\0') {	    /* not at end, append remaining path */	    int normLen = Tcl_DStringLength(&ds);	    Tcl_DStringAppend(&ds, path + nextCheckpoint,		    pathLen - nextCheckpoint);	    /* 	     * We recognise up to and including the directory	     * separator.	     */		    nextCheckpoint = normLen + 1;	} else {	    /* We recognise the whole string */ 	    nextCheckpoint = Tcl_DStringLength(&ds);	}	/* 	 * Overwrite with the normalized path.	 */	Tcl_SetStringObj(pathPtr, Tcl_DStringValue(&ds),		Tcl_DStringLength(&ds));    }    Tcl_DStringFree(&ds);#endif	/* !NO_REALPATH */    return nextCheckpoint;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -