// Copyright, 2001-2003, Astra Network Inc.  All Rights Reserved

// This source code has been published by Astra Network Inc. However, any
// use, reproduction, modification, distribution or transfer of this
// software, or any software which includes or is based upon any of this
// code, is only permitted if expressly authorized by a written license
// agreement from Astra. Contact your Astra representative directly for
// more information.


#include <fcntl.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

#include "olmod.h"

int64_t
getpidbyname_module_get (olmod_blackbox_t * data,
			 olmod_arglist_t * dynamic_args)
{
  regex_t direxp;
  regex_t namexp;
  pid_t process = 0;
  DIR *dir;
  struct dirent *dp;
  int fd;
  int rv;
  char *name = dynamic_args[0];
  char tbuf[256];		/* temp buffer */

  regcomp (&direxp, "^[0-9]+$", REG_EXTENDED | REG_NOSUB);
  snprintf (tbuf, 256, "^(.*/)*%s$", name);
  regcomp (&namexp, tbuf, REG_EXTENDED | REG_NOSUB);

  dir = opendir ("/proc");
  if (dir == NULL)
    return 0;

  for (;;)
    {
      dp = readdir (dir);
      if (dp == NULL)
	break;

      if (regexec (&direxp, dp->d_name, 0, NULL, 0) == REG_NOMATCH)
	continue;

      snprintf (tbuf, 256, "/proc/%s/cmdline", dp->d_name);
      if ((fd = open (tbuf, O_RDONLY)) == -1)
	continue;

      /* file is a packed series of null-terminated strings */
      rv = read (fd, tbuf, 255);
      tbuf[rv == -1 ? 0 : rv] = 0;	/* make sure it's null terminated */

      close (fd);

      if (regexec (&namexp, tbuf, 0, NULL, 0) == REG_NOMATCH)
	continue;

      process = atol (dp->d_name);
      break;
    }
  closedir (dir);
  regfree (&direxp);
  regfree (&namexp);
  return process;
}
