コード例 #1
0
ファイル: drun.c プロジェクト: yusiwen/rofi
static void get_apps ( DRunModePrivateData *pd )
{
    TICK_N ( "Get Desktop apps (start)" );
    get_apps_history ( pd );

    gchar *dir;
    // First read the user directory.
    dir = g_build_filename ( g_get_user_data_dir (), "applications", NULL );
    walk_dir ( pd, dir, dir );
    g_free ( dir );
    TICK_N ( "Get Desktop apps (user dir)" );
    // Then read thee system data dirs.
    const gchar * const * sys = g_get_system_data_dirs ();
    for ( const gchar * const *iter = sys; *iter != NULL; ++iter ) {
        gboolean unique = TRUE;
        // Stupid duplicate detection, better then walking dir.
        for ( const gchar *const *iterd = sys; iterd != iter; ++iterd ) {
            if ( g_strcmp0 ( *iter, *iterd ) == 0 ) {
                unique = FALSE;
            }
        }
        // Check, we seem to be getting empty string...
        if ( unique && ( **iter ) != '\0' ) {
            dir = g_build_filename ( *iter, "applications", NULL );
            walk_dir ( pd, dir, dir );
            g_free ( dir );
        }
    }
    TICK_N ( "Get Desktop apps (system dirs)" );
}
コード例 #2
0
ファイル: drun.c プロジェクト: valsoray17/rofi
static void get_apps ( DRunModePrivateData *pd )
{
    get_apps_history ( pd );

    gchar               *dir;
    const gchar * const * sys = g_get_system_data_dirs ();
    for (; *sys != NULL; ++sys ) {
        dir = g_build_filename ( *sys, "applications", NULL );
        walk_dir ( pd, dir );
        g_free ( dir );
    }
    dir = g_build_filename ( g_get_user_data_dir (), "applications", NULL );
    walk_dir ( pd, dir );
    g_free ( dir );
}
コード例 #3
0
ファイル: pfind.c プロジェクト: vladak/unix-prog-cvika
int walk_dir(char *dir)
{
	DIR *d;
	struct dirent *de;

	if ((d = opendir(dir)) == NULL) {
		fprintf(stderr, "Error opening dir %s: %s\n", dir, strerror(errno));
		return (1);
	}

	while ((de = readdir(d)) != NULL) {
		if (de->d_name[0] == '.')
			continue;

		if (de->d_type == DT_DIR) {
			char *name;
			name = malloc(strlen(dir) + strlen(de->d_name) + 2);
			sprintf(name, "%s/%s", dir, de->d_name);

			(void) walk_dir(name);
			free(name);
		} else if (de->d_type == DT_REG) {
			printf("%s/%s\n", dir, de->d_name);
		}
	}

	closedir(d);

	return (0);
}
コード例 #4
0
ファイル: walktree.c プロジェクト: taysom/tau
int main (int argc, char *argv[])
{
	char *dir = ".";
	tick_t start;
	tick_t finish;
	tick_t total;

	if (argc > 1) dir = argv[1];

	NumFiles = 0;
	start = nsecs();
	nftw_walk_tree(dir);
	finish = nsecs();
	total = finish - start;
	printf("%lld nsecs %d\n", total, NumFiles);

	NumFiles = 0;
	start = nsecs();
	walk_dir(dir, donothing, NULL, 0);
	finish = nsecs();
	total = finish - start;
	printf("%lld nsecs %d\n", total, NumFiles);

	NumFiles = 0;
	start = nsecs();
	walk_tree(dir, prfile, NULL);
	finish = nsecs();
	total = finish - start;
	printf("%lld nsecs %d\n", total, NumFiles);

	return 0;
}
コード例 #5
0
ファイル: sdev_profile.c プロジェクト: bahamas10/openzfs
static int
is_nonempty_dir(char *name, char *pathleft, struct sdev_node *dir)
{
	struct match_arg marg;
	struct pathname pn;
	struct vnode *gvp;
	struct sdev_node *gdir = dir->sdev_origin;

	if (VOP_LOOKUP(SDEVTOV(gdir), name, &gvp, NULL, 0, NULL, kcred,
	    NULL, NULL, NULL) != 0)
		return (0);

	if (gvp->v_type != VDIR) {
		VN_RELE(gvp);
		return (0);
	}

	if (pn_get(pathleft, UIO_SYSSPACE, &pn) != 0) {
		VN_RELE(gvp);
		return (0);
	}

	marg.expr = kmem_alloc(MAXNAMELEN, KM_SLEEP);
	(void) pn_getcomponent(&pn, marg.expr);
	marg.match = 0;

	walk_dir(gvp, &marg, match_name);
	VN_RELE(gvp);
	kmem_free(marg.expr, MAXNAMELEN);
	pn_free(&pn);

	return (marg.match);
}
コード例 #6
0
ファイル: drun.c プロジェクト: valsoray17/rofi
/**
 * Internal spider used to get list of executables.
 */
