/*
 * pidof: return the process ids of a named process.
 *
 * This code was written by orc@pell.chi.il.us (david parsons)
 * and released into the public domain on April 29, 1999.
 */
static const char rcsid[] = "Mastodon $Id: s.pidof.c 1.4 00/05/21 16:33:42-00:00 orc $";
 
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>

struct { int retval; }
main(int argc, char **argv)
{
    FILE *f;
    DIR *d;
    char *p;
    int len;
    int x;
    int iskillall = 0;
    int ct=0;
    struct dirent *de;
    char line[200];
    char process[200];
    char *pgm = basename(argv[0]);

    iskillall = strcasecmp(pgm, "killall") == 0;

    if (argc < 2) {
	fprintf(stderr, "usage: pidof process-name {...}\n");
	exit(1);
    }
    if ((d = opendir("/proc")) == 0) {
	fprintf(stderr, "could not open /proc -- is it mounted?\n");
	exit(1);
    }

    while ((de = readdir(d)) != 0) {
	if (de->d_name[0] == 0)		/* zero-length filename? huh? */
	    continue;
	/* check to see if this is a process file (name is process id) */
	for (p = de->d_name; *p; ++p)
	    if (!isdigit(*p))
		break;
	if (*p != 0)
	    continue;

	/* if it's a process file, pick the name of the process out
	 * of the status record.
	 */
	sprintf(line, "/proc/%s/status", de->d_name);
	if ((f = fopen(line, "r")) != 0) {
	    while (fgets(line, sizeof line, f) != 0) {
		len = strlen(line);
		if (line[len-1] != '\n')	/* overly long line?  Oh,
						 * drat!
						 */
		    continue;
		line[len-1] = 0;
		if (strncasecmp(line, "name:", 5) == 0) {
		    for (p = line+5; isspace(*p); ++p)
			;
		    for (x=1; x < argc; x++)
			if (strcmp(argv[x], p) == 0) {
			    puts(de->d_name);
			    ct++;
			    break;
			}
		    break;
		}
	    }
	    fclose(f);
	}
    }
    closedir(d);
    exit(ct ? 0 : 1);
} /* pidof */
