// 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 <olmod.h>
#include <sys/procfs.h>
#include <dirent.h>
#include <limits.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <libgen.h>

int64_t
getpidbyname_module_get (olmod_blackbox_t * data,
			 olmod_arglist_t * dynamic_args)
{
  char *name = (char *) dynamic_args[0];
  DIR *dirp;
  struct dirent *direntp;
  int fd;
  char filename[PATH_MAX];
  pid_t process = 0;
  static struct
  {
    procfs_debuginfo info;
    char buff[_POSIX_PATH_MAX];
  }
  proc_name;


  dirp = opendir ("/proc");
  if (dirp != NULL)
    {
      for (;;)
	{
	  direntp = readdir (dirp);
	  if (direntp == NULL)
	    break;
	  snprintf (filename, PATH_MAX, "/proc/%s/as", direntp->d_name);

	  /* The process of getting a process's name is taken from
	   * QSSL's pidin, it is also present in Igor's spin.
	   */

	  /* get process name, compare */
	  fd = open (filename, O_RDONLY);
	  if (fd == -1)
	    {
	      //printf("DEBUG mod_getpidbyname: %s: %s\n", 
	      //     filename, strerror(errno));
	      continue;
	    }

	  if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE,
		      &proc_name, sizeof (proc_name), 0) != EOK)
	    {
	      //printf("DEBUG mod_getpidbyname: devctl: %s\n", 
	      //     strerror(errno));
	      close (fd);
	      continue;
	    }
	  //printf("DEBUG mod_getpidbyname: %s\n", proc_name.info.path );
	  if (strcmp (name, basename (proc_name.info.path)) == 0)
	    {
	      process = atol (direntp->d_name);
	      close (fd);
	      break;
	    }
	  close (fd);
	}
      closedir (dirp);
    }
//  printf("DEBUG mod_getpidbyname: %s %d\n", name, process );
  return process;
}
