예제 #1
0
파일: dirent.c 프로젝트: Turingwy/turinux
int dirlink(struct inode *dp, char *dirname, uint32_t ino)
{
    if(!ISDIR(dp->mode) || ino < 1) {
        return -1;
    }
    
    if(dirlookup(dp, dirname, 0)) 
        return -1;

    struct dirent dir;
    int off;
    for(off = 0; off < dp->size; off+=sizeof(struct dirent))
    {
        if(!readi(dp, (char *)&dir, off, sizeof(struct dirent))) {
            return -1;
        }
        // found a new entry
        if(!dir.ino)
            break;
    }
    
    dir.ino = ino;
    strcpy(dir.name, dirname);
    writei(dp, (char *)&dir, off, sizeof(struct dirent));
    return 0;
}
예제 #2
0
파일: removeinc.c 프로젝트: chutzimir/coda
int main(int argc, char **argv) 
{
    ViceFid fid;
    char realm[MAXHOSTNAMELEN+1];
    char tmpfname[80];
    int fd;
    struct ViceIoctl vioc;
    char space[2048];
    int rc;

    if (argc != 2) {
	fprintf(stderr, "Usage: %s <inc-file-name>\n", argv[0]);
	exit(-1);
    }
    
    /* make sure object is inconsistent */
    if (!IsObjInc(argv[1], &fid, realm)) {
	fprintf(stderr, "%s isn't inconsistent\n", argv[1]);
	exit(0);
    }
    
    /* get fid and make sure it is a file */
    if (ISDIR(fid) && !FID_IsLocalDir(&fid)) {
	fprintf(stderr, "%s is a directory - must be removed manually\n", argv[1]);
	exit(-1);
    }

    /* create an empty file /tmp/REPAIR.XXXXXX */
    strcpy(tmpfname, "/tmp/RMINC.XXXXXX");
    if ((fd = mkstemp(tmpfname)) < 0) {
	fprintf(stderr, "Couldn't create /tmp file\n");
	exit(-1);
    }
    close(fd);

    /* dorepair on the fid with an empty file */
    vioc.in_size = (short)(1+strlen(tmpfname)); 
    vioc.in = tmpfname;
    vioc.out_size = (short) sizeof(space);
    vioc.out = space;
    memset(space, 0, (int) sizeof(space));
    rc = pioctl(argv[1], _VICEIOCTL(_VIOC_REPAIR), &vioc, 0);
    if (rc < 0 && errno != ETOOMANYREFS) {
	fprintf(stderr, "Error %d for repair\n", errno);
	unlink(tmpfname);
	exit(-1);
    }
    unlink(tmpfname);

    /* remove the repaired file */
    if (unlink(argv[1])) {
	fprintf(stderr, "Couldn't remove %s\n", argv[1]);
	exit(-1);
    }
    exit(0);
}
예제 #3
0
파일: removeinc.c 프로젝트: chutzimir/coda
int IsObjInc(char *name, ViceFid *fid, char *realm) 
{
    struct GetFid {
	ViceFid fid;
	ViceVersionVector vv;
	char realm[MAXHOSTNAMELEN+1];
    } out;
    struct ViceIoctl vio;
    struct stat statbuf;
    char symval[MAXPATHLEN];
    int rc, n;

    memset(fid, 0, sizeof(ViceFid));
    realm[0] = '\0';

    /* what if the begin repair has been done already */
    rc = stat(name, &statbuf);
    if (rc) {
	/* is it a sym link */
	symval[0] = 0;
	rc = readlink(name, symval, MAXPATHLEN);
	if (rc < 0) return(0);

	/* it's a sym link, alright */
	n = sscanf(symval, "@%x.%x.%x@%s",
		   &fid->Volume, &fid->Vnode, &fid->Unique, realm);

	return(n == 4);
    }

    memset(&out, 0, sizeof(out));
    vio.in = NULL;
    vio.in_size = 0;
    vio.out = (char *)&out;
    vio.out_size = sizeof(out);

    rc = pioctl(name, _VICEIOCTL(_VIOC_GETFID), &vio, 0);
    if (rc < 0 && errno != ETOOMANYREFS) {
	fprintf(stderr, "Error %d for Getfid\n", errno);
	return(0);
    }
    memcpy(fid, &out.fid, sizeof(ViceFid));
    strcpy(realm, out.realm);

    if (!ISDIR(out.fid) && (statbuf.st_mode & S_IFDIR))
	return(1);

    if (out.vv.StoreId.Host == -1) 
	return(1);

    return(0);
}
예제 #4
0
파일: dirent.c 프로젝트: Turingwy/turinux
static struct inode *_name(char *p, int nameiparent, char *dirname)
{
    struct inode *in, *next;
    char *name;
    char arr[64];
    char *path = arr;
    strcpy(arr, p);
    if(*path == '/') {
        in = iget(0, 1);
        while(*++path == '/')
            ;
    }
    else
        in = idup(current_proc->cwd);
    name = strtok(path, "/");
    while(name)
    {
//        printk("File system search:%s\n", name);
        ilock(in);
        if(!ISDIR(in->mode)) 
        {
            iunlock(in);
            iput(in);
            return NULL;
        }
        if(nameiparent && !tok_hasnext())
        {
            iunlock(in);
            if(dirname)
                strcpy(dirname, name);
            return in;
        }
        if(!(next = dirlookup(in, name, 0))) {
            iunlock(in);
            iput(in);
            return NULL;
        }
        iunlock(in);
        iput(in);
        in = next;
        if(!tok_hasnext() && dirname)
            strcpy(dirname, name);
        name = strtok(NULL, "/");
    }
    