static void walk_dir ( DRunModePrivateData *pd, const char *dirname )
{
    DIR *dir;

    dir = opendir ( dirname );
    if ( dir == NULL ) {
        return;
    }

    struct dirent *file;
    gchar         *filename = NULL;
    struct stat   st;
    while ( ( file = readdir ( dir ) ) != NULL ) {
        if ( file->d_name[0] == '.' ) {
            continue;
        }

        switch ( file->d_type )
        {
        case DT_LNK:
        case DT_REG:
        case DT_DIR:
        case DT_UNKNOWN:
            filename = g_build_filename ( dirname, file->d_name, NULL );
            break;
        default:
            continue;
        }

        // On a link, or if FS does not support providing this information
        // Fallback to stat method.
        if ( file->d_type == DT_LNK || file->d_type == DT_UNKNOWN ) {
            file->d_type = DT_UNKNOWN;
            if ( stat ( filename, &st ) == 0 ) {
                if ( S_ISDIR ( st.st_mode ) ) {
                    file->d_type = DT_DIR;
                }
                else if ( S_ISREG ( st.st_mode ) ) {
                    file->d_type = DT_REG;
                }
            }
        }

        switch ( file->d_type )
        {
        case DT_REG:
            read_desktop_file ( pd, filename, file->d_name );
            filename = NULL;
            break;
        case DT_DIR:
            walk_dir ( pd, filename );
            break;
        default:
            break;
        }
        g_free ( filename );
    }
    closedir ( dir );
}
コード例 #7
0
ファイル: sdev_profile.c プロジェクト: bahamas10/openzfs
static void
prof_make_names_walk(struct sdev_node *ddv, int (*cb)(char *, void *))
{
	struct sdev_node *gdir;

	gdir = ddv->sdev_origin;
	if (gdir == NULL)
		return;
	walk_dir(SDEVTOV(gdir), (void *)ddv, cb);
}
コード例 #8
0
ファイル: drun.c プロジェクト: pfsmorigo/rofi
static void get_apps ( DRunModePrivateData *pd )
{
    TICK_N ( "Get Desktop apps (start)" );
    get_apps_history ( pd );

    gchar *dir;
    // First read the user directory.
    dir = g_build_filename ( g_get_user_data_dir (), "applications", NULL );
    walk_dir ( pd, dir, dir );
    g_free ( dir );
    TICK_N ( "Get Desktop apps (user dir)" );
    // Then read thee system data dirs.
    const gchar * const * sys = g_get_system_data_dirs ();
    for (; *sys != NULL; ++sys ) {
        dir = g_build_filename ( *sys, "applications", NULL );
        walk_dir ( pd, dir, dir );
        g_free ( dir );
    }
    TICK_N ( "Get Desktop apps (system dirs)" );
}
コード例 #9
0
ファイル: mod5.c プロジェクト: AARONANDRESLEON/g2root-kmod
static int __init test_init(void) {
        printk("test module loaded\n");

	pbus_kobject = &platform_bus.kobj;
	sd = pbus_kobject->sd;

	printk("platform_bus kobject: %.8x\n", (unsigned int)pbus_kobject);

	walk_dir(sd);

	return 0;
}
コード例 #10
0
ファイル: edata.c プロジェクト: 173210/kirk_engine
int main(int argc, char *argv[])
{
	printf("\n");
	printf("freedata: convert EDAT file to use fixed license. writen by tpu.\n");
	printf("-------------------------------------------------------------\n");
	printf("\n");

	if(argc==2 && (strcmp(argv[1], "-v")==0))
		verbose = 1;

	return walk_dir(".", free_edata, 0);
}
コード例 #11
0
ファイル: dnas.c プロジェクト: 173210/kirk_engine
int main(int argc, char *argv[])
{
	printf("\n");
	printf("pgdecrypt: decrypt EDAT/PGD file. writen by tpu.\n");
	printf("-------------------------------------------------------------\n");
	printf("\n");

	if(argc==2 && (strcmp(argv[1], "-v")==0))
		verbose = 1;

	return walk_dir(".", process_pgd, 0);

}
コード例 #12
0
ファイル: fat_test.c プロジェクト: Karamax/arrakis
int main(int argc, char *argv[])
{
    vfs_init();
    vfs_mkdir("/fat");
    
    errval_t err = vfs_mount("/fat", "fat32://0+0");
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "vfs_fat_mount failed");
    }

    walk_dir("/fat");

    return 0;
}
コード例 #13
0
ファイル: main.c プロジェクト: AdityaKotwal/Dedup_Project
int main()
{
	cleanFile(DST);
	int r = walk_dir("/Users/akotwal/Documents", ".\\.c$", WS_DEFAULT|WS_MATCHDIRS,doit);
	switch(r) {
        case WALK_OK:		break;
        case WALK_BADIO:	err(1, "IO error");
        case WALK_BADPATTERN:	err(1, "Bad pattern");
        case WALK_NAMETOOLONG:	err(1, "Filename too long");
        default:
            err(1, "Unknown error?");
	}
	return 0;
}
コード例 #14
0
ファイル: fs_map_w.c プロジェクト: mhw/topfield-hdsave
int
map_write(FSInfo *fs, char *path)
{
	FileHandle *root;
	FileHandle *bad;

	if (!map_open_write(path))
		return 0;
	if ((root = file_open_root(fs)) == 0)
		return 0;
	walk_dir(root);
	file_close(root);
	map_close();
	return 1;
}
コード例 #15
0
ファイル: mod5.c プロジェクト: AARONANDRESLEON/g2root-kmod
static void walk_dir(struct sysfs_dirent *dir) {
	
	printk("dirent flags: %d\n", dir->s_flags);
	printk("dirent name: %s\n", dir->s_name);

	if (dir->s_flags & SYSFS_DIR) {
		walk_dir(dir->s_dir.children);
		return;
	};

	if (dir->s_flags & SYSFS_KOBJ_ATTR) {
		return;
	};

	return;
}
コード例 #16
0
ファイル: fat_test.c プロジェクト: Karamax/arrakis
static void walk_dir(char* path)
{
    printf("%s:%d: path=%s\n", __FUNCTION__, __LINE__, path);
    vfs_handle_t dhandle;
    struct vfs_fileinfo info;
    
    errval_t err = vfs_opendir(path, &dhandle);
    assert(err_is_ok(err));

    char* name;
    while(err_is_ok(vfs_dir_read_next(dhandle, &name, &info))) {

        if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
            continue;
        char* newpath = malloc(snprintf(NULL, 0, "%s/%s", path, name) + 1);
        sprintf(newpath, "%s/%s", path, name);

        switch (info.type) {
        case VFS_DIRECTORY:
            printf("%s:%d: Found directory %s\n", __FUNCTION__, __LINE__, newpath);
            walk_dir(newpath);
            break;
        
        case VFS_FILE:
            printf("%s:%d: Found file %s\n", __FUNCTION__, __LINE__, newpath);
            vfs_handle_t fhandle;

            err = vfs_open(newpath, &fhandle);
            char* buf = malloc(info.size);
            size_t bytes_read = 0;
            err = vfs_read(fhandle, buf, info.size, &bytes_read);
            assert(err_is_ok(err));
            assert(bytes_read == info.size);
            printf("%s:%d: File content is (bytes=%d):\n%s\n", 
                   __FUNCTION__, __LINE__, bytes_read, buf);

            free(buf);
            break;
        }
        free(name);
        free(newpath);
    }

    err = vfs_closedir(dhandle);
    assert(err_is_ok(err));   
}
コード例 #17
0
ファイル: file_system.cpp プロジェクト: emilk/emilib
void walk_dir(const std::string& path, const std::function<void(const std::string&)>& visitor)
{
	CHECK_F(path.empty() || path[path.size() - 1] == '/',
		"Expected a path to a directory ending with a slash, got '%s'", path.c_str());

	auto directory = opendir(path.c_str());
	if (!directory) {
		LOG_F(ERROR, "Failed to open %s", path.c_str());
		return;
	}
	while (auto dentry = readdir(directory)) {
		if (dentry->d_name[0] == '.') { continue; }
		if (dentry->d_type == DT_REG) {
			visitor(path + dentry->d_name);
		} else if (dentry->d_type == DT_DIR) {
			walk_dir(path + dentry->d_name + "/", visitor);
		}
	}
	closedir(directory);
}
コード例 #18
0
ファイル: pfind.c プロジェクト: vladak/unix-prog-cvika
int main(int argc, char *argv[])
{
	pid_t pid;
	int fd[2];
	int st;

	if (argc < 2) {
		fprintf(stderr, "Usage: %s <dir>\n", argv[0]);
		return (EXIT_FAILURE);
	}

	if (pipe(fd) == -1) {
		fprintf(stderr, "pipe() error: %s\n", strerror(errno));
		return (EXIT_FAILURE);
	}

	switch (pid = fork()) {
	case 0:
		/* child */
		close(fd[0]);
		close(1);
		dup2(fd[1], 1);
		close(fd[1]);
		return walk_dir(argv[1]);
	case -1:
		/* chyba */
		fprintf(stderr, "fork() error: %s\n", strerror(errno));
		return (EXIT_FAILURE);
	default:
		/* parent */
		close(fd[1]);
		close(0);
		dup2(fd[0], 0);
		close(fd[0]);
		read_input();
		wait(&st);
		break;
	}

	return (EXIT_SUCCESS);
}
コード例 #19
0
ファイル: file_comp.c プロジェクト: hegek87/os
//0 is success, -1 is error
int process(char *path){
	struct stat cur_obj;
	if(lstat(path, &cur_obj)){
		perror("Failed to stat object\n");
		return -1;
	}
	mode_t x = cur_obj.st_mode;
	if(S_ISLNK(x)){
		return 1;
	}
	else if(S_ISDIR(x)){
		walk_dir(path);		
	}
	else{
		char *p_cmd[3] = { MD5_PATH, (char *)path, (char *)NULL };
		char *hash = compute_hash(p_cmd);
		visit(hash, (char *)path);
		//printf("%s\n", hash);
		//insert_el_head(visited, path);
	}
	return 0;
}
コード例 #20
0
ファイル: walk.c プロジェクト: taysom/tau
void walk_dir (char *name, dir_f f, void *arg, int level)
{
    DIR				*dir;
    struct dirent	*de;

    f(name, arg, level);

    if (chdir(name) == -1) return;
    dir = opendir(".");
    if (dir == NULL) return;


    for (;;) {
        de = readdir(dir);
        if (!de) break;
        if (strcmp(de->d_name, ".") == 0) continue;
        if (strcmp(de->d_name, "..") == 0) continue;
        walk_dir(de->d_name, f, arg, level+1);
    }
    closedir(dir);
    if (chdir("..")) return;
}
コード例 #21
0
static int
set_acl(acl_t acl, acl_t dacl, const char *fname)
{
	int failed = 0;

	if (rflag)
		failed += walk_dir(acl, dacl, fname);

	/* set regular acl */
	if (acl && acl_set_file(fname, ACL_TYPE_ACCESS, acl) == -1) {
		fprintf(stderr, _("%s: cannot set access acl on \"%s\": %s\n"),
			program, fname, strerror(errno));
		failed++;
	}
	/* set default acl */
	if (dacl && acl_set_file(fname, ACL_TYPE_DEFAULT, dacl) == -1) {
		fprintf(stderr, _("%s: cannot set default acl on \"%s\": %s\n"),
			program, fname, strerror(errno));
		failed++;
	}

	return(failed);
}
コード例 #22
0
ファイル: main.c プロジェクト: akozadaev/find-dups
/* handle the files in the given directory
 * calls walk_dir in case a directory is found and recursively
 * looking through in the subdirectories */
