Beispiel #1
0
/*
 * Traverse() walks the logical directory structure specified by the argv list
 * in the order specified by the mastercmp() comparison function.  During the
 * traversal it passes linked lists of structures to display() which represent
 * a superset (may be exact set) of the files to be displayed.
 */
static void
traverse(int argc, char *argv[], int options)
{
    FTS *ftsp;
    FTSENT *p, *chp;
    int ch_options;

    if ((ftsp =
                fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
        err(EXIT_FAILURE, NULL);

    display(NULL, fts_children(ftsp, 0));
    if (f_listdir)
        return;

    /*
     * If not recursing down this tree and don't need stat info, just get
     * the names.
     */
    ch_options = !f_recursive && options & FTS_NOSTAT ? FTS_NAMEONLY : 0;

    while ((p = fts_read(ftsp)) != NULL)
        switch (p->fts_info) {
        case FTS_DC:
            warnx("%s: directory causes a cycle", p->fts_name);
            break;
        case FTS_DNR:
        case FTS_ERR:
            warnx("%s: %s", p->fts_name, strerror(p->fts_errno));
            rval = EXIT_FAILURE;
            break;
        case FTS_D:
            if (p->fts_level != FTS_ROOTLEVEL &&
                    p->fts_name[0] == '.' && !f_listdot)
                break;

            /*
             * If already output something, put out a newline as
             * a separator.  If multiple arguments, precede each
             * directory with its name.
             */
            if (output)
                (void)printf("\n%s:\n", p->fts_path);
            else if (argc > 1) {
                (void)printf("%s:\n", p->fts_path);
                output = 1;
            }

            chp = fts_children(ftsp, ch_options);
            display(p, chp);

            if (!f_recursive && chp != NULL)
                (void)fts_set(ftsp, p, FTS_SKIP);
            break;
        }
    if (errno)
        err(EXIT_FAILURE, "fts_read");
}
Beispiel #2
0
/////////////////////////////////////////////////////////////
// Count the number of files for header length calculation
/////////////////////////////////////////////////////////////
static int countFiles(char **source)
{
  FTS *ftsp;
  FTSENT *p, *chp;
  int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;

  if ((ftsp = fts_open(source, fts_options, NULL)) == NULL) {
    warn("fts_open");
    return -1;
  }

  /* Initialize ftsp with as many argv[] parts as possible. */
  chp = fts_children(ftsp, 0);
  if (chp == NULL) {
    return 0;               /* no files to traverse */
  }

  while ((p = fts_read(ftsp)) != NULL)
    {
      switch (p->fts_info) {
      case FTS_F:

        if(strstr(p->fts_path, "DS_Store") == NULL) //wasn't a DS_Store file.
          {
            //increment the file count
            fileCountForHeader++;
          }
        break;
      default:
        break;
      }
    }
  fts_close(ftsp);
  return 0;
}
Beispiel #3
0
static int remove_dir_recursively(char *dirname) {
        FTS *ftsp;
        FTSENT *p, *chp;
        int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;
        
        if ((ftsp = fts_open(&dirname, fts_options, NULL)) == NULL) {
                perror("fts_open");
                return -1;
        }
        chp = fts_children(ftsp, 0);
        if (chp == NULL) {
                fts_close(ftsp);
                rmdir(dirname);
                return 0;
        }
        while ((p = fts_read(ftsp)) != NULL) {
                switch (p->fts_info) {
                case FTS_D:
                        if (strcmp(dirname, p->fts_path)) {
                                remove_dir_recursively(p->fts_path);
                                rmdir(p->fts_path);
                        }
                        break;
                case FTS_F:
                        unlink(p->fts_path);
                        break;
                default:
                        break;
                }
        }
        fts_close(ftsp);
        rmdir(dirname);
        return 0;
}
void runSuccess() {
    char* argv[] = {anystring(), anystring(), NULL};
    //@ assert \exists int i; (argv[i] == \null);
    FTS* fts = fts_open(argv, anyint(), NULL);
    if (fts != NULL) {
        fts_children(fts, anyint());
    }
}
Beispiel #5
0
Datei: ls.c Projekt: Kaikaiw/apue
/* using fts library to traverse file hierarchies */
static void
traverse(int argc, char **argv, int options)
{
    FTS *dp;
    FTSENT *p, *chp;
    more=0;

    if ((dp=fts_open(argv, options, f_notsort ? NULL : comp))==NULL)
        err(-1, NULL);
    /**
     * print minus 1 level's children, if -d is specified
     * print files and directories, or only print files
     */
    chp=fts_children(dp, 0);
    display(NULL, chp);

    while (!f_plaintext && (p=fts_read(dp))!=NULL)
        switch (p->fts_info) {
            case FTS_DNR:
            case FTS_ERR: warn("%s", p->fts_path);
                break;
            case FTS_DC: warn("%s directory causes a cycle", p->fts_path);
                break;
            case FTS_D:
                /* do not jump over dot-start root provided to ls command */
                if (p->fts_level!=0 && p->fts_name[0]=='.' && !f_allentry) {
                    fts_set(dp, p, FTS_SKIP);
                    break;
                }
                if (more)
                    printf("\n%s:\n", p->fts_path);
                else if (argc>1 || f_recurse)
                    printf("%s:\n", p->fts_path);
                display(p, fts_children(dp, 0));
                if (!f_recurse)
                    fts_set(dp, p, FTS_SKIP);
                break;
            default:
                break;
        }

    fts_close(dp);
}
Beispiel #6
0
bool platform_directory_delete(const utf8 *path)
{
	log_verbose("Recursively deleting directory %s", path);

	FTS *ftsp;
	FTSENT *p, *chp;

	// fts_open only accepts non const paths, so we have to take a copy
	char* ourPath = (char*)malloc(strlen(path) + 1);
	strcpy(ourPath, path);

	utf8* const patharray[2] = {ourPath, NULL};
	if ((ftsp = fts_open(patharray, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, NULL)) == NULL) {
		log_error("fts_open returned NULL");
		free(ourPath);
		return false;
	}

	chp = fts_children(ftsp, 0);
	if (chp == NULL) {
		log_verbose("No files to traverse, deleting directory %s", path);
		if (remove(path) != 0)
		{
			log_error("Failed to remove %s, errno = %d", path, errno);
		}
		free(ourPath);
		return true; // No files to traverse
	}

	while ((p = fts_read(ftsp)) != NULL) {
		switch (p->fts_info) {
			case FTS_DP: // Directory postorder, which means
						 // the directory is empty
						 
			case FTS_F:  // File
				if(remove(p->fts_path)) {
					log_error("Could not remove %s", p->fts_path);
					fts_close(ftsp);
					free(ourPath);
					return false;
				}
				break;
			case FTS_ERR:
				log_error("Error traversing %s", path);
				fts_close(ftsp);
				free(ourPath);
				return false;
		}
	}

	free(ourPath);
	fts_close(ftsp);

	return true;
}
Beispiel #7
0
int openAndIndexDirectory(char *dir) {
	char *directory;
	directory = (char *) malloc (BUFSIZ);
	directory[0] = '\0';
	strcat(directory, dir);
	
	/*We need this to conform to how fts works*/
	/*fts needs an array of char arrays for some reason*/
	char *directoryArg[2];
	directoryArg[0] = directory;
	directoryArg[1] = NULL;
	
	FTS *ftsp;
	FTSENT *parent, *chp;
	int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;

	printf("DIR ARG IS %s\n",directoryArg);
	if((ftsp = fts_open(directoryArg, fts_options, NULL)) == NULL) {
		warn("fts_open");
		return -1;
	}
	
	/*If no children in directory, return */
	chp = fts_children(ftsp, 0);
	if (chp == NULL) return 0;
	
	char *fullPath;
	
	
	while ((parent = fts_read(ftsp)) != NULL ) {
		
		switch(parent->fts_info) {
			case FTS_F:
				
				fullPath = (char *) malloc( BUFSIZ+1 );

				snprintf(fullPath, BUFSIZ, "%s", parent->fts_path);
				/* strncat(fullPath, parent->fts_name, BUFSIZ - 1); */
				printf("FILE HERE:%s\n",fullPath);
				openAndIndexFile(fullPath);
				break;
			default:
				printf("HMM...\n");
				break;
		}
	}
	
	fts_close(ftsp);
	
	if (fullPath) free (fullPath);
	return 0;

}
void testValues() {
    f = 2;
    
    char* argv[] = {anystring(), anystring(), NULL};
    //@ assert \exists int i; (argv[i] == \null);
    FTS* fts = fts_open(argv, anyint(), NULL);
    if (fts != NULL) {
        FTSENT* ftsent = fts_children(fts, anyint());
        //@ assert ftsent != \null ==> ftsent->fts_level > -1;
        //@ assert ftsent != \null ==> ftsent->fts_number == 0;
        //@ assert ftsent != \null ==> valid_string(ftsent->fts_path);
        //@ assert ftsent != \null ==> ftsent->fts_link == \null || \valid(ftsent->fts_link);
    }
    
    //@ assert f == 2;
    //@ assert vacuous: \false;
}
Beispiel #9
0
/* In order to get a description of each file located in /usr/include using
 * fts.h, the code would be as follows: */
int ftw_simple(char *argv[])
{
	/* assume the path "/usr/include" has been passed through argv[3] */

	FTS *fileStruct;
	FTSENT *dirList;
	int ftsResult;

	fileStruct = fts_open(&argv[3], FTS_COMFOLLOW, 0);
	dirList = fts_children(fileStruct, FTS_NAMEONLY);

	do {
		FTSENT *fileInfo;
		void *result;

		fileInfo = (FTSENT *)fts_read((FTS *)dirList->fts_pointer);

		/* dummy condition to use value stored to 'fileInfo': */
		if (fileInfo == 0) {
			;
		}

		result = malloc(sizeof(int (*)(const FTSENT **, const FTSENT **)));

		/* at this point, you should be able to extract information from the
		 * FTSENT returned by fts_read(): */

		fileStruct = fts_open((char * const *)dirList->fts_link->fts_name,
							  FTS_PHYSICAL, (void *)result);
		/* TODO: write an actual compar() function to use in the 3rd argument
		 * here (see the following quote from the  manpage for fts_open() for
		 * reference: "The argument compar() specifies a user-defined function
		 * which may be used to order the traversal of the hierarchy. It takes
		 * two pointers to pointers to FTSENT structures as arguments and should
		 * return a negative value, zero, or a positive value to indicate if the
		 * file referenced by its first argument comes before, in any order with
		 * respect to, or after, the file referenced by its second argument.") */
		/* (started a stub for it below) */

	} while (dirList->fts_link != NULL);

	ftsResult = fts_close(fileStruct);

	return ftsResult;
}
Beispiel #10
0
int main(int argc, char* const argv[])
{
    FTS* fs = NULL;
    FTSENT* child = NULL;
    FTSENT* parent = NULL;

    if (argc<2)
    {
        printf("Usage: %s <path-spec>\n", argv[0]);
        exit(255);
    }

    fs = fts_open(argv + 1,FTS_COMFOLLOW | FTS_NOCHDIR,&compare);

    if (NULL != fs)
    {
        while( (parent = fts_read(fs)) != NULL)
        {
            child = fts_children(fs,0);

            if (errno != 0)
            {
                perror("fts_children");
            }

            while ((NULL != child)
                && (NULL != child->fts_link))
            {
                child = child->fts_link;
                // char* s = concat(child->fts_path, child->fts_name);
                fd = open(child->fts_name, O_RDONLY);
                fdatasync(fd);
                posix_fadvise(fd, 0,0,POSIX_FADV_DONTNEED);
                printf("%s%s -> POSIX_FADV_DONTNEED\n", child->fts_path,child->fts_name);
				close(fd);

	    }
        }
        fts_close(fs);
    }
    return 0;
}
Beispiel #11
0
static void
children (FTS *fts)
{
  FTSENT *child = fts_children (fts, 0);
  if (child == NULL && errno != 0)
    {
      printf ("FAIL: fts_children: %m\n");
      exit (1);
    }

  while (child != NULL)
    {
      short level = child->fts_level;
      const char *name = child->fts_name;
      if (child->fts_info == FTS_F || child->fts_info == FTS_NSOK)
	{
	  files++;
	  printf ("%*s%s\n", 2 * level, "", name);
	}
      child = child->fts_link;
    }
}
Beispiel #12
0
/*
 * Traverse() walks the logical directory structure specified by the argv list
 * in the order specified by the mastercmp() comparison function.  During the
 * traversal it passes linked lists of structures to display() which represent
 * a superset (may be exact set) of the files to be displayed.
 */
static void
traverse(int argc, char *argv[], int options)
{
	FTS *ftsp;
	FTSENT *p, *chp;
	int ch_options;

	if ((ftsp =
	    fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
		err(1, "fts_open");

	/*
	 * We ignore errors from fts_children here since they will be
	 * replicated and signalled on the next call to fts_read() below.
	 */
	chp = fts_children(ftsp, 0);
	if (chp != NULL)
		display(NULL, chp, options);
	if (f_listdir)
		return;

	/*
	 * If not recursing down this tree and don't need stat info, just get
	 * the names.
	 */
	ch_options = !f_recursive && !f_label &&
	    options & FTS_NOSTAT ? FTS_NAMEONLY : 0;

	while ((p = fts_read(ftsp)) != NULL)
		switch (p->fts_info) {
		case FTS_DC:
			warnx("%s: directory causes a cycle", p->fts_name);
			break;
		case FTS_DNR:
		case FTS_ERR:
			warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
			rval = 1;
			break;
		case FTS_D:
			if (p->fts_level != FTS_ROOTLEVEL &&
			    p->fts_name[0] == '.' && !f_listdot)
				break;

			/*
			 * If already output something, put out a newline as
			 * a separator.  If multiple arguments, precede each
			 * directory with its name.
			 */
			if (output) {
				putchar('\n');
				(void)printname(p->fts_path);
				puts(":");
			} else if (argc > 1) {
				(void)printname(p->fts_path);
				puts(":");
				output = 1;
			}
			chp = fts_children(ftsp, ch_options);
			display(p, chp, options);

			if (!f_recursive && chp != NULL)
				(void)fts_set(ftsp, p, FTS_SKIP);
			break;
		default:
			break;
		}
	if (errno)
		err(1, "fts_read");
}
Beispiel #13
0
static int packageSourceFolder(char **source, char *desintation, char *extensions[], int extCount)
{
  FTS *ftsp;
  FTSENT *p, *chp;
  int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;
  int rval = 0; // remove if unused!
  char line[512];
  FILE *pakFile;
  FILE *file;
  unsigned int start_offset= 0;
  unsigned int f_index=0; // file index

  if (file = fopen(desintation, "r"))
    {
      printf("File exists, would you like to overwrite it y/n ?  ");

      int answer;
      int loop=1;
      fclose(file);

      while (loop){

        answer = getchar();

        switch(answer){
        case 'y':
          loop=0;
          break;
        case 'n':
          printf("Please run Bundle again with the correct output path.\n");
          exit(1);
        case 10: // \n
          break;
        default:
          printf("not sure ? ;) \n (y/n) >");
        }
      }
    }else {
    fclose(file);
  }


  pakFile = fopen(desintation,"wb+");

  printf("\n----------------\n");

  // initialize header with nuber of files
  if ((start_offset=header_init(pakFile, fileCountForHeader)) == -1){
    // perror("bundler_header");
    fprintf(stderr, "Cannot initialize header...exiting\n");
    return 0;
  }

  size_t header_size = fileCountForHeader* HEADER_OFFSET_SIZE + sizeof(int);

  if ((ftsp = fts_open(source, fts_options, NULL)) == NULL) {
    warn("fts_open");
    return -1;
  }

  /* Initialize ftsp with as many argv[] parts as possible. */
  chp = fts_children(ftsp, 0);
  if (chp == NULL) {
    return 0;               /* no files to traverse */
  }

  printf("\nCreating the Bundle\n\n");

  while ((p = fts_read(ftsp)) != NULL)
    {
      int tempFileExists = 0; //used to flag temp file for deletion
      switch (p->fts_info)
        {
        case FTS_D:
          printf(">dir: %s\n\n", p->fts_path);
          printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n");
          printData(pakFile, p->fts_path);
          break;
        case FTS_F:
          if((strstr(p->fts_path, ".DS_Store") != NULL)//ignore DS_Store and exe
             || (strstr(p->fts_path, ".exe") != NULL))
            {
              printf("Found file to ignore: %s\n", p->fts_path);
              printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n");
            }
          else
            {
              printf("\t>file: %s\n", p->fts_path);
              printData(pakFile, p->fts_path);

              FILE *tempFile;

              if(shouldCompressFileType(p->fts_path, extensions, extCount) == 1)
                {
                  /*    compress the fts_path file and write
                        the compressed data one to pak file
                  */
                  compress_one_file(p->fts_path, "temp.txt");
                  tempFile = fopen("temp.txt","rb");
                  tempFileExists = 1;
                }
              else
                {
                  tempFile = fopen(p->fts_path,"rb");
                }
              char byte;

              fseek(pakFile, 0L, SEEK_END);
              off_t offset = ftell(pakFile);

              //get the size of the file
              fseek(tempFile, 0L, SEEK_END);
              long size = ftell(tempFile);
              fseek(tempFile, 0L, SEEK_SET);
              offset= offset;//-HEADER_OFFSET_SIZE;
              char *fileName = p->fts_path;
              char *tempFileName = strdup(fileName);

              //update header
              //offset_p off= malloc(HEADER_OFFSET_SIZE);

              header_offset off;
              off.hash = __ac_X31_hash_string( filename(fileName) );
              off.size= size;
              off.offset_start= offset;

              header_write_offset(pakFile, &off, f_index++);

              // print the file info
              if(tempFileName)
                {
                  printf("\t>The offset for %s is %d\n", tempFileName, (unsigned int)offset);
                  printf("\t>The written size of %s is %lu\n", basename(tempFileName), size);
                  printf("\t>%s was added to the bundle\n\n", basename(tempFileName));
                  printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n");
                  free(tempFileName);
                }

              // copy the data from the temp compressed file to the pak file
              //                    fseek(pakFile, start_offset, SEEK_SET);
              //fseek(pakFile, 0L, SEEK_SET);
              fseek(pakFile, 0L, SEEK_END);

              int d= 0;
              while (!feof(tempFile))
                {

                  fread(&byte, sizeof(char), 1, tempFile);
                  fwrite(&byte, sizeof(char), 1, pakFile);
                }

              fclose(tempFile); // done!

              //delete the temporary file
              if(tempFileExists == 1)
                {
                  if (remove("temp.txt") == -1)
                    perror("Error in deleting temp file");
                }
              break;
            }
        default:
          break;
        }
    }
  fclose(pakFile);
  fts_close(ftsp);
  return 0;
}
Beispiel #14
0
int 
main(int argc, char **argv)
{
	int c;
	char *blkszptr;
	char **path_argv; 
	char *default_dot_path[] = {".", NULL};
	struct winsize win;	
	FTS* ftsptr;
	FTSENT *argv_list;
	FTSENT *cur;
	FTSENT *read;
	int fts_options = FTS_PHYSICAL;
	int (* comp)(const FTSENT** obj1, const FTSENT** obj2);

	/*
	 * get term width
	 * refers to NetBSD's implementation
	 */
	
	if (isatty(STDOUT_FILENO)) {
		if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&win.ws_col > 0) {
			win_width = win.ws_col;			
		}
	}
	comp = sortbyname;
	
	setprogname(argv[0]);

	/* some default setting */
	if (isatty(STDOUT_FILENO)) {
		all_flags.qflag = 1;
		all_flags.Cflag = 1;
	} else {
		all_flags.wflag = 1;
		all_flags.oneflag = 1;
	}

	/*-A always set for super user*/
	if (getuid() == 0) {
		all_flags.Aflag = 1;
	}

	while( (c = getopt(argc, argv, "AacdFfhiklnqRrSstuw1xC")) != -1 ) {
		switch(c) {
		case 'A':
			all_flags.Aflag = 1;
			break;
		case 'a':
			all_flags.aflag = 1;
			break;
		case 'd':
			all_flags.dflag = 1;
			break;
		case 'f':
			comp = NULL;
			all_flags.fflag = 1;
			break;
		case 'F':
			all_flags.Fflag = 1;
			break;
		case 'R':
			all_flags.Rflag = 1;
			break;
		case 'i':
			all_flags.iflag = 1;
			break;
		case 'l':
			//overwrite
			all_flags.nflag = 0;
			all_flags.oneflag  = 0;
			all_flags.Cflag = 0;
			all_flags.xflag = 0;

			all_flags.lflag = 1;
			break;
		case 'n':
			//overwrite
			all_flags.lflag = 0;
			all_flags.oneflag = 0;
			all_flags.Cflag = 0;
			all_flags.xflag = 0;

			all_flags.nflag = 1;
			break;
		case 's':
			all_flags.sflag = 1;
			break;
		case 'S':
			comp = sortbysize;
			all_flags.Sflag = 1;
			break;
		case 'q':
			all_flags.wflag = 0;
			all_flags.qflag = 1;
			break;
		case 'w':
			all_flags.qflag = 0;
			all_flags.wflag = 1;
			break;
		case 't':
			comp = sortbytime;
			all_flags.tflag = 1;
			break;
		case '1':
			all_flags.lflag = 0;
			all_flags.nflag = 0;
			all_flags.oneflag = 1;
			break;
		case 'c':
			all_flags.uflag = 0;
			all_flags.cflag = 1;
			break;
		case 'x':
			//overwirte
			all_flags.oneflag = 0;
			all_flags.lflag = 0;
			all_flags.nflag = 0;
			all_flags.Cflag = 0;

			all_flags.xflag = 1;
			break;
		case 'C':
			//overwrite
			all_flags.oneflag = 0;
			all_flags.lflag = 0;
			all_flags.nflag = 0;
			all_flags.xflag = 0;

			all_flags.Cflag = 1;
			break;
		case 'u':
			all_flags.cflag = 0;
			all_flags.uflag = 1;
			break;
		case 'k':
			all_flags.hflag = 0;
			all_flags.kflag = 1;
			break;
		case 'h':
			all_flags.kflag = 0;
			all_flags.hflag = 1;
			break;
		case 'r':
			all_flags.rflag = 1;
			break;
		default:
			usage();
			break;
		}
	}

	argc -= optind;
	argv += optind;
	
	cldlist_init();

	path_argv = (argc == 0) ? default_dot_path : argv;

	/*set block size, blksize_t shall be signed integer*/
	if ( (blkszptr = getenv("BLOCKSIZE")) != NULL ) {
		blocksize = atoi(blkszptr);
	} else {
		blocksize = DEFAULT_BLOCKSIZE;
	}

	if (all_flags.kflag) {
		divide_term = 1024;
	}
	
	if (all_flags.aflag) {
		fts_options =  fts_options | FTS_SEEDOT;
	}


	if (all_flags.rflag) {
		if (all_flags.Sflag) {
			comp = sortbyrsize;
		} else if (all_flags.tflag) {
			comp = sortbyrsize;
		} else {
			comp = sortbyname;
		}
	}

	if ( (ftsptr = fts_open(path_argv, fts_options, comp)) == NULL) {
		if (errno != 0) {
			(void)fprintf(stderr, "%s: fts_open error %s\n", getprogname(), strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/*the special use case of fts_children, go through all files in the argv list*/
	if ( (argv_list = fts_children(ftsptr, 0)) == NULL ) {
		if (errno != 0) {
			(void)fprintf(stderr, "%s: fts_open error %s\n", getprogname(), strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/*
	 * refer to NetBSD implementation
	 * here we handle all `non-directory` files and error,
	 * leave the directory for the fts_read below 
	 */
	for (cur = argv_list; cur != NULL; cur = cur->fts_link) {

		if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS || cur->fts_info == FTS_DNR) {
			warnx("can't access %s: %s",cur->fts_name, strerror(cur->fts_errno));
			/*
			 * because error message also consider as an output
			 * `outputnum++` will make the directory to output its path name
			 */
			outputnum++;
			continue;
		}
		
		if (!all_flags.dflag && cur->fts_info == FTS_D) {
			/*leave the directory to the fts_read below*/
			outputnum++;
			continue;
		}
		outputentnum++;
		outputnum++;

		cook_entry(cur);
	}
	//Parent = NULL means it's at root level
	traverse_children(NULL);
	

	do{
		if (all_flags.dflag) {
			break;
		}
		/*
		 * handle the directory entry
		 */
		while( (read = fts_read(ftsptr)) != NULL) {
			
			unsigned short info = read->fts_info;
			
			if (info == FTS_DC) {
				warnx("%s causes a cycle in the tree ",read->fts_path);
				continue;
			}

			if (info == FTS_DNR || info == FTS_ERR) {
				warnx("can't access %s: %s",read->fts_path, strerror(read->fts_errno));
				continue;
			}

			if (info == FTS_D) {
				FTSENT* childrenptr;
				childrenptr = fts_children(ftsptr,0);
				
				if (childrenptr == NULL && errno != 0) {	
					/*
					 * if error heppen we don't do anything this moment
					 * error will be printed at the postorder visit
					 */
					continue;
					
				}

				config_output(childrenptr);
				// cook_multi_cols();
				traverse_children(read);
	
				if (!all_flags.Rflag && childrenptr != NULL) {
					if (fts_set(ftsptr, read, FTS_SKIP) != 0) {
						(void)fprintf(stderr, "%s: fts_set error %s\n", getprogname(), strerror(errno));
						exit(EXIT_FAILURE);
					}
				}
			}
		}
	}while(0);

	if (read == NULL && errno != 0) {
		(void)fprintf(stderr, "%s: fts_read error %s\n", getprogname(), strerror(errno));
		exit(EXIT_FAILURE);
	}

	cldlist_clear();
	return 0;
}
Beispiel #15
0
static int
traverseFolder(char * const argv[])
{
	FTS *ftsp;
	FTSENT *p, *chp;
	int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;

	//*****************
	FILE *fpRead;
	FILE *fpWrite;
       
	FILE *fpFileNames;

	char current_line[MAX_CHARS_PER_LINE];
	char new_line [MAX_CHARS_PER_LINE];
	
	int currentFileID = 0;
	char currOutputName [MAX_PATH_LENGTH];
	int currentLineLength = 0;

	int lineResult = 0;

	long totalCharacters = 0;

	if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL) {
		warn("fts_open");
		return -1;
	}

	// Initialize ftsp with as many argv[] parts as possible.
	chp = fts_children(ftsp, 0);
	if (chp == NULL) {
		return 0;               /* no files to traverse */
	}
	
	// Open file names file for writing - to map each input file name to its correponding file number
	if(!(fpFileNames= fopen ( "inputs/FILE_NAMES" , "w" )))
	{
		printf("Could not open FILE_NAMES file for writing \n");
		return (-1);
	}
	
	
	while ((p = fts_read(ftsp)) != NULL) 
	{
		if(p->fts_info == FTS_F) 
		{
			printf("processing file %d: %s\n", currentFileID, p->fts_name);   
			int filenamelength = strlen(p->fts_name);
			char lastchar=p->fts_name[filenamelength-1];
			if(DEBUG_MODE)
				printf("last char = %c\n",lastchar);
			
			// opening file for reading
			//ignore backup files
			if(lastchar!='~')
			{ 
				//open file for reading
				if(!(fpRead= fopen ( p->fts_path , "r" )))
				{
					printf("Could not open file \"%s\" for reading \n", p->fts_path);
					return (-1);
				}				

				//Record file name into INFO file
				fprintf(fpFileNames, "%s\n", p->fts_name);

				sprintf(currOutputName,"inputs/input_%d", currentFileID++);

				
				// opening file for writing
				if(!(fpWrite= fopen ( currOutputName , "w" )))
				{
					printf("Could not open file \"%s\" for writing \n", currOutputName);
					return (-1);
				}
				
				totalCharacters =0;
				//reading lines
				while( fgets (current_line, MAX_CHARS_PER_LINE-10, fpRead)!=NULL ) 
				{
					//this will replace valid characters a,c,g,t or A,C,G,T with lower case, 
					//and in case there are invalid characters will return false and this line will be ignored 
					lineResult = prepareLine(current_line,new_line,&currentLineLength);
				
					//writing concatenated content into a new file
					if(lineResult)
					{
						if(DEBUG_MODE)
							printf("%s\n",new_line);
						totalCharacters+=currentLineLength;
						if(totalCharacters<=MAX_FILE_SIZE_BYTES) //add to current file
							fprintf(fpWrite, "%s\n", new_line);
						else  //open a new file and write there
						{
							//close open output file
							fclose(fpWrite);
							//Record file name into INFO file - repeatingly
							fprintf(fpFileNames, "%s\n", p->fts_name);
							
							sprintf(currOutputName,"inputs/input_%d", currentFileID++);

				
							// opening new file for writing
							if(!(fpWrite= fopen ( currOutputName , "w" )))
							{
								printf("Could not open file \"%s\" for writing \n", currOutputName);
								return (-1);
							}
				
							totalCharacters =currentLineLength;
							fprintf(fpWrite, "%s\n", new_line);
						}		
					}				
				}
				fclose(fpRead);
				fclose(fpWrite);
			}
		}
	}
	fclose(fpFileNames);
	fts_close(ftsp);
	printf("Total %d new input files\n",currentFileID);	
	return 0;
}
Beispiel #16
0
/* update database */
void update_database(char *db_path, char *input_path, int exe_inst) {
    FTS *ftsp;
    FTSENT *p, *chp;
    int fts_options = FTS_NOSTAT | FTS_COMFOLLOW | FTS_PHYSICAL;
    char *target[2];
    DB *dbp;
    int ret;
    bitshred_t *vdb = NULL;
    FILE *fp = NULL;
    int nfile = 0;
    int nvirus = 0;
    int i;
    uint64_t t_filesize = 0;
    uint64_t t_secsize = 0;
    struct timeval t_stime, t_etime;
    double sec_elapsed = 0;
    char buf[64];

    sprintf(buf, "%s", db_path);
    if(access(buf, F_OK))
        mkdir(buf, S_IRWXU|S_IXGRP|S_IRGRP|S_IROTH|S_IXOTH);
    gettimeofday(&t_stime, NULL);

    /* initialize ftsp */
    target[0] = input_path;
    target[1] = NULL;
    if ((ftsp = fts_open(target, fts_options, NULL))==NULL) {
        bs_errmsg("[!] fts_open(): %s\n", input_path);
        exit(EXIT_FAILURE);
    }
    if ((chp = fts_children(ftsp, 0))==NULL) {
        return;   // No files to traverse
    }

    /* open DB */
    if((ret = db_create(&dbp, NULL, 0)) != 0){
        bs_errmsg("[!] db_create(): %s\n", db_strerror(ret));
        exit(EXIT_FAILURE);
    }
    sprintf(buf, "%s/vdb", db_path);
    //if((ret = dbp->open(dbp, NULL, vdb_path, NULL, DB_RECNO, DB_CREATE | DB_TRUNCATE, 0664)) != 0){
    if((ret = dbp->open(dbp, NULL, buf, NULL, DB_RECNO, DB_CREATE, 0664)) != 0){
        dbp->err(dbp, ret, "[!] %s", buf);
        exit(EXIT_FAILURE);
    }

    /* # virus in DB before update */
    sprintf(buf, "%s/vdb_nvir.txt", db_path);
    if(access(buf, F_OK) == 0) {
        if((fp = fopen(buf, "r")) == NULL) {
            bs_errmsg("[!] fopen(): %s\n", buf);
            exit(EXIT_FAILURE);
        }
        if((fgets(buf, 64, fp)) == NULL) {
            bs_errmsg("[!] fgets(): vdb_nvir.txt\n");
            exit(EXIT_FAILURE);
        }
        nvirus = atoi(buf);
        if((fgets(buf, 64, fp)) == NULL) {
            bs_errmsg("[!] fgets(): vdb_nvir.txt\n");
            exit(EXIT_FAILURE);
        }
        nvirus += atoi(buf);
        fclose(fp);
    }
    else {
        nvirus = 0;
    }

    /* list of input files */
    sprintf(buf, "%s/vdb_list.txt", db_path);
    if((fp = fopen(buf, "a")) == NULL) {
        bs_errmsg("[!] fopen(): %s\n", buf);
        exit(EXIT_FAILURE);
    }

    if((vdb = malloc(sizeof(bitshred_t))) == NULL){
        bs_errmsg("[!] malloc(): vdb\n");
        exit(EXIT_FAILURE);
    }

    bs_verbosemsg("[-] Updating database...\n");

    /* traverse input files */
    if (exe_inst==EXE_ADD_BIN) {    // binary files
        while ((p = fts_read(ftsp)) != NULL) {
            switch (p->fts_info) {
            case FTS_F:
            case FTS_NSOK:
                update_vdb_bin(dbp, fp, p->fts_name, vdb, nvirus, &nfile, &t_filesize, &t_secsize);
                break;
            default:
                break;
            }
        }
    }
    else if (exe_inst==EXE_ADD_TXT) {   // text files
        while ((p = fts_read(ftsp)) != NULL) {
            switch (p->fts_info) {
            case FTS_F:
            case FTS_NSOK:
                update_vdb_txt(dbp, fp, p->fts_name, vdb, nvirus, &nfile, &t_filesize, &t_secsize);
                break;
            default:
                break;
            }
        }
    }

    /* close DB */
    dbp->close(dbp, 0);
    fts_close(ftsp);
    free(vdb);
    fclose(fp);

    gettimeofday(&t_etime, NULL);
    sec_elapsed = time_diff(t_etime, t_stime);

    /* # virus in DB after update */
    sprintf(buf, "%s/vdb_nvir.txt", db_path);
    if((fp = fopen(buf, "w")) == NULL) {
        bs_errmsg("[!] fopen(): %s\n", buf);
        exit(EXIT_FAILURE);
    }
    fprintf(fp, "%d\n%d\n", nvirus, nfile);
    fclose(fp);

    /* report statistics */
    if((fp = fopen("/proc/self/status", "r")) == NULL) {
        bs_errmsg("[!] fopen(): /proc/self/status\n");
        exit(EXIT_FAILURE);
    }
    for(i=0; i<11; i++) {
        if((fgets(buf, 64, fp)) == NULL) {
            bs_errmsg("[!] fgets(): /proc/self/status\n");
            exit(EXIT_FAILURE);
        }
    }
    fclose(fp);

    bs_msg("\n--------------- Updating Database ---------------\n"
           "Processed files  : %u\n"
           "File size        : %.2f MiB\n"
           "Section size     : %.2f MiB (executable)\n"
           "Fingerprint size : %.2f MiB (considering only FP size w/o metadata)\n "
           "%s"
           "Time             : %umin %.3fsec\n\n"
           , nfile, 
           (double)t_filesize/(1024*1024), 
           (double)t_secsize/(1024*1024),
           (double)(FP_SIZE*nfile)/(1024*1024),
           buf,
           ((unsigned int)sec_elapsed / 60), 
           ((sec_elapsed-(unsigned int)sec_elapsed)+(unsigned int)sec_elapsed%60)
           );
}
Beispiel #17
0
/* query nearest neighbors */
void neighbor(char *db_path, char *input_path) {
    FTS *ftsp;
    FTSENT *p, *chp;
    int fts_options = FTS_NOSTAT | FTS_COMFOLLOW | FTS_PHYSICAL;
    char *target[2];
    DB *vdbp;
    int ret;
    bitshred_t *vdb = NULL;
    FILE *fp = NULL;
    int nfile = 0;
    unsigned int ncmp = 0;
    uint64_t t_filesize = 0;
    uint64_t t_secsize = 0;
    struct timeval t_stime, t_etime;
    double sec_elapsed = 0;
    char buf[64];
    int i, nvirus;

    gettimeofday(&t_stime, NULL);

    /* initialize ftsp */
    target[0] = input_path;
    target[1] = NULL;
    if ((ftsp = fts_open(target, fts_options, NULL))==NULL) {
        bs_errmsg("[!] fts_open(): %s\n", input_path);
        exit(EXIT_FAILURE);
    }
    if ((chp = fts_children(ftsp, 0))==NULL) {
        return;   // No files to traverse
    }

    /* open DB */
    if((ret = db_create(&vdbp, NULL, 0)) != 0){
        bs_errmsg("[!] db_create(): %s\n", db_strerror(ret));
        exit(EXIT_FAILURE);
    }
    sprintf(buf, "%s/vdb", db_path);
    if((ret = vdbp->open(vdbp, NULL, buf, NULL, DB_RECNO, DB_RDONLY, 0664)) != 0){
        vdbp->err(vdbp, ret, "[!] %s", buf);
        exit(EXIT_FAILURE);
    }

    /* # virus in DB */
    sprintf(buf, "%s/vdb_nvir.txt", db_path);
    if((fp = fopen(buf, "r")) == NULL) {
        bs_errmsg("[!] fopen(): %s\n", buf);
        exit(EXIT_FAILURE);
    }
    if((fgets(buf, 64, fp)) == NULL) {
        bs_errmsg("[!] fgets(): vdb_nvir.txt\n");
        exit(EXIT_FAILURE);
    }
    nvirus = atoi(buf);
    if((fgets(buf, 64, fp)) == NULL) {
        bs_errmsg("[!] fgets(): vdb_nvir.txt\n");
        exit(EXIT_FAILURE);
    }
    nvirus += atoi(buf);
    fclose(fp);

    if((vdb = malloc(sizeof(bitshred_t))) == NULL){
        bs_errmsg("[!] malloc(): vdb\n");
        exit(EXIT_FAILURE);
    }

    /* list of neighbors found */
    if((fp = fopen("neighbor_list.txt", "w")) == NULL) {
        bs_errmsg("[!] fopen(): neighbor_list.txt\n");
        exit(EXIT_FAILURE);
    }

    while ((p = fts_read(ftsp)) != NULL) {
        switch (p->fts_info) {
        case FTS_F:
        case FTS_NSOK:
            neighbor_vdb(vdbp, fp, p->fts_path, vdb, nvirus, &nfile, &ncmp, &t_filesize, &t_secsize);
            break;
        default:
            break;
        }
    }

    /* DB close */
    vdbp->close(vdbp, 0);
    fts_close(ftsp);
    free(vdb);
    fclose(fp);

    gettimeofday(&t_etime, NULL);
    sec_elapsed = time_diff(t_etime, t_stime);

    /* report statistics */
    if((fp = fopen("/proc/self/status", "r")) == NULL) {
        bs_errmsg("[!] fopen(): /proc/self/status\n");
        exit(EXIT_FAILURE);
    }
    for(i=0; i<11; i++) {
        if((fgets(buf, 64, fp)) == NULL) {
            bs_errmsg("[!] fgets(): /proc/self/status\n");
            exit(EXIT_FAILURE);
        }
    }
    fclose(fp);

    bs_msg("\n--------------- Querying NN ---------------\n"
           "Processed files  : %u\n"
           "File size        : %.2f MiB\n"
           "Section size     : %.2f MiB (.text or .CODE)\n"
           "# of comparison : %u\n"
           "%s"
           "Time             : %umin %.3fsec\n\n"
           , nfile, 
           (double)t_filesize/(1024*1024), 
           (double)t_secsize/(1024*1024),
           ncmp,
           buf,
           ((unsigned int)sec_elapsed / 60), 
           ((sec_elapsed-(unsigned int)sec_elapsed)+(unsigned int)sec_elapsed%60)
           );
}
Beispiel #18
0
int
main(int argc, char **argv)
{
    char *log_file = NULL;
    char *queue_dir = NULL;
    char *list[2];
    int num_to_send = DEFAULT_NUM, chunk;
    int fd;
    FTS *fts;
    FTSENT *ftsent;
    int piece, npieces;
    char filename[PATH_MAX];

    err_prog_name(argv[0]);

    OPTIONS("[-l log] [-n num] queuedir")
	NUMBER('n', num_to_send)
	STRING('l', log_file)
    ENDOPTS

    if (argc != 2)
	usage();

    if (log_file)
	err_set_log(log_file);

    queue_dir = argv[1];
    list[0] = queue_dir;
    list[1] = NULL;

    fts = fts_open(list, FTS_PHYSICAL|FTS_COMFOLLOW, fts_sort);
    if (fts == NULL)
    {
	err("fts failed on `%s'", queue_dir);
	exit(1);
    }

    ftsent = fts_read(fts);
    if (ftsent == NULL || ftsent->fts_info != FTS_D)
    {
	err("not a directory: %s", queue_dir);
	exit(1);
    }

    ftsent = fts_children(fts, 0);
    if (ftsent == NULL && errno)
    {
	err("*ftschildren failed");
	exit(1);
    }

    for (chunk = 1; ftsent != NULL; ftsent = ftsent->fts_link)
    {
	/*
	 * Skip non-files and ctm_smail tmp files (ones starting with `.')
	 */
	if (ftsent->fts_info != FTS_F || ftsent->fts_name[0] == '.')
	    continue;

	sprintf(filename, "%s/%s", queue_dir, ftsent->fts_name);
	fd = open(filename, O_RDONLY);
	if (fd < 0)
	{
	    err("*open: %s", filename);
	    exit(1);
	}

	if (run_sendmail(fd))
	    exit(1);

	close(fd);
	
	if (unlink(filename) < 0)
	{
	    err("*unlink: %s", filename);
	    exit(1);
	}
	
	/*
	 * Deduce the delta, piece number, and number of pieces from
	 * the name of the file in the queue.  Ideally, we should be
	 * able to get the mail alias name too.
	 *
	 * NOTE: This depends intimately on the queue name used in ctm_smail.
	 */
	npieces = atoi(&ftsent->fts_name[ftsent->fts_namelen-3]);
	piece = atoi(&ftsent->fts_name[ftsent->fts_namelen-7]);
	err("%.*s %d/%d sent", ftsent->fts_namelen-8, ftsent->fts_name,
		piece, npieces);

	if (chunk++ == num_to_send)
	    break;
    }

    fts_close(fts);

    return(0);
}
Beispiel #19
0
static int
statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode)
{
	FTSENT *p;
	gid_t sgid;
	uid_t suid;
	mode_t smode;
	struct group *gr;
	struct passwd *pw;
	gid_t savegid = *pgid;
	uid_t saveuid = *puid;
	mode_t savemode = *pmode;
	int maxgid;
	int maxuid;
	u_short maxmode;
	gid_t g[MAXGID];
	uid_t u[MAXUID];
	mode_t m[MAXMODE];
	static int first = 1;

	if ((p = fts_children(t, 0)) == NULL) {
		if (errno)
			error("%s: %s", RP(parent), strerror(errno));
		return (1);
	}

	bzero(g, sizeof(g));
	bzero(u, sizeof(u));
	bzero(m, sizeof(m));

	maxuid = maxgid = maxmode = 0;
	for (; p; p = p->fts_link) {
		if (!dflag || (dflag && S_ISDIR(p->fts_statp->st_mode))) {
			smode = p->fts_statp->st_mode & MBITS;
			if (smode < MAXMODE && ++m[smode] > maxmode) {
				savemode = smode;
				maxmode = m[smode];
			}
			sgid = p->fts_statp->st_gid;
			if (sgid < MAXGID && ++g[sgid] > maxgid) {
				savegid = sgid;
				maxgid = g[sgid];
			}
			suid = p->fts_statp->st_uid;
			if (suid < MAXUID && ++u[suid] > maxuid) {
				saveuid = suid;
				maxuid = u[suid];
			}
		}
	}
	/*
	 * If the /set record is the same as the last one we do not need to output
	 * a new one.  So first we check to see if anything changed.  Note that we
	 * always output a /set record for the first directory.
	 */
	if ((((keys & F_UNAME) | (keys & F_UID)) && (*puid != saveuid)) ||
	    (((keys & F_GNAME) | (keys & F_GID)) && (*pgid != savegid)) ||
	    ((keys & F_MODE) && (*pmode != savemode)) || (first)) {
		first = 0;
		if (dflag)
			(void)printf("/set type=dir");
		else
			(void)printf("/set type=file");
		if (keys & F_UNAME) {
			if ((pw = getpwuid(saveuid)) != NULL)
				(void)printf(" uname=%s", pw->pw_name);
			else
				error("could not get uname for uid=%u", saveuid);
		}
		if (keys & F_UID)
			(void)printf(" uid=%u", saveuid);
		if (keys & F_GNAME) {
			if ((gr = getgrgid(savegid)) != NULL)
				(void)printf(" gname=%s", gr->gr_name);
			else
				error("could not get gname for gid=%u", savegid);
		}
		if (keys & F_GID)
			(void)printf(" gid=%u", savegid);
		if (keys & F_MODE)
			(void)printf(" mode=%#o", savemode);
		if (keys & F_NLINK)
			(void)printf(" nlink=1");
		(void)printf("\n");
		*puid = saveuid;
		*pgid = savegid;
		*pmode = savemode;
	}
	return (0);
}
Beispiel #20
0
int openDirectory(char *dir){
    char *tempDir;
    tempDir = (char*)malloc((sizeof(char))*100);
    tempDir[0] = '\0'; //null char so we know when we end
    strcat(tempDir, dir);
    //attempting to use FTS for traversing directories
    
    char *directoryArray[2]; //create array of char array
    directoryArray[0] = tempDir;
    directoryArray[1] =  NULL;
    
    FTS *ftsPtr; // create pointer of file hierarchy
    FTSENT *parent, *child; //file structure repreentations
    /* typedef struct _ftsent {
               unsigned short fts_info;     // flags for FTSENT structure 
               char          *fts_accpath;  // access path 
               char          *fts_path;     // root path 
               short          fts_pathlen;  // strlen(fts_path) 
               char          *fts_name;     // filename 
               short          fts_namelen;  // strlen(fts_name) 
               short          fts_level;    // depth (-1 to N) 
               int            fts_errno;    // file errno 
               long           fts_number;   // local numeric value 
               void          *fts_pointer;  // local address value 
               struct ftsent *fts_parent;   // parent directory 
               struct ftsent *fts_link;     // next file structure/
               struct ftsent *fts_cycle;    // cycle structure 
               struct stat   *fts_statp;    // stat(2) information/
           } FTSENT; */
    
    // options for fts_open
    /* There are a number of options, at least one of which (either
       FTS_LOGICAL or FTS_PHYSICAL) must be specified.  The options are
       selected by ORing the following values:

       FTS_COMFOLLOW
                    This option causes any symbolic link specified as a root
                    path to be followed immediately whether or not
                    FTS_LOGICAL is also specified.

       FTS_LOGICAL  This option causes the fts routines to return FTSENT
                    structures for the targets of symbolic links instead of
                    the symbolic links themselves.  If this option is set,
                    the only symbolic links for which FTSENT structures are
                    returned to the application are those referencing
                    nonexistent files.  Either FTS_LOGICAL or FTS_PHYSICAL
                    must be provided to the fts_open() function.

       FTS_NOCHDIR  As a performance optimization, the fts functions change
                    directories as they walk the file hierarchy.  This has
                    the side-effect that an application cannot rely on being
                    in any particular directory during the traversal.  The
                    FTS_NOCHDIR option turns off this optimization, and the
                    fts functions will not change the current directory.
                    Note that applications should not themselves change
                    their current directory and try to access files unless
                    FTS_NOCHDIR is specified and absolute pathnames were
                    provided as arguments to fts_open().

       FTS_NOSTAT   By default, returned FTSENT structures reference file
                    characteristic information (the statp field) for each
                    file visited.  This option relaxes that requirement as a
                    performance optimization, allowing the fts functions to
                    set the fts_info field to FTS_NSOK and leave the
                    contents of the statp field undefined.

       FTS_PHYSICAL This option causes the fts routines to return FTSENT
                    structures for symbolic links themselves instead of the
                    target files they point to.  If this option is set,
                    FTSENT structures for all symbolic links in the
                    hierarchy are returned to the application.  Either
                    FTS_LOGICAL or FTS_PHYSICAL must be provided to the
                    fts_open() function.

       FTS_SEEDOT   By default, unless they are specified as path arguments
                    to fts_open(), any files named "."  or ".."  encountered
                    in the file hierarchy are ignored.  This option causes
                    the fts routines to return FTSENT structures for them.
     */
    int ftsOptions = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR; // | FTS_NOSTAT | FTS_PHYSICAL | FTS_SEEDOT;
    
    printf("we are in DIR %s\n",directoryArray);
    if((ftsPtr = fts_open(directoryArray, ftsOptions, NULL))==NULL){
        printf("error in fts\n"); //error
        return -1;
    }
    
    //no children
    /*fts_children()
       The fts_children() function returns a pointer to an FTSENT structure
       describing the first entry in a NULL-terminated linked list of the
       files in the directory represented by the FTSENT structure most
       recently returned by fts_read().  The list is linked through the
       fts_link field of the FTSENT structure, and is ordered by the user-
       specified comparison function, if any.  Repeated calls to
       fts_children() will re-create this linked list.
     */
    child = fts_children(ftsPtr,0);
    if(child ==  NULL) return 0;
    
    char *fullPathName;
    
    while((parent = fts_read(ftsPtr))!= NULL){
        switch(parent->fts_info){
            //FTS_F       A regular file.
            case FTS_F:
                fullPathName = (char*)malloc((sizeof(char))*100);
                fullPathName = parent->fts_path;
                openFile(fullPathName);
                break;
            default:
                printf("bad file\n");
                break;
        }
    }
    //close and free
    fts_close(ftsPtr);
    free(fullPathName);
    
}
Beispiel #21
0
static int
statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode, u_long *pflags)
{
	FTSENT *p;
	gid_t sgid;
	uid_t suid;
	mode_t smode;
	u_long sflags;
	struct group *gr;
	struct passwd *pw;
	gid_t savegid = *pgid;
	uid_t saveuid = *puid;
	mode_t savemode = *pmode;
	u_long saveflags = *pflags;
	u_short maxgid, maxuid, maxmode, maxflags;
	u_short g[MAXGID], u[MAXUID], m[MAXMODE], f[MAXFLAGS];
	char *fflags;
	static int first = 1;

	if ((p = fts_children(t, 0)) == NULL) {
		if (errno)
			err(1, "%s", RP(parent));
		return (1);
	}

	bzero(g, sizeof(g));
	bzero(u, sizeof(u));
	bzero(m, sizeof(m));
	bzero(f, sizeof(f));

	maxuid = maxgid = maxmode = maxflags = 0;
	for (; p; p = p->fts_link) {
		if (!dflag || (dflag && S_ISDIR(p->fts_statp->st_mode))) {
			smode = p->fts_statp->st_mode & MBITS;
			if (smode < MAXMODE && ++m[smode] > maxmode) {
				savemode = smode;
				maxmode = m[smode];
			}
			sgid = p->fts_statp->st_gid;
			if (sgid < MAXGID && ++g[sgid] > maxgid) {
				savegid = sgid;
				maxgid = g[sgid];
			}
			suid = p->fts_statp->st_uid;
			if (suid < MAXUID && ++u[suid] > maxuid) {
				saveuid = suid;
				maxuid = u[suid];
			}

			/*
			 * XXX
			 * note that the below will break when file flags
			 * are extended beyond the first 4 bytes of each
			 * half word of the flags
			 */
#define FLAGS2IDX(f) ((f & 0xf) | ((f >> 12) & 0xf0))
			sflags = p->fts_statp->st_flags;
			if (FLAGS2IDX(sflags) < MAXFLAGS &&
			    ++f[FLAGS2IDX(sflags)] > maxflags) {
				saveflags = sflags;
				maxflags = f[FLAGS2IDX(sflags)];
			}
		}
	}
	/*
	 * If the /set record is the same as the last one we do not need to output
	 * a new one.  So first we check to see if anything changed.  Note that we
	 * always output a /set record for the first directory.
	 */
	if ((((keys & F_UNAME) | (keys & F_UID)) && (*puid != saveuid)) ||
	    (((keys & F_GNAME) | (keys & F_GID)) && (*pgid != savegid)) ||
	    ((keys & F_MODE) && (*pmode != savemode)) ||
	    ((keys & F_FLAGS) && (*pflags != saveflags)) ||
	    (first)) {
		first = 0;
		if (dflag)
			(void)printf("/set type=dir");
		else
			(void)printf("/set type=file");
		if (keys & F_UNAME) {
			pw = getpwuid(saveuid);
			if (pw != NULL)
				(void)printf(" uname=%s", pw->pw_name);
			else if (wflag)
				warnx( "Could not get uname for uid=%u", saveuid);
			else
				errx(1, "Could not get uname for uid=%u", saveuid);
		}
		if (keys & F_UID)
			(void)printf(" uid=%lu", (u_long)saveuid);
		if (keys & F_GNAME) {
			gr = getgrgid(savegid);
			if (gr != NULL)
				(void)printf(" gname=%s", gr->gr_name);
			else if (wflag)
				warnx("Could not get gname for gid=%u", savegid);
			else
				errx(1, "Could not get gname for gid=%u", savegid);
		}
		if (keys & F_GID)
			(void)printf(" gid=%lu", (u_long)savegid);
		if (keys & F_MODE)
			(void)printf(" mode=%#o", savemode);
		if (keys & F_NLINK)
			(void)printf(" nlink=1");
		if (keys & F_FLAGS) {
			fflags = flags_to_string(saveflags);
			(void)printf(" flags=%s", fflags);
			free(fflags);
		}
		(void)printf("\n");
		*puid = saveuid;
		*pgid = savegid;
		*pmode = savemode;
		*pflags = saveflags;
	}
	return (0);
}
Beispiel #22
0
int
ftwalk(const char* path, int (*userf)(Ftw_t*), int flags, int (*comparf)(Ftw_t*, Ftw_t*))
{
	register FTS*		f;
	register FTSENT*	e;
	register int		children;
	register int		rv;
	int			oi;
	int			ns;
	int			os;
	int			nd;
	FTSENT*			x;
	FTSENT*			dd[2];

	flags ^= FTS_ONEPATH;
	if (flags & FTW_TWICE)
		flags &= ~(FTS_NOPREORDER|FTS_NOPOSTORDER);
	else if (flags & FTW_POST)
		flags |= FTS_NOPREORDER;
	else
		flags |= FTS_NOPOSTORDER;
	if (children = flags & FTW_CHILDREN)
		flags |= FTS_SEEDOT;
	state.comparf = comparf;
	if (!(f = fts_open((char* const*)path, flags, comparf ? ftscompare : 0)))
	{
		if (!path || !(flags & FTS_ONEPATH) && !(path = (const char*)(*((char**)path))))
			return -1;
		ns = strlen(path) + 1;
		if (!(e = newof(0, FTSENT, 1, ns)))
			return -1;
		e->fts_accpath = e->fts_name = e->fts_path = strcpy((char*)(e + 1), path);
		e->fts_namelen = e->fts_pathlen = ns;
		e->fts_info = FTS_NS;
		e->parent = e;
		e->parent->link = e;
		rv = (*userf)((Ftw_t*)e);
		free(e);
		return rv;
	}
	rv = 0;
	if (children && (e = fts_children(f, 0)))
	{
		nd = 0;
		for (x = e; x; x = x->link)
			if (x->info & FTS_DD)
			{
				x->statb = *x->fts_statp;
				x->info &= ~FTS_DD;
				dd[nd++] = x;
				if (nd >= elementsof(dd))
					break;
			}
		e->parent->link = e;
		rv = (*userf)((Ftw_t*)e->parent);
		e->parent->link = 0;
		while (nd > 0)
			dd[--nd]->info |= FTS_DD;
		for (x = e; x; x = x->link)
			if (!(x->info & FTS_D))
				x->status = FTS_SKIP;
	}
	while (!rv && (e = fts_read(f)))
	{
		oi = e->info;
		os = e->status;
		ns = e->status = e->path == e->fts_accpath ? FTW_PATH : FTW_NAME;
		nd = 0;
		switch (e->info)
		{
		case FTS_D:
		case FTS_DNX:
			if (children)
				for (x = fts_children(f, 0); x; x = x->link)
					if (x->info & FTS_DD)
					{
						x->statb = *x->fts_statp;
						x->info &= ~FTS_DD;
						dd[nd++] = x;
						if (nd >= elementsof(dd))
							break;
					}
			break;
		case FTS_DOT:
			continue;
		case FTS_ERR:
		case FTS_SLNONE:
			e->info = FTS_NS;
			break;
		case FTS_NSOK:
			e->info = FTS_NSOK;
			break;
		}
		rv = (*userf)((Ftw_t*)e);
		e->info = oi;
		if (e->status == ns)
			e->status = os;
		while (nd > 0)
			dd[--nd]->info |= FTS_DD;
	}
	fts_close(f);
	return rv;
}
Beispiel #23
0
int main ( int argc, char ** argv )
{
	int ch;
    FTS * ftsp;
    FTSENT *p, *chp, *cur;
    char * curr_dir = ".";
    int stat_ret;
    struct stat stat_buf;
    DIR * dp;
	struct dirent * dirp;

    /*
        -A is always set for the super user
    */

    if ( !getuid() )
        f_A_option = 1;

    /*
        The  tzset()  function initializes the tzname variable 
        from the TZ environment variable. 
    */
	
    tzset();

    /* 
        parse options
    */

	while ( ( ch = getopt(argc, argv, "AaCcdFfhiklnqRrSstuwx1") ) != -1 )
	{
		switch (ch)
		{
            case 'A':
                f_A_option = 1;
                break;
            case 'a':
                f_a_option = 1;
                break;
            case 'C':
                f_C_option = 1;
                f_x_option = 0;
                f_l_option = 0;
                f_n_option = 0;
                break;
            case 'c':
                f_c_option = 1;
                f_u_option = 0;     /* override -u */
                break;
            case 'd':
                f_d_option = 1;
                break;
            case 'F':
                f_F_option = 1;
                break;
            case 'f':
                f_f_option = 1;
                break;
            case 'h':
                f_h_option = 1;
                f_k_option = 0;     /* override -k */
                break;
            case 'i':
                f_i_option = 1;
                break;
            case 'k':
                f_k_option = 1;
                f_h_option = 0;     /* override -h */
                break;
			case 'l':
				f_l_option = 1;
                f_1_option = 0;     /* override */
                f_C_option = 0;
                f_x_option = 0;
				break;
            case 'n':
                f_n_option = 1;
                f_C_option = 0;
                f_x_option = 0;
                break;
            case 'q':
                f_q_option = 1;
                f_w_option = 0;
                break;
            case 'R':
                f_R_option = 1;
                break;
            case 'r':
                f_r_option = 1;
                break;
            case 'S':
                f_S_option = 1;
                break;
            case 's':
                f_s_option = 1;
                break;
            case 't':
                f_t_option = 1;
                break;
			case 'u':
                f_u_option = 1;
                f_c_option = 0;     /* override -c */
                break;
            case 'w':
                f_w_option = 1;
                f_q_option = 0;
                break;
            case 'x':
                f_x_option = 1;
                f_C_option = 0;
                f_l_option = 0;
                f_n_option = 0;
                break;
            case '1':
                f_1_option = 1;
                f_l_option = 0;
                break;
            default:
				usage();
                exit(1);
		}
	}

	argc -= optind;
	argv += optind;

	/* 
        parse file argument(s)
    */

	/* 
        If no operands are given, the contents of the current 
        directory ( "." ) are displayed. 
    */
	
    if ( argc == 0 )
	{
        /* -d */
        if ( f_d_option )
        {
            stat_ret = lstat ( curr_dir, &stat_buf );
            if ( stat_ret < 0 )
            {
                fprintf ( stderr, "stat error\n" );
                exit (1);
            }

            record_stat ( &stat_buf, curr_dir );
            print_file_info_list ();
            exit (0);    
        }
        
        /* non-recursive */
        if ( ! f_R_option )
        {
            /* read directory NAME, and list the files in it */	
            if ( ( dp = opendir(curr_dir) ) == NULL )
            {
                fprintf ( stderr, "can't open '%s'\n", curr_dir );
                exit(1);
            }

            /* enter directory */
            if ( chdir(curr_dir) == -1 )
            {
                fprintf ( stderr, "can't chdir to '%s': %s\n",
                    curr_dir, strerror(errno) );
                exit (1);
            }

            while ( ( dirp = readdir(dp) ) != NULL )
            {
                if ( lstat ( dirp->d_name, &stat_buf ) < 0 )
                {
                    fprintf ( stderr, "lstat() error" );
                    exit (1);
                }
                
                record_stat ( &stat_buf, dirp->d_name );
            }

            if ( closedir(dp) < 0 )
            {
                fprintf ( stderr, "can't close directory\n" );
                exit(1);
            }

            print_file_info_list();
            
            exit (0);
        }
        /* -R : recursive */
        else
        {
            if ( ( ftsp =
                 fts_open ( &curr_dir, FTS_LOGICAL, NULL ) ) == NULL )
            {
                fprintf ( stderr, "fts_open() error" );
                fts_close ( ftsp );
                exit(1);
            }
         
            while ( ( p = fts_read ( ftsp ) ) != NULL )
            {
                switch ( p->fts_info ) 
                {
                    /* directory */ 
                    case FTS_D:
#ifdef DEBUG
                        printf ( "^^%s\n", p->fts_name );
#endif
                        /* print directory path */                        
                        printf ( "%s:\n", p->fts_path ); 

                        // get files contained in a directory
                        chp = fts_children ( ftsp, 0 );
                        
                        // loop directory's files
                        for ( cur = chp; cur; cur = cur->fts_link )
                        {
#ifdef DEBUG
                            printf ( "\t@@ %s\n", cur->fts_name );
#endif            
                            record_stat ( cur->fts_statp, cur->fts_name );
                        }
                        
                        print_file_info_list();
                        
                        printf ( "\n" );

                        /* RE-initialize head of file_info linked list */
                        file_info_list_head = NULL;

                        break;

                    default:
                        break;
                }
            }
            
            if ( fts_close ( ftsp ) == -1 )
            {
                fprintf ( stderr, "fts_close() error.\n" );
                exit (1);
            }

            exit (0);
        }
    }

	/* 
        loop file arguments 
    */

    /* save current directory path */
    char save_current_dir [255];
    getcwd ( save_current_dir, sizeof(save_current_dir) / sizeof(save_current_dir[0]) ); 

	while (argc-- > 0)
	{
#ifdef DEBUG
        printf ( "\n## processing argv : %s\n", *argv );
#endif
        
        /* enter original working directory */
        if ( chdir(save_current_dir) == -1 )
        {
            fprintf ( stderr, "can't chdir to '%s': %s\n",
                save_current_dir, strerror(errno) );
            exit (1);
        }

        /* RE-initialize head of file_info linked list */
        file_info_list_head = NULL;

        stat_ret = lstat ( *argv, &stat_buf );
		if ( stat_ret < 0 )
		{
			fprintf ( stderr, "stat error for %s\n", *argv );
            argv++;
			continue;   /* to process the next argv */
		}

        /* argument is a file */
		if ( S_ISREG ( stat_buf.st_mode ) )
		{
            record_stat ( &stat_buf, *argv );
            print_file_info_list();
		}
        /* argument is a directory */
        else if ( S_ISDIR ( stat_buf.st_mode ) )
        {
            /* 
               -d means we need just print directory info
               (not recursively)
            */
            if ( f_d_option )
            {
                stat_ret = lstat ( *argv, &stat_buf );
                if ( stat_ret < 0 )
                {
                    fprintf ( stderr, "lstat error\n" );
                    argv++;
                    continue;
                }

                record_stat ( &stat_buf, *argv );
                print_file_info_list ();
                argv++; 
                continue;
            }

            /* non-recursive */
            if ( ! f_R_option )
            {
                /* read directory NAME, and list the files in it */	
                if ( ( dp = opendir(*argv) ) == NULL )
                {
                    fprintf ( stderr, "can't open '%s'\n", *argv );
                    exit(1);
                }

                /* enter directory */
                if ( chdir(*argv) == -1 )
                {
                    fprintf ( stderr, "can't chdir to '%s': %s\n",
                        *argv, strerror(errno) );
                    exit (1);
                }
                
                while ( ( dirp = readdir(dp) ) != NULL )
                {
                    if ( lstat ( dirp->d_name, &stat_buf ) < 0 )
                    {
                        fprintf ( stderr, "stat() error" );
                        exit (1);
                    }
                    
                    record_stat ( &stat_buf, dirp->d_name );
                }

                if ( closedir(dp) < 0 )
                {
                    fprintf ( stderr, "can't close directory\n" );
                    exit(1);
                }
                print_file_info_list();
            }
            /* -R : recursive */
            else
            {
                if ( ( ftsp =
                     fts_open ( &*argv, FTS_LOGICAL, NULL ) ) == NULL )
                {
                    // BUG, never executed!!!
                    fprintf ( stderr, "fts_open error %s", 
                        strerror(errno) );
                    argv++;
                    continue;
                }

                while ( ( p = fts_read ( ftsp ) ) != NULL )
                {
                    switch ( p->fts_info ) 
                    {
                        /* directory */
                        case FTS_D:

                            /* print directory path */                        
                            printf ( "%s:\n", p->fts_path ); 

                            // get files contained in a directory
                            chp = fts_children ( ftsp, 0 );
                            
                            // loop directory's files
                            for ( cur = chp; cur; cur = cur->fts_link )
                            {
                                record_stat ( cur->fts_statp, cur->fts_name );
                            }
                            
                            print_file_info_list();
                            
                            printf ( "\n" );

                            /* RE-initialize head of file_info linked list */
                            file_info_list_head = NULL;
                            
                            break;

                        default:
                            break;
                    }
                }
                
                if ( -1 == fts_close ( ftsp ) )
                {
                    fprintf ( stderr, "fts_close() error.\n" );
                    argv++;
                    continue;
                }

                print_file_info_list();
	        }	
        }

        printf ( "\n" );
		
        argv++;

	} /* endof while ( argc-- > 0 ) */

    /* return with success */
	exit(0);

} /* end of main() */
Beispiel #24
0
/* 
 * Traverse the file hierarchy by specified options.  single_argc is used
 * for formatting output. 
 */
static void
traverse(int single_argc, char * const *argv, int options)
{
	FTS    *handle;
	FTSENT *file, *child;

	if ((handle = fts_open(argv, options, f_nosort ? NULL : fts_cmp))
	    == NULL) {
		err(EXIT_FAILURE, "Failed to traverse");	
	}

	if ((child = fts_children(handle, 0)) == NULL) {
		if (errno != 0)
			err(EXIT_FAILURE, "Failed to search the operands");
	}

	print_file(ROOT, child);

	if (f_dir)
		goto end;

	while ((file = fts_read(handle)) != NULL) {
		if (file->fts_info == FTS_ERR || file->fts_info == FTS_NS) {
			warnx("%s: file error: %s", file->fts_name,
				strerror(file->fts_errno));

			return_val = EXIT_FAILURE;
		} else if (file->fts_info == FTS_DC) {
			warnx("%s: directory error: %s", file->fts_name,
				strerror(file->fts_errno));

			return_val = EXIT_FAILURE;
		} else if (file->fts_info == FTS_D) {
			/*
			 * Skip hidden directories if -a or -A not specified,
			 * except the hidden directories are the operands.
			 */
			if (!f_listall && file->fts_level != ROOT &&
			    file->fts_name[0] == '.') {
				if (fts_set(handle, file, FTS_SKIP) == -1) {
					warn("%s: failed to skip", 
					     file->fts_name);
					return_val = EXIT_FAILURE;
				}
				continue;
			}

			if (single_argc != SINGLE_ARG)
				printf("\n%s:\n",file->fts_path);
			else
				single_argc = 0;

			if ((child = fts_children(handle, 0)) == NULL) {
				if (errno != 0) {
					warn("%s: failed to search",
						file->fts_name);

					return_val = EXIT_FAILURE;
					continue;
				}
			}

			print_file(CHILD, child);

			/* stop searching subdirectories when -R not set */
			if (!f_recursive)
				if (fts_set(handle, file, FTS_SKIP) == -1) {
					warn("%s: failed to skip", 
					     file->fts_name);
					return_val = EXIT_FAILURE;
				}
		}

	}

	/* fts_read return NULL and errno is set */
	if (errno != 0) {
		warn("FTS read error");
		return_val = EXIT_FAILURE;
	}

end:	(void)fts_close(handle);

}
Beispiel #25
0
static int
statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode,
      u_long *pflags)
{
	FTSENT *p;
	gid_t sgid;
	uid_t suid;
	mode_t smode;
	u_long sflags = 0;
	const char *name;
	gid_t savegid;
	uid_t saveuid;
	mode_t savemode;
	u_long saveflags;
	u_short maxgid, maxuid, maxmode, maxflags;
	u_short g[MTREE_MAXGID], u[MTREE_MAXUID],
		m[MTREE_MAXMODE], f[MTREE_MAXFLAGS];
	static int first = 1;

	savegid = *pgid;
	saveuid = *puid;
	savemode = *pmode;
	saveflags = *pflags;
	if ((p = fts_children(t, 0)) == NULL) {
		if (errno)
			mtree_err("%s: %s", RP(parent), strerror(errno));
		return (1);
	}

	memset(g, 0, sizeof(g));
	memset(u, 0, sizeof(u));
	memset(m, 0, sizeof(m));
	memset(f, 0, sizeof(f));

	maxuid = maxgid = maxmode = maxflags = 0;
	for (; p; p = p->fts_link) {
		smode = p->fts_statp->st_mode & MBITS;
		if (smode < MTREE_MAXMODE && ++m[smode] > maxmode) {
			savemode = smode;
			maxmode = m[smode];
		}
		sgid = p->fts_statp->st_gid;
		if (sgid < MTREE_MAXGID && ++g[sgid] > maxgid) {
			savegid = sgid;
			maxgid = g[sgid];
		}
		suid = p->fts_statp->st_uid;
		if (suid < MTREE_MAXUID && ++u[suid] > maxuid) {
			saveuid = suid;
			maxuid = u[suid];
		}

#if HAVE_STRUCT_STAT_ST_FLAGS
		sflags = FLAGS2INDEX(p->fts_statp->st_flags);
		if (sflags < MTREE_MAXFLAGS && ++f[sflags] > maxflags) {
			saveflags = p->fts_statp->st_flags;
			maxflags = f[sflags];
		}
#endif
	}
	/*
	 * If the /set record is the same as the last one we do not need to
	 * output a new one.  So first we check to see if anything changed.
	 * Note that we always output a /set record for the first directory.
	 */
	if (((keys & (F_UNAME | F_UID)) && (*puid != saveuid)) ||
	    ((keys & (F_GNAME | F_GID)) && (*pgid != savegid)) ||
	    ((keys & F_MODE) && (*pmode != savemode)) || 
	    ((keys & F_FLAGS) && (*pflags != saveflags)) ||
	    first) {
		first = 0;
		printf("/set type=file");
		if (keys & (F_UID | F_UNAME)) {
			if (keys & F_UNAME &&
			    (name = user_from_uid(saveuid, 1)) != NULL)
				printf(" uname=%s", name);
			else /* if (keys & F_UID) */
				printf(" uid=%lu", (u_long)saveuid);
		}
		if (keys & (F_GID | F_GNAME)) {
			if (keys & F_GNAME &&
			    (name = group_from_gid(savegid, 1)) != NULL)
				printf(" gname=%s", name);
			else /* if (keys & F_UID) */
				printf(" gid=%lu", (u_long)savegid);
		}
		if (keys & F_MODE)
			printf(" mode=%#lo", (u_long)savemode);
		if (keys & F_NLINK)
			printf(" nlink=1");
		if (keys & F_FLAGS)
			printf(" flags=%s",
			    flags_to_string(saveflags, "none"));
		printf("\n");
		*puid = saveuid;
		*pgid = savegid;
		*pmode = savemode;
		*pflags = saveflags;
	}
	return (0);
}
void runFailure() {
    fts_children(NULL, anyint());
}