Пример #1
0
/**
 * @brief	Select a random truetype font from the directory specified in magma.http.fonts.
 * @return	NULL on failure, or a managed string containing the pathname of the randomly selected font file on success.
 */
stringer_t * register_captcha_random_font(void) {

	DIR *directory;
	stringer_t *path;
	struct dirent64 *dp;
	size_t count = 0, selection;

	// Open the current working directory.
	if (!(directory = opendir(magma.http.fonts))) {
		log_pedantic("Unable to open the font directory. { directory = %s }", magma.http.fonts);
		return NULL;
	}

	// Count the number of fonts.
	while ((dp = readdir64(directory))) {

		if (!st_cmp_ci_ends(NULLER(dp->d_name), PLACER(".ttf", 4))) {
			count++;
		}

	};

	// No fonts were found.
	if (!count) {
		log_pedantic("The web fonts directory is empty. { directory = %s }", magma.http.fonts);
		closedir(directory);
		return NULL;
	}

	// Pick a random font.
	selection = (rand_get_uint32() % count) + 1;

	// Reset the directory stream.
	rewinddir(directory);

	// Do the loop again.
	while (selection && (dp = readdir64(directory))) {

		if (!st_cmp_ci_ends(NULLER(dp->d_name), PLACER(".ttf", 4))) {
			selection--;
		}

	}

	// Build the path.
	if (selection || !dp || !(path = st_aprint("%s/%s", magma.http.fonts, dp->d_name))) {
		log_pedantic("Could not build the font file path.");
		closedir(directory);
		return NULL;
	}

	closedir(directory);
	return path;
}
Пример #2
0
std::vector<std::string> MAIN::Get_Directory_File_List(const std::string &i_szDirectory) /// get list of all files in the given direcctory
{
	std::vector<std::string> szRet;
	DIR * dirList = opendir (i_szDirectory.c_str());
	if (dirList)
	{
		dirent64 * direntInfo = readdir64(dirList);
		while (direntInfo)
		{
			if (direntInfo->d_name[0] != '.') // don't include . and ..; these can be assumed
				szRet.push_back(direntInfo->d_name);
			direntInfo = readdir64(dirList);
		}
	}
	return szRet;
}
Пример #3
0
static boolean_t
dir_is_empty_readdir(const char *dirname)
{
	DIR *dirp;
	struct dirent64 *dp;
	int dirfd;

	if ((dirfd = openat(AT_FDCWD, dirname,
	    O_RDONLY | O_NDELAY | O_LARGEFILE | O_CLOEXEC, 0)) < 0) {
		return (B_TRUE);
	}

	if ((dirp = fdopendir(dirfd)) == NULL) {
		(void) close(dirfd);
		return (B_TRUE);
	}

	while ((dp = readdir64(dirp)) != NULL) {

		if (strcmp(dp->d_name, ".") == 0 ||
		    strcmp(dp->d_name, "..") == 0)
			continue;

		(void) closedir(dirp);
		return (B_FALSE);
	}

	(void) closedir(dirp);
	return (B_TRUE);
}
Пример #4
0
static int nprocessors_conf(void)
{
	int ret = 0;
	DIR *dir = opendir("/sys/devices/system/cpu");

	if (dir) {
		struct dirent64 *dp;

		while ((dp = readdir64(dir))) {
			if (dp->d_type == DT_DIR
				&& dp->d_name[0] == 'c'
				&& dp->d_name[1] == 'p'
				&& dp->d_name[2] == 'u'
				&& isdigit(dp->d_name[3]))
				++ret;
		}
		closedir(dir);
	} else
	{
#if defined __sparc__
		char **l = NULL;
		parser_t *p = config_open("/proc/stat");
		while (config_read(p, &l, 2, 2, "\0:", PARSE_NORMAL))
			if (strncmp("ncpus probed", l[0], 13) == 0) {
				ret = atoi(l[1]);
				break;
			}
		config_close(p);
#else
		ret = nprocessors_onln();
#endif
	}
	return ret != 0 ? ret : 1;
}
Пример #5
0
char * portable_readdir(DIR* handle) {

#ifdef USE_DIRENT64
    struct dirent64 *entry_p;
#else
    struct dirent *entry_p;
#endif

    static GStaticMutex mutex = G_STATIC_MUTEX_INIT;

    g_static_mutex_lock(&mutex);

#ifdef USE_READDIR
    entry_p = readdir(handle);
#endif
#ifdef USE_READDIR64
    entry_p = readdir64(handle);
#endif

    g_static_mutex_unlock(&mutex);
    
    if (entry_p == NULL)
        return NULL;

    /* FIXME: According to glibc documentation, d_name may not be
       null-terminated in some cases on some very old platforms. Not
       sure what to do about that case. */
    return strdup(entry_p->d_name);
}
Пример #6
0
SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
	return readdir64(dirp);
#else
	return readdir(dirp);
#endif
}
/* Read a directory entry from DIRP, store result in ENTRY and return
   pointer to result in *RESULT.  */