    return in;
}
예제 #5
0
파일: dirent.c 프로젝트: Turingwy/turinux
struct inode *dirlookup(struct inode *dp, char *dirname, uint32_t *offp)
{
    if(!ISDIR(dp->mode))
        return NULL;

    struct dirent dir;
    for(int off = 0; off < dp->size; off+=sizeof(struct dirent))
    {
        if(readi(dp, (char *)&dir, off, sizeof(struct dirent)) != sizeof(struct dirent))
            return NULL;
        if(!strcmp(dir.name, dirname) && dir.ino)
        {
            if(offp)
                *offp = off;
           
            return iget(dp->dev, dir.ino);
        }
    }
    return NULL;
}
예제 #6
0
static void
matchdir(char *pattern)
{
	struct stat stb;
	struct dirent *dp;
	DIR *dirp;

	dirp = opendir(path);
	if (dirp == NULL) {
		if (expany)
			return;
		goto patherr2;
	}
	if (fstat(dirp->dd_fd, &stb) < 0)
		goto patherr1;
	if (!ISDIR(stb.st_mode)) {
		errno = ENOTDIR;
		goto patherr1;
	}
	while ((dp = readdir(dirp)) != NULL)
		if (match(dp->d_name, pattern)) {
			if (which & E_TILDE)
				Cat(path, dp->d_name);
			else {
				strcpy(pathp, dp->d_name);
				Cat(tilde, tpathp);
				*pathp = '\0';
			}
		}
	closedir(dirp);
	return;

patherr1:
	closedir(dirp);
patherr2:
	strcat(path, ": ");
	strcat(path, strerror(errno));
	yyerror(path);
}
예제 #7
0
// ----------------------------------------------------------------------
// Get file snap shot
// ----------------------------------------------------------------------
VOID GetFilesSnap(LPSNAPSHOT lpShot, LPTSTR lpszFullName, LPFILECONTENT lpFatherFC, LPFILECONTENT *lplpCaller) 
{
	LPFILECONTENT lpFC;
	HANDLE hFile;
	BOOL calculateHash = TRUE;
	BOOL found = FALSE;

	// Full dir/file name is already given
	// Extra local block to reduce stack usage due to recursive calls
	{
		LPTSTR lpszFindFileName;
		lpszFindFileName = NULL;
		// Get father file data if not already provided (=called from FileShot)
		// lpFatherFC only equals "C:\" and is called once at start
		if (NULL == lpFatherFC) 
		{
			// Check if file is to be GENERIC excluded
			if ((NULL == lpszFullName)
				|| (((TCHAR)'.' == lpszFullName[0])  // fast exclusion for 99% of the cases
				&& ((0 == _tcscmp(lpszFullName, TEXT(".")))
				|| (0 == _tcscmp(lpszFullName, TEXT("..")))))) {
				return;
			}
			// Create new file content
			lpFatherFC = MYALLOC0(sizeof(FILECONTENT));

			// Set file name length
			lpFatherFC->cchFileName = _tcslen(lpszFullName);
			// Copy file name to new buffer for directory search and more
			lpszFindFileName = MYALLOC((lpFatherFC->cchFileName + 4 + 1) * sizeof(TCHAR));  // +4 for "\*.*" search when directory (later in routine)
			_tcscpy(lpszFindFileName, lpszFullName);
			// Special case if root dir of a drive was specified, needs trailing backslash otherwise current dir of that drive is used
			if ((TCHAR)':' == lpszFindFileName[lpFatherFC->cchFileName - 1]) {
				lpszFindFileName[lpFatherFC->cchFileName] = (TCHAR)'\\';
				lpszFindFileName[lpFatherFC->cchFileName + 1] = (TCHAR)'\0';
			}
			//printf("lpszFullName: %ws\n", lpszFullName);
			//printf("lpszFindFileName: %ws\n", lpszFindFileName);

			hFile = FindFirstFile(lpszFullName, &FindData);
			if (INVALID_HANDLE_VALUE != hFile) {
				FindClose(hFile);
			}
			else {
				// Workaround for some cases in Windows Vista and later
				ZeroMemory(&FindData, sizeof(FindData));
				
				hFile = CreateFile(lpszFullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
				if (INVALID_HANDLE_VALUE != hFile) {
					BY_HANDLE_FILE_INFORMATION FileInformation;
					BOOL bResult;

					bResult = GetFileInformationByHandle(hFile, &FileInformation);
					if (bResult) {
						FindData.dwFileAttributes = FileInformation.dwFileAttributes;
						FindData.ftCreationTime = FileInformation.ftCreationTime;
						FindData.ftLastAccessTime = FileInformation.ftLastAccessTime;
						FindData.ftLastWriteTime = FileInformation.ftLastWriteTime;
						FindData.nFileSizeHigh = FileInformation.nFileSizeHigh;
						FindData.nFileSizeLow = FileInformation.nFileSizeLow;
					}
					else {
						FindData.dwFileAttributes = GetFileAttributes(lpszFullName);
						if (INVALID_FILE_ATTRIBUTES == FindData.dwFileAttributes) {
							FindData.dwFileAttributes = 0;
						}
						bResult = GetFileTime(hFile, &FindData.ftCreationTime, &FindData.ftLastAccessTime, &FindData.ftLastWriteTime);
						if (!bResult) {
							FindData.ftCreationTime.dwLowDateTime = 0;
							FindData.ftCreationTime.dwHighDateTime = 0;
							FindData.ftLastAccessTime.dwLowDateTime = 0;
							FindData.ftLastAccessTime.dwHighDateTime = 0;
							FindData.ftLastWriteTime.dwLowDateTime = 0;
							FindData.ftLastWriteTime.dwHighDateTime = 0;
						}
						FindData.nFileSizeLow = GetFileSize(hFile, &FindData.nFileSizeHigh);
						if (INVALID_FILE_SIZE == FindData.nFileSizeLow) {
							FindData.nFileSizeHigh = 0;
							FindData.nFileSizeLow = 0;
						}
					}
					CloseHandle(hFile);
				}
			}

			// Remove previously added backslash (if any)
			lpszFindFileName[lpFatherFC->cchFileName] = (TCHAR)'\0';

			// Copy pointer to current file into caller's pointer
			if (NULL != lplpCaller) {
				*lplpCaller = lpFatherFC;
			}
			          
			// Increase dir/file count
			if (ISFILE(FindData.dwFileAttributes)) {
				lpShot->stCounts.cFiles++;
			}
			else {
				lpShot->stCounts.cDirs++;
			}

			// Copy file name
			lpFatherFC->lpszFileName = MYALLOC((lpFatherFC->cchFileName + 1) * sizeof(TCHAR));
			_tcscpy(lpFatherFC->lpszFileName, lpszFullName);

			// Copy file data
			lpFatherFC->nWriteDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime;
			lpFatherFC->nWriteDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime;
			lpFatherFC->nAccessDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime;
			lpFatherFC->nAccessDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime;
			lpFatherFC->nFileSizeLow = FindData.nFileSizeLow;
			lpFatherFC->nFileSizeHigh = FindData.nFileSizeHigh;
			lpFatherFC->nFileAttributes = FindData.dwFileAttributes;

			// Set "lpFirstSubFC" pointer for storing the first child's pointer
			lplpCaller = &lpFatherFC->lpFirstSubFC;
		}

		// If father is a file, then leave (=special case when called from FileShot)
		if (ISFILE(lpFatherFC->nFileAttributes)) {
			if (NULL != lpszFindFileName) {
				MYFREE(lpszFindFileName);
			}
			return;
		}

		// Process all entries of directory
		// a) Create search pattern and start search
		if (NULL == lpszFindFileName) {
			lpszFindFileName = lpszFullName;
		}
		_tcscat(lpszFindFileName, TEXT("\\*.*"));
		hFile = FindFirstFile(lpszFindFileName, &FindData);
		if (lpszFindFileName != lpszFullName) {
			MYFREE(lpszFindFileName);
		}
	}  // End of extra local block
	if (INVALID_HANDLE_VALUE == hFile) {  
		// error: nothing in dir, no access, etc.
		//printf(">>> ERROR: fileshot.c: getFileSnap: INVALID_HANDLE_VALUE: %ws\n", lpszFullName);
		return;
	}
	// b) process entry then find next
	do {
		lpszFullName = NULL;
		//BOOL calculateHash = TRUE;
		//BOOL found = FALSE;

		// Check if file is to be GENERIC excluded (dot dirs)
		if ((NULL == FindData.cFileName)
			|| (((TCHAR)'.' == FindData.cFileName[0])  // fast exclusion for 99% of the cases
			&& ((0 == _tcscmp(FindData.cFileName, TEXT(".")))
			|| (0 == _tcscmp(FindData.cFileName, TEXT("..")))))) {
			continue;  // ignore this entry and continue with next file
		}

		// Create new file content
		lpFC = MYALLOC0(sizeof(FILECONTENT));
		// Set father of current key
		lpFC->lpFatherFC = lpFatherFC;
		// Set file name length
		lpFC->cchFileName = _tcslen(FindData.cFileName);

		// Allocate memory copy file name to FILECONTENT
		lpFC->lpszFileName = MYALLOC0((lpFC->cchFileName + 1) * sizeof(TCHAR));
		_tcscpy(lpFC->lpszFileName, FindData.cFileName);

		// Static blacklist for directories
		if (ISDIR(FindData.dwFileAttributes))
		{
			if (performStaticBlacklisting)
			{
				LPTSTR lpszFullPath;
				lpszFullPath = GetWholeFileName(lpFC, 4);

				found = TrieSearchPath(blacklistDIRS->children, lpszFullPath);
				if (found)
				{
					lpShot->stCounts.cFilesBlacklist++;
					MYFREE(lpszFullPath);
					FreeAllFileContents(lpFC);

					// Increase value count for display purposes
					lpShot->stCounts.cDirsBlacklist++;
					
					// Ignore this entry and continue with next brother value
					continue;  
				}
				else
				{
					MYFREE(lpszFullPath);
				}
			}
		}

		// Check if the file system entry is a symbolic link
		// If so, skip as it actually resides somewhere else on the file system!
		if (ISSYM(FindData.dwFileAttributes)) {
			if (ISFILE(FindData.dwFileAttributes)) {
				lpShot->stCounts.cFilesBlacklist++;
			}
			else {
				lpShot->stCounts.cDirsBlacklist++;
			}
			continue;
		}

		// Blacklisting implementation for files		
		if (ISFILE(FindData.dwFileAttributes))
		{
			if (dwBlacklist == 1)
			{
				// First snapshot, therefore populate the Trie (Prefix Tree)
				// Get the full file path
				LPTSTR lpszFullPath;
				lpszFullPath = GetWholeFileName(lpFC, 4);

				// Add full path to file blacklist prefix tree, then free path
				TrieAdd(&blacklistFILES, lpszFullPath);
				MYFREE(lpszFullPath);

				// Increase value count for display purposes
				lpShot->stCounts.cFiles++;

				// Ignore this entry and continue with next brother value
				//continue;  
			}
			else if (dwBlacklist == 2)
			{
				// Not the first snapshot, so either:
				// 1) If blacklisting enabled: Ignore file if its in the blacklist
				// 2) If hashing enabled (and not blacklisting): Mark file as not to be hashed
				LPTSTR lpszFullPath;
				lpszFullPath = GetWholeFileName(lpFC, 4);
				found = TrieSearchPath(blacklistFILES->children, lpszFullPath);
				if (found)
				{
					if (performDynamicBlacklisting)
					{
						MYFREE(lpszFullPath);
						FreeAllFileContents(lpFC);

						// Increase value count for display purposes
						lpShot->stCounts.cFilesBlacklist++;

						// Ignore this entry and continue with next brother value
						continue;  
					}
					if (performSHA1Hashing || performMD5Hashing)
					{
						lpShot->stCounts.cFiles++;
						MYFREE(lpszFullPath);
						calculateHash = FALSE;
					}
				}
				else
				{
					MYFREE(lpszFullPath);
				}
			}
		}
					
		// Copy pointer to current file into caller's pointer
		if (NULL != lplpCaller) {
			*lplpCaller = lpFC;
		}

		// Increase dir/file count
		if (ISFILE(FindData.dwFileAttributes)) {
			lpShot->stCounts.cFiles++;
		}
		else {
			lpShot->stCounts.cDirs++;
		}

		// Copy file data
		lpFC->nWriteDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime;
		lpFC->nWriteDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime;
		lpFC->nAccessDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime;
		lpFC->nAccessDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime;
		lpFC->nFileSizeLow = FindData.nFileSizeLow;
		lpFC->nFileSizeHigh = FindData.nFileSizeHigh;
		lpFC->nFileAttributes = FindData.dwFileAttributes;

		// Calculate file hash (computationally intensive!)
		// This should only be executed in the following scenarios:
		// 1) If the file system entry is a data file 
		// 2) If the data file is not blacklisted (previously known)
		if (ISFILE(FindData.dwFileAttributes))
		{
			if (dwBlacklist == 2 && calculateHash) {
			    if (performSHA1Hashing)
			    {
				    lpFC->cchSHA1 = 40;
				    lpFC->lpszSHA1 = MYALLOC((lpFC->cchSHA1 + 1) * sizeof(TCHAR));
				    _tcscpy(lpFC->lpszSHA1, CalculateSHA1(GetWholeFileName(lpFC, 4)));
                }
                if (performMD5Hashing)
                {
				    lpFC->cchMD5 = 32;
				    lpFC->lpszMD5 = MYALLOC((lpFC->cchMD5 + 1) * sizeof(TCHAR));
				    _tcscpy(lpFC->lpszMD5, CalculateMD5(GetWholeFileName(lpFC, 4)));
				}
				if (performMD5BlockHashing)
				{
					LPMD5BLOCK theMD5Block = CalculateMD5Blocks(GetWholeFileName(lpFC, 4), dwHashBlockSize);
					lpFC->lpMD5Block = MYALLOC0(sizeof(MD5BLOCK));
					lpFC->lpMD5Block = theMD5Block;
				}
			}
		}

		// Print file system shot status
		if ((dwBlacklist == 2 && performDynamicBlacklisting) || (performStaticBlacklisting)) {
			printf("  > Dirs: %d  Files: %d  Blacklisted Dirs: %d  Blacklisted Files: %d\r", lpShot->stCounts.cDirs, 
				lpShot->stCounts.cFiles,
				lpShot->stCounts.cDirsBlacklist,
				lpShot->stCounts.cFilesBlacklist);
		}
		else {
			printf("  > Dirs: %d  Files: %d\r", lpShot->stCounts.cDirs, lpShot->stCounts.cFiles);
		}

		// ATTENTION!!! FindData will be INVALID from this point on, due to recursive calls
		// If the entry is a directory, then do a recursive call for it
		// Pass this entry as father and "lpFirstSubFC" pointer for storing the first child's pointer
		if (ISDIR(lpFC->nFileAttributes)) {
			if (NULL == lpszFullName) {
				lpszFullName = GetWholeFileName(lpFC, 4);  // +4 for "\*.*" search (in recursive call)
			}
			GetFilesSnap(lpShot, lpszFullName, lpFC, &lpFC->lpFirstSubFC);
		}

		if (NULL != lpszFullName) {
			MYFREE(lpszFullName);
		}

		// Set "lpBrotherFC" pointer for storing the next brother's pointer
		lplpCaller = &lpFC->lpBrotherFC;
	} while (FindNextFile(hFile, &FindData));
	FindClose(hFile);
}
예제 #8
0
static int
amatch(char *s, char *p)
{
	int scc;
	int ok, lc, c, cc;
	char *spathp;
	struct stat stb;

	expany = 1;
	for (;;) {
		scc = *s++ & TRIM;
		switch (c = *p++) {

		case '{':
			return (execbrc(p - 1, s - 1));

		case '[':
			ok = 0;
			lc = 077777;
			while ((cc = *p++)) {
				if (cc == ']') {
					if (ok)
						break;
					return (0);
				}
				if (cc == '-') {
					if (lc <= scc && scc <= *p++)
						ok++;
				} else
					if (scc == (lc = cc))
						ok++;
			}
			if (cc == 0) {
				yyerror("Missing ']'");
				return (0);
			}
			continue;

		case '*':
			if (!*p)
				return (1);
			if (*p == '/') {
				p++;
				goto slash;
			}
			for (s--; *s; s++)
				if (amatch(s, p))
					return (1);
			return (0);

		case '\0':
			return (scc == '\0');

		default:
			if ((c & TRIM) != scc)
				return (0);
			continue;

		case '?':
			if (scc == '\0')
				return (0);
			continue;

		case '/':
			if (scc)
				return (0);
slash:
			s = entp;
			spathp = pathp;
			while (*s)
				addpath(*s++);
			addpath('/');
			if (stat(path, &stb) == 0 && ISDIR(stb.st_mode)) {
				if (*p == '\0') {
					if (which & E_TILDE)
						Cat(path, "");
					else
						Cat(tilde, tpathp);
				} else
					expsh(p);
			}
			pathp = spathp;
			*pathp = '\0';
			return (0);
		}
	}
}