#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/*
The members.c file is compiled via

gcc members.c -o /usr/local/mailman/bin/members

The object has permissions

-r-xr-s--- 1 apache mailman 5382 Mar  3 11:57 /usr/local/mailman/bin/members

If it is necessary to recompile, ownership and permissions need to be reset.

chown apache:mailman /usr/local/mailman/bin/members
chmod 2550 /usr/local/mailman/bin/members

If your web server user is not 'apache', replace 'apache' above with whatever
user name your web server runs under.

The idea is this is SETGID mailman and executable by the web server. It wraps
a few Mailman bin/ commands so that they can be executed by php scripts (or
anyone who can execute the file). The commands it recognizes/allows are in the
legals[] array in the source - currently just find_member, list_members

Once this is done, a command such as "list_members <arguments> list_name"
can be executed by apache in a php script using the php system() or exec()
functions, depending on how you want to handle output, using the string

 "/usr/local/mailman/bin/members list_members <arguments> list_name"

as the command.
*/

main(int argc, char** argv, char** env) {

char* legals[] = {
  "list_members",
  "find_member",
  (char*) NULL
};

int i;
int flag = 0;
char command[100];

    if (argc < 2) {
        dprintf(STDERR_FILENO,
                "Usage: %s command command_args\nNo command found\n",
                argv[0]);
        exit(1);
    }

    for ( i = 0; legals[i] != (char*) NULL; i++ ) {
        if (strcmp(legals[i], argv[1]) == 0) {
            flag = 1;
            break;
        }
    }
    if (!flag){
        dprintf(STDERR_FILENO,
                "Usage: %s command command_args\nUnknown command: %s\n",
                argv[0], argv[1]);
        exit(1);
    }
    sprintf(command, "/usr/local/mailman/bin/%s", argv[1]);
    execve(command, &argv[1], env);
    dprintf(STDERR_FILENO, "execve of %s failed\n", command);
    exit(2);
}