int
__readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
{
  entry = readdir64 (dirp);
  *result = entry;
  if (entry == NULL || result == NULL)
  	return -1;
  return 0;
}
Пример #8
0
/*VARARGS*/
char *
fpkginst(char *pkg, ...)
{
	static char pkginst[PKGSIZ+1];
	static DIR *pdirfp;
	struct dirent *dp;
	char	*ckarch, *ckvers;
	va_list	ap;

	va_start(ap, pkg);

	if (pkg == NULL) {
		/* request to close or rewind the file */
		if (pdirfp) {
			(void) closedir(pdirfp);
			pdirfp = NULL;
		}
		return (NULL);
	}

	ckarch = va_arg(ap, char *);
	ckvers = va_arg(ap, char *);
	va_end(ap);

	if (!pkgdir)
		pkgdir = get_PKGLOC();

	if (!pdirfp && ((pdirfp = opendir(pkgdir)) == NULL)) {
		errno = EACCES;
		return (NULL);
	}

	while ((dp = readdir64(pdirfp)) != NULL) {
		if (dp->d_name[0] == '.')
			continue;

		if (pkgnmchk(dp->d_name, pkg, 0))
			continue; /* ignore invalid SVR4 package names */

		if (ckinfo(dp->d_name, ckarch, ckvers))
			continue;

		/*
		 * Leave directory open in case user requests another
		 * instance.
		 */
		(void) strcpy(pkginst, dp->d_name);
		return (pkginst);
	}

	errno = ESRCH;
	/* close any file we might have open */
	(void) closedir(pdirfp);
	pdirfp = NULL;
	return (NULL);
}
Пример #9
0
struct dirent *readdir(DIR *dir){
	register struct dirent64 *de64=readdir64(dir);
	if(de64 == NULL)
		return NULL;
	else {
		dir->de32.d_ino=de64->d_ino;
		dir->de32.d_off=(de64->d_off > _MAX_OFF_T)?_MAX_OFF_T:de64->d_off;
		dir->de32.d_reclen=de64->d_reclen;
		dir->de32.d_type=de64->d_type;
		strcpy(dir->de32.d_name,de64->d_name);
		return &(dir->de32);
	}
}
Пример #10
0
/*
* Sys_FS_FindNext
*/
const char *Sys_FS_FindNext( unsigned musthave, unsigned canhave )
{
	struct dirent64 *d;

	assert( fdir );
	assert( findbase && findpattern );

	if( !fdir )
		return NULL;

	while( ( d = readdir64( fdir ) ) != NULL )
	{
		if( !CompareAttributes( d, findbase, musthave, canhave ) )
			continue;

		if( fdots > 0 )
		{
			// . and .. never match
			const char *base = COM_FileBase( d->d_name );
			if( !strcmp( base, "." ) || !strcmp( base, ".." ) )
			{
				fdots--;
				continue;
			}
		}

		if( !*findpattern || Com_GlobMatch( findpattern, d->d_name, 0 ) )
		{
			const char *dname = d->d_name;
			size_t dname_len = strlen( dname );
			size_t size = sizeof( char ) * ( findbase_size + dname_len + 1 + 1 );
			if( findpath_size < size )
			{
				if( findpath )
					Mem_TempFree( findpath );
				findpath_size = size * 2; // extra size to reduce reallocs
				findpath = Mem_TempMalloc( findpath_size );
			}

			Q_snprintfz( findpath, findpath_size, "%s/%s%s", findbase, dname,
				dname[dname_len-1] != '/' && FS_DirentIsDir( d, findbase ) ? "/" : "" );
			if( CompareAttributesForPath( d, findpath, musthave, canhave ) )
				return findpath;
		}
	}

	return NULL;
}
Пример #11
0
TEST(dirent, readdir64) {
  DIR* d = opendir("/proc/self");
  ASSERT_TRUE(d != NULL);
  std::set<std::string> name_set;
  errno = 0;
  dirent64* e;
  while ((e = readdir64(d)) != NULL) {
    name_set.insert(e->d_name);
  }
  // Reading to the end of the directory is not an error.
  // readdir64(3) returns NULL, but leaves errno as 0.
  ASSERT_EQ(0, errno);
  ASSERT_EQ(closedir(d), 0);

  CheckProcSelf(name_set);
}
// ****************************************************************************
// ***  Init
// ****************************************************************************
void
khResourceManager::Init(void)
{
  std::string statedir =
    geAssetRoot::Dirname(AssetDefs::AssetRoot(), geAssetRoot::StateDir);

  khLockGuard lock(mutex);

  // Find all the old task symlinks and tell the asset manager to resubmit
  // them. The symlinks have the form (taskid.task -> verref)
  DIR *dir = opendir(statedir.c_str());
  if (!dir) {
    notify(NFY_FATAL, "Unable to opendir(%s): %s", statedir.c_str(),
           khstrerror(errno).c_str());
  }
  struct dirent64 *entry;
  while ((entry = readdir64(dir))) {
    std::string dname = entry->d_name;

    if (dname == ".") continue;
    if (dname == "..") continue;
    if (!khHasExtension(dname, ".task")) continue;

    std::string child = statedir + "/" + dname;

    if (khSymlinkExists(child)) {
      uint32 taskid = 0;
      FromString(khDropExtension(dname), taskid);
      if (taskid == 0) {
        notify(NFY_FATAL, "Unrecognized task symlink %s",
               child.c_str());
      }
      std::string verref;
      if (!khReadSymlink(child, verref)) {
        notify(NFY_FATAL, "Unable to process old tasks");
      }
      if (!khUnlink(child)) {
        notify(NFY_FATAL, "Unable to process old tasks");
      }

      // Tell the asset manager we lost this task
      // He'll re-submit it with all the details
      NotifyTaskLost(TaskLostMsg(verref, taskid));
    }
  }
  closedir(dir);
}
Пример #13
0
/*
 * This is an ON Consolidation Private interface.
 *
 * Print out the aliases available to the program user.  Changes
 * depending in whether volume management is running.
 */
void
_media_printaliases(void)
{
	struct alias		*s;
	DIR			*dirp;
	struct dirent64		*dp;
	char			pathbuf[MAXPATHLEN+1];
	char			*p;
	static const char	*vold_root = NULL;



	if (vold_root == NULL) {
		vold_root = volmgt_root();
	}

	if (!volmgt_running()) {
		/* no volume management */
		for (s = device_aliases; *s->alias != NULLC; s++) {
			(void) printf("\t%s -> %s\n", s->alias, s->name);
		}
		return;
	}

	for (s = volmgt_aliases; *s->alias != NULLC; s++) {
		(void) printf("\t%s -> %s\n", s->alias, s->name);
	}

	(void) concat_paths(pathbuf, (char *)vold_root, ALIAS_DIR, NULL);

	if ((dirp = opendir(pathbuf)) == NULL) {
		return;
	}
	while (dp = readdir64(dirp)) {
		if (strcmp(dp->d_name, ".") == 0) {
			continue;
		}
		if (strcmp(dp->d_name, "..") == 0) {
			continue;
		}
		if ((p = media_findname(dp->d_name)) != NULL) {
			(void) printf("\t%s -> %s\n", dp->d_name, p);
		}
	}
	(void) closedir(dirp);
}
Пример #14
0
        std::vector<Path> DirectoryImplUnix::getContent(Uint32 flags)
        {
            dirent64* result;
            std::vector<Path> content;

            while((result = readdir64(m_handle)))
            {
                Path p = Path(m_path.toString() + Path::Separator + result->d_name);

                if((flags & (DirectorySearchFlag_Directories) && p.isDirectory()) || (flags & (DirectorySearchFlag_Files) && p.isFile()))
                {
                    content.push_back(p);
                }
            }

            return content;
        }