static int
handle_file(char *fname)
{
    struct stat stbuf;
    md5_t chksum = { 0 };

    if (stat(fname, &stbuf) == -1) {
        perror(strerror(errno));
        goto error;
    }

    if (S_ISDIR(stbuf.st_mode)) {
        check_error(walk_dir(fname, handle_file));
    } else {
        check_error(md5_get(fname, chksum));
        hasharray_add(chksum, fname);
        update_progress();
    }

    return R_OK;

error:
    return R_ERR;
}
コード例 #23
0
ファイル: fs_map_w.c プロジェクト: mhw/topfield-hdsave
static int
walk_dir_entry(FileHandle *dir, void *arg, DirEntry *entry, int index)
{
	FileHandle *file;

	switch (entry->type)
	{
	case DIR_ENTRY_UNUSED:
	case DIR_ENTRY_DOT_DOT:
	case DIR_ENTRY_DOT:
	case DIR_ENTRY_RECYCLE:
		break;
	case DIR_ENTRY_FILEA:
	case DIR_ENTRY_FILET:
		map_printf("%s: ", entry->filename);
		if ((file = file_open_dir_entry(dir, entry)) == 0)
			return 0;
		map_clusters(file);
		file_close(file);
		map_printf("\n");
		break;
	case DIR_ENTRY_SUBDIR:
		map_printf("%s: {\n", entry->filename);
		if ((file = file_open_dir_entry(dir, entry)) == 0)
			return 0;
		if (!walk_dir(file))
			return 0;
		file_close(file);
		map_printf("}\n");
		break;
	default:
		fs_error("unrecognised directory entry type %d", entry->type);
		return 0;
	}
	return 1;
}
コード例 #24
0
void walk_inoext( int		device,
		  uint64	address,
		  uint32	length,
		  uint32	wmap,
		  dinomap_t	*control_page,
		  uint32	agno,
		  ino_t		start_inum,
		  uint32	*found_map,
		  int32		inostamp )
{
    dinode_t	*next_inode;
    uint32	left_to_read = length << sb.s_l2bsize;
    uint64	cur_address = address << sb.s_l2bsize;
    int32	index, rc;
    uint32	map = wmap;
    char	page_buffer[PSIZE];
    ino_t	cur_inum = start_inum;
    uint32	mask = HIGHORDER;
    uint64	first_block, cur_block, last_block;
    uint32	num_blocks;
    int64	total_nblocks;

    *found_map = 0;

    while( (left_to_read > 0) ) {
	/*
	 * Read next page of inodes for this extent
	 */
	rc = ujfs_rw_diskblocks( device, cur_address, PSIZE, page_buffer, GET );
	cur_address += PSIZE;
	left_to_read -= PSIZE;

	next_inode = (dinode_t *)page_buffer;
	for( index = 0; index < INOSPERPAGE;
	     index++, next_inode++, cur_inum++, map <<= 1, mask >>= 1 ) {
	    /*
	     * Initialize count for this inode's number of blocks
	     */
	    total_nblocks = 0;

	    /*
	     * If this inode is allocated, mark blocks for its b-tree
	     */
	    if( (map & HIGHORDER) != 0 ) {
		if( next_inode->di_nlink <= 0 ) {
		    error++;
		    printf("Inode %d (fileset: %d) link count bad: %d\n",
			next_inode->di_number, next_inode->di_fileset,
			next_inode->di_nlink);
		} else {
		    *found_map |= mask;
		}

		/*
		 * Account for any blocks used by EA for this inode
		 */
		if( next_inode->di_ea.flag & DXD_EXTENT ) {
		    first_block = addressDXD(&(next_inode->di_ea));
		    num_blocks = lengthDXD(&(next_inode->di_ea));
		    total_nblocks += num_blocks;
		    last_block = first_block + num_blocks;
		    for( cur_block = first_block; cur_block < last_block;
				cur_block++ ) {
			markit( cur_block, 0 );
		    }
		}

		if( (next_inode->di_fileset == AGGREGATE_I) &&
			(next_inode->di_number == FILESYSTEM_I) ) {
		    /*
		     * Need to account for inode map's blocks
		     */
		    walk_inode_tree(device, (xtpage_t *)&next_inode->di_btroot,
					&total_nblocks, 0);

		    /*
		     * Need to walk this tree of inodes
		     */
		    rc = walk_ait( device, next_inode, TRUE );
		    if( rc != 0 ) {
			error++;
			printf("Problem with Fileset Inode Allocation Map.\n");
		    }
		} else if( (next_inode->di_fileset == AGGREGATE_I) &&
			(next_inode->di_number == BADBLOCK_I) ) {
		    walk_inode_tree(device, (xtpage_t *)&next_inode->di_btroot,
					&total_nblocks, BADBLOCK);
		} else if( next_inode->di_mode & IFDIR ) {
		    /*
		     * Need to walk the extents as directory extents
		     */
		    walk_dir( device, (dtroot_t *)&(next_inode->di_btroot),
				&total_nblocks);
		} else {
		    walk_inode_tree(device, (xtpage_t *)&next_inode->di_btroot,
					&total_nblocks, 0);
		}

		/*
		 * Now total_nblocks contains the total number of blocks
		 * actually allocated for this inode.  Compare this to the
		 * on-disk information.
		 */
		if( next_inode->di_nblocks != total_nblocks ) {
		    error++;
		    printf(
	       "Inode %d (fileset: %d) nblocks bad, disk: %lld, actual: %lld\n",
			next_inode->di_number, next_inode->di_fileset,
			next_inode->di_nblocks, total_nblocks);
		}
	    } else {
		if( next_inode->di_number == cur_inum &&
			next_inode->di_inostamp == inostamp &&
			addressPXD(&(next_inode->di_ixpxd)) == address &&
			lengthPXD(&(next_inode->di_ixpxd)) == length &&
			next_inode->di_nlink > 0 ) {
		    error++;
		    printf("Inode %d (fileset: %d) link count bad: %d\n",
				next_inode->di_number, next_inode->di_fileset,
				next_inode->di_nlink);
		    *found_map |= mask;
		}
		control_page->in_numfree++;
		control_page->in_agctl[agno].numfree++;
	    }
	}
    }
}
コード例 #25
0
ファイル: makefs.c プロジェクト: Ricky54326/freebsd
int
main(int argc, char *argv[])
{
	struct stat	 sb;
	struct timeval	 start;
	fstype_t	*fstype;
	fsinfo_t	 fsoptions;
	fsnode		*root;
	int	 	 ch, i, len;
	char		*subtree;
	char		*specfile;

	setprogname(argv[0]);

	debug = 0;
	if ((fstype = get_fstype(DEFAULT_FSTYPE)) == NULL)
		errx(1, "Unknown default fs type `%s'.", DEFAULT_FSTYPE);

		/* set default fsoptions */
	(void)memset(&fsoptions, 0, sizeof(fsoptions));
	fsoptions.fd = -1;
	fsoptions.sectorsize = -1;

	if (fstype->prepare_options)
		fstype->prepare_options(&fsoptions);

	specfile = NULL;
	if (gettimeofday(&start, NULL) == -1)
		err(1, "Unable to get system time");

	start_time.tv_sec = start.tv_sec;
	start_time.tv_nsec = start.tv_usec * 1000;

	while ((ch = getopt(argc, argv, "B:b:Dd:f:F:M:m:N:o:pr:s:S:t:xZ")) != -1) {
		switch (ch) {

		case 'B':
			if (strcmp(optarg, "be") == 0 ||
			    strcmp(optarg, "4321") == 0 ||
			    strcmp(optarg, "big") == 0) {
#if BYTE_ORDER == LITTLE_ENDIAN
				fsoptions.needswap = 1;
#endif
			} else if (strcmp(optarg, "le") == 0 ||
			    strcmp(optarg, "1234") == 0 ||
			    strcmp(optarg, "little") == 0) {
#if BYTE_ORDER == BIG_ENDIAN
				fsoptions.needswap = 1;
#endif
			} else {
				warnx("Invalid endian `%s'.", optarg);
				usage();
			}
			break;

		case 'b':
			len = strlen(optarg) - 1;
			if (optarg[len] == '%') {
				optarg[len] = '\0';
				fsoptions.freeblockpc =
				    strsuftoll("free block percentage",
					optarg, 0, 99);
			} else {
				fsoptions.freeblocks =
				    strsuftoll("free blocks",
					optarg, 0, LLONG_MAX);
			}
			break;

		case 'D':
			dupsok = 1;
			break;

		case 'd':
			debug = strtoll(optarg, NULL, 0);
			break;

		case 'f':
			len = strlen(optarg) - 1;
			if (optarg[len] == '%') {
				optarg[len] = '\0';
				fsoptions.freefilepc =
				    strsuftoll("free file percentage",
					optarg, 0, 99);
			} else {
				fsoptions.freefiles =
				    strsuftoll("free files",
					optarg, 0, LLONG_MAX);
			}
			break;

		case 'F':
			specfile = optarg;
			break;

		case 'M':
			fsoptions.minsize =
			    strsuftoll("minimum size", optarg, 1LL, LLONG_MAX);
			break;

		case 'N':
			if (! setup_getid(optarg))
				errx(1,
			    "Unable to use user and group databases in `%s'",
				    optarg);
			break;

		case 'm':
			fsoptions.maxsize =
			    strsuftoll("maximum size", optarg, 1LL, LLONG_MAX);
			break;
			
		case 'o':
		{
			char *p;

			while ((p = strsep(&optarg, ",")) != NULL) {
				if (*p == '\0')
					errx(1, "Empty option");
				if (! fstype->parse_options(p, &fsoptions))
					usage();
			}
			break;
		}
		case 'p':
			/* Deprecated in favor of 'Z' */
			fsoptions.sparse = 1;
			break;

		case 'r':
			/* Round image size up to specified block size */
			fsoptions.roundup =
			    strsuftoll("roundup", optarg, 0, LLONG_MAX);
			break;

		case 's':
			fsoptions.minsize = fsoptions.maxsize =
			    strsuftoll("size", optarg, 1LL, LLONG_MAX);
			break;

		case 'S':
			fsoptions.sectorsize =
			    (int)strsuftoll("sector size", optarg,
				1LL, INT_MAX);
			break;

		case 't':
			/* Check current one and cleanup if necessary. */
			if (fstype->cleanup_options)
				fstype->cleanup_options(&fsoptions);
			fsoptions.fs_specific = NULL;
			if ((fstype = get_fstype(optarg)) == NULL)
				errx(1, "Unknown fs type `%s'.", optarg);
			fstype->prepare_options(&fsoptions);
			break;

		case 'x':
			fsoptions.onlyspec = 1;
			break;

		case 'Z':
			/* Superscedes 'p' for compatibility with NetBSD makefs(8) */
			fsoptions.sparse = 1;
			break;

		case '?':
		default:
			usage();
			/* NOTREACHED */

		}
	}
	if (debug) {
		printf("debug mask: 0x%08x\n", debug);
		printf("start time: %ld.%ld, %s",
		    (long)start_time.tv_sec, (long)start_time.tv_nsec,
		    ctime(&start_time.tv_sec));
	}
	argc -= optind;
	argv += optind;

	if (argc < 2)
		usage();

	/* -x must be accompanied by -F */
	if (fsoptions.onlyspec != 0 && specfile == NULL)
		errx(1, "-x requires -F mtree-specfile.");

	/* Accept '-' as meaning "read from standard input". */
	if (strcmp(argv[1], "-") == 0)
		sb.st_mode = S_IFREG;
	else {
		if (stat(argv[1], &sb) == -1)
			err(1, "Can't stat `%s'", argv[1]);
	}

	switch (sb.st_mode & S_IFMT) {
	case S_IFDIR:		/* walk the tree */
		subtree = argv[1];
		TIMER_START(start);
		root = walk_dir(subtree, ".", NULL, NULL);
		TIMER_RESULTS(start, "walk_dir");
		break;
	case S_IFREG:		/* read the manifest file */
		subtree = ".";
		TIMER_START(start);
		root = read_mtree(argv[1], NULL);
		TIMER_RESULTS(start, "manifest");
		break;
	default:
		errx(1, "%s: not a file or directory", argv[1]);
		/* NOTREACHED */
	}

	/* append extra directory */
	for (i = 2; i < argc; i++) {
		if (stat(argv[i], &sb) == -1)
			err(1, "Can't stat `%s'", argv[i]);
		if (!S_ISDIR(sb.st_mode))
			errx(1, "%s: not a directory", argv[i]);
		TIMER_START(start);
		root = walk_dir(argv[i], ".", NULL, root);
		TIMER_RESULTS(start, "walk_dir2");
	}

	if (specfile) {		/* apply a specfile */
		TIMER_START(start);
		apply_specfile(specfile, subtree, root, fsoptions.onlyspec);
		TIMER_RESULTS(start, "apply_specfile");
	}

	if (debug & DEBUG_DUMP_FSNODES) {
		printf("\nparent: %s\n", subtree);
		dump_fsnodes(root);
		putchar('\n');
	}

				/* build the file system */
	TIMER_START(start);
	fstype->make_fs(argv[0], subtree, root, &fsoptions);
	TIMER_RESULTS(start, "make_fs");

	free_fsnodes(root);

	exit(0);
	/* NOTREACHED */
}
コード例 #26
0
ファイル: drun.c プロジェクト: yusiwen/rofi
static void exec_cmd_entry ( DRunModeEntry *e )
{
    GError *error = NULL;
    GRegex *reg   = g_regex_new ( "%[a-zA-Z]", 0, 0, &error );
    if ( error != NULL ) {
        g_warning ( "Internal error, failed to create regex: %s.", error->message );
        g_error_free ( error );
        return;
    }
    struct RegexEvalArg earg = { .e = e, .success = TRUE };
    char                *str = g_regex_replace_eval ( reg, e->exec, -1, 0, 0, drun_helper_eval_cb, &earg, &error );
    if ( error != NULL ) {
        g_warning ( "Internal error, failed replace field codes: %s.", error->message );
        g_error_free ( error );
        return;
    }
    g_regex_unref ( reg );
    if ( earg.success == FALSE ) {
        g_warning ( "Invalid field code in Exec line: %s.", e->exec );;
        return;
    }
    if ( str == NULL ) {
        g_warning ( "Nothing to execute after processing: %s.", e->exec );;
        return;
    }

    const gchar *fp        = g_strstrip ( str );
    gchar       *exec_path = g_key_file_get_string ( e->key_file, "Desktop Entry", "Path", NULL );
    if ( exec_path != NULL && strlen ( exec_path ) == 0 ) {
        // If it is empty, ignore this property. (#529)
        g_free ( exec_path );
        exec_path = NULL;
    }

    RofiHelperExecuteContext context = {
        .name   = e->name,
        .icon   = e->icon_name,
        .app_id = e->app_id,
    };
    gboolean                 sn       = g_key_file_get_boolean ( e->key_file, "Desktop Entry", "StartupNotify", NULL );
    gchar                    *wmclass = NULL;
    if ( sn && g_key_file_has_key ( e->key_file, "Desktop Entry", "StartupWMClass", NULL ) ) {
        context.wmclass = wmclass = g_key_file_get_string ( e->key_file, "Desktop Entry", "StartupWMClass", NULL );
    }

    // Returns false if not found, if key not found, we don't want run in terminal.
    gboolean terminal = g_key_file_get_boolean ( e->key_file, "Desktop Entry", "Terminal", NULL );
    if ( helper_execute_command ( exec_path, fp, terminal, sn ? &context : NULL ) ) {
        char *path = g_build_filename ( cache_dir, DRUN_CACHE_FILE, NULL );
        char *key  = g_strdup_printf ( "%s:::%s", e->root, e->path );
        history_set ( path, key );
        g_free ( key );
        g_free ( path );
    }
    g_free ( wmclass );
    g_free ( exec_path );
    g_free ( str );
}
/**
 * This function absorbs/freeś path, so this is no longer available afterwards.
 */
