chmod.cpp
资源名称:warftpd.zip [点击查看]
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:9k
源码类别:
Ftp客户端
开发平台:
Visual C++
- // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
- // Copyright 1996 by Jarle Aase. All rights reserved.
- // See the "War Software Series Licende Agreement" for details concerning
- // use and distribution.
- // ---
- // This source code, executables and programs containing source code or
- // binaries or proprietetary technology from the War Software Series are
- // NOT alloed used, viewed or tested by any governmental agencies in
- // any countries. This includes the government, departments, police,
- // military etc.
- // ---
- // This file is intended for use with Tab space = 2
- // Created and maintained in MSVC Developer Studio
- // ---
- // NAME : chmod.cpp
- // PURPOSE : extended UNIX chmod command
- // PROGRAM :
- // DATE : Oct. 13 1996
- // AUTHOR : Jarle Aase
- // ---
- // REVISION HISTORY
- //
- #include "stdafx.h"
- // For now, we don't support non-daemon programs
- //#include "WarSoftware.h"
- #include "WarDaemon.h"
- #include "WarFsys.h"
- #include "VfFSys.h"
- #include "UnixFsysTypes.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CChmod::CChmod(CFsysThread *pFsysThread)
- {
- set = NULL;
- m_Owner = -1;
- m_Group = -1;
- m_Comment = NULL;
- m_DefDirPerms = -1;
- m_DefFilePerms = -1;
- omode = -1;
- m_SetMode = FALSE;
- m_pFsysThread = pFsysThread;
- m_SpecialNewFilePerm = -1;
- }
- CChmod::~CChmod()
- {
- if (set)
- free(set);
- }
- int CChmod::main(int argc, char **argv)
- {
- char *ep, *mode;
- BOOL Alternate = FALSE;
- CFileList MasterFileList;
- int Rval;
- set = NULL;
- omode = 0;
- Hflag = Lflag = Pflag = Rflag = fflag = hflag = 0;
- while ((ch = getopt(argc, argv, "N:O:G:C:D:F:HLPRXfgorstuwx")) != EOF)
- switch (ch)
- {
- case 'N': // SpecialNewFilePerm (octal)
- if (!optarg || !*optarg)
- goto badarg;
- sscanf(optarg,"%o", &m_SpecialNewFilePerm);
- Alternate = TRUE;
- break;
- case 'O': // chown
- if (!optarg || !*optarg)
- goto badarg;
- if (atoi(optarg))
- m_Owner = atoi(optarg);
- else if ((m_Owner = CUsr::FindUser(UT_USER, optarg)) == 0)
- {
- printf("Unknown user name '%s'n", optarg);
- return -1;
- }
- Alternate = TRUE;
- break;
- case 'G': // chown
- if (!optarg || !*optarg)
- goto badarg;
- if (!optarg || !*optarg)
- goto badarg;
- if (atoi(optarg))
- m_Group = atoi(optarg);
- else if ((m_Group = CUsr::FindUser(UT_CLASS, optarg)) == 0)
- {
- printf("Unknown class name '%s'n", optarg);
- return -1;
- }
- Alternate = TRUE;
- break;
- case 'C': // change comment
- if (!optarg)
- goto badarg;
- m_Comment = optarg;
- Alternate = TRUE;
- break;
- case 'D':
- if (!optarg || !*optarg || (*optarg < '0') || (*optarg > '8'))
- goto badarg;
- m_DefDirPerms = strtol(optarg, &ep, 8);
- Alternate = TRUE;
- break;
- case 'F':
- if (!optarg || !*optarg || (*optarg < '0') || (*optarg > '8'))
- goto badarg;
- m_DefFilePerms = strtol(optarg, &ep, 8);
- Alternate = TRUE;
- break;
- case 'H':
- Hflag = 1;
- Lflag = Pflag = 0;
- break;
- case 'L':
- Lflag = 1;
- Hflag = Pflag = 0;
- break;
- case 'P':
- Pflag = 1;
- Hflag = Lflag = 0;
- break;
- case 'R':
- Rflag = 1;
- break;
- case 'f': /* XXX: undocumented. */
- fflag = 1;
- break;
- case 'h':
- /*
- * In System V (and probably POSIX.2) the -h option
- * causes chmod to change the mode of the symbolic
- * link. 4.4BSD's symbolic links don't have modes,
- * so it's an undocumented noop. Do syntax checking,
- * though.
- */
- hflag = 1;
- break;
- /*
- * XXX
- * "-[rwx]" are valid mode commands. If they are the entire
- * argument, getopt has moved past them, so decrement optind.
- * Regardless, we're done argument processing.
- */
- case 'g': case 'o': case 'r': case 's':
- case 't': case 'u': case 'w': case 'X': case 'x':
- if (argv[optind - 1][0] == '-' &&
- argv[optind - 1][1] == ch &&
- argv[optind - 1][2] == ' ')
- --optind;
- Alternate = FALSE;
- goto done;
- case '?':
- default:
- return usage();
- }
- done:
- argv += optind;
- argc -= optind;
- if (Rflag)
- {
- if (hflag)
- {
- printf("the -R and -h options may not be specified together.");
- return usage();
- }
- }
- if (!Alternate)
- {
- if (argc < 2)
- return usage();
- m_SetMode = TRUE;
- mode = *argv;
- --argc;
- ++argv;
- if (*mode >= '0' && *mode <= '7')
- {
- val = strtol(mode, &ep, 8);
- if (val > INT_MAX || val < 0)
- {
- printf("invalid file mode: %s", mode);
- return 1;
- }
- if (*ep)
- {
- printf("invalid file mode: %s", mode);
- return 1;
- }
- omode = val;
- oct = 1;
- }
- else
- {
- if ((set = setmode(mode)) == NULL)
- {
- printf("invalid file mode: %s", mode);
- return 1;
- }
- oct = 0;
- }
- }
- pLock->WriteLock();
- Rval = Process(argc, argv, 0, MasterFileList);
- pLock->UnlockWrite();
- return Rval;
- badarg:
- return usage();
- }
- int CChmod::Process(int argc, char **argv, int Level, CFileList& MasterFileList)
- {
- int argcSave = argc;
- char **argvSave = argv;
- for(;argc ; argc--, argv++)
- {
- // Prepere file system
- CString Path = *argv;
- m_pFsysThread->ParsePath(Path);
- m_pFsysThread->ScanPath(Path, FALSE, Rflag, FALSE, FALSE);
- }
- int Rval = _Process(argcSave, argvSave, Level, MasterFileList);
- return Rval;
- }
- int CChmod::_Process(int argc, char **argv, int Level, CFileList& MasterFileList)
- {
- CString cShowPath, cCurrentPath;
- CLinkedListItem *Item;
- ASSERT(argc >= 1);
- for(;argc ; argc--, argv++)
- {
- CFileList FileList;
- ASSERT(AfxIsValidString(*argv));
- if (m_VisitedDirs.Find(*argv))
- continue; // Already been here
- cCurrentPath = cShowPath = *argv;
- m_pFsysThread->BldFileInfoList(FileList, *argv, Rflag);
- if (Rflag)
- {
- m_VisitedDirs.AddHead(*argv);
- int Rval;
- for(Item = FileList.First(); Item; Item = FileList.Next(Item))
- {
- FILE_NODE *pNode = (FILE_NODE *)FileList.Ptr(Item);
- if ((pNode->Perms & NODE_DIR)
- && strcmp(pNode->Name,".") && strcmp(pNode->Name,".."))
- {
- CString cBuf;
- // We need to modify the current path
- LPSTR p = cCurrentPath.GetBuffer(1);
- LPSTR pp = strrchr(p, '/');
- if (pp)
- *pp = 0;
- else
- *p = 0;
- cCurrentPath.ReleaseBuffer();
- if (cCurrentPath.IsEmpty())
- cBuf = pNode->Name;
- else
- cBuf.Format("%s/%s", cCurrentPath, pNode->Name);
- cBuf += "/*";
- LPSTR MyArgs[1];
- MyArgs[0] = cBuf.GetBuffer(1);
- if (Rval = Process(1, MyArgs, Level +1, MasterFileList))
- return Rval; // Error
- }
- }
- }
- MasterFileList += FileList;
- }
- if (!Level)
- {
- if (!ChmodFileList(MasterFileList, cShowPath))
- return -1;
- // Flush
- for(Item = MasterFileList.First(); Item; Item = MasterFileList.Next(Item))
- {
- FILE_NODE *pNode = (FILE_NODE *)MasterFileList.Ptr(Item);
- m_pFsysThread->Flush(pNode->Father);
- }
- }
- return 0;
- }
- BOOL CChmod::ChmodFileList(CFileList& FileList, LPCSTR Path)
- {
- FILE_NODE *pNode;
- LPCSTR FileName;
- CLinkedListItem *Item;
- for(Item = FileList.First(); Item; Item = FileList.Next(Item))
- {
- pNode = (FILE_NODE *)FileList.Ptr(Item);
- FileName = pNode->Name;
- ASSERT(AfxIsValidString(FileName));
- if (!strcmp(FileName,".") || !strcmp(FileName,".."))
- continue;
- // Change the mode
- if (__chmod(
- pNode,
- m_SetMode ? oct ? omode : getmode(set,pNode->Perms) : -1,
- m_Owner, m_Group, m_Comment, m_DefDirPerms, m_DefFilePerms, m_SpecialNewFilePerm))
- {
- printf("chmod: %s - mode change failed %s/%sn", Path, FileName, GetLastErrorText());
- }
- }
- return TRUE;
- }
- int CChmod::usage()
- {
- printf("usage: chmod [-R [-H | -L | -P]] mode file ...n");
- printf(" or chmod [-O Owner] [-G Class] [-C "Comment"] [-D DefDirPerms] [-F DefFilePerms] file ...n");
- printf(" or chmod -N SpecialNewFilePerms directory ... (value is octal, default is 022)n");
- return 1;
- }
- // Chmod on a single file
- // Return 0 on success
- int CChmod::__chmod(FILE_NODE *pNode, int SetMode, int SetOwner,
- int SetClass, LPCSTR SetComment, int DefDirMode, int DefFileMode,
- int SpecialNewFilePerm)
- {
- int rval = 0;
- DWORD PreserveFlags = pNode->Perms & ~NODE_SETTABLE;
- // Check permission
- if (!m_Fsys->m_IsAdmin && (m_Fsys->m_User != pNode->User))
- {
- SetLastError(ERROR_ACCESS_DENIED);
- return -1;
- }
- // Set the new permissions
- if (SetMode != -1)
- pNode->Perms = (SetMode & NODE_SETTABLE) | PreserveFlags;
- if (SetOwner != -1)
- pNode->User = SetOwner;
- if (SetClass != -1)
- pNode->Class = SetClass;
- if ((SpecialNewFilePerm != -1) && (pNode->Perms & NODE_DIR))
- ((DIR_NODE *)pNode)->SpecialNewFilePerm = SpecialNewFilePerm;
- if (SetComment)
- ChangeNodeInformation(pNode, NULL, NULL, NULL, SetComment);
- DIR_NODE *pDir = (DIR_NODE *)pSmem->__Ptr(pNode->Father);
- if (pDir)
- pDir->f_Dirty = TRUE;
- return 0;
- }