Пример #15
0
int scandir64(const char *dir, struct dirent64 ***namelist,
	    int (*select)(const struct dirent64 *),
	    int (*compar)(const struct dirent64 **, const struct dirent64 **)) {
  DIR* d;
  struct dirent64 *D;
  size_t num=0;
  if (!(d=opendir(dir)))
    return -1;
  *namelist=0;
  while ((D=readdir64(d))) {
    if (select==0 ||  select(D)) {
      struct dirent64 **tmp;
      ++num;
/*      printf("realloc %p,%d -> ",*namelist,num*sizeof(struct dirent**)); */
      if (!(tmp=reallocarray(*namelist,num,sizeof(struct dirent64*))) ||
	  !(tmp[num-1]=malloc(sizeof(struct dirent64)))) {
	size_t i;
	for (i=0; i<num-1; ++i) free(tmp[i]);
	free(*namelist);
	closedir(d);
	return -1;
      }
      memccpy(tmp[num-1]->d_name,D->d_name,0,NAME_MAX);
      tmp[num-1]->d_off=D->d_off;
      tmp[num-1]->d_reclen=D->d_reclen;
      tmp[num-1]->d_type=D->d_type;
      *namelist=tmp;
/*      printf("%p; tmp[num-1(%d)]=%p\n",*namelist,num-1,tmp[num-1]); */
    }
  }
  closedir(d);
#if 0
  {
    int i;
    puts("pre-qsort:\n");
    for (i=0; i<num-1; ++i) {
      puts((*namelist)[i]->d_name);
    }
    puts("post-qsort:\n");
  }
#endif
//  qsort(&(*namelist)[0],num,sizeof(struct dirent*),(int (*)(const void*,const void*))(compar));
  if (compar)
    qsort(*namelist,num,sizeof(struct dirent64*),(int (*)(const void*,const void*))(compar));
  return num;
}
Пример #16
0
uintptr_t
omrfile_findfirst(struct OMRPortLibrary *portLibrary, const char *path, char *resultbuf)
{
#if defined(AIXPPC)
	DIR64 *dirp = NULL;
#else
	DIR *dirp = NULL;
#endif

#if defined(AIXPPC)
	struct dirent64 *entry;
#else
	struct dirent *entry;
#endif

	Trc_PRT_file_findfirst_Entry2(path, resultbuf);

#if defined(AIXPPC)
	dirp = opendir64(path);
#else
	dirp = opendir(path);
#endif
	if (dirp == NULL) {
		Trc_PRT_file_findfirst_ExitFail(-1);
		return (uintptr_t)-1;
	}
#if defined(AIXPPC)
	entry = readdir64(dirp);
#else
	entry = readdir(dirp);
#endif
	if (entry == NULL) {
#if defined(AIXPPC)
		closedir64(dirp);
#else
		closedir(dirp);
#endif
		Trc_PRT_file_findfirst_ExitFail(-1);
		return (uintptr_t)-1;
	}
	strcpy(resultbuf, entry->d_name);
	Trc_PRT_file_findfirst_Exit((uintptr_t)dirp);
	return (uintptr_t)dirp;
}
Пример #17
0
static char *
svr4inst(char *pkg)
{
	static char pkginst[PKGSIZ];
	static DIR *pdirfp;
	struct dirent64 *dp;
	struct stat64	status;	/* file status buffer */
	char	*pt;
	char	path[PATH_MAX];

	if (pkg == NULL) {
		if (pdirfp) {
			(void) closedir(pdirfp);
			pdirfp = NULL;
		}
		return (NULL);
	}

	if (!pdirfp && ((pdirfp = opendir(get_PKGOLD())) == NULL))
		return (NULL);

	while ((dp = readdir64(pdirfp)) != NULL) {
		if (dp->d_name[0] == '.')
			continue;
		pt = strchr(dp->d_name, '.');
		if (pt && strcmp(pt, ".name") == 0) {
			/* the pkgnmchk function works on .name extensions */
			if (pkgnmchk(dp->d_name, pkg, 1))
				continue;
			(void) sprintf(path, "%s/%s", get_PKGOLD(), dp->d_name);
			if (lstat64(path, &status))
				continue;
			if ((status.st_mode & S_IFMT) != S_IFREG)
				continue;
			*pt = '\0';
			(void) strcpy(pkginst, dp->d_name);
			return (pkginst);
		}
	}
	(void) closedir(pdirfp);
	pdirfp = NULL;
	return (NULL);
}
Пример #18
0
const osd_directory_entry *osd_readdir(osd_directory *dir)
{
	#if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_FREEBSD) || defined(SDLMAME_OS2)
	dir->data = readdir(dir->fd);
	#else
	dir->data = readdir64(dir->fd);
	#endif

	if (dir->data == NULL)
		return NULL;

	dir->ent.name = dir->data->d_name;
	#if defined (SDLMAME_LINUX) || defined (SDLMAME_FREEBSD) || defined(SDLMAME_DARWIN)
	dir->ent.type = get_attributes_enttype(dir->data->d_type);
	#else
	dir->ent.type = get_attributes_stat(dir->data->d_name);
	#endif
	dir->ent.size = osd_get_file_size(dir->data->d_name);
	return &dir->ent;
}
Пример #19
0
/*
 * Returns true if the specified directory is empty.  If we can't open the
 * directory at all, return true so that the mount can fail with a more
 * informative error message.
 */
