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; }
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); }
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); }
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; }
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; }
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); }
// ---------------------------------------------------------------------- // 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); }
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); } } }