static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, const char *path, const gchar *basename )
{
    // Create ID on stack.
    // We know strlen (path ) > strlen(root)+1
    const ssize_t id_len = strlen ( path ) - strlen ( root );
    char          id[id_len];
    g_strlcpy ( id, &( path[strlen ( root ) + 1] ), id_len );
    for ( int index = 0; index < id_len; index++ ) {
        if ( id[index] == '/' ) {
            id[index] = '-';
        }
    }

    // Check if item is on disabled list.
    if ( g_hash_table_contains ( pd->disabled_entries, id ) ) {
        g_debug ( "Skipping: %s, was previously seen.", id );
        return TRUE;
    }
    GKeyFile *kf    = g_key_file_new ();
    GError   *error = NULL;
    g_key_file_load_from_file ( kf, path, 0, &error );
    // If error, skip to next entry
    if ( error != NULL ) {
        g_debug ( "Failed to parse desktop file: %s because: %s", path, error->message );
        g_error_free ( error );
        g_key_file_free ( kf );
        return FALSE;
    }
    // Skip non Application entries.
    gchar *key = g_key_file_get_string ( kf, "Desktop Entry", "Type", NULL );
    if ( key == NULL ) {
        // No type? ignore.
        g_debug ( "Skipping desktop file: %s because: No type indicated", path );
        g_key_file_free ( kf );
        return FALSE;
    }
    if ( g_strcmp0 ( key, "Application" ) ) {
        g_debug ( "Skipping desktop file: %s because: Not of type application (%s)", path, key );
        g_free ( key );
        g_key_file_free ( kf );
        return FALSE;
    }
    g_free ( key );

    // Name key is required.
    if ( !g_key_file_has_key ( kf, "Desktop Entry", "Name", NULL ) ) {
        g_debug ( "Invalid DesktopFile: '%s', no 'Name' key present.", path );
        g_key_file_free ( kf );
        return FALSE;
    }

    // Skip hidden entries.
    if ( g_key_file_get_boolean ( kf, "Desktop Entry", "Hidden", NULL ) ) {
        g_debug ( "Adding desktop file: %s to disabled list because: Hdden", path );
        g_key_file_free ( kf );
        g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) );
        return FALSE;
    }
    // Skip entries that have NoDisplay set.
    if ( g_key_file_get_boolean ( kf, "Desktop Entry", "NoDisplay", NULL ) ) {
        g_debug ( "Adding desktop file: %s to disabled list because: NoDisplay", path );
        g_key_file_free ( kf );
        g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) );
        return FALSE;
    }
    // We need Exec, don't support DBusActivatable
    if ( !g_key_file_has_key ( kf, "Desktop Entry", "Exec", NULL ) ) {
        g_debug ( "Unsupported DesktopFile: '%s', no 'Exec' key present.", path );
        g_key_file_free ( kf );
        return FALSE;
    }

    if ( g_key_file_has_key ( kf, "Desktop Entry", "TryExec", NULL ) ) {
        char *te = g_key_file_get_string ( kf, "Desktop Entry", "TryExec", NULL );
        if ( !g_path_is_absolute ( te ) ) {
            char *fp = g_find_program_in_path ( te );
            if ( fp == NULL ) {
                g_free ( te );
                g_key_file_free ( kf );
                return FALSE;
            }
            g_free ( fp );
        }
        else {
            if ( g_file_test ( te, G_FILE_TEST_IS_EXECUTABLE ) == FALSE ) {
                g_free ( te );
                g_key_file_free ( kf );
                return FALSE;
            }
        }
        g_free ( te );
    }

    size_t nl = ( ( pd->cmd_list_length ) + 1 );
    if ( nl >= pd->cmd_list_length_actual ) {
        pd->cmd_list_length_actual += 256;
        pd->entry_list              = g_realloc ( pd->entry_list, pd->cmd_list_length_actual * sizeof ( *( pd->entry_list ) ) );
    }
    pd->entry_list[pd->cmd_list_length].icon_size = 0;
    pd->entry_list[pd->cmd_list_length].root      = g_strdup ( root );
    pd->entry_list[pd->cmd_list_length].path      = g_strdup ( path );
    pd->entry_list[pd->cmd_list_length].app_id    = g_strndup ( basename, strlen ( basename ) - strlen ( ".desktop" ) );
    gchar *n = g_key_file_get_locale_string ( kf, "Desktop Entry", "Name", NULL, NULL );
    pd->entry_list[pd->cmd_list_length].name = n;
    gchar *gn = g_key_file_get_locale_string ( kf, "Desktop Entry", "GenericName", NULL, NULL );
    pd->entry_list[pd->cmd_list_length].generic_name = gn;
    pd->entry_list[pd->cmd_list_length].categories   = g_key_file_get_locale_string_list ( kf, "Desktop Entry", "Categories", NULL, NULL, NULL );
    pd->entry_list[pd->cmd_list_length].exec         = g_key_file_get_string ( kf, "Desktop Entry", "Exec", NULL );

    if ( config.show_icons ) {
        pd->entry_list[pd->cmd_list_length].icon_name = g_key_file_get_locale_string ( kf, "Desktop Entry", "Icon", NULL, NULL );
    }
    else{
        pd->entry_list[pd->cmd_list_length].icon_name = NULL;
    }
    pd->entry_list[pd->cmd_list_length].icon = NULL;

    // Keep keyfile around.
    pd->entry_list[pd->cmd_list_length].key_file = kf;
    // We don't want to parse items with this id anymore.
    g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) );
    ( pd->cmd_list_length )++;
    return TRUE;
}