static boolean_t
dir_is_empty(const char *dirname)
{
	DIR *dirp;
	struct dirent64 *dp;

	if ((dirp = opendir(dirname)) == NULL)
		return (B_TRUE);

	while ((dp = readdir64(dirp)) != NULL) {

		if (strcmp(dp->d_name, ".") == 0 ||
		    strcmp(dp->d_name, "..") == 0)
			continue;

		(void) closedir(dirp);
		return (B_FALSE);
	}

	(void) closedir(dirp);
	return (B_TRUE);
}
Пример #20
0
static int
walk_dir(acl_t acl, acl_t dacl, const char *fname)
{
	int failed = 0;
	DIR *dir;
	struct dirent64 *d;
	char *name;

	if ((dir = opendir(fname)) == NULL) {
		if (errno != ENOTDIR) {
			fprintf(stderr, _("%s: opendir failed: %s\n"),
				program, strerror(errno));
			return(1);
		}
		return(0);	/* got a file, not an error */
	}

	while ((d = readdir64(dir)) != NULL) {
		/* skip "." and ".." entries */
		if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0)
			continue;
		
		name = malloc(strlen(fname) + strlen(d->d_name) + 2);
		if (name == NULL) {
			fprintf(stderr, _("%s: malloc failed: %s\n"),
				program, strerror(errno));
			exit(1);
		}
		sprintf(name, "%s/%s", fname, d->d_name);

		failed += set_acl(acl, dacl, name);
		free(name);
	}
	closedir(dir);

	return(failed);
}
Пример #21
0
/**
 * Find the next filename and path matching a given handle.
 *
 * @param[in] portLibrary The port library
 * @param[in] findhandle handle returned from @ref omrfile_findfirst.
 * @param[out] resultbuf next filename and path matching findhandle.
 *
 * @return 0 on success, -1 on failure or if no matching entries.
 * @internal @todo return negative portable return code on failure.
 */
