📄 tclunixfcmd.c
字号:
} result = TCL_ERROR; } return result;}/* *---------------------------------------------------------------------- * * TraversalCopy * * Called from TraverseUnixTree in order to execute a recursive copy * of a directory. * * Results: * Standard Tcl result. * * Side effects: * The file or directory src may be copied to dst, depending on * the value of type. * *---------------------------------------------------------------------- */static int TraversalCopy(srcPtr, dstPtr, statBufPtr, type, errorPtr) Tcl_DString *srcPtr; /* Source pathname to copy (native). */ Tcl_DString *dstPtr; /* Destination pathname of copy (native). */ CONST Tcl_StatBuf *statBufPtr; /* Stat info for file specified by srcPtr. */ int type; /* Reason for call - see TraverseUnixTree(). */ Tcl_DString *errorPtr; /* If non-NULL, uninitialized or free * DString filled with UTF-8 name of file * causing error. */{ switch (type) { case DOTREE_F: if (DoCopyFile(Tcl_DStringValue(srcPtr), Tcl_DStringValue(dstPtr)) == TCL_OK) { return TCL_OK; } break; case DOTREE_PRED: if (DoCreateDirectory(Tcl_DStringValue(dstPtr)) == TCL_OK) { return TCL_OK; } break; case DOTREE_POSTD: if (CopyFileAtts(Tcl_DStringValue(srcPtr), Tcl_DStringValue(dstPtr), statBufPtr) == TCL_OK) { return TCL_OK; } break; } /* * There shouldn't be a problem with src, because we already checked it * to get here. */ if (errorPtr != NULL) { Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(dstPtr), Tcl_DStringLength(dstPtr), errorPtr); } return TCL_ERROR;}/* *--------------------------------------------------------------------------- * * TraversalDelete -- * * Called by procedure TraverseUnixTree for every file and directory * that it encounters in a directory hierarchy. This procedure unlinks * files, and removes directories after all the containing files * have been processed. * * Results: * Standard Tcl result. * * Side effects: * Files or directory specified by src will be deleted. * *---------------------------------------------------------------------- */static intTraversalDelete(srcPtr, ignore, statBufPtr, type, errorPtr) Tcl_DString *srcPtr; /* Source pathname (native). */ Tcl_DString *ignore; /* Destination pathname (not used). */ CONST Tcl_StatBuf *statBufPtr; /* Stat info for file specified by srcPtr. */ int type; /* Reason for call - see TraverseUnixTree(). */ Tcl_DString *errorPtr; /* If non-NULL, uninitialized or free * DString filled with UTF-8 name of file * causing error. */{ switch (type) { case DOTREE_F: { if (TclpDeleteFile(Tcl_DStringValue(srcPtr)) == 0) { return TCL_OK; } break; } case DOTREE_PRED: { return TCL_OK; } case DOTREE_POSTD: { if (DoRemoveDirectory(srcPtr, 0, NULL) == 0) { return TCL_OK; } break; } } if (errorPtr != NULL) { Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(srcPtr), Tcl_DStringLength(srcPtr), errorPtr); } return TCL_ERROR;}/* *--------------------------------------------------------------------------- * * CopyFileAtts -- * * Copy the file attributes such as owner, group, permissions, * and modification date from one file to another. * * Results: * Standard Tcl result. * * Side effects: * user id, group id, permission bits, last modification time, and * last access time are updated in the new file to reflect the * old file. * *--------------------------------------------------------------------------- */static intCopyFileAtts(src, dst, statBufPtr) CONST char *src; /* Path name of source file (native). */ CONST char *dst; /* Path name of target file (native). */ CONST Tcl_StatBuf *statBufPtr; /* Stat info for source file */{ struct utimbuf tval; mode_t newMode; newMode = statBufPtr->st_mode & (S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO); /* * Note that if you copy a setuid file that is owned by someone * else, and you are not root, then the copy will be setuid to you. * The most correct implementation would probably be to have the * copy not setuid to anyone if the original file was owned by * someone else, but this corner case isn't currently handled. * It would require another lstat(), or getuid(). */ if (chmod(dst, newMode)) { /* INTL: Native. */ newMode &= ~(S_ISUID | S_ISGID); if (chmod(dst, newMode)) { /* INTL: Native. */ return TCL_ERROR; } } tval.actime = statBufPtr->st_atime; tval.modtime = statBufPtr->st_mtime; if (utime(dst, &tval)) { /* INTL: Native. */ return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * GetGroupAttribute * * Gets the group attribute of a file. * * Results: * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr * if there is no error. * * Side effects: * A new object is allocated. * *---------------------------------------------------------------------- */static intGetGroupAttribute(interp, objIndex, fileName, attributePtrPtr) 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 **attributePtrPtr; /* A pointer to return the object with. */{ Tcl_StatBuf statBuf; struct group *groupPtr; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { Tcl_AppendResult(interp, "could not read \"", Tcl_GetString(fileName), "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } groupPtr = getgrgid(statBuf.st_gid); /* INTL: Native. */ if (groupPtr == NULL) { *attributePtrPtr = Tcl_NewIntObj((int) statBuf.st_gid); } else { Tcl_DString ds; CONST char *utf; utf = Tcl_ExternalToUtfDString(NULL, groupPtr->gr_name, -1, &ds); *attributePtrPtr = Tcl_NewStringObj(utf, -1); Tcl_DStringFree(&ds); } endgrent(); return TCL_OK;}/* *---------------------------------------------------------------------- * * GetOwnerAttribute * * Gets the owner attribute of a file. * * Results: * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr * if there is no error. * * Side effects: * A new object is allocated. * *---------------------------------------------------------------------- */static intGetOwnerAttribute(interp, objIndex, fileName, attributePtrPtr) 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 **attributePtrPtr; /* A pointer to return the object with. */{ Tcl_StatBuf statBuf; struct passwd *pwPtr; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { Tcl_AppendResult(interp, "could not read \"", Tcl_GetString(fileName), "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } pwPtr = getpwuid(statBuf.st_uid); /* INTL: Native. */ if (pwPtr == NULL) { *attributePtrPtr = Tcl_NewIntObj((int) statBuf.st_uid); } else { Tcl_DString ds; CONST char *utf; utf = Tcl_ExternalToUtfDString(NULL, pwPtr->pw_name, -1, &ds); *attributePtrPtr = Tcl_NewStringObj(utf, Tcl_DStringLength(&ds)); Tcl_DStringFree(&ds); } endpwent(); return TCL_OK;}/* *---------------------------------------------------------------------- * * GetPermissionsAttribute * * Gets the group attribute of a file. * * Results: * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr * if there is no error. The object will have ref count 0. * * Side effects: * A new object is allocated. * *---------------------------------------------------------------------- */static intGetPermissionsAttribute(interp, objIndex, fileName, attributePtrPtr) 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 **attributePtrPtr; /* A pointer to return the object with. */{ Tcl_StatBuf statBuf; char returnString[7]; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { Tcl_AppendResult(interp, "could not read \"", Tcl_GetString(fileName), "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } sprintf(returnString, "%0#5lo", (long) (statBuf.st_mode & 0x00007FFF)); *attributePtrPtr = Tcl_NewStringObj(returnString, -1); return TCL_OK;}/* *--------------------------------------------------------------------------- * * SetGroupAttribute -- * * Sets the group of the file to the specified group. * * Results: * Standard TCL result. * * Side effects: * As above. * *--------------------------------------------------------------------------- */static intSetGroupAttribute(interp, objIndex, fileName, attributePtr) Tcl_Interp *interp; /* The interp for error reporting. */ int objIndex; /* The index of the attribute. */ Tcl_Obj *fileName; /* The name of the file (UTF-8). */ Tcl_Obj *attributePtr; /* New group for file. */{ long gid; int result; CONST char *native; if (Tcl_GetLongFromObj(NULL, attributePtr, &gid) != TCL_OK) { Tcl_DString ds; struct group *groupPtr; CONST char *string; int length; string = Tcl_GetStringFromObj(attributePtr, &length); native = Tcl_UtfToExternalDString(NULL, string, length, &ds); groupPtr = getgrnam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); if (groupPtr == NULL) { endgrent(); Tcl_AppendResult(interp, "could not set group for file \"", Tcl_GetString(fileName), "\": group \"", string, "\" does not exist", (char *) NULL); return TCL_ERROR; } gid = groupPtr->gr_gid; } native = Tcl_FSGetNativePath(fileName); result = chown(native, (uid_t) -1, (gid_t) gid); /* INTL: Native. */ endgrent(); if (result != 0) { Tcl_AppendResult(interp, "could not set group for file \"", Tcl_GetString(fileName), "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *--------------------------------------------------------------------------- * * SetOwnerAttribute -- * * Sets the owner of the file to the specified owner. * * Results: * Standard TCL result. * * Side effects: * As above. * *--------------------------------------------------------------------------- */static intSetOwnerAttribute(interp, objIndex, fileName, attributePtr) Tcl_Interp *interp; /* The interp for error reporting. */ int objIndex; /* The index of the attribute. */ Tcl_Obj *fileName; /* The name of the file (UTF-8). */ Tcl_Obj *attributePtr; /* New owner for file. */{ long uid; int result; CONST char *native; if (Tcl_GetLongFromObj(NULL, attributePtr, &uid) != TCL_OK) { Tcl_DString ds; struct passwd *pwPtr; CONST char *string; int length; string = Tcl_GetStringFromObj(attributePtr, &length); native = Tcl_UtfToExternalDString(NULL, string, length, &ds); pwPtr = getpwnam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); if (pwPtr == NULL) { Tcl_AppendResult(interp, "could not set owner for file \"", Tcl_GetString(fileName), "\": user \"", string, "\" does not exist", (char *) NULL); return TCL_ERROR; } uid = pwPtr->pw_uid; } native = Tcl_FSGetNativePath(fileName); result = chown(native, (uid_t) uid, (gid_t) -1); /* INTL: Native. */ if (result != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -