Ejemplo n.º 1
0
/**
 * Gets all meta data for a file and returns a filled meta_data_t *
 * structure.
 * @param file_event is the structure that contains directory and fileinfo
 *        structures. directory is the directory we are iterating over. It
 *        is used here to build the filename name. fileinfo is a glib
 *        structure that contains all meta data and more for a file.
 * @param filter is a structure containing all structures needed to filter
 *        files as database, regex_exclude_list and contains a boolean
 *        that is set to TRUE if the file has been filtered out and FALSE
 *        otherwise.
 * @param opt are the selected options for the program.
 * @returns a newly allocated and filled meta_data_t * structure.
 */
static meta_data_t *get_meta_data_from_fileinfo(file_event_t *file_event, filter_file_t *filter, options_t *opt)
{
    meta_data_t *meta = NULL;
    gchar *directory = NULL;
    GFileInfo *fileinfo = NULL;

    if (file_event != NULL)
    {
        directory = file_event->directory;
        fileinfo = file_event->fileinfo;
    }

    if (directory != NULL && fileinfo != NULL &&  filter != NULL && filter->database != NULL)
    {
        /* filling meta data for the file represented by fileinfo */
        meta = new_meta_data_t();

        meta->file_type = g_file_info_get_file_type(fileinfo);
        meta->name = g_build_path(G_DIR_SEPARATOR_S, directory, g_file_info_get_name(fileinfo), NULL);

        if (exclude_file(filter->regex_exclude_list, meta->name) == FALSE)
        {
            /* fills meta_data_t *meta structure */
            get_file_attributes(meta, fileinfo);
            meta->blocksize = calculate_file_blocksize(opt, meta->size);

            /* We need to determine if the file has already been saved by looking into the local database
             * This is usefull only when carving directories at the begining of the process as when called
             * by m_fanotify we already know that the file was written and that something changed.
             */
            meta->in_cache = is_file_in_cache(filter->database, meta);
            filter->excluded = FALSE;
        }
        else
        {
            filter->excluded = TRUE;
        }
    }

    return meta;
}
Ejemplo n.º 2
0
Archivo: rmbin.c Proyecto: olebole/iraf
/* RMBIN -- Remove all binaries in a directory or in a directory tree.
 * We chdir to each directory to minimize path searches.
 */
static void
rmbin (
    char *dir, 
    int	  recurse, 
    char *path 			/* pathname of current directory */
)
{
	char	newpath[SZ_PATHNAME+1];
	char	fname[SZ_PATHNAME+1];
	int	dp, ftype;

	if ((dp = os_diropen (dir)) == ERR) {
	    fprintf (stderr, "cannot open directory `%s'\n", dir);
	    fflush (stderr);
	    return;
	}

	sprintf (newpath, "%s%s/", path, dir);

	/* Descend into the subdirectory.
	 */
	if (strcmp (dir, ".") != 0)
	    if (os_chdir (dir) == ERR) {
		os_dirclose (dp);
		fprintf (stderr, "cannot change directory to `%s'\n", newpath);
		fflush (stderr);
		return;
	    }

	/* Scan through the directory.
	 */
	while (os_gfdir (dp, fname, SZ_PATHNAME) > 0) {
	    if (os_symlink (fname, 0, 0))
		continue;

	    if ((ftype = os_filetype (fname)) == DIRECTORY_FILE)
		rmbin (fname, recurse, newpath);
	    else {
		if (only[0] != NULL) {
		    if (exclude_file (fname))
			continue;
		} else if (ftype != BINARY_FILE || exclude_file (fname))
		    continue;

		/* We have a binary file which is not excluded from deletion
		 * by its extension, so delete it.
		 */
		if (interactive && (verify_delete (fname, newpath) == NO))
		    continue;

		if (verbose) {
		    printf ("%s%s\n", newpath, fname);
		    fflush (stdout);
		}

		if (execute)
		    if (os_delete (fname) == ERR) {
			fprintf (stderr, "cannot delete `%s'\n", fname);
			fflush (stderr);
		    }
	    }
	}

	/* Return from the subdirectory.
	 */
	if (strcmp (dir, ".") != 0)
	    if (os_chdir ("..") == ERR) {
		fprintf (stderr, "cannot return from subdirectory `%s'\n",
		    newpath);
		fflush (stderr);
	    }

	os_dirclose (dp);
}
Ejemplo n.º 3
0
static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statbuf,
			void *userData, int depth UNUSED_PARAM)
{
	struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData;
	const char *header_name;
	int inputFileFd = -1;

	/* Strip leading '/' (must be before memorizing hardlink's name) */
	header_name = fileName;
	while (header_name[0] == '/') {
		static smallint warned;

		if (!warned) {
			bb_error_msg("removing leading '/' from member names");
			warned = 1;
		}
		header_name++;
	}

	if (header_name[0] == '\0')
		return TRUE;

	/* It is against the rules to archive a socket */
	if (S_ISSOCK(statbuf->st_mode)) {
		bb_error_msg("%s: socket ignored", fileName);
		return TRUE;
	}

	/*
	 * Check to see if we are dealing with a hard link.
	 * If so -
	 * Treat the first occurance of a given dev/inode as a file while
	 * treating any additional occurances as hard links.  This is done
	 * by adding the file information to the HardLinkInfo linked list.
	 */
	tbInfo->hlInfo = NULL;
	if (statbuf->st_nlink > 1) {
		tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf);
		if (tbInfo->hlInfo == NULL)
			addHardLinkInfo(&tbInfo->hlInfoHead, statbuf, header_name);
	}

	/* It is a bad idea to store the archive we are in the process of creating,
	 * so check the device and inode to be sure that this particular file isn't
	 * the new tarball */
	if (tbInfo->statBuf.st_dev == statbuf->st_dev
	 && tbInfo->statBuf.st_ino == statbuf->st_ino
	) {
		bb_error_msg("%s: file is the archive; skipping", fileName);
		return TRUE;
	}

	if (exclude_file(tbInfo->excludeList, header_name))
		return SKIP;

#if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS
	if (strlen(header_name) >= NAME_SIZE) {
		bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported");
		return TRUE;
	}
#endif

	/* Is this a regular file? */
	if (tbInfo->hlInfo == NULL && S_ISREG(statbuf->st_mode)) {
		/* open the file we want to archive, and make sure all is well */
		inputFileFd = open_or_warn(fileName, O_RDONLY);
		if (inputFileFd < 0) {
			return FALSE;
		}
	}

	/* Add an entry to the tarball */
	if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) {
		return FALSE;
	}

	/* If it was a regular file, write out the body */
	if (inputFileFd >= 0) {
		size_t readSize;
		/* Write the file to the archive. */
		/* We record size into header first, */
		/* and then write out file. If file shrinks in between, */
		/* tar will be corrupted. So we don't allow for that. */
		/* NB: GNU tar 1.16 warns and pads with zeroes */
		/* or even seeks back and updates header */
		bb_copyfd_exact_size(inputFileFd, tbInfo->tarFd, statbuf->st_size);
		////off_t readSize;
		////readSize = bb_copyfd_size(inputFileFd, tbInfo->tarFd, statbuf->st_size);
		////if (readSize != statbuf->st_size && readSize >= 0) {
		////	bb_error_msg_and_die("short read from %s, aborting", fileName);
		////}

		/* Check that file did not grow in between? */
		/* if (safe_read(inputFileFd, 1) == 1) warn but continue? */

		close(inputFileFd);

		/* Pad the file up to the tar block size */
		/* (a few tricks here in the name of code size) */
		readSize = (-(int)statbuf->st_size) & (TAR_BLOCK_SIZE-1);
		memset(block_buf, 0, readSize);
		xwrite(tbInfo->tarFd, block_buf, readSize);
	}

	return TRUE;
}
Ejemplo n.º 4
0
static int writeFileToTarball(const char *fileName, struct stat *statbuf,
							  void *userData)
{
	struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData;
	const char *header_name;

	/*
	   ** Check to see if we are dealing with a hard link.
	   ** If so -
	   ** Treat the first occurance of a given dev/inode as a file while
	   ** treating any additional occurances as hard links.  This is done
	   ** by adding the file information to the HardLinkInfo linked list.
	 */
	tbInfo->hlInfo = NULL;
	if (statbuf->st_nlink > 1) {
		tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf);
		if (tbInfo->hlInfo == NULL)
			addHardLinkInfo(&tbInfo->hlInfoHead, statbuf, fileName);
	}

	/* It is against the rules to archive a socket */
	if (S_ISSOCK(statbuf->st_mode)) {
		bb_error_msg("%s: socket ignored", fileName);
		return (TRUE);
	}

	/* It is a bad idea to store the archive we are in the process of creating,
	 * so check the device and inode to be sure that this particular file isn't
	 * the new tarball */
	if (tbInfo->statBuf.st_dev == statbuf->st_dev &&
		tbInfo->statBuf.st_ino == statbuf->st_ino) {
		bb_error_msg("%s: file is the archive; skipping", fileName);
		return (TRUE);
	}

	header_name = fileName;
	while (header_name[0] == '/') {
		static int alreadyWarned = FALSE;

		if (alreadyWarned == FALSE) {
			bb_error_msg("Removing leading '/' from member names");
			alreadyWarned = TRUE;
		}
		header_name++;
	}

	if (strlen(fileName) >= NAME_SIZE) {
		bb_error_msg(bb_msg_name_longer_than_foo, NAME_SIZE);
		return (TRUE);
	}

	if (header_name[0] == '\0')
		return TRUE;

# ifdef CONFIG_FEATURE_TAR_FROM
	if (exclude_file(tbInfo->excludeList, header_name)) {
		return SKIP;
	}
# endif							/* CONFIG_FEATURE_TAR_FROM */

	if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) {
		return (FALSE);
	}

	/* Now, if the file is a regular file, copy it out to the tarball */
	if ((tbInfo->hlInfo == NULL)
		&& (S_ISREG(statbuf->st_mode))) {
		int inputFileFd;
		ssize_t readSize = 0;

		/* open the file we want to archive, and make sure all is well */
		if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
			bb_perror_msg("%s: Cannot open", fileName);
			return (FALSE);
		}

		/* write the file to the archive */
		readSize = bb_copyfd_eof(inputFileFd, tbInfo->tarFd);

		/* Pad the file up to the tar block size */
		for (; (readSize % TAR_BLOCK_SIZE) != 0; readSize++) {
			write(tbInfo->tarFd, "\0", 1);
		}
		close(inputFileFd);
	}

	return (TRUE);
}
Ejemplo n.º 5
0
/*
 * Read a tar file and extract or list the specified files within it.
 * If the list is empty than all files are extracted or listed.
 */
static int readTarFile(int tarFd, int extractFlag, int listFlag, 
		int tostdoutFlag, int verboseFlag, char** extractList,
		char** excludeList)
{
	int status;
	int errorFlag=FALSE;
	int skipNextHeaderFlag=FALSE;
	TarHeader rawHeader;
	TarInfo header;

	/* Read the tar file, and iterate over it one file at a time */
	while ( (status = full_read(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) {

		/* Try to read the header */
		if ( readTarHeader(&rawHeader, &header) == FALSE ) {
			if ( *(header.name) == '\0' ) {
				goto endgame;
			} else {
				errorFlag=TRUE;
				error_msg("Bad tar header, skipping");
				continue;
			}
		}
		if ( *(header.name) == '\0' )
			continue;
		header.tarFd = tarFd;

		/* Skip funky extra GNU headers that precede long files */
		if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) {
			skipNextHeaderFlag=TRUE;
			if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
				errorFlag = TRUE;
			continue;
		}
		if ( skipNextHeaderFlag == TRUE ) { 
			skipNextHeaderFlag=FALSE;
			error_msg(name_longer_than_foo, NAME_SIZE); 
			if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
				errorFlag = TRUE;
			continue;
		}

#if defined BB_FEATURE_TAR_EXCLUDE
		if (exclude_file(excludeList, header.name)) {
			/* There are not the droids you're looking for, move along */
			/* If it is a regular file, pretend to extract it with
			 * the extractFlag set to FALSE, so the junk in the tarball
			 * is properly skipped over */
			if ( header.type==REGTYPE || header.type==REGTYPE0 ) {
				if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
					errorFlag = TRUE;
			}
			continue;
		}
#endif

		if (!extract_file(extractList, header.name)) {
			/* There are not the droids you're looking for, move along */
			/* If it is a regular file, pretend to extract it with
			 * the extractFlag set to FALSE, so the junk in the tarball
			 * is properly skipped over */
			if ( header.type==REGTYPE || header.type==REGTYPE0 ) {
				if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
					errorFlag = TRUE;
			}
			continue;
		}

		if (listFlag == TRUE) {
			/* Special treatment if the list (-t) flag is on */
			if (verboseFlag == TRUE) {
				int len, len1;
				char buf[35];
				struct tm *tm = localtime (&(header.mtime));

				len=printf("%s ", mode_string(header.mode));
				my_getpwuid(buf, header.uid);
				if (! *buf)
					len+=printf("%d", header.uid);
				else
					len+=printf("%s", buf);
				my_getgrgid(buf, header.gid);
				if (! *buf)
					len+=printf("/%-d ", header.gid);
				else
					len+=printf("/%-s ", buf);

				if (header.type==CHRTYPE || header.type==BLKTYPE) {
					len1=snprintf(buf, sizeof(buf), "%ld,%-ld ", 
							header.devmajor, header.devminor);
				} else {
					len1=snprintf(buf, sizeof(buf), "%lu ", (long)header.size);
				}
				/* Jump through some hoops to make the columns match up */
				for(;(len+len1)<31;len++)
					printf(" ");
				printf(buf);

				/* Use ISO 8610 time format */
				if (tm) { 
					printf ("%04d-%02d-%02d %02d:%02d:%02d ", 
							tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 
							tm->tm_hour, tm->tm_min, tm->tm_sec);
				}
			}
			printf("%s", header.name);
			if (verboseFlag == TRUE) {
				if (header.type==LNKTYPE)	/* If this is a link, say so */
					printf(" link to %s", header.linkname);
				else if (header.type==SYMTYPE)
					printf(" -> %s", header.linkname);
			}
			printf("\n");
		}

		/* List contents if we are supposed to do that */
		if (verboseFlag == TRUE && extractFlag == TRUE) {
			/* Now the normal listing */
			FILE *vbFd = stdout;
			if (tostdoutFlag == TRUE)	// If the archive goes to stdout, verbose to stderr
				vbFd = stderr;
			fprintf(vbFd, "%s\n", header.name);
		}
			
		/* Remove files if we would overwrite them */
		if (extractFlag == TRUE && tostdoutFlag == FALSE)
			unlink(header.name);

		/* If we got here, we can be certain we have a legitimate 
		 * header to work with.  So work with it.  */
		switch ( header.type ) {
			case REGTYPE:
			case REGTYPE0:
				/* If the name ends in a '/' then assume it is
				 * supposed to be a directory, and fall through */
				if (!last_char_is(header.name,'/')) {
					if (tarExtractRegularFile(&header, extractFlag, tostdoutFlag)==FALSE)
						errorFlag=TRUE;
					break;
				}
			case DIRTYPE:
				if (tarExtractDirectory( &header, extractFlag, tostdoutFlag)==FALSE)
					errorFlag=TRUE;
				break;
			case LNKTYPE:
				if (tarExtractHardLink( &header, extractFlag, tostdoutFlag)==FALSE)
					errorFlag=TRUE;
				break;
			case SYMTYPE:
				if (tarExtractSymLink( &header, extractFlag, tostdoutFlag)==FALSE)
					errorFlag=TRUE;
				break;
			case CHRTYPE:
			case BLKTYPE:
			case FIFOTYPE:
				if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)
					errorFlag=TRUE;
				break;
#if 0
			/* Handled earlier */
			case GNULONGNAME:
			case GNULONGLINK:
				skipNextHeaderFlag=TRUE;
				break;
#endif
			default:
				error_msg("Unknown file type '%c' in tar file", header.type);
				close( tarFd);
				return( FALSE);
		}
	}
	close(tarFd);
	if (status > 0) {
		/* Bummer - we read a partial header */
		perror_msg("Error reading tar file");
		return ( FALSE);
	}
	else if (errorFlag==TRUE) {
		error_msg( "Error exit delayed from previous errors");
		return( FALSE);
	} else 
		return( status);

	/* Stuff to do when we are done */
endgame:
	close( tarFd);
	if ( *(header.name) == '\0' ) {
		if (errorFlag==TRUE)
			error_msg( "Error exit delayed from previous errors");
		else
			return( TRUE);
	} 
	return( FALSE);
}