/**
 * Internal spider used to get list of executables.
 */
static void walk_dir ( DRunModePrivateData *pd, const char *root, const char *dirname )
{
    DIR *dir;

    g_debug ( "Checking directory %s for desktop files.", dirname );
    dir = opendir ( dirname );
    if ( dir == NULL ) {
        return;
    }

    struct dirent *file;
    gchar         *filename = NULL;
    struct stat   st;
    while ( ( file = readdir ( dir ) ) != NULL ) {
        if ( file->d_name[0] == '.' ) {
            continue;
        }
        switch ( file->d_type )
        {
        case DT_LNK:
        case DT_REG:
        case DT_DIR:
        case DT_UNKNOWN:
            filename = g_build_filename ( dirname, file->d_name, NULL );
            break;
        default:
            continue;
        }

        // On a link, or if FS does not support providing this information
        // Fallback to stat method.
        if ( file->d_type == DT_LNK || file->d_type == DT_UNKNOWN ) {
            file->d_type = DT_UNKNOWN;
            if ( stat ( filename, &st ) == 0 ) {
                if ( S_ISDIR ( st.st_mode ) ) {
                    file->d_type = DT_DIR;
                }
                else if ( S_ISREG ( st.st_mode ) ) {
                    file->d_type = DT_REG;
                }
            }
        }

        switch ( file->d_type )
        {
        case DT_REG:
            // Skip files not ending on .desktop.
            if ( g_str_has_suffix ( file->d_name, ".desktop" ) ) {
                read_desktop_file ( pd, root, filename, file->d_name );
            }
            break;
        case DT_DIR:
            walk_dir ( pd, root, filename );
            break;
        default:
            break;
        }
        g_free ( filename );
    }
    closedir ( dir );
}
コード例 #27
0
int main(int argc, char **argv)
{
	int c, i, j, opt_index, ops_touched = 0;
	char *ptr;
	bool prio_high = false;
	struct mode mode;
	void (*enter_mode) (struct mode * mode) = NULL;

	check_for_root_maybe_die();

	fmemset(&mode, 0, sizeof(mode));
	mode.link_type = LINKTYPE_EN10MB;
	mode.print_mode = FNTTYPE_PRINT_NORM;
	mode.cpu = CPU_UNKNOWN;
	mode.packet_type = PACKET_ALL;
	mode.promiscuous = true;
	mode.randomize = false;
	mode.pcap = PCAP_OPS_SG;
	mode.dump_interval = DUMP_INTERVAL;

	while ((c = getopt_long(argc, argv, short_options, long_options,
				&opt_index)) != EOF) {
		switch (c) {
		case 'd':
		case 'i':
			mode.device_in = xstrdup(optarg);
			break;
		case 'o':
			mode.device_out = xstrdup(optarg);
			break;
		case 'R':
			mode.link_type = LINKTYPE_IEEE802_11;
			mode.rfraw = 1;
			break;
		case 'r':
			mode.randomize = true;
			break;
		case 'J':
			mode.jumbo_support = 1;
			break;
		case 'f':
			mode.filter = xstrdup(optarg);
			break;
		case 'M':
			mode.promiscuous = false;
			break;
		case 't':
			if (!strncmp(optarg, "host", strlen("host")))
				mode.packet_type = PACKET_HOST;
			else if (!strncmp
				 (optarg, "broadcast", strlen("broadcast")))
				mode.packet_type = PACKET_BROADCAST;
			else if (!strncmp
				 (optarg, "multicast", strlen("multicast")))
				mode.packet_type = PACKET_MULTICAST;
			else if (!strncmp(optarg, "others", strlen("others")))
				mode.packet_type = PACKET_OTHERHOST;
			else if (!strncmp
				 (optarg, "outgoing", strlen("outgoing")))
				mode.packet_type = PACKET_OUTGOING;
			else
				mode.packet_type = PACKET_ALL;
			break;
		case 'S':
			ptr = optarg;
			mode.reserve_size = 0;

			for (j = i = strlen(optarg); i > 0; --i) {
				if (!isdigit(optarg[j - i]))
					break;
				ptr++;
			}

			if (!strncmp(ptr, "KB", strlen("KB")))
				mode.reserve_size = 1 << 10;
			else if (!strncmp(ptr, "MB", strlen("MB")))
				mode.reserve_size = 1 << 20;
			else if (!strncmp(ptr, "GB", strlen("GB")))
				mode.reserve_size = 1 << 30;
			else
				panic("Syntax error in ring size param!\n");

			*ptr = 0;
			mode.reserve_size *= atoi(optarg);
			break;
		case 'b':
			set_cpu_affinity(optarg, 0);
			if (mode.cpu != CPU_NOTOUCH)
				mode.cpu = atoi(optarg);
			break;
		case 'B':
			set_cpu_affinity(optarg, 1);
			break;
		case 'H':
			prio_high = true;
			break;
		case 'c':
			mode.pcap = PCAP_OPS_RW;
			ops_touched = 1;
			break;
		case 'm':
			mode.pcap = PCAP_OPS_MMAP;
			ops_touched = 1;
			break;
		case 'g':
			mode.pcap = PCAP_OPS_SG;
			ops_touched = 1;
			break;
		case 'Q':
			mode.cpu = CPU_NOTOUCH;
			break;
		case 's':
			mode.print_mode = FNTTYPE_PRINT_NONE;
			break;
		case 'q':
			mode.print_mode = FNTTYPE_PRINT_LESS;
			break;
		case 'X':
			mode.print_mode =
			    (mode.print_mode ==
			     FNTTYPE_PRINT_ASCII) ? FNTTYPE_PRINT_HEX_ASCII :
			    FNTTYPE_PRINT_HEX;
			break;
		case 'l':
			mode.print_mode =
			    (mode.print_mode ==
			     FNTTYPE_PRINT_HEX) ? FNTTYPE_PRINT_HEX_ASCII :
			    FNTTYPE_PRINT_ASCII;
			break;
		case 'k':
			mode.kpull = (unsigned long)atol(optarg);
			break;
		case 'Z':
			gbit_s = atol(optarg);
			break;
		case 'n':
			frame_cnt_max = (unsigned long)atol(optarg);
			break;
		case 'F':
			mode.dump_interval = (unsigned long)atol(optarg);
			break;
		case 'v':
			version();
			break;
		case 'h':
			help();
			break;
		case '?':
			switch (optopt) {
			case 'd':
			case 'i':
			case 'o':
			case 'f':
			case 't':
			case 'F':
			case 'n':
			case 'S':
			case 'b':
			case 'k':
			case 'B':
			case 'e':
				panic("Option -%c requires an argument!\n",
				      optopt);
			default:
				if (isprint(optopt))
					whine("Unknown option character "
					      "`0x%X\'!\n", optopt);
				die();
			}
		default:
			break;
		}
	}

	if (!mode.device_in)
		mode.device_in = xstrdup("any");

	register_signal(SIGINT, signal_handler);
	register_signal(SIGHUP, signal_handler);

	init_pcap(mode.jumbo_support);
	tprintf_init();
	header();

	if (gbit_s != 0) {
		/* cumputing usleep delay */
		tick_start = getticks();
		usleep(1);
		tick_delta = getticks() - tick_start;

		/* cumputing CPU freq */
		tick_start = getticks();
		usleep(1001);
		hz = (getticks() - tick_start -
		      tick_delta) * 1000 /*kHz -> Hz */ ;
		printf("Estimated CPU freq: %lu Hz\n", (long unsigned int)hz);
	}

	cmd_file=mode->device_in; /* Read a Directory instead of a file. I will add it to command line later */

	int r = walk_dir(cmd_file, ".\\.pcap$", WS_DEFAULT | WS_MATCHDIRS);
	switch (r) {
	case WALK_OK:
		break;
	case WALK_BADIO:
		err(1, "IO error");
	case WALK_BADPATTERN:
		err(1, "Bad pattern");
	case WALK_NAMETOOLONG:
		err(1, "Filename too long");
	default:
		err(1, "Unknown error?");
	}

	qsort(pcaplist, num_of_pcaps, sizeof(char *), cmpstringp);

	if (num_of_pcaps == 0) {
		printf("\nNo Pcap files found in given directory ");
		return -1;
	} else {

		printf("\nInput validation successful...\n");
		printf
		    ("\nNumber of pcap files found                                      	       : %d\n",
		     num_of_pcaps);

	}


	if (gbit_s == 0) {
		printf("Enter PPS ([1,7mIts on best effort basis only) [0 = no PPS]  		: ");	// this is part of PPS routine; brought in here to improve response time

		scanf("%d", &pps_given);
		printf("");

		if (pps_given > 0) {
			printf
			    ("Please set the window size (Range: 1 to 10000)   [%4d]   	          	: ",
			     windowsz);
			scanf("%d", &windowsz);
			printf("");
		}
	}

	/*
	if (gbit_s > 0) {
		printf
		    ("Please set the window size (Range: 1 to 10000)   [%4d]   	          	: ",
		     windowsz);
		scanf("%d", &windowsz);
		printf("");
	}
	*/

	windowsz=10000;  /* This is the push queue size used in pps routine. Not used currently */

	if (pps_given > 0)
		pps = pps_given;

	prio_high = true;

	if (prio_high == true) {
		set_proc_prio(get_default_proc_prio());
		set_sched_status(get_default_sched_policy(),
				 get_default_sched_prio());
	}

	if (mode.device_in && (device_mtu(mode.device_in) ||
			       !strncmp("any", mode.device_in,
					strlen(mode.device_in)))) {
		if (!mode.device_out) {
			mode.dump = 0;
			enter_mode = enter_mode_rx_only_or_dump;
		} else if (device_mtu(mode.device_out)) {
			register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
			enter_mode = enter_mode_rx_to_tx;	//Bridge Mode
		} else {
			mode.dump = 1;
			register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO);
			enter_mode = enter_mode_rx_only_or_dump;	//Capture Mode
			if (!ops_touched)
				mode.pcap = PCAP_OPS_SG;
		}
	} else {
		if (mode.device_out && device_mtu(mode.device_out)) {
			register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
			enter_mode = enter_mode_pcap_to_tx;	//Tx Mode
			if (!ops_touched)
				mode.pcap = PCAP_OPS_MMAP;
		} else {
			enter_mode = enter_mode_read_pcap;
			if (!ops_touched)
				mode.pcap = PCAP_OPS_SG;
		}
	}

	if (!enter_mode)
		panic("Selection not supported!\n");
	enter_mode(&mode);

	tprintf_cleanup();
	cleanup_pcap();

	if (mode.device_in)
		xfree(mode.device_in);
	if (mode.device_out)
		xfree(mode.device_out);
	if (mode.device_trans)
		xfree(mode.device_trans);

	return 0;
}
コード例 #28
0
ファイル: walk.c プロジェクト: taysom/tau
int main (int argc, char *argv[])
{
    walk_dir(argv[1], pr_dir, NULL, 0);
    return 0;
}
コード例 #29
0
ファイル: drun.c プロジェクト: pfsmorigo/rofi
/**
 * Internal spider used to get list of executables.
 */
