Re: [dwm] dmenu-input

From: Anselm R. Garbe <arg_AT_10kloc.org>
Date: Thu, 5 Oct 2006 15:18:24 +0200

On Thu, Oct 05, 2006 at 10:18:07AM +0200, Rob Manea wrote:
> Hi,
>
> I just wrote a quick replacement for the shell construct in Anselm's
> config.arg.h which feeds dmenu with a list of all executables found in
> $PATH.
>
> The programm simply scans $PATH, extracts all files executable for the
> user running the programm and outputs those files to stdout.
>
> Usage:
> dmenu-input | dmenu
>
> If you want it sorted:
>
> dmenu-input | sort -u | dmenu
>
>
> The small source file is attached to this message, just in case anyone
> may find it useful.

#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int
main(int argc, char *argv[]) {
        int dfd, i;
        gid_t gid = getgid();
        struct dirent *dp;
        struct stat s;
        uid_t uid = getuid();
        DIR *dir;

        for(i = 0; i < argc; i++)
                if((dir = opendir(argv[i]))) {
                        fchdir((dfd = dirfd(dir)));
                        do
                                if((dp = readdir(dir))
                                        && (stat(dp->d_name, &s) != -1)
                                        && S_ISREG (s.st_mode)
                                        && ((s.st_uid == uid && s.st_mode & S_IXUSR) ||
                                                (s.st_gid == gid && s.st_mode & S_IXGRP) ||
                                                (s.st_mode & S_IXOTH)))
                                        puts(dp->d_name);
                        while(dp);
                        closedir(dir);
                }
        return 0;
}

I reduced your version with the assumption that all command line
args are absolute paths to directories containing executables.
This keeps the tool quite small, but more flexible and much
simplier, see above.

> /* dmenu_input - get all files, executable for the user running this
> * program, from $PATH
> *
> *
> * Copyright (C) 2006 by Robert Manea <rob.manea_AT_gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> * the Free Software Foundation; either version 2 of the License, or
> * (at your option) any later version
> *
> * This program is distributed in the hope that it will be useful, but
> * WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> * General Public License for more details.
> *
> * You should have received a copy of the GNU General Public License
> * along with this program; if not, write to the Free Software
> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
> * USA
> */
>
> #include<stdio.h>
> #include<stdlib.h>
> #include<unistd.h>
> #include<string.h>
> #include<sys/types.h>
> #include<sys/stat.h>
> #include<dirent.h>
> #include<limits.h>
>
> #define EVARLEN 5
>
> uid_t userid;
> gid_t groupid;
>
> int
> is_exec (char *filename)
> {
> struct stat sp;
>
> if ((stat (filename, &sp) != -1) && S_ISREG (sp.st_mode)) {
> if ((sp.st_uid == userid && sp.st_mode & S_IXUSR) ||
> (sp.st_gid == groupid && sp.st_mode & S_IXGRP) ||
> (sp.st_mode & S_IXOTH))
> return 1;
> }
>
> return 0;
> }
>
> int
> getfiles (char *path)
> {
>
> static char fname[NAME_MAX + PATH_MAX + 1];
> DIR *dirh;
> struct dirent *dp;
> int plen, flen;
>
> if (!(dirh = opendir (path)))
> return -1;
>
> plen = strlen (path);
> do {
> if ((dp = readdir (dirh))) {
> flen = strlen(dp->d_name);
> if ((plen + flen + 1) > (NAME_MAX + PATH_MAX))
> continue;
>
> strncpy (fname, path, plen);
> fname[plen] = '/'; fname[plen + 1] = '\0';
> strncat (fname, dp->d_name, flen);
>
> if (is_exec (fname))
> puts (dp->d_name);
> }
>
> } while (dp != NULL);
>
> closedir (dirh);
> return 0;
> }
>
> int
> main (int argc, char *argv[], char *envp[])
> {
>
> int i;
> char *path = NULL;
> char *sp, *n;
>
> for (i = 0; envp[i]; ++i) {
> if (!strncmp (envp[i], "PATH=", EVARLEN)) {
> path = envp[i] + EVARLEN;
> break;
> }
> }
>
> if (!path)
> return EXIT_FAILURE;
>
> userid = getuid (); groupid = getgid ();
>
> for (n = path;; n = NULL) {
> n = strtok_r (n, ":", &sp);
> if (n == NULL)
> break;
>
> if (getfiles (n) == -1)
> continue;
> }
>
>
> return EXIT_SUCCESS;
> }

-- 
 Anselm R. Garbe  ><><  www.ebrag.de  ><><  GPG key: 0D73F361
Received on Thu Oct 05 2006 - 15:18:25 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 14:31:51 UTC