int32_t
omrfile_findnext(struct OMRPortLibrary *portLibrary, uintptr_t findhandle, char *resultbuf)
{
#if defined(AIXPPC)
	struct dirent64 *entry;
#else
	struct dirent *entry;
#endif

	Trc_PRT_file_findnext_Entry2(findhandle, resultbuf);

#if defined(AIXPPC)
	entry = readdir64((DIR64 *)findhandle);
#else
	entry = readdir((DIR *)findhandle);
#endif
	if (entry == NULL) {
		Trc_PRT_file_findnext_ExitFail(-1);
		return -1;
	}
	strcpy(resultbuf, entry->d_name);
	Trc_PRT_file_findnext_Exit(0);
	return 0;
}
Пример #22
0
void
_PXFREADDIR(
#endif
	    _f_int *IDIRID,
	    _f_int *JDIRENT,
	    _f_int *IERROR
)
{
#if defined(_MIPSEB)
  struct dirent64 *direntptr, *newdirentptr;
#else
  struct dirent *direntptr, *newdirentptr;
#endif
  int errno_save;
  DIR *dirp;
  int cdirent, cdirid;
  
  /* set errno to invalid error number so end of directory can be checked since
   * readdir returns NULL but does not set errno when the end of a directory
   * is reached. */
  errno_save = errno;
  errno = -1;
  
  cdirid = *IDIRID;
  if (cdirid < 0) {
    cdirid = -cdirid;
  }

  /* fetch the real DIR pointer from the pxfdir_table */
  dirp = _table_lookup(&_pxfdir_table, cdirid);
  if (dirp == NULL) {
    *IERROR = EBADID;
    return;
  }
  
#if defined(_MIPSEB)
  if ((direntptr = readdir64(dirp)) == NULL) {
#else
  if ((direntptr = readdir(dirp)) == NULL) {
#endif
    if (errno == -1) {
      /* end of directory entries */
      *IERROR = EEND;
    } else {
      *IERROR = errno;
    }
    errno = errno_save;
    return;
  }

  errno = errno_save;

  /* Since the size of the dirent structure returned from readdir varies in
   * size the old dirent struct needs to be free'd and a new struct of size
   * direntptr->d_reclen malloc'd.
   */

#if defined(_MIPSEB)
  newdirentptr = (struct dirent64 *)malloc(direntptr->d_reclen);
#else
  newdirentptr = (struct dirent *)malloc(direntptr->d_reclen);
#endif
  if (newdirentptr == NULL) {
    *IERROR = ENOMEM;
    return;
  }

  (void)memcpy(newdirentptr, direntptr, direntptr->d_reclen);

  /* Determine if a new entry in the pxfhandle table is needed.
   * If IDIRID is negative, then pxfreaddir has not been called
   * and a new pxfhandle table entry is needed.
   */
  if (*IDIRID < 0) {
    cdirent = _pxfhandle_table_add(&_pxfhandle_table,
				   newdirentptr,
				   PXF_DIRENT);
    if (cdirent < 0) {
      *IERROR = ENOMEM;
      return;
    } else {
      *JDIRENT = cdirent;
      *IDIRID = cdirid;
    }
  } else if (!_pxfhandle_table_replace(&_pxfhandle_table,
				       *JDIRENT,
				       newdirentptr,
				       PXF_DIRENT)) {
    *IERROR = EBADHANDLE;
    return;
  }
  
  *IERROR = 0;
}
  
#ifndef _UNICOS
void
pxfreaddir_(
	    _f_int *IDIRID,
	    _f_int *JDIRENT,
	    _f_int *IERROR
)
{
  _PXFREADDIR(IDIRID, JDIRENT, IERROR);
}
Пример #23
0
struct dirent64 *
readdir_largefile(DIR *dir) {
    return readdir64(dir);
}
Пример #24
0
static int
do_test (void)
{
  /* fdopendir takes over the descriptor, make a copy.  */
  int dupfd = dup (dir_fd);
  if (dupfd == -1)
    {
      puts ("dup failed");
      return 1;
    }
  if (lseek (dupfd, 0, SEEK_SET) != 0)
    {
      puts ("1st lseek failed");
      return 1;
    }

  /* The directory should be empty safe the . and .. files.  */
  DIR *dir = fdopendir (dupfd);
  if (dir == NULL)
    {
      puts ("fdopendir failed");
      return 1;
    }
  struct dirent64 *d;
  while ((d = readdir64 (dir)) != NULL)
    if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
      {
	printf ("temp directory contains file \"%s\"\n", d->d_name);
	return 1;
      }
  closedir (dir);

  /* Try to create a file.  */
  int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
  if (fd == -1)
    {
      if (errno == ENOSYS)
	{
	  puts ("*at functions not supported");
	  return 0;
	}

      puts ("file creation failed");
      return 1;
    }
  write (fd, "hello", 5);
  puts ("file created");

  struct stat64 st1;
  if (fstat64 (fd, &st1) != 0)
    {
      puts ("fstat64 failed");
      return 1;
    }

  close (fd);

  if (linkat (dir_fd, "some-file", dir_fd, "another-file", 0) != 0)
    {
      puts ("symlinkat failed");
      return 1;
    }

  struct stat64 st2;
  if (fstatat64 (dir_fd, "some-file", &st2, 0) != 0)
    {
      puts ("fstatat64 failed");
      return 1;
    }
  if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
    {
      puts ("file changed after symlinkat");
      return 1;
    }

  if (fstatat64 (dir_fd, "another-file", &st2, AT_SYMLINK_NOFOLLOW) != 0)
    {
      puts ("2nd fstatat64 failed");
      return 1;
    }
  if (S_ISLNK (st2.st_mode))
    {
      puts ("2nd fstatat64 shows file is a symlink");
      return 1;
    }
  if (st1.st_dev != st2.st_dev
      || st1.st_ino != st2.st_ino
      || st1.st_size != st2.st_size)
    {
      puts ("stat results for linked file do not match");
      return 1;
    }

  if (fstatat64 (dir_fd, "another-file", &st2, 0) != 0)
    {
      puts ("3rd fstatat64 failed");
      return 1;
    }
  if (st1.st_dev != st2.st_dev
      || st1.st_ino != st2.st_ino
      || st1.st_size != st2.st_size)
    {
      puts ("stat results do not match");
      return 1;
    }

  if (unlinkat (dir_fd, "another-file", 0) != 0)
    {
      puts ("unlinkat failed");
      return 1;
    }
  if (unlinkat (dir_fd, "some-file", 0) != 0)
    {
      puts ("2nd unlinkat failed");
      return 1;
    }

  close (dir_fd);

  return 0;
}
Пример #25
0
/*
 * Given a list of directories to search, find all pools stored on disk.  This
 * includes partial pools which are not available to import.  If no args are
 * given (argc is 0), then the default directory (/dev/dsk) is searched.
 * poolname or guid (but not both) are provided by the caller when trying
 * to import a specific pool.
 */
static nvlist_t *
zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
{
	int i, dirs = iarg->paths;
	struct dirent64 *dp;
	char path[MAXPATHLEN];
	char *end, **dir = iarg->path;
	size_t pathleft;
	nvlist_t *ret = NULL;
	static char *default_dir = "/dev/dsk";
	pool_list_t pools = { 0 };
	pool_entry_t *pe, *penext;
	vdev_entry_t *ve, *venext;
	config_entry_t *ce, *cenext;
	name_entry_t *ne, *nenext;
	avl_tree_t slice_cache;
	rdsk_node_t *slice;
	void *cookie;

	if (dirs == 0) {
		dirs = 1;
		dir = &default_dir;
	}

	/*
	 * Go through and read the label configuration information from every
	 * possible device, organizing the information according to pool GUID
	 * and toplevel GUID.
	 */
	for (i = 0; i < dirs; i++) {
		tpool_t *t;
		char *rdsk;
		int dfd;
		boolean_t config_failed = B_FALSE;
		DIR *dirp;

		/* use realpath to normalize the path */
		if (realpath(dir[i], path) == 0) {
			(void) zfs_error_fmt(hdl, EZFS_BADPATH,
			    dgettext(TEXT_DOMAIN, "cannot open '%s'"), dir[i]);
			goto error;
		}
		end = &path[strlen(path)];
		*end++ = '/';
		*end = 0;
		pathleft = &path[sizeof (path)] - end;

		/*
		 * Using raw devices instead of block devices when we're
		 * reading the labels skips a bunch of slow operations during
		 * close(2) processing, so we replace /dev/dsk with /dev/rdsk.
		 */
		if (strcmp(path, "/dev/dsk/") == 0)
			rdsk = "/dev/rdsk/";
		else
			rdsk = path;

		if ((dfd = open64(rdsk, O_RDONLY)) < 0 ||
		    (dirp = fdopendir(dfd)) == NULL) {
			if (dfd >= 0)
				(void) close(dfd);
			zfs_error_aux(hdl, strerror(errno));
			(void) zfs_error_fmt(hdl, EZFS_BADPATH,
			    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
			    rdsk);
			goto error;
		}

		avl_create(&slice_cache, slice_cache_compare,
		    sizeof (rdsk_node_t), offsetof(rdsk_node_t, rn_node));
		/*
		 * This is not MT-safe, but we have no MT consumers of libzfs
		 */
		while ((dp = readdir64(dirp)) != NULL) {
			const char *name = dp->d_name;
			if (name[0] == '.' &&
			    (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
				continue;

			slice = zfs_alloc(hdl, sizeof (rdsk_node_t));
			slice->rn_name = zfs_strdup(hdl, name);
			slice->rn_avl = &slice_cache;
			slice->rn_dfd = dfd;
			slice->rn_hdl = hdl;
			slice->rn_nozpool = B_FALSE;
			avl_add(&slice_cache, slice);
		}
		/*
		 * create a thread pool to do all of this in parallel;
		 * rn_nozpool is not protected, so this is racy in that
		 * multiple tasks could decide that the same slice can
		 * not hold a zpool, which is benign.  Also choose
		 * double the number of processors; we hold a lot of
		 * locks in the kernel, so going beyond this doesn't
		 * buy us much.
		 */
		t = tpool_create(1, 2 * sysconf(_SC_NPROCESSORS_ONLN),
		    0, NULL);
		for (slice = avl_first(&slice_cache); slice;
		    (slice = avl_walk(&slice_cache, slice,
		    AVL_AFTER)))
			(void) tpool_dispatch(t, zpool_open_func, slice);
		tpool_wait(t);
		tpool_destroy(t);

		cookie = NULL;
		while ((slice = avl_destroy_nodes(&slice_cache,
		    &cookie)) != NULL) {
			if (slice->rn_config != NULL && !config_failed) {
				nvlist_t *config = slice->rn_config;
				boolean_t matched = B_TRUE;

				if (iarg->poolname != NULL) {
					char *pname;

					matched = nvlist_lookup_string(config,
					    ZPOOL_CONFIG_POOL_NAME,
					    &pname) == 0 &&
					    strcmp(iarg->poolname, pname) == 0;
				} else if (iarg->guid != 0) {
					uint64_t this_guid;

					matched = nvlist_lookup_uint64(config,
					    ZPOOL_CONFIG_POOL_GUID,
					    &this_guid) == 0 &&
					    iarg->guid == this_guid;
				}
				if (!matched) {
					nvlist_free(config);
				} else {
					/*
					 * use the non-raw path for the config
					 */
					(void) strlcpy(end, slice->rn_name,
					    pathleft);
					if (add_config(hdl, &pools, path,
					    config) != 0)
						config_failed = B_TRUE;
				}
			}
			free(slice->rn_name);
			free(slice);
		}
		avl_destroy(&slice_cache);

		(void) closedir(dirp);

		if (config_failed)
			goto error;
	}

	ret = get_configs(hdl, &pools, iarg->can_be_active);

error:
	for (pe = pools.pools; pe != NULL; pe = penext) {
		penext = pe->pe_next;
		for (ve = pe->pe_vdevs; ve != NULL; ve = venext) {
			venext = ve->ve_next;
			for (ce = ve->ve_configs; ce != NULL; ce = cenext) {
				cenext = ce->ce_next;
				if (ce->ce_config)
					nvlist_free(ce->ce_config);
				free(ce);
			}
			free(ve);
		}
		free(pe);
	}

	for (ne = pools.names; ne != NULL; ne = nenext) {
		nenext = ne->ne_next;
		free(ne->ne_name);
		free(ne);
	}

	return (ret);
}
Пример #26
0
/*
 * Given a list of directories to search, find all pools stored on disk.  This
 * includes partial pools which are not available to import.  If no args are
 * given (argc is 0), then the default directory (/dev/dsk) is searched.
 * poolname or guid (but not both) are provided by the caller when trying
 * to import a specific pool.
 */
static nvlist_t *
zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
{
	int i, dirs = iarg->paths;
	DIR *dirp = NULL;
	struct dirent64 *dp;
	char path[MAXPATHLEN];
	char *end, **dir = iarg->path;
	size_t pathleft;
	struct stat64 statbuf;
	nvlist_t *ret = NULL, *config;
	int fd;
	pool_list_t pools = { 0 };
	pool_entry_t *pe, *penext;
	vdev_entry_t *ve, *venext;
	config_entry_t *ce, *cenext;
	name_entry_t *ne, *nenext;

	verify(iarg->poolname == NULL || iarg->guid == 0);

	if (dirs == 0) {
#ifdef HAVE_LIBBLKID
		/* Use libblkid to scan all device for their type */
		if (zpool_find_import_blkid(hdl, &pools) == 0)
			goto skip_scanning;

		(void) zfs_error_fmt(hdl, EZFS_BADCACHE,
		    dgettext(TEXT_DOMAIN, "blkid failure falling back "
		    "to manual probing"));
#endif /* HAVE_LIBBLKID */

		dir = zpool_default_import_path;
		dirs = DEFAULT_IMPORT_PATH_SIZE;
	}

	/*
	 * Go through and read the label configuration information from every
	 * possible device, organizing the information according to pool GUID
	 * and toplevel GUID.
	 */
	for (i = 0; i < dirs; i++) {
		char *rdsk;
		int dfd;

		/* use realpath to normalize the path */
		if (realpath(dir[i], path) == 0) {

			/* it is safe to skip missing search paths */
			if (errno == ENOENT)
				continue;

			zfs_error_aux(hdl, strerror(errno));
			(void) zfs_error_fmt(hdl, EZFS_BADPATH,
			    dgettext(TEXT_DOMAIN, "cannot open '%s'"), dir[i]);
			goto error;
		}
		end = &path[strlen(path)];
		*end++ = '/';
		*end = 0;
		pathleft = &path[sizeof (path)] - end;

		/*
		 * Using raw devices instead of block devices when we're
		 * reading the labels skips a bunch of slow operations during
		 * close(2) processing, so we replace /dev/dsk with /dev/rdsk.
		 */
		if (strcmp(path, "/dev/dsk/") == 0)
			rdsk = "/dev/rdsk/";
		else
			rdsk = path;

		if ((dfd = open64(rdsk, O_RDONLY)) < 0 ||
		    (dirp = fdopendir(dfd)) == NULL) {
			zfs_error_aux(hdl, strerror(errno));
			(void) zfs_error_fmt(hdl, EZFS_BADPATH,
			    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
			    rdsk);
			goto error;
		}

		/*
		 * This is not MT-safe, but we have no MT consumers of libzfs
		 */
		while ((dp = readdir64(dirp)) != NULL) {
			const char *name = dp->d_name;
			if (name[0] == '.' &&
			    (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
				continue;

			/*
			 * Skip checking devices with well known prefixes:
			 * watchdog - A special close is required to avoid
			 *            triggering it and resetting the system.
			 * fuse     - Fuse control device.
			 * ppp      - Generic PPP driver.
			 * tty*     - Generic serial interface.
			 * vcs*     - Virtual console memory.
			 * parport* - Parallel port interface.
			 * lp*      - Printer interface.
			 * fd*      - Floppy interface.
			 * hpet     - High Precision Event Timer, crashes qemu
			 *            when accessed from a virtual machine.
			 * core     - Symlink to /proc/kcore, causes a crash
			 *            when access from Xen dom0.
			 */
			if ((strncmp(name, "watchdog", 8) == 0) ||
			    (strncmp(name, "fuse", 4) == 0)     ||
			    (strncmp(name, "ppp", 3) == 0)      ||
			    (strncmp(name, "tty", 3) == 0)      ||
			    (strncmp(name, "vcs", 3) == 0)      ||
			    (strncmp(name, "parport", 7) == 0)  ||
			    (strncmp(name, "lp", 2) == 0)       ||
			    (strncmp(name, "fd", 2) == 0)       ||
			    (strncmp(name, "hpet", 4) == 0)     ||
			    (strncmp(name, "core", 4) == 0))
				continue;

			/*
			 * Ignore failed stats.  We only want regular
			 * files and block devices.
			 */
			if ((fstatat64(dfd, name, &statbuf, 0) != 0) ||
			    (!S_ISREG(statbuf.st_mode) &&
			    !S_ISBLK(statbuf.st_mode)))
				continue;

			if ((fd = openat64(dfd, name, O_RDONLY)) < 0)
				continue;

			if ((zpool_read_label(fd, &config)) != 0) {
				(void) close(fd);
				(void) no_memory(hdl);
				goto error;
			}

			(void) close(fd);

			if (config != NULL) {
				boolean_t matched = B_TRUE;
				char *pname;

				if ((iarg->poolname != NULL) &&
				    (nvlist_lookup_string(config,
				    ZPOOL_CONFIG_POOL_NAME, &pname) == 0)) {

					if (strcmp(iarg->poolname, pname))
					       matched = B_FALSE;

				} else if (iarg->guid != 0) {
					uint64_t this_guid;

					matched = nvlist_lookup_uint64(config,
					    ZPOOL_CONFIG_POOL_GUID,
					    &this_guid) == 0 &&
					    iarg->guid == this_guid;
				}
				if (!matched) {
					nvlist_free(config);
					config = NULL;
					continue;
				}
				/* use the non-raw path for the config */
				(void) strlcpy(end, name, pathleft);
				if (add_config(hdl, &pools, path, i+1, config))
					goto error;
			}
		}

		(void) closedir(dirp);
		dirp = NULL;
	}

#ifdef HAVE_LIBBLKID
skip_scanning:
#endif
	ret = get_configs(hdl, &pools, iarg->can_be_active);

error:
	for (pe = pools.pools; pe != NULL; pe = penext) {
		penext = pe->pe_next;
		for (ve = pe->pe_vdevs; ve != NULL; ve = venext) {
			venext = ve->ve_next;
			for (ce = ve->ve_configs; ce != NULL; ce = cenext) {
				cenext = ce->ce_next;
				if (ce->ce_config)
					nvlist_free(ce->ce_config);
				free(ce);
			}
			free(ve);
		}
		free(pe);
	}

	for (ne = pools.names; ne != NULL; ne = nenext) {
		nenext = ne->ne_next;
		if (ne->ne_name)
			free(ne->ne_name);
		free(ne);
	}

	if (dirp)
		(void) closedir(dirp);

	return (ret);
}
Пример #27
0
static int
srch_dir(const entry_t path,	/* current path */
	int match_mask,		/* flags mask */
	int depth,		/* current depth (/dev = 0) */
	const entry_t skip_dirs[], /* directories not needing searching */
	struct stat64 *fsb)	/* the file being searched for */
{
	DIR *dirp;
	struct dirent64 *direntp;
	struct stat64 tsb;
	char file_name[MAX_DEV_PATH];
	entry_t file;
	char *last_comp;
	int found = 0;
	int dirno = 0;
	size_t path_len;

	file.name = file_name;
	file.flags = path.flags & match_mask;
	if (file.flags == 0)
		file.flags = match_mask;

	/*
	 * do we need to search this directory? (always search /dev at depth 0)
	 */
	if ((skip_dirs != NULL) && (depth != 0))
		while (skip_dirs[dirno].name != NULL)
			if (strcmp(skip_dirs[dirno++].name, path.name) == 0)
				return (0);

	/*
	 * open directory
	 */
	if ((dirp = opendir(path.name)) == NULL) {
		return (0);
	}

	/*
	 * skip two first entries ('.' and '..')
	 */
	if (((direntp = readdir64(dirp)) == NULL) ||
	    ((direntp = readdir64(dirp)) == NULL)) {
		(void) closedir(dirp);
		return (0);
	}

	path_len = strlen(path.name);
	(void) strcpy(file_name, path.name);
	last_comp = file_name + path_len;
	*last_comp++ = '/';

	/*
	 * read thru the directory
	 */
	while ((!found) && ((direntp = readdir64(dirp)) != NULL)) {

		/*
		 * if the file name (path + "/" + d_name + NULL) would be too
		 * long, skip it
		 */
		if ((path_len + strlen(direntp->d_name) + 2) > MAX_DEV_PATH)
			continue;
		else
			(void) strcpy(last_comp, direntp->d_name);

		if (stat64(file_name, &tsb) < 0)
			continue;

		/*
		 * if a file is a directory and we are not too deep, recurse
		 */
		if ((tsb.st_mode & S_IFMT) == S_IFDIR)
			if (depth < MAX_SRCH_DEPTH)
				found = srch_dir(file, match_mask, depth+1,
						skip_dirs, fsb);
			else
				continue;

		/*
		 * else if it is not a directory, is it a character special
		 * file?
		 */
		else if ((tsb.st_mode & S_IFMT) == S_IFCHR) {
			int flag = 0;
			if (tsb.st_dev == fsb->st_dev)
				flag |= MATCH_FS;
			if (tsb.st_rdev == fsb->st_rdev)
				flag |= MATCH_MM;
			if (tsb.st_ino == fsb->st_ino)
				flag |= MATCH_INO;

			if ((flag & file.flags) == file.flags) {
				(void) strcpy(rbuf, file.name);
				found = 1;
			} else if ((flag & (MATCH_MM | MATCH_FS)) ==
					(MATCH_MM | MATCH_FS)) {

				/*
				 * no (inodes do not match), but save the name
				 * for later
				 */
				(void) strcpy(dev_rbuf, file.name);
				dev_flag = 1;
			}
		}
	}
	(void) closedir(dirp);
	return (found);
}
Пример #28
0
/*VARARGS*/
char *
fpkginst(char *pkg, ...)
{
	static char pkginst[PKGSIZ+1];
	static DIR *pdirfp;
	struct dirent64 *dp;
	char	*pt, *ckarch, *ckvers;
	va_list	ap;

	va_start(ap, pkg);

	if (pkg == NULL) {
		/* request to close or rewind the file */
		if (pdirfp) {
			(void) closedir(pdirfp);
			pdirfp = NULL;
		}
		(void) svr4inst(NULL); /* close any files used here */
		return (NULL);
	}

	ckarch = va_arg(ap, char *);
	ckvers = va_arg(ap, char *);
	va_end(ap);

	if (!pkgdir)
		pkgdir = get_PKGLOC();

	if (!pdirfp && ((pdirfp = opendir(pkgdir)) == NULL)) {
		errno = EACCES;
		return (NULL);
	}

	while ((dp = readdir64(pdirfp)) != NULL) {
		if (dp->d_name[0] == '.')
			continue;

		if (pkgnmchk(dp->d_name, pkg, 0))
			continue; /* ignore invalid SVR4 package names */

		if (ckinfo(dp->d_name, ckarch, ckvers))
			continue;

		/*
		 * Leave directory open in case user requests another
		 * instance.
		 */
		(void) strcpy(pkginst, dp->d_name);
		return (pkginst);
	}

	/*
	 * If we are searching the directory which contains info about
	 * installed packages, check the pre-svr4 directory for an instance
	 * and be sure it matches any version specification provided to us
	 */
	if (strcmp(pkgdir, get_PKGLOC()) == 0 && (ckarch == NULL)) {
		/* search for pre-SVR4 instance */
		if (pt = svr4inst(pkg))
			return (pt);
	}
	errno = ESRCH;
	/* close any file we might have open */
	(void) closedir(pdirfp);
	pdirfp = NULL;
	return (NULL);
}
Пример #29
0
static int
do_test (void)
{
  /* fdopendir takes over the descriptor, make a copy.  */
  int dupfd = dup (dir_fd);
  if (dupfd == -1)
    {
      puts ("dup failed");
      return 1;
    }
  if (lseek (dupfd, 0, SEEK_SET) != 0)
    {
      puts ("1st lseek failed");
      return 1;
    }

  /* The directory should be empty save the . and .. files.  */
  DIR *dir = fdopendir (dupfd);
  if (dir == NULL)
    {
      puts ("fdopendir failed");
      return 1;
    }
  struct dirent64 *d;
  while ((d = readdir64 (dir)) != NULL)
    if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
      {
	printf ("temp directory contains file \"%s\"\n", d->d_name);
	return 1;
      }
  closedir (dir);

  umask (022);

  /* Try to create a file.  */
  int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
  if (fd == -1)
    {
      if (errno == ENOSYS)
	{
	  puts ("*at functions not supported");
	  return 0;
	}

      puts ("file creation failed");
      return 1;
    }
  write (fd, "hello", 5);
  puts ("file created");

  struct stat64 st1;
  if (fstat64 (fd, &st1) != 0)
    {
      puts ("fstat64 failed");
      return 1;
    }

  /* Before closing the file, try using this file descriptor to open
     another file.  This must fail.  */
  if (fchmodat (fd, "some-file", 0400, 0) != -1)
    {
      puts ("fchmodat using descriptor for normal file worked");
      return 1;
    }
  if (errno != ENOTDIR)
    {
      puts ("\
error for fchmodat using descriptor for normal file not ENOTDIR ");
      return 1;
    }
Пример #30
0
static int
ses_plugin_load_dir(ses_target_t *tp, const char *pluginroot)
{
	char path[PATH_MAX];
	DIR *dirp;
	struct dirent64 *dp;
	char *vendor, *product, *revision;
	char isa[257];

	(void) snprintf(path, sizeof (path), "%s/%s",
	    pluginroot, LIBSES_PLUGIN_FRAMEWORK);

#if defined(_LP64)
	if (sysinfo(SI_ARCHITECTURE_64, isa, sizeof (isa)) < 0)
		isa[0] = '\0';
#else
	isa[0] = '\0';
#endif

	if ((dirp = opendir(path)) != NULL) {
		while ((dp = readdir64(dirp)) != NULL) {
			if (strcmp(dp->d_name, ".") == 0 ||
			    strcmp(dp->d_name, "..") == 0)
				continue;

			(void) snprintf(path, sizeof (path), "%s/%s/%s/%s",
			    pluginroot, LIBSES_PLUGIN_FRAMEWORK,
			    isa, dp->d_name);

			if (ses_plugin_loadone(tp, path, 0) != 0) {
				(void) closedir(dirp);
				return (-1);
			}
		}

		(void) closedir(dirp);
	}

	/*
	 * Create a local copy of the vendor/product/revision, strip out any
	 * questionable characters, and then attempt to load each plugin.
	 */
	vendor = strdupa(libscsi_vendor(tp->st_target));
	product = strdupa(libscsi_product(tp->st_target));
	revision = strdupa(libscsi_revision(tp->st_target));

	ses_plugin_cleanstr(vendor);
	ses_plugin_cleanstr(product);
	ses_plugin_cleanstr(revision);

	(void) snprintf(path, sizeof (path), "%s/%s/%s/%s%s", pluginroot,
	    LIBSES_PLUGIN_VENDOR, isa, vendor,
	    LIBSES_PLUGIN_EXT);
	if (ses_plugin_loadone(tp, path, 1) != 0)
		return (-1);

	(void) snprintf(path, sizeof (path), "%s/%s/%s/%s-%s%s", pluginroot,
	    LIBSES_PLUGIN_VENDOR, isa, vendor, product,
	    LIBSES_PLUGIN_EXT);
	if (ses_plugin_loadone(tp, path, 2) != 0)
		return (-1);

	(void) snprintf(path, sizeof (path), "%s/%s/%s/%s-%s-%s%s", pluginroot,
	    LIBSES_PLUGIN_VENDOR, isa, vendor, product,
	    revision, LIBSES_PLUGIN_EXT);
	if (ses_plugin_loadone(tp, path, 3) != 0)
		return (-1);

	return (0);
}