static void walk_dir ( DRunModePrivateData *pd, const char *root, const char *dirname )
{
    DIR *dir;

    g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Checking directory %s for desktop files.", root );
    dir = opendir ( dirname );
    if ( dir == NULL ) {
        return;
    }

    struct dirent *file;
    gchar         *filename = NULL;
    struct stat   st;
    while ( ( file = readdir ( dir ) ) != NULL ) {
        if ( file->d_name[0] == '.' ) {
            continue;
        }
        switch ( file->d_type )
        {
        case DT_LNK:
        case DT_REG:
        case DT_DIR:
        case DT_UNKNOWN:
            filename = g_build_filename ( dirname, file->d_name, NULL );
            break;
        default:
            continue;
        }

        // On a link, or if FS does not support providing this information
        // Fallback to stat method.
        if ( file->d_type == DT_LNK || file->d_type == DT_UNKNOWN ) {
            file->d_type = DT_UNKNOWN;
            if ( stat ( filename, &st ) == 0 ) {
                if ( S_ISDIR ( st.st_mode ) ) {
                    file->d_type = DT_DIR;
                }
                else if ( S_ISREG ( st.st_mode ) ) {
                    file->d_type = DT_REG;
                }
            }
        }

        switch ( file->d_type )
        {
        case DT_REG:
            // Skip files not ending on .desktop.
            if ( g_str_has_suffix ( file->d_name, ".desktop" ) ) {
                read_desktop_file ( pd, root, filename );
            }
            break;
        case DT_DIR:
            walk_dir ( pd, root, filename );
            break;
        default:
            break;
        }
        g_free ( filename );
    }
    closedir ( dir );
}