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.


Cheers, Rob
/*  dmenu_input - get all files, executable for the user running this
*                program, from $PATH
*
* 
*  Copyright (C) 2006 by Robert Manea  <[EMAIL PROTECTED]>
*
*  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;
}

Reply via email to